mirror of
https://github.com/status-im/nimbus-eth1.git
synced 2025-02-10 11:06:49 +00:00
rm more Snap sync code (#3047)
* rm more Snap sync code * clean up snap1
This commit is contained in:
parent
796c2f7cbf
commit
daebbfa18d
@ -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.
|
||||
|
@ -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" &
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
# ------------------------------------------------------------------------------
|
@ -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
|
||||
|
Loading…
x
Reference in New Issue
Block a user