def get_transaction(self, txhash): "return (tx, block, index)" blockhash, tx_num_enc = rlp.decode(self.db.get(txhash)) blk = rlp.decode(self.db.get(blockhash), blocks.Block, env=self.env) num = utils.decode_int(tx_num_enc) tx_data = blk.get_transaction(num) return tx_data, blk, num
def load_block_tests(data, db): """Load blocks from json file. :param data: the data from the json file as dictionary :param db: the db in which the blocks will be stored :raises: :exc:`ValueError` if the file contains invalid blocks :raises: :exc:`KeyError` if the file is missing required data fields :returns: a list of blocks in an ephem db """ scanners = ethereum.utils.scanners initial_alloc = {} for address, acct_state in data['pre'].items(): address = ethereum.utils.decode_hex(address) balance = scanners['int256b'](acct_state['balance'][2:]) nonce = scanners['int256b'](acct_state['nonce'][2:]) initial_alloc[address] = { 'balance': balance, 'code': acct_state['code'], 'nonce': nonce, 'storage': acct_state['storage'] } genesis(db, start_alloc=initial_alloc) # builds the state trie genesis_block = rlp.decode(ethereum.utils.decode_hex(data['genesisRLP'][2:]), Block, db=db) blocks = {genesis_block.hash: genesis_block} for blk in data['blocks']: rlpdata = ethereum.utils.decode_hex(blk['rlp'][2:]) assert ethereum.utils.decode_hex(blk['blockHeader']['parentHash']) in blocks parent = blocks[ethereum.utils.decode_hex(blk['blockHeader']['parentHash'])] block = rlp.decode(rlpdata, Block, db=db, parent=parent) blocks[block.hash] = block return sorted(blocks.values(), key=lambda b: b.number)
def load_block_tests(data, db): """Load blocks from json file. :param data: the data from the json file as dictionary :param db: the db in which the blocks will be stored :raises: :exc:`ValueError` if the file contains invalid blocks :raises: :exc:`KeyError` if the file is missing required data fields :returns: a list of blocks in an ephem db """ scanners = ethereum.utils.scanners initial_alloc = {} for address, acct_state in data['pre'].items(): address = ethereum.utils.decode_hex(address) balance = scanners['int256b'](acct_state['balance'][2:]) nonce = scanners['int256b'](acct_state['nonce'][2:]) initial_alloc[address] = { 'balance': balance, 'code': acct_state['code'], 'nonce': nonce, 'storage': acct_state['storage'] } genesis(db, initial_alloc) # builds the state trie genesis_block = rlp.decode(ethereum.utils.decode_hex(data['genesisRLP'][2:]), Block, db=db) blocks = [genesis_block] for blk in data['blocks']: rlpdata = ethereum.utils.decode_hex(blk['rlp'][2:]) blocks.append(rlp.decode(rlpdata, Block, db=db, parent=blocks[-1])) return blocks
def commit_refcount_changes(self, epoch): # Save death row nodes timeout_epoch = epoch + self.ttl try: death_row_nodes = rlp.decode( self._keyValueStorage.get('deathrow:' + str(timeout_epoch))) except BaseException: death_row_nodes = [] for nodekey in self.death_row: refcount, val = rlp.decode( self._keyValueStorage.get(b'r:' + nodekey)) if refcount == ZERO_ENCODED: new_refcount = utils.encode_int( DEATH_ROW_OFFSET + timeout_epoch) self._keyValueStorage.put( b'r:' + nodekey, rlp.encode([new_refcount, val])) if len(self.death_row) > 0: sys.stderr.write('%d nodes marked for pruning during block %d\n' % (len(self.death_row), timeout_epoch)) death_row_nodes.extend(self.death_row) self.death_row = [] self._keyValueStorage.put('deathrow:' + str(timeout_epoch), rlp.encode(death_row_nodes)) # Save journal try: journal = rlp.decode( self._keyValueStorage.get('journal:' + str(epoch))) except BaseException: journal = [] journal.extend(self.journal) self.journal = [] self._keyValueStorage.put('journal:' + str(epoch), rlp.encode(journal))
def add_block(self, block): blockhash = block.hash() if blockhash == GENESIS_H: parent_score = 0 else: try: parent = rlp.decode(self.blockchain.get(block.prevhash)) except: raise Exception("Parent of block not found") parent_score = utils.big_endian_to_int(parent[1]) total_score = utils.int_to_big_endian(block.difficulty + parent_score) self.blockchain.put( blockhash, rlp.encode([block.serialize(), total_score])) try: head = self.blockchain.get('head') head_data = rlp.decode(self.blockchain.get(head)) head_score = utils.big_endian_to_int(head_data[1]) except: head_score = 0 if total_score > head_score: self.head = blockhash self.blockchain.put('head', blockhash) return True return False
def cleanup(self, epoch): try: death_row_node = self._keyValueStorage.get( 'deathrow:' + str(epoch)) except BaseException: death_row_node = rlp.encode([]) death_row_nodes = rlp.decode(death_row_node) pruned = 0 for nodekey in death_row_nodes: try: refcount, val = rlp.decode( self._keyValueStorage.get(b'r:' + nodekey)) if utils.decode_int(refcount) == DEATH_ROW_OFFSET + epoch: self._keyValueStorage.remove(b'r:' + nodekey) pruned += 1 except BaseException: pass sys.stderr.write('%d nodes successfully pruned\n' % pruned) # Delete the deathrow after processing it try: self._keyValueStorage.remove('deathrow:' + str(epoch)) except BaseException: pass # Delete journals that are too old try: self._keyValueStorage.remove('journal:' + str(epoch - self.ttl)) except BaseException: pass
def test_block_serialization_same_db(db): k, v, k2, v2 = accounts() blk = mkquickgenesis({v: {"balance": utils.denoms.ether * 1}}, db) assert blk.hash == rlp.decode(rlp.encode(blk), blocks.Block, env=env(db)).hash store_block(blk) blk2 = mine_next_block(blk) assert blk.hash == rlp.decode(rlp.encode(blk), blocks.Block, env=env(db)).hash assert blk2.hash == rlp.decode(rlp.encode(blk2), blocks.Block, env=env(db)).hash
def test_byte_not_supported_exception(self): sample = "c6827a77c10401" try: rlp.decode(sample.decode('hex')) except: excinfo = py.code.ExceptionInfo() assert "RuntimeError: byte not supported: 198" == excinfo.exconly() else: pytest.fail("RuntimeError not raised")
def lookup(self, node): if not isinstance(node, (str, unicode)): return node elif len(node) == 0: return node elif len(node) < 32: return rlp.decode(node) else: return rlp.decode(self.db.get(node))
def test_serializable(): class Test1(Serializable): fields = ( ('field1', big_endian_int), ('field2', binary), ('field3', List((big_endian_int, binary))) ) class Test2(Serializable): fields = ( ('field1', Test1), ('field2', List((Test1, Test1))), ) t1a_data = (5, 'a', (0, '')) t1b_data = (9, 'b', (2, '')) test1a = Test1(*t1a_data) test1b = Test1(*t1b_data) test2 = Test2(test1a, [test1a, test1b]) # equality assert test1a == test1a assert test1b == test1b assert test2 == test2 assert test1a != test1b assert test1b != test2 assert test2 != test1a with pytest.raises(SerializationError): Test1.serialize(test2) with pytest.raises(SerializationError): Test2.serialize(test1a) with pytest.raises(SerializationError): Test2.serialize(test1b) # inference assert infer_sedes(test1a) == Test1 assert infer_sedes(test1b) == Test1 assert infer_sedes(test2) == Test2 # serialization serial_1a = Test1.serialize(test1a) serial_1b = Test1.serialize(test1b) serial_2 = Test2.serialize(test2) assert serial_1a == [b'\x05', b'a', [b'', b'']] assert serial_1b == [b'\x09', b'b', [b'\x02', b'']] assert serial_2 == [serial_1a, [serial_1a, serial_1b]] # deserialization assert Test1.deserialize(serial_1a) == test1a assert Test1.deserialize(serial_1b) == test1b assert Test2.deserialize(serial_2) == test2 # encoding and decoding assert decode(encode(test1a), Test1) == test1a assert decode(encode(test1b), Test1) == test1b assert decode(encode(test2), Test2) == test2
def get_blocks_from_textdump(data): if '\n' not in data: r = rlp.decode(decode_hex(data)) if len(r[0]) != 3: blocks = [r] else: blocks = r else: blocks = [rlp.decode(decode_hex(ln)) for ln in data.split('\n')] return blocks
def check_db_tightness(trees, db): all_nodes = [] for t in trees: for nd in t.all_nodes(): if nd not in all_nodes: all_nodes.append(nd) if len(db.kv) != len(all_nodes): for k, v in db.kv.items(): if rlp.decode(rlp.decode(v)[1]) not in all_nodes: print(utils.encode_hex(k[2:]), rlp.decode(rlp.decode(v)[1])) raise Exception("unpruned key leak: %d %d" % (len(db.kv), len(all_nodes)))
def pay_fee(self, address, fee, tominer=True): # Subtract fee from sender sender_state = rlp.decode(self.state.get(address)) if not sender_state or sender_state[1] < fee: return False sender_state[1] -= fee self.state.update(address, sender_state) # Pay fee to miner if tominer: miner_state = rlp.decode(self.state.get(self.coinbase)) or [0, 0, 0] miner_state[1] += fee self.state.update(self.coinbase, miner_state) return True
def process_transactions(block,transactions): while len(transactions) > 0: tx = transactions.pop(0) enc = (tx.value, tx.fee, tx.sender.encode('hex'), tx.to.encode('hex')) sys.stderr.write("Attempting to send %d plus fee %d from %s to %s\n" % enc) # Grab data about sender, recipient and miner sdata = rlp.decode(block.state.get(tx.sender)) or [0,0,0] tdata = rlp.decode(block.state.get(tx.to)) or [0,0,0] # Calculate fee if tx.to == '\x00'*20: fee = getfee('newcontractfee') else: fee = getfee('txfee') # Insufficient fee, do nothing if fee > tx.fee: sys.stderr.write("Insufficient fee\n") continue # Too much data, do nothing if len(tx.data) > 256: sys.stderr.write("Too many data items\n") continue if not sdata or sdata[1] < tx.value + tx.fee: sys.stderr.write("Insufficient funds to send fee\n") continue elif tx.nonce != sdata[2] and sdata[0] == 0: sys.stderr.write("Bad nonce\n") continue # Try to send the tx if sdata[0] == 0: sdata[2] += 1 sdata[1] -= (tx.value + tx.fee) block.reward += tx.fee if tx.to != '': tdata[1] += tx.value else: addr = tx.hash()[-20:] adata = rlp.decode(block.state.get(addr)) if adata[2] != '': sys.stderr.write("Contract already exists\n") continue block.state.update(addr,rlp.encode([1,tx.value,''])) contract = block.get_contract(addr) for i in range(len(tx.data)): contract.update(encode(i,256,32),tx.data[i]) block.update_contract(addr) print (sdata, tdata) block.state.update(tx.sender,rlp.encode(sdata)) block.state.update(tx.to,rlp.encode(tdata)) # Evaluate contract if applicable if tdata[0] == 1: eval_contract(block,transactions,tx) sys.stderr.write("tx processed\n")
def decode_payload(cls, rlp_data): log.debug('decoding rlp', size=len(rlp_data)) if isinstance(cls.structure, sedes.CountableList): decoder = cls.structure else: decoder = sedes.List([x[1] for x in cls.structure]) try: data = rlp.decode(str(rlp_data), sedes=decoder) except (AssertionError, rlp.RLPException, TypeError) as e: print repr(rlp.decode(rlp_data)) raise e if isinstance(cls.structure, sedes.CountableList): return data else: # convert to dict return dict((cls.structure[i][0], v) for i, v in enumerate(data))
def test_votinginstruction(): peer, proto, chain, cb_data, cb = setup() height = 1 round = 0 bh = '1' * 32 round_lockset = LockSet(len(validators)) for i, privkey in enumerate(privkeys): if i < len(validators) // 3 + 1: v = VoteBlock(height, 0, bh) else: v = VoteNil(height, 0) v.sign(privkey) round_lockset.add(v) bp = VotingInstruction(height=height, round=1, round_lockset=round_lockset) bp.sign(tester.k0) payload = bp proto.send_votinginstruction(payload) packet = peer.packets.pop() assert len(rlp.decode(packet.payload)) == 1 def list_cb(proto, votinginstruction): cb_data.append((proto, votinginstruction)) proto.receive_votinginstruction_callbacks.append(list_cb) proto._receive_votinginstruction(packet) _p, vi = cb_data.pop() assert vi == bp
def eval(block,transactions,timestamp,coinbase): h = block.hash() # Process all transactions process_transactions(block,transactions) # Pay miner fee miner_state = rlp.decode(block.state.get(block.coinbase)) or [0,0,0] block.number += 1 reward = params['reward'] miner_state[1] += reward for uncle in block.uncles: sib_miner_state = rlp_decode(block.state.get(uncle[3])) sib_miner_state[1] += reward*7/8 block.state.update(uncle[3],sib_miner_state) miner_state[1] += reward/8 block.state.update(block.coinbase,rlp.encode(miner_state)) # Check timestamp if timestamp < block.timestamp or timestamp > int(time.time()) + 3600: raise Exception("timestamp not in valid range!") # Update difficulty if timestamp >= block.timestamp + 42: block.difficulty += int(block.difficulty / 1024) else: block.difficulty -= int(block.difficulty / 1024) block.prevhash = h block.coinbase = coinbase block.transactions = [] block.uncles = [] return block
def test_add_longer_side_chain(db, alt_db): """" Local: L0, L1, L2 Remote: R0, R1, R2, R3 """ k, v, k2, v2 = accounts() # Remote: mine one block blk = mkquickgenesis({v: {"balance": utils.denoms.ether * 1}}, db=db) store_block(blk) remote_blocks = [blk] for i in range(3): tx = get_transaction(nonce=i) blk = mine_next_block(remote_blocks[-1], transactions=[tx]) store_block(blk) remote_blocks.append(blk) # Local: mine two blocks L0 = mkquickgenesis({v: {"balance": utils.denoms.ether * 1}}, db=alt_db) chain = Chain(env=env(L0.db), genesis=L0) tx0 = get_transaction(nonce=0) L1 = mine_next_block(L0, transactions=[tx0]) chain.add_block(L1) tx1 = get_transaction(nonce=1) L2 = mine_next_block(L1, transactions=[tx1]) chain.add_block(L2) # receive serialized remote blocks, newest first rlp_blocks = [rlp.encode(x) for x in remote_blocks] for rlp_block in rlp_blocks: block = blocks.Block.deserialize(rlp.decode(rlp_block), env=chain.env) chain.add_block(block) assert chain.head == remote_blocks[-1]
def get_devp2p_cmd_id(msg: bytes) -> int: """Return the cmd_id for the given devp2p msg. The cmd_id, also known as the payload type, is always the first entry of the RLP, interpreted as an integer. """ return rlp.decode(msg[:1], sedes=rlp.sedes.big_endian_int)
def test_returnten(): s = tester.state() open(filename, 'w').write(mul2_code) c = s.contract(returnten_code) s.send(tester.k0, c, 0) b2 = rlp.decode(rlp.encode(s.block), blocks.Block, db=s.db) assert rlp.encode(b2) == rlp.encode(s.block)
async def get_account( self, block_hash: bytes, address: bytes, cancel_token: CancelToken) -> Account: key = keccak(address) proof = await self._get_proof(cancel_token, block_hash, account_key=b'', key=key) header = await self.get_block_header_by_hash(block_hash, cancel_token) rlp_account = HexaryTrie.get_from_proof(header.state_root, key, proof) return rlp.decode(rlp_account, sedes=Account)
def verify(block, parent): def must_equal(what, a, b): if not a == b: raise VerificationFailed(what, a, '==', b) if not block.timestamp >= parent.timestamp: raise VerificationFailed('timestamp', block.timestamp, '>=', parent.timestamp) if not block.timestamp <= time.time() + 900: raise VerificationFailed('timestamps', block.timestamp, '<=', time.time() + 900) block2 = blocks.Block.init_from_parent(parent, block.coinbase, extra_data=block.extra_data, timestamp=block.timestamp, uncles=block.uncles) must_equal('difficulty', block2.difficulty, block.difficulty) must_equal('gas limit', block2.gas_limit, block.gas_limit) for i in range(block.transaction_count): tx, s, g = rlp.decode( block.transactions.get(rlp.encode(utils.encode_int(i)))) tx = transactions.Transaction.create(tx) if not tx.startgas + block2.gas_used <= block.gas_limit: raise VerificationFailed('gas_limit', tx.startgas + block2.gas_used, '<=', block.gas_limit) apply_transaction(block2, tx) must_equal('tx state root', s, block2.state.root_hash) must_equal('tx gas used', g, utils.encode_int(block2.gas_used)) block2.finalize() must_equal('block state root', block2.state.root_hash, block.state.root_hash) must_equal('block gas used', block2.gas_used, block.gas_used) return True
def _list_transactions(self): # returns [[tx_lst_serialized, state_root, gas_used_encoded],...] txlist = [] for i in range(self.transaction_count): txlist.append(rlp.decode( self.transactions.get(utils.encode_int(i)))) return txlist
def unpack(self, message): """ macSize = 256 / 8 = 32 sigSize = 520 / 8 = 65 headSize = macSize + sigSize = 97 hash, sig, sigdata := buf[:macSize], buf[macSize:headSize], buf[headSize:] shouldhash := crypto.Sha3(buf[macSize:]) """ mdc = message[:32] assert mdc == crypto.sha3(message[32:]) signature = message[32:97] assert len(signature) == 65 signed_data = crypto.sha3(message[97:]) remote_pubkey = crypto.ecdsa_recover(signed_data, signature) assert len(remote_pubkey) == 512 / 8 if not crypto.verify(remote_pubkey, signature, signed_data): raise InvalidSignature() cmd_id = self.decoders['cmd_id'](message[97]) assert cmd_id in self.cmd_id_map.values() payload = rlp.decode(message[98:]) assert isinstance(payload, list) expiration = self.decoders['expiration'](payload.pop()) if time.time() > expiration: raise PacketExpired() return remote_pubkey, cmd_id, payload, mdc
def decompress_db(ins): ins = rlp.decode(ins) vals = [None] * len(ins) def decipher(i): if vals[i] is None: v = ins[i] o = "" pos = 0 while pos < len(v): if v[pos : pos + 2] == magic: if v[pos + 2 : pos + 4] == magic: o += magic else: ind = ord(v[pos + 2]) * 256 + ord(v[pos + 3]) o += hashfunc(decipher(ind)) pos += 4 else: o += v[pos] pos += 1 vals[i] = o return vals[i] for i in range(len(ins)): decipher(i) o = EphemDB() for v in vals: o.put(hashfunc(v), v) return o
def get_transaction(self, txhash): "return (tx, block)" blockhash, tx_num_enc = rlp.decode(self.db.get(txhash)) blk = blocks.get_block(blockhash) num = utils.decode_int(tx_num_enc) tx_data, msr, gas = blk.get_transaction(num) return Transaction.create(tx_data), blk
def test_blocks(): peer, proto, chain, cb_data, cb = setup() gls = genesis_signing_lockset(chain.blocks[0], privkeys[0]) # test blocks chain.mine(n=2) assert len(chain.blocks) == 3 proposals = [create_proposal(b) for b in chain.blocks[1:]] payload = [rlp.encode(p) for p in proposals] proto.send_blockproposals(*payload) packet = peer.packets.pop() assert len(rlp.decode(packet.payload)) == 2 def list_cb(proto, blocks): cb_data.append((proto, blocks)) proto.receive_blockproposals_callbacks.append(list_cb) proto._receive_blockproposals(packet) _p, proposals = cb_data.pop() assert isinstance(proposals, tuple) for proposal in proposals: assert isinstance(proposal, BlockProposal) assert proposal.height == proposal.block.header.number assert isinstance(proposal.block, TransientBlock) assert isinstance(proposal.block.transaction_list, tuple) assert isinstance(proposal.block.uncles, tuple) # assert that transactions and uncles have not been decoded assert len(proposal.block.transaction_list) == 0 assert len(proposal.block.uncles) == 0
def revert_refcount_changes(self, epoch): timeout_epoch = epoch + self.ttl # Delete death row additions try: self.db.delete('deathrow:'+str(timeout_epoch)) except: pass # Revert journal changes try: journal = rlp.decode(self.db.get('journal:'+str(epoch))) for new_refcount, hashkey in journal[::-1]: node_object = rlp.decode(self.db.get(b'r:'+hashkey)) self.db.put(b'r:'+hashkey, rlp.encode([new_refcount, node_object[1]])) except: pass
def get_pending_transaction(self, transaction_hash, transaction_class): try: data = self.db.get(make_transaction_hash_to_data_lookup_key(transaction_hash)) return rlp.decode(data, sedes=transaction_class) except KeyError: raise TransactionNotFound( "Transaction with hash {} not found".format(encode_hex(transaction_hash)))
def test_add_side_chain(db, alt_db): """" Local: L0, L1, L2 add Remote: R0, R1 """ k, v, k2, v2 = accounts() # Remote: mine one block R0 = mkquickgenesis({v: {"balance": utils.denoms.ether * 1}}, db=db) store_block(R0) tx0 = get_transaction(nonce=0) R1 = mine_next_block(R0, transactions=[tx0]) store_block(R1) assert tx0.hash in [x.hash for x in R1.get_transactions()] # Local: mine two blocks L0 = mkquickgenesis({v: {"balance": utils.denoms.ether * 1}}, alt_db) chain = Chain(env=env(L0.db), genesis=L0) tx0 = get_transaction(nonce=0) L1 = mine_next_block(L0, transactions=[tx0]) chain.add_block(L1) tx1 = get_transaction(nonce=1) L2 = mine_next_block(L1, transactions=[tx1]) chain.add_block(L2) # receive serialized remote blocks, newest first rlp_blocks = [rlp.encode(R0), rlp.encode(R1)] for rlp_block in rlp_blocks: block = blocks.Block.deserialize(rlp.decode(rlp_block), env=chain.env) chain.add_block(block) assert L2.hash in chain
def create_transaction_signature(unsigned_txn: BaseTransaction, private_key: datatypes.PrivateKey, chain_id: int=None) -> VRS: transaction_parts = rlp.decode(rlp.encode(unsigned_txn)) if chain_id: transaction_parts_for_signature = ( transaction_parts + [int_to_big_endian(chain_id), b'', b''] ) else: transaction_parts_for_signature = transaction_parts message = rlp.encode(transaction_parts_for_signature) signature = private_key.sign_msg(message) canonical_v, r, s = signature.vrs if chain_id: v = canonical_v + chain_id * 2 + EIP155_CHAIN_ID_OFFSET else: v = canonical_v + V_OFFSET return VRS((v, r, s))
def eth_sign(self, transaction: bytes, keypath: Sequence[int], coin: eth.ETHCoin = eth.ETH) -> bytes: """ transaction should be given as a full rlp encoded eth transaction. """ nonce, gas_price, gas_limit, recipient, value, data, _, _, _ = rlp.decode( transaction) request = eth.ETHRequest() # pylint: disable=no-member request.sign.CopyFrom( eth.ETHSignRequest( coin=coin, keypath=keypath, nonce=nonce, gas_price=gas_price, gas_limit=gas_limit, recipient=recipient, value=value, data=data, )) return self._eth_msg_query(request, expected_response="sign").sign.signature
def test_block_serialization_with_transaction_other_db(): hx = lambda x: encode_hex(x) k, v, k2, v2 = accounts() a_db, b_db = db(), db() # mine two blocks a_blk = mkquickgenesis({v: {"balance": utils.denoms.ether * 1}}, db=a_db) store_block(a_blk) tx = get_transaction() logger.debug('a: state_root before tx %r' % hx(a_blk.state_root)) logger.debug('a: state:\n%s' % utils.dump_state(a_blk.state)) a_blk2 = mine_next_block(a_blk, transactions=[tx]) logger.debug('a: state_root after tx %r' % hx(a_blk2.state_root)) logger.debug('a: state:\n%s' % utils.dump_state(a_blk2.state)) assert tx in a_blk2.get_transactions() store_block(a_blk2) assert tx in a_blk2.get_transactions() logger.debug('preparing receiving chain ---------------------') # receive in other db b_blk = mkquickgenesis({v: {"balance": utils.denoms.ether * 1}}, b_db) store_block(b_blk) assert b_blk.number == 0 assert b_blk == a_blk logger.debug('b: state_root before tx %r' % hx(b_blk.state_root)) logger.debug('starting deserialization of remote block w/ tx') b_blk2 = rlp.decode(rlp.encode(a_blk2), blocks.Block, env=env(b_blk.db)) logger.debug('b: state_root after %r' % hx(b_blk2.state_root)) assert a_blk2.hash == b_blk2.hash assert tx in b_blk2.get_transactions() store_block(b_blk2) assert a_blk2.hash == b_blk2.hash assert tx in b_blk2.get_transactions()
def test_block_to_bx_block__empty_block_success(self): block = Block(mock_eth_messages.get_dummy_block_header(8), [], []) dummy_chain_difficulty = 10 block_msg = NewBlockEthProtocolMessage(None, block, dummy_chain_difficulty) self.assertTrue(block_msg.rawbytes()) internal_new_block_msg = InternalEthBlockInfo.from_new_block_msg( block_msg) bx_block_msg, block_info = self.eth_message_converter.block_to_bx_block( internal_new_block_msg, self.tx_service) self.assertEqual(0, block_info.txn_count) self.assertEqual(convert.bytes_to_hex(block.header.prev_hash), block_info.prev_block_hash) self.assertTrue(bx_block_msg) self.assertIsInstance(bx_block_msg, memoryview) block_offsets = compact_block_short_ids_serializer.get_bx_block_offsets( bx_block_msg) _, short_ids_len = compact_block_short_ids_serializer.deserialize_short_ids_from_buffer( bx_block_msg, block_offsets.short_id_offset) compact_block = rlp.decode( bx_block_msg[block_offsets.block_begin_offset:block_offsets. short_id_offset].tobytes(), CompactBlock) self.assertTrue(compact_block) self.assertIsInstance(compact_block, CompactBlock) self._assert_values_equal(compact_block.header, block.header) self.assertEqual(0, len(compact_block.uncles)) self.assertEqual(0, len(compact_block.transactions)) self.assertEqual(compact_block.chain_difficulty, block_msg.chain_difficulty)
def decode_raw_tx(raw_tx: str): tx_bytes = hex_to_bytes(raw_tx) tx = rlp.decode(tx_bytes, Transaction) hash_tx = Web3.toHex(keccak(tx_bytes)) from_ = w3.eth.account.recover_transaction(raw_tx) to = w3.toChecksumAddress(tx.to) if tx.to else None data = w3.toHex(tx.data) r = hex(tx.r) s = hex(tx.s) chain_id = (tx.v - 35) // 2 if tx.v % 2 else (tx.v - 36) // 2 return { 'txHash': hash_tx, 'from': from_, 'to': to, 'nonce': tx.nonce, 'gas': hex(tx.gas), 'gasPrice': hex(tx.gas_price), 'value': hex(tx.value), 'data': data, 'chainId': chain_id, 'r': r, 's': s, 'v': tx.v }
def verify_independent_transaction_spv_proof(db, proof): _, prevheader, header, index, nodes = rlp.decode(proof) index = utils.decode_int(index) pb = blocks.Block.deserialize_header(prevheader) b = blocks.Block.init_from_header(db, header) b.set_proof_mode(blocks.VERIFYING, nodes) if index != 0: pre_med, pre_gas, _, _ = b.get_receipt(index - 1) else: pre_med, pre_gas = pb['state_root'], '' if utils.sha3(rlp.encode(prevheader)) != b.prevhash: return False b.state_root = pre_med b.gas_used = utils.decode_int(pre_gas) tx = b.get_transaction(index) post_med, post_gas, bloom, logs = b.get_receipt(index) tx = transactions.Transaction.create(tx) o = verify_transaction_spv_proof(b, tx, nodes) if b.state_root == post_med: if b.gas_used == utils.decode_int(post_gas): if [x.serialize() for x in b.logs] == logs: if b.mk_log_bloom() == bloom: return o return False
def apply_transaction(self, transaction): if transaction[0] == '1': return '' tx = rlp.decode(utils.decode_hex(transaction[1:]), Transaction) if tx.prev_block == 0: self.deposit.add(transaction) return tx.hash else: prev_tx = self.db.get_block(tx.prev_block).get_tx_by_uid(tx.uid) if prev_tx is None: raise PreviousTxNotFoundException('failed to apply transaction') if prev_tx.spent: raise TxAlreadySpentException('failed to apply transaction') if prev_tx.amount != tx.amount: raise TxAmountMismatchException('failed to apply transaction') if tx.sig == b'\x00' * 65 or tx.sender != prev_tx.new_owner: raise InvalidTxSignatureException('failed to apply transaction') if self.current_block.get_tx_by_uid(tx.uid): raise TxWithSameUidAlreadyExists('failed to apply transaction') prev_tx.spent = True # Mark the previous tx as spent self.current_block.add_tx(tx) return tx.hash
def get_transaction_by_index( self, block_number: BlockNumber, transaction_index: int, transaction_class: Type[SignedTransactionAPI]) -> SignedTransactionAPI: """ Returns the transaction at the specified `transaction_index` from the block specified by `block_number` from the canonical chain. Raises TransactionNotFound if no block """ try: block_header = self.get_canonical_block_header_by_number(block_number) except HeaderNotFound: raise TransactionNotFound(f"Block {block_number} is not in the canonical chain") transaction_db = HexaryTrie(self.db, root_hash=block_header.transaction_root) encoded_index = rlp.encode(transaction_index) encoded_transaction = transaction_db[encoded_index] if encoded_transaction != b'': return rlp.decode(encoded_transaction, sedes=transaction_class) else: raise TransactionNotFound( f"No transaction is at index {transaction_index} of block {block_number}" )
def process_hex_str(hex_str): ''' : hex_str should be a byte string but if not, we convert it an int : returns state, results mapped into a list of namedtuples ''' if not isinstance(hex_str, bytes): hex_str = int(hex_str, 16) eth_bs = Web3.toBytes(int(hex_str, 16)) eth_txs = rlp.decode(eth_bs) # got to move it into global scope # Ethview = namedtuple('Ethview','key,value,unit') results = [] for tx in zip(TX_KEYS, eth_txs): if tx[1]: results.append( Ethview(tx[0][0], getattr(Web3, tx[0][1])(tx[1]), tx[0][2])) else: results.append(Ethview(tx[0][0], None, None)) return True, results
def _on_data(self): """Try to read P2P messages from the recv buffer. This method reads data from the buffer in a loop. It deserializes, parses and verifies the P2P header, then passes the P2P payload to the on_message callback for processing.""" try: while True: if len(self.recvbuf) < 3: return packet_size = struct.unpack("<L", rzpad(self.recvbuf[:3], 4))[0] if len(self.recvbuf) < 3 + packet_size: return packet_id = self.recvbuf[3] if packet_id != PACKET_HELLO and packet_id != PACKET_DISCONNECT and (not self.had_hello): raise ValueError("bad protocol") payload = self.recvbuf[4:3 + packet_size] self.recvbuf = self.recvbuf[3 + packet_size:] self._log_message("receive", packet_id) if packet_id == PACKET_HELLO: self.on_hello(payload) elif packet_id == PACKET_DISCONNECT: disconnect = rlp.decode(payload, Disconnect) self.on_disconnect(disconnect) elif packet_id == PACKET_PING: self.on_ping() elif packet_id == PACKET_PONG: self.on_pong() elif packet_id == PACKET_PONG: pass else: assert packet_id == PACKET_PROTOCOL self.on_protocol_packet(payload) except Exception as e: logger.exception('Error reading message: ' + repr(e)) raise
def test_from_rlp(Uxxx, byte_length): value = Uxxx(0) assert Uxxx.from_rlp(value.rlp_bytes()) == (value) assert Uxxx(decode(value.rlp_bytes(), big_endian_int)) == value value = Uxxx(1) assert Uxxx.from_rlp(value.rlp_bytes()) == (value) assert Uxxx(decode(value.rlp_bytes(), big_endian_int)) == value value = Uxxx(0x79) assert Uxxx.from_rlp(value.rlp_bytes()) == (value) assert Uxxx(decode(value.rlp_bytes(), big_endian_int)) == value value = Uxxx(255) assert Uxxx.from_rlp(value.rlp_bytes()) == (value) assert Uxxx(decode(value.rlp_bytes(), big_endian_int)) == value value = Uxxx(1000) assert Uxxx.from_rlp(value.rlp_bytes()) == (value) assert Uxxx(decode(value.rlp_bytes(), big_endian_int)) == value value = Uxxx("1000000000000000") assert Uxxx.from_rlp(value.rlp_bytes()) == (value) assert Uxxx(decode(value.rlp_bytes(), big_endian_int)) == value rlpdata = [0x80 + byte_length] + [0xFF for i in range(byte_length)] assert Uxxx.from_rlp(bytes(rlpdata)) == (Uxxx.MAX_VALUE)
def __init__(self, header: bytes, body: bytes): self.header = header self.body = body self.command_id = rlp.decode(self.body[:1], sedes=rlp.sedes.big_endian_int) self.encoded_payload = self.body[1:]
def test_round_trip_text_encoding_and_decoding(value): sedes = Text() encoded = encode(value, sedes=sedes) actual = decode(encoded, sedes=sedes) assert actual == value
def get_block_uncles(self, uncles_hash): validate_word(uncles_hash, title="Uncles Hash") return rlp.decode(self.db.get(uncles_hash), sedes=rlp.sedes.CountableList(BlockHeader))
def get_block_transactions(self, block_header, transaction_class): for encoded_transaction in self._get_block_transaction_data(block_header): yield rlp.decode(encoded_transaction, sedes=transaction_class)
def send_raw_transaction(self, raw_transaction): from ethereum.transactions import Transaction rlp_transaction = rlp.decode(raw_transaction, Transaction) self.evm.direct_tx(rlp_transaction) return self.evm.last_tx.hash
def get_score(self, block_hash): return rlp.decode( self.db.get(make_block_hash_to_score_lookup_key(block_hash)), sedes=rlp.sedes.big_endian_int)
def test_transaction_decode_failure(vm_class, encoded, expected_failure): sedes = vm_class.get_transaction_builder() with pytest.raises(expected_failure): rlp.decode(encoded, sedes=sedes)
def send_raw_transaction(self, raw_transaction): vm = _get_vm_for_block_number(self.chain, "latest") TransactionClass = vm.get_transaction_class() evm_transaction = rlp.decode(raw_transaction, TransactionClass) _insert_transaction_to_pending_block(self.chain, evm_transaction) return evm_transaction.hash
def on_post(self, req, res): LOG.info("v2.eth.SendRawTransaction") session = req.context["session"] request_json = SendRawTransaction.validate(req) raw_tx_hex_list = request_json["raw_tx_hex_list"] # Get TokenList Contract ListContract = Contract.get_contract( "TokenList", config.TOKEN_LIST_CONTRACT_ADDRESS ) # Check token status # NOTE: Check the token status before sending a transaction. for raw_tx_hex in raw_tx_hex_list: try: raw_tx = decode(HexBytes(raw_tx_hex)) to_contract_address = to_checksum_address("0x" + raw_tx[3].hex()) except Exception as err: LOG.info(f"RLP decoding failed: {err}") continue listed_token = session.query(Listing). \ filter(Listing.token_address == to_contract_address). \ first() if listed_token is not None: LOG.info(f"Token Address: {to_contract_address}") token_attribute = ListContract.functions.getTokenByAddress(to_contract_address).call() if token_attribute[1] != "": try: TokenContract = Contract.get_contract(token_attribute[1], to_contract_address) except Exception as err: LOG.warning(f"Could not get token status: {err}") continue if TokenContract.functions.status().call() is False: raise SuspendedTokenError("Token is currently suspended") # Check block synchronization state # NOTE: If the block is out of sync, the nonce is not the correct value. block = session.query(Node).first() if block is None or not block.is_synced: raise ServiceUnavailable("Block synchronization is down") # Send transaction result = [] for i, raw_tx_hex in enumerate(raw_tx_hex_list): # Get the contract address of the execution target. try: raw_tx = decode(HexBytes(raw_tx_hex)) to_contract_address = to_checksum_address("0x" + raw_tx[3].hex()) LOG.info(raw_tx) except Exception as err: result.append({"id": i + 1, "status": 0}) LOG.error(f"RLP decoding failed: {err}") continue # Check that contract is executable executable_contract = session.query(ExecutableContract). \ filter(to_contract_address == ExecutableContract.contract_address). \ first() if executable_contract is None: # If it is not a default contract, return error status. if to_contract_address != config.PAYMENT_GATEWAY_CONTRACT_ADDRESS and \ to_contract_address != config.PERSONAL_INFO_CONTRACT_ADDRESS and \ to_contract_address != config.IBET_SB_EXCHANGE_CONTRACT_ADDRESS and \ to_contract_address != config.IBET_SHARE_EXCHANGE_CONTRACT_ADDRESS and \ to_contract_address != config.IBET_MEMBERSHIP_EXCHANGE_CONTRACT_ADDRESS and \ to_contract_address != config.IBET_CP_EXCHANGE_CONTRACT_ADDRESS: result.append({"id": i + 1, "status": 0}) LOG.error("Not executable") continue # Send raw transaction try: tx_hash = web3.eth.sendRawTransaction(raw_tx_hex) except ValueError as err: result.append({ "id": i + 1, "status": 0, }) LOG.error(f"Send transaction failed: {err}") continue # Handling a transaction execution result try: tx = web3.eth.waitForTransactionReceipt(tx_hash, timeout=config.TRANSACTION_WAIT_TIMEOUT) except TimeExhausted as err: status = 2 # execution success (pending transaction) # Transactions that are not promoted to pending and remain in the queued state # will return an error status. try: from_address = Account.recoverTransaction(raw_tx_hex) except Exception as err: result.append({"id": i + 1, "status": 0}) LOG.error(f"get sender address from signed transaction failed: {err}") continue nonce = int("0x0" if raw_tx[0].hex() == "" else raw_tx[0].hex(), 16) txpool_inspect = GethTxPool.inspect if from_address in txpool_inspect.queued: if str(nonce) in txpool_inspect.queued[from_address]: status = 0 # execution failure result.append({ "id": i + 1, "status": status, }) LOG.warning(f"Transaction receipt timeout: {err}") continue except Exception as err: result.append({ "id": i + 1, "status": 0, }) LOG.error(f"Transaction failed: {err}") continue result.append({ "id": i + 1, "status": tx["status"], }) self.on_success(res, result)
def on_post(self, req, res): LOG.info("v2.eth.SendRawTransactionNoWait") session = req.context["session"] request_json = SendRawTransactionNoWait.validate(req) raw_tx_hex_list = request_json["raw_tx_hex_list"] # Get TokenList Contract ListContract = Contract.get_contract( "TokenList", config.TOKEN_LIST_CONTRACT_ADDRESS ) # Check token status # NOTE: Check the token status before sending a transaction. for raw_tx_hex in raw_tx_hex_list: try: raw_tx = decode(HexBytes(raw_tx_hex)) to_contract_address = to_checksum_address("0x" + raw_tx[3].hex()) except Exception as err: LOG.info(f"RLP decoding failed: {err}") continue listed_token = session.query(Listing). \ filter(Listing.token_address == to_contract_address). \ first() if listed_token is not None: LOG.info(f"Token Address: {to_contract_address}") token_attribute = ListContract.functions.getTokenByAddress(to_contract_address).call() if token_attribute[1] != "": try: TokenContract = Contract.get_contract(token_attribute[1], to_contract_address) except Exception as err: LOG.warning(f"Could not get token status: {err}") continue if TokenContract.functions.status().call() is False: raise SuspendedTokenError("Token is currently suspended") # Check block synchronization state # NOTE: If the block is out of sync, the nonce is not the correct value. node = session.query(Node).first() if node is None or not node.is_synced: raise ServiceUnavailable("Block synchronization is down") # Send transaction result = [] for i, raw_tx_hex in enumerate(raw_tx_hex_list): # Get the contract address of the execution target. try: raw_tx = decode(HexBytes(raw_tx_hex)) to_contract_address = to_checksum_address("0x" + raw_tx[3].hex()) LOG.info(raw_tx) except Exception as err: result.append({"id": i + 1, "status": 0}) LOG.error(f"RLP decoding failed: {err}") continue # Check that contract is executable executable_contract = session.query(ExecutableContract). \ filter(to_contract_address == ExecutableContract.contract_address). \ first() if executable_contract is None: # If it is not a default contract, return error status. if to_contract_address != config.PAYMENT_GATEWAY_CONTRACT_ADDRESS and \ to_contract_address != config.PERSONAL_INFO_CONTRACT_ADDRESS and \ to_contract_address != config.IBET_SB_EXCHANGE_CONTRACT_ADDRESS and \ to_contract_address != config.IBET_SHARE_EXCHANGE_CONTRACT_ADDRESS and \ to_contract_address != config.IBET_MEMBERSHIP_EXCHANGE_CONTRACT_ADDRESS and \ to_contract_address != config.IBET_CP_EXCHANGE_CONTRACT_ADDRESS: result.append({"id": i + 1, "status": 0}) LOG.error("Not executable") continue # Send raw transaction try: transaction_hash = web3.eth.sendRawTransaction(raw_tx_hex) except ValueError as err: result.append({ "id": i + 1, "status": 0, "transaction_hash": None }) LOG.error(f"Send transaction failed: {err}") continue result.append({ "id": i + 1, "status": 1, "transaction_hash": transaction_hash.hex() }) self.on_success(res, result)
def from_base_transaction( cls, transaction: 'BaseTransaction') -> 'BaseTransaction': return rlp.decode(rlp.encode(transaction), sedes=cls)
def test_str(): s = 'Hello World' se = rlp.encode(s) sd = rlp.decode(se) assert b'Hello World' == sd
def test_list(): s = ['Hi', 1, [23, 'Nov']] se = rlp.encode(s) sd = rlp.decode(se) s_ = [b'Hi', b'\x01', [b'\x17', b'Nov']] assert s_ == sd
def test_ExchangeWorkflowBuyTokensWithEth(self): ## ## STARTING STATE ## self.chain.mine(1) self.assertEqual(TOTAL_TOKEN_SUPPLY - TOKEN_AMOUNT_STARTING - BOB_STARTING_TOKEN_AMOUNT, self.token_contract.balanceOf(CONTRACT_OWNER_ADDRESS)) self.assertEqual(TOKEN_AMOUNT_STARTING, self.token_contract.balanceOf(self.exchange_contract.address)) self.assertEqual(ACCOUNT_STARTING_BALANCE - ETH_AMOUNT_STARTING, self.chain.head_state.get_balance(rec_hex(CONTRACT_OWNER_ADDRESS))) self.assertEqual(ACCOUNT_STARTING_BALANCE, self.chain.head_state.get_balance(rec_hex(ALICE_ADDRESS))) self.assertEqual(ETH_AMOUNT_STARTING, self.chain.head_state.get_balance(rec_hex(self.exchange_contract.address))) self.assertEqual(BOB_STARTING_TOKEN_AMOUNT, self.token_contract.balanceOf(BOB_ADDRESS)) self.assertEqual(0, self.token_contract.balanceOf(ALICE_ADDRESS)) self.assertEqual(ETH_AMOUNT_STARTING, self.exchange_contract.ethPool()) self.assertEqual(TOKEN_AMOUNT_STARTING, self.exchange_contract.tokenPool()) self.assertEqual(ETH_AMOUNT_STARTING * TOKEN_AMOUNT_STARTING, self.exchange_contract.invariant()) currentInvariant = ETH_AMOUNT_STARTING * TOKEN_AMOUNT_STARTING self.assertEqual(COMMIT_PERIOD_LENGTH, self.exchange_contract.commitPeriodLength()) ## ## ALICE BUYS TOKENS WITH ETH ## commitAddressAlice, commitAlice, witnessAlice, unlock_tx_hexAlice = generate_submarine_commit.generateCommitAddress( normalize_address(rec_hex(ALICE_ADDRESS)), normalize_address(rec_hex(self.exchange_contract.address)), ALICE_TRADE_AMOUNT, b'', OURGASPRICE, OURGASLIMIT) unlock_tx_infoAlice = rlp.decode(rec_bin(unlock_tx_hexAlice)) unlock_tx_objectAlice = transactions.Transaction( int.from_bytes(unlock_tx_infoAlice[0], byteorder="big"), # nonce; int.from_bytes(unlock_tx_infoAlice[1], byteorder="big"), # gasprice int.from_bytes(unlock_tx_infoAlice[2], byteorder="big"), # startgas unlock_tx_infoAlice[3], # to addr int.from_bytes(unlock_tx_infoAlice[4], byteorder="big"), # value unlock_tx_infoAlice[5], # data int.from_bytes(unlock_tx_infoAlice[6], byteorder="big"), # v int.from_bytes(unlock_tx_infoAlice[7], byteorder="big"), # r int.from_bytes(unlock_tx_infoAlice[8], byteorder="big") # s ) commit_tx_objectAlice = transactions.Transaction( 0, OURGASPRICE, BASIC_SEND_GAS_LIMIT, rec_bin(commitAddressAlice), (ALICE_TRADE_AMOUNT + extraTransactionFees), b'').sign(ALICE_PRIVATE_KEY) self.chain.direct_tx(commit_tx_objectAlice) commit_gasAlice = int(self.chain.head_state.gas_used) self.chain.mine(1) commit_block_numberAlice, commit_block_indexAlice = self.chain.chain.get_tx_position( commit_tx_objectAlice) self.assertEqual(ALICE_TRADE_AMOUNT + extraTransactionFees, self.chain.head_state.get_balance(commitAddressAlice)) self.assertEqual( ACCOUNT_STARTING_BALANCE - (ALICE_TRADE_AMOUNT + extraTransactionFees + BASIC_SEND_GAS_LIMIT * OURGASPRICE), self.chain.head_state.get_balance(rec_hex(ALICE_ADDRESS))) session_dataAlice = self.exchange_contract.getSubmarineState(rec_bin(commitAlice)) self.assertListEqual(session_dataAlice, [SOLIDITY_NULL_INITIALVAL, SOLIDITY_NULL_INITIALVAL, SOLIDITY_NULL_INITIALVAL, SOLIDITY_NULL_INITIALVAL]) finished_boolAlice = self.exchange_contract.revealedAndUnlocked(rec_bin(commitAlice)) self.assertFalse( finished_boolAlice, "The contract should not be finished before it's even begun.") ## ## GENERATE AND BROADCAST REVEAL BID TXS ## self.chain.mine(COMMIT_PERIOD_LENGTH) proveth_commit_blockAlice = proveth_compatible_commit_block( self.chain.chain.get_block_by_number(commit_block_numberAlice), commit_tx_objectAlice, ) commit_proof_blobAlice = proveth.generate_proof_blob( proveth_commit_blockAlice, commit_block_indexAlice) _unlockExtraData = b'' # In this example we dont have any extra embedded data as part of the unlock TX unlock_tx_unsigned_objectAlice = transactions.UnsignedTransaction( int.from_bytes(unlock_tx_infoAlice[0], byteorder="big"), # nonce; int.from_bytes(unlock_tx_infoAlice[1], byteorder="big"), # gasprice int.from_bytes(unlock_tx_infoAlice[2], byteorder="big"), # startgas unlock_tx_infoAlice[3], # to addr int.from_bytes(unlock_tx_infoAlice[4], byteorder="big"), # value unlock_tx_infoAlice[5], # data ) unlock_tx_unsigned_rlpAlice = rlp.encode(unlock_tx_unsigned_objectAlice, transactions.UnsignedTransaction) self.chain.mine(5) self.exchange_contract.reveal( commit_block_numberAlice, # uint32 _commitBlockNumber, _unlockExtraData, # bytes _commitData, rec_bin(witnessAlice), # bytes32 _witness, unlock_tx_unsigned_rlpAlice, # bytes _rlpUnlockTxUnsigned, commit_proof_blobAlice, # bytes _proofBlob sender=ALICE_PRIVATE_KEY, gasprice=OURGASPRICE) reveal_gasAlice = int(self.chain.head_state.gas_used) ## ## BROADCAST UNLOCK ## self.chain.mine(1) self.chain.direct_tx(unlock_tx_objectAlice) self.chain.mine(1) ## ## Call the actual ethToTokenSwap function ## self.exchange_contract.ethToTokenSwap(rec_bin(commitAlice), sender=ALICE_PRIVATE_KEY, gasprice=OURGASPRICE) swapcall_gasAlice = int(self.chain.head_state.gas_used) self.chain.mine(1) # unlock_block_numberAlice, unlock_block_indexAlice = self.chain.chain.get_tx_position( # unlock_tx_objectAlice) # unlock_block_objectAlice = self.chain.chain.get_block_by_number(unlock_block_numberAlice) # print(unlock_block_objectAlice.as_dict()) # print(unlock_block_objectAlice.as_dict()['transactions'][0].as_dict()) # print(unlock_block_objectAlice.as_dict()['header'].as_dict()) ## ## CHECK STATE AFTER TOKEN PURCHASE ## self.assertEqual(ETH_AMOUNT_STARTING+ALICE_TRADE_AMOUNT, self.exchange_contract.ethPool()) self.assertEqual(ETH_AMOUNT_STARTING+ALICE_TRADE_AMOUNT, self.chain.head_state.get_balance(rec_hex(self.exchange_contract.address))) self.assertEqual(ACCOUNT_STARTING_BALANCE - ALICE_TRADE_AMOUNT - (OURGASPRICE*(commit_gasAlice + reveal_gasAlice + swapcall_gasAlice)) - extraTransactionFees, self.chain.head_state.get_balance(rec_hex(ALICE_ADDRESS))) tokens_out = int(TOKEN_AMOUNT_STARTING - (currentInvariant //(ETH_AMOUNT_STARTING + ALICE_TRADE_AMOUNT))) # // floor division self.assertEqual(tokens_out, self.token_contract.balanceOf(ALICE_ADDRESS)) self.assertEqual(TOKEN_AMOUNT_STARTING - tokens_out, self.token_contract.balanceOf(self.exchange_contract.address)) self.assertEqual(TOKEN_AMOUNT_STARTING - tokens_out, self.exchange_contract.tokenPool())
def get_current_block(self): block = self.child_chain.get_current_block() return rlp.decode(utils.decode_hex(block), Block)
def get_storage_data(self, key): if key not in self.storage_cache: v = self.storage_trie.get(utils.encode_int32(key)) self.storage_cache[key] = utils.big_endian_to_int( rlp.decode(v) if v else b"") return self.storage_cache[key]
def get_block(self, blknum): block = self.child_chain.get_block(blknum) return rlp.decode(utils.decode_hex(block), Block)
def _decode_block_header(header_rlp: bytes) -> BlockHeader: return rlp.decode(header_rlp, sedes=BlockHeader)
def get_transaction(self, blknum, txindex): encoded_transaction = self.child_chain.get_transaction(blknum, txindex) return rlp.decode(utils.decode_hex(encoded_transaction), Transaction)