add: `get_custody_columns` for das_core (#6532)
* add: get_custody_columnns in das core specs with tests * apply review changes * review changes 2 * review 3
This commit is contained in:
parent
e6ebefc364
commit
444d1dd093
|
@ -175,6 +175,19 @@ OK: 1/1 Fail: 0/1 Skip: 0/1
|
||||||
+ Tail block only in common OK
|
+ Tail block only in common OK
|
||||||
```
|
```
|
||||||
OK: 2/2 Fail: 0/2 Skip: 0/2
|
OK: 2/2 Fail: 0/2 Skip: 0/2
|
||||||
|
## EF - EIP7594 - Networking [Preset: mainnet]
|
||||||
|
```diff
|
||||||
|
+ Networking - Get Custody Columns - mainnet/eip7594/networking/get_custody_columns/pyspec_t OK
|
||||||
|
+ Networking - Get Custody Columns - mainnet/eip7594/networking/get_custody_columns/pyspec_t OK
|
||||||
|
+ Networking - Get Custody Columns - mainnet/eip7594/networking/get_custody_columns/pyspec_t OK
|
||||||
|
+ Networking - Get Custody Columns - mainnet/eip7594/networking/get_custody_columns/pyspec_t OK
|
||||||
|
+ Networking - Get Custody Columns - mainnet/eip7594/networking/get_custody_columns/pyspec_t OK
|
||||||
|
+ Networking - Get Custody Columns - mainnet/eip7594/networking/get_custody_columns/pyspec_t OK
|
||||||
|
+ Networking - Get Custody Columns - mainnet/eip7594/networking/get_custody_columns/pyspec_t OK
|
||||||
|
+ Networking - Get Custody Columns - mainnet/eip7594/networking/get_custody_columns/pyspec_t OK
|
||||||
|
+ Networking - Get Custody Columns - mainnet/eip7594/networking/get_custody_columns/pyspec_t OK
|
||||||
|
```
|
||||||
|
OK: 9/9 Fail: 0/9 Skip: 0/9
|
||||||
## EF - KZG
|
## EF - KZG
|
||||||
```diff
|
```diff
|
||||||
+ KZG - Blob to KZG commitment - blob_to_kzg_commitment_case_invalid_blob_59d64ff6b4648fad OK
|
+ KZG - Blob to KZG commitment - blob_to_kzg_commitment_case_invalid_blob_59d64ff6b4648fad OK
|
||||||
|
@ -1100,4 +1113,4 @@ OK: 2/2 Fail: 0/2 Skip: 0/2
|
||||||
OK: 9/9 Fail: 0/9 Skip: 0/9
|
OK: 9/9 Fail: 0/9 Skip: 0/9
|
||||||
|
|
||||||
---TOTAL---
|
---TOTAL---
|
||||||
OK: 749/754 Fail: 0/754 Skip: 5/754
|
OK: 758/763 Fail: 0/763 Skip: 5/763
|
||||||
|
|
|
@ -0,0 +1,110 @@
|
||||||
|
# beacon_chain
|
||||||
|
# Copyright (c) 2022-2024 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).
|
||||||
|
# * Apache v2 license (license terms in the root directory or at https://www.apache.org/licenses/LICENSE-2.0).
|
||||||
|
# at your option. This file may not be copied, modified, or distributed except according to those terms.
|
||||||
|
|
||||||
|
{.push raises: [].}
|
||||||
|
|
||||||
|
import
|
||||||
|
std/[sequtils],
|
||||||
|
"."/[altair, base, deneb],
|
||||||
|
kzg4844/[kzg, kzg_abi]
|
||||||
|
|
||||||
|
from std/strutils import join
|
||||||
|
|
||||||
|
export base
|
||||||
|
|
||||||
|
const
|
||||||
|
# https://github.com/ethereum/consensus-specs/blob/v1.5.0-alpha.5/specs/_features/eip7594/polynomial-commitments-sampling.md#cells
|
||||||
|
FIELD_ELEMENTS_PER_EXT_BLOB* = 2 * kzg_abi.FIELD_ELEMENTS_PER_BLOB
|
||||||
|
# Number of field elements in a Reed-Solomon extended blob |
|
||||||
|
FIELD_ELEMENTS_PER_CELL* = 64 # Number of field elements in a cell |
|
||||||
|
BYTES_PER_CELL* = FIELD_ELEMENTS_PER_CELL * kzg_abi.BYTES_PER_FIELD_ELEMENT
|
||||||
|
# The number of bytes in a cell |
|
||||||
|
CELLS_PER_EXT_BLOB* = FIELD_ELEMENTS_PER_EXT_BLOB div FIELD_ELEMENTS_PER_CELL
|
||||||
|
# The number of cells in an extended blob |
|
||||||
|
|
||||||
|
# https://github.com/ethereum/consensus-specs/blob/v1.5.0-alpha.5/specs/_features/eip7594/p2p-interface.md#preset
|
||||||
|
KZG_COMMITMENTS_INCLUSION_PROOF_DEPTH* = 4
|
||||||
|
|
||||||
|
type
|
||||||
|
# https://github.com/ethereum/consensus-specs/blob/v1.5.0-alpha.5/specs/_features/eip7594/polynomial-commitments-sampling.md#custom-types
|
||||||
|
BLSFieldElement* = KzgBytes32
|
||||||
|
G2Point* = array[96, byte]
|
||||||
|
PolynomialCoeff* = List[BLSFieldElement, FIELD_ELEMENTS_PER_EXT_BLOB]
|
||||||
|
Coset* = array[FIELD_ELEMENTS_PER_CELL, BLSFieldElement]
|
||||||
|
CosetEvals* = array[FIELD_ELEMENTS_PER_CELL, BLSFieldElement]
|
||||||
|
Cell* = KzgCell
|
||||||
|
Cells* = KzgCells
|
||||||
|
CellsAndProofs* = KzgCellsAndKzgProofs
|
||||||
|
|
||||||
|
# https://github.com/ethereum/consensus-specs/blob/v1.5.0-alpha.5/specs/_features/eip7594/das-core.md#custom-types
|
||||||
|
RowIndex* = uint64
|
||||||
|
ColumnIndex* = uint64
|
||||||
|
CellIndex* = uint64
|
||||||
|
|
||||||
|
const
|
||||||
|
# https://github.com/ethereum/consensus-specs/blob/v1.5.0-alpha.5/specs/_features/eip7594/das-core.md#data-size
|
||||||
|
NUMBER_OF_COLUMNS* = 128
|
||||||
|
|
||||||
|
# https://github.com/ethereum/consensus-specs/blob/v1.5.0-alpha.5/specs/_features/eip7594/das-core.md#networking
|
||||||
|
DATA_COLUMN_SIDECAR_SUBNET_COUNT* = 128
|
||||||
|
|
||||||
|
# https://github.com/ethereum/consensus-specs/blob/v1.5.0-alpha.5/specs/_features/eip7594/das-core.md#custody-setting
|
||||||
|
SAMPLES_PER_SLOT* = 8
|
||||||
|
CUSTODY_REQUIREMENT* = 4
|
||||||
|
|
||||||
|
type
|
||||||
|
DataColumn* = List[KzgCell, Limit(MAX_BLOB_COMMITMENTS_PER_BLOCK)]
|
||||||
|
|
||||||
|
# https://github.com/ethereum/consensus-specs/blob/v1.5.0-alpha.5/specs/_features/eip7594/das-core.md#datacolumnsidecar
|
||||||
|
DataColumnSidecar* = object
|
||||||
|
index*: ColumnIndex # Index of column in extended matrix
|
||||||
|
column*: DataColumn
|
||||||
|
kzg_commitments*: KzgCommitments
|
||||||
|
kzg_proofs*: KzgProofs
|
||||||
|
signed_block_header*: SignedBeaconBlockHeader
|
||||||
|
kzg_commitments_inclusion_proof*:
|
||||||
|
array[KZG_COMMITMENTS_INCLUSION_PROOF_DEPTH, Eth2Digest]
|
||||||
|
|
||||||
|
DataColumnSidecars* = seq[ref DataColumnSidecar]
|
||||||
|
|
||||||
|
# https://github.com/ethereum/consensus-specs/blob/v1.5.0-alpha.5/specs/_features/eip7594/p2p-interface.md#datacolumnidentifier
|
||||||
|
DataColumnIdentifier* = object
|
||||||
|
block_root*: Eth2Digest
|
||||||
|
index*: ColumnIndex
|
||||||
|
|
||||||
|
# https://github.com/ethereum/consensus-specs/blob/v1.5.0-alpha.5/specs/_features/eip7594/das-core.md#matrixentry
|
||||||
|
MatrixEntry* = object
|
||||||
|
cell*: Cell
|
||||||
|
kzg_proof*: KzgProof
|
||||||
|
column_index*: ColumnIndex
|
||||||
|
row_index*: RowIndex
|
||||||
|
|
||||||
|
# Not in spec, defined in order to compute custody subnets
|
||||||
|
CscBits* = BitArray[DATA_COLUMN_SIDECAR_SUBNET_COUNT]
|
||||||
|
|
||||||
|
CscCount* = uint8
|
||||||
|
|
||||||
|
# https://github.com/ethereum/consensus-specs/blob/v1.5.0-alpha.5/specs/_features/eip7594/p2p-interface.md#metadata
|
||||||
|
MetaData* = object
|
||||||
|
seq_number*: uint64
|
||||||
|
attnets*: AttnetBits
|
||||||
|
syncnets*: SyncnetBits
|
||||||
|
custody_subnet_count*: CscCount
|
||||||
|
|
||||||
|
func shortLog*(v: DataColumnSidecar): auto =
|
||||||
|
(
|
||||||
|
index: v.index,
|
||||||
|
kzg_commitments: v.kzg_commitments.len,
|
||||||
|
kzg_proofs: v.kzg_proofs.len,
|
||||||
|
block_header: shortLog(v.signed_block_header.message),
|
||||||
|
)
|
||||||
|
|
||||||
|
func shortLog*(v: seq[DataColumnSidecar]): auto =
|
||||||
|
"[" & v.mapIt(shortLog(it)).join(", ") & "]"
|
||||||
|
|
||||||
|
func shortLog*(x: seq[DataColumnIdentifier]): string =
|
||||||
|
"[" & x.mapIt(shortLog(it.block_root) & "/" & $it.index).join(", ") & "]"
|
|
@ -0,0 +1,105 @@
|
||||||
|
# beacon_chain
|
||||||
|
# Copyright (c) 2018-2024 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).
|
||||||
|
# * Apache v2 license (license terms in the root directory or at https://www.apache.org/licenses/LICENSE-2.0).
|
||||||
|
# at your option. This file may not be copied, modified, or distributed except according to those terms.
|
||||||
|
|
||||||
|
{.push raises: [].}
|
||||||
|
|
||||||
|
# Uncategorized helper functions from the spec
|
||||||
|
import
|
||||||
|
std/[algorithm, hashes],
|
||||||
|
results,
|
||||||
|
eth/p2p/discoveryv5/[node],
|
||||||
|
./[helpers, digest],
|
||||||
|
./datatypes/[eip7594]
|
||||||
|
|
||||||
|
proc sortedColumnIndices*(columnsPerSubnet: ColumnIndex,
|
||||||
|
subnetIds: HashSet[uint64]):
|
||||||
|
seq[ColumnIndex] =
|
||||||
|
var res: seq[ColumnIndex] = @[]
|
||||||
|
for i in 0'u64 ..< columnsPerSubnet:
|
||||||
|
for subnetId in subnetIds:
|
||||||
|
let index = DATA_COLUMN_SIDECAR_SUBNET_COUNT * i + subnetId
|
||||||
|
res.add(ColumnIndex(index))
|
||||||
|
res.sort
|
||||||
|
res
|
||||||
|
|
||||||
|
proc sortedColumnIndexList*(columnsPerSubnet: ColumnIndex,
|
||||||
|
subnetIds: HashSet[uint64]):
|
||||||
|
List[ColumnIndex, NUMBER_OF_COLUMNS] =
|
||||||
|
var
|
||||||
|
res: seq[ColumnIndex]
|
||||||
|
for i in 0'u64 ..< columnsPerSubnet:
|
||||||
|
for subnetId in subnetIds:
|
||||||
|
let index = DATA_COLUMN_SIDECAR_SUBNET_COUNT * i + subnetId
|
||||||
|
res.add(ColumnIndex(index))
|
||||||
|
res.sort()
|
||||||
|
let list = List[ColumnIndex, NUMBER_OF_COLUMNS].init(res)
|
||||||
|
list
|
||||||
|
|
||||||
|
proc get_custody_column_subnets*(node_id: NodeId,
|
||||||
|
custody_subnet_count: uint64):
|
||||||
|
Result[HashSet[uint64], cstring] =
|
||||||
|
|
||||||
|
# Decouples the custody subnet computation part from
|
||||||
|
# `get_custody_columns`, in order to later use this subnet list
|
||||||
|
# in order to maintain subscription to specific column subnets.
|
||||||
|
|
||||||
|
if not (custody_subnet_count <= DATA_COLUMN_SIDECAR_SUBNET_COUNT):
|
||||||
|
return err("Eip7594: Custody subnet count exceeds the DATA_COLUMN_SIDECAR_SUBNET_COUNT")
|
||||||
|
|
||||||
|
var
|
||||||
|
subnet_ids: HashSet[uint64]
|
||||||
|
current_id = node_id
|
||||||
|
|
||||||
|
while subnet_ids.lenu64 < custody_subnet_count:
|
||||||
|
var
|
||||||
|
hashed_bytes: array[8, byte]
|
||||||
|
|
||||||
|
let
|
||||||
|
current_id_bytes = current_id.toBytesLE()
|
||||||
|
hashed_current_id = eth2digest(current_id_bytes)
|
||||||
|
|
||||||
|
hashed_bytes[0..7] = hashed_current_id.data.toOpenArray(0,7)
|
||||||
|
let subnet_id = bytes_to_uint64(hashed_bytes) mod
|
||||||
|
DATA_COLUMN_SIDECAR_SUBNET_COUNT
|
||||||
|
|
||||||
|
subnet_ids.incl(subnet_id)
|
||||||
|
|
||||||
|
if current_id == UInt256.high.NodeId:
|
||||||
|
# Overflow prevention
|
||||||
|
current_id = NodeId(StUint[256].zero)
|
||||||
|
current_id += NodeId(StUint[256].one)
|
||||||
|
|
||||||
|
ok(subnet_ids)
|
||||||
|
|
||||||
|
# https://github.com/ethereum/consensus-specs/blob/v1.5.0-alpha.5/specs/_features/eip7594/das-core.md#get_custody_columns
|
||||||
|
proc get_custody_columns*(node_id: NodeId,
|
||||||
|
custody_subnet_count: uint64):
|
||||||
|
seq[ColumnIndex] =
|
||||||
|
let
|
||||||
|
subnet_ids =
|
||||||
|
get_custody_column_subnets(node_id, custody_subnet_count).get
|
||||||
|
const
|
||||||
|
columns_per_subnet =
|
||||||
|
NUMBER_OF_COLUMNS div DATA_COLUMN_SIDECAR_SUBNET_COUNT
|
||||||
|
|
||||||
|
sortedColumnIndices(ColumnIndex(columns_per_subnet), subnet_ids)
|
||||||
|
|
||||||
|
|
||||||
|
proc get_custody_column_list*(node_id: NodeId,
|
||||||
|
custody_subnet_count: uint64):
|
||||||
|
List[ColumnIndex, NUMBER_OF_COLUMNS] =
|
||||||
|
|
||||||
|
# Not in spec in the exact format, but it is useful in sorting custody columns
|
||||||
|
# before sending, data_column_sidecars_by_range requests
|
||||||
|
let
|
||||||
|
subnet_ids =
|
||||||
|
get_custody_column_subnets(node_id, custody_subnet_count).get
|
||||||
|
const
|
||||||
|
columns_per_subnet =
|
||||||
|
NUMBER_OF_COLUMNS div DATA_COLUMN_SIDECAR_SUBNET_COUNT
|
||||||
|
|
||||||
|
sortedColumnIndexList(ColumnIndex(columns_per_subnet), subnet_ids)
|
|
@ -15,4 +15,5 @@
|
||||||
|
|
||||||
import
|
import
|
||||||
./test_fixture_kzg,
|
./test_fixture_kzg,
|
||||||
|
./test_fixture_networking,
|
||||||
./test_fixture_ssz_generic_types
|
./test_fixture_ssz_generic_types
|
||||||
|
|
|
@ -0,0 +1,51 @@
|
||||||
|
# beacon_chain
|
||||||
|
# Copyright (c) 2024 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).
|
||||||
|
# * Apache v2 license (license terms in the root directory or at https://www.apache.org/licenses/LICENSE-2.0).
|
||||||
|
# at your option. This file may not be copied, modified, or distributed except according to those terms.
|
||||||
|
|
||||||
|
{.push raises: [].}
|
||||||
|
{.used.}
|
||||||
|
|
||||||
|
import
|
||||||
|
std/[json, streams],
|
||||||
|
yaml,
|
||||||
|
kzg4844/[kzg, kzg_abi],
|
||||||
|
stint,
|
||||||
|
eth/p2p/discoveryv5/[node],
|
||||||
|
../../beacon_chain/spec/eip7594_helpers,
|
||||||
|
../testutil,
|
||||||
|
./fixtures_utils, ./os_ops
|
||||||
|
|
||||||
|
from std/sequtils import mapIt
|
||||||
|
|
||||||
|
proc runGetCustodyColumns(suiteName, path: string) =
|
||||||
|
let relativePathComponent = path.relativeTestPathComponent()
|
||||||
|
test "Networking - Get Custody Columns - " & relativePathComponent:
|
||||||
|
type TestMetaYaml = object
|
||||||
|
node_id: string
|
||||||
|
custody_subnet_count: uint64
|
||||||
|
result: seq[uint64]
|
||||||
|
let
|
||||||
|
meta = block:
|
||||||
|
var s = openFileStream(path/"meta.yaml")
|
||||||
|
defer: close(s)
|
||||||
|
var res: TestMetaYaml
|
||||||
|
yaml.load(s, res)
|
||||||
|
res
|
||||||
|
node_id = UInt256.fromDecimal(meta.node_id)
|
||||||
|
custody_subnet_count = meta.custody_subnet_count
|
||||||
|
reslt = (meta.result).mapIt(it)
|
||||||
|
|
||||||
|
let columns = get_custody_columns(node_id, custody_subnet_count)
|
||||||
|
|
||||||
|
for i in 0..<columns.lenu64:
|
||||||
|
check columns[i] == reslt[i]
|
||||||
|
|
||||||
|
suite "EF - EIP7594 - Networking" & preset():
|
||||||
|
const presetPath = SszTestsDir/const_preset
|
||||||
|
let basePath =
|
||||||
|
presetPath/"eip7594"/"networking"/"get_custody_columns"/"pyspec_tests"
|
||||||
|
for kind, path in walkDir(basePath, relative = true, checkDir = true):
|
||||||
|
runGetCustodyColumns(suiteName, basePath/path)
|
Loading…
Reference in New Issue