def generateInvalidUnlockTx(self, userAddress, contractAddress, maliciousAddress): commit, witness, R, S = generate_submarine_commit._generateRS( normalize_address(rec_hex(userAddress)), normalize_address(rec_hex(contractAddress)), UNLOCK_AMOUNT, b'', OURGASPRICE, OURGASLIMIT) unlockFunctionSelector = b"\xec\x9b\x5b\x3a" submarineData = unlockFunctionSelector + commit # need the unsigned TX hash for ECRecover unlock_tx_unsigned_object = transactions.UnsignedTransaction( 0, # nonce; OURGASPRICE, # gasprice OURGASLIMIT, # startgas normalize_address(maliciousAddress), # to addr UNLOCK_AMOUNT, # value submarineData, # data ) unlock_tx_unsigned_hash = sha3( rlp.encode(unlock_tx_unsigned_object, transactions.UnsignedTransaction)) unlock_tx_object = transactions.Transaction( 0, # nonce; OURGASPRICE, # gasprice OURGASLIMIT, # startgas normalize_address(maliciousAddress), # to addr UNLOCK_AMOUNT, # value submarineData, # data 27, # v R, # r S # s ) try: pub = ecrecover_to_pub(unlock_tx_unsigned_hash, 27, R, S) if pub == b"\x00" * 64: log.info("Address no good, retrying") return self.generateInvalidUnlockTx(userAddress, contractAddress, maliciousAddress) else: commit_addr = sha3(pub)[-20:] log.info("Fake Unlock TX Dict: {}".format( unlock_tx_unsigned_object.as_dict())) log.info("Fake Unlock TX Commit B: {}".format(commit_addr)) return unlock_tx_object, unlock_tx_unsigned_object, commit_addr, commit, witness except (ValueError, InvalidTransaction) as e: if isinstance(e, ValueError) and "VRS" not in str(e): raise log.info("Address no good (%s), retrying" % e) return self.generateInvalidUnlockTx(userAddress, contractAddress, maliciousAddress)
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 test_auctionWorkflow(self): ## ## STARTING STATE ## starting_block_height = self.chain.head_state.block_number starting_owner_eth_holdings = self.chain.head_state.get_balance(rec_hex(CONTRACT_OWNER_ADDRESS)) self.chain.mine(1) self.assertTrue(self.erc721_contract.isMinter(CONTRACT_OWNER_ADDRESS)) self.chain.mine(1) self.assertEqual(1, self.erc721_contract.balanceOf(rec_hex(CONTRACT_OWNER_ADDRESS), sender=CONTRACT_OWNER_PRIVATE_KEY)) self.assertEqual(rec_hex(CONTRACT_OWNER_ADDRESS), self.erc721_contract.ownerOf(TOKEN_ID, sender=CONTRACT_OWNER_PRIVATE_KEY)) self.assertEqual(ACCOUNT_STARTING_BALANCE, self.chain.head_state.get_balance(rec_hex(ALICE_ADDRESS))) self.assertEqual(ACCOUNT_STARTING_BALANCE, self.chain.head_state.get_balance(rec_hex(BOB_ADDRESS))) self.assertEqual(ACCOUNT_STARTING_BALANCE, self.chain.head_state.get_balance(rec_hex(CHARLIE_ADDRESS))) self.assertTrue(self.auction_contract.address) self.assertEqual(27, self.auction_contract.vee()) ## ## START THE AUCTION ## (By sending the token to the auction contract, triggering onERC721Received) startAuctionBlock = self.chain.head_state.block_number + 1 endCommitPeriodBlock = self.chain.head_state.block_number + COMMIT_PERIOD_LENGTH onERC721RecievedDataField = encode_single_packed('(uint32,uint32)', [startAuctionBlock, endCommitPeriodBlock]) self.erc721_contract.safeTransferFrom(CONTRACT_OWNER_ADDRESS, self.auction_contract.address, TOKEN_ID, onERC721RecievedDataField, sender=CONTRACT_OWNER_PRIVATE_KEY) self.assertEqual(rec_hex(self.auction_contract.address), self.erc721_contract.ownerOf(TOKEN_ID)) self.assertEqual(rec_hex(CONTRACT_OWNER_ADDRESS), self.auction_contract.seller()) self.assertEqual(startAuctionBlock, self.auction_contract.startBlock()) self.assertEqual(endCommitPeriodBlock, self.auction_contract.endCommitBlock()) self.assertEqual(endCommitPeriodBlock+REVEAL_PERIOD_LENGTH, self.auction_contract.endRevealBlock()) self.assertEqual(TOKEN_ID, self.auction_contract.erc721TokenId()) self.assertEqual(rec_hex(self.erc721_contract.address), self.auction_contract.erc721()) # # GENERATE UNLOCK TXs # commitAddressAlice, commitAlice, witnessAlice, unlock_tx_hexAlice = generate_submarine_commit.generateCommitAddress( normalize_address(rec_hex(ALICE_ADDRESS)), normalize_address(rec_hex(self.auction_contract.address)), BID_AMOUNT_Alice, 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 ) commitAddressBob, commitBob, witnessBob, unlock_tx_hexBob = generate_submarine_commit.generateCommitAddress( normalize_address(rec_hex(BOB_ADDRESS)), normalize_address(rec_hex(self.auction_contract.address)), BID_AMOUNT_Bob, b'', OURGASPRICE, OURGASLIMIT) unlock_tx_infoBob = rlp.decode(rec_bin(unlock_tx_hexBob)) unlock_tx_objectBob = transactions.Transaction( int.from_bytes(unlock_tx_infoBob[0], byteorder="big"), # nonce; int.from_bytes(unlock_tx_infoBob[1], byteorder="big"), # gasprice int.from_bytes(unlock_tx_infoBob[2], byteorder="big"), # startgas unlock_tx_infoBob[3], # to addr int.from_bytes(unlock_tx_infoBob[4], byteorder="big"), # value unlock_tx_infoBob[5], # data int.from_bytes(unlock_tx_infoBob[6], byteorder="big"), # v int.from_bytes(unlock_tx_infoBob[7], byteorder="big"), # r int.from_bytes(unlock_tx_infoBob[8], byteorder="big") # s ) commitAddressCharlie, commitCharlie, witnessCharlie, unlock_tx_hexCharlie = generate_submarine_commit.generateCommitAddress( normalize_address(rec_hex(CHARLIE_ADDRESS)), normalize_address(rec_hex(self.auction_contract.address)), BID_AMOUNT_Charlie, b'', OURGASPRICE, OURGASLIMIT) unlock_tx_infoCharlie = rlp.decode(rec_bin(unlock_tx_hexCharlie)) unlock_tx_objectCharlie = transactions.Transaction( int.from_bytes(unlock_tx_infoCharlie[0], byteorder="big"), # nonce; int.from_bytes(unlock_tx_infoCharlie[1], byteorder="big"), # gasprice int.from_bytes(unlock_tx_infoCharlie[2], byteorder="big"), # startgas unlock_tx_infoCharlie[3], # to addr int.from_bytes(unlock_tx_infoCharlie[4], byteorder="big"), # value unlock_tx_infoCharlie[5], # data int.from_bytes(unlock_tx_infoCharlie[6], byteorder="big"), # v int.from_bytes(unlock_tx_infoCharlie[7], byteorder="big"), # r int.from_bytes(unlock_tx_infoCharlie[8], byteorder="big") # s ) # # GENERATE + BROADCAST COMMIT TXs # commit_tx_objectAlice = transactions.Transaction( 0, OURGASPRICE, BASIC_SEND_GAS_LIMIT, rec_bin(commitAddressAlice), (BID_AMOUNT_Alice + extraTransactionFees), b'').sign(ALICE_PRIVATE_KEY) commit_gasAlice = int(self.chain.head_state.gas_used) self.chain.mine(1) self.chain.direct_tx(commit_tx_objectAlice) self.chain.mine(1) commit_tx_objectBob = transactions.Transaction( 0, OURGASPRICE, BASIC_SEND_GAS_LIMIT, rec_bin(commitAddressBob), (BID_AMOUNT_Bob + extraTransactionFees), b'').sign(BOB_PRIVATE_KEY) commit_gasBob = int(self.chain.head_state.gas_used) self.chain.direct_tx(commit_tx_objectBob) self.chain.mine(1) commit_tx_objectCharlie = transactions.Transaction( 0, OURGASPRICE, BASIC_SEND_GAS_LIMIT, rec_bin(commitAddressCharlie), (BID_AMOUNT_Charlie + extraTransactionFees), b'').sign(CHARLIE_PRIVATE_KEY) commit_gasCharlie = int(self.chain.head_state.gas_used) self.chain.direct_tx(commit_tx_objectCharlie) self.chain.mine(1) ## ## CHECK STATE AFTER COMMIT TX ## commit_block_numberAlice, commit_block_indexAlice = self.chain.chain.get_tx_position( commit_tx_objectAlice) self.assertEqual(BID_AMOUNT_Alice + extraTransactionFees, self.chain.head_state.get_balance(commitAddressAlice)) self.assertEqual( ACCOUNT_STARTING_BALANCE - (BID_AMOUNT_Alice + extraTransactionFees + BASIC_SEND_GAS_LIMIT * OURGASPRICE), self.chain.head_state.get_balance(rec_hex(ALICE_ADDRESS))) session_dataAlice = self.auction_contract.getSubmarineState(rec_bin(commitAlice)) self.assertListEqual(session_dataAlice, [SOLIDITY_NULL_INITIALVAL, SOLIDITY_NULL_INITIALVAL, SOLIDITY_NULL_INITIALVAL, SOLIDITY_NULL_INITIALVAL]) revealedAndUnlocked_boolAlice = self.auction_contract.revealedAndUnlocked(rec_bin(commitAlice)) self.assertFalse( revealedAndUnlocked_boolAlice, "The contract should not be revealedAndUnlocked before it's even begun.") commit_block_numberBob, commit_block_indexBob = self.chain.chain.get_tx_position( commit_tx_objectBob) self.assertEqual(BID_AMOUNT_Bob + extraTransactionFees, self.chain.head_state.get_balance(commitAddressBob)) self.assertEqual( ACCOUNT_STARTING_BALANCE - (BID_AMOUNT_Bob + extraTransactionFees + BASIC_SEND_GAS_LIMIT * OURGASPRICE), self.chain.head_state.get_balance(rec_hex(BOB_ADDRESS))) session_dataBob = self.auction_contract.getSubmarineState(rec_bin(commitBob)) self.assertListEqual(session_dataBob, [SOLIDITY_NULL_INITIALVAL, SOLIDITY_NULL_INITIALVAL, SOLIDITY_NULL_INITIALVAL, SOLIDITY_NULL_INITIALVAL]) revealedAndUnlocked_boolBob = self.auction_contract.revealedAndUnlocked(rec_bin(commitBob)) self.assertFalse( revealedAndUnlocked_boolBob, "The contract should not be revealedAndUnlocked before it's even begun.") commit_block_numberCharlie, commit_block_indexCharlie = self.chain.chain.get_tx_position( commit_tx_objectCharlie) self.assertEqual(BID_AMOUNT_Charlie + extraTransactionFees, self.chain.head_state.get_balance(commitAddressCharlie)) self.assertEqual( ACCOUNT_STARTING_BALANCE - (BID_AMOUNT_Charlie + extraTransactionFees + BASIC_SEND_GAS_LIMIT * OURGASPRICE), self.chain.head_state.get_balance(rec_hex(CHARLIE_ADDRESS))) session_dataCharlie = self.auction_contract.getSubmarineState(rec_bin(commitCharlie)) self.assertListEqual(session_dataCharlie, [SOLIDITY_NULL_INITIALVAL, SOLIDITY_NULL_INITIALVAL, SOLIDITY_NULL_INITIALVAL, SOLIDITY_NULL_INITIALVAL]) revealedAndUnlocked_boolCharlie = self.auction_contract.revealedAndUnlocked(rec_bin(commitCharlie)) self.assertFalse( revealedAndUnlocked_boolCharlie, "The contract should not be revealedAndUnlocked before it's even begun.") ## ## GENERATE AND BROADCAST REVEAL BID TXS ## self.chain.mine(COMMIT_PERIOD_LENGTH + 1) commit_block_objectAlice = self.chain.chain.get_block_by_number(commit_block_numberAlice) proveth_expected_block_format_dictAlice = dict() proveth_expected_block_format_dictAlice['parentHash'] = commit_block_objectAlice['prevhash'] proveth_expected_block_format_dictAlice['sha3Uncles'] = commit_block_objectAlice['uncles_hash'] proveth_expected_block_format_dictAlice['miner'] = commit_block_objectAlice['coinbase'] proveth_expected_block_format_dictAlice['stateRoot'] = commit_block_objectAlice['state_root'] proveth_expected_block_format_dictAlice['transactionsRoot'] = commit_block_objectAlice['tx_list_root'] proveth_expected_block_format_dictAlice['receiptsRoot'] = commit_block_objectAlice['receipts_root'] proveth_expected_block_format_dictAlice['logsBloom'] = commit_block_objectAlice['bloom'] proveth_expected_block_format_dictAlice['difficulty'] = commit_block_objectAlice['difficulty'] proveth_expected_block_format_dictAlice['number'] = commit_block_objectAlice['number'] proveth_expected_block_format_dictAlice['gasLimit'] = commit_block_objectAlice['gas_limit'] proveth_expected_block_format_dictAlice['gasUsed'] = commit_block_objectAlice['gas_used'] proveth_expected_block_format_dictAlice['timestamp'] = commit_block_objectAlice['timestamp'] proveth_expected_block_format_dictAlice['extraData'] = commit_block_objectAlice['extra_data'] proveth_expected_block_format_dictAlice['mixHash'] = commit_block_objectAlice['mixhash'] proveth_expected_block_format_dictAlice['nonce'] = commit_block_objectAlice['nonce'] proveth_expected_block_format_dictAlice['hash'] = commit_block_objectAlice.hash proveth_expected_block_format_dictAlice['uncles'] = [] proveth_expected_block_format_dictAlice['transactions'] = ({ "blockHash": commit_block_objectAlice.hash, "blockNumber": str(hex((commit_block_objectAlice['number']))), "from": checksum_encode(ALICE_ADDRESS), "gas": str(hex(commit_tx_objectAlice['startgas'])), "gasPrice": str(hex(commit_tx_objectAlice['gasprice'])), "hash": rec_hex(commit_tx_objectAlice['hash']), "input": rec_hex(commit_tx_objectAlice['data']), "nonce": str(hex(commit_tx_objectAlice['nonce'])), "to": checksum_encode(commit_tx_objectAlice['to']), "transactionIndex": str(hex(0)), "value": str(hex(commit_tx_objectAlice['value'])), "v": str(hex(commit_tx_objectAlice['v'])), "r": str(hex(commit_tx_objectAlice['r'])), "s": str(hex(commit_tx_objectAlice['s'])) }, ) commit_proof_blobAlice = proveth.generate_proof_blob( proveth_expected_block_format_dictAlice, 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.auction_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) reveal_gasAlice = int(self.chain.head_state.gas_used) self.chain.mine(1) commit_block_objectBob = self.chain.chain.get_block_by_number(commit_block_numberBob) proveth_expected_block_format_dictBob = dict() proveth_expected_block_format_dictBob['parentHash'] = commit_block_objectBob['prevhash'] proveth_expected_block_format_dictBob['sha3Uncles'] = commit_block_objectBob['uncles_hash'] proveth_expected_block_format_dictBob['miner'] = commit_block_objectBob['coinbase'] proveth_expected_block_format_dictBob['stateRoot'] = commit_block_objectBob['state_root'] proveth_expected_block_format_dictBob['transactionsRoot'] = commit_block_objectBob['tx_list_root'] proveth_expected_block_format_dictBob['receiptsRoot'] = commit_block_objectBob['receipts_root'] proveth_expected_block_format_dictBob['logsBloom'] = commit_block_objectBob['bloom'] proveth_expected_block_format_dictBob['difficulty'] = commit_block_objectBob['difficulty'] proveth_expected_block_format_dictBob['number'] = commit_block_objectBob['number'] proveth_expected_block_format_dictBob['gasLimit'] = commit_block_objectBob['gas_limit'] proveth_expected_block_format_dictBob['gasUsed'] = commit_block_objectBob['gas_used'] proveth_expected_block_format_dictBob['timestamp'] = commit_block_objectBob['timestamp'] proveth_expected_block_format_dictBob['extraData'] = commit_block_objectBob['extra_data'] proveth_expected_block_format_dictBob['mixHash'] = commit_block_objectBob['mixhash'] proveth_expected_block_format_dictBob['nonce'] = commit_block_objectBob['nonce'] proveth_expected_block_format_dictBob['hash'] = commit_block_objectBob.hash proveth_expected_block_format_dictBob['uncles'] = [] proveth_expected_block_format_dictBob['transactions'] = ({ "blockHash": commit_block_objectBob.hash, "blockNumber": str(hex((commit_block_objectBob['number']))), "from": checksum_encode(BOB_ADDRESS), "gas": str(hex(commit_tx_objectBob['startgas'])), "gasPrice": str(hex(commit_tx_objectBob['gasprice'])), "hash": rec_hex(commit_tx_objectBob['hash']), "input": rec_hex(commit_tx_objectBob['data']), "nonce": str(hex(commit_tx_objectBob['nonce'])), "to": checksum_encode(commit_tx_objectBob['to']), "transactionIndex": str(hex(0)), "value": str(hex(commit_tx_objectBob['value'])), "v": str(hex(commit_tx_objectBob['v'])), "r": str(hex(commit_tx_objectBob['r'])), "s": str(hex(commit_tx_objectBob['s'])) }, ) commit_proof_blobBob = proveth.generate_proof_blob( proveth_expected_block_format_dictBob, commit_block_indexBob) _unlockExtraData = b'' # In this example we dont have any extra embedded data as part of the unlock TX unlock_tx_unsigned_objectBob = transactions.UnsignedTransaction( int.from_bytes(unlock_tx_infoBob[0], byteorder="big"), # nonce; int.from_bytes(unlock_tx_infoBob[1], byteorder="big"), # gasprice int.from_bytes(unlock_tx_infoBob[2], byteorder="big"), # startgas unlock_tx_infoBob[3], # to addr int.from_bytes(unlock_tx_infoBob[4], byteorder="big"), # value unlock_tx_infoBob[5], # data ) unlock_tx_unsigned_rlpBob = rlp.encode(unlock_tx_unsigned_objectBob, transactions.UnsignedTransaction) self.auction_contract.reveal( commit_block_numberBob, # uint32 _commitBlockNumber, _unlockExtraData, # bytes _commitData, rec_bin(witnessBob), # bytes32 _witness, unlock_tx_unsigned_rlpBob, # bytes _rlpUnlockTxUnsigned, commit_proof_blobBob, # bytes _proofBlob sender=BOB_PRIVATE_KEY) reveal_gasBob = int(self.chain.head_state.gas_used) self.chain.mine(1) commit_block_objectCharlie = self.chain.chain.get_block_by_number(commit_block_numberCharlie) proveth_expected_block_format_dictCharlie = dict() proveth_expected_block_format_dictCharlie['parentHash'] = commit_block_objectCharlie['prevhash'] proveth_expected_block_format_dictCharlie['sha3Uncles'] = commit_block_objectCharlie['uncles_hash'] proveth_expected_block_format_dictCharlie['miner'] = commit_block_objectCharlie['coinbase'] proveth_expected_block_format_dictCharlie['stateRoot'] = commit_block_objectCharlie['state_root'] proveth_expected_block_format_dictCharlie['transactionsRoot'] = commit_block_objectCharlie['tx_list_root'] proveth_expected_block_format_dictCharlie['receiptsRoot'] = commit_block_objectCharlie['receipts_root'] proveth_expected_block_format_dictCharlie['logsBloom'] = commit_block_objectCharlie['bloom'] proveth_expected_block_format_dictCharlie['difficulty'] = commit_block_objectCharlie['difficulty'] proveth_expected_block_format_dictCharlie['number'] = commit_block_objectCharlie['number'] proveth_expected_block_format_dictCharlie['gasLimit'] = commit_block_objectCharlie['gas_limit'] proveth_expected_block_format_dictCharlie['gasUsed'] = commit_block_objectCharlie['gas_used'] proveth_expected_block_format_dictCharlie['timestamp'] = commit_block_objectCharlie['timestamp'] proveth_expected_block_format_dictCharlie['extraData'] = commit_block_objectCharlie['extra_data'] proveth_expected_block_format_dictCharlie['mixHash'] = commit_block_objectCharlie['mixhash'] proveth_expected_block_format_dictCharlie['nonce'] = commit_block_objectCharlie['nonce'] proveth_expected_block_format_dictCharlie['hash'] = commit_block_objectCharlie.hash proveth_expected_block_format_dictCharlie['uncles'] = [] proveth_expected_block_format_dictCharlie['transactions'] = ({ "blockHash": commit_block_objectCharlie.hash, "blockNumber": str(hex((commit_block_objectCharlie['number']))), "from": checksum_encode(CHARLIE_ADDRESS), "gas": str(hex(commit_tx_objectCharlie['startgas'])), "gasPrice": str(hex(commit_tx_objectCharlie['gasprice'])), "hash": rec_hex(commit_tx_objectCharlie['hash']), "input": rec_hex(commit_tx_objectCharlie['data']), "nonce": str(hex(commit_tx_objectCharlie['nonce'])), "to": checksum_encode(commit_tx_objectCharlie['to']), "transactionIndex": str(hex(0)), "value": str(hex(commit_tx_objectCharlie['value'])), "v": str(hex(commit_tx_objectCharlie['v'])), "r": str(hex(commit_tx_objectCharlie['r'])), "s": str(hex(commit_tx_objectCharlie['s'])) }, ) commit_proof_blobCharlie = proveth.generate_proof_blob( proveth_expected_block_format_dictCharlie, commit_block_indexCharlie) _unlockExtraData = b'' # In this example we dont have any extra embedded data as part of the unlock TX unlock_tx_unsigned_objectCharlie = transactions.UnsignedTransaction( int.from_bytes(unlock_tx_infoCharlie[0], byteorder="big"), # nonce; int.from_bytes(unlock_tx_infoCharlie[1], byteorder="big"), # gasprice int.from_bytes(unlock_tx_infoCharlie[2], byteorder="big"), # startgas unlock_tx_infoCharlie[3], # to addr int.from_bytes(unlock_tx_infoCharlie[4], byteorder="big"), # value unlock_tx_infoCharlie[5], # data ) unlock_tx_unsigned_rlpCharlie = rlp.encode(unlock_tx_unsigned_objectCharlie, transactions.UnsignedTransaction) self.auction_contract.reveal( commit_block_numberCharlie, # uint32 _commitBlockNumber, _unlockExtraData, # bytes _commitData, rec_bin(witnessCharlie), # bytes32 _witness, unlock_tx_unsigned_rlpCharlie, # bytes _rlpUnlockTxUnsigned, commit_proof_blobCharlie, # bytes _proofBlob sender=CHARLIE_PRIVATE_KEY) reveal_gasCharlie = int(self.chain.head_state.gas_used) self.chain.mine(1) ## ## CHECK THE STATE AFTER REVEAL ## bidRecordAlice = self.auction_contract.bidders(rec_bin(commitAlice)) self.assertEqual(rec_hex(ALICE_ADDRESS), bidRecordAlice) session_dataAlice = self.auction_contract.getSubmarineState(rec_bin(commitAlice)) self.assertListEqual(session_dataAlice, [BID_AMOUNT_Alice, SOLIDITY_NULL_INITIALVAL, commit_block_numberAlice, commit_block_indexAlice]) revealedAndUnlocked_boolAlice = self.auction_contract.revealedAndUnlocked(rec_bin(commitAlice)) self.assertFalse(revealedAndUnlocked_boolAlice) bidRecordBob = self.auction_contract.bidders(rec_bin(commitBob)) self.assertEqual(rec_hex(BOB_ADDRESS), bidRecordBob) session_dataBob = self.auction_contract.getSubmarineState(rec_bin(commitBob)) self.assertListEqual(session_dataBob, [BID_AMOUNT_Bob, SOLIDITY_NULL_INITIALVAL, commit_block_numberBob, commit_block_indexBob]) revealedAndUnlocked_boolBob = self.auction_contract.revealedAndUnlocked(rec_bin(commitBob)) self.assertFalse(revealedAndUnlocked_boolBob) bidRecordCharlie = self.auction_contract.bidders(rec_bin(commitCharlie)) self.assertEqual(rec_hex(CHARLIE_ADDRESS), bidRecordCharlie) session_dataCharlie = self.auction_contract.getSubmarineState(rec_bin(commitCharlie)) self.assertListEqual(session_dataCharlie, [BID_AMOUNT_Charlie, SOLIDITY_NULL_INITIALVAL, commit_block_numberCharlie, commit_block_indexCharlie]) revealedAndUnlocked_boolCharlie = self.auction_contract.revealedAndUnlocked(rec_bin(commitCharlie)) self.assertFalse(revealedAndUnlocked_boolCharlie) ## ## BROADCAST UNLOCK ## self.chain.mine(1) self.chain.direct_tx(unlock_tx_objectAlice) unlock_gasAlice = int(self.chain.head_state.gas_used) self.chain.mine(1) self.chain.mine(1) self.chain.direct_tx(unlock_tx_objectBob) unlock_gasBob = int(self.chain.head_state.gas_used) self.chain.mine(1) self.chain.mine(1) self.chain.direct_tx(unlock_tx_objectCharlie) unlock_gasCharlie = int(self.chain.head_state.gas_used) self.chain.mine(1) ## ## CHECK STATE AFTER UNLOCK ## # # stuff to help with debugging # # 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()) self.assertEqual( self.chain.head_state.get_balance(commitAddressAlice), (extraTransactionFees - unlock_gasAlice*OURGASPRICE), "Commit address should send along the money and have almost 0 money left." ) self.assertEqual( self.chain.head_state.get_balance(commitAddressBob), (extraTransactionFees - unlock_gasBob*OURGASPRICE), "Commit address should send along the money and have almost 0 money left." ) self.assertEqual( self.chain.head_state.get_balance(commitAddressCharlie), (extraTransactionFees - unlock_gasCharlie*OURGASPRICE), "Commit address should send along the money and have almost 0 money left." ) self.assertEqual( self.chain.head_state.get_balance(self.auction_contract.address), (BID_AMOUNT_Alice + BID_AMOUNT_Bob + BID_AMOUNT_Charlie), "Contract address should have the sum of the bids balance." ) session_dataAlice = self.auction_contract.getSubmarineState(rec_bin(commitAlice)) self.assertListEqual(session_dataAlice, [BID_AMOUNT_Alice, BID_AMOUNT_Alice, commit_block_numberAlice, commit_block_indexAlice]) revealedAndUnlocked_boolAlice = self.auction_contract.revealedAndUnlocked(rec_bin(commitAlice)) self.assertTrue(revealedAndUnlocked_boolAlice) session_dataBob = self.auction_contract.getSubmarineState(rec_bin(commitBob)) self.assertListEqual(session_dataBob, [BID_AMOUNT_Bob, BID_AMOUNT_Bob, commit_block_numberBob, commit_block_indexBob]) revealedAndUnlocked_boolBob = self.auction_contract.revealedAndUnlocked(rec_bin(commitBob)) self.assertTrue(revealedAndUnlocked_boolBob) session_dataCharlie = self.auction_contract.getSubmarineState(rec_bin(commitCharlie)) self.assertListEqual(session_dataCharlie, [BID_AMOUNT_Charlie, BID_AMOUNT_Charlie, commit_block_numberCharlie, commit_block_indexCharlie]) revealedAndUnlocked_boolCharlie = self.auction_contract.revealedAndUnlocked(rec_bin(commitCharlie)) self.assertTrue(revealedAndUnlocked_boolCharlie) ## ## END AUCTION ## self.chain.mine(REVEAL_PERIOD_LENGTH) self.auction_contract.finalize(rec_bin(commitAlice), sender=ALICE_PRIVATE_KEY) self.auction_contract.finalize(rec_bin(commitBob), sender=BOB_PRIVATE_KEY) self.auction_contract.finalize(rec_bin(commitCharlie), sender=CHARLIE_PRIVATE_KEY) # ## # ## CHECK STATE NOW THAT AUCTION IS OVER self.assertEqual(commitCharlie, self.auction_contract.winningSubmarineId().hex()) self.assertEqual( ACCOUNT_STARTING_BALANCE - (extraTransactionFees + BASIC_SEND_GAS_LIMIT * OURGASPRICE), self.chain.head_state.get_balance(rec_hex(ALICE_ADDRESS))) self.assertEqual( ACCOUNT_STARTING_BALANCE - (extraTransactionFees + BASIC_SEND_GAS_LIMIT * OURGASPRICE), self.chain.head_state.get_balance(rec_hex(BOB_ADDRESS))) self.assertEqual( ACCOUNT_STARTING_BALANCE - (BID_AMOUNT_Charlie + extraTransactionFees + BASIC_SEND_GAS_LIMIT * OURGASPRICE), self.chain.head_state.get_balance(rec_hex(CHARLIE_ADDRESS))) self.assertEqual(starting_owner_eth_holdings + BID_AMOUNT_Charlie, self.chain.head_state.get_balance(rec_hex(CONTRACT_OWNER_ADDRESS)))
def test_spam_unlock_large_spam(self): ## ## STARTING STATE ## ALICE_ADDRESS = t.a1 ALICE_PRIVATE_KEY = t.k1 SPAM_PRIVATE_KEY_MALLORY = t.k7 self.chain.mine(1) ## ## GENERATE UNLOCK TX ## addressB, commit, witness, unlock_tx_hex = generate_submarine_commit.generateCommitAddress( normalize_address(rec_hex(ALICE_ADDRESS)), normalize_address(rec_hex(self.verifier_contract.address)), UNLOCK_AMOUNT, b'', OURGASPRICE, OURGASLIMIT) unlock_tx_info = rlp.decode(rec_bin(unlock_tx_hex)) unlock_tx_object = transactions.Transaction( int.from_bytes(unlock_tx_info[0], byteorder="big"), # nonce; int.from_bytes(unlock_tx_info[1], byteorder="big"), # gasprice int.from_bytes(unlock_tx_info[2], byteorder="big"), # startgas unlock_tx_info[3], # to addr int.from_bytes(unlock_tx_info[4], byteorder="big"), # value unlock_tx_info[5], # data int.from_bytes(unlock_tx_info[6], byteorder="big"), # v int.from_bytes(unlock_tx_info[7], byteorder="big"), # r int.from_bytes(unlock_tx_info[8], byteorder="big") # s ) unlock_tx_unsigned_object = transactions.UnsignedTransaction( int.from_bytes(unlock_tx_info[0], byteorder="big"), # nonce; int.from_bytes(unlock_tx_info[1], byteorder="big"), # gasprice int.from_bytes(unlock_tx_info[2], byteorder="big"), # startgas unlock_tx_info[3], # to addr int.from_bytes(unlock_tx_info[4], byteorder="big"), # value unlock_tx_info[5], # data ) unlock_tx_unsigned_rlp = rlp.encode(unlock_tx_unsigned_object, transactions.UnsignedTransaction) ## ## SPAM THE UNLOCK FUNCTION ## SPAM_AMOUNT = UNLOCK_AMOUNT + 3235 spam_tx_object = transactions.Transaction( 0, OURGASPRICE, OURGASLIMIT, normalize_address(rec_hex(self.verifier_contract.address)), SPAM_AMOUNT, unlock_tx_object[5]).sign(SPAM_PRIVATE_KEY_MALLORY) self.chain.direct_tx(spam_tx_object) session_data = self.verifier_contract.getSubmarineState(rec_bin(commit)) self.assertListEqual(session_data, [SOLIDITY_NULL_INITIALVAL, SPAM_AMOUNT, SOLIDITY_NULL_INITIALVAL, SOLIDITY_NULL_INITIALVAL]) self.chain.mine(1) ## ## GENERATE COMMIT ## commit_tx_object = transactions.Transaction( 0, OURGASPRICE, BASIC_SEND_GAS_LIMIT, rec_bin(addressB), (UNLOCK_AMOUNT + extraTransactionFees), b'').sign(ALICE_PRIVATE_KEY) self.chain.direct_tx(commit_tx_object) self.chain.mine(4) session_data = self.verifier_contract.getSubmarineState(rec_bin(commit)) self.assertListEqual(session_data, [SOLIDITY_NULL_INITIALVAL, SPAM_AMOUNT, SOLIDITY_NULL_INITIALVAL, SOLIDITY_NULL_INITIALVAL]) finished_bool = self.verifier_contract.revealedAndUnlocked(rec_bin(commit)) self.assertFalse( finished_bool, "The contract should not be finished until after the reveal.") commit_block_number, commit_block_index = self.chain.chain.get_tx_position(commit_tx_object) ## ## BROADCAST UNLOCK (this should cause an exception since someone else donated money to your cause) ## with self.assertRaises(t.TransactionFailed): self.chain.direct_tx(unlock_tx_object) ## ## CHECK STATE AFTER UNLOCK ## session_data = self.verifier_contract.getSubmarineState(rec_bin(commit)) self.assertListEqual( session_data, [SOLIDITY_NULL_INITIALVAL, SPAM_AMOUNT, SOLIDITY_NULL_INITIALVAL, SOLIDITY_NULL_INITIALVAL], "State does not match expected value after unlock.") finished_bool = self.verifier_contract.revealedAndUnlocked(rec_bin(commit)) self.assertFalse(finished_bool) ## ## GENERATE AND BROADCAST REVEAL TX ## assert (isinstance(witness, str)) commit_block_object = self.chain.chain.get_block_by_number( commit_block_number) log.info("Block information: {}".format( str(commit_block_object.as_dict()))) log.info("Block header: {}".format( str(commit_block_object.as_dict()['header'].as_dict()))) log.info("Block transactions: {}".format( str(commit_block_object.as_dict()['transactions'][0].as_dict()))) proveth_commit_block = proveth_compatible_commit_block(commit_block_object, commit_tx_object) commit_proof_blob = proveth.generate_proof_blob( proveth_commit_block, commit_block_index) log.info("Proof Blob generate by proveth.py: {}".format( rec_hex(commit_proof_blob))) # Solidity Event log listener def _event_listener(llog): log.info('Solidity Event listener log fire: {}'.format(str(llog))) log.info('Solidity Event listener log fire hex: {}'.format( str(rec_hex(llog['data'])))) self.chain.head_state.log_listeners.append(_event_listener) _unlockExtraData = b'' # In this example we dont have any extra embedded data as part of the unlock TX self.chain.mine(20) self.verifier_contract.reveal( #print( commit_block_number, # uint32 _commitBlockNumber, _unlockExtraData, # bytes _commitData, rec_bin(witness), # bytes32 _witness, unlock_tx_unsigned_rlp, # bytes _rlpUnlockTxUnsigned, commit_proof_blob, # bytes _proofBlob sender=ALICE_PRIVATE_KEY) log.info("Reveal TX Gas Used HeadState {}".format( self.chain.head_state.gas_used)) reveal_gas = int(self.chain.head_state.gas_used) self.chain.mine(1) ## ## CHECK STATE AFTER REVEAL TX ## session_data = self.verifier_contract.getSubmarineState(rec_bin(commit)) self.assertListEqual( session_data, [UNLOCK_AMOUNT, SPAM_AMOUNT, commit_block_number, commit_block_index], "After the Reveal, the state should report both revealed and unlocked." ) finished_bool = self.verifier_contract.revealedAndUnlocked(rec_bin(commit)) self.assertTrue( finished_bool, "The contract was unlocked first and then revealed, it should be finished" )
def test_workflow(self): ## ## STARTING STATE ## ALICE_ADDRESS = t.a1 ALICE_PRIVATE_KEY = t.k1 log.info("Contract Address: {}".format( rec_hex(self.verifier_contract.address))) log.info("State: Starting A1 has {} and has address {}".format( self.chain.head_state.get_balance(rec_hex(ALICE_ADDRESS)), rec_hex(ALICE_ADDRESS))) self.chain.mine(1) ## ## GENERATE UNLOCK AND BROADCAST TX, THEN BROADCAST JUST COMMIT TX ## addressB, commit, witness, unlock_tx_hex = generate_submarine_commit.generateCommitAddress( normalize_address(rec_hex(ALICE_ADDRESS)), normalize_address(rec_hex(self.verifier_contract.address)), UNLOCK_AMOUNT, b'', OURGASPRICE, OURGASLIMIT) log.info("Precomputed address of commit target: {}".format(addressB)) assert (isinstance(witness, str)) unlock_tx_info = rlp.decode(rec_bin(unlock_tx_hex)) log.info("Unlock tx hex object: {}".format(rec_hex(unlock_tx_info))) unlock_tx_object = transactions.Transaction( int.from_bytes(unlock_tx_info[0], byteorder="big"), # nonce; int.from_bytes(unlock_tx_info[1], byteorder="big"), # gasprice int.from_bytes(unlock_tx_info[2], byteorder="big"), # startgas unlock_tx_info[3], # to addr int.from_bytes(unlock_tx_info[4], byteorder="big"), # value unlock_tx_info[5], # data int.from_bytes(unlock_tx_info[6], byteorder="big"), # v int.from_bytes(unlock_tx_info[7], byteorder="big"), # r int.from_bytes(unlock_tx_info[8], byteorder="big") # s ) log.info("Unlock tx hash: {}".format(rec_hex(unlock_tx_object.hash))) unlock_tx_unsigned_object = transactions.UnsignedTransaction( int.from_bytes(unlock_tx_info[0], byteorder="big"), # nonce; int.from_bytes(unlock_tx_info[1], byteorder="big"), # gasprice int.from_bytes(unlock_tx_info[2], byteorder="big"), # startgas unlock_tx_info[3], # to addr int.from_bytes(unlock_tx_info[4], byteorder="big"), # value unlock_tx_info[5], # data ) unlock_tx_unsigned_rlp = rlp.encode(unlock_tx_unsigned_object, transactions.UnsignedTransaction) commit_tx_object = transactions.Transaction( 0, OURGASPRICE, BASIC_SEND_GAS_LIMIT, rec_bin(addressB), (UNLOCK_AMOUNT + extraTransactionFees), b'').sign(ALICE_PRIVATE_KEY) log.info("Commit TX Object: {}".format( str(commit_tx_object.to_dict()))) log.info("Commit TX gas used Intrinsic: {}".format( str(commit_tx_object.intrinsic_gas_used))) commit_gas = int(self.chain.head_state.gas_used) self.chain.direct_tx(commit_tx_object) log.info("Commit TX Gas Used HeadState {}".format( self.chain.head_state.gas_used)) self.chain.mine(1) ## ## CHECK STATE AFTER COMMIT TX ## commit_block_number, commit_block_index = self.chain.chain.get_tx_position( commit_tx_object) log.info("Commit Tx block number {} and tx block index {}".format( commit_block_number, commit_block_index)) log.info("State: After commit A1 has {} and has address {}".format( self.chain.head_state.get_balance(rec_hex(ALICE_ADDRESS)), rec_hex(ALICE_ADDRESS))) log.info("State: After commit B has {} and has address {}".format( self.chain.head_state.get_balance(addressB), addressB)) self.assertEqual(UNLOCK_AMOUNT + extraTransactionFees, self.chain.head_state.get_balance(addressB)) self.assertEqual( ACCOUNT_STARTING_BALANCE - (UNLOCK_AMOUNT + extraTransactionFees + BASIC_SEND_GAS_LIMIT * OURGASPRICE), self.chain.head_state.get_balance(rec_hex(ALICE_ADDRESS))) session_data = self.verifier_contract.getSubmarineState(rec_bin(commit)) self.assertListEqual( session_data, [SOLIDITY_NULL_INITIALVAL, SOLIDITY_NULL_INITIALVAL, SOLIDITY_NULL_INITIALVAL, SOLIDITY_NULL_INITIALVAL], "The contract should not know anything about the commit until after it's been revealed... " ) finished_bool = self.verifier_contract.revealedAndUnlocked(rec_bin(commit)) self.assertFalse( finished_bool, "The contract should not be finished before it's even begun.") ## ## GENERATE AND BROADCAST REVEAL TX ## commit_block_object = self.chain.chain.get_block_by_number( commit_block_number) log.info("Block information: {}".format( str(commit_block_object.as_dict()))) log.info("Block header: {}".format( str(commit_block_object.as_dict()['header'].as_dict()))) log.info("Block transactions: {}".format( str(commit_block_object.as_dict()['transactions'][0].as_dict()))) proveth_commit_block = proveth_compatible_commit_block(commit_block_object, commit_tx_object) commit_proof_blob = proveth.generate_proof_blob( proveth_commit_block, commit_block_index) log.info("Proof Blob generate by proveth.py: {}".format( rec_hex(commit_proof_blob))) # Solidity Event log listener def _event_listener(llog): log.info('Solidity Event listener log fire: {}'.format(str(llog))) log.info('Solidity Event listener log fire hex: {}'.format( str(rec_hex(llog['data'])))) self.chain.head_state.log_listeners.append(_event_listener) _unlockExtraData = b'' # In this example we dont have any extra embedded data as part of the unlock TX self.chain.mine(20) self.verifier_contract.reveal( #print( commit_block_number, # uint32 _commitBlockNumber, _unlockExtraData, # bytes _commitData, rec_bin(witness), # bytes32 _witness, unlock_tx_unsigned_rlp, # bytes _rlpUnlockTxUnsigned, commit_proof_blob, # bytes _proofBlob sender=ALICE_PRIVATE_KEY) log.info("Reveal TX Gas Used HeadState {}".format( self.chain.head_state.gas_used)) reveal_gas = int(self.chain.head_state.gas_used) self.chain.mine(1) ## ## CHECK STATE AFTER REVEAL TX ## session_data = self.verifier_contract.getSubmarineState(rec_bin(commit)) self.assertListEqual( session_data, [UNLOCK_AMOUNT, SOLIDITY_NULL_INITIALVAL, commit_block_number, commit_block_index ], "After the Reveal, the state should report revealed but not unlocked." ) finished_bool = self.verifier_contract.revealedAndUnlocked(rec_bin(commit)) self.assertFalse( finished_bool, "The contract is only revealed, not unlocked and therefore finished." ) ## ## BROADCAST UNLOCK ## self.chain.direct_tx(unlock_tx_object) log.info("Unlock TX Gas Used HeadState {}".format( self.chain.head_state.gas_used)) unlock_gas = int(self.chain.head_state.gas_used) ## ## CHECK STATE AFTER UNLOCK ## log.info("State: After unlock B has {} and has address {}".format( self.chain.head_state.get_balance(addressB), addressB)) self.assertLess( self.chain.head_state.get_balance(addressB), UNLOCK_AMOUNT + extraTransactionFees, "Address B should send along the money and have almost 0 money left." ) self.assertEqual( 999998562999979000000000, self.chain.head_state.get_balance(rec_hex(ALICE_ADDRESS))) session_data = self.verifier_contract.getSubmarineState(rec_bin(commit)) self.assertListEqual( session_data, [UNLOCK_AMOUNT, UNLOCK_AMOUNT, commit_block_number, commit_block_index ], "State does not match expected value after unlock.") finished_bool = self.verifier_contract.revealedAndUnlocked(rec_bin(commit)) self.assertTrue(finished_bool, "After unlock, contract should be finished.") sumGas = commit_gas + reveal_gas + unlock_gas log.info("Final Gas Estimation {}".format(str(sumGas)))
def test_auctionWorkflow(self): ## ## STARTING STATE ## starting_block_height = self.chain.head_state.block_number starting_owner_eth_holdings = self.chain.head_state.get_balance( rec_hex(CONTRACT_OWNER_ADDRESS)) self.chain.mine(1) self.assertEqual( ACCOUNT_STARTING_BALANCE, self.chain.head_state.get_balance(rec_hex(ALICE_ADDRESS))) self.assertEqual( ACCOUNT_STARTING_BALANCE, self.chain.head_state.get_balance(rec_hex(BOB_ADDRESS))) self.assertEqual( ACCOUNT_STARTING_BALANCE, self.chain.head_state.get_balance(rec_hex(CHARLIE_ADDRESS))) self.assertEqual(27, self.verifier_contract.vee()) self.assertEqual(COMMIT_PERIOD_LENGTH, self.verifier_contract.commitPeriodLength()) self.assertEqual(REVEAL_PERIOD_LENGTH, self.verifier_contract.revealPeriodLength()) self.assertEqual( starting_block_height + COMMIT_PERIOD_LENGTH + REVEAL_PERIOD_LENGTH, self.verifier_contract.auctionEndBlock()) # # GENERATE UNLOCK TXs # commitAddressAlice, commitAlice, witnessAlice, unlock_tx_hexAlice = generate_submarine_commit.generateCommitAddress( normalize_address(rec_hex(ALICE_ADDRESS)), normalize_address(rec_hex(self.verifier_contract.address)), BID_AMOUNT_Alice, 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 ) commitAddressBob, commitBob, witnessBob, unlock_tx_hexBob = generate_submarine_commit.generateCommitAddress( normalize_address(rec_hex(BOB_ADDRESS)), normalize_address(rec_hex(self.verifier_contract.address)), BID_AMOUNT_Bob, b'', OURGASPRICE, OURGASLIMIT) unlock_tx_infoBob = rlp.decode(rec_bin(unlock_tx_hexBob)) unlock_tx_objectBob = transactions.Transaction( int.from_bytes(unlock_tx_infoBob[0], byteorder="big"), # nonce; int.from_bytes(unlock_tx_infoBob[1], byteorder="big"), # gasprice int.from_bytes(unlock_tx_infoBob[2], byteorder="big"), # startgas unlock_tx_infoBob[3], # to addr int.from_bytes(unlock_tx_infoBob[4], byteorder="big"), # value unlock_tx_infoBob[5], # data int.from_bytes(unlock_tx_infoBob[6], byteorder="big"), # v int.from_bytes(unlock_tx_infoBob[7], byteorder="big"), # r int.from_bytes(unlock_tx_infoBob[8], byteorder="big") # s ) commitAddressCharlie, commitCharlie, witnessCharlie, unlock_tx_hexCharlie = generate_submarine_commit.generateCommitAddress( normalize_address(rec_hex(CHARLIE_ADDRESS)), normalize_address(rec_hex(self.verifier_contract.address)), BID_AMOUNT_Charlie, b'', OURGASPRICE, OURGASLIMIT) unlock_tx_infoCharlie = rlp.decode(rec_bin(unlock_tx_hexCharlie)) unlock_tx_objectCharlie = transactions.Transaction( int.from_bytes(unlock_tx_infoCharlie[0], byteorder="big"), # nonce; int.from_bytes(unlock_tx_infoCharlie[1], byteorder="big"), # gasprice int.from_bytes(unlock_tx_infoCharlie[2], byteorder="big"), # startgas unlock_tx_infoCharlie[3], # to addr int.from_bytes(unlock_tx_infoCharlie[4], byteorder="big"), # value unlock_tx_infoCharlie[5], # data int.from_bytes(unlock_tx_infoCharlie[6], byteorder="big"), # v int.from_bytes(unlock_tx_infoCharlie[7], byteorder="big"), # r int.from_bytes(unlock_tx_infoCharlie[8], byteorder="big") # s ) # # GENERATE + BROADCAST COMMIT TXs # commit_tx_objectAlice = transactions.Transaction( 0, OURGASPRICE, BASIC_SEND_GAS_LIMIT, rec_bin(commitAddressAlice), (BID_AMOUNT_Alice + extraTransactionFees), b'').sign(ALICE_PRIVATE_KEY) commit_gasAlice = int(self.chain.head_state.gas_used) self.chain.direct_tx(commit_tx_objectAlice) self.chain.mine(1) commit_tx_objectBob = transactions.Transaction( 0, OURGASPRICE, BASIC_SEND_GAS_LIMIT, rec_bin(commitAddressBob), (BID_AMOUNT_Bob + extraTransactionFees), b'').sign(BOB_PRIVATE_KEY) commit_gasBob = int(self.chain.head_state.gas_used) self.chain.direct_tx(commit_tx_objectBob) self.chain.mine(1) commit_tx_objectCharlie = transactions.Transaction( 0, OURGASPRICE, BASIC_SEND_GAS_LIMIT, rec_bin(commitAddressCharlie), (BID_AMOUNT_Charlie + extraTransactionFees), b'').sign(CHARLIE_PRIVATE_KEY) commit_gasCharlie = int(self.chain.head_state.gas_used) self.chain.direct_tx(commit_tx_objectCharlie) self.chain.mine(1) ## ## CHECK STATE AFTER COMMIT TX ## commit_block_numberAlice, commit_block_indexAlice = self.chain.chain.get_tx_position( commit_tx_objectAlice) self.assertEqual(BID_AMOUNT_Alice + extraTransactionFees, self.chain.head_state.get_balance(commitAddressAlice)) self.assertEqual( ACCOUNT_STARTING_BALANCE - (BID_AMOUNT_Alice + extraTransactionFees + BASIC_SEND_GAS_LIMIT * OURGASPRICE), self.chain.head_state.get_balance(rec_hex(ALICE_ADDRESS))) session_dataAlice = self.verifier_contract.getCommitState( rec_bin(commitAlice)) self.assertListEqual(session_dataAlice, [ SOLIDITY_NULL_INITIALVAL, SOLIDITY_NULL_INITIALVAL, SOLIDITY_NULL_INITIALVAL, SOLIDITY_NULL_INITIALVAL ]) finished_boolAlice = self.verifier_contract.finished( rec_bin(commitAlice)) self.assertFalse( finished_boolAlice, "The contract should not be finished before it's even begun.") commit_block_numberBob, commit_block_indexBob = self.chain.chain.get_tx_position( commit_tx_objectBob) self.assertEqual(BID_AMOUNT_Bob + extraTransactionFees, self.chain.head_state.get_balance(commitAddressBob)) self.assertEqual( ACCOUNT_STARTING_BALANCE - (BID_AMOUNT_Bob + extraTransactionFees + BASIC_SEND_GAS_LIMIT * OURGASPRICE), self.chain.head_state.get_balance(rec_hex(BOB_ADDRESS))) session_dataBob = self.verifier_contract.getCommitState( rec_bin(commitBob)) self.assertListEqual(session_dataBob, [ SOLIDITY_NULL_INITIALVAL, SOLIDITY_NULL_INITIALVAL, SOLIDITY_NULL_INITIALVAL, SOLIDITY_NULL_INITIALVAL ]) finished_boolBob = self.verifier_contract.finished(rec_bin(commitBob)) self.assertFalse( finished_boolBob, "The contract should not be finished before it's even begun.") commit_block_numberCharlie, commit_block_indexCharlie = self.chain.chain.get_tx_position( commit_tx_objectCharlie) self.assertEqual( BID_AMOUNT_Charlie + extraTransactionFees, self.chain.head_state.get_balance(commitAddressCharlie)) self.assertEqual( ACCOUNT_STARTING_BALANCE - (BID_AMOUNT_Charlie + extraTransactionFees + BASIC_SEND_GAS_LIMIT * OURGASPRICE), self.chain.head_state.get_balance(rec_hex(CHARLIE_ADDRESS))) session_dataCharlie = self.verifier_contract.getCommitState( rec_bin(commitCharlie)) self.assertListEqual(session_dataCharlie, [ SOLIDITY_NULL_INITIALVAL, SOLIDITY_NULL_INITIALVAL, SOLIDITY_NULL_INITIALVAL, SOLIDITY_NULL_INITIALVAL ]) finished_boolCharlie = self.verifier_contract.finished( rec_bin(commitCharlie)) self.assertFalse( finished_boolCharlie, "The contract should not be finished before it's even begun.") ## ## GENERATE AND BROADCAST REVEAL BID TXS ## self.chain.mine(COMMIT_PERIOD_LENGTH) commit_block_objectAlice = self.chain.chain.get_block_by_number( commit_block_numberAlice) proveth_expected_block_format_dictAlice = dict() proveth_expected_block_format_dictAlice[ 'parentHash'] = commit_block_objectAlice['prevhash'] proveth_expected_block_format_dictAlice[ 'sha3Uncles'] = commit_block_objectAlice['uncles_hash'] proveth_expected_block_format_dictAlice[ 'miner'] = commit_block_objectAlice['coinbase'] proveth_expected_block_format_dictAlice[ 'stateRoot'] = commit_block_objectAlice['state_root'] proveth_expected_block_format_dictAlice[ 'transactionsRoot'] = commit_block_objectAlice['tx_list_root'] proveth_expected_block_format_dictAlice[ 'receiptsRoot'] = commit_block_objectAlice['receipts_root'] proveth_expected_block_format_dictAlice[ 'logsBloom'] = commit_block_objectAlice['bloom'] proveth_expected_block_format_dictAlice[ 'difficulty'] = commit_block_objectAlice['difficulty'] proveth_expected_block_format_dictAlice[ 'number'] = commit_block_objectAlice['number'] proveth_expected_block_format_dictAlice[ 'gasLimit'] = commit_block_objectAlice['gas_limit'] proveth_expected_block_format_dictAlice[ 'gasUsed'] = commit_block_objectAlice['gas_used'] proveth_expected_block_format_dictAlice[ 'timestamp'] = commit_block_objectAlice['timestamp'] proveth_expected_block_format_dictAlice[ 'extraData'] = commit_block_objectAlice['extra_data'] proveth_expected_block_format_dictAlice[ 'mixHash'] = commit_block_objectAlice['mixhash'] proveth_expected_block_format_dictAlice[ 'nonce'] = commit_block_objectAlice['nonce'] proveth_expected_block_format_dictAlice[ 'hash'] = commit_block_objectAlice.hash proveth_expected_block_format_dictAlice['uncles'] = [] proveth_expected_block_format_dictAlice['transactions'] = ({ "blockHash": commit_block_objectAlice.hash, "blockNumber": str(hex((commit_block_objectAlice['number']))), "from": checksum_encode(ALICE_ADDRESS), "gas": str(hex(commit_tx_objectAlice['startgas'])), "gasPrice": str(hex(commit_tx_objectAlice['gasprice'])), "hash": rec_hex(commit_tx_objectAlice['hash']), "input": rec_hex(commit_tx_objectAlice['data']), "nonce": str(hex(commit_tx_objectAlice['nonce'])), "to": checksum_encode(commit_tx_objectAlice['to']), "transactionIndex": str(hex(0)), "value": str(hex(commit_tx_objectAlice['value'])), "v": str(hex(commit_tx_objectAlice['v'])), "r": str(hex(commit_tx_objectAlice['r'])), "s": str(hex(commit_tx_objectAlice['s'])) }, ) commit_proof_blobAlice = proveth.generate_proof_blob( proveth_expected_block_format_dictAlice, 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.verifier_contract.revealBid( 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) reveal_gasAlice = int(self.chain.head_state.gas_used) self.chain.mine(1) commit_block_objectBob = self.chain.chain.get_block_by_number( commit_block_numberBob) proveth_expected_block_format_dictBob = dict() proveth_expected_block_format_dictBob[ 'parentHash'] = commit_block_objectBob['prevhash'] proveth_expected_block_format_dictBob[ 'sha3Uncles'] = commit_block_objectBob['uncles_hash'] proveth_expected_block_format_dictBob[ 'miner'] = commit_block_objectBob['coinbase'] proveth_expected_block_format_dictBob[ 'stateRoot'] = commit_block_objectBob['state_root'] proveth_expected_block_format_dictBob[ 'transactionsRoot'] = commit_block_objectBob['tx_list_root'] proveth_expected_block_format_dictBob[ 'receiptsRoot'] = commit_block_objectBob['receipts_root'] proveth_expected_block_format_dictBob[ 'logsBloom'] = commit_block_objectBob['bloom'] proveth_expected_block_format_dictBob[ 'difficulty'] = commit_block_objectBob['difficulty'] proveth_expected_block_format_dictBob[ 'number'] = commit_block_objectBob['number'] proveth_expected_block_format_dictBob[ 'gasLimit'] = commit_block_objectBob['gas_limit'] proveth_expected_block_format_dictBob[ 'gasUsed'] = commit_block_objectBob['gas_used'] proveth_expected_block_format_dictBob[ 'timestamp'] = commit_block_objectBob['timestamp'] proveth_expected_block_format_dictBob[ 'extraData'] = commit_block_objectBob['extra_data'] proveth_expected_block_format_dictBob[ 'mixHash'] = commit_block_objectBob['mixhash'] proveth_expected_block_format_dictBob[ 'nonce'] = commit_block_objectBob['nonce'] proveth_expected_block_format_dictBob[ 'hash'] = commit_block_objectBob.hash proveth_expected_block_format_dictBob['uncles'] = [] proveth_expected_block_format_dictBob['transactions'] = ({ "blockHash": commit_block_objectBob.hash, "blockNumber": str(hex((commit_block_objectBob['number']))), "from": checksum_encode(BOB_ADDRESS), "gas": str(hex(commit_tx_objectBob['startgas'])), "gasPrice": str(hex(commit_tx_objectBob['gasprice'])), "hash": rec_hex(commit_tx_objectBob['hash']), "input": rec_hex(commit_tx_objectBob['data']), "nonce": str(hex(commit_tx_objectBob['nonce'])), "to": checksum_encode(commit_tx_objectBob['to']), "transactionIndex": str(hex(0)), "value": str(hex(commit_tx_objectBob['value'])), "v": str(hex(commit_tx_objectBob['v'])), "r": str(hex(commit_tx_objectBob['r'])), "s": str(hex(commit_tx_objectBob['s'])) }, ) commit_proof_blobBob = proveth.generate_proof_blob( proveth_expected_block_format_dictBob, commit_block_indexBob) _unlockExtraData = b'' # In this example we dont have any extra embedded data as part of the unlock TX unlock_tx_unsigned_objectBob = transactions.UnsignedTransaction( int.from_bytes(unlock_tx_infoBob[0], byteorder="big"), # nonce; int.from_bytes(unlock_tx_infoBob[1], byteorder="big"), # gasprice int.from_bytes(unlock_tx_infoBob[2], byteorder="big"), # startgas unlock_tx_infoBob[3], # to addr int.from_bytes(unlock_tx_infoBob[4], byteorder="big"), # value unlock_tx_infoBob[5], # data ) unlock_tx_unsigned_rlpBob = rlp.encode( unlock_tx_unsigned_objectBob, transactions.UnsignedTransaction) self.verifier_contract.revealBid( commit_block_numberBob, # uint32 _commitBlockNumber, _unlockExtraData, # bytes _commitData, rec_bin(witnessBob), # bytes32 _witness, unlock_tx_unsigned_rlpBob, # bytes _rlpUnlockTxUnsigned, commit_proof_blobBob, # bytes _proofBlob sender=BOB_PRIVATE_KEY) reveal_gasBob = int(self.chain.head_state.gas_used) self.chain.mine(1) commit_block_objectCharlie = self.chain.chain.get_block_by_number( commit_block_numberCharlie) proveth_expected_block_format_dictCharlie = dict() proveth_expected_block_format_dictCharlie[ 'parentHash'] = commit_block_objectCharlie['prevhash'] proveth_expected_block_format_dictCharlie[ 'sha3Uncles'] = commit_block_objectCharlie['uncles_hash'] proveth_expected_block_format_dictCharlie[ 'miner'] = commit_block_objectCharlie['coinbase'] proveth_expected_block_format_dictCharlie[ 'stateRoot'] = commit_block_objectCharlie['state_root'] proveth_expected_block_format_dictCharlie[ 'transactionsRoot'] = commit_block_objectCharlie['tx_list_root'] proveth_expected_block_format_dictCharlie[ 'receiptsRoot'] = commit_block_objectCharlie['receipts_root'] proveth_expected_block_format_dictCharlie[ 'logsBloom'] = commit_block_objectCharlie['bloom'] proveth_expected_block_format_dictCharlie[ 'difficulty'] = commit_block_objectCharlie['difficulty'] proveth_expected_block_format_dictCharlie[ 'number'] = commit_block_objectCharlie['number'] proveth_expected_block_format_dictCharlie[ 'gasLimit'] = commit_block_objectCharlie['gas_limit'] proveth_expected_block_format_dictCharlie[ 'gasUsed'] = commit_block_objectCharlie['gas_used'] proveth_expected_block_format_dictCharlie[ 'timestamp'] = commit_block_objectCharlie['timestamp'] proveth_expected_block_format_dictCharlie[ 'extraData'] = commit_block_objectCharlie['extra_data'] proveth_expected_block_format_dictCharlie[ 'mixHash'] = commit_block_objectCharlie['mixhash'] proveth_expected_block_format_dictCharlie[ 'nonce'] = commit_block_objectCharlie['nonce'] proveth_expected_block_format_dictCharlie[ 'hash'] = commit_block_objectCharlie.hash proveth_expected_block_format_dictCharlie['uncles'] = [] proveth_expected_block_format_dictCharlie['transactions'] = ({ "blockHash": commit_block_objectCharlie.hash, "blockNumber": str(hex((commit_block_objectCharlie['number']))), "from": checksum_encode(CHARLIE_ADDRESS), "gas": str(hex(commit_tx_objectCharlie['startgas'])), "gasPrice": str(hex(commit_tx_objectCharlie['gasprice'])), "hash": rec_hex(commit_tx_objectCharlie['hash']), "input": rec_hex(commit_tx_objectCharlie['data']), "nonce": str(hex(commit_tx_objectCharlie['nonce'])), "to": checksum_encode(commit_tx_objectCharlie['to']), "transactionIndex": str(hex(0)), "value": str(hex(commit_tx_objectCharlie['value'])), "v": str(hex(commit_tx_objectCharlie['v'])), "r": str(hex(commit_tx_objectCharlie['r'])), "s": str(hex(commit_tx_objectCharlie['s'])) }, ) commit_proof_blobCharlie = proveth.generate_proof_blob( proveth_expected_block_format_dictCharlie, commit_block_indexCharlie) _unlockExtraData = b'' # In this example we dont have any extra embedded data as part of the unlock TX unlock_tx_unsigned_objectCharlie = transactions.UnsignedTransaction( int.from_bytes(unlock_tx_infoCharlie[0], byteorder="big"), # nonce; int.from_bytes(unlock_tx_infoCharlie[1], byteorder="big"), # gasprice int.from_bytes(unlock_tx_infoCharlie[2], byteorder="big"), # startgas unlock_tx_infoCharlie[3], # to addr int.from_bytes(unlock_tx_infoCharlie[4], byteorder="big"), # value unlock_tx_infoCharlie[5], # data ) unlock_tx_unsigned_rlpCharlie = rlp.encode( unlock_tx_unsigned_objectCharlie, transactions.UnsignedTransaction) self.verifier_contract.revealBid( commit_block_numberCharlie, # uint32 _commitBlockNumber, _unlockExtraData, # bytes _commitData, rec_bin(witnessCharlie), # bytes32 _witness, unlock_tx_unsigned_rlpCharlie, # bytes _rlpUnlockTxUnsigned, commit_proof_blobCharlie, # bytes _proofBlob sender=CHARLIE_PRIVATE_KEY) reveal_gasCharlie = int(self.chain.head_state.gas_used) self.chain.mine(1) ## ## CHECK THE STATE AFTER REVEAL ## bidListLength = self.verifier_contract.getBidListLength() self.assertEqual( bidListLength, 3, "Number of bids should match the number of participants in the auction" ) bidListItemAlice = self.verifier_contract.BidList(0) self.assertListEqual( ["0x" + ALICE_ADDRESS.hex(), bytearray.fromhex(commitAlice)], bidListItemAlice) session_dataAlice = self.verifier_contract.getCommitState( rec_bin(commitAlice)) self.assertListEqual(session_dataAlice, [ BID_AMOUNT_Alice, SOLIDITY_NULL_INITIALVAL, commit_block_numberAlice, commit_block_indexAlice ]) finished_boolAlice = self.verifier_contract.finished( rec_bin(commitAlice)) self.assertFalse(finished_boolAlice) bidListItemBob = self.verifier_contract.BidList(1) self.assertListEqual( ["0x" + BOB_ADDRESS.hex(), bytearray.fromhex(commitBob)], bidListItemBob) session_dataBob = self.verifier_contract.getCommitState( rec_bin(commitBob)) self.assertListEqual(session_dataBob, [ BID_AMOUNT_Bob, SOLIDITY_NULL_INITIALVAL, commit_block_numberBob, commit_block_indexBob ]) finished_boolBob = self.verifier_contract.finished(rec_bin(commitBob)) self.assertFalse(finished_boolBob) bidListItemCharlie = self.verifier_contract.BidList(2) self.assertListEqual( ["0x" + CHARLIE_ADDRESS.hex(), bytearray.fromhex(commitCharlie)], bidListItemCharlie) session_dataCharlie = self.verifier_contract.getCommitState( rec_bin(commitCharlie)) self.assertListEqual(session_dataCharlie, [ BID_AMOUNT_Charlie, SOLIDITY_NULL_INITIALVAL, commit_block_numberCharlie, commit_block_indexCharlie ]) finished_boolCharlie = self.verifier_contract.finished( rec_bin(commitCharlie)) self.assertFalse(finished_boolCharlie) ## ## BROADCAST UNLOCK ## self.chain.mine(1) self.chain.direct_tx(unlock_tx_objectAlice) unlock_gasAlice = int(self.chain.head_state.gas_used) self.chain.mine(1) self.chain.mine(1) self.chain.direct_tx(unlock_tx_objectBob) unlock_gasBob = int(self.chain.head_state.gas_used) self.chain.mine(1) self.chain.mine(1) self.chain.direct_tx(unlock_tx_objectCharlie) unlock_gasCharlie = int(self.chain.head_state.gas_used) self.chain.mine(1) ## ## CHECK STATE AFTER UNLOCK ## # stuff to help with debugging # 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()) self.assertEqual( self.chain.head_state.get_balance(commitAddressAlice), (extraTransactionFees - unlock_gasAlice * OURGASPRICE), "Commit address should send along the money and have almost 0 money left." ) self.assertEqual( self.chain.head_state.get_balance(commitAddressBob), (extraTransactionFees - unlock_gasBob * OURGASPRICE), "Commit address should send along the money and have almost 0 money left." ) self.assertEqual( self.chain.head_state.get_balance(commitAddressCharlie), (extraTransactionFees - unlock_gasCharlie * OURGASPRICE), "Commit address should send along the money and have almost 0 money left." ) self.assertEqual( self.chain.head_state.get_balance(self.verifier_contract.address), (BID_AMOUNT_Alice + BID_AMOUNT_Bob + BID_AMOUNT_Charlie), "Contract address should have the sum of the bids balance.") session_dataAlice = self.verifier_contract.getCommitState( rec_bin(commitAlice)) self.assertListEqual(session_dataAlice, [ BID_AMOUNT_Alice, BID_AMOUNT_Alice, commit_block_numberAlice, commit_block_indexAlice ]) finished_boolAlice = self.verifier_contract.finished( rec_bin(commitAlice)) self.assertTrue(finished_boolAlice) session_dataBob = self.verifier_contract.getCommitState( rec_bin(commitBob)) self.assertListEqual(session_dataBob, [ BID_AMOUNT_Bob, BID_AMOUNT_Bob, commit_block_numberBob, commit_block_indexBob ]) finished_boolBob = self.verifier_contract.finished(rec_bin(commitBob)) self.assertTrue(finished_boolBob) session_dataCharlie = self.verifier_contract.getCommitState( rec_bin(commitCharlie)) self.assertListEqual(session_dataCharlie, [ BID_AMOUNT_Charlie, BID_AMOUNT_Charlie, commit_block_numberCharlie, commit_block_indexCharlie ]) finished_boolCharlie = self.verifier_contract.finished( rec_bin(commitCharlie)) self.assertTrue(finished_boolCharlie) self.assertFalse(self.verifier_contract.auctionIsOver()) ## ## END AUCTION ## self.chain.mine(REVEAL_PERIOD_LENGTH) self.verifier_contract.endauction(sender=RANDO_ADDRESS_PRIVATE_KEY) ## ## CHECK STATE NOW THAT AUCTION IS OVER self.assertTrue(self.verifier_contract.auctionIsOver()) self.assertEqual(rec_hex(CHARLIE_ADDRESS), self.verifier_contract.dogieOwner()) self.assertEqual( ACCOUNT_STARTING_BALANCE - (extraTransactionFees + BASIC_SEND_GAS_LIMIT * OURGASPRICE), self.chain.head_state.get_balance(rec_hex(ALICE_ADDRESS))) self.assertEqual( ACCOUNT_STARTING_BALANCE - (extraTransactionFees + BASIC_SEND_GAS_LIMIT * OURGASPRICE), self.chain.head_state.get_balance(rec_hex(BOB_ADDRESS))) self.assertEqual( ACCOUNT_STARTING_BALANCE - (BID_AMOUNT_Charlie + extraTransactionFees + BASIC_SEND_GAS_LIMIT * OURGASPRICE), self.chain.head_state.get_balance(rec_hex(CHARLIE_ADDRESS))) self.assertEqual( starting_owner_eth_holdings + BID_AMOUNT_Charlie, self.chain.head_state.get_balance(rec_hex(CONTRACT_OWNER_ADDRESS)))