Skip to content
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
12 changes: 6 additions & 6 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -37,17 +37,17 @@ jobs:
cpu: arm64
- os: windows
cpu: amd64
branch: [~, upstream/version-2-2]
branch: [~, upstream/version-2-0]
exclude:
- target:
os: macos
branch: upstream/version-2-2
branch: upstream/version-2-0
- target:
os: windows
branch: upstream/version-2-2
branch: upstream/version-2-0
include:
- branch: upstream/version-2-2
branch-short: version-2-2
- branch: upstream/version-2-0
branch-short: version-2-0
nimflags-extra: --mm:refc
- target:
os: linux
Expand Down Expand Up @@ -212,7 +212,7 @@ jobs:
# allowed to prevent potential problems with downloads on different
# file systems". However, GitHub Actions workflows do not support a
# usual assortment of string functions.
name: Unit Test Results ${{ matrix.target.os }}-${{ matrix.target.cpu }}-${{ matrix.branch == 'upstream/version-2-2' && 'version-2-2' || matrix.branch }}
name: Unit Test Results ${{ matrix.target.os }}-${{ matrix.target.cpu }}-${{ matrix.branch == 'upstream/version-2-0' && 'version-2-0' || matrix.branch }}
path: build/*.xml

devbuild:
Expand Down
2 changes: 2 additions & 0 deletions AllTests-mainnet.md
Original file line number Diff line number Diff line change
Expand Up @@ -741,6 +741,7 @@ AllTests-mainnet
## Nimbus remote signer/signing test (verifying-web3signer)
```diff
+ Signing BeaconBlock (getBlockSignature(deneb)) OK
+ Signing BeaconBlock (getBlockSignature(electra)) OK
+ Waiting for signing node (/upcheck) test OK
```
## Nimbus remote signer/signing test (web3signer)
Expand All @@ -749,6 +750,7 @@ AllTests-mainnet
+ Public keys enumeration (/api/v1/eth2/publicKeys) test OK
+ Public keys reload (/reload) test OK
+ Signing BeaconBlock (getBlockSignature(deneb)) OK
+ Signing BeaconBlock (getBlockSignature(electra)) OK
+ Signing SC contribution and proof (getContributionAndProofSignature()) OK
+ Signing SC message (getSyncCommitteeMessage()) OK
+ Signing SC selection proof (getSyncCommitteeSelectionProof()) OK
Expand Down
140 changes: 135 additions & 5 deletions tests/test_signing_node.nim
Original file line number Diff line number Diff line change
Expand Up @@ -9,15 +9,18 @@
{.used.}

import
unittest2, chronicles, results, stew/[byteutils, io2],
unittest2, chronicles, results,
chronos/asyncproc,
chronos/unittest2/asynctests,
../beacon_chain/spec/[signatures, crypto],
../beacon_chain/spec/crypto,
../beacon_chain/spec/eth2_apis/rest_remote_signer_calls,
../beacon_chain/filepath,
../beacon_chain/validators/validator_pool

from std/os import getEnv, osErrorMsg
from stew/byteutils import hexToByteArray
from ../beacon_chain/filepath import secureCreatePath, secureWriteFile
from ../beacon_chain/spec/signatures import
get_aggregate_and_proof_signature, get_block_signature

const
TestDirectoryName = "test-signing-node"
Expand Down Expand Up @@ -64,6 +67,8 @@ const

DenebBlockContents = "{\"signed_block\":{\"message\":{\"slot\":\"5297696\",\"proposer_index\":\"153094\",\"parent_root\":\"0xe6106533af9be918120ead7440a8006c7f123cc3cb7daf1f11d951864abea014\",\"state_root\":\"0xf86196d34500ca25d1f4e7431d4d52f6f85540bcaf97dd0d2ad9ecdb3eebcdf0\",\"body\":{\"randao_reveal\":\"0xa7efee3d5ddceb60810b23e3b5d39734696418f41dfd13a0851c7be7a72acbdceaa61e1db27513801917d72519d1c1040ccfed829faf06abe06d9964949554bf4369134b66de715ea49eb4fecf3e2b7e646f1764a1993e31e53dbc6557929c12\",\"eth1_data\":{\"deposit_root\":\"0x8ec87d7219a3c873fff3bfe206b4f923d1b471ce4ff9d6d6ecc162ef07825e14\",\"deposit_count\":\"259476\",\"block_hash\":\"0x877b6f8332c7397251ff3f0c5cecec105ff7d4cb78251b47f91fd15a86a565ab\"},\"graffiti\":\"\",\"proposer_slashings\":[],\"attester_slashings\":[],\"attestations\":[],\"deposits\":[],\"voluntary_exits\":[],\"sync_aggregate\":{\"sync_committee_bits\":\"0x733dfda7f5ffde5ade73367fcbf7fffeef7fe43777ffdffab9dbad6f7eed5fff9bfec4affdefbfaddf35bf5efbff9ffff9dfd7dbf97fbfcdfaddfeffbf95f75f\",\"sync_committee_signature\":\"0x81fdf76e797f81b0116a1c1ae5200b613c8041115223cd89e8bd5477aab13de6097a9ebf42b130c59527bbb4c96811b809353a17c717549f82d4bd336068ef0b99b1feebd4d2432a69fa77fac12b78f1fcc9d7b59edbeb381adf10b15bc4a520\"},\"execution_payload\":{\"parent_hash\":\"0x14c2242a8cfbce559e84c391f5f16d10d7719751b8558873012dc88ae5a193e8\",\"fee_recipient\":\"$1\",\"state_root\":\"0xdf8d96b2c292736d39e72e25802c2744d34d3d3c616de5b362425cab01f72fa5\",\"receipts_root\":\"0x4938a2bf640846d213b156a1a853548b369cd02917fa63d8766ab665d7930bac\",\"logs_bloom\":\"0x298610600038408c201080013832408850a00bc8f801920121840030a015310010e2a0e0108628110552062811441c84802f43825c4fc82140b036c58025a28800054c80a44025c052090a0f2c209a0400058040019ea0008e589084078048050880930113a2894082e0112408b088382402a851621042212aa40018a408d07e178c68691486411aa9a2809043b000a04c040000065a030028018540b04b1820271d00821b00c29059095022322c10a530060223240416140190056608200063c82248274ba8f0098e402041cd9f451031481a1010b8220824833520490221071898802d206348449116812280014a10a2d1c210100a30010802490f0a221849\",\"prev_randao\":\"0xc061711e135cd40531ec3ee29d17d3824c0e5f80d07f721e792ab83240aa0ab5\",\"block_number\":\"8737497\",\"gas_limit\":\"30000000\",\"gas_used\":\"16367052\",\"timestamp\":\"1680080352\",\"extra_data\":\"0xd883010b05846765746888676f312e32302e32856c696e7578\",\"base_fee_per_gas\":\"231613172261\",\"block_hash\":\"0x5aa9fd22a9238925adb2b038fd6eafc77adabf554051db5bc16ae5168a52eff6\",\"transactions\":[],\"withdrawals\":[],\"blob_gas_used\":\"2316131761\",\"excess_blob_gas\":\"231613172261\"},\"bls_to_execution_changes\":[],\"blob_kzg_commitments\":[]}},\"signature\":\"$2\"},\"kzg_proofs\":[],\"blobs\":[]}"

ElectraBlockContents = "{\"signed_block\":{\"message\":{\"slot\":\"5297696\",\"proposer_index\":\"153094\",\"parent_root\":\"0xe6106533af9be918120ead7440a8006c7f123cc3cb7daf1f11d951864abea014\",\"state_root\":\"0xf86196d34500ca25d1f4e7431d4d52f6f85540bcaf97dd0d2ad9ecdb3eebcdf0\",\"body\":{\"randao_reveal\":\"0xa7efee3d5ddceb60810b23e3b5d39734696418f41dfd13a0851c7be7a72acbdceaa61e1db27513801917d72519d1c1040ccfed829faf06abe06d9964949554bf4369134b66de715ea49eb4fecf3e2b7e646f1764a1993e31e53dbc6557929c12\",\"eth1_data\":{\"deposit_root\":\"0x8ec87d7219a3c873fff3bfe206b4f923d1b471ce4ff9d6d6ecc162ef07825e14\",\"deposit_count\":\"259476\",\"block_hash\":\"0x877b6f8332c7397251ff3f0c5cecec105ff7d4cb78251b47f91fd15a86a565ab\"},\"graffiti\":\"\",\"proposer_slashings\":[],\"attester_slashings\":[],\"attestations\":[],\"deposits\":[],\"voluntary_exits\":[],\"sync_aggregate\":{\"sync_committee_bits\":\"0x733dfda7f5ffde5ade73367fcbf7fffeef7fe43777ffdffab9dbad6f7eed5fff9bfec4affdefbfaddf35bf5efbff9ffff9dfd7dbf97fbfcdfaddfeffbf95f75f\",\"sync_committee_signature\":\"0x81fdf76e797f81b0116a1c1ae5200b613c8041115223cd89e8bd5477aab13de6097a9ebf42b130c59527bbb4c96811b809353a17c717549f82d4bd336068ef0b99b1feebd4d2432a69fa77fac12b78f1fcc9d7b59edbeb381adf10b15bc4a520\"},\"execution_payload\":{\"parent_hash\":\"0x14c2242a8cfbce559e84c391f5f16d10d7719751b8558873012dc88ae5a193e8\",\"fee_recipient\":\"$1\",\"state_root\":\"0xdf8d96b2c292736d39e72e25802c2744d34d3d3c616de5b362425cab01f72fa5\",\"receipts_root\":\"0x4938a2bf640846d213b156a1a853548b369cd02917fa63d8766ab665d7930bac\",\"logs_bloom\":\"0x298610600038408c201080013832408850a00bc8f801920121840030a015310010e2a0e0108628110552062811441c84802f43825c4fc82140b036c58025a28800054c80a44025c052090a0f2c209a0400058040019ea0008e589084078048050880930113a2894082e0112408b088382402a851621042212aa40018a408d07e178c68691486411aa9a2809043b000a04c040000065a030028018540b04b1820271d00821b00c29059095022322c10a530060223240416140190056608200063c82248274ba8f0098e402041cd9f451031481a1010b8220824833520490221071898802d206348449116812280014a10a2d1c210100a30010802490f0a221849\",\"prev_randao\":\"0xc061711e135cd40531ec3ee29d17d3824c0e5f80d07f721e792ab83240aa0ab5\",\"block_number\":\"8737497\",\"gas_limit\":\"30000000\",\"gas_used\":\"16367052\",\"timestamp\":\"1680080352\",\"extra_data\":\"0xd883010b05846765746888676f312e32302e32856c696e7578\",\"base_fee_per_gas\":\"231613172261\",\"block_hash\":\"0x5aa9fd22a9238925adb2b038fd6eafc77adabf554051db5bc16ae5168a52eff6\",\"transactions\":[],\"withdrawals\":[],\"blob_gas_used\":\"2316131761\",\"excess_blob_gas\":\"231613172261\"},\"bls_to_execution_changes\":[],\"blob_kzg_commitments\":[],\"execution_requests\":{\"deposits\":[],\"withdrawals\":[],\"consolidations\":[]}}},\"signature\":\"$2\"},\"kzg_proofs\":[],\"blobs\":[]}"

SigningNodeAddress = "127.0.0.1"
defaultSigningNodePort = 35333

Expand Down Expand Up @@ -98,8 +103,9 @@ proc getBlock(
DenebBlockContents % [feeRecipient, SomeSignature],
DenebSignedBlockContents).signed_block.message)
of ConsensusFork.Electra:
debugComment "electra test signing node getblock"
raiseAssert "electra unsupported"
ForkedBeaconBlock.init(RestJson.decode(
ElectraBlockContents % [feeRecipient, SomeSignature],
ElectraSignedBlockContents).signed_block.message)
of ConsensusFork.Fulu:
debugFuluComment "electra test signing node getblock"
raiseAssert "fulu unsupported"
Expand Down Expand Up @@ -868,6 +874,41 @@ block:
sres2.get() == rres2.get()
sres3.get() == rres3.get()

asyncTest "Signing BeaconBlock (getBlockSignature(electra))":
let
forked = getBlock(ConsensusFork.Electra)
blockRoot = withBlck(forked): hash_tree_root(forkyBlck)

sres1 =
await validator1.getBlockSignature(SigningFork, GenesisValidatorsRoot,
Slot(1), blockRoot, forked)
sres2 =
await validator2.getBlockSignature(SigningFork, GenesisValidatorsRoot,
Slot(1), blockRoot, forked)
sres3 =
await validator3.getBlockSignature(SigningFork, GenesisValidatorsRoot,
Slot(1), blockRoot, forked)
rres1 =
await validator4.getBlockSignature(SigningFork, GenesisValidatorsRoot,
Slot(1), blockRoot, forked)
rres2 =
await validator5.getBlockSignature(SigningFork, GenesisValidatorsRoot,
Slot(1), blockRoot, forked)
rres3 =
await validator6.getBlockSignature(SigningFork, GenesisValidatorsRoot,
Slot(1), blockRoot, forked)

check:
sres1.isOk()
sres2.isOk()
sres3.isOk()
rres1.isOk()
rres2.isOk()
rres3.isOk()
sres1.get() == rres1.get()
sres2.get() == rres2.get()
sres3.get() == rres3.get()

asyncTest "Connection timeout test":
let
request = Web3SignerRequest.init(SigningFork, GenesisValidatorsRoot,
Expand Down Expand Up @@ -1089,5 +1130,94 @@ block:
finally:
await client.closeWait()

asyncTest "Signing BeaconBlock (getBlockSignature(electra))":
let
fork = ConsensusFork.Electra
forked1 = getBlock(fork)
blockRoot1 = withBlck(forked1): hash_tree_root(forkyBlck)
forked2 = getBlock(fork, SigningOtherFeeRecipient)
blockRoot2 = withBlck(forked2): hash_tree_root(forkyBlck)
request1 = Web3SignerRequest.init(SigningFork, GenesisValidatorsRoot,
Web3SignerForkedBeaconBlock.init(forked1))
request2 = Web3SignerRequest.init(SigningFork, GenesisValidatorsRoot,
Web3SignerForkedBeaconBlock.init(forked1), @[])
remoteUrl = "http://" & SigningNodeAddress & ":" &
$getNodePort(basePort, RemoteSignerType.VerifyingWeb3Signer)
prestoFlags = {RestClientFlag.CommaSeparatedArray}
rclient = RestClientRef.new(remoteUrl, prestoFlags, {})
publicKey1 = ValidatorPubKey.fromHex(ValidatorPubKey1).get()
publicKey2 = ValidatorPubKey.fromHex(ValidatorPubKey2).get()
publicKey3 = ValidatorPubKey.fromHex(ValidatorPubKey3).get()

check rclient.isOk()

let
client = rclient.get()
sres1 =
await validator1.getBlockSignature(SigningFork, GenesisValidatorsRoot,
Slot(1), blockRoot1, forked1)
sres2 =
await validator2.getBlockSignature(SigningFork, GenesisValidatorsRoot,
Slot(1), blockRoot1, forked1)
sres3 =
await validator3.getBlockSignature(SigningFork, GenesisValidatorsRoot,
Slot(1), blockRoot1, forked1)
rres1 =
await validator4.getBlockSignature(SigningFork, GenesisValidatorsRoot,
Slot(1), blockRoot1, forked1)
rres2 =
await validator5.getBlockSignature(SigningFork, GenesisValidatorsRoot,
Slot(1), blockRoot1, forked1)
rres3 =
await validator6.getBlockSignature(SigningFork, GenesisValidatorsRoot,
Slot(1), blockRoot1, forked1)
bres1 =
await validator4.getBlockSignature(SigningFork, GenesisValidatorsRoot,
Slot(1), blockRoot2, forked2)
bres2 =
await validator5.getBlockSignature(SigningFork, GenesisValidatorsRoot,
Slot(1), blockRoot2, forked2)
bres3 =
await validator6.getBlockSignature(SigningFork, GenesisValidatorsRoot,
Slot(1), blockRoot2, forked2)

check:
# Local requests
sres1.isOk()
sres2.isOk()
sres3.isOk()
# Remote requests with proper Merkle proof of proper FeeRecipent field
rres1.isOk()
rres2.isOk()
rres3.isOk()
# Signature comparison
sres1.get() == rres1.get()
sres2.get() == rres2.get()
sres3.get() == rres3.get()
# Remote requests with changed FeeRecipient field
bres1.isErr()
bres2.isErr()
bres3.isErr()

try:
let
# `proofs` array is not present.
response1 = await client.signDataPlain(publicKey1, request1)
response2 = await client.signDataPlain(publicKey2, request1)
response3 = await client.signDataPlain(publicKey3, request1)
# `proofs` array is empty.
response4 = await client.signDataPlain(publicKey1, request2)
response5 = await client.signDataPlain(publicKey2, request2)
response6 = await client.signDataPlain(publicKey3, request2)
check:
response1.status == 400
response2.status == 400
response3.status == 400
response4.status == 400
response5.status == 400
response6.status == 400
finally:
await client.closeWait()

waitFor(shutdownSigningNodeProcess(process))
removeTestDir(RemoteSignerType.VerifyingWeb3Signer)