mirror of
https://github.com/status-im/nimbus-eth2.git
synced 2025-02-17 00:47:03 +00:00
Remove beacon_block_and_blobs_sidecar_by_root RPC (#4672)
Along with its use in the request manager.
This commit is contained in:
parent
cdca07908b
commit
a999da3361
@ -394,7 +394,7 @@ proc initFullNode(
|
||||
node.requestManager = RequestManager.init(node.network,
|
||||
dag.cfg.DENEB_FORK_EPOCH,
|
||||
getBeaconTime,
|
||||
blockVerifier, blockBlobsVerifier)
|
||||
blockVerifier)
|
||||
node.syncManager = syncManager
|
||||
node.backfiller = backfiller
|
||||
node.router = router
|
||||
|
@ -40,10 +40,8 @@ type
|
||||
RequestManager* = object
|
||||
network*: Eth2Node
|
||||
inpQueue*: AsyncQueue[FetchRecord]
|
||||
DENEB_FORK_EPOCH: Epoch
|
||||
getBeaconTime: GetBeaconTimeFn
|
||||
blockVerifier: BlockVerifier
|
||||
blockBlobsVerifier: BlockBlobsVerifier
|
||||
loopFuture: Future[void]
|
||||
|
||||
func shortLog*(x: seq[Eth2Digest]): string =
|
||||
@ -55,31 +53,14 @@ func shortLog*(x: seq[FetchRecord]): string =
|
||||
proc init*(T: type RequestManager, network: Eth2Node,
|
||||
eip4844Epoch: Epoch,
|
||||
getBeaconTime: GetBeaconTimeFn,
|
||||
blockVerifier: BlockVerifier,
|
||||
blockBlobsVerifier: BlockBlobsVerifier): RequestManager =
|
||||
blockVerifier: BlockVerifier): RequestManager =
|
||||
RequestManager(
|
||||
network: network,
|
||||
inpQueue: newAsyncQueue[FetchRecord](),
|
||||
DENEB_FORK_EPOCH: eip4844Epoch,
|
||||
getBeaconTime: getBeaconTime,
|
||||
blockVerifier: blockVerifier,
|
||||
blockBlobsVerifier: blockBlobsVerifier,
|
||||
)
|
||||
|
||||
proc checkResponse(roots: openArray[Eth2Digest],
|
||||
blocks: openArray[ref SignedBeaconBlockAndBlobsSidecar]): bool =
|
||||
## This procedure checks peer's response.
|
||||
var checks = @roots
|
||||
if len(blocks) > len(roots):
|
||||
return false
|
||||
for item in blocks:
|
||||
let res = checks.find(item[].beacon_block.root)
|
||||
if res == -1:
|
||||
return false
|
||||
else:
|
||||
checks.del(res)
|
||||
true
|
||||
|
||||
proc checkResponse(roots: openArray[Eth2Digest],
|
||||
blocks: openArray[ref ForkedSignedBeaconBlock]): bool =
|
||||
## This procedure checks peer's response.
|
||||
@ -166,94 +147,6 @@ proc fetchAncestorBlocksFromNetwork(rman: RequestManager,
|
||||
if not(isNil(peer)):
|
||||
rman.network.peerPool.release(peer)
|
||||
|
||||
proc fetchAncestorBlocksAndBlobsFromNetwork(rman: RequestManager,
|
||||
items: seq[Eth2Digest]) {.async.} =
|
||||
var peer: Peer
|
||||
try:
|
||||
peer = await rman.network.peerPool.acquire()
|
||||
debug "Requesting blocks and sidecars by root",
|
||||
peer = peer, blocks = shortLog(items), peer_score = peer.getScore()
|
||||
|
||||
let blocks = await beaconBlockAndBlobsSidecarByRoot_v1(peer,
|
||||
BlockRootsList items)
|
||||
|
||||
if blocks.isOk:
|
||||
let ublocks = blocks.get()
|
||||
if checkResponse(items, ublocks.asSeq()):
|
||||
var
|
||||
gotGoodBlock = false
|
||||
gotUnviableBlock = false
|
||||
|
||||
for b in ublocks:
|
||||
let ver = await rman.blockBlobsVerifier(
|
||||
ForkedSignedBeaconBlock.init(b[].beacon_block),
|
||||
b[].blobs_sidecar, false)
|
||||
if ver.isErr():
|
||||
case ver.error()
|
||||
of VerifierError.MissingParent:
|
||||
# Ignoring because the order of the blocks that
|
||||
# we requested may be different from the order in which we need
|
||||
# these blocks to apply.
|
||||
discard
|
||||
of VerifierError.Duplicate:
|
||||
# Ignoring because these errors could occur due to the
|
||||
# concurrent/parallel requests we made.
|
||||
discard
|
||||
of VerifierError.UnviableFork:
|
||||
# If they're working a different fork, we'll want to descore them
|
||||
# but also process the other blocks (in case we can register the
|
||||
# other blocks as unviable)
|
||||
gotUnviableBlock = true
|
||||
of VerifierError.Invalid:
|
||||
# We stop processing blocks because peer is either sending us
|
||||
# junk or working a different fork
|
||||
notice "Received invalid block and blobs",
|
||||
peer = peer, blocks = shortLog(items),
|
||||
peer_score = peer.getScore()
|
||||
peer.updateScore(PeerScoreBadValues)
|
||||
|
||||
return # Stop processing this junk...
|
||||
else:
|
||||
gotGoodBlock = true
|
||||
|
||||
if gotUnviableBlock:
|
||||
notice "Received blocks and blobs from an unviable fork",
|
||||
peer = peer, blocks = shortLog(items),
|
||||
peer_score = peer.getScore()
|
||||
peer.updateScore(PeerScoreUnviableFork)
|
||||
elif gotGoodBlock:
|
||||
# We reward peer only if it returns something.
|
||||
peer.updateScore(PeerScoreGoodValues)
|
||||
else:
|
||||
let err = blocks.error()
|
||||
case err.kind
|
||||
of ReceivedErrorResponse:
|
||||
if err.responseCode == ResourceUnavailable:
|
||||
if not(isNil(peer)):
|
||||
rman.network.peerPool.release(peer)
|
||||
await rman.fetchAncestorBlocksFromNetwork(items)
|
||||
return
|
||||
else:
|
||||
peer.updateScore(PeerScoreBadResponse)
|
||||
else:
|
||||
discard
|
||||
else:
|
||||
peer.updateScore(PeerScoreNoValues)
|
||||
|
||||
except CancelledError as exc:
|
||||
raise exc
|
||||
except CatchableError as exc:
|
||||
peer.updateScore(PeerScoreNoValues)
|
||||
debug "Error while fetching ancestor blocks and blobs", exc = exc.msg,
|
||||
items = shortLog(items), peer = peer, peer_score = peer.getScore()
|
||||
raise exc
|
||||
finally:
|
||||
if not(isNil(peer)):
|
||||
rman.network.peerPool.release(peer)
|
||||
|
||||
|
||||
proc isBlobsTime(rman: RequestManager): bool =
|
||||
rman.getBeaconTime().slotOrZero.epoch >= rman.DENEB_FORK_EPOCH
|
||||
|
||||
proc requestManagerLoop(rman: RequestManager) {.async.} =
|
||||
var rootList = newSeq[Eth2Digest]()
|
||||
@ -271,17 +164,8 @@ proc requestManagerLoop(rman: RequestManager) {.async.} =
|
||||
|
||||
let start = SyncMoment.now(0)
|
||||
|
||||
# As soon as DENEB_FORK_EPOCH comes around in wall time, we
|
||||
# switch to requesting blocks and blobs. In the vicinity of the
|
||||
# transition, that means that we *may* request blobs for a
|
||||
# pre-eip4844. In that case, we get ResourceUnavailable from the
|
||||
# peer and fall back to requesting blocks only.
|
||||
let getBlobs = rman.isBlobsTime()
|
||||
for i in 0 ..< PARALLEL_REQUESTS:
|
||||
workers[i] = if getBlobs:
|
||||
rman.fetchAncestorBlocksAndBlobsFromNetwork(rootList)
|
||||
else:
|
||||
rman.fetchAncestorBlocksFromNetwork(rootList)
|
||||
workers[i] = rman.fetchAncestorBlocksFromNetwork(rootList)
|
||||
|
||||
# We do not care about
|
||||
await allFutures(workers)
|
||||
|
@ -445,88 +445,6 @@ p2pProtocol BeaconSync(version = 1,
|
||||
debug "Block root request done",
|
||||
peer, roots = blockRoots.len, count, found
|
||||
|
||||
# https://github.com/ethereum/consensus-specs/blob/v1.3.0-rc.2/specs/eip4844/p2p-interface.md#beaconblockandblobssidecarbyroot-v1
|
||||
proc beaconBlockAndBlobsSidecarByRoot_v1(
|
||||
peer: Peer,
|
||||
# Please note that the SSZ list here ensures that the
|
||||
# spec constant MAX_REQUEST_BLOCKS is enforced:
|
||||
blockRoots: BlockRootsList,
|
||||
response: MultipleChunksResponse[
|
||||
ref SignedBeaconBlockAndBlobsSidecar, MAX_REQUEST_BLOCKS])
|
||||
{.async, libp2pProtocol("beacon_block_and_blobs_sidecar_by_root", 1).} =
|
||||
# unlike for beaconBlocksByRoot_v2, we don't need to
|
||||
# dynamically decode the correct fork here. so returning a ref
|
||||
# is solely for performance sake
|
||||
|
||||
if blockRoots.len == 0:
|
||||
raise newException(InvalidInputsError, "No blocks requested")
|
||||
|
||||
let
|
||||
dag = peer.networkState.dag
|
||||
count = blockRoots.len
|
||||
# https://github.com/ethereum/consensus-specs/blob/v1.3.0-rc.1/specs/eip4844/p2p-interface.md#beaconblockandblobssidecarbyroot-v1
|
||||
min_epochs =
|
||||
if MIN_EPOCHS_FOR_BLOBS_SIDECARS_REQUESTS > dag.head.slot.epoch:
|
||||
dag.head.slot.epoch
|
||||
else:
|
||||
Epoch(MIN_EPOCHS_FOR_BLOBS_SIDECARS_REQUESTS)
|
||||
|
||||
epochBoundary =
|
||||
if dag.head.slot.epoch - min_epochs < dag.cfg.DENEB_FORK_EPOCH:
|
||||
dag.cfg.DENEB_FORK_EPOCH
|
||||
else:
|
||||
dag.head.slot.epoch - MIN_EPOCHS_FOR_BLOBS_SIDECARS_REQUESTS
|
||||
minimum_request_epoch = max(dag.finalizedHead.slot.epoch, epochBoundary)
|
||||
|
||||
var
|
||||
found = 0
|
||||
bytes: seq[byte]
|
||||
blck: Opt[eip4844.TrustedSignedBeaconBlock]
|
||||
blobsSidecar: Opt[BlobsSidecar]
|
||||
|
||||
for i in 0..<count:
|
||||
let
|
||||
blockRef = dag.getBlockRef(blockRoots[i]).valueOr:
|
||||
continue
|
||||
|
||||
blck = dag.getBlock(blockRef.bid, eip4844.TrustedSignedBeaconBlock)
|
||||
if blck.isNone():
|
||||
continue
|
||||
|
||||
if blockRef.bid.slot.epoch < minimum_request_epoch:
|
||||
raise newException(ResourceUnavailableError, BlobsOutOfRange)
|
||||
|
||||
# In general, there is not much intermediate time between post-merge
|
||||
# blocks all being optimistic and none of them being optimistic. The
|
||||
# EL catches up, tells the CL the head is verified, and that's it.
|
||||
if blockRef.slot.epoch >= dag.cfg.BELLATRIX_FORK_EPOCH and
|
||||
dag.is_optimistic(dag.head.root):
|
||||
continue
|
||||
|
||||
blobsSidecar = dag.db.getBlobsSidecar(blockRef.bid.root)
|
||||
if blobsSidecar.isNone():
|
||||
continue
|
||||
|
||||
peer.awaitQuota(blockResponseCost, "beacon_block_and_blobs_sidecar_by_root/1")
|
||||
peer.network.awaitQuota(blockResponseCost, "beacon_block_and_blobs_sidecar_by_root/1")
|
||||
|
||||
let sbbabs = SignedBeaconBlockAndBlobsSidecar(
|
||||
beacon_block: asSigned(blck.get()),
|
||||
blobs_sidecar: blobsSidecar.get())
|
||||
bytes = snappy.encodeFramed(SSZ.encode(sbbabs))
|
||||
|
||||
let uncompressedLen = uncompressedLenFramed(bytes).valueOr:
|
||||
warn "Cannot read block and blobs size", length = bytes.len()
|
||||
continue
|
||||
|
||||
await response.writeBytesSZ(
|
||||
uncompressedLen, bytes,
|
||||
peer.networkState.forkDigestAtEpoch(blockRef.slot.epoch).data)
|
||||
|
||||
inc found
|
||||
|
||||
debug "Block and blobs sidecar root request done",
|
||||
peer, roots = blockRoots.len, count, found
|
||||
|
||||
# https://github.com/ethereum/consensus-specs/blob/v1.3.0-rc.0/specs/eip4844/p2p-interface.md#blobssidecarsbyrange-v1
|
||||
proc blobsSidecarsByRange(
|
||||
|
Loading…
x
Reference in New Issue
Block a user