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_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_fake_unlock_commit_does_not_match_to_address(self): ## ## STARTING STATE ## ALICE_ADDRESS = t.a1 ALICE_PRIVATE_KEY = t.k1 MALICIOUS_ADDRESS = t.a7 self.chain.mine(1) ## ## GENERATE FAKE UNLOCK TX ## unlock_tx_object, unlock_tx_unsigned_object, commit_addr, commit, witness = self.generateInvalidUnlockTx(ALICE_ADDRESS, self.verifier_contract.address, MALICIOUS_ADDRESS) unlock_tx_unsigned_rlp = rlp.encode(unlock_tx_unsigned_object, transactions.UnsignedTransaction) ## ## GENERATE COMMIT ## commit_tx_object = transactions.Transaction( 0, OURGASPRICE, BASIC_SEND_GAS_LIMIT, commit_addr, (UNLOCK_AMOUNT + extraTransactionFees), b'').sign(ALICE_PRIVATE_KEY) self.chain.direct_tx(commit_tx_object) self.chain.mine(4) 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(commit_addr), commit_addr)) log.info("State: After commit C has {} and has address {}".format( self.chain.head_state.get_balance(MALICIOUS_ADDRESS), MALICIOUS_ADDRESS)) afterCommitCommitAddressAmount = UNLOCK_AMOUNT + extraTransactionFees afterCommitAliceAddressAmount = ACCOUNT_STARTING_BALANCE - (UNLOCK_AMOUNT + extraTransactionFees + BASIC_SEND_GAS_LIMIT * OURGASPRICE) self.assertEqual(afterCommitCommitAddressAmount, self.chain.head_state.get_balance(commit_addr)) self.assertEqual(afterCommitAliceAddressAmount, self.chain.head_state.get_balance(rec_hex(ALICE_ADDRESS))) ## ## 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.direct_tx(unlock_tx_object) log.info("State: After unlock A1 has {} and has address {}".format( self.chain.head_state.get_balance(rec_hex(ALICE_ADDRESS)), rec_hex(ALICE_ADDRESS))) log.info("State: After unlock B has {} and has address {}".format( self.chain.head_state.get_balance(commit_addr), commit_addr)) log.info("State: After unlock C has {} and has address {}".format( self.chain.head_state.get_balance(MALICIOUS_ADDRESS), MALICIOUS_ADDRESS)) self.assertLess(self.chain.head_state.get_balance(commit_addr), afterCommitCommitAddressAmount) self.assertGreater(self.chain.head_state.get_balance(rec_hex(MALICIOUS_ADDRESS)), ACCOUNT_STARTING_BALANCE) self.chain.mine(20) ## ## THE REVEAL SHOULD NOW FAIL ## with self.assertRaises(t.TransactionFailed): self.verifier_contract.reveal( commit_block_number, # uint32 _commitBlockNumber, _unlockExtraData, # bytes _commitData, witness, # bytes32 _witness, unlock_tx_unsigned_rlp, # bytes _rlpUnlockTxUnsigned, commit_proof_blob, # bytes _proofBlob sender=ALICE_PRIVATE_KEY )
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)))