def test_challenge_standard_exit_with_in_flight_exit_tx_should_succeed( ethtester, testlang): # exit cross-spend test, cases 3 and 4 owner, amount = testlang.accounts[0], 100 deposit_id = testlang.deposit(owner, amount) spend_id = testlang.spend_utxo([deposit_id], [owner.key], outputs=[(owner.address, NULL_ADDRESS, amount)]) ife_tx = Transaction(inputs=[decode_utxo_id(spend_id)], outputs=[(owner.address, NULL_ADDRESS, amount)]) ife_tx.sign(0, owner.key) (encoded_spend, encoded_inputs, proofs, signatures) = testlang.get_in_flight_exit_info(None, spend_tx=ife_tx) bond = testlang.root_chain.inFlightExitBond() testlang.root_chain.startInFlightExit(encoded_spend, encoded_inputs, proofs, signatures, value=bond, sender=owner.key) testlang.start_standard_exit(spend_id, owner.key) assert testlang.get_standard_exit(spend_id).amount == 100 exit_id = testlang.get_standard_exit_id(spend_id) # FIXME a proper way of getting encoded body of IFE tx is to get it out of generated events testlang.root_chain.challengeStandardExit(exit_id, ife_tx.encoded, 0, ife_tx.signatures[0]) assert testlang.get_standard_exit(spend_id) == [ NULL_ADDRESS_HEX, NULL_ADDRESS_HEX, 0, 0 ]
def test_should_not_allow_to_withdraw_outputs_from_two_ifes_marked_as_canonical_but_sharing_an_input(testlang, plasma_framework, token): alice, amount_token = testlang.accounts[0], 200 caroline, amount_eth = testlang.accounts[1], 100 deposit_id_token = testlang.deposit_token(alice, token, amount_token) deposit_id_eth = testlang.deposit(caroline, amount_eth) swap_tx_id = testlang.spend_utxo( [deposit_id_token, deposit_id_eth], [alice, caroline], [(alice.address, NULL_ADDRESS, amount_eth), (caroline.address, token.address, amount_token)]) # in-flight transaction not included in Plasma steal_tx = Transaction(inputs=[decode_utxo_id(deposit_id_eth)], outputs=[(caroline.address, NULL_ADDRESS, amount_eth)]) steal_tx.sign(0, caroline, verifying_contract=testlang.root_chain.plasma_framework) testlang.start_in_flight_exit(swap_tx_id) testlang.start_in_flight_exit(None, spend_tx=steal_tx) caroline_token_balance_before = token.balanceOf(caroline.address) caroline_eth_balance_before = testlang.get_balance(caroline) testlang.piggyback_in_flight_exit_output(swap_tx_id, 1, caroline) testlang.piggyback_in_flight_exit_output(None, 0, caroline, spend_tx=steal_tx) testlang.forward_timestamp(2 * MIN_EXIT_PERIOD + 1) testlang.process_exits(token.address, 0, 1) testlang.process_exits(NULL_ADDRESS, 0, 1) # caroline exits with the tokens (previously owned by alice) caroline_token_balance = token.balanceOf(caroline.address) assert caroline_token_balance == caroline_token_balance_before + amount_token # but she can not exit with Eth caroline_eth_balance = testlang.get_balance(caroline) assert caroline_eth_balance == caroline_eth_balance_before
def test_challenge_standard_exit_wrong_oindex_should_fail(testlang): from plasma_core.utils.transactions import decode_utxo_id, encode_utxo_id from plasma_core.transaction import Transaction alice, bob, alice_money, bob_money = testlang.accounts[0], testlang.accounts[1], 10, 90 deposit_id = testlang.deposit(alice, alice_money + bob_money) deposit_blknum, _, _ = decode_utxo_id(deposit_id) utxo = testlang.child_chain.get_transaction(deposit_id) spend_tx = Transaction(*decode_utxo_id(deposit_id), 0, 0, 0, utxo.cur12, alice.address, alice_money, bob.address, bob_money) spend_tx.sign1(alice.key) blknum = testlang.submit_block([spend_tx]) alice_utxo = encode_utxo_id(blknum, 0, 0) bob_utxo = encode_utxo_id(blknum, 0, 1) testlang.start_standard_exit(alice, alice_utxo) bob_spend_id = testlang.spend_utxo(bob_utxo, bob, bob_money, bob) alice_spend_id = testlang.spend_utxo(alice_utxo, alice, alice_money, alice) with pytest.raises(TransactionFailed): testlang.challenge_standard_exit(alice_utxo, bob_spend_id) testlang.challenge_standard_exit(alice_utxo, alice_spend_id)
def test_not_canonial_in_flight_exit_processed_successfully(testlang, plasma_framework): owner, deposit_1_amount, deposit_2_amount = testlang.accounts[0], 100, 200 deposit_id_1 = testlang.deposit(owner, deposit_1_amount) deposit_id_2 = testlang.deposit(owner, deposit_2_amount) starting_vault_balance = testlang.get_balance(plasma_framework.eth_vault) amount_spent = 100 spend_deposit_2_id = testlang.spend_utxo([deposit_id_2], [owner], outputs=[(owner.address, NULL_ADDRESS, amount_spent)]) testlang.start_standard_exit(spend_deposit_2_id, account=owner) testlang.forward_timestamp(2 * MIN_EXIT_PERIOD + 1) testlang.process_exits(NULL_ADDRESS, 0, 1) vault_balance = testlang.get_balance(plasma_framework.eth_vault) assert vault_balance == starting_vault_balance - amount_spent # in-flight transaction not included in Plasma inputs = [decode_utxo_id(deposit_id_1), decode_utxo_id(deposit_id_2)] spend_deposits_tx = Transaction(inputs=inputs, outputs=[(owner.address, NULL_ADDRESS, deposit_2_amount + deposit_1_amount)]) for i in range(0, len(inputs)): spend_deposits_tx.sign(i, owner, verifying_contract=testlang.root_chain.plasma_framework) testlang.start_in_flight_exit(None, spend_tx=spend_deposits_tx) testlang.piggyback_in_flight_exit_input(None, 0, owner, spend_tx=spend_deposits_tx) testlang.challenge_in_flight_exit_not_canonical(None, spend_deposit_2_id, account=owner, in_flight_tx=spend_deposits_tx) testlang.forward_timestamp(2 * MIN_EXIT_PERIOD + 1) testlang.process_exits(NULL_ADDRESS, 0, 1) vault_balance = testlang.get_balance(plasma_framework.eth_vault) # deposit 1 is withdrawn assert vault_balance == starting_vault_balance - amount_spent - deposit_1_amount
def test_challenge_standard_exit_wrong_oindex_should_fail(testlang): from plasma_core.utils.transactions import decode_utxo_id, encode_utxo_id from plasma_core.transaction import Transaction alice, bob, alice_money, bob_money = testlang.accounts[ 0], testlang.accounts[1], 10, 90 deposit_id = testlang.deposit(alice, alice_money + bob_money) deposit_blknum, _, _ = decode_utxo_id(deposit_id) spend_tx = Transaction(inputs=[decode_utxo_id(deposit_id)], outputs=[(alice.address, NULL_ADDRESS, alice_money), (bob.address, NULL_ADDRESS, bob_money)]) spend_tx.sign(0, alice.key) blknum = testlang.submit_block([spend_tx]) alice_utxo = encode_utxo_id(blknum, 0, 0) bob_utxo = encode_utxo_id(blknum, 0, 1) testlang.start_standard_exit(alice_utxo, alice.key) bob_spend_id = testlang.spend_utxo([bob_utxo], [bob.key], outputs=[(bob.address, NULL_ADDRESS, bob_money)]) alice_spend_id = testlang.spend_utxo([alice_utxo], [alice.key], outputs=[(alice.address, NULL_ADDRESS, alice_money)]) with pytest.raises(TransactionFailed): testlang.challenge_standard_exit(alice_utxo, bob_spend_id) testlang.challenge_standard_exit(alice_utxo, alice_spend_id)
def spend_utxo(self, utxo_id, new_owner, amount, signer): """Creates a spending transaction and inserts it into the chain. Args: utxo_id (int): Identifier of the UTXO to spend. new_owner (EthereumAccount): Account to own the output of this spend. amount (int): Amount to spend. signer (EthereumAccount): Account to sign this transaction. Returns: int: Unique identifier of the spend. """ spend_tx = Transaction(*decode_utxo_id(utxo_id), 0, 0, 0, NULL_ADDRESS, new_owner.address, amount, NULL_ADDRESS, 0) spend_tx.sign1(signer.key) blknum = self.root_chain.currentChildBlock() block = Block(transaction_set=[spend_tx], number=blknum) block.sign(self.operator.key) self.root_chain.submitBlock(block.root) self.child_chain.add_block(block) return encode_utxo_id(blknum, 0, 0)
def set_dict(self, **num): print("set test") print("Data type of argument:", type(num)) for key, value in num.items(): print("{} is {}".format(key, value)) #self.root_chain.deposit(transact={'from': owner, 'value': amount}) mapping = {} mapping.update(num) for key, value in mapping.items(): print("{} is {}".format(key, value)) #convert dict to binary string bin_mapping = pickle.dumps(mapping) blknum = self.chain.next_deposit_block new_block = Block(None, blknum, NULL_SIGNATURE) new_block.add_mapping(mapping) self.chain.add_block(new_block) print("Number {} {}".format(new_block.number, self.chain.next_deposit_block)) tx = Transaction( blknum, 0, 0, 0, 0, 0, utils.normalize_address(0x0), utils.normalize_address( '0xfd02EcEE62797e75D86BCff1642EB0844afB28c7'), 1, utils.normalize_address(NULL_ADDRESS), 1, NULL_SIGNATURE, NULL_SIGNATURE, 0, bin_mapping) key1 = '3bb369fecdc16b93b99514d8ed9c2e87c5824cf4a6a98d2e8e91b7dd0c063304' print("Data type of key1:", type(key1)) tx.sign1(utils.normalize_key(key1)) self.current_block.add_transaction(tx) print("Added {}".format(self.current_block.transaction_set[0])) print("Added {}".format(self.current_block.transaction_set[0].mapping)) self.chain.set_dict(**num)
def spend_utxo(self, input_ids, keys, outputs=[], force_invalid=False): inputs = [decode_utxo_id(input_id) for input_id in input_ids] spend_tx = Transaction(inputs=inputs, outputs=outputs) for i in range(0, len(inputs)): spend_tx.sign(i, keys[i]) blknum = self.submit_block([spend_tx], force_invalid=force_invalid) spend_id = encode_utxo_id(blknum, 0, 0) return spend_id
def test_get_output(plasma_core_test): null = '0x0000000000000000000000000000000000000000' owner = b'0x82a978b3f5962a5b0957d9ee9eef472ee55b42f1' amount = 100 tx = Transaction(outputs=[(owner, null, amount)]) tx = Transaction(outputs=[(owner, null, amount)]) assert plasma_core_test.getOutput( tx.encoded, 0) == [owner.decode("utf-8"), null, amount] assert plasma_core_test.getOutput(tx.encoded, 1) == [null, null, 0]
def test_decode_mallability(testlang, plasma_core_test): owner, amount = testlang.accounts[0], 100 null = '0x0000000000000000000000000000000000000000' tx = Transaction(outputs=[(owner.address, null, amount)]) tx.sign(0, owner.key) import rlp encoded_with_signatures = rlp.encode(tx, Transaction) with pytest.raises(TransactionFailed): plasma_core_test.getOutput(encoded_with_signatures, 0)
def test_should_not_allow_to_withdraw_inputs_and_outputs_when_ifes_processing_interchanges(testlang, plasma_framework, token): alice, amount_token = testlang.accounts[0], 200 caroline, amount_eth = testlang.accounts[1], 100 deposit_id_token = testlang.deposit_token(alice, token, amount_token) deposit_id_eth = testlang.deposit(caroline, amount_eth) swap_tx_id = testlang.spend_utxo( [deposit_id_token, deposit_id_eth], [alice, caroline], [(alice.address, NULL_ADDRESS, amount_eth), (caroline.address, token.address, amount_token)]) # in-flight transaction not included in Plasma steal_tx = Transaction(inputs=[decode_utxo_id(deposit_id_eth)], outputs=[(caroline.address, NULL_ADDRESS, amount_eth)]) steal_tx.sign(0, caroline, verifying_contract=testlang.root_chain.plasma_framework) alice_token_balance_before = token.balanceOf(alice.address) alice_eth_balance_before = testlang.get_balance(alice) caroline_token_balance_before = token.balanceOf(caroline.address) caroline_eth_balance_before = testlang.get_balance(caroline) testlang.start_in_flight_exit(swap_tx_id) testlang.start_in_flight_exit(None, spend_tx=steal_tx) testlang.piggyback_in_flight_exit_input(swap_tx_id, 0, alice) testlang.piggyback_in_flight_exit_input(swap_tx_id, 1, caroline) testlang.piggyback_in_flight_exit_output(swap_tx_id, 0, alice) testlang.piggyback_in_flight_exit_output(swap_tx_id, 1, caroline) # we have encounter flaky tests. we are guessing it is caused by two exits being enqueued in the time that is too close. # within same root chain block time span, the priority in the queue could be the same and hard to differentiate. # https://github.com/omgnetwork/plasma-contracts/issues/606 TIME_DIFF_FOR_ENSUREING_EXIT_PRIORITY = 10 testlang.forward_timestamp(TIME_DIFF_FOR_ENSUREING_EXIT_PRIORITY) testlang.piggyback_in_flight_exit_output(None, 0, caroline, spend_tx=steal_tx) testlang.piggyback_in_flight_exit_input(None, 0, caroline, spend_tx=steal_tx) testlang.forward_timestamp(2 * MIN_EXIT_PERIOD + 1) # process swap_tx Eth exit and then steal_tx Eth exit testlang.process_exits(NULL_ADDRESS, 0, 2) # process token exit testlang.process_exits(token.address, 0, 1) # caroline exits with the tokens caroline_token_balance = token.balanceOf(caroline.address) assert caroline_token_balance == caroline_token_balance_before + amount_token # but she does not get ETH back caroline_eth_balance = testlang.get_balance(caroline) assert caroline_eth_balance == caroline_eth_balance_before # alice exits with eth alice_eth_balance = testlang.get_balance(alice) assert alice_eth_balance == alice_eth_balance_before + amount_eth # but she does not get token back alice_token_balance = token.balanceOf(alice.address) assert alice_token_balance == alice_token_balance_before
def test_challenge_exit(t, u, root_chain, assert_tx_failed): owner, value_1, key = t.a1, 100, t.k1 tx1 = Transaction(0, 0, 0, 0, 0, 0, NULL_ADDRESS, owner, value_1, NULL_ADDRESS, 0) deposit_tx_hash = get_deposit_hash(owner, NULL_ADDRESS, value_1) utxo_pos1 = encode_utxo_id(root_chain.getDepositBlock(), 0, 0) root_chain.deposit(value=value_1, sender=key) utxo_pos2 = encode_utxo_id(root_chain.getDepositBlock(), 0, 0) root_chain.deposit(value=value_1, sender=key) merkle = FixedMerkle(16, [deposit_tx_hash], True) proof = merkle.create_membership_proof(deposit_tx_hash) confirmSig1 = confirm_tx(tx1, root_chain.getPlasmaBlock(utxo_pos1)[0], key) sigs = tx1.sig1 + tx1.sig2 + confirmSig1 root_chain.startDepositExit(utxo_pos1, NULL_ADDRESS, tx1.amount1, sender=key) tx3 = Transaction(utxo_pos2, 0, 0, 0, 0, 0, NULL_ADDRESS, owner, value_1, NULL_ADDRESS, 0) tx3.sign1(key) tx_bytes3 = rlp.encode(tx3, UnsignedTransaction) merkle = FixedMerkle(16, [tx3.merkle_hash], True) proof = merkle.create_membership_proof(tx3.merkle_hash) child_blknum = root_chain.currentChildBlock() root_chain.submitBlock(merkle.root) confirmSig = confirm_tx(tx3, root_chain.getPlasmaBlock(child_blknum)[0], key) sigs = tx3.sig1 + tx3.sig2 utxo_pos3 = encode_utxo_id(child_blknum, 0, 0) tx4 = Transaction(utxo_pos1, 0, 0, 0, 0, 0, NULL_ADDRESS, owner, value_1, NULL_ADDRESS, 0) tx4.sign1(key) tx_bytes4 = rlp.encode(tx4, UnsignedTransaction) merkle = FixedMerkle(16, [tx4.merkle_hash], True) proof = merkle.create_membership_proof(tx4.merkle_hash) child_blknum = root_chain.currentChildBlock() root_chain.submitBlock(merkle.root) confirmSig = confirm_tx(tx4, root_chain.getPlasmaBlock(child_blknum)[0], key) sigs = tx4.sig1 + tx4.sig2 utxo_pos4 = encode_utxo_id(child_blknum, 0, 0) oindex1 = 0 assert root_chain.exits(utxo_pos1) == [ '0x' + owner.hex(), NULL_ADDRESS_HEX, 100 ] # Fails if transaction after exit doesn't reference the utxo being exited assert_tx_failed(lambda: root_chain.challengeExit( utxo_pos3, oindex1, tx_bytes3, proof, sigs, confirmSig)) # Fails if transaction proof is incorrect assert_tx_failed(lambda: root_chain.challengeExit( utxo_pos4, oindex1, tx_bytes4, proof[::-1], sigs, confirmSig)) # Fails if transaction confirmation is incorrect assert_tx_failed(lambda: root_chain.challengeExit( utxo_pos4, oindex1, tx_bytes4, proof, sigs, confirmSig[::-1])) root_chain.challengeExit(utxo_pos4, oindex1, tx_bytes4, proof, sigs, confirmSig) assert root_chain.exits(utxo_pos1) == [ NULL_ADDRESS_HEX, NULL_ADDRESS_HEX, value_1 ]
def test_decoding_tx_with_gaps_in_inputs_fails(testlang, plasma_core_test): owner, amount = testlang.accounts[0], 100 tx = Transaction(inputs=[(0, 0, 0), (1, 0, 0)], outputs=[(owner.address, NULL_ADDRESS, amount)]) with pytest.raises(TransactionFailed): plasma_core_test.getInputUtxoPosition(tx.encoded, 0) tx = Transaction(inputs=[(1, 0, 0), (0, 0, 0), (1, 1, 0)], outputs=[(owner.address, NULL_ADDRESS, amount)]) with pytest.raises(TransactionFailed): plasma_core_test.getInputUtxoPosition(tx.encoded, 1)
def test_token_deposit_no_approve_should_fail(testlang, token): owner, amount = testlang.accounts[0], 100 deposit_tx = Transaction(outputs=[(owner.address, token.address, amount)]) token.mint(owner.address, amount) with pytest.raises(TransactionFailed): testlang.root_chain.depositFrom(deposit_tx.encoded, sender=owner.key)
def test_old_signature_scheme_does_not_work_any_longer(testlang, utxo): # In this test I will challenge standard exit with old signature schema to show it no longer works # Then passing new signature to the same challenge data, challenge will succeed alice = testlang.accounts[0] outputs = [(alice.address, NULL_ADDRESS, 50)] spend_id = testlang.spend_utxo([utxo.spend_id], [alice], outputs) testlang.start_standard_exit(spend_id, alice) exit_id = testlang.get_standard_exit_id(spend_id) # let's prepare old schema signature for a transaction with an input of exited utxo spend_tx = Transaction(inputs=[decode_utxo_id(spend_id)], outputs=outputs) old_signature = alice.key.sign_msg_hash(spend_tx.hash).to_bytes() # challenge will fail on signature verification with pytest.raises(TransactionFailed): testlang.root_chain.challengeStandardExit(exit_id, spend_tx.encoded, 0, old_signature) # sanity check: let's provide new schema signature for a challenge new_signature = alice.key.sign_msg_hash( hash_struct(spend_tx, verifying_contract=testlang.root_chain)).to_bytes() testlang.root_chain.challengeStandardExit(exit_id, spend_tx.encoded, 0, new_signature)
def test_get_input_id(plasma_core_test): input_id = (2, 2, 2) tx = Transaction(inputs=[input_id]) assert plasma_core_test.getInputUtxoPosition(tx.encoded, 0) == tx.inputs[0].identifier assert plasma_core_test.getInputUtxoPosition(tx.encoded, 1) == 0 assert plasma_core_test.getInputUtxoPosition(tx.encoded, 2) == 0 assert plasma_core_test.getInputUtxoPosition(tx.encoded, 3) == 0
def test_deposit_with_input_should_fail(testlang): owner, amount = testlang.accounts[0], 100 deposit_tx = Transaction(inputs=[(1, 0, 0)], outputs=[(owner.address, NULL_ADDRESS, amount)]) with pytest.raises(TransactionFailed): testlang.root_chain.deposit(deposit_tx.encoded, value=amount)
def deposit_token(self, owner, token, amount): """Mints, approves and deposits token for given owner and amount Args: owner (EthereumAccount): Account to own the deposit. token (Contract: ERC20, MintableToken): Token to be deposited. amount (int): Deposit amount. Returns: int: Unique identifier of the deposit. """ deposit_tx = Transaction(0, 0, 0, 0, 0, 0, token.address, owner.address, amount, NULL_ADDRESS, 0) token.mint(owner.address, amount) self.ethtester.chain.mine() token.approve(self.root_chain.address, amount, sender=owner.key) self.ethtester.chain.mine() blknum = self.root_chain.getDepositBlock() self.root_chain.depositFrom(owner.address, token.address, amount, sender=owner.key) block = Block(transaction_set=[deposit_tx], number=blknum) self.child_chain.add_block(block) return blknum
def test_finalize_exits(t, u, root_chain): two_weeks = 60 * 60 * 24 * 14 owner, value_1, key = t.a1, 100, t.k1 tx1 = Transaction(0, 0, 0, 0, 0, 0, NULL_ADDRESS, owner, value_1, NULL_ADDRESS, 0) dep1_blknum = root_chain.getDepositBlock() root_chain.deposit(value=value_1, sender=key) utxo_pos1 = encode_utxo_id(dep1_blknum, 0, 0) exit_bond = root_chain.EXIT_BOND() root_chain.startDepositExit(utxo_pos1, NULL_ADDRESS, tx1.amount1, sender=key, value=exit_bond) t.chain.head_state.timestamp += two_weeks * 2 assert root_chain.exits(utxo_pos1) == [ '0x' + owner.hex(), NULL_ADDRESS_HEX, 100 ] pre_balance = t.chain.head_state.get_balance(owner) root_chain.finalizeExits(sender=t.k2) post_balance = t.chain.head_state.get_balance(owner) assert post_balance == pre_balance + value_1 + exit_bond assert root_chain.exits(utxo_pos1) == [ NULL_ADDRESS_HEX, NULL_ADDRESS_HEX, value_1 ]
def test_decoding_tx_with_gaps_in_outputs_fails(testlang, plasma_core_test): owner, amount = testlang.accounts[0], 100 null_output = (NULL_ADDRESS, NULL_ADDRESS, 0) tx = Transaction( inputs=[(1, 0, 0)], outputs=[null_output, (owner.address, NULL_ADDRESS, amount)]) with pytest.raises(TransactionFailed): plasma_core_test.getOutput(tx.encoded, 0) tx = Transaction(inputs=[(1, 0, 0)], outputs=[(owner.address, NULL_ADDRESS, amount), null_output, (owner.address, NULL_ADDRESS, amount)]) with pytest.raises(TransactionFailed): plasma_core_test.getOutput(tx.encoded, 1)
def deposit_token(self, owner, token, amount): """Mints, approves and deposits token for given owner and amount Args: owner (EthereumAccount): Account to own the deposit. token (Contract: ERC20, MintableToken): Token to be deposited. amount (int): Deposit amount. Returns: int: Unique identifier of the deposit. """ deposit_tx = Transaction(outputs=[(owner.address, token.address, amount)]) token.mint(owner.address, amount) token.approve(self.root_chain.erc20_vault.address, amount, **{'from': owner.address}) blknum = self.root_chain.getDepositBlockNumber() pre_balance = self.get_balance(self.root_chain.erc20_vault, token) self.root_chain.depositFrom(deposit_tx.encoded, **{'from': owner.address}) balance = self.get_balance(self.root_chain.erc20_vault, token) assert balance == pre_balance + amount block = Block(transactions=[deposit_tx], number=blknum) self.child_chain.add_block(block) return encode_utxo_id(blknum, 0, 0)
def _deposit(testlang, owner, amount, blknum): deposit_tx = Transaction(outputs=[(owner.address, NULL_ADDRESS, amount)]) testlang.root_chain.eth_vault.functions.deposit(deposit_tx.encoded).transact({'from': owner.address, 'value': amount}) deposit_id = encode_utxo_id(blknum, 0, 0) block = Block([deposit_tx], number=blknum) testlang.child_chain.add_block(block) return deposit_id
def test_token_deposit_non_existing_token_should_fail(testlang, token): owner, amount = testlang.accounts[0], 100 deposit_tx = Transaction(outputs=[(owner.address, NULL_ADDRESS, amount)]) token.mint(owner.address, amount) token.approve(testlang.root_chain.erc20_vault.address, amount, **{'from': owner.address}) with pytest.raises(TransactionFailed): testlang.root_chain.depositFrom(deposit_tx.encoded, **{'from': owner.address})
def spend_utxo(self, input_ids, keys, outputs=None, metadata=None, force_invalid=False): if outputs is None: outputs = [] inputs = [decode_utxo_id(input_id) for input_id in input_ids] spend_tx = Transaction(inputs=inputs, outputs=outputs, metadata=metadata) for i in range(0, len(inputs)): spend_tx.sign(i, keys[i], verifyingContract=self.root_chain) blknum = self.submit_block([spend_tx], force_invalid=force_invalid) spend_id = encode_utxo_id(blknum, 0, 0) return spend_id
def test_get_output(plasma_core_test): null = '0x0000000000000000000000000000000000000000' owner = '0x82a978b3f5962a5b0957d9ee9eef472ee55b42f1' amount = 100 tx = Transaction(outputs=[(owner, null, amount)]) assert plasma_core_test.getOutput( tx.encoded, 0) == [to_checksum_address(owner), null, amount] assert plasma_core_test.getOutput(tx.encoded, 1) == [null, null, 0]
def deposit(self, owner, amount): deposit_tx = Transaction(outputs=[(owner.address, NULL_ADDRESS, amount)]) blknum = self.root_chain.getDepositBlockNumber() self.root_chain.deposit(deposit_tx.encoded, value=amount) deposit_id = encode_utxo_id(blknum, 0, 0) block = Block([deposit_tx], number=blknum) self.child_chain.add_block(block) return deposit_id
def test_decode_mallability(testlang, plasma_core_test): owner, amount = testlang.accounts[0], 100 null = '0x0000000000000000000000000000000000000000' tx = Transaction(outputs=[(owner.address, null, amount)], metadata="") import rlp encoded_with_extra_field = rlp.encode([tx.inputs, tx.outputs, tx.metadata, 0]) with pytest.raises(TransactionFailed): plasma_core_test.getOutput(encoded_with_extra_field, 0)
def test_start_standard_exit_wrong_oindex_should_fail(testlang): alice, bob, alice_money, bob_money = testlang.accounts[0], testlang.accounts[1], 10, 90 deposit_id = testlang.deposit(alice, alice_money + bob_money) spend_tx = Transaction(inputs=[decode_utxo_id(deposit_id)], outputs=[(alice.address, NULL_ADDRESS, alice_money), (bob.address, NULL_ADDRESS, bob_money)]) spend_tx.sign(0, alice, verifying_contract=testlang.root_chain) blknum = testlang.submit_block([spend_tx]) alice_utxo = encode_utxo_id(blknum, 0, 0) bob_utxo = encode_utxo_id(blknum, 0, 1) with pytest.raises(TransactionFailed): testlang.start_standard_exit(bob_utxo, alice) with pytest.raises(TransactionFailed): testlang.start_standard_exit(alice_utxo, bob) testlang.start_standard_exit(alice_utxo, alice) testlang.start_standard_exit(bob_utxo, bob)
def test_transfer(test_lang): owner_1 = test_lang.get_account() owner_2 = test_lang.get_account() amount = 100 deposit_id = test_lang.deposit(owner_1, amount) transfer_id = test_lang.transfer(deposit_id, owner_2, amount, owner_1) tx = Transaction(1, 0, 0, 0, 0, 0, NULL_ADDRESS, owner_2['address'], amount, NULL_ADDRESS, 0) assert test_lang.child_chain.get_transaction(transfer_id).hash == tx.hash
def create_transaction(self, blknum1=0, txindex1=0, oindex1=0, blknum2=0, txindex2=0, oindex2=0, newowner1=NULL_ADDRESS, amount1=0, newowner2=NULL_ADDRESS, amount2=0, cur12=NULL_ADDRESS, fee=0): return Transaction(blknum1, txindex1, oindex1, blknum2, txindex2, oindex2, cur12, newowner1, amount1, newowner2, amount2, fee)