Skip to content

Commit 397033a

Browse files
authored
Improve the compatibility with various Web3Signer versions and configurations (#3640)
* Some Web3Signer versions insist replying with text/plain messages * When reading blocks, the Web3Signer uses upper-case fork identifiers instead of lower-case identifies like the Beacon API.
1 parent 1177f33 commit 397033a

File tree

5 files changed

+62
-37
lines changed

5 files changed

+62
-37
lines changed

beacon_chain/spec/eth2_apis/eth2_rest_serialization.nim

Lines changed: 26 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -665,9 +665,9 @@ proc readValue*(
665665
reader, "Expected a valid hex string with " & $value.len() & " bytes")
666666

667667
## ForkedBeaconBlock
668-
proc readValue*(reader: var JsonReader[RestJson],
669-
value: var ForkedBeaconBlock) {.
670-
raises: [IOError, SerializationError, Defect].} =
668+
proc readValue*[BlockType: Web3SignerForkedBeaconBlock|ForkedBeaconBlock](
669+
reader: var JsonReader[RestJson],
670+
value: var BlockType) {.raises: [IOError, SerializationError, Defect].} =
671671
var
672672
version: Option[BeaconBlockFork]
673673
data: Option[JsonString]
@@ -680,17 +680,17 @@ proc readValue*(reader: var JsonReader[RestJson],
680680
"ForkedBeaconBlock")
681681
let vres = reader.readValue(string)
682682
case vres
683-
of "phase0":
683+
of "PHASE0", "phase0":
684684
version = some(BeaconBlockFork.Phase0)
685-
of "altair":
685+
of "ALTAIR", "altair":
686686
version = some(BeaconBlockFork.Altair)
687-
of "bellatrix":
687+
of "BELLATRIX", "bellatrix":
688688
version = some(BeaconBlockFork.Bellatrix)
689689
else:
690690
reader.raiseUnexpectedValue("Incorrect version field value")
691-
of "data":
691+
of "block", "block_header", "data":
692692
if data.isSome():
693-
reader.raiseUnexpectedField("Multiple data fields found",
693+
reader.raiseUnexpectedField("Multiple block or block_header fields found",
694694
"ForkedBeaconBlock")
695695
data = some(reader.readValue(JsonString))
696696
else:
@@ -711,7 +711,7 @@ proc readValue*(reader: var JsonReader[RestJson],
711711
none[phase0.BeaconBlock]()
712712
if res.isNone():
713713
reader.raiseUnexpectedValue("Incorrect phase0 block format")
714-
value = ForkedBeaconBlock.init(res.get())
714+
value = ForkedBeaconBlock.init(res.get()).BlockType
715715
of BeaconBlockFork.Altair:
716716
let res =
717717
try:
@@ -721,7 +721,7 @@ proc readValue*(reader: var JsonReader[RestJson],
721721
none[altair.BeaconBlock]()
722722
if res.isNone():
723723
reader.raiseUnexpectedValue("Incorrect altair block format")
724-
value = ForkedBeaconBlock.init(res.get())
724+
value = ForkedBeaconBlock.init(res.get()).BlockType
725725
of BeaconBlockFork.Bellatrix:
726726
let res =
727727
try:
@@ -731,20 +731,29 @@ proc readValue*(reader: var JsonReader[RestJson],
731731
none[bellatrix.BeaconBlock]()
732732
if res.isNone():
733733
reader.raiseUnexpectedValue("Incorrect bellatrix block format")
734-
value = ForkedBeaconBlock.init(res.get())
734+
value = ForkedBeaconBlock.init(res.get()).BlockType
735+
736+
737+
proc writeValue*[BlockType: Web3SignerForkedBeaconBlock|ForkedBeaconBlock](
738+
writer: var JsonWriter[RestJson],
739+
value: BlockType) {.raises: [IOError, Defect].} =
740+
741+
template forkIdentifier(id: string): auto =
742+
when BlockType is ForkedBeaconBlock:
743+
id
744+
else:
745+
(static toUpperAscii id)
735746

736-
proc writeValue*(writer: var JsonWriter[RestJson], value: ForkedBeaconBlock) {.
737-
raises: [IOError, Defect].} =
738747
writer.beginRecord()
739748
case value.kind
740749
of BeaconBlockFork.Phase0:
741-
writer.writeField("version", "phase0")
750+
writer.writeField("version", forkIdentifier "phase0")
742751
writer.writeField("data", value.phase0Data)
743752
of BeaconBlockFork.Altair:
744-
writer.writeField("version", "altair")
753+
writer.writeField("version", forkIdentifier "altair")
745754
writer.writeField("data", value.altairData)
746755
of BeaconBlockFork.Bellatrix:
747-
writer.writeField("version", "bellatrix")
756+
writer.writeField("version", forkIdentifier "bellatrix")
748757
writer.writeField("data", value.bellatrixData)
749758
writer.endRecord()
750759

@@ -1452,7 +1461,7 @@ proc readValue*(reader: var JsonReader[RestJson],
14521461
reader.raiseUnexpectedValue("Field `fork_info` is missing")
14531462
let data =
14541463
block:
1455-
let res = decodeJsonString(ForkedBeaconBlock, data.get(), true)
1464+
let res = decodeJsonString(Web3SignerForkedBeaconBlock, data.get(), true)
14561465
if res.isErr():
14571466
reader.raiseUnexpectedValue(
14581467
"Incorrect field `beacon_block` format")

beacon_chain/spec/eth2_apis/rest_remote_signer_calls.nim

Lines changed: 27 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ import
1212
nimcrypto/utils as ncrutils,
1313
serialization, json_serialization,
1414
json_serialization/std/[options, net, sets],
15-
stew/[results, base10],
15+
stew/[results, base10, byteutils],
1616
"."/[rest_types, eth2_rest_serialization]
1717

1818
export chronos, httpclient, client, rest_types, eth2_rest_serialization, results
@@ -58,16 +58,19 @@ declareHistogram nbc_remote_signer_time,
5858
buckets = delayBuckets
5959

6060
proc getUpcheck*(): RestResponse[Web3SignerStatusResponse] {.
61-
rest, endpoint: "/upcheck", meth: MethodGet.}
61+
rest, endpoint: "/upcheck",
62+
meth: MethodGet, accept: "application/json" .}
6263
## https://consensys.github.io/web3signer/web3signer-eth2.html#tag/Server-Status
6364

6465
proc getKeys*(): RestResponse[Web3SignerKeysResponse] {.
65-
rest, endpoint: "/api/v1/eth2/publicKeys", meth: MethodGet.}
66+
rest, endpoint: "/api/v1/eth2/publicKeys",
67+
meth: MethodGet, accept: "application/json" .}
6668
## https://consensys.github.io/web3signer/web3signer-eth2.html#tag/Public-Key
6769

6870
proc signDataPlain*(identifier: ValidatorPubKey,
6971
body: Web3SignerRequest): RestPlainResponse {.
70-
rest, endpoint: "/api/v1/eth2/sign/{identifier}", meth: MethodPost.}
72+
rest, endpoint: "/api/v1/eth2/sign/{identifier}",
73+
meth: MethodPost, accept: "application/json" .}
7174
# https://consensys.github.io/web3signer/web3signer-eth2.html#tag/Signing
7275

7376
proc signData*(client: RestClientRef, identifier: ValidatorPubKey,
@@ -77,7 +80,8 @@ proc signData*(client: RestClientRef, identifier: ValidatorPubKey,
7780
inc(nbc_remote_signer_requests)
7881
let response =
7982
try:
80-
await client.signDataPlain(identifier, body)
83+
await client.signDataPlain(identifier, body,
84+
restAcceptType = "application/json")
8185
except RestError as exc:
8286
let msg = "[" & $exc.name & "] " & $exc.msg
8387
debug "Error occured while generating signature",
@@ -101,19 +105,27 @@ proc signData*(client: RestClientRef, identifier: ValidatorPubKey,
101105
case response.status
102106
of 200:
103107
inc(nbc_remote_signer_200_responses)
104-
let res = decodeBytes(Web3SignerSignatureResponse, response.data,
105-
response.contentType)
106-
if res.isErr():
107-
let msg = "Unable to decode remote signer response [" &
108-
$res.error() & "]"
109-
inc(nbc_remote_signer_failures)
110-
return Web3SignerDataResponse.err(msg)
111-
let sig = res.get().signature.load()
112-
if sig.isNone():
108+
let sig = if response.contentType.contains("text/plain"):
109+
let asStr = fromBytes(string, response.data)
110+
let sigFromText = fromHex(ValidatorSig, asStr)
111+
if sigFromText.isErr:
112+
return Web3SignerDataResponse.err("Unable to decode signature from plain text")
113+
sigFromText.get.load
114+
else:
115+
let res = decodeBytes(Web3SignerSignatureResponse, response.data,
116+
response.contentType)
117+
if res.isErr:
118+
let msg = "Unable to decode remote signer response [" & $res.error() & "]"
119+
inc(nbc_remote_signer_failures)
120+
return Web3SignerDataResponse.err(msg)
121+
res.get.signature.load
122+
123+
if sig.isNone:
113124
let msg = "Remote signer returns invalid signature"
114125
inc(nbc_remote_signer_failures)
115126
return Web3SignerDataResponse.err(msg)
116-
Web3SignerDataResponse.ok(sig.get())
127+
128+
Web3SignerDataResponse.ok(sig.get)
117129
of 400:
118130
inc(nbc_remote_signer_400_responses)
119131
let res = decodeBytes(Web3SignerErrorResponse, response.data,

beacon_chain/spec/eth2_apis/rest_types.nim

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -489,7 +489,7 @@ type
489489
serializedFieldName: "block".}: phase0.BeaconBlock
490490
of Web3SignerRequestKind.BlockV2:
491491
beaconBlock* {.
492-
serializedFieldName: "beacon_block".}: ForkedBeaconBlock
492+
serializedFieldName: "beacon_block".}: Web3SignerForkedBeaconBlock
493493
of Web3SignerRequestKind.Deposit:
494494
deposit*: Web3SignerDepositData
495495
of Web3SignerRequestKind.RandaoReveal:
@@ -658,7 +658,7 @@ func init*(t: typedesc[Web3SignerRequest], fork: Fork,
658658
)
659659

660660
func init*(t: typedesc[Web3SignerRequest], fork: Fork,
661-
genesis_validators_root: Eth2Digest, data: ForkedBeaconBlock,
661+
genesis_validators_root: Eth2Digest, data: Web3SignerForkedBeaconBlock,
662662
signingRoot: Option[Eth2Digest] = none[Eth2Digest]()
663663
): Web3SignerRequest =
664664
Web3SignerRequest(

beacon_chain/spec/forks.nim

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -107,6 +107,8 @@ type
107107
of BeaconBlockFork.Altair: altairData*: altair.BeaconBlock
108108
of BeaconBlockFork.Bellatrix: bellatrixData*: bellatrix.BeaconBlock
109109

110+
Web3SignerForkedBeaconBlock* {.borrow: `.`} = distinct ForkedBeaconBlock
111+
110112
ForkedTrustedBeaconBlock* = object
111113
case kind*: BeaconBlockFork
112114
of BeaconBlockFork.Phase0: phase0Data*: phase0.TrustedBeaconBlock
@@ -345,8 +347,8 @@ template asTrusted*(x: ForkedSignedBeaconBlock): ForkedTrustedSignedBeaconBlock
345347
isomorphicCast[ForkedTrustedSignedBeaconBlock](x)
346348

347349
template withBlck*(
348-
x: ForkedBeaconBlock | ForkedSignedBeaconBlock |
349-
ForkedTrustedSignedBeaconBlock,
350+
x: ForkedBeaconBlock | Web3SignerForkedBeaconBlock |
351+
ForkedSignedBeaconBlock | ForkedTrustedSignedBeaconBlock,
350352
body: untyped): untyped =
351353
case x.kind
352354
of BeaconBlockFork.Phase0:
@@ -368,6 +370,8 @@ func proposer_index*(x: ForkedBeaconBlock): uint64 =
368370
func hash_tree_root*(x: ForkedBeaconBlock): Eth2Digest =
369371
withBlck(x): hash_tree_root(blck)
370372

373+
func hash_tree_root*(x: Web3SignerForkedBeaconBlock): Eth2Digest {.borrow.}
374+
371375
template getForkedBlockField*(x: ForkedSignedBeaconBlock | ForkedTrustedSignedBeaconBlock, y: untyped): untyped =
372376
# unsafeAddr avoids a copy of the field in some cases
373377
(case x.kind

beacon_chain/validators/validator_pool.nim

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -205,7 +205,7 @@ proc signWithRemoteValidator*(v: AttachedValidator, fork: Fork,
205205
genesis_validators_root: Eth2Digest,
206206
blck: ForkedBeaconBlock): Future[SignatureResult]
207207
{.async.} =
208-
let request = Web3SignerRequest.init(fork, genesis_validators_root, blck)
208+
let request = Web3SignerRequest.init(fork, genesis_validators_root, blck.Web3SignerForkedBeaconBlock)
209209
debug "Signing block proposal using remote signer",
210210
validator = shortLog(v)
211211
return await v.signData(request)

0 commit comments

Comments
 (0)