Skip to content
This repository has been archived by the owner on Nov 15, 2023. It is now read-only.

BEEFY & MMR zombienet tests #7068

Merged
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
27 commits
Select commit Hold shift + click to select a range
4111408
test that successfully verify self-generated proof
Lederstrumpf Mar 30, 2023
064b089
verify proof result on all unpaused nodes
Lederstrumpf Mar 30, 2023
00fa900
tighten interface: reuse connection
Lederstrumpf Mar 30, 2023
5e1cfc0
generate the proof on arbitrary node
Lederstrumpf Mar 30, 2023
05c18f9
s/stub-name/validator
Lederstrumpf Mar 30, 2023
b15bb8e
rename script
Lederstrumpf Mar 30, 2023
0f86706
add basic mmr-leaves test
Lederstrumpf Apr 6, 2023
d004a42
documentation formatting
Lederstrumpf Apr 6, 2023
6995af6
check lower bound on mmr leaves
Lederstrumpf Apr 6, 2023
3dac9a0
test beefy rpc: finalized heads match
Lederstrumpf Apr 6, 2023
6db45b1
test mmr api: stateless proofs
Lederstrumpf Apr 6, 2023
b7c313e
set lower bound on number of leaves
Lederstrumpf Apr 13, 2023
bf5bb97
change leaves in proof generation
Lederstrumpf Apr 13, 2023
e4b8572
remove TODOs
Lederstrumpf Apr 13, 2023
909a7f7
cleanup: consistently ignore zndsl name arg
Lederstrumpf Apr 13, 2023
097fbc0
Merge remote-tracking branch 'upstream/master' into rhmb/beefy-mmr-zo…
Lederstrumpf Apr 13, 2023
aaa2ec3
refactor: simplify returns
Lederstrumpf Apr 19, 2023
c01e3f3
lax finalized head test
Lederstrumpf Apr 20, 2023
9242ac5
fixup! refactor: simplify returns
Lederstrumpf Apr 20, 2023
2df10ff
refactor out getApis
Lederstrumpf Apr 21, 2023
edb0a95
split out paused validator from group
Lederstrumpf Apr 24, 2023
b29b1e1
refactor: don't ignore node arg
Lederstrumpf Apr 24, 2023
89ced7d
only check min block height, not relative
Lederstrumpf Apr 27, 2023
324cb73
verify finalized heads share same canonical chain
Lederstrumpf May 1, 2023
c320c4a
fixup! split out paused validator from group
Lederstrumpf May 1, 2023
b52fda9
Merge remote-tracking branch 'upstream/master' into rhmb/beefy-mmr-zo…
Lederstrumpf May 4, 2023
aa54576
Merge remote-tracking branch 'origin/master' into rhmb/beefy-mmr-zomb…
May 4, 2023
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
2 changes: 1 addition & 1 deletion zombienet_tests/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ To run any test locally use the native provider (`zombienet test -p native ...`)
To build them use:
* adder-collator -> `cargo build --profile testnet -p test-parachain-adder-collator`
* undying-collator -> `cargo build --profile testnet -p test-parachain-undying-collator`
* malus -> cargo build --profile testnet -p polkadot-test-malus
* malus -> `cargo build --profile testnet -p polkadot-test-malus`
* polkadot (in polkadot repo) and polkadot-collator (in cumulus repo) -> `cargo build --profile testnet`

One solution is to use the `.set_env` file (from this directory) and fill the `CUSTOM_PATHS` before *source* it to patch the PATH of your system to find the binaries you just built.
Expand Down
6 changes: 5 additions & 1 deletion zombienet_tests/functional/0003-beefy-and-mmr.toml
Original file line number Diff line number Diff line change
Expand Up @@ -8,5 +8,9 @@ command = "polkadot"

[[relaychain.node_groups]]
name = "validator"
count = 4
count = 3
args = ["--log=beefy=debug", "--beefy", "--enable-offchain-indexing=true"]

[[relaychain.nodes]]
name = "validator-unstable"
args = ["--log=beefy=debug", "--beefy", "--enable-offchain-indexing=true"]
50 changes: 21 additions & 29 deletions zombienet_tests/functional/0003-beefy-and-mmr.zndsl
Original file line number Diff line number Diff line change
Expand Up @@ -3,45 +3,37 @@ Network: ./0003-beefy-and-mmr.toml
Creds: config

# Check authority status.
validator-0: reports node_roles is 4
validator-1: reports node_roles is 4
validator-2: reports node_roles is 4
validator-3: reports node_roles is 4
validator: reports node_roles is 4
validator-unstable: reports node_roles is 4

# BEEFY sanity checks.
validator-0: reports substrate_beefy_validator_set_id is 0
validator-1: reports substrate_beefy_validator_set_id is 0
validator-2: reports substrate_beefy_validator_set_id is 0
validator-3: reports substrate_beefy_validator_set_id is 0
validator: reports substrate_beefy_validator_set_id is 0
validator-unstable: reports substrate_beefy_validator_set_id is 0

# Verify voting happens and 1st mandatory block is finalized within 1st session.
validator-0: reports substrate_beefy_best_block is at least 1 within 60 seconds
validator-1: reports substrate_beefy_best_block is at least 1 within 60 seconds
validator-2: reports substrate_beefy_best_block is at least 1 within 60 seconds
validator-3: reports substrate_beefy_best_block is at least 1 within 60 seconds
validator: reports substrate_beefy_best_block is at least 1 within 60 seconds
validator-unstable: reports substrate_beefy_best_block is at least 1 within 60 seconds

# Pause validator-3 and test chain is making progress without it.
validator-3: pause
# Pause validator-unstable and test chain is making progress without it.
validator-unstable: pause

# Verify validator sets get changed on new sessions.
validator-0: reports substrate_beefy_validator_set_id is at least 1 within 70 seconds
validator-1: reports substrate_beefy_validator_set_id is at least 1 within 70 seconds
validator-2: reports substrate_beefy_validator_set_id is at least 1 within 70 seconds
validator: reports substrate_beefy_validator_set_id is at least 1 within 70 seconds
# Check next session too.
validator-0: reports substrate_beefy_validator_set_id is at least 2 within 130 seconds
validator-1: reports substrate_beefy_validator_set_id is at least 2 within 130 seconds
validator-2: reports substrate_beefy_validator_set_id is at least 2 within 130 seconds
validator: reports substrate_beefy_validator_set_id is at least 2 within 130 seconds

# Verify voting happens and blocks are being finalized for new sessions too:
# since we verified we're at least in the 3rd session, verify BEEFY finalized mandatory #21.
validator-0: reports substrate_beefy_best_block is at least 21 within 130 seconds
validator-1: reports substrate_beefy_best_block is at least 21 within 130 seconds
validator-2: reports substrate_beefy_best_block is at least 21 within 130 seconds
validator: reports substrate_beefy_best_block is at least 21 within 130 seconds

# TODO (issue #11972): Custom JS to test BEEFY RPCs
# TODO (issue #11972): Custom JS to test MMR RPCs
# Custom JS to test BEEFY RPCs.
serban300 marked this conversation as resolved.
Show resolved Hide resolved
validator-0: js-script ./0003-beefy-finalized-heads.js with "validator-0,validator-1,validator-2" return is 1 within 5 seconds

# Resume validator-3 and verify it imports all BEEFY justification and catches up.
validator-3: resume
validator-3: reports substrate_beefy_validator_set_id is at least 2 within 30 seconds
validator-3: reports substrate_beefy_best_block is at least 21 within 30 seconds
# Custom JS to test MMR RPCs.
validator: js-script ./0003-mmr-leaves.js with "21" return is 1 within 5 seconds
validator: js-script ./0003-mmr-generate-and-verify-proof.js with "validator-0,validator-1,validator-2" return is 1 within 5 seconds
serban300 marked this conversation as resolved.
Show resolved Hide resolved

# Resume validator-unstable and verify it imports all BEEFY justification and catches up.
validator-unstable: resume
validator-unstable: reports substrate_beefy_validator_set_id is at least 2 within 30 seconds
validator-unstable: reports substrate_beefy_best_block is at least 21 within 30 seconds
35 changes: 35 additions & 0 deletions zombienet_tests/functional/0003-beefy-finalized-heads.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
const common = require('./0003-common.js');

async function run(_, networkInfo, nodeNames) {
const apis = await common.getApis(networkInfo, nodeNames);

const finalizedHeads = await Promise.all(
Object.entries(apis).map(async ([nodeName, api]) => {
const finalizedHead = await api.rpc.beefy.getFinalizedHead();
return { nodeName, finalizedHead, finalizedHeight: await api.rpc.chain.getHeader(finalizedHead).then((header) => header.number) };
})
);

// select the node with the highest finalized height
const highestFinalizedHeight = finalizedHeads.reduce(
(acc, { nodeName, finalizedHeight }) =>
finalizedHeight >= acc.finalizedHeight
? { nodeName, finalizedHeight }
: acc,
{ nodeName: 'validator', finalizedHeight: 0 }
);

// get all block hashes up until the highest finalized height
const blockHashes = [];
for (let blockNumber = 0; blockNumber <= highestFinalizedHeight.finalizedHeight; blockNumber++) {
const blockHash = await apis[highestFinalizedHeight.nodeName].rpc.chain.getBlockHash(blockNumber);
blockHashes.push(blockHash);
}

// verify that height(finalized_head) is at least as high as the substrate_beefy_best_block test already verified
return finalizedHeads.every(({ finalizedHead, finalizedHeight }) =>
finalizedHeight >= 21 && finalizedHead.toHex() === blockHashes[finalizedHeight].toHex()
)
}

module.exports = { run };
16 changes: 16 additions & 0 deletions zombienet_tests/functional/0003-common.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
async function getApis(networkInfo, nodeNames) {
const connectionPromises = nodeNames.map(async (nodeName) => {
const { wsUri, userDefinedTypes } = networkInfo.nodesByName[nodeName];
const connection = await zombie.connect(wsUri, userDefinedTypes);
return { nodeName, connection };
});

const connections = await Promise.all(connectionPromises);

return connections.reduce((map, { nodeName, connection }) => {
map[nodeName] = connection;
return map;
}, {});
}

module.exports = { getApis };
26 changes: 26 additions & 0 deletions zombienet_tests/functional/0003-mmr-generate-and-verify-proof.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
const common = require('./0003-common.js');

async function run(nodeName, networkInfo, nodeNames) {
const apis = await common.getApis(networkInfo, nodeNames);

const proof = await apis[nodeName].rpc.mmr.generateProof([1, 9, 20]);

const root = await apis[nodeName].rpc.mmr.root()

const proofVerifications = await Promise.all(
Object.values(apis).map(async (api) => {
return api.rpc.mmr.verifyProof(proof);
})
);

const proofVerificationsStateless = await Promise.all(
Object.values(apis).map(async (api) => {
return api.rpc.mmr.verifyProofStateless(root, proof);
})
);

// check that all nodes accepted the proof
return proofVerifications.every((proofVerification) => proofVerification) && proofVerificationsStateless.every((proofVerification) => proofVerification)
}

module.exports = { run };
9 changes: 9 additions & 0 deletions zombienet_tests/functional/0003-mmr-leaves.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
async function run(nodeName, networkInfo, args) {
const { wsUri, userDefinedTypes } = networkInfo.nodesByName[nodeName];
const api = await zombie.connect(wsUri, userDefinedTypes);

const mmrLeaves = await api.query.mmr.numberOfLeaves();
return mmrLeaves.toNumber() >= args[0]
}

module.exports = { run };