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 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.
- Or Linux inside a VM (e.g. VirtualBox) on Windows or MacOS.

View File

@ -495,13 +495,12 @@ type
name: "engine-api-ws" .}: bool
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: @[]
defaultValueDesc: "*"
name: "allowed-origins" .}: seq[string]
# github.com/ethereum/execution-apis/
# /blob/v1.0.0-alpha.8/src/engine/authentication.md#key-distribution
# https://github.com/ethereum/execution-apis/blob/v1.0.0-beta.4/src/engine/authentication.md#key-distribution
jwtSecret* {.
desc: "Path to a file containing a 32 byte hex-encoded shared secret" &
" 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
*db1*, *db2*, or *db3*. In a different, more algebraic notation, the above
tansformation is written as
transformation is written as
| tx1, ø | (8)
| tx2, ø | PBE

View File

@ -1,5 +1,5 @@
# Nimbus
# Copyright (c) 2021-2024 Status Research & Development GmbH
# Copyright (c) 2021-2025 Status Research & Development GmbH
# Licensed and distributed under either of
# * MIT license (license terms in the root directory or at
# https://opensource.org/licenses/MIT).
@ -11,43 +11,20 @@
## Provision of `eth` and `snap` protocol version parameters
##
## `Eth` related parameters:
## `ethVersions`: seq[int] -- constant list of all available versions
## `eth` -- type symbol of default version
## `proto_eth` -- export of default version directives
##
## `Snap` related parameters:
## `snap` -- type symbol of default version
## `proto_snap` -- export of default version directives
## ..aliases.. -- type names, syntactic sugar (see below)
##
{.push raises: [].}
import
./protocol/eth68 as proto_eth
type eth* = eth68
# ---------------
import
./protocol/snap1 as proto_snap
export
proto_eth,
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-2024 Status Research & Development GmbH
# Copyright (c) 2021-2025 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)
@ -9,223 +7,39 @@
# at your option. This file may not be copied, modified, or distributed
# except according to those terms.
## This module implements Ethereum Snapshot Protocol version 1, `snap/1`.
## Specification:
## `snap/1 <https://github.com/ethereum/devp2p/blob/master/caps/snap.md>`_
{.push raises: [].}
import
std/options,
chronicles,
chronos,
eth/[common, p2p, p2p/private/p2p_types],
./snap/snap_types,
../../constants
from eth/common import Account, Hash32
export
snap_types
type
SnapAccount = object
accHash: Hash32
accBody: Account
logScope:
topics = "snap1"
SnapProof* = distinct seq[byte]
## RLP-coded node data, to be handled differently from a generic `Blob`
const
snapVersion* = 1
prettySnapProtoName* = "[snap/" & $snapVersion & "]"
SnapProofNodes = object
## Wrapper around `seq[SnapProof]` for controlling serialisation.
nodes: seq[SnapProof]
# Pickeled tracer texts
trSnapRecvReceived* =
"<< " & prettySnapProtoName & " Received "
trSnapRecvProtocolViolation* =
"<< " & prettySnapProtoName & " Protocol violation, "
trSnapRecvError* =
"<< " & prettySnapProtoName & " Error "
trSnapRecvTimeoutWaiting* =
"<< " & prettySnapProtoName & " Timeout waiting "
SnapStorage* = object
slotHash*: Hash32
slotData*: seq[byte]
trSnapSendSending* =
">> " & prettySnapProtoName & " Sending "
trSnapSendReplying* =
">> " & prettySnapProtoName & " Replying "
SnapAccountRange* = object
accounts: seq[SnapAccount]
proof: SnapProofNodes
SnapStorageRanges* = object
slotLists: seq[seq[SnapStorage]]
proof: SnapProofNodes
proc read(rlp: var Rlp, t: var SnapAccount, T: type Account): T =
## RLP mixin, decoding
rlp.snapRead T
SnapByteCodes* = object
codes: seq[seq[byte]]
proc read(rlp: var Rlp; T: type SnapProofNodes): T =
## RLP mixin, decoding
rlp.snapRead T
SnapTrieNodes* = object
nodes: seq[seq[byte]]
proc read(rlp: var Rlp; T: type SnapTriePaths): T =
## RLP mixin, decoding
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
func to*(data: seq[byte]; T: type SnapProof): T = data.T
func to*(node: SnapProof; T: type seq[byte]): T = node.T