omgnetwork / plasma-mvp

OmiseGO's research implementation of Minimal Viable Plasma
MIT License
561 stars 158 forks source link

Many Failing Tests #161

Closed bh2smith closed 6 years ago

bh2smith commented 6 years ago

Issue Type

[x] bug report
[ ] feature request

Current Behavior

'make test' is not passing. More specifically there are 10 failed test cases in the following two files.

tests/child_chain/test_child_chain.py FFFFF...
tests/child_chain/test_child_chain_integration.py FFFFF

It appears that the main problem involves a KeyError.

Steps to Reproduce

run $ make test

System Specs

atomicwrites==1.1.5 attrdict==2.0.0 attrs==18.1.0 certifi==2018.4.16 chardet==3.0.4 click==6.7 cytoolz==0.9.0.1 eth-abi==1.1.1 eth-account==0.2.3 eth-hash==0.1.4 eth-keyfile==0.5.1 eth-keys==0.2.0b3 eth-rlp==0.1.2 eth-utils==1.0.3 ethereum==2.3.0 flake8==3.5.0 future==0.16.0 hexbytes==0.1.0 idna==2.7 json-rpc==1.10.8 lru-dict==1.1.6 mccabe==0.6.1 more-itertools==4.2.0 parsimonious==0.8.0 pbkdf2==1.3 plasma==0.0.0 pluggy==0.6.0 plyvel==1.0.4 py==1.5.4 py-ecc==1.4.3 py-solc==3.1.0 pycodestyle==2.3.1 pycryptodome==3.6.4 pyethash==0.1.27 pyflakes==1.6.0 pysha3==1.0.2 pytest==3.6.3 PyYAML==4.2b4 repoze.lru==0.7 requests==2.19.1 rlp==0.6.0 scrypt==0.8.6 semantic-version==2.6.0 six==1.11.0 toolz==0.9.0 urllib3==1.23 web3==4.3.0 websockets==4.0.1 Werkzeug==0.13

Detailed Error Log

========================================================================== test session starts ========================================================================== platform darwin -- Python 3.6.5, pytest-3.6.3, py-1.5.4, pluggy-0.6.0 rootdir: /Users/admin/Projects/test-mvp/plasma-mvp, inifile: collected 39 items

tests/child_chain/test_block.py .. [ 5%] tests/child_chain/test_child_chain.py FFFFF... [ 25%] tests/child_chain/test_child_chain_integration.py FFFFF [ 38%] tests/child_chain/test_transaction.py . [ 41%] tests/root_chain/contracts/data_structures/test_priority_queue.py ....... [ 58%] tests/root_chain/contracts/root_chain/test_rlp.py .. [ 64%] tests/root_chain/contracts/root_chain/test_root_chain.py ...... [ 79%] tests/utils/test_fixed_merkle.py ........ [100%]

=============================================================================== FAILURES ================================================================================ __ test_apply_deposit ___

test_lang = <testlang.testing_language.TestingLanguage object at 0x107ca2e80>

def test_apply_deposit(test_lang):
    owner = test_lang.get_account()
    amount = 100

    test_lang.deposit(owner, amount)

    deposit_block_number = 1
  deposit_block = test_lang.child_chain.get_block(deposit_block_number)

tests/child_chain/test_child_chain.py:14:


plasma/child_chain/child_chain.py:51: in get_block return self.chain.get_block(blknum)


self = <plasma_core.chain.Chain object at 0x108058470>, blknum = 1

def get_block(self, blknum):
  return self.blocks[blknum]

E KeyError: 1

plasmacore/chain.py:86: KeyError ------------------------------------------------------------------------- Captured stdout setup ------------------------------------------------------------------------- Successfully deployed RootChain contract! ____ test_send_tx_withsig ____

test_lang = <testlang.testing_language.TestingLanguage object at 0x107d36dd8>

def test_send_tx_with_sig(test_lang):
    owner_1 = test_lang.get_account()
    owner_2 = test_lang.get_account()
    amount = 100

    deposit_id = test_lang.deposit(owner_1, amount)
  test_lang.transfer(deposit_id, owner_2, amount, owner_1)

tests/child_chain/test_child_chain.py:24:


testlang/testing_language.py:58: in transfer spend_id = self.child_chain.apply_transaction(tx) plasma/child_chain/child_chain.py:36: in apply_transaction self.chain.validate_transaction(tx, self.current_block.spent_utxos)


self = <plasma_core.chain.Chain object at 0x1079e37b8>, tx = <plasma_core.transaction.Transaction object at 0x107cf8a58>, temp_spent = {}

def validate_transaction(self, tx, temp_spent={}):
    input_amount = 0
    output_amount = tx.amount1 + tx.amount2

    inputs = [(tx.blknum1, tx.txindex1, tx.oindex1), (tx.blknum2, tx.txindex2, tx.oindex2)]
    for (blknum, txindex, oindex) in inputs:
        # Transactions coming from block 0 are valid.
        if blknum == 0:
            continue
      input_tx = self.blocks[blknum].transaction_set[txindex]

E KeyError: 1

plasma_core/chain.py:63: KeyError ------------------------------------------------------------------------- Captured stdout setup ------------------------------------------------------------------------- Successfully deployed RootChain contract! __ test_send_tx_no_sig __

test_lang = <testlang.testing_language.TestingLanguage object at 0x107d96780>

def test_send_tx_no_sig(test_lang):
    owner_1 = test_lang.get_account()
    owner_2 = test_lang.get_account()
    amount = 100
    key = None

    deposit_id = test_lang.deposit(owner_1, amount)

    with pytest.raises(InvalidTxSignatureException):
      test_lang.transfer(deposit_id, owner_2, amount, key)

tests/child_chain/test_child_chain.py:36:


testlang/testing_language.py:58: in transfer spend_id = self.child_chain.apply_transaction(tx) plasma/child_chain/child_chain.py:36: in apply_transaction self.chain.validate_transaction(tx, self.current_block.spent_utxos)


self = <plasma_core.chain.Chain object at 0x107ca2b70>, tx = <plasma_core.transaction.Transaction object at 0x1079e3d30>, temp_spent = {}

def validate_transaction(self, tx, temp_spent={}):
    input_amount = 0
    output_amount = tx.amount1 + tx.amount2

    inputs = [(tx.blknum1, tx.txindex1, tx.oindex1), (tx.blknum2, tx.txindex2, tx.oindex2)]
    for (blknum, txindex, oindex) in inputs:
        # Transactions coming from block 0 are valid.
        if blknum == 0:
            continue
      input_tx = self.blocks[blknum].transaction_set[txindex]

E KeyError: 1

plasma_core/chain.py:63: KeyError ------------------------------------------------------------------------- Captured stdout setup ------------------------------------------------------------------------- Successfully deployed RootChain contract! ___ test_send_tx_invalid_sig ____

test_lang = <testlang.testing_language.TestingLanguage object at 0x10801c240>

def test_send_tx_invalid_sig(test_lang):
    owner_1 = test_lang.get_account()
    owner_2 = test_lang.get_account()
    owner_3 = test_lang.get_account()
    amount = 100

    deposit_id = test_lang.deposit(owner_1, amount)

    with pytest.raises(InvalidTxSignatureException):
      test_lang.transfer(deposit_id, owner_2, amount, owner_3)

tests/child_chain/test_child_chain.py:48:


testlang/testing_language.py:58: in transfer spend_id = self.child_chain.apply_transaction(tx) plasma/child_chain/child_chain.py:36: in apply_transaction self.chain.validate_transaction(tx, self.current_block.spent_utxos)


self = <plasma_core.chain.Chain object at 0x107daef60>, tx = <plasma_core.transaction.Transaction object at 0x107dc2ba8>, temp_spent = {}

def validate_transaction(self, tx, temp_spent={}):
    input_amount = 0
    output_amount = tx.amount1 + tx.amount2

    inputs = [(tx.blknum1, tx.txindex1, tx.oindex1), (tx.blknum2, tx.txindex2, tx.oindex2)]
    for (blknum, txindex, oindex) in inputs:
        # Transactions coming from block 0 are valid.
        if blknum == 0:
            continue
      input_tx = self.blocks[blknum].transaction_set[txindex]

E KeyError: 1

plasma_core/chain.py:63: KeyError ------------------------------------------------------------------------- Captured stdout setup ------------------------------------------------------------------------- Successfully deployed RootChain contract! _ test_send_tx_doublespend

test_lang = <testlang.testing_language.TestingLanguage object at 0x107ddf048>

def test_send_tx_double_spend(test_lang):
    owner_1 = test_lang.get_account()
    owner_2 = test_lang.get_account()
    amount = 100

    deposit_id = test_lang.deposit(owner_1, amount)
  test_lang.transfer(deposit_id, owner_2, amount, owner_1)

tests/child_chain/test_child_chain.py:57:


testlang/testing_language.py:58: in transfer spend_id = self.child_chain.apply_transaction(tx) plasma/child_chain/child_chain.py:36: in apply_transaction self.chain.validate_transaction(tx, self.current_block.spent_utxos)


self = <plasma_core.chain.Chain object at 0x107d31208>, tx = <plasma_core.transaction.Transaction object at 0x107ddff60>, temp_spent = {}

def validate_transaction(self, tx, temp_spent={}):
    input_amount = 0
    output_amount = tx.amount1 + tx.amount2

    inputs = [(tx.blknum1, tx.txindex1, tx.oindex1), (tx.blknum2, tx.txindex2, tx.oindex2)]
    for (blknum, txindex, oindex) in inputs:
        # Transactions coming from block 0 are valid.
        if blknum == 0:
            continue
      input_tx = self.blocks[blknum].transaction_set[txindex]

E KeyError: 1

plasmacore/chain.py:63: KeyError ------------------------------------------------------------------------- Captured stdout setup ------------------------------------------------------------------------- Successfully deployed RootChain contract! ____ test_deposit __

test_lang = <testlang.testing_language.TestingLanguage object at 0x109b3a8d0>

def test_deposit(test_lang):
    owner_1 = test_lang.get_account()
    amount = 100

    deposit_id = test_lang.deposit(owner_1, amount)

    tx = Transaction(0, 0, 0, 0, 0, 0, NULL_ADDRESS, owner_1['address'], amount, NULL_ADDRESS, 0)
    deposit_hash = Web3.soliditySha3(['address', 'address', 'uint256'], [owner_1['address'], NULL_ADDRESS_HEX, amount])  # pylint: disable=E1120

    (deposit_blknum, _, _) = decode_utxo_id(deposit_id)
  deposit_block = test_lang.child_chain.get_block(deposit_blknum)

tests/child_chain/test_child_chain_integration.py:17:


plasma/child_chain/child_chain.py:51: in get_block return self.chain.get_block(blknum)


self = <plasma_core.chain.Chain object at 0x107db7cc0>, blknum = 1

def get_block(self, blknum):
  return self.blocks[blknum]

E KeyError: 1

plasmacore/chain.py:86: KeyError ------------------------------------------------------------------------- Captured stdout setup ------------------------------------------------------------------------- Successfully deployed RootChain contract! ____ testtransfer ____

test_lang = <testlang.testing_language.TestingLanguage object at 0x107dbe978>

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)

tests/child_chain/test_child_chain_integration.py:28:


testlang/testing_language.py:58: in transfer spend_id = self.child_chain.apply_transaction(tx) plasma/child_chain/child_chain.py:36: in apply_transaction self.chain.validate_transaction(tx, self.current_block.spent_utxos)


self = <plasma_core.chain.Chain object at 0x107dbe9e8>, tx = <plasma_core.transaction.Transaction object at 0x109b35f98>, temp_spent = {}

def validate_transaction(self, tx, temp_spent={}):
    input_amount = 0
    output_amount = tx.amount1 + tx.amount2

    inputs = [(tx.blknum1, tx.txindex1, tx.oindex1), (tx.blknum2, tx.txindex2, tx.oindex2)]
    for (blknum, txindex, oindex) in inputs:
        # Transactions coming from block 0 are valid.
        if blknum == 0:
            continue
      input_tx = self.blocks[blknum].transaction_set[txindex]

E KeyError: 1

plasma_core/chain.py:63: KeyError ------------------------------------------------------------------------- Captured stdout setup ------------------------------------------------------------------------- Successfully deployed RootChain contract! _ test_submitblock

test_lang = <testlang.testing_language.TestingLanguage object at 0x107dddb70>

def test_submit_block(test_lang):
    owner_1 = test_lang.get_account()
    owner_2 = test_lang.get_account()
    amount = 100

    deposit_id = test_lang.deposit(owner_1, amount)
  test_lang.transfer(deposit_id, owner_2, amount, owner_1)

tests/child_chain/test_child_chain_integration.py:45:


testlang/testing_language.py:58: in transfer spend_id = self.child_chain.apply_transaction(tx) plasma/child_chain/child_chain.py:36: in apply_transaction self.chain.validate_transaction(tx, self.current_block.spent_utxos)


self = <plasma_core.chain.Chain object at 0x108032860>, tx = <plasma_core.transaction.Transaction object at 0x1080323c8>, temp_spent = {}

def validate_transaction(self, tx, temp_spent={}):
    input_amount = 0
    output_amount = tx.amount1 + tx.amount2

    inputs = [(tx.blknum1, tx.txindex1, tx.oindex1), (tx.blknum2, tx.txindex2, tx.oindex2)]
    for (blknum, txindex, oindex) in inputs:
        # Transactions coming from block 0 are valid.
        if blknum == 0:
            continue
      input_tx = self.blocks[blknum].transaction_set[txindex]

E KeyError: 1

plasma_core/chain.py:63: KeyError ------------------------------------------------------------------------- Captured stdout setup ------------------------------------------------------------------------- Successfully deployed RootChain contract! ____ test_withdrawtransfer ____

test_lang = <testlang.testing_language.TestingLanguage object at 0x107de89e8>

def test_withdraw_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)

tests/child_chain/test_child_chain_integration.py:57:


testlang/testing_language.py:58: in transfer spend_id = self.child_chain.apply_transaction(tx) plasma/child_chain/child_chain.py:36: in apply_transaction self.chain.validate_transaction(tx, self.current_block.spent_utxos)


self = <plasma_core.chain.Chain object at 0x107d9db38>, tx = <plasma_core.transaction.Transaction object at 0x1079d9940>, temp_spent = {}

def validate_transaction(self, tx, temp_spent={}):
    input_amount = 0
    output_amount = tx.amount1 + tx.amount2

    inputs = [(tx.blknum1, tx.txindex1, tx.oindex1), (tx.blknum2, tx.txindex2, tx.oindex2)]
    for (blknum, txindex, oindex) in inputs:
        # Transactions coming from block 0 are valid.
        if blknum == 0:
            continue
      input_tx = self.blocks[blknum].transaction_set[txindex]

E KeyError: 1

plasmacore/chain.py:63: KeyError ------------------------------------------------------------------------- Captured stdout setup ------------------------------------------------------------------------- Successfully deployed RootChain contract! ____ test_withdrawdeposit ____

test_lang = <testlang.testing_language.TestingLanguage object at 0x108032ac8>

def test_withdraw_deposit(test_lang):
    owner_1 = test_lang.get_account()
    amount = 100

    deposit_id = test_lang.deposit(owner_1, amount)
  test_lang.start_deposit_exit(deposit_id, owner_1)

tests/child_chain/test_child_chain_integration.py:72:


testlang/testing_language.py:85: in start_deposit_exit tx = self.child_chain.get_transaction(utxo_id) plasma/child_chain/child_chain.py:48: in get_transaction return self.chain.get_transaction(tx_id)


self = <plasma_core.chain.Chain object at 0x107cf3160>, transaction_id = 1000000000

def get_transaction(self, transaction_id):
    (blknum, txindex, _) = decode_utxo_id(transaction_id)
  return self.blocks[blknum].transaction_set[txindex]

E KeyError: 1

plasma_core/chain.py:90: KeyError ------------------------------------------------------------------------- Captured stdout setup ------------------------------------------------------------------------- Successfully deployed RootChain contract! ================================================================= 10 failed, 29 passed in 21.67 seconds ================================================================= make: *** [test] Error 1

smartcontracts commented 6 years ago

Hi, can you confirm you're using the latest version of ganache-cli?

bh2smith commented 6 years ago

I am using the most recent ganache-cli

Ganache CLI v6.1.6 (ganache-core: 2.1.5)

and I have noticed that we should downgrade some versions, but I still haven't managed to figure out how.

bh2smith commented 6 years ago

So, it turns out there are issues with the handling of transactions in both _Block.addtransaction and _Chain.validatetransaction. Transactions are inconsistently being passed as encoded and decoded versions of themselves.

This can be boiled down to a single try-catch in _ChildChain.applytransaction as follows;

    def apply_transaction(self, encoded_transaction):
        try:
            tx = rlp.decode(utils.decode_hex(encoded_transaction), Transaction)
        except TypeError:
            tx = encoded_transaction

        self.chain.validate_transaction(tx, self.current_block.spent_utxos)
        self.current_block.add_transaction(tx)
        return encode_utxo_id(self.current_block.number, len(self.current_block.transaction_set) - 1, 0)

I will commit and contribute this solution as a TEMPORARY fix (for the time being) that manages to get 100% passing test cases.

smartcontracts commented 6 years ago

Can you try updating ganache-cli to version 6.1.8? I believe that should fix the issue.