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

test: include test vector submodule and runner for execution proofs and lc blocks #897

Open
wants to merge 2 commits into
base: master
Choose a base branch
from
Open
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
1 change: 1 addition & 0 deletions .github/workflows/contracts-eth.yml
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,7 @@ jobs:
- name: Clone the repository
uses: actions/checkout@v3
with:
submodules: 'true'
lfs: 'true'

- name: Execute
Expand Down
3 changes: 3 additions & 0 deletions .gitmodules
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
[submodule "near-light-client-tests"]
path = near-light-client-tests
url = https://github.com/austinabell/near-light-client-tests.git
76 changes: 76 additions & 0 deletions contracts/eth/nearbridge/test/BlockVectors.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,76 @@
// const { expect } = require('chai');
const { ethers } = require('hardhat');
const { getAllJsonFilesRecursive } = require('../../../../utils/proof-vector-utils');
const { borshify, borshifyInitialValidators } = require('rainbow-bridge-utils');

async function runTestVectors(testVectors) {
const Ed25519 = await (await ethers.getContractFactory('Ed25519')).deploy();
for (const test of testVectors) {
let {
description,
params: { previous_block, current_bps, new_block },
expected: { is_valid, error },
} = test;

if (description == "Invalid approval message signature at index 2") {
// Signature validation isn't done because too slow (see below). This test case must
// be skipped because block valid outside of signature.
continue;
}

let wasValid;
let executionError;
try {
const NearBridge = await (await ethers.getContractFactory('NearBridge')).deploy(
Ed25519.address,
ethers.BigNumber.from('1000000000000000000'), // 1e18
ethers.BigNumber.from('360'), // lock duration
ethers.BigNumber.from('362627730000'), // replace duration
await (await ethers.getSigners())[0].getAddress(),
0,
);
await NearBridge.deposit({ value: ethers.utils.parseEther('1') });

await NearBridge.initWithValidators(borshifyInitialValidators(current_bps));
// Note: hacky workaround since the initWithBlock method requires `approvals_after_next`
// and `next_block_inner_hash`, which it does not use and `next_bps` that is a bit
// redundant with the validators initialization.
previous_block.approvals_after_next = new_block.approvals_after_next;
previous_block.next_bps = current_bps;
previous_block.next_block_inner_hash = new_block.next_block_inner_hash;
await NearBridge.initWithBlock(borshify(previous_block));
await NearBridge.addLightClientBlock(borshify(new_block));

// Note: this validation is really slow and stalls the test suite, but worked until it did
// for (let j = 0; j < new_block.approvals_after_next.length; j++) {
// if (new_block.approvals_after_next[j]) {
// expect(await NearBridge.checkBlockProducerSignatureInHead(j)).to.be.true;
// }
// }
wasValid = true;
} catch (error) {
wasValid = false;
executionError = error;
}
if (wasValid !== is_valid) {
const prefix = `Test Case "${description}": FAILED - expected`;
throw new Error(
`${prefix} ${is_valid
? `valid, got error ${executionError}`
: `invalid result${error ? ` with error "${error}"` : ''}`
}`,
);
}
}
}

describe('light client block vectors', async function () {
const files = getAllJsonFilesRecursive('../../../near-light-client-tests/test-vectors/blocks');

for (const file of files) {
const fileName = file.split('\\').pop().split('/').pop();
it(`block vector file "${fileName}"`, async function () {
await runTestVectors(require('../' + file));
});
}
});
36 changes: 25 additions & 11 deletions contracts/eth/nearbridge/yarn.lock
Original file line number Diff line number Diff line change
Expand Up @@ -2118,6 +2118,11 @@ [email protected]:
resolved "https://registry.yarnpkg.com/bn.js/-/bn.js-4.11.6.tgz#53344adb14617a13f6e8dd2ce28905d1c0ba3215"
integrity sha1-UzRK2xRhehP26N0s4okF0cC6MhU=

[email protected]:
version "5.2.1"
resolved "https://registry.yarnpkg.com/bn.js/-/bn.js-5.2.1.tgz#0bc527a6a0d18d0aa8d5b0538ce4a77dccfa7b70"
integrity sha512-eXRvHzWyYPBuB4NBy0cmYQjGitUrtqwbvlzP3G6VFnNRbsZQIxQ10PbKKHt8gZ/HW/D/747aDl+QkDqg3KQLMQ==

bn.js@^4.0.0, bn.js@^4.1.0, bn.js@^4.10.0, bn.js@^4.11.0, bn.js@^4.11.6, bn.js@^4.11.8, bn.js@^4.11.9, bn.js@^4.8.0:
version "4.12.0"
resolved "https://registry.yarnpkg.com/bn.js/-/bn.js-4.12.0.tgz#775b3f278efbb9718eec7361f483fb36fbbfea88"
Expand Down Expand Up @@ -2160,6 +2165,15 @@ body-parser@^1.16.0:
raw-body "2.4.2"
type-is "~1.6.18"

borsh@^0.7.0:
version "0.7.0"
resolved "https://registry.yarnpkg.com/borsh/-/borsh-0.7.0.tgz#6e9560d719d86d90dc589bca60ffc8a6c51fec2a"
integrity sha512-CLCsZGIBCFnPtkNnieW/a8wmreDmfUtjU2m9yHrzPXIlNbqVs0AQrSatSG6vdNYUqdc83tkQi2eHfF98ubzQLA==
dependencies:
bn.js "^5.2.0"
bs58 "^4.0.0"
text-encoding-utf-8 "^1.0.2"

brace-expansion@^1.1.7:
version "1.1.11"
resolved "https://registry.yarnpkg.com/brace-expansion/-/brace-expansion-1.1.11.tgz#3c7fcbf529d87226f3d2f52b966ff5271eb441dd"
Expand Down Expand Up @@ -3380,7 +3394,7 @@ error-ex@^1.2.0:
dependencies:
is-arrayish "^0.2.1"

error-polyfill@^0.1.2:
error-polyfill@^0.1.3:
version "0.1.3"
resolved "https://registry.yarnpkg.com/error-polyfill/-/error-polyfill-0.1.3.tgz#df848b61ad8834f7a5db69a70b9913df86721d15"
integrity sha512-XHJk60ufE+TG/ydwp4lilOog549iiQF2OAPhkk9DdiYWMrltz5yhDz/xnKuenNwP7gy3dsibssO5QpVhkrSzzg==
Expand Down Expand Up @@ -6997,20 +7011,20 @@ natural-compare@^1.4.0:
resolved "https://registry.yarnpkg.com/natural-compare/-/natural-compare-1.4.0.tgz#4abebfeed7541f2c27acfb29bdbbd15c8d5ba4f7"
integrity sha1-Sr6/7tdUHywnrPspvbvRXI1bpPc=

near-api-js@^0.26.0:
version "0.26.0"
resolved "https://registry.yarnpkg.com/near-api-js/-/near-api-js-0.26.0.tgz#1d13571e0ec107aaf61b908466c38110ba5bf97b"
integrity sha512-aeRU2oWo6qKJF2oM7IcZ10vEqohxk6palTTx7LBUBsaKjF8561gBNIPhnkndhSrpsVSA9NBibX80WfOmK1tqrw==
near-api-js@^1.1.0:
version "1.1.0"
resolved "https://registry.yarnpkg.com/near-api-js/-/near-api-js-1.1.0.tgz#907e807f052c1f043c6fbf28f61872de3c02235a"
integrity sha512-qYKv1mYsaDZc2uYndhS+ttDhR9+60qFc+ZjD6lWsAxr3ZskMjRwPffDGQZYhC7BRDQMe1HEbk6d5mf+TVm0Lqg==
dependencies:
"@types/bn.js" "^4.11.5"
bn.js "^5.0.0"
bn.js "5.2.1"
borsh "^0.7.0"
bs58 "^4.0.0"
depd "^2.0.0"
error-polyfill "^0.1.2"
error-polyfill "^0.1.3"
http-errors "^1.7.2"
js-sha256 "^0.9.0"
mustache "^4.0.0"
node-fetch "^2.3.0"
node-fetch "^2.6.1"
text-encoding-utf-8 "^1.0.2"
tweetnacl "^1.0.1"

Expand Down Expand Up @@ -7062,7 +7076,7 @@ [email protected]:
object.getownpropertydescriptors "^2.0.3"
semver "^5.7.0"

node-fetch@^2.3.0, node-fetch@^2.6.0, node-fetch@^2.6.1, node-fetch@^2.6.7:
node-fetch@^2.6.0, node-fetch@^2.6.1, node-fetch@^2.6.7:
version "2.6.7"
resolved "https://registry.yarnpkg.com/node-fetch/-/node-fetch-2.6.7.tgz#24de9fba827e3b4ae44dc8b20256a379160052ad"
integrity sha512-ZjMPFEfVx5j+y2yF35Kzx5sF7kDzxuDj6ziH4FFbOp87zKDZNx8yExJIb05OGF4Nlt9IHFIMBkRl41VdvcNdbQ==
Expand Down Expand Up @@ -7882,7 +7896,7 @@ queue-microtask@^1.2.2:
eth-object "https://github.com/aurora-is-near/eth-object#a84d1420fdde87a768b96c6a3b3d0ee435998f72"
eth-util-lite near/eth-util-lite#master
lodash "^4.17.20"
near-api-js "^0.26.0"
near-api-js "^1.1.0"
web3 "^1.6.0"

randomatic@^3.0.0:
Expand Down
3 changes: 2 additions & 1 deletion contracts/eth/nearprover/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,8 @@
"readline-sync": "^1.4.10",
"solc": "0.8.3",
"solidity-coverage": "^0.7.16",
"solium": "^1.2.5"
"solium": "^1.2.5",
"bs58": "^4.0.1"
},
"scripts": {
"build": "hardhat compile",
Expand Down
45 changes: 45 additions & 0 deletions contracts/eth/nearprover/test/NearProver.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,8 @@ const { ethers } = require('hardhat');
const { borshifyOutcomeProof } = require(`rainbow-bridge-utils`);
const fs = require('fs').promises;
const { computeMerkleRoot } = require('../utils/utils');
const bs58 = require('bs58');
const { getAllJsonFilesRecursive } = require('../../../../utils/proof-vector-utils');

let NearProver, NearBridgeMock;

Expand All @@ -15,6 +17,49 @@ beforeEach(async function () {
);
});

async function runTestVectors(testVectors) {
for (const test of testVectors) {
const {
description,
params: { proof, block_merkle_root },
expected: { is_valid, error },
} = test;
let wasValid;
let executionError;
try {
const blockMerkleRoot = bs58.decode(block_merkle_root).toString('hex');
// Note, the height shouldn't matter here, defaulting to 100
const height = 100;
expect(blockMerkleRoot === computeMerkleRoot(proof).toString('hex')).to.be.true;
await NearBridgeMock.setBlockMerkleRoot(height, "0x" + blockMerkleRoot);
wasValid = await NearProver.proveOutcome(borshifyOutcomeProof(proof), height);
} catch (error) {
wasValid = false;
executionError = error;
}
if (wasValid !== is_valid) {
const prefix = `Test Case "${description}": FAILED - expected`;
throw new Error(
`${prefix} ${is_valid
? `valid, got error ${executionError}`
: `invalid result${error ? ` with error "${error}"` : ""}`
}`
);
}
}
}

describe('execution outcome proof vectors', async function () {
const files = getAllJsonFilesRecursive("../../../near-light-client-tests/test-vectors/executions");

for (const file of files) {
const fileName = file.split('\\').pop().split('/').pop();
it(`execution vector file "${fileName}"`, async function () {
await runTestVectors(require("../" + file));
});
}
});

async function testProof(merkleRoot, height, proofPath) {
let proof = require(proofPath);
console.log(computeMerkleRoot(proof).toString('hex'));
Expand Down
1 change: 1 addition & 0 deletions near-light-client-tests
22 changes: 22 additions & 0 deletions utils/proof-vector-utils.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
const { join } = require("path");
const { readdirSync, statSync } = require("fs");

function getAllJsonFilesRecursive(dirPath) {
let arrayOfFiles = [];
const files = readdirSync(dirPath);

files.forEach((file) => {
if (statSync(join(dirPath, file)).isDirectory()) {
const subDirFiles = getAllJsonFilesRecursive(join(dirPath, file));
arrayOfFiles = arrayOfFiles.concat(subDirFiles);
} else if (file.endsWith(".json")) {
arrayOfFiles.push(join(dirPath, file));
}
});

return arrayOfFiles;
}

module.exports = {
getAllJsonFilesRecursive,
}