Add Web3signer electra support (#6607)
* Add Electra support to nimbus_signing_node. Add tests. Annotate nimbus_signing_node with asyncraises. * Update AllTests.
This commit is contained in:
parent
ab4574ef36
commit
5d11c5229b
|
@ -782,7 +782,8 @@ OK: 3/3 Fail: 0/3 Skip: 0/3
|
|||
+ Signing SC contribution and proof (getContributionAndProofSignature()) OK
|
||||
+ Signing SC message (getSyncCommitteeMessage()) OK
|
||||
+ Signing SC selection proof (getSyncCommitteeSelectionProof()) OK
|
||||
+ Signing aggregate and proof (getAggregateAndProofSignature()) OK
|
||||
+ Signing aggregate and proof (getAggregateAndProofSignature(electra)) OK
|
||||
+ Signing aggregate and proof (getAggregateAndProofSignature(phase0)) OK
|
||||
+ Signing aggregation slot (getSlotSignature()) OK
|
||||
+ Signing attestation (getAttestationSignature()) OK
|
||||
+ Signing deposit message (getDepositMessageSignature()) OK
|
||||
|
@ -791,7 +792,7 @@ OK: 3/3 Fail: 0/3 Skip: 0/3
|
|||
+ Signing voluntary exit (getValidatorExitSignature()) OK
|
||||
+ Waiting for signing node (/upcheck) test OK
|
||||
```
|
||||
OK: 16/16 Fail: 0/16 Skip: 0/16
|
||||
OK: 17/17 Fail: 0/17 Skip: 0/17
|
||||
## Old database versions [Preset: mainnet]
|
||||
```diff
|
||||
+ pre-1.1.0 OK
|
||||
|
@ -1128,4 +1129,4 @@ OK: 2/2 Fail: 0/2 Skip: 0/2
|
|||
OK: 9/9 Fail: 0/9 Skip: 0/9
|
||||
|
||||
---TOTAL---
|
||||
OK: 765/770 Fail: 0/770 Skip: 5/770
|
||||
OK: 766/771 Fail: 0/771 Skip: 5/771
|
||||
|
|
|
@ -71,14 +71,14 @@ proc start(sn: SigningNodeRef) =
|
|||
of SigningNodeKind.NonSecure:
|
||||
sn.signingServer.nserver.start()
|
||||
|
||||
proc stop(sn: SigningNodeRef) {.async.} =
|
||||
proc stop(sn: SigningNodeRef) {.async: (raises: []).} =
|
||||
case sn.signingServer.kind
|
||||
of SigningNodeKind.Secure:
|
||||
await sn.signingServer.sserver.stop()
|
||||
of SigningNodeKind.NonSecure:
|
||||
await sn.signingServer.nserver.stop()
|
||||
|
||||
proc close(sn: SigningNodeRef) {.async.} =
|
||||
proc close(sn: SigningNodeRef) {.async: (raises: []).} =
|
||||
case sn.signingServer.kind
|
||||
of SigningNodeKind.Secure:
|
||||
await sn.signingServer.sserver.closeWait()
|
||||
|
@ -209,6 +209,15 @@ proc installApiHandlers*(node: SigningNodeRef) =
|
|||
forkInfo.genesis_validators_root, request.aggregateAndProof,
|
||||
validator.data.privateKey).toValidatorSig().toHex()
|
||||
signatureResponse(Http200, signature)
|
||||
of Web3SignerRequestKind.AggregateAndProofV2:
|
||||
let
|
||||
forkInfo = request.forkInfo.get()
|
||||
signature =
|
||||
withAggregateAndProof(request.forkedAggregateAndProof):
|
||||
get_aggregate_and_proof_signature(forkInfo.fork,
|
||||
forkInfo.genesis_validators_root, forkyProof,
|
||||
validator.data.privateKey).toValidatorSig().toHex()
|
||||
signatureResponse(Http200, signature)
|
||||
of Web3SignerRequestKind.Attestation:
|
||||
let
|
||||
forkInfo = request.forkInfo.get()
|
||||
|
@ -330,7 +339,7 @@ proc installApiHandlers*(node: SigningNodeRef) =
|
|||
validator.data.privateKey).toValidatorSig().toHex()
|
||||
signatureResponse(Http200, signature)
|
||||
|
||||
proc asyncInit(sn: SigningNodeRef) {.async.} =
|
||||
proc asyncInit(sn: SigningNodeRef) {.async: (raises: [SigningNodeError]).} =
|
||||
notice "Launching signing node", version = fullVersionStr,
|
||||
cmdParams = commandLineParams(), config = sn.config
|
||||
|
||||
|
@ -403,7 +412,7 @@ proc asyncInit(sn: SigningNodeRef) {.async.} =
|
|||
raise newException(SigningNodeError, "")
|
||||
SigningNodeServer(kind: SigningNodeKind.NonSecure, nserver: res.get())
|
||||
|
||||
proc asyncRun*(sn: SigningNodeRef) {.async.} =
|
||||
proc asyncRun*(sn: SigningNodeRef) {.async: (raises: []).} =
|
||||
sn.runKeystoreCachePruningLoopFut =
|
||||
runKeystoreCachePruningLoop(sn.keystoreCache)
|
||||
sn.installApiHandlers()
|
||||
|
@ -428,11 +437,18 @@ proc asyncRun*(sn: SigningNodeRef) {.async.} =
|
|||
|
||||
template runWithSignals(sn: SigningNodeRef, body: untyped): bool =
|
||||
let future = body
|
||||
discard await race(future, sn.sigintHandleFut, sn.sigtermHandleFut)
|
||||
try:
|
||||
discard await race(future, sn.sigintHandleFut, sn.sigtermHandleFut)
|
||||
except CancelledError:
|
||||
discard
|
||||
if future.finished():
|
||||
if future.failed() or future.cancelled():
|
||||
discard future.readError()
|
||||
debug "Signing node initialization failed"
|
||||
let exc = future.error
|
||||
if not(isNil(exc)):
|
||||
debug "Signing node initialization failed",
|
||||
error_name = $exc.name, reason = $exc.msg
|
||||
else:
|
||||
debug "Signing node initialization failed"
|
||||
var pending: seq[Future[void]]
|
||||
if not(sn.sigintHandleFut.finished()):
|
||||
pending.add(cancelAndWait(sn.sigintHandleFut))
|
||||
|
@ -453,7 +469,7 @@ template runWithSignals(sn: SigningNodeRef, body: untyped): bool =
|
|||
await noCancel allFutures(pending)
|
||||
false
|
||||
|
||||
proc runSigningNode(config: SigningNodeConf) {.async.} =
|
||||
proc runSigningNode(config: SigningNodeConf) {.async: (raises: []).} =
|
||||
let sn = SigningNodeRef.new(config)
|
||||
if not sn.runWithSignals(asyncInit sn):
|
||||
return
|
||||
|
|
|
@ -1871,6 +1871,72 @@ proc readValue*[T: SomeForkedLightClientObject](
|
|||
else:
|
||||
reader.raiseUnexpectedValue("Unsupported fork " & $version.get)
|
||||
|
||||
## ForkedAggregateAndProof
|
||||
proc readValue*(reader: var JsonReader[RestJson],
|
||||
value: var ForkedAggregateAndProof) {.
|
||||
raises: [IOError, SerializationError].} =
|
||||
var
|
||||
version: Opt[ConsensusFork]
|
||||
data: Opt[JsonString]
|
||||
|
||||
for fieldName {.inject.} in readObjectFields(reader):
|
||||
case fieldName
|
||||
of "version":
|
||||
if version.isSome():
|
||||
reader.raiseUnexpectedField("Multiple version fields found",
|
||||
"ForkedAggregateAndProof")
|
||||
let vres = reader.readValue(string).toLowerAscii()
|
||||
version = ConsensusFork.init(vres)
|
||||
if version.isNone():
|
||||
reader.raiseUnexpectedValue("Incorrect version field value")
|
||||
of "data":
|
||||
if data.isSome():
|
||||
reader.raiseUnexpectedField(
|
||||
"Multiple '" & fieldName & "' fields found",
|
||||
"ForkedAggregateAndProof")
|
||||
data = Opt.some(reader.readValue(JsonString))
|
||||
else:
|
||||
unrecognizedFieldWarning(fieldName, "ForkedAggregateAndProof")
|
||||
|
||||
if version.isNone():
|
||||
reader.raiseUnexpectedValue("Field `version` is missing")
|
||||
if data.isNone():
|
||||
reader.raiseUnexpectedValue("Field `data` is missing")
|
||||
|
||||
withConsensusFork(version.get()):
|
||||
when consensusFork < ConsensusFork.Electra:
|
||||
let res =
|
||||
try:
|
||||
RestJson.decode(string(data.get()),
|
||||
phase0.AggregateAndProof,
|
||||
requireAllFields = true,
|
||||
allowUnknownFields = true)
|
||||
except SerializationError as exc:
|
||||
reader.raiseUnexpectedValue(
|
||||
"Incorrect phase0 aggregated attestation format, [" &
|
||||
exc.formatMsg("ForkedAggregateAndProof") & "]")
|
||||
value = ForkedAggregateAndProof.init(res, consensusFork)
|
||||
else:
|
||||
let res =
|
||||
try:
|
||||
RestJson.decode(string(data.get()),
|
||||
electra.AggregateAndProof,
|
||||
requireAllFields = true,
|
||||
allowUnknownFields = true)
|
||||
except SerializationError as exc:
|
||||
reader.raiseUnexpectedValue(
|
||||
"Incorrect electra aggregated attestation format, [" &
|
||||
exc.formatMsg("ForkedAggregateAndProof") & "]")
|
||||
value = ForkedAggregateAndProof.init(res, consensusFork)
|
||||
|
||||
proc writeValue*(writer: var JsonWriter[RestJson],
|
||||
proof: ForkedAggregateAndProof) {.raises: [IOError].} =
|
||||
writer.beginRecord()
|
||||
writer.writeField("version", proof.kind)
|
||||
withAggregateAndProof(proof):
|
||||
writer.writeField("data", forkyProof)
|
||||
writer.endRecord()
|
||||
|
||||
## Web3SignerRequest
|
||||
proc writeValue*(
|
||||
writer: var JsonWriter[RestJson], value: Web3SignerRequest
|
||||
|
@ -1895,6 +1961,14 @@ proc writeValue*(
|
|||
if isSome(value.signingRoot):
|
||||
writer.writeField("signingRoot", value.signingRoot)
|
||||
writer.writeField("aggregate_and_proof", value.aggregateAndProof)
|
||||
of Web3SignerRequestKind.AggregateAndProofV2:
|
||||
doAssert(value.forkInfo.isSome(),
|
||||
"forkInfo should be set for this type of request")
|
||||
writer.writeField("type", "AGGREGATE_AND_PROOF_V2")
|
||||
writer.writeField("fork_info", value.forkInfo.get())
|
||||
if isSome(value.signingRoot):
|
||||
writer.writeField("signingRoot", value.signingRoot)
|
||||
writer.writeField("aggregate_and_proof", value.forkedAggregateAndProof)
|
||||
of Web3SignerRequestKind.Attestation:
|
||||
doAssert(value.forkInfo.isSome(),
|
||||
"forkInfo should be set for this type of request")
|
||||
|
@ -1998,6 +2072,8 @@ proc readValue*(reader: var JsonReader[RestJson],
|
|||
Web3SignerRequestKind.AggregationSlot
|
||||
of "AGGREGATE_AND_PROOF":
|
||||
Web3SignerRequestKind.AggregateAndProof
|
||||
of "AGGREGATE_AND_PROOF_V2":
|
||||
Web3SignerRequestKind.AggregateAndProofV2
|
||||
of "ATTESTATION":
|
||||
Web3SignerRequestKind.Attestation
|
||||
of "BLOCK_V2":
|
||||
|
@ -2055,13 +2131,10 @@ proc readValue*(reader: var JsonReader[RestJson],
|
|||
reader.raiseUnexpectedValue("Field `aggregation_slot` is missing")
|
||||
if forkInfo.isNone():
|
||||
reader.raiseUnexpectedValue("Field `fork_info` is missing")
|
||||
let data =
|
||||
block:
|
||||
let res = decodeJsonString(Web3SignerAggregationSlotData, data.get())
|
||||
if res.isErr():
|
||||
reader.raiseUnexpectedValue(
|
||||
"Incorrect field `aggregation_slot` format")
|
||||
res.get()
|
||||
let data = decodeJsonString(Web3SignerAggregationSlotData,
|
||||
data.get()).valueOr:
|
||||
reader.raiseUnexpectedValue(
|
||||
"Incorrect field `aggregation_slot` format")
|
||||
Web3SignerRequest(kind: Web3SignerRequestKind.AggregationSlot,
|
||||
forkInfo: forkInfo, signingRoot: signingRoot, aggregationSlot: data
|
||||
)
|
||||
|
@ -2070,29 +2143,33 @@ proc readValue*(reader: var JsonReader[RestJson],
|
|||
reader.raiseUnexpectedValue("Field `aggregate_and_proof` is missing")
|
||||
if forkInfo.isNone():
|
||||
reader.raiseUnexpectedValue("Field `fork_info` is missing")
|
||||
let data =
|
||||
block:
|
||||
let res = decodeJsonString(phase0.AggregateAndProof, data.get())
|
||||
if res.isErr():
|
||||
reader.raiseUnexpectedValue(
|
||||
"Incorrect field `aggregate_and_proof` format")
|
||||
res.get()
|
||||
let data = decodeJsonString(phase0.AggregateAndProof, data.get()).valueOr:
|
||||
reader.raiseUnexpectedValue(
|
||||
"Incorrect field `aggregate_and_proof` format")
|
||||
Web3SignerRequest(
|
||||
kind: Web3SignerRequestKind.AggregateAndProof,
|
||||
forkInfo: forkInfo, signingRoot: signingRoot, aggregateAndProof: data
|
||||
)
|
||||
of Web3SignerRequestKind.AggregateAndProofV2:
|
||||
if dataName != "aggregate_and_proof":
|
||||
reader.raiseUnexpectedValue("Field `aggregate_and_proof` is missing")
|
||||
if forkInfo.isNone():
|
||||
reader.raiseUnexpectedValue("Field `fork_info` is missing")
|
||||
let data = decodeJsonString(ForkedAggregateAndProof, data.get()).valueOr:
|
||||
reader.raiseUnexpectedValue(
|
||||
"Incorrect field `aggregate_and_proof` format")
|
||||
Web3SignerRequest(
|
||||
kind: Web3SignerRequestKind.AggregateAndProofV2,
|
||||
forkInfo: forkInfo, signingRoot: signingRoot,
|
||||
forkedAggregateAndProof: data
|
||||
)
|
||||
of Web3SignerRequestKind.Attestation:
|
||||
if dataName != "attestation":
|
||||
reader.raiseUnexpectedValue("Field `attestation` is missing")
|
||||
if forkInfo.isNone():
|
||||
reader.raiseUnexpectedValue("Field `fork_info` is missing")
|
||||
let data =
|
||||
block:
|
||||
let res = decodeJsonString(AttestationData, data.get())
|
||||
if res.isErr():
|
||||
reader.raiseUnexpectedValue(
|
||||
"Incorrect field `attestation` format")
|
||||
res.get()
|
||||
let data = decodeJsonString(AttestationData, data.get()).valueOr:
|
||||
reader.raiseUnexpectedValue("Incorrect field `attestation` format")
|
||||
Web3SignerRequest(
|
||||
kind: Web3SignerRequestKind.Attestation,
|
||||
forkInfo: forkInfo, signingRoot: signingRoot, attestation: data
|
||||
|
@ -2104,13 +2181,9 @@ proc readValue*(reader: var JsonReader[RestJson],
|
|||
reader.raiseUnexpectedValue("Field `beacon_block` is missing")
|
||||
if forkInfo.isNone():
|
||||
reader.raiseUnexpectedValue("Field `fork_info` is missing")
|
||||
let data =
|
||||
block:
|
||||
let res = decodeJsonString(Web3SignerForkedBeaconBlock, data.get())
|
||||
if res.isErr():
|
||||
reader.raiseUnexpectedValue(
|
||||
"Incorrect field `beacon_block` format")
|
||||
res.get()
|
||||
let data = decodeJsonString(Web3SignerForkedBeaconBlock,
|
||||
data.get()).valueOr:
|
||||
reader.raiseUnexpectedValue("Incorrect field `beacon_block` format")
|
||||
if len(proofs) > 0:
|
||||
Web3SignerRequest(
|
||||
kind: Web3SignerRequestKind.BlockV2,
|
||||
|
@ -2125,13 +2198,8 @@ proc readValue*(reader: var JsonReader[RestJson],
|
|||
of Web3SignerRequestKind.Deposit:
|
||||
if dataName != "deposit":
|
||||
reader.raiseUnexpectedValue("Field `deposit` is missing")
|
||||
let data =
|
||||
block:
|
||||
let res = decodeJsonString(Web3SignerDepositData, data.get())
|
||||
if res.isErr():
|
||||
reader.raiseUnexpectedValue(
|
||||
"Incorrect field `deposit` format")
|
||||
res.get()
|
||||
let data = decodeJsonString(Web3SignerDepositData, data.get()).valueOr:
|
||||
reader.raiseUnexpectedValue("Incorrect field `deposit` format")
|
||||
Web3SignerRequest(
|
||||
kind: Web3SignerRequestKind.Deposit,
|
||||
signingRoot: signingRoot, deposit: data
|
||||
|
@ -2141,13 +2209,9 @@ proc readValue*(reader: var JsonReader[RestJson],
|
|||
reader.raiseUnexpectedValue("Field `randao_reveal` is missing")
|
||||
if forkInfo.isNone():
|
||||
reader.raiseUnexpectedValue("Field `fork_info` is missing")
|
||||
let data =
|
||||
block:
|
||||
let res = decodeJsonString(Web3SignerRandaoRevealData, data.get())
|
||||
if res.isErr():
|
||||
reader.raiseUnexpectedValue(
|
||||
"Incorrect field `randao_reveal` format")
|
||||
res.get()
|
||||
let data = decodeJsonString(Web3SignerRandaoRevealData,
|
||||
data.get()).valueOr:
|
||||
reader.raiseUnexpectedValue("Incorrect field `randao_reveal` format")
|
||||
Web3SignerRequest(
|
||||
kind: Web3SignerRequestKind.RandaoReveal,
|
||||
forkInfo: forkInfo, signingRoot: signingRoot, randaoReveal: data
|
||||
|
@ -2157,13 +2221,8 @@ proc readValue*(reader: var JsonReader[RestJson],
|
|||
reader.raiseUnexpectedValue("Field `voluntary_exit` is missing")
|
||||
if forkInfo.isNone():
|
||||
reader.raiseUnexpectedValue("Field `fork_info` is missing")
|
||||
let data =
|
||||
block:
|
||||
let res = decodeJsonString(VoluntaryExit, data.get())
|
||||
if res.isErr():
|
||||
reader.raiseUnexpectedValue(
|
||||
"Incorrect field `voluntary_exit` format")
|
||||
res.get()
|
||||
let data = decodeJsonString(VoluntaryExit, data.get()).valueOr:
|
||||
reader.raiseUnexpectedValue("Incorrect field `voluntary_exit` format")
|
||||
Web3SignerRequest(
|
||||
kind: Web3SignerRequestKind.VoluntaryExit,
|
||||
forkInfo: forkInfo, signingRoot: signingRoot, voluntaryExit: data
|
||||
|
@ -2174,13 +2233,10 @@ proc readValue*(reader: var JsonReader[RestJson],
|
|||
"Field `sync_committee_message` is missing")
|
||||
if forkInfo.isNone():
|
||||
reader.raiseUnexpectedValue("Field `fork_info` is missing")
|
||||
let data =
|
||||
block:
|
||||
let res = decodeJsonString(Web3SignerSyncCommitteeMessageData, data.get())
|
||||
if res.isErr():
|
||||
reader.raiseUnexpectedValue(
|
||||
"Incorrect field `sync_committee_message` format")
|
||||
res.get()
|
||||
let data = decodeJsonString(Web3SignerSyncCommitteeMessageData,
|
||||
data.get()).valueOr:
|
||||
reader.raiseUnexpectedValue(
|
||||
"Incorrect field `sync_committee_message` format")
|
||||
Web3SignerRequest(
|
||||
kind: Web3SignerRequestKind.SyncCommitteeMessage,
|
||||
forkInfo: forkInfo, signingRoot: signingRoot,
|
||||
|
@ -2192,13 +2248,10 @@ proc readValue*(reader: var JsonReader[RestJson],
|
|||
"Field `sync_aggregator_selection_data` is missing")
|
||||
if forkInfo.isNone():
|
||||
reader.raiseUnexpectedValue("Field `fork_info` is missing")
|
||||
let data =
|
||||
block:
|
||||
let res = decodeJsonString(SyncAggregatorSelectionData, data.get())
|
||||
if res.isErr():
|
||||
reader.raiseUnexpectedValue(
|
||||
"Incorrect field `sync_aggregator_selection_data` format")
|
||||
res.get()
|
||||
let data = decodeJsonString(SyncAggregatorSelectionData,
|
||||
data.get()).valueOr:
|
||||
reader.raiseUnexpectedValue(
|
||||
"Incorrect field `sync_aggregator_selection_data` format")
|
||||
Web3SignerRequest(
|
||||
kind: Web3SignerRequestKind.SyncCommitteeSelectionProof,
|
||||
forkInfo: forkInfo, signingRoot: signingRoot,
|
||||
|
@ -2210,13 +2263,9 @@ proc readValue*(reader: var JsonReader[RestJson],
|
|||
"Field `contribution_and_proof` is missing")
|
||||
if forkInfo.isNone():
|
||||
reader.raiseUnexpectedValue("Field `fork_info` is missing")
|
||||
let data =
|
||||
block:
|
||||
let res = decodeJsonString(ContributionAndProof, data.get())
|
||||
if res.isErr():
|
||||
reader.raiseUnexpectedValue(
|
||||
"Incorrect field `contribution_and_proof` format")
|
||||
res.get()
|
||||
let data = decodeJsonString(ContributionAndProof, data.get()).valueOr:
|
||||
reader.raiseUnexpectedValue(
|
||||
"Incorrect field `contribution_and_proof` format")
|
||||
Web3SignerRequest(
|
||||
kind: Web3SignerRequestKind.SyncCommitteeContributionAndProof,
|
||||
forkInfo: forkInfo, signingRoot: signingRoot,
|
||||
|
@ -2228,14 +2277,10 @@ proc readValue*(reader: var JsonReader[RestJson],
|
|||
"Field `validator_registration` is missing")
|
||||
if forkInfo.isNone():
|
||||
reader.raiseUnexpectedValue("Field `fork_info` is missing")
|
||||
let data =
|
||||
block:
|
||||
let res =
|
||||
decodeJsonString(Web3SignerValidatorRegistration, data.get())
|
||||
if res.isErr():
|
||||
reader.raiseUnexpectedValue(
|
||||
"Incorrect field `validator_registration` format")
|
||||
res.get()
|
||||
let data = decodeJsonString(Web3SignerValidatorRegistration,
|
||||
data.get()).valueOr:
|
||||
reader.raiseUnexpectedValue(
|
||||
"Incorrect field `validator_registration` format")
|
||||
Web3SignerRequest(
|
||||
kind: Web3SignerRequestKind.ValidatorRegistration,
|
||||
forkInfo: forkInfo, signingRoot: signingRoot,
|
||||
|
|
|
@ -412,8 +412,8 @@ type
|
|||
proof*: seq[Eth2Digest]
|
||||
|
||||
Web3SignerRequestKind* {.pure.} = enum
|
||||
AggregationSlot, AggregateAndProof, Attestation, BlockV2,
|
||||
Deposit, RandaoReveal, VoluntaryExit, SyncCommitteeMessage,
|
||||
AggregationSlot, AggregateAndProof, AggregateAndProofV2, Attestation,
|
||||
BlockV2, Deposit, RandaoReveal, VoluntaryExit, SyncCommitteeMessage,
|
||||
SyncCommitteeSelectionProof, SyncCommitteeContributionAndProof,
|
||||
ValidatorRegistration
|
||||
|
||||
|
@ -427,6 +427,9 @@ type
|
|||
of Web3SignerRequestKind.AggregateAndProof:
|
||||
aggregateAndProof* {.
|
||||
serializedFieldName: "aggregate_and_proof".}: phase0.AggregateAndProof
|
||||
of Web3SignerRequestKind.AggregateAndProofV2:
|
||||
forkedAggregateAndProof* {.
|
||||
serializedFieldName: "aggregate_and_proof".}: ForkedAggregateAndProof
|
||||
of Web3SignerRequestKind.Attestation:
|
||||
attestation*: AttestationData
|
||||
of Web3SignerRequestKind.BlockV2:
|
||||
|
@ -766,12 +769,22 @@ func init*(t: typedesc[Web3SignerRequest], fork: Fork,
|
|||
aggregateAndProof: data
|
||||
)
|
||||
|
||||
func init*(t: typedesc[Web3SignerRequest], fork: Fork,
|
||||
genesis_validators_root: Eth2Digest, data: electra.AggregateAndProof,
|
||||
signingRoot: Opt[Eth2Digest] = Opt.none(Eth2Digest)
|
||||
): Web3SignerRequest =
|
||||
debugComment "doesn't seem specified yet"
|
||||
Web3SignerRequest()
|
||||
func init*(
|
||||
t: typedesc[Web3SignerRequest],
|
||||
fork: Fork,
|
||||
genesis_validators_root: Eth2Digest,
|
||||
data: electra.AggregateAndProof,
|
||||
signingRoot: Opt[Eth2Digest] = Opt.none(Eth2Digest)
|
||||
): Web3SignerRequest =
|
||||
Web3SignerRequest(
|
||||
kind: Web3SignerRequestKind.AggregateAndProofV2,
|
||||
forkInfo: Opt.some(Web3SignerForkInfo(
|
||||
fork: fork, genesis_validators_root: genesis_validators_root
|
||||
)),
|
||||
signingRoot: signingRoot,
|
||||
forkedAggregateAndProof:
|
||||
ForkedAggregateAndProof.init(data, typeof(data).kind)
|
||||
)
|
||||
|
||||
func init*(t: typedesc[Web3SignerRequest], fork: Fork,
|
||||
genesis_validators_root: Eth2Digest, data: AttestationData,
|
||||
|
|
|
@ -153,6 +153,23 @@ type
|
|||
deneb_mev.BlindedBeaconBlock |
|
||||
electra_mev.BlindedBeaconBlock
|
||||
|
||||
ForkyAggregateAndProof* =
|
||||
phase0.AggregateAndProof |
|
||||
electra.AggregateAndProof
|
||||
|
||||
ForkySignedAggregateAndProof* =
|
||||
phase0.SignedAggregateAndProof |
|
||||
electra.SignedAggregateAndProof
|
||||
|
||||
ForkedAggregateAndProof* = object
|
||||
case kind*: ConsensusFork
|
||||
of ConsensusFork.Phase0: phase0Data*: phase0.AggregateAndProof
|
||||
of ConsensusFork.Altair: altairData*: phase0.AggregateAndProof
|
||||
of ConsensusFork.Bellatrix: bellatrixData*: phase0.AggregateAndProof
|
||||
of ConsensusFork.Capella: capellaData*: phase0.AggregateAndProof
|
||||
of ConsensusFork.Deneb: denebData*: phase0.AggregateAndProof
|
||||
of ConsensusFork.Electra: electraData*: electra.AggregateAndProof
|
||||
|
||||
ForkedBeaconBlock* = object
|
||||
case kind*: ConsensusFork
|
||||
of ConsensusFork.Phase0: phase0Data*: phase0.BeaconBlock
|
||||
|
@ -305,7 +322,8 @@ template kind*(
|
|||
phase0.TrustedBeaconBlockBody |
|
||||
phase0.SigVerifiedSignedBeaconBlock |
|
||||
phase0.MsgTrustedSignedBeaconBlock |
|
||||
phase0.TrustedSignedBeaconBlock]): ConsensusFork =
|
||||
phase0.TrustedSignedBeaconBlock |
|
||||
phase0.AggregateAndProof]): ConsensusFork =
|
||||
ConsensusFork.Phase0
|
||||
|
||||
template kind*(
|
||||
|
@ -396,7 +414,8 @@ template kind*(
|
|||
electra.SigVerifiedSignedBeaconBlock |
|
||||
electra.MsgTrustedSignedBeaconBlock |
|
||||
electra.TrustedSignedBeaconBlock |
|
||||
electra_mev.SignedBlindedBeaconBlock]): ConsensusFork =
|
||||
electra_mev.SignedBlindedBeaconBlock |
|
||||
electra.AggregateAndProof]): ConsensusFork =
|
||||
ConsensusFork.Electra
|
||||
|
||||
template BeaconState*(kind: static ConsensusFork): auto =
|
||||
|
@ -1221,6 +1240,34 @@ template withStateAndBlck*(
|
|||
template forkyBlck: untyped {.inject, used.} = b.phase0Data
|
||||
body
|
||||
|
||||
template withAggregateAndProof*(a: ForkedAggregateAndProof,
|
||||
body: untyped): untyped =
|
||||
case a.kind
|
||||
of ConsensusFork.Electra:
|
||||
const consensusFork {.inject, used.} = ConsensusFork.Electra
|
||||
template forkyProof: untyped {.inject.} = a.electraData
|
||||
body
|
||||
of ConsensusFork.Deneb:
|
||||
const consensusFork {.inject, used.} = ConsensusFork.Deneb
|
||||
template forkyProof: untyped {.inject.} = a.denebData
|
||||
body
|
||||
of ConsensusFork.Capella:
|
||||
const consensusFork {.inject, used.} = ConsensusFork.Capella
|
||||
template forkyProof: untyped {.inject.} = a.capellaData
|
||||
body
|
||||
of ConsensusFork.Bellatrix:
|
||||
const consensusFork {.inject, used.} = ConsensusFork.Bellatrix
|
||||
template forkyProof: untyped {.inject.} = a.bellatrixData
|
||||
body
|
||||
of ConsensusFork.Altair:
|
||||
const consensusFork {.inject, used.} = ConsensusFork.Altair
|
||||
template forkyProof: untyped {.inject.} = a.altairData
|
||||
body
|
||||
of ConsensusFork.Phase0:
|
||||
const consensusFork {.inject, used.} = ConsensusFork.Phase0
|
||||
template forkyProof: untyped {.inject.} = a.phase0Data
|
||||
body
|
||||
|
||||
func toBeaconBlockHeader*(
|
||||
blck: SomeForkyBeaconBlock | deneb_mev.BlindedBeaconBlock |
|
||||
electra_mev.BlindedBeaconBlock): BeaconBlockHeader =
|
||||
|
@ -1549,3 +1596,31 @@ func committee_index*(v: electra.Attestation, on_chain: static bool): uint64 =
|
|||
{.error: "cannot get single committee_index for on_chain attestation".}
|
||||
else:
|
||||
uint64 v.committee_bits.get_committee_index_one().expect("network attestation")
|
||||
|
||||
template init*(T: type ForkedAggregateAndProof,
|
||||
proof: phase0.AggregateAndProof,
|
||||
fork: ConsensusFork): T =
|
||||
case fork
|
||||
of ConsensusFork.Phase0:
|
||||
ForkedAggregateAndProof(kind: ConsensusFork.Phase0, phase0Data: proof)
|
||||
of ConsensusFork.Altair:
|
||||
ForkedAggregateAndProof(kind: ConsensusFork.Altair, altairData: proof)
|
||||
of ConsensusFork.Bellatrix:
|
||||
ForkedAggregateAndProof(kind: ConsensusFork.Bellatrix, bellatrixData: proof)
|
||||
of ConsensusFork.Capella:
|
||||
ForkedAggregateAndProof(kind: ConsensusFork.Capella, capellaData: proof)
|
||||
of ConsensusFork.Deneb:
|
||||
ForkedAggregateAndProof(kind: ConsensusFork.Deneb, denebData: proof)
|
||||
of ConsensusFork.Electra:
|
||||
raiseAssert $fork &
|
||||
" fork should not be used for this type of aggregate and proof"
|
||||
|
||||
template init*(T: type ForkedAggregateAndProof,
|
||||
proof: electra.AggregateAndProof,
|
||||
fork: ConsensusFork): T =
|
||||
case fork
|
||||
of ConsensusFork.Phase0 .. ConsensusFork.Deneb:
|
||||
raiseAssert $fork &
|
||||
" fork should not be used for this type of aggregate and proof"
|
||||
of ConsensusFork.Electra:
|
||||
ForkedAggregateAndProof(kind: ConsensusFork.Electra, electraData: proof)
|
||||
|
|
|
@ -59,7 +59,8 @@ const
|
|||
SigningExpectedFeeRecipient = "0x000095e79eac4d76aab57cb2c1f091d553b36ca0"
|
||||
SigningOtherFeeRecipient = "0x000096e79eac4d76aab57cb2c1f091d553b36ca0"
|
||||
|
||||
AgAttestation = "{\"data\":{\"aggregation_bits\":\"0x01\",\"signature\":\"0x1b66ac1fb663c9bc59509846d6ec05345bd908eda73e670af888da41af171505cc411d61252fb6cb3fa0017b679f8bb2305b26a285fa2737f175668d0dff91cc1b66ac1fb663c9bc59509846d6ec05345bd908eda73e670af888da41af171505\",\"data\":{\"slot\":\"1\",\"index\":\"1\",\"beacon_block_root\":\"0xcf8e0d4e9587369b2301d0790347320302cc0943d5a1884560367e8208d920f2\",\"source\":{\"epoch\":\"1\",\"root\":\"0xcf8e0d4e9587369b2301d0790347320302cc0943d5a1884560367e8208d920f2\"},\"target\":{\"epoch\":\"1\",\"root\":\"0xcf8e0d4e9587369b2301d0790347320302cc0943d5a1884560367e8208d920f2\"}}}}"
|
||||
AgAttestationPhase0 = "{\"data\":{\"aggregation_bits\":\"0x01\",\"signature\":\"0x1b66ac1fb663c9bc59509846d6ec05345bd908eda73e670af888da41af171505cc411d61252fb6cb3fa0017b679f8bb2305b26a285fa2737f175668d0dff91cc1b66ac1fb663c9bc59509846d6ec05345bd908eda73e670af888da41af171505\",\"data\":{\"slot\":\"1\",\"index\":\"1\",\"beacon_block_root\":\"0xcf8e0d4e9587369b2301d0790347320302cc0943d5a1884560367e8208d920f2\",\"source\":{\"epoch\":\"1\",\"root\":\"0xcf8e0d4e9587369b2301d0790347320302cc0943d5a1884560367e8208d920f2\"},\"target\":{\"epoch\":\"1\",\"root\":\"0xcf8e0d4e9587369b2301d0790347320302cc0943d5a1884560367e8208d920f2\"}}}}"
|
||||
AgAttestationElectra = "{\"data\":{\"aggregation_bits\":\"0x01\",\"committee_bits\":\"0x0000000000000001\",\"signature\":\"0x1b66ac1fb663c9bc59509846d6ec05345bd908eda73e670af888da41af171505cc411d61252fb6cb3fa0017b679f8bb2305b26a285fa2737f175668d0dff91cc1b66ac1fb663c9bc59509846d6ec05345bd908eda73e670af888da41af171505\",\"data\":{\"slot\":\"1\",\"index\":\"1\",\"beacon_block_root\":\"0xcf8e0d4e9587369b2301d0790347320302cc0943d5a1884560367e8208d920f2\",\"source\":{\"epoch\":\"1\",\"root\":\"0xcf8e0d4e9587369b2301d0790347320302cc0943d5a1884560367e8208d920f2\"},\"target\":{\"epoch\":\"1\",\"root\":\"0xcf8e0d4e9587369b2301d0790347320302cc0943d5a1884560367e8208d920f2\"}}}}"
|
||||
|
||||
CapellaBlock = "{\"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\":[]},\"bls_to_execution_changes\":[]}},\"signature\":\"$2\"}"
|
||||
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\":[]}"
|
||||
|
@ -657,13 +658,14 @@ block:
|
|||
sres2.get() == rres2.get()
|
||||
sres3.get() == rres3.get()
|
||||
|
||||
asyncTest "Signing aggregate and proof (getAggregateAndProofSignature())":
|
||||
asyncTest "Signing aggregate and proof " &
|
||||
"(getAggregateAndProofSignature(phase0))":
|
||||
let
|
||||
contentType = ContentTypeData(
|
||||
mediaType: MediaType.init("application/json"))
|
||||
agAttestation = decodeBytes(
|
||||
GetAggregatedAttestationResponse,
|
||||
AgAttestation.toOpenArrayByte(0, len(AgAttestation) - 1),
|
||||
AgAttestationPhase0.toOpenArrayByte(0, len(AgAttestationPhase0) - 1),
|
||||
Opt.some(contentType)).tryGet().data
|
||||
agProof = phase0.AggregateAndProof(
|
||||
aggregator_index: 1'u64,
|
||||
|
@ -699,6 +701,50 @@ block:
|
|||
sres2.get() == rres2.get()
|
||||
sres3.get() == rres3.get()
|
||||
|
||||
asyncTest "Signing aggregate and proof " &
|
||||
"(getAggregateAndProofSignature(electra))":
|
||||
let
|
||||
contentType = ContentTypeData(
|
||||
mediaType: MediaType.init("application/json"))
|
||||
agAttestation = decodeBytes(
|
||||
GetElectraAggregatedAttestationResponse,
|
||||
AgAttestationElectra.toOpenArrayByte(0,
|
||||
len(AgAttestationElectra) - 1),
|
||||
Opt.some(contentType)).tryGet().data
|
||||
agProof = electra.AggregateAndProof(
|
||||
aggregator_index: 1'u64,
|
||||
aggregate: agAttestation,
|
||||
selection_proof: ValidatorSig.fromHex(SomeSignature).get())
|
||||
sres1 =
|
||||
await validator1.getAggregateAndProofSignature(SigningFork,
|
||||
GenesisValidatorsRoot, agProof)
|
||||
sres2 =
|
||||
await validator2.getAggregateAndProofSignature(SigningFork,
|
||||
GenesisValidatorsRoot, agProof)
|
||||
sres3 =
|
||||
await validator3.getAggregateAndProofSignature(SigningFork,
|
||||
GenesisValidatorsRoot, agProof)
|
||||
rres1 =
|
||||
await validator4.getAggregateAndProofSignature(SigningFork,
|
||||
GenesisValidatorsRoot, agProof)
|
||||
rres2 =
|
||||
await validator5.getAggregateAndProofSignature(SigningFork,
|
||||
GenesisValidatorsRoot, agProof)
|
||||
rres3 =
|
||||
await validator6.getAggregateAndProofSignature(SigningFork,
|
||||
GenesisValidatorsRoot, agProof)
|
||||
|
||||
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 "Signing validator registration (getBuilderSignature())":
|
||||
let
|
||||
vdata = default(ValidatorRegistrationV1)
|
||||
|
|
Loading…
Reference in New Issue