rm more Snap sync code (#3047)

* rm more Snap sync code

* clean up snap1
This commit is contained in:
tersec 2025-02-07 01:45:03 +00:00 committed by GitHub
parent 796c2f7cbf
commit daebbfa18d
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
6 changed files with 34 additions and 469 deletions

View File

@ -4,7 +4,7 @@ This is a short manual to help you quickly setup and run
Hive. For more detailed information please read the Hive. For more detailed information please read the
[hive documentation](https://github.com/ethereum/hive/blob/master/docs/overview.md). [hive documentation](https://github.com/ethereum/hive/blob/master/docs/overview.md).
## Prerequisities ## Prerequisites
- A Linux machine. Trust me, it does not work on Windows or MacOS. - A Linux machine. Trust me, it does not work on Windows or MacOS.
- Or Linux inside a VM (e.g. VirtualBox) on Windows or MacOS. - Or Linux inside a VM (e.g. VirtualBox) on Windows or MacOS.

View File

@ -495,13 +495,12 @@ type
name: "engine-api-ws" .}: bool name: "engine-api-ws" .}: bool
allowedOrigins* {. allowedOrigins* {.
desc: "Comma separated list of domains from which to accept cross origin requests" desc: "Comma-separated list of domains from which to accept cross origin requests"
defaultValue: @[] defaultValue: @[]
defaultValueDesc: "*" defaultValueDesc: "*"
name: "allowed-origins" .}: seq[string] name: "allowed-origins" .}: seq[string]
# github.com/ethereum/execution-apis/ # https://github.com/ethereum/execution-apis/blob/v1.0.0-beta.4/src/engine/authentication.md#key-distribution
# /blob/v1.0.0-alpha.8/src/engine/authentication.md#key-distribution
jwtSecret* {. jwtSecret* {.
desc: "Path to a file containing a 32 byte hex-encoded shared secret" & desc: "Path to a file containing a 32 byte hex-encoded shared secret" &
" needed for websocket authentication. By default, the secret key" & " needed for websocket authentication. By default, the secret key" &

View File

@ -433,7 +433,7 @@ database, the above architecture mutates to
When looked at descriptor API there are no changes when accessing data via When looked at descriptor API there are no changes when accessing data via
*db1*, *db2*, or *db3*. In a different, more algebraic notation, the above *db1*, *db2*, or *db3*. In a different, more algebraic notation, the above
tansformation is written as transformation is written as
| tx1, ø | (8) | tx1, ø | (8)
| tx2, ø | PBE | tx2, ø | PBE

View File

@ -1,5 +1,5 @@
# Nimbus # Nimbus
# Copyright (c) 2021-2024 Status Research & Development GmbH # Copyright (c) 2021-2025 Status Research & Development GmbH
# Licensed and distributed under either of # Licensed and distributed under either of
# * MIT license (license terms in the root directory or at # * MIT license (license terms in the root directory or at
# https://opensource.org/licenses/MIT). # https://opensource.org/licenses/MIT).
@ -11,43 +11,20 @@
## Provision of `eth` and `snap` protocol version parameters ## Provision of `eth` and `snap` protocol version parameters
## ##
## `Eth` related parameters: ## `Eth` related parameters:
## `ethVersions`: seq[int] -- constant list of all available versions
## `eth` -- type symbol of default version ## `eth` -- type symbol of default version
## `proto_eth` -- export of default version directives ## `proto_eth` -- export of default version directives
## ##
## `Snap` related parameters:
## `snap` -- type symbol of default version {.push raises: [].}
## `proto_snap` -- export of default version directives
## ..aliases.. -- type names, syntactic sugar (see below)
##
import import
./protocol/eth68 as proto_eth ./protocol/eth68 as proto_eth
type eth* = eth68 type eth* = eth68
# ---------------
import import
./protocol/snap1 as proto_snap ./protocol/snap1 as proto_snap
export export
proto_eth, proto_eth,
proto_snap proto_snap
type
snap* = snap1
SnapAccountRange* = accountRangeObj
## Syntactic sugar, type defined in `snap1`
SnapStorageRanges* = storageRangesObj
## Ditto
SnapByteCodes* = byteCodesObj
## Ditto
SnapTrieNodes* = trieNodesObj
## Ditto
# End

View File

@ -1,225 +0,0 @@
# Nimbus
# Copyright (c) 2018-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
std/[hashes, sequtils],
results,
chronicles,
eth/common,
../../../constants
logScope:
topics = "snap-wire"
type
SnapAccount* = object
accHash*: Hash32
accBody* {.rlpCustomSerialization.}: Account
SnapProof* = distinct seq[byte]
## Rlp coded node data, to be handled different from a generic `Blob`
SnapProofNodes* = object
## Wrapper around `seq[SnapProof]` for controlling serialisation.
nodes*: seq[SnapProof]
SnapStorage* = object
slotHash*: Hash32
slotData*: seq[byte]
SnapTriePaths* = object
accPath*: seq[byte]
slotPaths*: seq[seq[byte]]
SnapWireBase* = ref object of RootRef
SnapPeerState* = ref object of RootRef
# ------------------------------------------------------------------------------
# Public `SnapProof` type helpers
# ------------------------------------------------------------------------------
proc to*(data: seq[byte]; T: type SnapProof): T = data.T
proc to*(node: SnapProof; T: type seq[byte]): T = node.T
proc hash*(sp: SnapProof): Hash =
## Mixin for Table/HashSet
sp.to(seq[byte]).hash
proc `==`*(a,b: SnapProof): bool =
## Mixin for Table/HashSet
a.to(seq[byte]) == b.to(seq[byte])
# ------------------------------------------------------------------------------
# Public serialisation helpers
# ------------------------------------------------------------------------------
# The `snap` protocol represents `Account` differently from the regular RLP
# serialisation used in `eth` protocol as well as the canonical Merkle hash
# over all accounts. In `snap`, empty storage hash and empty code hash are
# each represented by an RLP zero-length string instead of the full hash. This
# avoids transmitting these hashes in about 90% of accounts. We need to
# recognise or set these hashes in `Account` when serialising RLP for `snap`.
proc snapRead*(
rlp: var Rlp;
T: type Account;
strict: static[bool] = false;
): T
{.gcsafe, raises: [RlpError]} =
## RLP decoding for `Account`. The `snap` RLP representation of the account
## differs from standard `Account` RLP. Empty storage hash and empty code
## hash are each represented by an RLP zero-length string instead of the
## full hash.
##
## Normally, this read function will silently handle standard encodinig and
## `snap` enciding. Setting the argument strict as `false` the function will
## throw an exception if `snap` encoding is violated.
rlp.tryEnterList()
result.nonce = rlp.read(typeof(result.nonce))
result.balance = rlp.read(typeof(result.balance))
if rlp.blobLen != 0 or not rlp.isBlob:
result.storageRoot = rlp.read(typeof(result.storageRoot))
when strict:
if result.storageRoot == EMPTY_ROOT_HASH:
raise newException(RlpTypeMismatch,
"EMPTY_ROOT_HASH not encoded as empty string in Snap protocol")
else:
rlp.skipElem()
result.storageRoot = EMPTY_ROOT_HASH
if rlp.blobLen != 0 or not rlp.isBlob:
result.codeHash = rlp.read(typeof(result.codeHash))
when strict:
if result.codeHash == EMPTY_CODE_HASH:
raise newException(RlpTypeMismatch,
"EMPTY_SHA3 not encoded as empty string in Snap protocol")
else:
rlp.skipElem()
result.codeHash = EMPTY_CODE_HASH
proc snapAppend*(
writer: var RlpWriter;
account: Account;
) =
## RLP encoding for `Account`. The snap RLP representation of the account
## differs from standard `Account` RLP. Empty storage hash and empty code
## hash are each represented by an RLP zero-length string instead of the
## full hash.
writer.startList(4)
writer.append(account.nonce)
writer.append(account.balance)
if account.storageRoot == EMPTY_ROOT_HASH:
writer.append("")
else:
writer.append(account.storageRoot)
if account.codeHash == EMPTY_CODE_HASH:
writer.append("")
else:
writer.append(account.codeHash)
# ---------------------
proc snapRead*(
rlp: var Rlp;
T: type SnapProofNodes;
): T
{.gcsafe, raises: [RlpError].} =
## RLP decoding for a wrapped `SnapProof` sequence. This extra wrapper is
## needed as the `SnapProof` items are `Blob` items at heart which is also
## the serialised destination data type.
if rlp.isList:
for w in rlp.items:
result.nodes.add w.rawData.toSeq.to(SnapProof)
elif rlp.isBlob:
result.nodes.add rlp.rawData.toSeq.to(SnapProof)
proc snapAppend*(writer: var RlpWriter; spn: SnapProofNodes) =
## RLP encoding for a wrapped `SnapProof` sequence. This extra wrapper is
## needed as the `SnapProof` items are `Blob` items at heart which is also
## the serialised destination data type.
writer.startList spn.nodes.len
for w in spn.nodes:
writer.appendRawBytes w.to(seq[byte])
# ---------------------
proc snapRead*(
rlp: var Rlp;
T: type SnapTriePaths;
): T
{.gcsafe, raises: [RlpError].} =
## RLP decoding
if not rlp.isList:
raise newException(RlpTypeMismatch, "List expected")
var first = true
for w in rlp.items:
if first:
result.accPath = rlp.read(seq[byte])
first = false
else:
result.slotPaths.add rlp.read(seq[byte])
proc snapAppend*(writer: var RlpWriter; stn: SnapTriePaths) =
## RLP encoding
writer.startList(1 + stn.slotPaths.len)
writer.append(stn.accPath)
for w in stn.slotPaths:
writer.append(w)
# ------------------------------------------------------------------------------
# Public service stubs
# ------------------------------------------------------------------------------
proc notImplemented(name: string) =
debug "Method not implemented", meth = name
method getAccountRange*(
ctx: SnapWireBase;
root: Hash32;
origin: openArray[byte];
limit: openArray[byte];
replySizeMax: uint64;
): Result[(seq[SnapAccount], SnapProofNodes), string]
{.base, gcsafe.} =
notImplemented("getAccountRange")
method getStorageRanges*(
ctx: SnapWireBase;
root: Hash32;
accounts: openArray[Hash32];
origin: openArray[byte];
limit: openArray[byte];
replySizeMax: uint64;
): Result[(seq[seq[SnapStorage]], SnapProofNodes), string]
{.base, gcsafe.} =
notImplemented("getStorageRanges")
method getByteCodes*(
ctx: SnapWireBase;
nodes: openArray[Hash32];
replySizeMax: uint64;
): Result[seq[seq[byte]], string]
{.base, gcsafe.} =
notImplemented("getByteCodes")
method getTrieNodes*(
ctx: SnapWireBase;
root: Hash32;
pathGroups: openArray[SnapTriePaths];
replySizeMax: uint64;
): Result[seq[seq[byte]], string]
{.base, gcsafe.} =
notImplemented("getTrieNodes")
# ------------------------------------------------------------------------------
# End
# ------------------------------------------------------------------------------

View File

@ -1,6 +1,4 @@
# Nimbus - Ethereum Snap Protocol (SNAP), version 1 # Copyright (c) 2021-2025 Status Research & Development GmbH
#
# Copyright (c) 2021-2024 Status Research & Development GmbH
# Licensed under either of # Licensed under either of
# * Apache License, version 2.0, ([LICENSE-APACHE](LICENSE-APACHE) or # * Apache License, version 2.0, ([LICENSE-APACHE](LICENSE-APACHE) or
# http://www.apache.org/licenses/LICENSE-2.0) # http://www.apache.org/licenses/LICENSE-2.0)
@ -9,223 +7,39 @@
# at your option. This file may not be copied, modified, or distributed # at your option. This file may not be copied, modified, or distributed
# except according to those terms. # except according to those terms.
## This module implements Ethereum Snapshot Protocol version 1, `snap/1`. {.push raises: [].}
## Specification:
## `snap/1 <https://github.com/ethereum/devp2p/blob/master/caps/snap.md>`_
import from eth/common import Account, Hash32
std/options,
chronicles,
chronos,
eth/[common, p2p, p2p/private/p2p_types],
./snap/snap_types,
../../constants
export type
snap_types SnapAccount = object
accHash: Hash32
accBody: Account
logScope: SnapProof* = distinct seq[byte]
topics = "snap1" ## RLP-coded node data, to be handled differently from a generic `Blob`
const SnapProofNodes = object
snapVersion* = 1 ## Wrapper around `seq[SnapProof]` for controlling serialisation.
prettySnapProtoName* = "[snap/" & $snapVersion & "]" nodes: seq[SnapProof]
# Pickeled tracer texts SnapStorage* = object
trSnapRecvReceived* = slotHash*: Hash32
"<< " & prettySnapProtoName & " Received " slotData*: seq[byte]
trSnapRecvProtocolViolation* =
"<< " & prettySnapProtoName & " Protocol violation, "
trSnapRecvError* =
"<< " & prettySnapProtoName & " Error "
trSnapRecvTimeoutWaiting* =
"<< " & prettySnapProtoName & " Timeout waiting "
trSnapSendSending* = SnapAccountRange* = object
">> " & prettySnapProtoName & " Sending " accounts: seq[SnapAccount]
trSnapSendReplying* = proof: SnapProofNodes
">> " & prettySnapProtoName & " Replying "
SnapStorageRanges* = object
slotLists: seq[seq[SnapStorage]]
proof: SnapProofNodes
proc read(rlp: var Rlp, t: var SnapAccount, T: type Account): T = SnapByteCodes* = object
## RLP mixin, decoding codes: seq[seq[byte]]
rlp.snapRead T
proc read(rlp: var Rlp; T: type SnapProofNodes): T = SnapTrieNodes* = object
## RLP mixin, decoding nodes: seq[seq[byte]]
rlp.snapRead T
proc read(rlp: var Rlp; T: type SnapTriePaths): T = func to*(data: seq[byte]; T: type SnapProof): T = data.T
## RLP mixin, decoding func to*(node: SnapProof; T: type seq[byte]): T = node.T
rlp.snapRead T
proc append(writer: var RlpWriter, t: SnapAccount, account: Account) =
## RLP mixin, encoding
writer.snapAppend account
proc append(writer: var RlpWriter; spn: SnapProofNodes) =
## RLP mixin, encoding
writer.snapAppend spn
proc append(writer: var RlpWriter; stn: SnapTriePaths) =
## RLP mixin, encoding
writer.snapAppend stn
template handleHandlerError(x: untyped) =
if x.isErr:
raise newException(EthP2PError, x.error)
p2pProtocol snap1(version = snapVersion,
rlpxName = "snap",
peerState = SnapPeerState,
networkState = SnapWireBase,
useRequestIds = true):
requestResponse:
# User message 0x00: GetAccountRange.
proc getAccountRange(
peer: Peer;
root: Hash32;
origin: openArray[byte];
limit: openArray[byte];
replySizeMax: uint64;
) =
trace trSnapRecvReceived & "GetAccountRange (0x00)", peer, root,
nOrigin=origin.len, nLimit=limit.len, replySizeMax
let
ctx = peer.networkState()
res = ctx.getAccountRange(
root, origin, limit, replySizeMax)
handleHandlerError(res)
let
(accounts, proof) = res.get
# For logging only
nAccounts = accounts.len
nProof = proof.nodes.len
if nAccounts == 0 and nProof == 0:
trace trSnapSendReplying & "EMPTY AccountRange (0x01)", peer
else:
trace trSnapSendReplying & "AccountRange (0x01)", peer,
nAccounts, nProof
await response.send(accounts, proof)
# User message 0x01: AccountRange.
proc accountRange(
peer: Peer;
accounts: openArray[SnapAccount];
proof: SnapProofNodes)
requestResponse:
# User message 0x02: GetStorageRanges.
proc getStorageRanges(
peer: Peer;
root: Hash32;
accounts: openArray[Hash32];
origin: openArray[byte];
limit: openArray[byte];
replySizeMax: uint64;
) =
trace trSnapRecvReceived & "GetStorageRanges (0x02)", peer, root,
nAccounts=accounts.len, nOrigin=origin.len, nLimit=limit.len,
replySizeMax
let
ctx = peer.networkState()
res = ctx.getStorageRanges(
root, accounts, origin, limit, replySizeMax)
handleHandlerError(res)
let
(slots, proof) = res.get
# For logging only
nSlots = slots.len
nProof = proof.nodes.len
if nSlots == 0 and nProof == 0:
trace trSnapSendReplying & "EMPTY StorageRanges (0x03)", peer
else:
trace trSnapSendReplying & "StorageRanges (0x03)", peer,
nSlots, nProof
await response.send(slots, proof)
# User message 0x03: StorageRanges.
# Note: See comments in this file for a list of Geth quirks to expect.
proc storageRanges(
peer: Peer;
slotLists: openArray[seq[SnapStorage]];
proof: SnapProofNodes)
requestResponse:
# User message 0x04: GetByteCodes.
proc getByteCodes(
peer: Peer;
nodes: openArray[Hash32];
replySizeMax: uint64;
) =
trace trSnapRecvReceived & "GetByteCodes (0x04)", peer,
nNodes=nodes.len, replySizeMax
let
ctx = peer.networkState()
codes = ctx.getByteCodes(nodes, replySizeMax)
handleHandlerError(codes)
let
# For logging only
nCodes = codes.get.len
if nCodes == 0:
trace trSnapSendReplying & "EMPTY ByteCodes (0x05)", peer
else:
trace trSnapSendReplying & "ByteCodes (0x05)", peer, nCodes
await response.send(codes.get)
# User message 0x05: ByteCodes.
proc byteCodes(
peer: Peer;
codes: openArray[seq[byte]])
requestResponse:
# User message 0x06: GetTrieNodes.
proc getTrieNodes(
peer: Peer;
root: Hash32;
pathGroups: openArray[SnapTriePaths];
replySizeMax: uint64;
) =
trace trSnapRecvReceived & "GetTrieNodes (0x06)", peer, root,
nPathGroups=pathGroups.len, replySizeMax
let
ctx = peer.networkState()
nodes = ctx.getTrieNodes(root, pathGroups, replySizeMax)
handleHandlerError(nodes)
let
# For logging only
nNodes = nodes.get.len
if nNodes == 0:
trace trSnapSendReplying & "EMPTY TrieNodes (0x07)", peer
else:
trace trSnapSendReplying & "TrieNodes (0x07)", peer, nNodes
await response.send(nodes.get)
# User message 0x07: TrieNodes.
proc trieNodes(
peer: Peer;
nodes: openArray[seq[byte]])
# End