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

Add scripts to run relays in testnets #21

Merged
merged 12 commits into from
Feb 19, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
3 changes: 2 additions & 1 deletion .gitmodules
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
[submodule "ethrelay/ethashproof"]
path = ethrelay/ethashproof
url = https://github.com/talbaneth/ethashproof.git
url = https://github.com/nearprotocol/ethashproof.git
branch = near/relay/rlpheader-arg
37 changes: 33 additions & 4 deletions .travis.yml
Original file line number Diff line number Diff line change
Expand Up @@ -5,35 +5,64 @@
sudo: required
dist: trusty
language: node_js
branches:
only:
- master
node_js:
- '10'
env:
- ETHBRIDGE=1
- ETHRELAY=1
- NEARBRIDGE=1
- NEARBRIDGE_LINT=1
- NEARBRIDGE_COVERAGE=1
- NEARRELAY=1
script:
- if [ $ETHBRIDGE == "1" ]; then
- if [ "$ETHBRIDGE" = "1" ]; then
cd ./ethbridge;
sh <(curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs) -y && export PATH=$PATH:~/.cargo/bin;
rustup toolchain install stable;
rustup default stable;
rustup target add wasm32-unknown-unknown --toolchain stable;
./test.sh;
fi
- if [ $NEARBRIDGE == "1" ]; then
- if [ "$ETHRELAY" = "1" ]; then
cd ./ethbridge;
sh <(curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs) -y && export PATH=$PATH:~/.cargo/bin;
rustup toolchain install stable;
rustup default stable;
rustup target add wasm32-unknown-unknown --toolchain stable;
./build.sh;
cd ../ethrelay/ethashproof;
eval "$(gimme 1.12)";
go version;
./build.sh;
cd ..;
yarn && yarn run test;
fi
- if [ $NEARBRIDGE = "1" ]; then
cd ./nearbridge;
yarn;
yarn run test;
npx codechecks;
fi
- if [ $NEARBRIDGE_LINT == "1" ]; then
- if [ "$NEARBRIDGE_LINT" = "1" ]; then
cd ./nearbridge;
yarn;
yarn run lint;
fi
- if [ $NEARBRIDGE_COVERAGE == "1" ]; then
- if [ "$NEARBRIDGE_COVERAGE" = "1" ]; then
cd ./nearbridge;
yarn;
yarn run coverage && cat coverage/lcov.info | coveralls;
fi
- if [ "$NEARRELAY" = "1" ]; then
cd ./ethbridge;
sh <(curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs) -y && export PATH=$PATH:~/.cargo/bin;
rustup toolchain install stable;
rustup default stable;
rustup target add wasm32-unknown-unknown --toolchain stable;
./build.sh;
cd ../nearrelay;
yarn && yarn run test;
fi
18 changes: 13 additions & 5 deletions ethbridge/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,7 @@ pub struct HeaderInfo {
#[near_bindgen]
#[derive(BorshDeserialize, BorshSerialize)]
pub struct EthBridge {
validate_ethash: bool,
dags_start_epoch: u64,
dags_merkle_roots: Vec<H128>,

Expand All @@ -77,8 +78,9 @@ const NUMBER_OF_BLOCKS_FINALITY: u64 = 30;
const NUMBER_OF_BLOCKS_SAFE: u64 = 10;

impl EthBridge {
pub fn init(dags_start_epoch: u64, dags_merkle_roots: Vec<H128>) -> Self {
pub fn init(validate_ethash: bool, dags_start_epoch: u64, dags_merkle_roots: Vec<H128>) -> Self {
Self {
validate_ethash,
dags_start_epoch,
dags_merkle_roots,

Expand Down Expand Up @@ -263,8 +265,13 @@ impl EthBridge {
// 2. Added condition: header.parent_hash() == prev.hash()
//
ethereum_types::U256::from((result.0).0) < ethash::cross_boundary(header.difficulty.0)
&& header.difficulty < header.difficulty * 101 / 100
&& header.difficulty > header.difficulty * 99 / 100
&& (
!self.validate_ethash
|| (
header.difficulty < header.difficulty * 101 / 100
&& header.difficulty > header.difficulty * 99 / 100
)
)
&& header.gas_used <= header.gas_limit
&& header.gas_limit < prev.gas_limit * 1025 / 1024
&& header.gas_limit > prev.gas_limit * 1023 / 1024
Expand Down Expand Up @@ -297,7 +304,7 @@ impl EthBridge {

// Each two nodes are packed into single 128 bytes with Merkle proof
let node = &nodes[idx / 2];
if idx % 2 == 0 {
if idx % 2 == 0 && self.validate_ethash {
// Divide by 2 to adjust offset for 64-byte words instead of 128-byte
assert_eq!(merkle_root, node.apply_merkle_proof((offset / 2) as u64));
};
Expand All @@ -323,12 +330,13 @@ pub extern "C" fn init() {
near_bindgen::env::set_blockchain_interface(Box::new(near_blockchain::NearBlockchain {}));
let input = near_bindgen::env::input().unwrap();
let mut c = Cursor::new(&input);
let validate_ethash: bool = borsh::BorshDeserialize::deserialize(&mut c).unwrap();
let dags_start_epoch: u64 = borsh::BorshDeserialize::deserialize(&mut c).unwrap();
let dags_merkle_roots: Vec<H128> =
borsh::BorshDeserialize::deserialize(&mut c).unwrap();
assert_eq!(c.position(), input.len() as u64, "Not all bytes read from input");
assert!(near_bindgen::env::state_read::<EthBridge>().is_none(), "Already initialized");
let contract = EthBridge::init(dags_start_epoch, dags_merkle_roots);
let contract = EthBridge::init(validate_ethash, dags_start_epoch, dags_merkle_roots);
near_bindgen::env::state_write(&contract);
}
#[cfg(target_arch = "wasm32")]
Expand Down
11 changes: 6 additions & 5 deletions ethbridge/src/tests.rs
Original file line number Diff line number Diff line change
Expand Up @@ -234,7 +234,7 @@ fn add_dags_merkle_roots() {
testing_env!(get_context(vec![], false));

let dmr = read_roots_collection();
let contract = EthBridge::init(0, read_roots_collection().dag_merkle_roots);
let contract = EthBridge::init(true, 0, read_roots_collection().dag_merkle_roots);

assert_eq!(dmr.dag_merkle_roots[0], contract.dag_merkle_root(0));
assert_eq!(dmr.dag_merkle_roots[10], contract.dag_merkle_root(10));
Expand All @@ -257,7 +257,7 @@ fn add_blocks_2_and_3() {
.map(|filename| read_block((&filename).to_string()))
.collect();

let mut contract = EthBridge::init(0, read_roots_collection().dag_merkle_roots);
let mut contract = EthBridge::init(true, 0, read_roots_collection().dag_merkle_roots);

for (block, proof) in blocks.into_iter().zip(blocks_with_proofs.into_iter()) {
contract.add_block_header(block, proof.to_double_node_with_merkle_proof_vec());
Expand All @@ -284,7 +284,7 @@ fn add_400000_block_only() {

let block_with_proof = read_block("./src/data/400000.json".to_string());

let mut contract = EthBridge::init(400_000 / 30000, vec![block_with_proof.merkle_root]);
let mut contract = EthBridge::init(true, 400_000 / 30000, vec![block_with_proof.merkle_root]);

// let result = catch_unwind_silent(panic::AssertUnwindSafe(
// || contract.add_block_headers(
Expand Down Expand Up @@ -329,7 +329,7 @@ fn add_two_blocks_from_8996776() {
.map(|filename| read_block((&filename).to_string()))
.collect();

let mut contract = EthBridge::init(0, read_roots_collection().dag_merkle_roots);
let mut contract = EthBridge::init(true, 0, read_roots_collection().dag_merkle_roots);

for (block, proof) in blocks.into_iter().zip(blocks_with_proofs.into_iter()) {
contract.add_block_header(block, proof.to_double_node_with_merkle_proof_vec());
Expand Down Expand Up @@ -365,6 +365,7 @@ fn add_2_blocks_from_400000() {
.collect();

let mut contract = EthBridge::init(
true,
400_000 / 30000,
vec![blocks_with_proofs.first().unwrap().merkle_root],
);
Expand Down Expand Up @@ -396,7 +397,7 @@ fn add_2_blocks_from_400000() {
// ].iter().map(|filename| read_block((&filename).to_string())).collect();
//
// let mut contract = EthBridge::default();
// contract.init(0, read_roots_collection().dag_merkle_roots);
// contract.init(true, 0, read_roots_collection().dag_merkle_roots);
//
// contract.add_block_headers(blocks1);
// contract.add_block_headers(blocks2);
Expand Down
2 changes: 1 addition & 1 deletion ethrelay/ethashproof
Submodule ethashproof updated 2 files
+10 −16 cmd/relayer/main.go
+0 −26 utils.go
53 changes: 34 additions & 19 deletions ethrelay/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,8 @@ const Web3 = require('web3');
const nearlib = require('nearlib');
const BN = require('bn.js');
const exec = require('child_process').exec;
const blockFromRpc = require('ethereumjs-block/from-rpc')
const utils = require('ethereumjs-util');

const roots = require('./dag_merkle_roots.json');

Expand Down Expand Up @@ -37,20 +39,17 @@ function subscribeOnBlocksRangesFrom(web3, block_number, handler) {
});
}

function arrayPrefixU32Length(array) {
return [
Math.trunc(array.length) % 256,
Math.trunc(array.length / 256) % 256,
Math.trunc(array.length / 256 / 256) % 256,
Math.trunc(array.length / 256 / 256 / 256) % 256,
].concat(...array);
}

const hexToBuffer = (hex) => Buffer.from(Web3.utils.hexToBytes(hex));
const readerToHex = (len) => (reader) => Web3.utils.bytesToHex(reader.read_fixed_array(len));

const borshSchema = {
'bool': {
kind: 'function',
ser: (b) => Buffer.from(Web3.utils.hexToBytes(b ? '0x01' : '0x00')),
deser: (z) => readerToHex(1)(z) === '0x01'
},
'initInput': {kind: 'struct', fields: [
['validate_ethash', 'bool'],
['dags_start_epoch', 'u64'],
['dags_merkle_roots', ['H128']]
]},
Expand Down Expand Up @@ -339,18 +338,29 @@ class EthBridgeContract extends Contract {
}
}

function web3BlockToRlp(blockData) {
blockData.difficulty = parseInt(blockData.difficulty, 10);
blockData.totalDifficulty = parseInt(blockData.totalDifficulty, 10);
blockData.uncleHash = blockData.sha3Uncles;
blockData.coinbase = blockData.miner;
blockData.transactionTrie = blockData.transactionsRoot;
blockData.receiptTrie = blockData.receiptsRoot;
blockData.bloom = blockData.logsBloom;
const blockHeader = blockFromRpc(blockData);
return utils.rlp.encode(blockHeader.header.raw);
}

(async function () {

const web3 = new Web3("wss://mainnet.infura.io/ws/v3/b5f870422ee5454fb11937e947154cd2");
const web3 = new Web3(process.env.ETHEREUM_NODE_URL);
const near = await nearlib.connect({
nodeUrl: 'http://localhost:3030', //'https://rpc.nearprotocol.com',
networkId: 'local', // TODO: detect automatically
nodeUrl: process.env.NEAR_NODE_URL, // 'https://rpc.nearprotocol.com',
networkId: process.env.NEAR_NODE_NETWORK_ID, // TODO: detect automatically
deps: {
keyStore: new nearlib.keyStores.UnencryptedFileSystemKeyStore(__dirname + '/neardev')
}
});


const account = new nearlib.Account(near.connection, 'ethbridge');

const ethBridgeContract = new EthBridgeContract(account, 'ethbridge');
Expand All @@ -365,6 +375,7 @@ class EthBridgeContract extends Contract {
if (!initialized) {
console.log('EthBridge is not initialized, initializing...');
await ethBridgeContract.init({
validate_ethash: process.env.BRIDGE_VALIDATE_ETHASH === 'true',
dags_start_epoch: 0,
dags_merkle_roots: roots.dag_merkle_roots
}, new BN('1000000000000000'));
Expand Down Expand Up @@ -422,6 +433,7 @@ class EthBridgeContract extends Contract {
.map((element, index) => {
return web3.utils.padLeft(element, 64) + web3.utils.padLeft(block.elements[index*2 + 1], 64).substr(2)
});

const args = {
block_header: web3.utils.hexToBytes(block.header_rlp),
dag_nodes: h512s
Expand All @@ -430,18 +442,19 @@ class EthBridgeContract extends Contract {
return {
dag_nodes: [element, h512s[index*2 + 1]],
proof: block.merkle_proofs.slice(
index * block.proof_length,
(index + 1) * block.proof_length,
index * block.proof_length,
(index + 1) * block.proof_length,
).map(leaf => web3.utils.padLeft(leaf, 32))
};
}),
};

for (let i = 0; i < 10; ++i) {
try {
await ethBridgeContract.add_block_header(args, new BN('1000000000000000'));
console.log(
"Blocks submission took " + Math.trunc((Date.now() - timeBeforeSubmission)/10)/100 + "s " +
"(" + Math.trunc((Date.now() - timeBeforeSubmission)/10)/100 + "s per header)"
"Blocks submission took " + Math.trunc((Date.now() - timeBeforeSubmission)/10)/100 + "s " +
"(" + Math.trunc((Date.now() - timeBeforeSubmission)/10)/100 + "s per header)"
);
console.log(`Successfully submitted block ${blockNumber} to EthBridge`);
return;
Expand All @@ -453,6 +466,7 @@ class EthBridgeContract extends Contract {
});
}
}

throw new Error("Failed to submit a block");
};

Expand All @@ -461,9 +475,10 @@ class EthBridgeContract extends Contract {
console.log(`Processing ${stop - start + 1} blocks from #${start} to #${stop}`);
for (let i = start; i <= stop; ++i) {
let ok = false;
for (let retryIter = 0; retryIter < 10; ++retryIter) {
for (let retryIter = 0; retryIter < 10; retryIter++) {
try {
const block = JSON.parse(await execute(`./ethashproof/cmd/relayer/relayer ${i} | sed -e '1,/Json output/d'`));
const blockRlp = web3.utils.bytesToHex(web3BlockToRlp(await web3.eth.getBlock(i)));
const block = JSON.parse(await execute(`./ethashproof/cmd/relayer/relayer ${blockRlp} | sed -e '1,/Json output/d'`));
submitBlock(block, i).catch((e) => {
throw e;
})
Expand Down
6 changes: 5 additions & 1 deletion ethrelay/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -4,13 +4,17 @@
"description": "Ethereum >> Near relay",
"main": "index.js",
"scripts": {
"start": "scripts/start.sh"
"test": "scripts/run_ganache_to_localnet.sh",
"start": "scripts/run_mainnet_to_localnet.sh"
},
"author": "",
"license": "MIT",
"dependencies": {
"near-shell": "^0.20.1",
"nearlib": "^0.21.0",
"ganache-cli": "^6.9.0",
"ethereumjs-block": "^2.2.2",
"ethereumjs-util": "^6.2.0",
"web3": "^1.2.4"
}
}
Loading