Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Feature/cli submit block #4

Open
wants to merge 18 commits into
base: master
Choose a base branch
from
Open
Changes from all commits
Commits
Show all changes
18 commits
Select commit Hold shift + click to select a range
7faf296
Can call the latest block from an instance of ethereum
maxrobot Jun 18, 2018
294747f
Adding in a testing framework
maxrobot Jun 19, 2018
4061564
got the CLI working and RPC stuff off in a different file.
maxrobot Jun 19, 2018
facb261
added the rlp encoding testing which was surprisingly painful and tes…
maxrobot Jun 19, 2018
c10346b
Ok we now can pull RLP encoded blocks :)
maxrobot Jun 19, 2018
957c3ee
Cleaned up the generation of RLP encoded blocks
maxrobot Jun 20, 2018
52fba22
Started creating the contract to actually verify signatures legitimately
maxrobot Jun 20, 2018
529efca
Merge pull request #2 from maxrobot/feature/rpc-calls
Jun 20, 2018
fa71842
Understand how to ecrecover stuff signed in the javascript modules pi…
maxrobot Jun 20, 2018
b474ad0
Initial inauthenticate block is there
maxrobot Jun 21, 2018
2c6be71
Another painful thing to figure out even though it was quite simple, …
maxrobot Jun 21, 2018
665779c
So everything is working as expected would be nice to handle the cont…
maxrobot Jun 21, 2018
62a8d2c
Not sure
maxrobot Jun 22, 2018
5a12e59
have funcitonality to query smart contracts from golang cli
maxrobot Jun 22, 2018
bf1469e
Have added the functionality to query the validators contract
maxrobot Jun 22, 2018
23b2e1e
Improved the CLI help and also the readme
maxrobot Jun 23, 2018
7a86b03
Just didnt want to see the bad link in the README
maxrobot Jun 24, 2018
5fe2666
Improved the readme and added the user accounts to the setup.json
maxrobot Jun 25, 2018
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
105 changes: 90 additions & 15 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,47 +1,122 @@
# Clique Block Verification
This repo allows you to set up a "Clique" proof of authority Ethereum blockchain with two separate peers who both engage in the sealing of blocks. The instructions are based on the tutorial of [Salanfe](https://hackernoon.com/setup-your-own-private-proof-of-authority-ethereum-network-with-geth-9a0a3750cda8) but has the more complicated parts already initialised.
# Block Validation Scheme
Block validation scheme is a set of smart contract which aim to be able to ensure that block headers submitted to the contract are sealed by an approved partie(s). The motivation behind this is to update the state of a Clique PoA or Istanbul PBFT chain onto any other blockchain. To do this we first need to know which blocks are valid - dependent on the definition of a valid by the underlying consensus algorithm.

Once the network has been launched the tests validate that the blocks have been signed by a known validator.
At this stage a Clique PoA chain is launched and then the block headers updated to the smart contract which is deployed on itself. However in the near future this will be extended to update the Clique header onto any other chain. For a full description and roadmap of the project please refer to the Clearmatics [Ion-Stage-2 Wiki](https://github.com/clearmatics/ion/wiki/Ion-Stage-2---Proposal#validation).

## Launch the Network
In order to run the network first install an instance of [geth](https://geth.ethereum.org/downloads/) the directory structure and accounts have been set up a priori. Hence all that is required to launch the network is to follow these instructions:
## Running the Project
This project contains a number of components:
* Validation smart contract and tests
* Clique _proof of authority_ test network
* Command Line Interface for interacting with the smart contract

### Initialise Nodes
In order to use the smart contracts and run the tests it is necessary to first initialise the test network.

***Note:*** that as the contract searches for specific parts of the block header that only exist in Clique, Ganache or Ethash chains cannot be used.

### Initialise the Test Network
The instructions are based on the tutorial of [Salanfe](https://hackernoon.com/setup-your-own-private-proof-of-authority-ethereum-network-with-geth-9a0a3750cda8) but has the more complicated parts already initialised.

First install an instance of [geth](https://geth.ethereum.org/downloads/) and clone the repo.

Having cloned and entered the repo:
```
$ git clone [email protected]:maxrobot/validation.git
$ cd /path/to/validation
```

Now run the command:
```
$ tree -L 1
```

Which hopefully returns this:
```
├── abi
├── build
├── contracts
├── migrations
├── package.json
├── poa-network
├── README.md
├── src
├── test
└── truffle.js
```

#### Initialise Nodes
Network files are found in the `/path/to/validation/poa-network` directory. Enter the poa-network directory and initialise the two nodes which will be sealing blocks:
```
$ cd /path/to/validation/poa-network
$ geth --datadir node1/ init genesis.json
$ geth --datadir node2/ init genesis.json
```

### Launch the Bootnode
#### Launch the Bootnode
The boot node tells the peers how to connect with each other. In another terminal instance run:
```
$ bootnode -nodekey boot.key -verbosity 9 -addr :30310
$ INFO [06-07|12:16:21] UDP listener up self=enode://dcb1dbf8d710eb7d10e0e2db1e6d3370c4b048efe47c7a85c4b537b60b5c11832ef25f026915b803e928c1d93f01b853131e412c6308c4c6141d1504c78823c8@[::]:30310
```
As the peers communicate this terminal should fill with logs.

### Start and Attach to the Nodes
Each node must be launch, either as a background operation or on separate terminal instances. For node 1:
***Note:*** bootnode may not be found if go-ethereum/geth is not installed fully.

#### Start and Attach to the Nodes
Each node must be launched either as a background operation or on separate terminal instances. Thus from the poa-network directory for node 1 run:
```
$ geth --datadir node1/ --syncmode 'full' --port 30311 --rpc --rpcaddr 'localhost' --rpcport 8501 --bootnodes 'enode://dcb1dbf8d710eb7d10e0e2db1e6d3370c4b048efe47c7a85c4b537b60b5c11832ef25f026915b803e928c1d93f01b853131e412c6308c4c6141d1504c78823c8@127.0.0.1:30310' --networkid 1515 --gasprice '1' -unlock '0x2be5ab0e43b6dc2908d5321cf318f35b80d0c10d' --password node1/password.txt --mine
```
then attach,
then attach:
```
$ geth attach node1/geth.ipc
```
node 2:
and again for node 2:
```
$ geth --datadir node2/ --syncmode 'full' --port 30312 --rpc --rpcaddr 'localhost' --rpcport 8502 --bootnodes 'enode://dcb1dbf8d710eb7d10e0e2db1e6d3370c4b048efe47c7a85c4b537b60b5c11832ef25f026915b803e928c1d93f01b853131e412c6308c4c6141d1504c78823c8@127.0.0.1:30310' --networkid 1515 --gasprice '0' -unlock '0x8671e5e08d74f338ee1c462340842346d797afd3' --password node2/password.txt --mine
```
again attach,
attaching:
```
$ geth attach node2/geth.ipc
```
Notice that IPC has been used to attach to the nodes, this allows the clique module to be used.
***Note:*** that IPC has been used to attach to the nodes, this allows the clique module to be used.

## Test
After launching the network:
### Testing Contracts
After launching the network, from the root of the repository:
```
$ npm install
$ truffle test
```

### Ion Command Line Interface
The Ion CLI is a tool for handling the passing of block headers between to blockchains written in Golang to leverage the extensive ethereum libraries. It is not a critical part of the Ion infrastructure rather is just an open utility that people can extend and use as they see fit.

In its current form the Ion CLI allows the user to connect to two separate blockchains, via RPC, and submit block headers to a validation contract.

#### Running the CLI
As mentioned in the project description this simple implementation of the validation contract is active only on a single blockchain, however the CLI is simulating the passing of the headers to and from as if it were between separate chains.

Having followed the instructions on how to setup a Clique blockchain, which is hosted on `127.0.0.1:8502`, and running another chain on `127.0.0.1:8501` we can attach the CLI.

```
$ cd /path/to/validation/src
$ make build
```
Assuming a successful build the tool can be run,
```
$ ./ion-cli [/path/to/setup.json]
===============================================================
Ion Command Line Interface
RPC Client [to]:
Listening on: 127.0.0.1:8501
User Account: 0x2be5ab0e43b6dc2908d5321cf318f35b80d0c10d
Ion Contract: 0xb9fd43a71c076f02d1dbbf473c389f0eacec559f
RPC Client [from]:
Listening on: 127.0.0.1:8502
User Account: 0x8671e5e08d74f338ee1c462340842346d797afd3
===============================================================
>>>
```


1 change: 1 addition & 0 deletions abi/ECVerify.abi
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
[]
1 change: 1 addition & 0 deletions abi/ECVerify.bin
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
604c602c600b82828239805160001a60731460008114601c57601e565bfe5b5030600052607381538281f30073000000000000000000000000000000000000000030146080604052600080fd00a165627a7a72305820acb6e646edaf05c92bfe7c53e47edcf3f96a2d5cf3d55019662508f330c1d89f0029
1 change: 1 addition & 0 deletions abi/Migrations.abi
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
[{"constant":false,"inputs":[{"name":"new_address","type":"address"}],"name":"upgrade","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[],"name":"last_completed_migration","outputs":[{"name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"owner","outputs":[{"name":"","type":"address"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"name":"completed","type":"uint256"}],"name":"setCompleted","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"inputs":[],"payable":false,"stateMutability":"nonpayable","type":"constructor"}]
1 change: 1 addition & 0 deletions abi/Migrations.bin
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
608060405234801561001057600080fd5b50336000806101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055506102f8806100606000396000f300608060405260043610610062576000357c0100000000000000000000000000000000000000000000000000000000900463ffffffff1680630900f01014610067578063445df0ac146100aa5780638da5cb5b146100d5578063fdacd5761461012c575b600080fd5b34801561007357600080fd5b506100a8600480360381019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190505050610159565b005b3480156100b657600080fd5b506100bf610241565b6040518082815260200191505060405180910390f35b3480156100e157600080fd5b506100ea610247565b604051808273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390f35b34801561013857600080fd5b506101576004803603810190808035906020019092919050505061026c565b005b60008060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16141561023d578190508073ffffffffffffffffffffffffffffffffffffffff1663fdacd5766001546040518263ffffffff167c010000000000000000000000000000000000000000000000000000000002815260040180828152602001915050600060405180830381600087803b15801561022457600080fd5b505af1158015610238573d6000803e3d6000fd5b505050505b5050565b60015481565b6000809054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b6000809054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614156102c957806001819055505b505600a165627a7a7230582090db59736857b6a69a78d054d092a30ff8e90f10f6f3bca8afc3d994c885eedd0029
1 change: 1 addition & 0 deletions abi/Recover.abi
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
[{"constant":false,"inputs":[{"name":"header","type":"bytes"},{"name":"prefixHeader","type":"bytes"},{"name":"prefixExtraData","type":"bytes"}],"name":"ExtractHash","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"name":"header","type":"bytes"},{"name":"sig","type":"bytes"}],"name":"VerifyBlock","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"name":"data","type":"bytes32"},{"name":"sig","type":"bytes"}],"name":"VerifyHash","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"inputs":[],"payable":false,"stateMutability":"nonpayable","type":"constructor"},{"anonymous":false,"inputs":[{"indexed":false,"name":"owner","type":"address"}],"name":"broadcastSig","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"name":"header","type":"bytes"},{"indexed":false,"name":"parentHash","type":"bytes"},{"indexed":false,"name":"rootHash","type":"bytes"}],"name":"broadcastHashData","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"name":"blockHash","type":"bytes32"}],"name":"broadcastHash","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"name":"header","type":"bytes"}],"name":"test","type":"event"}]
1 change: 1 addition & 0 deletions abi/Recover.bin
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
608060405234801561001057600080fd5b50336000806101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550610b11806100606000396000f300608060405260043610610057576000357c0100000000000000000000000000000000000000000000000000000000900463ffffffff168063b0e7308f1461005c578063d09ca90414610151578063fdace1be14610200575b600080fd5b34801561006857600080fd5b5061014f600480360381019080803590602001908201803590602001908080601f0160208091040260200160405190810160405280939291908181526020018383808284378201915050505050509192919290803590602001908201803590602001908080601f0160208091040260200160405190810160405280939291908181526020018383808284378201915050505050509192919290803590602001908201803590602001908080601f0160208091040260200160405190810160405280939291908181526020018383808284378201915050505050509192919290505050610277565b005b34801561015d57600080fd5b506101fe600480360381019080803590602001908201803590602001908080601f0160208091040260200160405190810160405280939291908181526020018383808284378201915050505050509192919290803590602001908201803590602001908080601f016020809104026020016040519081016040528093929190818152602001838380828437820191505050505050919291929050505061055e565b005b34801561020c57600080fd5b506102756004803603810190808035600019169060200190929190803590602001908201803590602001908080601f0160208091040260200160405190810160405280939291908181526020018383808284378201915050505050509192919290505050610840565b005b60008060608060608060606000808b5198508b6040518082805190602001908083835b6020831015156102bf578051825260208201915060208101905060208303925061029a565b6001836020036101000a038019825116818451168082178552505050505050905001915050604051809103902097507fcd7ee33e1a630d6301d87631aab1d4ddce7e1942593cd2689aa989f76d67cf018860405180826000191660001916815260200191505060405180910390a1608d89036040519080825280601f01601f1916602001820160405280156103635781602001602082028038833980820191505090505b509650601f6040519080825280601f01601f19166020018201604052801561039a5781602001602082028038833980820191505090505b50955060416040519080825280601f01601f1916602001820160405280156103d15781602001602082028038833980820191505090505b509450602a6040519080825280601f01601f1916602001820160405280156104085781602001602082028038833980820191505090505b509350610419878d60008a516108b6565b600260218801600260208e016004610bb8fa5061043c868d608c8c0389516108b6565b600160208701600160208d016004610bb8fa5061045f848d602a8c0387516108b6565b61046a878786610971565b9250826040518082805190602001908083835b6020831015156104a2578051825260208201915060208101905060208303925061047d565b6001836020036101000a038019825116818451168082178552505050505050905001915050604051809103902091506104e1858d606b8c0388516108b6565b6104eb8286610a1d565b90507fba2fe28067a0918af64c5359b1579f887bf1479dd3163c7e5d456314168854a581604051808273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390a1505050505050505050505050565b600080606080856040518082805190602001908083835b60208310151561059a5780518252602082019150602081019050602083039250610575565b6001836020036101000a038019825116818451168082178552505050505050905001915050604051809103902093506105d38486610a1d565b925060206040519080825280601f01601f1916602001820160405280156106095781602001602082028038833980820191505090505b50915060206040519080825280601f01601f1916602001820160405280156106405781602001602082028038833980820191505090505b5090506106518287600460206108b6565b61065f8187605b60206108b6565b7f8511795469a13c04a2bc22c3f1309fc0bd918a0a25a3e7e222a0417b719274c786838360405180806020018060200180602001848103845287818151815260200191508051906020019080838360005b838110156106cb5780820151818401526020810190506106b0565b50505050905090810190601f1680156106f85780820380516001836020036101000a031916815260200191505b50848103835286818151815260200191508051906020019080838360005b83811015610731578082015181840152602081019050610716565b50505050905090810190601f16801561075e5780820380516001836020036101000a031916815260200191505b50848103825285818151815260200191508051906020019080838360005b8381101561079757808201518184015260208101905061077c565b50505050905090810190601f1680156107c45780820380516001836020036101000a031916815260200191505b50965050505050505060405180910390a17fba2fe28067a0918af64c5359b1579f887bf1479dd3163c7e5d456314168854a583604051808273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390a1505050505050565b600061084c8383610a1d565b90507fba2fe28067a0918af64c5359b1579f887bf1479dd3163c7e5d456314168854a581604051808273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390a1505050565b60008090505b8181101561096a57838184018151811015156108d457fe5b9060200101517f010000000000000000000000000000000000000000000000000000000000000090047f010000000000000000000000000000000000000000000000000000000000000002858281518110151561092d57fe5b9060200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916908160001a90535080806001019150506108bc565b5050505050565b606060008060008060008060608a5196508951955060208701945088519350600260208888010101925060028487890101019150816040519080825280601f01601f1916602001820160405280156109d85781602001602082028038833980820191505090505b50905086602082018860208e016004610bb8fa50858582018760208d016004610bb8fa50838382018560208c016004610bb8fa50809750505050505050509392505050565b60008060008060418551141515610a3357600080fd5b6020850151925060408501519150606085015160001a9050601b8160ff161015610a5e57601b810190505b601b8160ff161480610a735750601c8160ff16145b1515610a7e57600080fd5b610a8a86828585610a95565b935050505092915050565b60008060006040518781528660208201528560408201528460608201526020816080836001610bb8fa9250805191505060011515821515141515610ad857600080fd5b80925050509493505050505600a165627a7a7230582084747b0b9ea8d1285e7c7714b82fb8ff314f3245d9b3e8132f7679cf08b7ca2b0029
1 change: 1 addition & 0 deletions abi/Validation.abi
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
[{"constant":false,"inputs":[{"name":"header","type":"bytes"},{"name":"prefixHeader","type":"bytes"},{"name":"prefixExtraData","type":"bytes"}],"name":"ValidateBlock","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[],"name":"GetValidators","outputs":[{"name":"_validators","type":"address[]"}],"payable":false,"stateMutability":"view","type":"function"},{"inputs":[{"name":"_validators","type":"address[]"}],"payable":false,"stateMutability":"nonpayable","type":"constructor"},{"anonymous":false,"inputs":[{"indexed":false,"name":"owner","type":"address"}],"name":"broadcastSig","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"name":"header","type":"bytes"},{"indexed":false,"name":"parentHash","type":"bytes"},{"indexed":false,"name":"rootHash","type":"bytes"}],"name":"broadcastHashData","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"name":"blockHash","type":"bytes32"}],"name":"broadcastHash","type":"event"}]
1 change: 1 addition & 0 deletions abi/Validation.bin
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
608060405234801561001057600080fd5b506040516109d73803806109d7833981018060405281019080805182019291905050506000336000806101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550600090505b815181101561017c576001828281518110151561009357fe5b9060200190602002015190806001815401808255809150509060018203906000526020600020016000909192909190916101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555050600160026000848481518110151561011457fe5b9060200190602002015173ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81548160ff021916908315150217905550808060010191505061007a565b505061084a8061018d6000396000f30060806040526004361061004c576000357c0100000000000000000000000000000000000000000000000000000000900463ffffffff168063aae933e414610051578063d405af3d14610146575b600080fd5b34801561005d57600080fd5b50610144600480360381019080803590602001908201803590602001908080601f0160208091040260200160405190810160405280939291908181526020018383808284378201915050505050509192919290803590602001908201803590602001908080601f0160208091040260200160405190810160405280939291908181526020018383808284378201915050505050509192919290803590602001908201803590602001908080601f01602080910402602001604051908101604052809392919081815260200183838082843782019150505050505091929192905050506101b2565b005b34801561015257600080fd5b5061015b610561565b6040518080602001828103825283818151815260200191508051906020019060200280838360005b8381101561019e578082015181840152602081019050610183565b505050509050019250505060405180910390f35b60008060608060608060606000808b5198508b6040518082805190602001908083835b6020831015156101fa57805182526020820191506020810190506020830392506101d5565b6001836020036101000a038019825116818451168082178552505050505050905001915050604051809103902097507fcd7ee33e1a630d6301d87631aab1d4ddce7e1942593cd2689aa989f76d67cf018860405180826000191660001916815260200191505060405180910390a1608d89036040519080825280601f01601f19166020018201604052801561029e5781602001602082028038833980820191505090505b509650601f6040519080825280601f01601f1916602001820160405280156102d55781602001602082028038833980820191505090505b50955060416040519080825280601f01601f19166020018201604052801561030c5781602001602082028038833980820191505090505b509450602a6040519080825280601f01601f1916602001820160405280156103435781602001602082028038833980820191505090505b509350610354878d60008a516105ef565b600260218801600260208e016004610bb8fa50610377868d608c8c0389516105ef565b600160208701600160208d016004610bb8fa5061039a848d602a8c0387516105ef565b6103a58787866106aa565b9250826040518082805190602001908083835b6020831015156103dd57805182526020820191506020810190506020830392506103b8565b6001836020036101000a0380198251168184511680821785525050505050509050019150506040518091039020915061041c858d606b8c0388516105ef565b6104268286610756565b905060011515600260008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900460ff1615151415156104f0576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260178152602001807f5369676e6572206e6f7420612076616c696461746f722100000000000000000081525060200191505060405180910390fd5b7fba2fe28067a0918af64c5359b1579f887bf1479dd3163c7e5d456314168854a581604051808273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390a1505050505050505050505050565b606060018054806020026020016040519081016040528092919081815260200182805480156105e557602002820191906000526020600020905b8160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001906001019080831161059b575b5050505050905090565b60008090505b818110156106a3578381840181518110151561060d57fe5b9060200101517f010000000000000000000000000000000000000000000000000000000000000090047f010000000000000000000000000000000000000000000000000000000000000002858281518110151561066657fe5b9060200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916908160001a90535080806001019150506105f5565b5050505050565b606060008060008060008060608a5196508951955060208701945088519350600260208888010101925060028487890101019150816040519080825280601f01601f1916602001820160405280156107115781602001602082028038833980820191505090505b50905086602082018860208e016004610bb8fa50858582018760208d016004610bb8fa50838382018560208c016004610bb8fa50809750505050505050509392505050565b6000806000806041855114151561076c57600080fd5b6020850151925060408501519150606085015160001a9050601b8160ff16101561079757601b810190505b601b8160ff1614806107ac5750601c8160ff16145b15156107b757600080fd5b6107c3868285856107ce565b935050505092915050565b60008060006040518781528660208201528560408201528460608201526020816080836001610bb8fa925080519150506001151582151514151561081157600080fd5b80925050509493505050505600a165627a7a72305820bfdda3defd1a9101b13153fe900905c379572f205ad37b4197c70cdd78be35e20029
2,459 changes: 2,459 additions & 0 deletions build/contracts/ECVerify.json

Large diffs are not rendered by default.

1,387 changes: 1,387 additions & 0 deletions build/contracts/Migrations.json

Large diffs are not rendered by default.

9,861 changes: 9,212 additions & 649 deletions build/contracts/Recover.json

Large diffs are not rendered by default.

8,881 changes: 8,881 additions & 0 deletions build/contracts/Validation.json

Large diffs are not rendered by default.

122 changes: 122 additions & 0 deletions contracts/Validation.sol
Original file line number Diff line number Diff line change
@@ -0,0 +1,122 @@
// Copyright (c) 2016-2018 Clearmatics Technologies Ltd
// SPDX-License-Identifier: LGPL-3.0+
pragma solidity ^0.4.23;

import "./ECVerify.sol";

contract Validation {
address Owner;

event broadcastSig(address owner);
event broadcastHashData(bytes header, bytes parentHash, bytes rootHash);
event broadcastHash(bytes32 blockHash);

address[] validators;

struct BlockHeader {
bytes32 prevBlockHash;
}

mapping (bytes32 => BlockHeader) public m_blockheaders;
mapping( address => bool ) m_validators;

/*
* @param _validators list of validators at block 0
*/
constructor (address[] _validators) public {
Owner = msg.sender;
for (uint i = 0; i < _validators.length; i++) {
validators.push(_validators[i]);
m_validators[_validators[i]] = true;
}
}

/*
* Returns the validators array
*/
function GetValidators() public view returns (address[] _validators) {
return validators;
}

/*
* @param header header rlp encoded, with extraData signatures removed
* @param prefixHeader the new prefix for the signed hash header
* @param prefixExtraData the new prefix for the extraData field
*/
function ValidateBlock(bytes header, bytes prefixHeader, bytes prefixExtraData) public {
uint256 length = header.length;
bytes32 blockHash = keccak256(header);

emit broadcastHash(blockHash);

bytes memory headerStart = new bytes(length - 141);
bytes memory extraData = new bytes(31);
bytes memory extraDataSig = new bytes(65);
bytes memory headerEnd = new bytes(42);

// Extract the start of the header and replace the length
extractData(headerStart, header, 0, headerStart.length);
assembly {
let ret := staticcall(3000, 4, add(prefixHeader, 32), 2, add(headerStart, 33), 2)
}

// Extract the real extra data and create the signed hash
extractData(extraData, header, length-140, extraData.length);
assembly {
let ret := staticcall(3000, 4, add(prefixExtraData, 32), 1, add(extraData, 32), 1)
}

// Extract the end of the header
extractData(headerEnd, header, length-42, headerEnd.length);
bytes memory newHeader = mergeHash(headerStart, extraData, headerEnd);

bytes32 hashData = keccak256(newHeader);

// Extract the signature of the hash create above
extractData(extraDataSig, header, length-107, extraDataSig.length);

address sig_addr = ECVerify.ecrecovery(hashData, extraDataSig);
require(m_validators[sig_addr]==true, "Signer not a validator!");

emit broadcastSig(sig_addr);

}

function mergeHash(bytes headerStart, bytes extraData, bytes headerEnd) internal view returns (bytes output) {
// Get the lengths sorted because they're needed later...
uint256 headerStartLength = headerStart.length;
uint256 extraDataLength = extraData.length;
uint256 extraDataStart = headerStartLength + 32;
uint256 headerEndLength = headerEnd.length;
uint256 headerEndStart = extraDataLength + headerStartLength + 32 + 2;
uint256 newLength = headerStartLength + extraDataLength + headerEndLength + 2; // extra two is for the prefix
bytes memory header = new bytes(newLength);


// Add in the first part of the header
assembly {
let ret := staticcall(3000, 4, add(headerStart, 32), headerStartLength, add(header, 32), headerStartLength)
}
assembly {
let ret := staticcall(3000, 4, add(extraData, 32), extraDataLength, add(header, extraDataStart), extraDataLength)
}
assembly {
let ret := staticcall(3000, 4, add(headerEnd, 32), headerEndLength, add(header, headerEndStart), headerEndLength)
}

output = header;
}

/*
* @param data memory allocation for the data you need to extract
* @param sig array from which the data should be extracted
* @param start index which the data starts within the byte array
* @param length total length of the data to be extracted
*/
function extractData(bytes data, bytes input, uint start, uint length) private pure {
for (uint i=0; i<length; i++) {
data[i] = input[start+i];
}
}

}
3 changes: 3 additions & 0 deletions migrations/2_deploy_contracts.js
Original file line number Diff line number Diff line change
@@ -1,9 +1,12 @@
const Recover = artifacts.require("Recover");
const Validation = artifacts.require("Validation");

module.exports = async (deployer) => {
try {
deployer.deploy(Recover)
.then(() => Recover.deployed)
.then(() => deployer.deploy(Validation, ["0x2be5ab0e43b6dc2908d5321cf318f35b80d0c10d", "0x8671e5e08d74f338ee1c462340842346d797afd3"]))
.then(() => Validation.deployed)
} catch(err) {
console.log('ERROR on deploy:',err);
}
3 changes: 3 additions & 0 deletions package.json
Original file line number Diff line number Diff line change
@@ -9,6 +9,9 @@
"dependencies": {
"babel-preset-node6": "^11.0.0",
"crypto-js": "^3.1.9-1",
"elliptic": "^6.4.0",
"ethereumjs-util": "^5.2.0",
"ethjs-util": "^0.1.6",
"rlp": "^2.0.0",
"solc": "^0.4.23",
"solhint": "^1.1.10",
Empty file removed poa-network/node1/geth/LOCK
Empty file.
Binary file removed poa-network/node1/geth/chaindata/000002.ldb
Binary file not shown.
Binary file removed poa-network/node1/geth/chaindata/000003.log
Binary file not shown.
1 change: 0 additions & 1 deletion poa-network/node1/geth/chaindata/CURRENT

This file was deleted.

Empty file.
16 changes: 0 additions & 16 deletions poa-network/node1/geth/chaindata/LOG

This file was deleted.

Binary file removed poa-network/node1/geth/chaindata/MANIFEST-000004
Binary file not shown.
Binary file removed poa-network/node1/geth/lightchaindata/000001.log
Binary file not shown.
1 change: 0 additions & 1 deletion poa-network/node1/geth/lightchaindata/CURRENT

This file was deleted.

Empty file.
6 changes: 0 additions & 6 deletions poa-network/node1/geth/lightchaindata/LOG

This file was deleted.

Binary file removed poa-network/node1/geth/lightchaindata/MANIFEST-000000
Binary file not shown.
1 change: 0 additions & 1 deletion poa-network/node1/geth/nodekey

This file was deleted.

Binary file removed poa-network/node1/geth/nodes/000001.log
Binary file not shown.
1 change: 0 additions & 1 deletion poa-network/node1/geth/nodes/CURRENT

This file was deleted.

Empty file removed poa-network/node1/geth/nodes/LOCK
Empty file.
6 changes: 0 additions & 6 deletions poa-network/node1/geth/nodes/LOG

This file was deleted.

Binary file removed poa-network/node1/geth/nodes/MANIFEST-000000
Binary file not shown.
Binary file removed poa-network/node1/geth/transactions.rlp
Binary file not shown.
Empty file removed poa-network/node2/geth/LOCK
Empty file.
Binary file removed poa-network/node2/geth/chaindata/000002.ldb
Binary file not shown.
Binary file removed poa-network/node2/geth/chaindata/000003.log
Binary file not shown.
1 change: 0 additions & 1 deletion poa-network/node2/geth/chaindata/CURRENT

This file was deleted.

Empty file.
16 changes: 0 additions & 16 deletions poa-network/node2/geth/chaindata/LOG

This file was deleted.

Binary file removed poa-network/node2/geth/chaindata/MANIFEST-000004
Binary file not shown.
Binary file removed poa-network/node2/geth/lightchaindata/000001.log
Binary file not shown.
1 change: 0 additions & 1 deletion poa-network/node2/geth/lightchaindata/CURRENT

This file was deleted.

Empty file.
6 changes: 0 additions & 6 deletions poa-network/node2/geth/lightchaindata/LOG

This file was deleted.

Binary file removed poa-network/node2/geth/lightchaindata/MANIFEST-000000
Binary file not shown.
1 change: 0 additions & 1 deletion poa-network/node2/geth/nodekey

This file was deleted.

Binary file removed poa-network/node2/geth/nodes/000001.log
Binary file not shown.
1 change: 0 additions & 1 deletion poa-network/node2/geth/nodes/CURRENT

This file was deleted.

Empty file removed poa-network/node2/geth/nodes/LOCK
Empty file.
6 changes: 0 additions & 6 deletions poa-network/node2/geth/nodes/LOG

This file was deleted.

Binary file removed poa-network/node2/geth/nodes/MANIFEST-000000
Binary file not shown.
Empty file.
10 changes: 5 additions & 5 deletions src/Makefile
Original file line number Diff line number Diff line change
@@ -4,10 +4,10 @@ PACKAGES = $(shell find ./ -type d -not -path "./vendor" -not -path "./vendor/*"
SHELL=/bin/bash

clean:
@rm -f cli-tool
@rm -f ion-cli

#test:
# @go test ./... -v
test:
@go test ./... -v

format:
@gofmt -s -w ${GOFILES_NOVENDOR}
@@ -19,8 +19,8 @@ coverage:
tail -n +2 coverage.out >> coverage-all.out;)
go tool cover -html=coverage-all.out

run:
@go build -o cli-tool .
build:
@go build -o ion-cli .

check:
@if [ -n "$(shell gofmt -l ${GOFILES_NOVENDOR})" ]; then \
591 changes: 591 additions & 0 deletions src/Validation/Validation.go

Large diffs are not rendered by default.

22 changes: 22 additions & 0 deletions src/block.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
{
"parentHash": "0xad34f0f919e4b06b18b0c674b8b9f6738a4878c76e837c8f31a2079f21dced1c",
"difficulty": "2",
"extraData": "0xd78301080a846765746887676f312e392e33856c696e75780000000000000000e0ac79c5577889dfb5745ace9c5dfebe1a11bb19ced9b98b427e7bd4c85765ce17154e658440915743ec442fb64756483bc592616754d13a3c62fce5a56ac9f501",
"gasLimit": "16614106",
"gasUsed": "0",
"hash": "0xd1d7abeb1345861e0103a24a239c178ccf930b069e50f2697d82fdd3496746ab",
"logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000",
"miner": "0x0000000000000000000000000000000000000000",
"mixHash": "0x0000000000000000000000000000000000000000000000000000000000000000",
"nonce": "0x0000000000000000",
"number": "10",
"receiptsRoot": "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421",
"sha3Uncles": "0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347",
"size": "606",
"stateRoot": "0xdb37435caa1fca7e1aa5b4da1c69fdf1d127232519eb3b1b5069825e6c62f5dc",
"timestamp": "1529396972",
"totalDifficulty": "21",
"transactions": [],
"transactionsRoot": "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421",
"uncles": []
}
Binary file removed src/cli-tool
Binary file not shown.
137 changes: 126 additions & 11 deletions src/cli/cli.go
Original file line number Diff line number Diff line change
@@ -3,31 +3,121 @@
package cli

import (
// "strings"
"fmt"
"log"
"strconv"

"github.com/abiosoft/ishell"
// "gitlab.clearmatics.net/dev/boe-poc/src/api"
// "gitlab.clearmatics.net/dev/boe-poc/src/config"
"github.com/ethereum/go-ethereum/accounts/abi/bind"
"github.com/ethereum/go-ethereum/common"
"github.com/ethereum/go-ethereum/ethclient"

"github.com/validation/src/Validation"
"github.com/validation/src/config"
)

func Launch() {
// Launch - definition of commands and creates the iterface
func Launch(setup config.Setup) {
// by default, new shell includes 'exit', 'help' and 'clear' commands.
shell := ishell.New()

// display welcome info.
shell.Println("Block Validation CLI Tool")
// Connect to the RPC Client
client, err := ethclient.Dial("http://" + setup.AddrTo + ":" + setup.PortTo)
if err != nil {
log.Fatalf("could not create RPC client: %v", err)
}

// Initialise the contract
address := common.HexToAddress(setup.Ion)
validation, err := Validation.NewValidation(address, client)
if err != nil {
log.Fatal(err)
}

printInfo(setup)

// Get the latest block number
shell.AddCmd(&ishell.Cmd{
Name: "latestBlock",
Help: "Returns latest block number, arguments: latestBlock",
Func: func(c *ishell.Context) {
c.Println("===============================================================")
c.Println("Get latest block number:")
latestBlock(client)
c.Println("===============================================================")
},
})

// display specific account balance
// Get block N
shell.AddCmd(&ishell.Cmd{
Name: "getBlock",
Help: "get an ethereum block from a chain",
Help: "Returns a block header, arguments: getBlock [integer]",
Func: func(c *ishell.Context) {
c.Println("===============================================================")
if len(c.Args) == 0 {
c.Println("Input argument required, e.g.: getBlock 10")
} else if len(c.Args) > 1 {
c.Println("Only enter single argument")
} else {
getBlock(client, c.Args[0])
}
c.Println("===============================================================")
},
})

shell.AddCmd(&ishell.Cmd{
Name: "getValidators",
Help: "Queries the validator contract for the whitelist of validators",
Func: func(c *ishell.Context) {
c.Println("===============================================================")
result, err := validation.GetValidators(&bind.CallOpts{})
if err != nil {
fmt.Printf("Error: %s", err)
return
}
c.Println("Validators Whitelist:")
c.Printf("%x\n", result)

c.Println("===============================================================")
},
})

// Get block N and spew out the RLP encoded block
shell.AddCmd(&ishell.Cmd{
Name: "rlpBlock",
Help: "Returns RLP encoded block header, arguments: rlpBlock [integer]",
Func: func(c *ishell.Context) {
c.Println("===============================================================")
if len(c.Args) == 0 {
c.Println("Input argument required, e.g.: rlpBlock 10")
} else if len(c.Args) > 1 {
c.Println("Only enter single argument")
} else {
c.Println("RLP encode block: " + c.Args[0])
rlpEncodeBlock(client, c.Args[0])
}
c.Println("===============================================================")
},
})

shell.AddCmd(&ishell.Cmd{
Name: "submitRlpBlock",
Help: "Returns the RLP block header, signed block prefix, extra data prefix and submits to validation contract, arguments: submitRlpBlock [integer]",
Func: func(c *ishell.Context) {
c.Println("===============================================================")
c.Println("Get block:")
if len(c.Args) > 1 {
if len(c.Args) == 0 {
c.Println("Choose a block.")
} else if len(c.Args) > 1 {
c.Println("Too many arguments entered.")
} else {
c.Println(c.Args[0])
c.Println("RLP encode block: " + c.Args[0])
encodedBlock, prefixBlock, prefixExtra := calculateRlpEncoding(client, c.Args[0])
res, err := validation.ValidateBlock(&bind.TransactOpts{}, encodedBlock, prefixBlock, prefixExtra)
if err != nil {
c.Printf("Error: %s", err)
return
}
c.Printf("Error: %s", res)
}
c.Println("===============================================================")
},
@@ -36,3 +126,28 @@ func Launch() {
// run shell
shell.Run()
}

func printInfo(setup config.Setup) {
// display welcome info.
fmt.Println("===============================================================")
fmt.Println("Ion Command Line Interface\n")
fmt.Println("RPC Client [to]:")
fmt.Println("Listening on: " + setup.AddrTo + ":" + setup.PortTo)
fmt.Println("User Account: " + setup.AccountTo)
fmt.Println("Ion Contract: " + setup.Ion)
fmt.Println("\nRPC Client [from]: ")
fmt.Println("Listening on: " + setup.AddrFrom + ":" + setup.PortFrom)
fmt.Println("User Account: " + setup.AccountFrom)
fmt.Println("===============================================================")
}

func strToHex(input string) (output string) {
val, err := strconv.Atoi(input)
if err != nil {
fmt.Println("please input decimal:", err)
return
}
output = strconv.FormatInt(int64(val), 16)

return "0x" + output
}
29 changes: 29 additions & 0 deletions src/cli/cli_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
// Copyright (c) 2018 Clearmatics Technologies Ltd

package cli_test

import (
"runtime"
"strings"
"testing"

"github.com/stretchr/testify/assert"

"github.com/validation/src/config"
)

func Test_Read_ValidSetupJson(t *testing.T) {
path := findPath() + "../setup.json"
setup := config.Read(path)

assert.Equal(t, "8501", setup.PortTo)
assert.Equal(t, "127.0.0.1", setup.AddrTo)
assert.Equal(t, "8502", setup.PortFrom)
assert.Equal(t, "127.0.0.1", setup.AddrFrom)
}

func findPath() string {
_, path, _, _ := runtime.Caller(0)
pathSlice := strings.Split(path, "/")
return strings.Trim(path, pathSlice[len(pathSlice)-1])
}
162 changes: 162 additions & 0 deletions src/cli/rpc.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,162 @@
// Copyright (c) 2018 Clearmatics Technologies Ltd

package cli

import (
"context"
"encoding/hex"
"encoding/json"
"fmt"
"math/big"
"reflect"

"github.com/ethereum/go-ethereum/ethclient"
"github.com/ethereum/go-ethereum/rlp"
)

type Header struct {
ParentHash string `json:"parentHash"`
UncleHash string `json:"sha3Uncles"`
Coinbase string `json:"miner"`
Root string `json:"stateRoot"`
TxHash string `json:"transactionsRoot"`
ReceiptHash string `json:"receiptsRoot"`
Bloom string `json:"logsBloom"`
Difficulty string `json:"difficulty"`
Number string `json:"number"`
GasLimit string `json:"gasLimit"`
GasUsed string `json:"gasUsed"`
Time string `json:"timestamp"`
Extra string `json:"extraData"`
MixDigest string `json:"mixHash"`
Nonce string `json:"nonce"`
}

func latestBlock(client *ethclient.Client) {
// var lastBlock Block
lastBlock, err := client.HeaderByNumber(context.Background(), nil)
if err != nil {
fmt.Println("can't get latest block:", err)
return
}
// Print events from the subscription as they arrive.
fmt.Printf("latest block: %v\n", lastBlock.Number)
}

func getBlock(client *ethclient.Client, block string) {
// var blockHeader Header
blockNum := new(big.Int)
blockNum.SetString(block, 10)

lastBlock, err := client.HeaderByNumber(context.Background(), blockNum)
if err != nil {
fmt.Println("can't get requested block:", err)
return
}
// Marshal into a JSON
b, err := json.MarshalIndent(lastBlock, "", " ")
if err != nil {
fmt.Printf("Error: %s", err)
return
}
fmt.Println("Block:", block)
fmt.Println(string(b))
}

// func rlpEncodeBlock(client *rpc.Client, block string) {
func rlpEncodeBlock(client *ethclient.Client, block string) {
var blockHeader Header
blockNum := new(big.Int)
blockNum.SetString(block, 10)

lastBlock, err := client.HeaderByNumber(context.Background(), blockNum)
if err != nil {
fmt.Println("can't get requested block:", err)
return
}

// Marshal into a JSON
b, err := json.MarshalIndent(lastBlock, "", " ")
if err != nil {
fmt.Printf("Error: %s", err)
return
}
err = json.Unmarshal([]byte(b), &blockHeader)
if err != nil {
fmt.Printf("Error: %s", err)
return
}

// fmt.Printf("%+v\n", blockHeader)
blockInterface := GenerateInterface(blockHeader)
encodedBlock := EncodeBlock(blockInterface)
fmt.Printf("%+x\n", encodedBlock)
}

// func calculateRlpEncoding(client *ethclient.Client, block string) {
func calculateRlpEncoding(client *ethclient.Client, block string) (rlpBlock []byte, prefixBlock []byte, prefixExtra []byte) {
var blockHeader Header
blockNum := new(big.Int)
blockNum.SetString(block, 10)

lastBlock, err := client.HeaderByNumber(context.Background(), blockNum)
if err != nil {
fmt.Println("can't get requested block:", err)
return
}

// Marshal into a JSON
b, err := json.MarshalIndent(lastBlock, "", " ")
if err != nil {
fmt.Printf("Error: %s", err)
return
}
err = json.Unmarshal([]byte(b), &blockHeader)
if err != nil {
fmt.Printf("Error: %s", err)
return
}

// Generate an interface to encode the standard block header
blockInterface := GenerateInterface(blockHeader)
encodedBlock := EncodeBlock(blockInterface)
fmt.Printf("\n%+x\n", encodedBlock)

// Generate an interface to encode the blockheader without the signature in the extraData
blockHeader.Extra = blockHeader.Extra[:len(blockHeader.Extra)-130]
blockInterface = GenerateInterface(blockHeader)
encodedBlock = EncodeBlock(blockInterface)
prefixBlock = encodedBlock[1:3]
fmt.Printf("\n%+x\n", prefixBlock)

// Generate an interface to encode the blockheader without the signature in the extraData
encExtra, _ := hex.DecodeString(blockHeader.Extra[2:])
encodedBlock = EncodeBlock(encExtra)
prefixExtra = encodedBlock[0:1]
fmt.Printf("\n%+x\n", prefixExtra)

return encodedBlock, prefixBlock, prefixExtra

}

// Creates an interface for a block
func GenerateInterface(blockHeader Header) (rest interface{}) {
blockInterface := []interface{}{}
s := reflect.ValueOf(&blockHeader).Elem()

// Append items into the interface
for i := 0; i < s.NumField(); i++ {
f := s.Field(i).String()
element, _ := hex.DecodeString(f[2:])
blockInterface = append(blockInterface, element)
}

return blockInterface
}

// Encodes a block
func EncodeBlock(blockInterface interface{}) (h []byte) {
h, _ = rlp.EncodeToBytes(blockInterface)

return h
}
19 changes: 19 additions & 0 deletions src/cli/rpc_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
// Copyright (c) 2018 Clearmatics Technologies Ltd

package cli_test

// func Test_EncodeBlock(t *testing.T) {
// // read a fake block
// raw, _ := ioutil.ReadFile("../block.json")
//
// const expectedRlpHex = "f90256a0ad34f0f919e4b06b18b0c674b8b9f6738a4878c76e837c8f31a2079f21dced1ca01dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347940000000000000000000000000000000000000000a0db37435caa1fca7e1aa5b4da1c69fdf1d127232519eb3b1b5069825e6c62f5dca056e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421a056e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421b9010000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000020a83fd82da80845b28beecb861d78301080a846765746887676f312e392e33856c696e75780000000000000000e0ac79c5577889dfb5745ace9c5dfebe1a11bb19ced9b98b427e7bd4c85765ce17154e658440915743ec442fb64756483bc592616754d13a3c62fce5a56ac9f501a00000000000000000000000000000000000000000000000000000000000000000880000000000000000"
//
// var marshalledBlock cli.Header
// json.Unmarshal(raw, &marshalledBlock)
//
// // Now RLP encode the block
// blockInterface := cli.GenerateInterface(marshalledBlock)
// fmt.Printf("%+v\n", marshalledBlock.Extra)
// hash := cli.EncodeBlock(blockInterface)
// assert.Equal(t, expectedRlpHex, hex.EncodeToString(hash))
// }
11 changes: 7 additions & 4 deletions src/config/config.go
Original file line number Diff line number Diff line change
@@ -10,10 +10,13 @@ import (

// Settings
type Setup struct {
Port_to string `json:"rpc-port-to"`
Addr_to string `json:"rpc-addr-to"`
Port_from string `json:"rpc-port-from"`
Addr_from string `json:"rpc-addr-from"`
PortTo string `json:"rpc-port-to"`
AddrTo string `json:"rpc-addr-to"`
AccountTo string `json:"account-to"`
PortFrom string `json:"rpc-port-from"`
AddrFrom string `json:"rpc-addr-from"`
AccountFrom string `json:"account-from"`
Ion string `json:"ion-addr"`
}

func Read(config string) (setup Setup) {
22 changes: 11 additions & 11 deletions src/config/config_test.go
Original file line number Diff line number Diff line change
@@ -3,24 +3,24 @@
package config_test

import (
"github.com/stretchr/testify/assert"
"runtime"
"strings"
"testing"

"gitlab.clearmatics.net/dev/boe-poc/src/config"
)
"github.com/stretchr/testify/assert"

func Test_ParseParameters_ValidUserFile(t *testing.T) {
path := findPath() + "../user.json"
commandLine := []string{path}
"github.com/validation/src/config"
)

setup := config.ParseParameters(commandLine)
func Test_Read_ValidSetupJson(t *testing.T) {
path := findPath() + "../setup.json"
setup := config.Read(path)

assert.Equal(t, "http://rt-poc2-2.azurewebsites.net", setup.APIURL)
assert.Equal(t, "password", setup.Grant_type)
assert.Equal(t, "svcp93lXc&", setup.Password)
assert.Equal(t, "user1@scheme1.co.uk", setup.User)
assert.Equal(t, "8501", setup.PortTo)
assert.Equal(t, "127.0.0.1", setup.AddrTo)
assert.Equal(t, "8502", setup.PortFrom)
assert.Equal(t, "127.0.0.1", setup.AddrFrom)
assert.Equal(t, "0xb9fd43a71c076f02d1dbbf473c389f0eacec559f", setup.Ion)
}

func findPath() string {
8 changes: 5 additions & 3 deletions src/main.go
Original file line number Diff line number Diff line change
@@ -3,22 +3,24 @@
package main

import (
"flag"
"fmt"
"os"
"flag"

"github.com/validation/src/cli"
"github.com/validation/src/config"
)

var configFile = flag.String("config", "", "Description:\n path to the configuration file")
var configFile = flag.String("config", "setup.json", "Description:\n path to the configuration file")

func main() {
flag.Parse()

if *configFile != "" {
setup := config.Read(*configFile)
cli.Launch()

// Launch the CLI
cli.Launch(setup)
} else {
fmt.Print("Error: empty config!\n")
os.Exit(3)
7 changes: 5 additions & 2 deletions src/setup.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,9 @@
{
"rpc-addr-to":"127.0.0.1",
"rpc-port-to":8501,
"rpc-port-to":"8501",
"account-to":"0x2be5ab0e43b6dc2908d5321cf318f35b80d0c10d",
"rpc-addr-from":"127.0.0.1",
"rpc-port-from":8502
"rpc-port-from":"8502",
"account-from":"0x8671e5e08d74f338ee1c462340842346d797afd3",
"ion-addr":"0xb9fd43a71c076f02d1dbbf473c389f0eacec559f"
}
455 changes: 455 additions & 0 deletions test/validation.js

Large diffs are not rendered by default.