From 3da923481f755d0a090854035ed4ada9ea1ee440 Mon Sep 17 00:00:00 2001 From: nolash Date: Mon, 11 Oct 2021 08:57:03 +0200 Subject: [PATCH] Add full deployment test --- cic/ext/eth/__init__.py | 37 ++++++++---- cic/hash.py | 10 ++++ setup.cfg | 2 +- tests/eth/base_eth.py | 49 +++++++++++++++- tests/eth/test_eth_full.py | 74 ++++++++++++++++++++++++ tests/eth/test_eth_token.py | 18 ++---- tests/test_proof.py | 40 +++++++++++++ tests/testdata/proof/attachments/bar.txt | 1 + tests/testdata/proof/attachments/foo.txt | 1 + 9 files changed, 206 insertions(+), 26 deletions(-) create mode 100644 cic/hash.py create mode 100644 tests/eth/test_eth_full.py create mode 100644 tests/test_proof.py create mode 100644 tests/testdata/proof/attachments/bar.txt create mode 100644 tests/testdata/proof/attachments/foo.txt diff --git a/cic/ext/eth/__init__.py b/cic/ext/eth/__init__.py index 8dec6d0..04d3c74 100644 --- a/cic/ext/eth/__init__.py +++ b/cic/ext/eth/__init__.py @@ -7,22 +7,27 @@ from chainlib.chain import ChainSpec from chainlib.eth.tx import ( TxFormat, TxFactory, + Tx, + receipt, ) from chainlib.eth.connection import RPCConnection from chainlib.eth.contract import ( ABIContractEncoder, ABIContractType ) +from chainlib.eth.gas import OverrideGasOracle +from chainlib.eth.nonce import RPCNonceOracle from chainlib.eth.address import is_address from eth_token_index import TokenUniqueSymbolIndex from eth_address_declarator import Declarator +from eth_address_declarator.declarator import AddressDeclarator logg = logging.getLogger(__name__) class CICEth: - def __init__(self, chain_spec, resources, proof, signer=None, rpc=None, nonce_oracle=None, fee_oracle=None): + def __init__(self, chain_spec, resources, proof, signer=None, rpc=None, fee_oracle=None): """resources will be modified """ self.resources = resources @@ -30,7 +35,6 @@ class CICEth: self.chain_spec = chain_spec self.signer = signer self.rpc = rpc - self.nonce_oracle = nonce_oracle self.fee_oracle = fee_oracle self.token_details = None self.token_address = None @@ -127,7 +131,9 @@ class CICEth: code = self.token_details['code'] + enc.get() signer_address = self.resources['token']['key_address'] - c = TxFactory(self.chain_spec, signer=self.signer, nonce_oracle=self.nonce_oracle, gas_oracle=self.fee_oracle) + nonce_oracle = RPCNonceOracle(signer_address, conn=self.rpc) + + c = TxFactory(self.chain_spec, signer=self.signer, nonce_oracle=nonce_oracle, gas_oracle=self.fee_oracle) tx = c.template(signer_address, None, use_nonce=True) tx = c.set_code(tx, code) o = c.finalize(tx, self.tx_format) @@ -135,6 +141,10 @@ class CICEth: r = None if self.rpc != None: r = self.rpc.do(o[1]) + ro = receipt(r) + rr = self.rpc.do(ro) + rr = Tx.src_normalize(rr) + self.token_address = rr['contract_address'] elif self.signer != None: r = o[1] @@ -146,10 +156,12 @@ class CICEth: def process_token_index(self): - c = TokenUniqueSymbolIndex(self.chain_spec, signer=self.signer, nonce_oracle=self.nonce_oracle, gas_oracle=self.fee_oracle) - - contract_address = self.resources['token_index']['reference'] signer_address = self.resources['token_index']['key_address'] + contract_address = self.resources['token_index']['reference'] + + gas_oracle = OverrideGasOracle(limit=TokenUniqueSymbolIndex.gas(), conn=self.rpc) + nonce_oracle = RPCNonceOracle(signer_address, conn=self.rpc) + c = TokenUniqueSymbolIndex(self.chain_spec, signer=self.signer, nonce_oracle=nonce_oracle, gas_oracle=gas_oracle) o = c.register(contract_address, signer_address, self.token_address, tx_format=self.tx_format) r = None @@ -165,10 +177,12 @@ class CICEth: def process_address_declarator(self): - c = Declarator(self.chain_spec, signer=self.signer, nonce_oracle=self.nonce_oracle, gas_oracle=self.fee_oracle) - - contract_address = self.resources['address_declarator']['reference'] signer_address = self.resources['address_declarator']['key_address'] + contract_address = self.resources['address_declarator']['reference'] + + gas_oracle = OverrideGasOracle(limit=AddressDeclarator.gas(), conn=self.rpc) + nonce_oracle = RPCNonceOracle(signer_address, conn=self.rpc) + c = Declarator(self.chain_spec, signer=self.signer, nonce_oracle=nonce_oracle, gas_oracle=gas_oracle) r = [] for proof in self.proof.get(): @@ -187,6 +201,7 @@ class CICEth: def process(self): tasks = [] self.token_address = self.resources['token']['reference'] + if self.token_address == None: tasks.append('token') @@ -197,7 +212,9 @@ class CICEth: tasks.append(k) for task in tasks: - getattr(self, 'process_' + task)() + r = getattr(self, 'process_' + task)() + + return self.outputs def new(resources, proof, signer_hint=None): diff --git a/cic/hash.py b/cic/hash.py new file mode 100644 index 0000000..34eafd3 --- /dev/null +++ b/cic/hash.py @@ -0,0 +1,10 @@ +class Hasher: + + def __basehasher(self, v): + h = hashlib.sha256() + h.update(v) + return h.digest() + + + def hash(self, v): + return self.__basehasher(v) diff --git a/setup.cfg b/setup.cfg index 3f31f67..cdb72d7 100644 --- a/setup.cfg +++ b/setup.cfg @@ -31,4 +31,4 @@ packages = cic.ext.eth [options.extras_require] -eth = chainlib-eth>=0.0.10a1,<0.1.0; funga-eth>=0.5.1a1,<0.6.0; eth-token-index>=0.2.4a1,<0.3.0; eth-address-index>=0.2.4a1,<0.3.0 +eth = chainlib-eth>=0.0.10a1,<0.1.0; funga-eth>=0.5.1a1,<0.6.0; eth-token-index>=0.2.4a1,<0.3.0; eth-address-index>=0.2.4a1,<0.3.0, okota>=0.2.4a6,<0.3.0 diff --git a/tests/eth/base_eth.py b/tests/eth/base_eth.py index 55c401a..0b8d69e 100644 --- a/tests/eth/base_eth.py +++ b/tests/eth/base_eth.py @@ -6,11 +6,19 @@ import logging # external imports from chainlib.chain import ChainSpec from chainlib.eth.unittest.ethtester import EthTesterCase +from chainlib.eth.tx import ( + Tx, + receipt, + ) +from chainlib.eth.gas import OverrideGasOracle +from chainlib.eth.nonce import RPCNonceOracle from hexathon import ( add_0x, strip_0x, ) from funga.eth.keystore.dict import DictKeystore +from eth_address_declarator.declarator import AddressDeclarator +from okota.token_index.index import TokenUniqueSymbolIndexAddressDeclarator # local imports from cic.ext.eth import CICEth @@ -28,9 +36,35 @@ class TestCICEthBase(EthTesterCase): def setUp(self): super(TestCICEthBase, self).setUp() random.seed(42) + self.initial_description = add_0x(random.randbytes(32).hex()) self.token_address = add_0x(random.randbytes(20).hex()) - self.token_index_address = add_0x(random.randbytes(20).hex()) + addresses = self.keystore.list() + + nonce_oracle = RPCNonceOracle(addresses[2], self.rpc) + gas_oracle = OverrideGasOracle(limit=AddressDeclarator.gas(), conn=self.rpc) + c = AddressDeclarator(self.chain_spec, self.signer, nonce_oracle=nonce_oracle, gas_oracle=gas_oracle) + (tx_hash_hex, o) = c.constructor(addresses[2], self.initial_description) + r = self.rpc.do(o) + o = receipt(r) + r = self.rpc.do(o) + Tx.src_normalize(r) + self.assertEqual(r['status'], 1) + self.address_declarator_address = r['contract_address'] + logg.debug('address declarator deployed at {}'.format(self.address_declarator_address)) + + nonce_oracle = RPCNonceOracle(addresses[1], self.rpc) + gas_oracle = OverrideGasOracle(limit=TokenUniqueSymbolIndexAddressDeclarator.gas(), conn=self.rpc) + c = TokenUniqueSymbolIndexAddressDeclarator(self.chain_spec, self.signer, nonce_oracle=nonce_oracle, gas_oracle=gas_oracle) + (tx_hash_hex, o) = c.constructor(addresses[1], self.address_declarator_address) + r = self.rpc.do(o) + o = receipt(r) + r = self.rpc.do(o) + Tx.src_normalize(r) + self.assertEqual(r['status'], 1) + self.token_index_address = r['contract_address'] + logg.debug('token index deployed at {}'.format(self.token_index_address)) + self.resources = { 'token': { 'reference': self.token_address, @@ -41,7 +75,7 @@ class TestCICEthBase(EthTesterCase): 'key_address': addresses[1], }, 'address_declarator': { - 'reference': self.token_index_address, + 'reference': self.address_declarator_address, 'key_address': addresses[2], }, } @@ -50,3 +84,14 @@ class TestCICEthBase(EthTesterCase): attach.load() self.proofs = Proof(proof_dir, attachments=attach) self.proofs.load() + + +class TestCICEthTokenBase(TestCICEthBase): + + def setUp(self): + super(TestCICEthTokenBase, self).setUp() + self.resources['token']['reference'] = None + self.adapter = CICEth(self.chain_spec, self.resources, self.proofs) + self.token_name = 'FOotoken' + self.token_symbol = 'FOO' + self.token_precision = 8 diff --git a/tests/eth/test_eth_full.py b/tests/eth/test_eth_full.py new file mode 100644 index 0000000..e171a5b --- /dev/null +++ b/tests/eth/test_eth_full.py @@ -0,0 +1,74 @@ +# standard imports +import unittest +import logging + +# external imports +from chainlib.eth.nonce import ( + RPCNonceOracle, + nonce, + ) +from chainlib.eth.gas import ( + RPCGasOracle, + OverrideGasOracle, + ) +from chainlib.eth.tx import ( + TxFormat, + unpack, + receipt, + ) +from hexathon import strip_0x +from giftable_erc20_token import GiftableToken +from eth_token_index import TokenUniqueSymbolIndex + +# local imports +from cic.ext.eth import CICEth + +# test imports +from tests.eth.base_eth import TestCICEthTokenBase + +logging.basicConfig(level=logging.DEBUG) +logg = logging.getLogger() + + +class TestCICEthRPC(TestCICEthTokenBase): + + def setUp(self): + super(TestCICEthRPC, self).setUp() + nonce_oracle = RPCNonceOracle(self.accounts[0], self.rpc) + gas_oracle = RPCGasOracle(self.rpc) + + self.adapter = CICEth(self.chain_spec, self.resources, self.proofs, signer=self.signer, rpc=self.rpc, fee_oracle=gas_oracle) + + + def test_rpc_process_notoken(self): + results = self.adapter.process() + for hsh in results: + logg.debug('hsh {}'.format(hsh)) + o = receipt(hsh) + r = self.rpc.do(o) + self.assertEqual(r['status'], 1) + + + def test_rpc_process_withtoken(self): + self.adapter.fee_oracle = OverrideGasOracle(limit=GiftableToken.gas(), conn=self.rpc) + self.adapter.prepare_token(self.token_name, self.token_symbol, self.token_precision, GiftableToken.bytecode()) + results = self.adapter.process() + for hsh in results: + logg.debug('hsh {}'.format(hsh)) + o = receipt(hsh) + r = self.rpc.do(o) + self.assertEqual(r['status'], 1) + + o = receipt(results[0]) + r = self.rpc.do(o) + token_contract_address = r['contract_address'] + + c = TokenUniqueSymbolIndex(self.chain_spec) + o = c.address_of(self.token_index_address, 'FOO', sender_address=self.accounts[0]) + r = self.rpc.do(o) + token_contract_address_lookup = c.parse_address_of(r) + self.assertEqual(strip_0x(token_contract_address), strip_0x(token_contract_address_lookup)) + + +if __name__ == '__main__': + unittest.main() diff --git a/tests/eth/test_eth_token.py b/tests/eth/test_eth_token.py index 1837258..cc01b51 100644 --- a/tests/eth/test_eth_token.py +++ b/tests/eth/test_eth_token.py @@ -15,6 +15,8 @@ from chainlib.eth.contract import ( ) from chainlib.jsonrpc import JSONRPCRequest from hexathon import add_0x +from giftable_erc20_token import GiftableToken +from eth_erc20 import ERC20 # local imports from cic.ext.eth import CICEth @@ -22,22 +24,12 @@ from cic.ext.eth import CICEth # tests imports from tests.eth.base_eth import TestCICEthBase from tests.base_cic import test_data_dir -from giftable_erc20_token import GiftableToken -from eth_erc20 import ERC20 logging.basicConfig(level=logging.DEBUG) logg = logging.getLogger() -class TestCICEthToken(TestCICEthBase): - - def setUp(self): - super(TestCICEthToken, self).setUp() - self.resources['token']['reference'] = None - self.adapter = CICEth(self.chain_spec, self.resources, self.proofs) - self.token_name = 'FOotoken' - self.token_symbol = 'FOO' - self.token_precision = 8 +class TestCICEthToken(TestCICEthTokenBase): def test_token_nobackend(self): @@ -48,7 +40,7 @@ class TestCICEthToken(TestCICEthBase): def test_token_sign(self): self.adapter.signer = self.signer self.adapter.tx_format = TxFormat.RLP_SIGNED - self.adapter.prepare_token('FOoToken', 'FOO', 8, GiftableToken.bytecode()) + self.adapter.prepare_token(self.token_name, self.token_symbol, self.token_precision, GiftableToken.bytecode()) v = self.adapter.process_token() @@ -56,7 +48,7 @@ class TestCICEthToken(TestCICEthBase): self.adapter.signer = self.signer self.adapter.rpc = self.rpc self.adapter.tx_format = TxFormat.JSONRPC - self.adapter.prepare_token('FOoToken', 'FOO', 8, GiftableToken.bytecode()) + self.adapter.prepare_token(self.token_name, self.token_symbol, self.token_precision, GiftableToken.bytecode()) v = self.adapter.process_token() o = receipt(v) r = self.rpc.do(o) diff --git a/tests/test_proof.py b/tests/test_proof.py new file mode 100644 index 0000000..baf3084 --- /dev/null +++ b/tests/test_proof.py @@ -0,0 +1,40 @@ +# standard imports +import os +import unittest +import logging + +# local imports +from cic import Proof +from cic.attachment import Attachment + +# test imports +from tests.base_cic import test_data_dir + +logging.basicConfig(level=logging.DEBUG) +logg = logging.getLogger() + + +foo_hash = '2c26b46b68ffc68ff99b453c1d30413413422d706483bfa0f98a5e886266e7ae' +bar_hash = 'fcde2b2edba56bf408601fb721fe9b5c338d10ee429ea04fae5511b68fbf8fb9' + +class TestProof(unittest.TestCase): + + def test_proof_serialize(self): + proof_path = os.path.join(test_data_dir, 'proof') + c = Proof(path=proof_path) + v = c.get() + logg.debug('v {}'.format(v)) + + + def test_proof_serialize_merge(self): + proof_path = os.path.join(test_data_dir, 'proof') + + attach = Attachment(proof_path) + attach.load() + + c = Proof(path=proof_path, attachments=attach) + v = c.get() + + +if __name__ == '__main__': + unittest.main() diff --git a/tests/testdata/proof/attachments/bar.txt b/tests/testdata/proof/attachments/bar.txt new file mode 100644 index 0000000..ba0e162 --- /dev/null +++ b/tests/testdata/proof/attachments/bar.txt @@ -0,0 +1 @@ +bar \ No newline at end of file diff --git a/tests/testdata/proof/attachments/foo.txt b/tests/testdata/proof/attachments/foo.txt new file mode 100644 index 0000000..1910281 --- /dev/null +++ b/tests/testdata/proof/attachments/foo.txt @@ -0,0 +1 @@ +foo \ No newline at end of file