commit e142dd043282c3c52b873d7be492ff89bd0fdf60
parent 64621ca9b3411753e8015ffec4f2e315b46a849f
Author: nolash <dev@holbrook.no>
Date: Sat, 5 Jun 2021 19:19:17 +0200
Add transfer, mint, balance to sim
Diffstat:
5 files changed, 129 insertions(+), 6 deletions(-)
diff --git a/python/config/eth.ini b/python/config/eth.ini
@@ -0,0 +1,2 @@
+[eth]
+provider=http://localhost:8545
diff --git a/python/config/session.ini b/python/config/session.ini
@@ -0,0 +1,2 @@
+[session]
+chain_spec=
diff --git a/python/config/token.ini b/python/config/token.ini
@@ -0,0 +1,8 @@
+[token]
+redistribution_period=10800
+demurrage_level=50
+supply_limit=0
+symbol=RDT
+name=Redistributed Demurraged Token
+decimals=6
+sink_address=
diff --git a/python/erc20_demurrage_token/sim/sim.py b/python/erc20_demurrage_token/sim/sim.py
@@ -1,9 +1,23 @@
+# standard imports
+import logging
+
# external imports
from chainlib.eth.unittest.ethtester import create_tester_signer
from chainlib.eth.unittest.base import TestRPCConnection
-from chainlib.eth.tx import receipt
+from chainlib.eth.tx import (
+ receipt,
+ Tx,
+ )
from chainlib.eth.nonce import RPCNonceOracle
+from chainlib.eth.gas import (
+ OverrideGasOracle,
+ Gas,
+ )
from chainlib.eth.address import to_checksum_address
+from chainlib.eth.block import (
+ block_latest,
+ block_by_number,
+ )
from crypto_dev_signer.keystore.dict import DictKeystore
from crypto_dev_signer.eth.signer import ReferenceSigner as EIP155Signer
from hexathon import (
@@ -14,14 +28,19 @@ from hexathon import (
# local imports
from erc20_demurrage_token import DemurrageToken
+logg = logging.getLogger(__name__)
+
+
class DemurrageTokenSimulation:
- def __init__(self, chain_spec, settings, redistribute=True, cap=0):
+ def __init__(self, chain_spec, settings, redistribute=True, cap=0, actors=1):
+ self.chain_spec = chain_spec
self.accounts = []
self.keystore = DictKeystore()
self.signer = EIP155Signer(self.keystore)
self.eth_helper = create_tester_signer(self.keystore)
self.eth_backend = self.eth_helper.backend
+ self.gas_oracle = OverrideGasOracle(limit=100000, price=1)
self.rpc = TestRPCConnection(None, self.eth_helper, self.signer)
for a in self.keystore.list():
self.accounts.append(add_0x(to_checksum_address(a)))
@@ -36,3 +55,83 @@ class DemurrageTokenSimulation:
if (r['status'] != 1):
raise RuntimeError('contract deployment failed')
self.address = r['contract_address']
+
+ self.period_seconds = settings.period_minutes * 60
+
+ o = block_latest()
+ r = self.rpc.do(o)
+ self.last_block = r
+
+ o = block_by_number(r)
+ r = self.rpc.do(o)
+ self.last_timestamp = r['timestamp']
+
+ self.actors = []
+ for i in range(actors):
+ idx = i % 10
+ address = self.keystore.new()
+ self.actors.append(address)
+ self.accounts.append(address)
+
+ nonce_oracle = RPCNonceOracle(self.accounts[idx], conn=self.rpc)
+ c = Gas(self.chain_spec, signer=self.signer, nonce_oracle=nonce_oracle, gas_oracle=self.gas_oracle)
+ (tx_hash, o) = c.create(self.accounts[idx], address, 100000 * 1000000)
+ self.rpc.do(o)
+ o = receipt(tx_hash)
+ r = self.rpc.do(o)
+ if r['status'] != 1:
+ raise RuntimeError('failed gas transfer to account #{}: {} from {}'.format(i, address, self.accounts[idx]))
+ logg.debug('added actor account #{}: {}'.format(i, address))
+
+ self.eth_helper.disable_auto_mine_transactions()
+
+ logg.info('intialized at block {} timestamp {} period {} demurrage level {} sink address {} (first address in keystore)'.format(
+ self.last_block,
+ self.last_timestamp,
+ settings.period_minutes,
+ settings.demurrage_level,
+ settings.sink_address,
+ )
+ )
+
+ self.caller_contract = DemurrageToken(self.chain_spec)
+
+
+ def mint(self, recipient, value):
+ nonce_oracle = RPCNonceOracle(self.accounts[0], conn=self.rpc)
+ c = DemurrageToken(self.chain_spec, signer=self.signer, nonce_oracle=nonce_oracle, gas_oracle=self.gas_oracle)
+ (tx_hash, o) = c.mint_to(self.address, self.accounts[0], recipient, value)
+ self.rpc.do(o)
+ return tx_hash
+
+
+ def transfer(self, sender, recipient, value):
+ nonce_oracle = RPCNonceOracle(sender, conn=self.rpc)
+ c = DemurrageToken(self.chain_spec, signer=self.signer, nonce_oracle=nonce_oracle, gas_oracle=self.gas_oracle)
+ (tx_hash, o) = c.transfer(self.address, sender, recipient, value)
+ self.rpc.do(o)
+ return tx_hash
+
+
+ def balance(self, holder):
+ o = self.caller_contract.balance_of(self.address, holder, sender_address=self.accounts[0])
+ r = self.rpc.do(o)
+ return self.caller_contract.parse_balance_of(r)
+
+
+ def next(self):
+ self.last_timestamp += self.period_seconds
+ self.eth_helper.mine_block()
+ self.eth_helper.time_travel(self.last_timestamp)
+ self.last_block += 1
+ o = block_by_number(self.last_block)
+ r = self.rpc.do(o)
+
+ for tx_hash in r['transactions']:
+ o = receipt(tx_hash)
+ rcpt = self.rpc.do(o)
+ if rcpt['status'] == 0:
+ raise RuntimeError('tx {} (block {} index {}) failed'.format(tx_hash, self.last_block, rcpt['transaction_index']))
+ logg.debug('tx {} (block {} index {}) verified'.format(tx_hash, self.last_block, rcpt['transaction_index']))
+
+ return (self.last_block, self.last_timestamp)
diff --git a/python/tests/sim/tests_sim.py b/python/tests/sim/tests_sim.py
@@ -9,6 +9,7 @@ from chainlib.chain import ChainSpec
from erc20_demurrage_token import DemurrageTokenSettings
from erc20_demurrage_token.sim import DemurrageTokenSimulation
+logging.basicConfig(level=logging.DEBUG)
logg = logging.getLogger()
@@ -16,18 +17,29 @@ class TestSim(unittest.TestCase):
def setUp(self):
self.chain_spec = ChainSpec('evm', 'foochain', 42)
- self.cap = 1000000000
+ #self.cap = 1000000000
+ self.cap = 0
settings = DemurrageTokenSettings()
settings.name = 'Simulated Demurrage Token'
settings.symbol = 'SIM'
settings.decimals = 6
settings.demurrage_level = 50
settings.period_minutes = 10800
- self.sim = DemurrageTokenSimulation(self.chain_spec, settings, redistribute=True, cap=self.cap)
+ self.sim = DemurrageTokenSimulation(self.chain_spec, settings, redistribute=True, cap=self.cap, actors=10)
- def test_hello(self):
- pass
+ def test_mint(self):
+ self.sim.mint(self.sim.actors[0], 1024)
+ self.sim.next()
+ balance = self.sim.balance(self.sim.actors[0])
+ self.assertEqual(balance, 1024)
+
+
+ def test_transfer(self):
+ self.sim.mint(self.sim.actors[0], 1024)
+ self.sim.transfer(self.sim.actors[0], self.sim.actors[1], 500)
+ self.sim.next()
+
if __name__ == '__main__':
unittest.main()