Initial commit; receive all eth code from chainlib package
This commit is contained in:
5
tests/Makefile
Normal file
5
tests/Makefile
Normal file
@@ -0,0 +1,5 @@
|
||||
SOLC = /usr/bin/solc
|
||||
|
||||
all:
|
||||
$(SOLC) --bin TestContract.sol --evm-version byzantium | awk 'NR>3' > TestContract.bin
|
||||
truncate -s -1 TestContract.bin
|
||||
1
tests/TestContract.bin
Normal file
1
tests/TestContract.bin
Normal file
@@ -0,0 +1 @@
|
||||
608060405234801561001057600080fd5b50610260806100206000396000f3fe608060405234801561001057600080fd5b5060043610610048576000357c01000000000000000000000000000000000000000000000000000000009004806333aa24121461004d575b600080fd5b61006760048036038101906100629190610122565b61007d565b604051610074919061018b565b60405180910390f35b6000827fa8ed44a382304c8db2c9059e4de342080401fb8e9a71986396d595c869fa3792836040516100af91906101a6565b60405180910390a27f33c4ea6ccc21f1a14e9de7326edcc52c2b8a302ac875ae6b8fee2560eadd75ad836040516100e691906101c1565b60405180910390a16001905092915050565b600081359050610107816101fc565b92915050565b60008135905061011c81610213565b92915050565b6000806040838503121561013557600080fd5b60006101438582860161010d565b9250506020610154858286016100f8565b9150509250929050565b610167816101dc565b82525050565b610176816101e8565b82525050565b610185816101f2565b82525050565b60006020820190506101a0600083018461015e565b92915050565b60006020820190506101bb600083018461016d565b92915050565b60006020820190506101d6600083018461017c565b92915050565b60008115159050919050565b6000819050919050565b6000819050919050565b610205816101e8565b811461021057600080fd5b50565b61021c816101f2565b811461022757600080fd5b5056fea26469706673582212205c428504ca5a53a9250d76b287bec8ee4b13d5c7cb386a0f67cbf77ecb96a9ea64736f6c63430008040033
|
||||
13
tests/TestContract.sol
Normal file
13
tests/TestContract.sol
Normal file
@@ -0,0 +1,13 @@
|
||||
pragma solidity ^0.8.0;
|
||||
|
||||
contract TestEventContract {
|
||||
|
||||
event TestEventOne(uint256 indexed _foo, bytes32 _bar);
|
||||
event TestEventTwo(uint256 _foo);
|
||||
|
||||
function foo(uint256 _foo, bytes32 _bar) public returns (bool) {
|
||||
emit TestEventOne(_foo, _bar);
|
||||
emit TestEventTwo(_foo);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
66
tests/contract.py
Normal file
66
tests/contract.py
Normal file
@@ -0,0 +1,66 @@
|
||||
# standard imports
|
||||
import os
|
||||
|
||||
# external iports
|
||||
from chainlib.eth.tx import (
|
||||
TxFactory,
|
||||
TxFormat,
|
||||
receipt,
|
||||
)
|
||||
from chainlib.eth.contract import (
|
||||
ABIContractEncoder,
|
||||
#ABIContractDecoder,
|
||||
ABIContractType,
|
||||
)
|
||||
from hexathon import add_0x
|
||||
|
||||
script_dir = os.path.realpath(os.path.dirname(__file__))
|
||||
data_dir = script_dir
|
||||
|
||||
class TestContract(TxFactory):
|
||||
|
||||
__abi = None
|
||||
__bytecode = None
|
||||
|
||||
@staticmethod
|
||||
def gas(code=None):
|
||||
return 1000000
|
||||
|
||||
|
||||
@staticmethod
|
||||
def abi():
|
||||
if TestContract.__abi == None:
|
||||
f = open(os.path.join(data_dir, 'TestContract.json'), 'r')
|
||||
TestContract.__abi = json.load(f)
|
||||
f.close()
|
||||
return TestContract.__abi
|
||||
|
||||
|
||||
@staticmethod
|
||||
def bytecode():
|
||||
if TestContract.__bytecode == None:
|
||||
f = open(os.path.join(data_dir, 'TestContract.bin'))
|
||||
TestContract.__bytecode = f.read()
|
||||
f.close()
|
||||
return TestContract.__bytecode
|
||||
|
||||
|
||||
def constructor(self, sender_address, tx_format=TxFormat.JSONRPC, id_generator=None):
|
||||
code = TestContract.bytecode()
|
||||
tx = self.template(sender_address, None, use_nonce=True)
|
||||
tx = self.set_code(tx, code)
|
||||
return self.finalize(tx, tx_format, id_generator=id_generator)
|
||||
|
||||
|
||||
def foo(self, contract_address, sender_address, x, y, tx_format=TxFormat.JSONRPC, id_generator=None):
|
||||
enc = ABIContractEncoder()
|
||||
enc.method('foo')
|
||||
enc.typ(ABIContractType.UINT256)
|
||||
enc.typ(ABIContractType.BYTES32)
|
||||
enc.uint256(x)
|
||||
enc.bytes32(y)
|
||||
data = add_0x(enc.get())
|
||||
tx = self.template(sender_address, contract_address, use_nonce=True)
|
||||
tx = self.set_code(tx, data)
|
||||
tx = self.finalize(tx, tx_format, id_generator=id_generator)
|
||||
return tx
|
||||
29
tests/test_abi.py
Normal file
29
tests/test_abi.py
Normal file
@@ -0,0 +1,29 @@
|
||||
from chainlib.eth.contract import (
|
||||
ABIContractEncoder,
|
||||
ABIContractType,
|
||||
)
|
||||
|
||||
|
||||
def test_abi_param():
|
||||
|
||||
e = ABIContractEncoder()
|
||||
e.uint256(42)
|
||||
e.bytes32('0x666f6f')
|
||||
e.address('0xdeadbeefdeadbeefdeadbeefdeadbeefdeadbeef')
|
||||
e.method('foo')
|
||||
e.typ(ABIContractType.UINT256)
|
||||
e.typ(ABIContractType.BYTES32)
|
||||
e.typ(ABIContractType.ADDRESS)
|
||||
|
||||
assert e.types[0] == ABIContractType.UINT256
|
||||
assert e.types[1] == ABIContractType.BYTES32
|
||||
assert e.types[2] == ABIContractType.ADDRESS
|
||||
assert e.contents[0] == '000000000000000000000000000000000000000000000000000000000000002a'
|
||||
assert e.contents[1] == '0000000000000000000000000000000000000000000000000000000000666f6f'
|
||||
assert e.contents[2] == '000000000000000000000000deadbeefdeadbeefdeadbeefdeadbeefdeadbeef'
|
||||
|
||||
assert e.get() == 'a08f54bb000000000000000000000000000000000000000000000000000000000000002a0000000000000000000000000000000000000000000000000000000000666f6f000000000000000000000000deadbeefdeadbeefdeadbeefdeadbeefdeadbeef'
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
test_abi_param()
|
||||
35
tests/test_address.py
Normal file
35
tests/test_address.py
Normal file
@@ -0,0 +1,35 @@
|
||||
import unittest
|
||||
|
||||
from chainlib.eth.address import (
|
||||
is_address,
|
||||
is_checksum_address,
|
||||
to_checksum,
|
||||
)
|
||||
|
||||
from tests.base import TestBase
|
||||
|
||||
|
||||
class TestChain(TestBase):
|
||||
|
||||
def test_chain_spec(self):
|
||||
checksum_address = '0xEb3907eCad74a0013c259D5874AE7f22DcBcC95C'
|
||||
plain_address = checksum_address.lower()
|
||||
|
||||
self.assertEqual(checksum_address, to_checksum(checksum_address))
|
||||
|
||||
self.assertTrue(is_address(plain_address))
|
||||
self.assertFalse(is_checksum_address(plain_address))
|
||||
self.assertTrue(is_checksum_address(checksum_address))
|
||||
|
||||
self.assertFalse(is_address(plain_address + "00"))
|
||||
self.assertFalse(is_address(plain_address[:len(plain_address)-2]))
|
||||
|
||||
with self.assertRaises(ValueError):
|
||||
to_checksum(plain_address + "00")
|
||||
|
||||
with self.assertRaises(ValueError):
|
||||
to_checksum(plain_address[:len(plain_address)-2])
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
unittest.main()
|
||||
120
tests/test_bloom.py
Normal file
120
tests/test_bloom.py
Normal file
@@ -0,0 +1,120 @@
|
||||
# standard imports
|
||||
import os
|
||||
import unittest
|
||||
import logging
|
||||
|
||||
# local imports
|
||||
from chainlib.eth.unittest.ethtester import EthTesterCase
|
||||
from chainlib.eth.nonce import RPCNonceOracle
|
||||
from chainlib.eth.gas import OverrideGasOracle
|
||||
from chainlib.eth.tx import receipt
|
||||
from chainlib.eth.block import block_by_number
|
||||
from chainlib.eth.log import LogBloom
|
||||
from hexathon import (
|
||||
strip_0x,
|
||||
add_0x,
|
||||
)
|
||||
|
||||
# test imports
|
||||
from tests.contract import TestContract
|
||||
|
||||
script_dir = os.path.realpath(os.path.dirname(__file__))
|
||||
|
||||
logging.basicConfig(level=logging.DEBUG)
|
||||
logg = logging.getLogger()
|
||||
|
||||
#{'blockHash': '0xe657e31045be85cfff8c28af6b4fd6417cace7150c4ebbeb736e638313d8e66d', 'block_hash': '0xe657e31045be85cfff8c28af6b4fd6417cace7150c4ebbeb736e638313d8e66d', 'blockNumber': '0xc1ee5a', 'block_number': '0xc1ee5a', 'contractAddress': None, 'contract_address': None, 'cumulativeGasUsed': '0xbc659', 'cumulative_gas_used': '0xbc659', 'from': '0xf6025e63cee5e436a5f1486e040aeead7e97b745', 'gasUsed': '0x1dddb', 'gas_used': '0x1dddb', 'logs': [
|
||||
|
||||
#{'address': '0x4e58ab12d2051ea2068e78e4fcee7ddee6785848', 'blockHash': '0xe657e31045be85cfff8c28af6b4fd6417cace7150c4ebbeb736e638313d8e66d', 'blockNumber': '0xc1ee5a', 'data': '0x', 'logIndex': '0xd', 'removed': False, 'topics': ['0x92e98423f8adac6e64d0608e519fd1cefb861498385c6dee70d58fc926ddc68c', '0x0000000000000000000000000000000000000000000000000000000005f6aa5a', '0x00000000000000000000000000000000000000000000000000000000000000d6', '0x000000000000000000000000f6025e63cee5e436a5f1486e040aeead7e97b745'], 'transactionHash': '0xd0f039591953d277d55f628694248cb442590fab95ac53fcfb69e9dbba7db97a', 'transactionIndex': '0xe'},
|
||||
|
||||
#{'address': '0x4e58ab12d2051ea2068e78e4fcee7ddee6785848', 'blockHash': '0xe657e31045be85cfff8c28af6b4fd6417cace7150c4ebbeb736e638313d8e66d', 'blockNumber': '0xc1ee5a', 'data': '0x0000000000000000000000000000000000000000000000000000000060d7119f', 'logIndex': '0xe', 'removed': False, 'topics': ['0x0559884fd3a460db3073b7fc896cc77986f16e378210ded43186175bf646fc5f', '0x0000000000000000000000000000000000000000000000000000000005f6aa5a', '0x00000000000000000000000000000000000000000000000000000000000000d6'], 'transactionHash': '0xd0f039591953d277d55f628694248cb442590fab95ac53fcfb69e9dbba7db97a', 'transactionIndex': '0xe'},
|
||||
|
||||
#{'address': '0x4e58ab12d2051ea2068e78e4fcee7ddee6785848', 'blockHash': '0xe657e31045be85cfff8c28af6b4fd6417cace7150c4ebbeb736e638313d8e66d', 'blockNumber': '0xc1ee5a', 'data': '0x', 'logIndex': '0xf', 'removed': False, 'topics': ['0xfe25c73e3b9089fac37d55c4c7efcba6f04af04cebd2fc4d6d7dbb07e1e5234f', '0x0000000000000000000000000000000000000000000000813b65aa80e5770000'], 'transactionHash': '0xd0f039591953d277d55f628694248cb442590fab95ac53fcfb69e9dbba7db97a', 'transactionIndex': '0xe'}]
|
||||
|
||||
#, 'logsBloom': '0x0000000000000000000000000000000000000080000000000000000000c000000000000000408000000000000000000000000000000200080000000000000000100000000000000000000000000000000000000000000200000020000000000000000000000000800000400000000000400000000400000000000400100000000000000000000000000000000000000000000480000000000000000000000000000000000000000000000000008000000000080000000000000000000000000000000000000000000000000000000008000000000000000000000000000000000000000000000000000000000000000000000000000002008000000000000000', 'logs_bloom': '0x0000000000000000000000000000000000000080000000000000000000c000000000000000408000000000000000000000000000000200080000000000000000100000000000000000000000000000000000000000000200000020000000000000000000000000800000400000000000400000000400000000000400100000000000000000000000000000000000000000000480000000000000000000000000000000000000000000000000008000000000080000000000000000000000000000000000000000000000000000000008000000000000000000000000000000000000000000000000000000000000000000000000000002008000000000000000', 'status': '0x1', 'to': '0x4e58ab12d2051ea2068e78e4fcee7ddee6785848', 'transactionHash': '0xd0f039591953d277d55f628694248cb442590fab95ac53fcfb69e9dbba7db97a', 'transaction_hash': '0xd0f039591953d277d55f628694248cb442590fab95ac53fcfb69e9dbba7db97a', 'transactionIndex': '0xe', 'transaction_index': '0xe', 'type': '0x0'}
|
||||
|
||||
|
||||
class BloomTestCase(EthTesterCase):
|
||||
|
||||
def setUp(self):
|
||||
super(BloomTestCase, self).setUp()
|
||||
|
||||
nonce_oracle = RPCNonceOracle(self.accounts[0], conn=self.rpc)
|
||||
c = TestContract(self.chain_spec, signer=self.signer, nonce_oracle=nonce_oracle)
|
||||
(tx_hash, o) = c.constructor(self.accounts[0])
|
||||
r = self.rpc.do(o)
|
||||
o = receipt(tx_hash)
|
||||
r = self.rpc.do(o)
|
||||
self.assertEqual(r['status'], 1)
|
||||
|
||||
self.address = r['contract_address']
|
||||
logg.info('deployed contract on {}'.format(self.address))
|
||||
|
||||
|
||||
def test_log_proof(self):
|
||||
bloom = LogBloom()
|
||||
|
||||
address = bytes.fromhex(strip_0x('0x4e58ab12d2051ea2068e78e4fcee7ddee6785848'))
|
||||
logs = [
|
||||
['0x92e98423f8adac6e64d0608e519fd1cefb861498385c6dee70d58fc926ddc68c', '0x0000000000000000000000000000000000000000000000000000000005f6aa5a', '0x00000000000000000000000000000000000000000000000000000000000000d6', '0x000000000000000000000000f6025e63cee5e436a5f1486e040aeead7e97b745'],
|
||||
['0x0559884fd3a460db3073b7fc896cc77986f16e378210ded43186175bf646fc5f', '0x0000000000000000000000000000000000000000000000000000000005f6aa5a', '0x00000000000000000000000000000000000000000000000000000000000000d6'],
|
||||
['0xfe25c73e3b9089fac37d55c4c7efcba6f04af04cebd2fc4d6d7dbb07e1e5234f', '0x0000000000000000000000000000000000000000000000813b65aa80e5770000'],
|
||||
]
|
||||
|
||||
bloom.add(address)
|
||||
for topics in logs:
|
||||
topics_bytes = []
|
||||
for topic in topics:
|
||||
topic_bytes = bytes.fromhex(strip_0x(topic))
|
||||
bloom.add(topic_bytes)
|
||||
|
||||
log_proof_hex = '0x0000000000000000000000000000000000000080000000000000000000c000000000000000408000000000000000000000000000000200080000000000000000100000000000000000000000000000000000000000000200000020000000000000000000000000800000400000000000400000000400000000000400100000000000000000000000000000000000000000000480000000000000000000000000000000000000000000000000008000000000080000000000000000000000000000000000000000000000000000000008000000000000000000000000000000000000000000000000000000000000000000000000000002008000000000000000'
|
||||
log_proof = bytes.fromhex(strip_0x(log_proof_hex))
|
||||
|
||||
log_proof_bitcount = 0
|
||||
for b in log_proof:
|
||||
for i in range(8):
|
||||
if b & (1 << (7 - i)) > 0:
|
||||
log_proof_bitcount += 1
|
||||
logg.debug('proof log has {} bits set'.format(log_proof_bitcount))
|
||||
|
||||
log_created_bitcount = 0
|
||||
for b in bloom.content:
|
||||
for i in range(8):
|
||||
if b & (1 << (7 - i)) > 0:
|
||||
log_created_bitcount += 1
|
||||
logg.debug('created log has {} bits set'.format(log_created_bitcount))
|
||||
|
||||
logg.debug('log_proof:\n{}'.format(log_proof_hex))
|
||||
logg.debug('log_created:\n{}'.format(add_0x(bloom.content.hex())))
|
||||
for i in range(len(bloom.content)):
|
||||
chk = bloom.content[i] & log_proof[i]
|
||||
if chk != bloom.content[i]:
|
||||
self.fail('mismatch at {}: {} != {}'.format(i, chk, bloom.content[i]))
|
||||
|
||||
|
||||
|
||||
@unittest.skip('pyevm tester produces bogus log blooms')
|
||||
def test_log(self):
|
||||
nonce_oracle = RPCNonceOracle(self.accounts[0], conn=self.rpc)
|
||||
gas_oracle = OverrideGasOracle(limit=50000, conn=self.rpc)
|
||||
c = TestContract(self.chain_spec, signer=self.signer, nonce_oracle=nonce_oracle)
|
||||
b = b'\xee' * 32
|
||||
(tx_hash, o) = c.foo(self.address, self.accounts[0], 42, b.hex())
|
||||
r = self.rpc.do(o)
|
||||
o = receipt(tx_hash)
|
||||
rcpt = self.rpc.do(o)
|
||||
self.assertEqual(rcpt['status'], 1)
|
||||
|
||||
bloom = LogBloom()
|
||||
topic = rcpt['logs'][0]['topics'][0]
|
||||
topic = bytes.fromhex(strip_0x(topic))
|
||||
address = bytes.fromhex(strip_0x(self.address))
|
||||
bloom.add(topic, address)
|
||||
|
||||
o = block_by_number(rcpt['block_number'])
|
||||
r = self.rpc.do(o)
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
unittest.main()
|
||||
38
tests/test_event.py
Normal file
38
tests/test_event.py
Normal file
@@ -0,0 +1,38 @@
|
||||
# standard imports
|
||||
import unittest
|
||||
import logging
|
||||
|
||||
# local imports
|
||||
from chainlib.eth.unittest.ethtester import EthTesterCase
|
||||
from chainlib.eth.contract import (
|
||||
ABIContractLogDecoder,
|
||||
ABIContractType,
|
||||
)
|
||||
|
||||
logging.basicConfig(level=logging.DEBUG)
|
||||
|
||||
|
||||
class TestContractLog(EthTesterCase):
|
||||
|
||||
def test_log(self):
|
||||
dec = ABIContractLogDecoder()
|
||||
dec.topic('TestEventOne')
|
||||
dec.typ(ABIContractType.UINT256)
|
||||
dec.typ(ABIContractType.BYTES32)
|
||||
s = dec.get_method_signature()
|
||||
n = 42
|
||||
topics = [
|
||||
s,
|
||||
n.to_bytes(32, byteorder='big'),
|
||||
]
|
||||
data = [
|
||||
(b'\xee' * 32),
|
||||
]
|
||||
dec.apply(topics, data)
|
||||
o = dec.decode()
|
||||
self.assertEqual(o[0], 42)
|
||||
self.assertEqual(o[1], data[0].hex())
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
unittest.main()
|
||||
26
tests/test_nonce.py
Normal file
26
tests/test_nonce.py
Normal file
@@ -0,0 +1,26 @@
|
||||
# standard imports
|
||||
import os
|
||||
import unittest
|
||||
|
||||
# local imports
|
||||
from chainlib.eth.address import to_checksum_address
|
||||
from chainlib.eth.nonce import OverrideNonceOracle
|
||||
from hexathon import add_0x
|
||||
|
||||
# test imports
|
||||
from tests.base import TestBase
|
||||
|
||||
|
||||
class TestNonce(TestBase):
|
||||
|
||||
def test_nonce(self):
|
||||
addr_bytes = os.urandom(20)
|
||||
addr = add_0x(to_checksum_address(addr_bytes.hex()))
|
||||
n = OverrideNonceOracle(addr, 42)
|
||||
self.assertEqual(n.get_nonce(), 42)
|
||||
self.assertEqual(n.next_nonce(), 42)
|
||||
self.assertEqual(n.next_nonce(), 43)
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
unittest.main()
|
||||
119
tests/test_sign.py
Normal file
119
tests/test_sign.py
Normal file
@@ -0,0 +1,119 @@
|
||||
# standard imports
|
||||
import os
|
||||
import socket
|
||||
import unittest
|
||||
import unittest.mock
|
||||
import logging
|
||||
import json
|
||||
|
||||
# external imports
|
||||
from crypto_dev_signer.eth.transaction import EIP155Transaction
|
||||
from crypto_dev_signer.eth.signer.defaultsigner import ReferenceSigner
|
||||
from crypto_dev_signer.keystore.dict import DictKeystore
|
||||
|
||||
# local imports
|
||||
import chainlib
|
||||
from chainlib.eth.connection import EthUnixSignerConnection
|
||||
from chainlib.eth.sign import sign_transaction
|
||||
from chainlib.eth.tx import TxFactory
|
||||
from chainlib.eth.address import to_checksum_address
|
||||
from chainlib.jsonrpc import (
|
||||
jsonrpc_response,
|
||||
jsonrpc_error,
|
||||
)
|
||||
from hexathon import (
|
||||
add_0x,
|
||||
)
|
||||
from chainlib.chain import ChainSpec
|
||||
|
||||
from tests.base import TestBase
|
||||
|
||||
logging.basicConfig(level=logging.DEBUG)
|
||||
logg = logging.getLogger()
|
||||
|
||||
keystore = DictKeystore()
|
||||
alice = keystore.new()
|
||||
bob = keystore.new()
|
||||
|
||||
|
||||
class Mocket(socket.socket):
|
||||
|
||||
req_id = None
|
||||
error = False
|
||||
tx = None
|
||||
signer = None
|
||||
|
||||
def connect(self, v):
|
||||
return self
|
||||
|
||||
|
||||
def send(self, v):
|
||||
o = json.loads(v)
|
||||
logg.debug('mocket received {}'.format(v))
|
||||
Mocket.req_id = o['id']
|
||||
params = o['params'][0]
|
||||
if to_checksum_address(params.get('from')) != alice:
|
||||
logg.error('from does not match alice {}'.format(params))
|
||||
Mocket.error = True
|
||||
if to_checksum_address(params.get('to')) != bob:
|
||||
logg.error('to does not match bob {}'.format(params))
|
||||
Mocket.error = True
|
||||
if not Mocket.error:
|
||||
Mocket.tx = EIP155Transaction(params, params['nonce'], params['chainId'])
|
||||
logg.debug('mocket {}'.format(Mocket.tx))
|
||||
return len(v)
|
||||
|
||||
|
||||
def recv(self, c):
|
||||
if Mocket.req_id != None:
|
||||
|
||||
o = None
|
||||
if Mocket.error:
|
||||
o = jsonrpc_error(Mocket.req_id)
|
||||
else:
|
||||
tx = Mocket.tx
|
||||
r = Mocket.signer.sign_transaction_to_rlp(tx)
|
||||
Mocket.tx = None
|
||||
o = jsonrpc_response(Mocket.req_id, add_0x(r.hex()))
|
||||
Mocket.req_id = None
|
||||
return json.dumps(o).encode('utf-8')
|
||||
|
||||
return b''
|
||||
|
||||
|
||||
class TestSign(TestBase):
|
||||
|
||||
|
||||
def setUp(self):
|
||||
super(TestSign, self).__init__()
|
||||
self.chain_spec = ChainSpec('evm', 'foo', 42)
|
||||
|
||||
|
||||
logg.debug('alice {}'.format(alice))
|
||||
logg.debug('bob {}'.format(bob))
|
||||
|
||||
self.signer = ReferenceSigner(keystore)
|
||||
|
||||
Mocket.signer = self.signer
|
||||
|
||||
|
||||
def test_sign_build(self):
|
||||
with unittest.mock.patch('chainlib.connection.socket.socket', Mocket) as m:
|
||||
rpc = EthUnixSignerConnection('foo', chain_spec=self.chain_spec)
|
||||
f = TxFactory(self.chain_spec, signer=rpc)
|
||||
tx = f.template(alice, bob, use_nonce=True)
|
||||
tx = f.build(tx)
|
||||
logg.debug('tx result {}'.format(tx))
|
||||
|
||||
|
||||
def test_sign_rpc(self):
|
||||
with unittest.mock.patch('chainlib.connection.socket.socket', Mocket) as m:
|
||||
rpc = EthUnixSignerConnection('foo')
|
||||
f = TxFactory(self.chain_spec, signer=rpc)
|
||||
tx = f.template(alice, bob, use_nonce=True)
|
||||
tx_o = sign_transaction(tx)
|
||||
rpc.do(tx_o)
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
unittest.main()
|
||||
49
tests/test_stat.py
Normal file
49
tests/test_stat.py
Normal file
@@ -0,0 +1,49 @@
|
||||
# standard imports
|
||||
import unittest
|
||||
import datetime
|
||||
|
||||
# external imports
|
||||
from chainlib.stat import ChainStat
|
||||
from chainlib.eth.block import Block
|
||||
|
||||
|
||||
class TestStat(unittest.TestCase):
|
||||
|
||||
def test_block(self):
|
||||
|
||||
s = ChainStat()
|
||||
|
||||
d = datetime.datetime.utcnow() - datetime.timedelta(seconds=30)
|
||||
block_a = Block({
|
||||
'timestamp': d.timestamp(),
|
||||
'hash': None,
|
||||
'transactions': [],
|
||||
'number': 41,
|
||||
})
|
||||
|
||||
d = datetime.datetime.utcnow()
|
||||
block_b = Block({
|
||||
'timestamp': d.timestamp(),
|
||||
'hash': None,
|
||||
'transactions': [],
|
||||
'number': 42,
|
||||
})
|
||||
|
||||
s.block_apply(block_a)
|
||||
s.block_apply(block_b)
|
||||
self.assertEqual(s.block_average(), 30.0)
|
||||
|
||||
d = datetime.datetime.utcnow() + datetime.timedelta(seconds=10)
|
||||
block_c = Block({
|
||||
'timestamp': d.timestamp(),
|
||||
'hash': None,
|
||||
'transactions': [],
|
||||
'number': 43,
|
||||
})
|
||||
|
||||
s.block_apply(block_c)
|
||||
self.assertEqual(s.block_average(), 20.0)
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
unittest.main()
|
||||
79
tests/test_tx.py
Normal file
79
tests/test_tx.py
Normal file
@@ -0,0 +1,79 @@
|
||||
# standard imports
|
||||
import os
|
||||
import unittest
|
||||
import logging
|
||||
|
||||
# local imports
|
||||
from chainlib.eth.unittest.ethtester import EthTesterCase
|
||||
from chainlib.eth.nonce import RPCNonceOracle
|
||||
from chainlib.eth.gas import (
|
||||
RPCGasOracle,
|
||||
Gas,
|
||||
)
|
||||
from chainlib.eth.tx import (
|
||||
unpack,
|
||||
pack,
|
||||
raw,
|
||||
transaction,
|
||||
TxFormat,
|
||||
TxFactory,
|
||||
Tx,
|
||||
)
|
||||
from chainlib.eth.contract import (
|
||||
ABIContractEncoder,
|
||||
ABIContractType,
|
||||
)
|
||||
from chainlib.eth.address import to_checksum_address
|
||||
from hexathon import (
|
||||
strip_0x,
|
||||
add_0x,
|
||||
)
|
||||
|
||||
logging.basicConfig(level=logging.DEBUG)
|
||||
logg = logging.getLogger()
|
||||
|
||||
|
||||
class TxTestCase(EthTesterCase):
|
||||
|
||||
def test_tx_reciprocal(self):
|
||||
nonce_oracle = RPCNonceOracle(self.accounts[0], self.rpc)
|
||||
gas_oracle = RPCGasOracle(self.rpc)
|
||||
c = Gas(signer=self.signer, nonce_oracle=nonce_oracle, gas_oracle=gas_oracle, chain_spec=self.chain_spec)
|
||||
(tx_hash_hex, o) = c.create(self.accounts[0], self.accounts[1], 1024, tx_format=TxFormat.RLP_SIGNED)
|
||||
tx = unpack(bytes.fromhex(strip_0x(o)), self.chain_spec)
|
||||
self.assertEqual(tx['from'], self.accounts[0])
|
||||
self.assertEqual(tx['to'], self.accounts[1])
|
||||
|
||||
|
||||
def test_tx_pack(self):
|
||||
nonce_oracle = RPCNonceOracle(self.accounts[0], self.rpc)
|
||||
gas_oracle = RPCGasOracle(self.rpc)
|
||||
|
||||
mock_contract = to_checksum_address(add_0x(os.urandom(20).hex()))
|
||||
|
||||
f = TxFactory(self.chain_spec, signer=self.rpc)
|
||||
enc = ABIContractEncoder()
|
||||
enc.method('fooMethod')
|
||||
enc.typ(ABIContractType.UINT256)
|
||||
enc.uint256(13)
|
||||
data = enc.get()
|
||||
tx = f.template(self.accounts[0], mock_contract, use_nonce=True)
|
||||
tx = f.set_code(tx, data)
|
||||
(tx_hash, tx_signed_raw_hex) = f.finalize(tx, TxFormat.RLP_SIGNED)
|
||||
logg.debug('tx result {}'.format(tx))
|
||||
o = raw(tx_signed_raw_hex)
|
||||
r = self.rpc.do(o)
|
||||
o = transaction(tx_hash)
|
||||
tx_rpc_src = self.rpc.do(o)
|
||||
logg.debug('rpc src {}'.format(tx_rpc_src))
|
||||
|
||||
tx_signed_raw_bytes = bytes.fromhex(strip_0x(tx_signed_raw_hex))
|
||||
tx_src = unpack(tx_signed_raw_bytes, self.chain_spec)
|
||||
txo = Tx(tx_src)
|
||||
tx_signed_raw_bytes_recovered = pack(txo, self.chain_spec)
|
||||
logg.debug('o {}'.format(tx_signed_raw_bytes.hex()))
|
||||
logg.debug('r {}'.format(tx_signed_raw_bytes_recovered.hex()))
|
||||
self.assertEqual(tx_signed_raw_bytes, tx_signed_raw_bytes_recovered)
|
||||
|
||||
if __name__ == '__main__':
|
||||
unittest.main()
|
||||
@@ -0,0 +1 @@
|
||||
{"address":"eb3907ecad74a0013c259d5874ae7f22dcbcc95c","crypto":{"cipher":"aes-128-ctr","ciphertext":"b0f70a8af4071faff2267374e2423cbc7a71012096fd2215866d8de7445cc215","cipherparams":{"iv":"9ac89383a7793226446dcb7e1b45cdf3"},"kdf":"scrypt","kdfparams":{"dklen":32,"n":262144,"p":1,"r":8,"salt":"299f7b5df1d08a0a7b7f9c9eb44fe4798683b78da3513fcf9603fd913ab3336f"},"mac":"6f4ed36c11345a9a48353cd2f93f1f92958c96df15f3112a192bc994250e8d03"},"id":"61a9dd88-24a9-495c-9a51-152bd1bfaa5b","version":3}
|
||||
Reference in New Issue
Block a user