nimbus-eth1/nimbus/core/eip6110.nim

77 lines
2.6 KiB
Nim

# Nimbus
# Copyright (c) 2024 Status Research & Development GmbH
# Licensed under either of
# * Apache License, version 2.0, ([LICENSE-APACHE](LICENSE-APACHE) or
# http://www.apache.org/licenses/LICENSE-2.0)
# * MIT license ([LICENSE-MIT](LICENSE-MIT) or
# http://opensource.org/licenses/MIT)
# at your option. This file may not be copied, modified, or distributed except
# according to those terms.
{.push raises: [].}
import
eth/common,
stew/arrayops,
stew/endians2,
results,
../constants
# -----------------------------------------------------------------------------
# Private helpers
# -----------------------------------------------------------------------------
# UnpackIntoDeposit unpacks a serialized DepositEvent.
func unpackIntoDeposit(data: openArray[byte]): Result[Request, string] =
if data.len != 576:
return err("deposit wrong length: want 576, have " & $data.len)
# The ABI encodes the position of dynamic elements first. Since there
# are 5 elements, skip over the positional data. The first 32 bytes of
# dynamic elements also encode their actual length. Skip over that value too.
const
b = 32*5 + 32
c = b + 48 + 16 + 32
d = c + 32 + 32
e = d + 8 + 24 + 32
f = e + 96 + 32
template copyFrom(T: type, input, a, b): auto =
T.initCopyFrom(input.toOpenArray(a, b))
let res = Request(
requestType: DepositRequestType,
deposit: DepositRequest(
# PublicKey is the first element. ABI encoding pads values to 32 bytes,
# so despite BLS public keys being length 48, the value length
# here is 64. Then skip over the next length value.
pubkey: array[48, byte].copyFrom(data, b, b+47),
# WithdrawalCredentials is 32 bytes. Read that value then skip over next
# length.
withdrawalCredentials: array[32, byte].copyFrom(data, c, c+31),
# Amount is 8 bytes, but it is padded to 32. Skip over it and the next
# length.
amount: uint64.fromBytesLE(data.toOpenArray(d, d+7)),
# Signature is 96 bytes. Skip over it and the next length.
signature: array[96, byte].copyFrom(data, e, e+95),
# Amount is 8 bytes.
index: uint64.fromBytesLE(data.toOpenArray(f, f+7)),
)
)
ok(res)
# -----------------------------------------------------------------------------
# Public functions
# -----------------------------------------------------------------------------
func parseDepositLogs*(logs: openArray[Log]): Result[seq[Request], string] =
var res: seq[Request]
for log in logs:
if log.address == DEPOSIT_CONTRACT_ADDRESS:
res.add ?unpackIntoDeposit(log.data)
ok(res)