Example #1
0
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
    ]
Example #2
0
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]
Example #3
0
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)
Example #4
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)
Example #5
0
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
    ]
Example #6
0
    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_transaction(t):
    blknum1, txindex1, oindex1 = 1, 1, 0
    blknum2, txindex2, oindex2 = 2, 2, 1
    newowner1, amount1 = t.a1, 100
    newowner2, amount2 = t.a2, 150
    oldowner1, oldowner2 = t.a1, t.a2
    key1, key2 = t.k1, t.k2
    tx = Transaction(blknum1, txindex1, oindex1,
                     blknum2, txindex2, oindex2,
                     NULL_ADDRESS,
                     newowner1, amount1,
                     newowner2, amount2)
    assert tx.blknum1 == blknum1
    assert tx.txindex1 == txindex1
    assert tx.oindex1 == oindex1
    assert tx.blknum2 == blknum2
    assert txindex2 == txindex2
    assert tx.oindex2 == oindex2
    assert tx.newowner1 == newowner1
    assert tx.amount1 == amount1
    assert tx.newowner2 == newowner2
    assert tx.amount2 == amount2
    assert tx.sig1 == NULL_SIGNATURE
    assert tx.sig2 == NULL_SIGNATURE
    tx.sign1(key1)
    assert tx.sender1 == oldowner1
    tx.sign2(key2)
    assert tx.sender2 == oldowner2
Example #8
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 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)
Example #10
0
def sendtx(client,
           blknum1, txindex1, oindex1,
           blknum2, txindex2, oindex2,
           cur12,
           amount1, newowner1,
           amount2, newowner2,
           key1, key2):
    if cur12 == "0x0":
        cur12 = NULL_ADDRESS
    if newowner1 == "0x0":
        newowner1 = NULL_ADDRESS
    if newowner2 == "0x0":
        newowner2 = NULL_ADDRESS

    # Form a transaction
    tx = Transaction(blknum1, txindex1, oindex1,
                     blknum2, txindex2, oindex2,
                     utils.normalize_address(cur12),
                     utils.normalize_address(newowner1), amount1,
                     utils.normalize_address(newowner2), amount2)

    # Sign it
    if key1:
        tx.sign1(utils.normalize_key(key1))
    if key2:
        tx.sign2(utils.normalize_key(key2))

    client_call(client.apply_transaction, [tx], "Sent transaction")
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)
Example #12
0
    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_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)

    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)
Example #16
0
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_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
Example #18
0
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 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
Example #20
0
    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)
Example #21
0
    def transfer(self,
                 input1, newowner1, amount1, signatory1,
                 input2=0, newowner2=None, amount2=0, signatory2=None, cur12=NULL_ADDRESS):
        newowner_address1 = newowner1['address']
        newowner_address2 = NULL_ADDRESS
        if newowner2 is not None:
            newowner_address2 = newowner2['address']

        tx = Transaction(*decode_utxo_id(input1),
                         *decode_utxo_id(input2),
                         cur12,
                         newowner_address1, amount1,
                         newowner_address2, amount2)

        if signatory1 is not None:
            key1 = signatory1['key']
            tx.sign1(key1)

        if signatory2 is not None:
            key2 = signatory2['key']
            tx.sign2(key2)

        spend_id = self.child_chain.apply_transaction(tx)
        self.submit_block()
        return spend_id
Example #22
0
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
    ]
Example #23
0
 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 = '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 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})
Example #26
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)
Example #28
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_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