GithubHelp home page GithubHelp logo

plasma-mvp's Introduction

Notice!

This is an old research repo. No active work is being done here. Efforts in the direction of production-ready MVP plasma chain (MoreVP, ERC20, audits) are in https://github.com/omisego/plasma-contracts.

Plasma MVP

We're implementing Minimum Viable Plasma. This repository represents a work in progress and will undergo large-scale modifications as requirements change.

Overview

Plasma MVP is split into four main parts: root_chain, child_chain, client, and cli. Below is an overview of each sub-project.

root_chain

root_chain represents the Plasma contract to be deployed to the root blockchain. In our case, this contract is written in Solidity and is designed to be deployed to Ethereum. root_chain also includes a compilation/deployment script.

RootChain.sol is based off of the Plasma design specified in Minimum Viable Plasma. Currently, this contract allows a single authority to publish child chain blocks to the root chain. This is not a permanent design and is intended to simplify development of more critical components in the short term.

child_chain

child_chain is a Python implementation of a Plasma MVP child chain client. It's useful to think of child_chain as analogous to Parity or Geth. This component manages a store of Blocks and Transactions that are updated when events are fired in the root contract.

child_chain also contains an RPC server that enables client interactions. By default, this server runs on port 8546.

client

client is a simple Python wrapper of the RPC API exposed by child_chain, similar to Web3.py for Ethereum. You can use this client to write Python applications that interact with this Plasma chain.

cli

cli is a simple Python application that uses client to interact with child_chain, via the command line. A detailed documentation of cli is available here.

Getting Started

Dependencies

This project has a few pre-installation dependencies.

Mac:

brew update
brew upgrade
brew tap ethereum/ethereum
brew install solidity

Linux:

sudo add-apt-repository ppa:ethereum/ethereum
sudo apt-get update
sudo apt-get install solc

Windows:

Follow this guide

Mac:

brew install python

Linux:

sudo apt-get install software-properties-common
sudo add-apt-repository ppa:deadsnakes/ppa
sudo apt-get update
sudo apt-get install python3

Windows:

choco install python

Installation

Note: we optionally recommend using something like virtualenv in order to create an isolated Python environment:

$ virtualenv env -p python3

Fetch and install the project's dependencies with:

$ make

Testing

Before you run tests, make sure you have an Ethereum client running and an JSON RPC API exposed on port 8545. We recommend using ganache-cli to accomplish this when running tests. Start it with the command-line argument -m="plasma_mvp".

Project tests can be found in the tests/ folder. Run tests with:

$ make test

If you're contributing to this project, make sure you also install flake8 and lint your work:

$ make lint

Starting Plasma

The fastest way to start playing with our Plasma MVP is by starting up ganache-cli, deploying everything locally, and running our CLI. Full documentation for the CLI is available here.

$ ganache-cli -m=plasma_mvp # Start ganache-cli
$ make root-chain           # Deploy the root chain contract
$ make child-chain          # Run our child chain and server

CLI Documentation

omg is a simple Plasma CLI that enables interactions with the child chain. Full documentation is provided below.

help

Description

Shows a list of available commands.

Usage

--help

deposit

Description

Creates a deposit transaction and submits it to the child chain.

Usage

deposit <amount> <address>

Example

deposit 100 0xfd02EcEE62797e75D86BCff1642EB0844afB28c7

sendtx

Description

Creates a transaction and submits it to the child chain.

Usage

sendtx <blknum1> <txindex1> <oindex1> <blknum2> <txindex2> <oindex2> <cur12> <newowner1> <amount1> <newowner2> <amount2> <key1> [<key2>]

Example

sendtx 1 0 0 0 0 0 0x0 0xfd02EcEE62797e75D86BCff1642EB0844afB28c7 50 0x4B3eC6c9dC67079E82152d6D55d8dd96a8e6AA26 45 3bb369fecdc16b93b99514d8ed9c2e87c5824cf4a6a98d2e8e91b7dd0c063304

submitblock

Description

Signs and submits the current block to the root contract.

Usage

submitblock <key>

Example

submitblock 3bb369fecdc16b93b99514d8ed9c2e87c5824cf4a6a98d2e8e91b7dd0c063304

withdraw

Description

Creates an exit transaction for the given UTXO.

Usage

withdraw <blknum> <txindex> <oindex> <key1> [<key2>]

Example

withdraw 1000 0 0 3bb369fecdc16b93b99514d8ed9c2e87c5824cf4a6a98d2e8e91b7dd0c063304

withdrawdeposit

Description

Withdraws from a deposit.

Usage

withdrawdeposit <owner> <blknum> <amount>

Example

withdrawdeposit 0xfd02EcEE62797e75D86BCff1642EB0844afB28c7 1 100

CLI Example

Let's play around a bit:

  1. Deploy the root chain contract and start the child chain as per Starting Plasma.

  2. Start by depositing:

omg deposit 100 0xfd02EcEE62797e75D86BCff1642EB0844afB28c7
  1. Send a transaction:
omg sendtx 1 0 0 0 0 0 0x0 0xfd02EcEE62797e75D86BCff1642EB0844afB28c7 50 0x4B3eC6c9dC67079E82152d6D55d8dd96a8e6AA26 45 3bb369fecdc16b93b99514d8ed9c2e87c5824cf4a6a98d2e8e91b7dd0c063304
  1. Submit the block:
omg submitblock 3bb369fecdc16b93b99514d8ed9c2e87c5824cf4a6a98d2e8e91b7dd0c063304
  1. Withdraw the original deposit (this is a double spend!):
omg withdrawdeposit 0xfd02EcEE62797e75D86BCff1642EB0844afB28c7 1 100

Note: The functionality to challenge double spends from the cli is still being worked on.

plasma-mvp's People

Contributors

ackintosh avatar bakaoh avatar benjaminion avatar bun919tw avatar colin-axner avatar davidknott avatar dcb9 avatar dongsam avatar eashend avatar jtakalai avatar kasima avatar mdschaeffer avatar nvonpentz avatar paulperegud avatar pik694 avatar rcallan avatar renlulu avatar shapeshed avatar shingonu avatar smartcontracts avatar sonatard avatar spawn66336 avatar stevenspasbo avatar takashi avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

plasma-mvp's Issues

Deposit blocks are not signed before being included in the list of blocks.

In child_chain.py,

If a block in <current_block> is signed, then this block is appended to <blocks = {}> variable.

It is block signing process.

However, when deposit tx and make a block, this block does not signed but included in <blocks = {}> variables.

I think signing process should be implemented at child_chain.py, apply_deposit() function.

And merkle, too.

Deployment Error: `ImportError: cannot import name 'force_text'`

I'm getting an ImportError: cannot import name 'force_text' when trying to make root-chain after pulling from master today. I started fresh and ran make. I'll continue troubleshooting but I'd appreciate any hint if anyone run into the same issue or if I'm just missing something obvious.

(python3) Frederics-MacBook-Pro:plasma-mvp fredfortier$ solc --version
solc, the solidity compiler commandline interface
Version: 0.4.20+commit.3155dd80.Darwin.appleclang
Frederics-MacBook-Pro:~ fredfortier$ ganache-cli -m=plasma_mvp
Ganache CLI v6.0.3 (ganache-core: 2.0.2)
(python3) Frederics-MacBook-Pro:plasma-mvp fredfortier$ pip freeze
attrs==17.4.0
certifi==2018.1.18
chardet==3.0.4
click==6.7
cytoolz==0.9.0
eth-abi==1.0.0
eth-hash==0.1.0
eth-keyfile==0.5.1
eth-keys==0.2.0b3
eth-tester==0.1.0b21
eth-utils==1.0.1
ethereum==2.3.0
future==0.16.0
idna==2.6
json-rpc==1.10.8
pbkdf2==1.3
plasma==0.0.0
pluggy==0.6.0
plyvel==1.0.4
py==1.5.2
py-ecc==1.4.2
py-solc==2.1.0
pycryptodome==3.4.11
pyethash==0.1.27
pylru==1.0.9
pysha3==1.0.2
pytest==3.4.1
PyYAML==3.12
repoze.lru==0.7
requests==2.18.4
rlp==0.6.0
scrypt==0.8.6
semantic-version==2.6.0
six==1.11.0
toolz==0.9.0
urllib3==1.22
web3==3.16.4
Werkzeug==0.13
(python3) Frederics-MacBook-Pro:plasma-mvp fredfortier$ python --version
Python 3.6.4
(python3) Frederics-MacBook-Pro:plasma-mvp fredfortier$ make root-chain
python deployment.py
Traceback (most recent call last):
  File "deployment.py", line 1, in <module>
    from plasma.root_chain.deployer import Deployer
  File "/Users/fredfortier/Code/sandbox/plasma-mvp/plasma/root_chain/deployer.py", line 2, in <module>
    import web3
  File "/Users/fredfortier/Code/sandbox/plasma-mvp/python3/lib/python3.6/site-packages/web3-3.16.4-py3.6.egg/web3/__init__.py", line 5, in <module>
    from web3.main import Web3
  File "/Users/fredfortier/Code/sandbox/plasma-mvp/python3/lib/python3.6/site-packages/web3-3.16.4-py3.6.egg/web3/main.py", line 6, in <module>
    from eth_utils import (
ImportError: cannot import name 'force_text'
make: *** [root-chain] Error 1

Add Apache 2.0 license headers

According to Applying the Apache License, Version 2.0:

Each original source document (code and documentation, but excluding the LICENSE and NOTICE files) SHOULD include a short license header at the top.

Here's what that license header should look like:

Copyright 2018 OmiseGO

Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at

    http://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.

Things to consider:

  • Some files have been contributed by users that have not signed any form of CLA. Should we have new and existing contributes sign a CLA?
  • The pre-Apache 2.0 licensed code is probably All Rights Reserved, although I'm not sure if this applies to code contributed by other people.

Make ChildChain stateful

As per the discussion at #32, it makes sense to have ChildChain maintain state. We've already gone ahead and made the CLI stateless as per #102.

Every new block to the child chain should be stored in some DB. We should abstract the DB (see pyethereum for an example) so that we can plug in any DB back-end. I think we'll probably also want an option to run the DB in-memory so we don't need to wipe everything before each unit test.

Validate.sol should verify each signature individually

Validate.sol currently assumes that both signatures on the inputs to a transaction will come from msg.sender. However, it's possible that the signatures come from another user or two different users entirely. Instead of assuming msg.sender, we should require that the owners of the signatures be provided.

Here's an example:

    /**
     * @dev Checks if the signatures on a transaction are valid
     * @param txHash Hash of the transaction to check
     * @param blknum1 Block number of the first input
     * @param owner1 Address the first signature should belong to
     * @param blknum2 Block number of the second input
     * @param owner2 Address the second signature should belong to
     * @param sigs Signatures to verify
     * @return true if the transaction is valid, false otherwise
     */
    function checkSigs(bytes32 txHash, uint256 blknum1, address owner1, uint256 blknum2, address owner2, bytes sigs)
        internal
        view
        returns (bool)
    {
        require(sigs.length % 65 == 0 && sigs.length <= 260);

        bytes memory sig1 = ByteUtils.slice(sigs, 0, 65);
        bytes memory sig2 = ByteUtils.slice(sigs, 65, 65);

        bool sig1valid = true;
        bool sig2valid = true;
        if (blknum1 > 0) {
            sig1valid = ECRecovery.recover(txHash, sig1) == owner1;
        } 
        if (blknum2 > 0) {
            sig2valid = ECRecovery.recover(txHash, sig2) == owner2;
        }

        return sig1valid && sig2valid;
    }

Add tests for child chain server endpoints

Tests need to be added for child chain endpoints specified in server.py to establish a sturdy foundation for when we start playing around with more complex Plasma chain designs.

Clean up unnecessary or missing imports/variables

Implement a fee structure

Plasma MVP does not currently take any fees for transactions. A fee structure will need to be implemented for Plasma MVP v0. The exact form of this fee structure is up for debate, depending on whether we decide to use implicit or explicit fees. This decision should not impact user experience. However, some considerations need to be taken into account before either is implemented.

To elaborate, explicit fees look like what Vitalik described in Minimum Viable Plasma:

[blknum1, txindex1, oindex1, sig1, # Input 1
 blknum2, txindex2, oindex2, sig2, # Input 2
 newowner1, denom1,                # Output 1
 newowner2, denom2,                # Output 2
 fee]

Here, the fees are made explicit as a separate field of the transaction.

Implicit fees look like Bitcoin-esque transactions where the fee is taken to be the difference between inputs and outputs. This would remove the fee component of the transaction.

The explicit design makes it more difficult to accidentally specify a $2.3m transaction fee. However, the implicit saves a few bytes per transaction and might be "cleaner". I have no preference between the two.

It should be possible to implement the structure around the fees without worrying about if this will be implicit or explicit.

Improve ChildChainService error handling

Errors are not handled in ChildChainService. An invalid request will simply result in the following KeyError:

KeyError: 'result'

This error occurs because ChildChainService expects each response to have a 'result' field:

    def send_request(self, method, args):
        payload = {
            "method": method,
            "params": args,
            "jsonrpc": "2.0",
            "id": 0,
        }
        response = requests.post(self.url, json=payload).json()
        return response["result"]

We should handle this gracefully, perhaps by passing the error back through the server and into the child chain service.

Require child chain validate transaction signatures

Child chain doesn't currently validate that the signatures on each input are valid. This should happen inside apply_transaction. The easiest way to check this is with a check similar to self.blocks[blknum].transaction_set[txindex].newowner1 == tx.sender1 for each input.

No such file or directory: 'pkg-config' during setup.py

When I try running python setup.py install, it seems that it mostly goes without any errors and then it fails with the error:

error: Setup script exited with error: [Errno 2] No such file or directory: 'pkg-config': 'pkg-config'

Any ideas why this is happening?

Protection against Ethereum reorgs is needed

Currently, reorg that leads to deposit block disappearing from the chain can invalidate operator's block if it is in the mempool. If such invalid block is mined, all users must exit.

Refactor CLI

I think the CLI could use a bit of a refactor. We currently use omg start to run the interface, but I think omg <command> <args> is a better UX and matches other similar CLIs

This is a relatively simple task.

Add a testing lang

We're developing increasingly complex tests with intricate setups. It makes sense to start thinking about a testing language, similar to the one in cbc-casper.

@DavidKnott suggested that a test vector in this language could look somewhat like:

Deposit1[Owner1, Amount1] Transfer1[Deposit1, Owner2, Amount1] Withdraw[Transfer1, Owner2]

This basically means that we could design a single set of test vectors to be parsed/tested by each implementation.

KeyError: 'abi' when making root

When running make root-chain I am getting this error:

 File "/workspace/plasma-mvp/plasma/root_chain/deployer.py", line 35, in compile_contract
    abi = compiled_sol['contracts'][file_name][contract_name]['abi']
KeyError: 'abi'
make: *** [root-chain] Error 1

Haven't been able to find anything about why this might be happening. Any thoughts?

Add more descriptive exceptions

We're currently handling a significant portion of our exceptions as AssertionError. This is bad practice because it means we end up with unit tests that look like this:

https://github.com/omisego/plasma-mvp/blob/cf479aa6a9ec5baf64b0ca64db521f657dfa78a4/tests/child_chain/test_child_chain.py#L45-L60

There's absolutely no way to determine if the AssertionError being caught in test#1 is actually the correct AssertionError. We should create better and more descriptive exceptions.

There's a few ways to do this properly:

  1. Continue to use AssertionError, but attach messages to the assert statement and verify those messages (samples thanks to @boolafish):

Modify the assert:

assert valid_signature, 'invalid signature'

Modify the test:

with pytest.raises(AssertionError) as e:
    child_chain.submit_block(block)
assert str(e.value) == 'invalid signature'
  1. Extend Exception with more descriptive errors, e.g.:
class InvalidBlockSignatureError(Exception):
    """Raise when a block is signed by anyone but the operator"""

I'm personally a fan of (2), but I couldn't find any sort of guide on which model to generally stick to.

Clean up unit tests

Our tests are starting to become extremely large. We should clean things up so they're easier to read and understand.

test_root_chain.py seems like a good place to start.

challengeExit() doesn't correctly verify a challenge

challengeExit(), reproduced below, is only checking that a later spend by a UTXO's owner exists and does not check that the spend is actually spending the exiting UTXO.

https://github.com/omisego/plasma-mvp/blob/4b119a80dd20e2dd8bb4b4cb2dda67d3b88d6f40/plasma/root_chain/contracts/RootChain/RootChain.sol#L167-L182

Challenges are valid in the case that a UTXO has either already been exited, that the UTXO was spent in a later transaction, or that the UTXO was created from an input that was already spent. So we really need to verify that there exists a valid transaction that spends the UTXO. Currently we're just verifying that there exists a valid transaction spent by the owner of the UTXO. This process should look like:

  1. Check that the challenge tx is included in the referenced block and that it has correct signatures.
  2. Check that the exiting UTXO is included as an input to the challenge tx OR that the challenge tx comes before the exiting UTXO and both have a common input.

Here's a test case that demonstrates the problem:

def test_invalid_challenge_exit(t, u, root_chain):
    owner, value_1, key = t.a1, 100, t.k1
    null_address = b'\x00' * 20

    # Create a deposit
    tx1 = Transaction(0, 0, 0, 0, 0, 0,
                      owner, value_1, null_address, 0, 0)
    tx_bytes1 = rlp.encode(tx1, UnsignedTransaction)
    root_chain.deposit(tx_bytes1, value=value_1)

    # Create an exit for the first deposit
    merkle = FixedMerkle(16, [tx1.merkle_hash], True)
    proof1 = merkle.create_membership_proof(tx1.merkle_hash)
    confirmSig1 = confirm_tx(tx1, root_chain.getChildChain(1)[0], key)
    sigs1 = tx1.sig1 + tx1.sig2 + confirmSig1
    exitId1 = 1 * 1000000000 + 0 * 10000 + 0
    root_chain.startExit(exitId1, tx_bytes1, proof1, sigs1, sender=key)

    # Create a second deposit
    tx2 = Transaction(0, 0, 0, 0, 0, 0,
                      owner, value_1, null_address, 0, 0)
    tx_bytes2 = rlp.encode(tx2, UnsignedTransaction)
    root_chain.deposit(tx_bytes2, value=value_1)

    # Spend the second (unrelated) deposit
    tx3 = Transaction(2, 0, 0, 0, 0, 0,
                      owner, value_1, null_address, 0, 0)
    tx3.sign1(key)
    tx_bytes3 = rlp.encode(tx3, UnsignedTransaction)

    merkle2 = FixedMerkle(16, [tx3.merkle_hash], True)
    proof2 = merkle2.create_membership_proof(tx3.merkle_hash)
    root_chain.submitBlock(merkle2.root, root_chain.currentChildBlock())

    confirmSig2 = confirm_tx(tx3, root_chain.getChildChain(3)[0], key)

    sigs2 = tx3.sig1 + tx3.sig2
    exitId2 = 3 * 1000000000 + 0 * 10000 + 0
    
    # The exit should exist before
    assert root_chain.exits(exitId1) == ['0x' + owner.hex(), 100, exitId1]
    assert root_chain.exitIds(exitId1) == exitId1

    # Challenge the exit with an unrelated spend
    with pytest.raises(TransactionFailed):
        root_chain.challengeExit(exitId2, exitId1, tx_bytes3, proof2, sigs2, confirmSig2)

    # The exit should also exist afterwards because this challenge is invalid
    assert root_chain.exits(exitId1) == ['0x' + owner.hex(), 100, exitId1]
    assert root_chain.exitIds(exitId1) == exitId1

Error when running make root-chain

Traceback (most recent call last):
  File "deployment.py", line 3, in <module>
    Deployer().create_contract("RootChain/RootChain.sol")
  File "/home/go/src/plasma-mvp/plasma/root_chain/deployer.py", line 54, in create_contract
    contract_instance = self.w3.eth.contract(abi, contract_address, ContractFactoryClass=ConciseContract)
TypeError: contract() takes from 1 to 2 positional arguments but 3 were given
make: *** [Makefile:11: root-chain] Error 1

TestRPC log is

Listening on localhost:8545
eth_accounts
eth_sendTransaction

  Transaction: 0x174ab053557367f27cf0ce051796e36bed0c0ff11ecc4616efda4d7ada7aec24
  Contract created: 0x1f63ad696aae56f34aabf2015e883128ca1ef018
  Gas usage: 3567286
  Block Number: 1
  Block Time: Thu Jan 18 2018 11:03:34 GMT+0000 (GMT)

eth_getTransactionReceipt

Upgrade to Web3.py v4

We should start thinking about the upgrade to Web3.py v4.

Impacted files:

This is probably a good time to refactor deployer.py.

Some potential things to look out for:

  • Web3.py v4 is having some trouble detecting events with Ganache CLI link
  • The Contracts API has changed slightly link

Refactor event names

[chore]

According to the Solidity style guide:

Events should be named using the CapWords style.

We're currently naming events in RootChain.sol with camelCase, we should change that.

Update and clean up README

The current README.md can probably be cleaned up a little bit. For example, the inputs to the CLI commands should be better documented:

deposit [amount] [key]

submit_block [key]

etc etc

Document design decisions

It seems useful to document design decisions. These could be placed in a more detailed elaboration of each of the individual "sub-projects" that make up this repository. This would help describe the differences between the implementation in this repository and the Minimal Viable Plasma specification.

More detailed documentation should also make it easier for users to understand the project from a high-level and (hopefully) contribute.

Pull transaction validation out of `apply_transaction`

Transaction validation is currently handled in a relatively messy way:

https://github.com/omisego/plasma-mvp/blob/530b78fbe01385c467838b17a41f1f2b04d708bf/plasma/child_chain/child_chain.py#L36-L53

This will only get messier once confirmation validation is implemented.

Each check is separated into its own method, and each method tends to make the same blknum == 0, oindex == 0 checks. It's probably easier to pull this out into a single method validate_transaction(tx) to make things clear.

finalizeExit() DoS attack

If transfer() fails in finalizeExit(), then the entire function reverts, stopping any future exits from being processes. The PQ essentially cannot pop off the malicious exit. One could easily exploit this by writing a contract that has a payable fall back function:

function() payable public { revert(); }

This can be solved by moving the transfer() function to a separate withdraw function that the owner must call. We would map each user's address to their balance, and the withdraw function will refund them.

  • Blockchain @ Berkeley Researcher

Prevent Repeatedly Exiting UTXO

References vulnerability found here: https://ethresear.ch/t/plasma-vulnerabiltity-sybil-txs-drained-contract/1654

Transaction must include the confirm signatures for the inputs being spent. If the confirm signatures are only ever sent to the receivers of UTXO's then one can create a chain of "Sybil Transactions" and then exit multiple times.
Additionally, If someone is offline for an extended amount of time and the sender of one of their UTXO's has already successfully exited, nothing currently stops them from simply exiting their invalid UTXO as well.

Proposed changes to fix the vulnerability:

  1. Include confirm signatures of inputs in transaction

  2. Include ability to challenge exit by proving that its input has already successfully exited.

  • Blockchain @ Berkeley Researcher

Update Travis build for `solc` and `ganache-cli`

We need to start unit testing parts of the project that rely on Ethereum. This includes, but isn't limited to, root_chain and now child_chain. As a result, we'll have to have an Ethereum node running.

The easiest and fastest way to test things is by running an instance of ganache-cli (aka TestRPC). This is already recommended for testing locally.

We also don't have solc on the docker container, so things break.

Something like this should work:

language: python

python:
  - "3.6"

cache: pip

env:
  NODE_VERSION="6"

install:
  - nvm install $NODE_VERSION
  - npm install --global ganache-cli
  - wget https://github.com/ethereum/solidity/releases/download/v0.4.18/solc-static-linux && chmod +x ./solc-static-linux && sudo mv solc-static-linux /usr/bin/solc
  - pip install --upgrade pip setuptools
  - make

script:
  - (ganache-cli &) && while ! curl -s localhost:8545 >/dev/null; do sleep 1; done
  - make test
  - make lint

Transaction Input Bug

Since inputCount is used to determine how many inputs were used in a transaction, if a user were to create a transaction with Input 1 zeroed out and Input 2 with a valid reference to a utxo. They would not be able to successfully withdraw from that transaction as Validate.sol would attempt to check for two valid inputs.

Perhaps enforcing valid transaction structuring on the child chain would be the best way to avoid this. Any input 1 field with all zeros should also imply that input 2 fields are also zero.

-Blockchain @ Berkeley Researcher

Bonded Exits

StartExit should require a bond proportional to the UTXO being exited to provide a stronger disincentive for invalid exit transactions and eliminates the burden on users to be vigilant of fraudulent exits from previous owners.
Since a successful challengeExit will transfer the bond to the sender of the challengeExit transaction, one can broadcast their confirmSigs to "fraud bounty hunters" who can challenge fraudelent exits on the user's behalf and claim the bond as a reward.

  • Blockchain @ Berkeley Researcher

Have Client automatically decode things

Client doesn't decode anything that it receives from ChildChainService. This means that everything using Client needs to manually decode its output.

For example, get_current_block returns the hex-encoded block:

    def get_current_block(self):
        return self.child_chain.get_current_block()

Instead, it should return the Block object:

import rlp
from ethereum import utils
...
    def get_current_block(self):
        encoded_block = self.child_chain.get_current_block()
        return rlp.decode(utils.decode_hex(encoded_block), Block)

Priority Queue is Broken

I was testing the PQ recently, and noticed that when the PQ is emptied, the minimum value will now become 0 and will always be zero. This issue is that delete heapList[currentSize]; only sets the value at that index to null (0 in the case of uint256).

Let's say you have a PQ initially with 5 items. Then all items are removed. The length of the list is still 5. So if you call insert on the empty PQ, the item is inserted at index 5, not index 1. When percUp(1) is called, the item is still stuck at the end.

The easy solution to this is to add the line
heapList.length = heapList.length.sub(1);
at the end of delMin() function.

  • Blockchain @ Berkeley Researcher

Client Command Broken Because of the RootChain Contract Changes

Although all tests run through without problems for me, some of the client commands, like deposit and withdraw are broken in the command line. I guess it's because RootChain.sol is updated. I've fixed the deposit command, which I changed the line 38 in file plasma/client/client.py
from:
self.root_chain.deposit(rlp.encode(transaction, UnsignedTransaction), transact={'from': '0x' + transaction.newowner1.hex(), 'value': transaction.amount1})
to:
self.root_chain.deposit(transact={'from': '0x' + transaction.newowner1.hex(), 'value': transaction.amount1})

I also tried to fix the withdraw command, but got revert error when running against the Ganache-cli. Anyone has a similar problem?

Block.merkilize_transaction_set should not be a property

Block currently specifies merkilize_transaction_set as a property, but it should probably be a function:

    @property
    def merkilize_transaction_set(self):
        hashed_transaction_set = [transaction.merkle_hash for transaction in self.transaction_set]
        self.merkle = FixedMerkle(16, hashed_transaction_set, hashed=True)
        return self.merkle.root

Integration tests for child_chain.py

We're currently just unit testing child_chain.py with a mock RootChain. We should add integration tests to make sure that the two actually work together.

Package name taken on PyPI

I was curious to see if the package was available on PyPI, and it turns out it's not, see https://pypi.python.org/pypi/plasma

Other than that, a quick look at the setup.py also shows the long_description as the contents of Readme.md, which will lose its formatting since PyPI by default assumes .rst instead of markdown.

Add child chain validation to the client

The command line interface is able to hit the child chain server and receive blocks up until the most recent block, the next step is to add validation on the client side to make sure that each block being received from the child chain is valid (because they're not everyone should exit).

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.