diff --git a/go.sum b/go.sum index 029298b46b..ff93729771 100644 --- a/go.sum +++ b/go.sum @@ -567,6 +567,7 @@ github.com/status-im/keycard-go v0.2.0 h1:QDLFswOQu1r5jsycloeQh3bVU8n/NatHHaZobt github.com/status-im/keycard-go v0.2.0/go.mod h1:wlp8ZLbsmrF6g6WjugPAx+IzoLrkdf9+mHxBEeo3Hbg= github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= github.com/stretchr/objx v0.1.1/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= +github.com/stretchr/objx v0.5.0/go.mod h1:Yh+to48EsGEfYuaHDzXPcE3xhTkx73EhmCGUpEOglKo= github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs= github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI= github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4= @@ -617,6 +618,7 @@ go.opencensus.io v0.22.0/go.mod h1:+kGneAE2xo2IficOXnaByMWTGM9T73dGwxeWcUqIpI8= go.opencensus.io v0.22.2/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw= go.opencensus.io v0.22.3/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw= go.opencensus.io v0.22.4/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw= +go.uber.org/atomic v1.7.0/go.mod h1:fEN4uk6kAWBTFdckzkM89CLk9XfWZrxpCo0nPH17wJc= go.uber.org/automaxprocs v1.5.2 h1:2LxUOGiR3O6tw8ui5sZa2LAaHnsviZdVOUZw4fvbnME= go.uber.org/automaxprocs v1.5.2/go.mod h1:eRbA25aqJrxAbsLO0xy5jVwPt7FQnRgjW+efnwa1WM0= go.uber.org/goleak v1.2.0 h1:xqgm/S+aQvhWFTtR0XK3Jvg7z8kGV8P4X14IzwN3Eqk= diff --git a/portalnetwork/history/accumulator.go b/portalnetwork/history/accumulator.go new file mode 100644 index 0000000000..9dafee13c2 --- /dev/null +++ b/portalnetwork/history/accumulator.go @@ -0,0 +1,230 @@ +package history + +import ( + _ "embed" + "encoding/binary" + "errors" + + "github.com/ethereum/go-ethereum/core/types" + "github.com/ethereum/go-ethereum/rlp" + ssz "github.com/ferranbt/fastssz" + "github.com/holiman/uint256" +) + +const ( + epochSize = 8192 + mergeBlockNumber uint64 = 15537394 + preMergeEpochs = (mergeBlockNumber + epochSize - 1) / epochSize +) + +var ( + ErrNotPreMergeHeader = errors.New("must be pre merge header") + ErrPreMergeHeaderMustWithProof = errors.New("pre merge header must has accumulator proof") +) + +//go:embed assets/merge_macc.bin +var masterAccumulatorBytes []byte + +var zeroRecordBytes = make([]byte, 64) + +type AccumulatorProof [][]byte + +type epoch struct { + records [][]byte + difficulty *uint256.Int +} + +func newEpoch() *epoch { + return &epoch{ + records: make([][]byte, 0, epochSize), + difficulty: uint256.NewInt(0), + } +} + +func (e *epoch) add(header types.Header) error { + blockHash := header.Hash().Bytes() + difficulty := uint256.MustFromBig(header.Number) + e.difficulty = uint256.NewInt(0).Add(e.difficulty, difficulty) + record := HeaderRecord{ + BlockHash: blockHash, + TotalDifficulty: e.difficulty.Bytes(), + } + sszBytes, err := record.MarshalSSZ() + if err != nil { + return nil + } + e.records = append(e.records, sszBytes) + return nil +} + +type Accumulator struct { + historicalEpochs [][]byte + currentEpoch *epoch +} + +type BlockEpochData struct { + epochHash []byte + blockRelativeIndex uint64 +} + +func NewAccumulator() *Accumulator { + return &Accumulator{ + historicalEpochs: make([][]byte, 0, int(preMergeEpochs)), + currentEpoch: newEpoch(), + } +} + +func (a *Accumulator) Update(header types.Header) error { + if header.Number.Uint64() >= mergeBlockNumber { + return ErrNotPreMergeHeader + } + + if len(a.currentEpoch.records) == epochSize { + epochAccu := EpochAccumulator{ + HeaderRecords: a.currentEpoch.records, + } + root, err := epochAccu.HashTreeRoot() + if err != nil { + return err + } + a.historicalEpochs = append(a.historicalEpochs, MixInLength(root, epochSize)) + a.currentEpoch = newEpoch() + } + a.currentEpoch.add(header) + return nil +} + +func (a *Accumulator) Finish() (*MasterAccumulator, error) { + // padding with zero bytes + for len(a.currentEpoch.records) < epochSize { + a.currentEpoch.records = append(a.currentEpoch.records, zeroRecordBytes) + } + epochAccu := EpochAccumulator{ + HeaderRecords: a.currentEpoch.records, + } + root, err := epochAccu.HashTreeRoot() + if err != nil { + return nil, err + } + a.historicalEpochs = append(a.historicalEpochs, MixInLength(root, epochSize)) + return &MasterAccumulator{ + HistoricalEpochs: a.historicalEpochs, + }, nil +} + +func GetEpochIndex(blockNumber uint64) uint64 { + return blockNumber / epochSize +} + +func GetEpochIndexByHeader(header types.Header) uint64 { + return GetEpochIndex(header.Number.Uint64()) +} + +func GetHeaderRecordIndex(blockNumber uint64) uint64 { + return blockNumber % epochSize +} + +func GetHeaderRecordIndexByHeader(header types.Header) uint64 { + return GetHeaderRecordIndex(header.Number.Uint64()) +} + +func BuildProof(header types.Header, epochAccumulator EpochAccumulator) (AccumulatorProof, error) { + tree, err := epochAccumulator.GetTree() + if err != nil { + return nil, err + } + index := GetHeaderRecordIndexByHeader(header) + // maybe the calculation of index should impl in ssz + proofIndex := epochSize*2 + index*2 + sszProof, err := tree.Prove(int(proofIndex)) + // the epoch hash root has mix in with epochsize, so we have to add it to proof + hashes := sszProof.Hashes + sizeBytes := make([]byte, 32) + binary.LittleEndian.PutUint32(sizeBytes, epochSize) + hashes = append(hashes, sizeBytes) + return AccumulatorProof(hashes), err +} + +func BuildHeaderWithProof(header types.Header, epochAccumulator EpochAccumulator) (*BlockHeaderWithProof, error) { + proof, err := BuildProof(header, epochAccumulator) + if err != nil { + return nil, err + } + rlpBytes, err := rlp.EncodeToBytes(header) + if err != nil { + return nil, err + } + return &BlockHeaderWithProof{ + Header: rlpBytes, + Proof: &BlockHeaderProof{ + Selector: accumulatorProof, + Proof: proof, + }, + }, nil +} + +func (f MasterAccumulator) GetBlockEpochDataForBlockNumber(blockNumber uint64) BlockEpochData { + epochIndex := GetEpochIndex(blockNumber) + return BlockEpochData{ + epochHash: f.HistoricalEpochs[epochIndex], + blockRelativeIndex: GetHeaderRecordIndex(blockNumber), + } +} + +func (f MasterAccumulator) VerifyAccumulatorProof(header types.Header, proof AccumulatorProof) (bool, error) { + if header.Number.Uint64() > mergeBlockNumber { + return false, ErrNotPreMergeHeader + } + + epochIndex := GetEpochIndexByHeader(header) + root := f.HistoricalEpochs[epochIndex] + valid := verifyProof(root, header, proof) + return valid, nil +} + +func (f MasterAccumulator) VerifyHeader(header types.Header, headerProof BlockHeaderProof) (bool, error) { + switch headerProof.Selector { + case accumulatorProof: + return f.VerifyAccumulatorProof(header, headerProof.Proof) + case none: + if header.Number.Uint64() > mergeBlockNumber { + return false, ErrNotPreMergeHeader + } + return false, ErrPreMergeHeaderMustWithProof + } + return false, nil +} + +func MixInLength(root [32]byte, length uint64) []byte { + hash := ssz.NewHasher() + hash.AppendBytes32(root[:]) + hash.MerkleizeWithMixin(0, length, 0) + // length of root is 32, so we can ignore the err + newRoot, _ := hash.HashRoot() + return newRoot[:] +} + +func verifyProof(root []byte, header types.Header, proof AccumulatorProof) bool { + leaf := header.Hash() + + recordIndex := GetHeaderRecordIndexByHeader(header) + index := epochSize*2*2 + recordIndex*2 + sszProof := &ssz.Proof{ + Index: int(index), + Leaf: leaf[:], + Hashes: proof, + } + valid, err := ssz.VerifyProof(root, sszProof) + if err != nil { + return false + } + return valid +} + +func NewMasterAccumulator() (MasterAccumulator, error) { + var masterAcc = MasterAccumulator{ + HistoricalEpochs: make([][]byte, 0), + } + err := masterAcc.UnmarshalSSZ(masterAccumulatorBytes) + return masterAcc, err +} diff --git a/portalnetwork/history/accumulator_test.go b/portalnetwork/history/accumulator_test.go new file mode 100644 index 0000000000..0df94fe78c --- /dev/null +++ b/portalnetwork/history/accumulator_test.go @@ -0,0 +1,114 @@ +package history + +import ( + "bytes" + "encoding/json" + "fmt" + "os" + "strconv" + "testing" + + "github.com/ethereum/go-ethereum/common/hexutil" + "github.com/ethereum/go-ethereum/core/types" + "github.com/ethereum/go-ethereum/rlp" + "github.com/stretchr/testify/assert" +) + +func TestVerifyHeaderWithProofs(t *testing.T) { + headerWithProofs, err := parseHeaderWithProof() + assert.NoError(t, err) + masterAcc, err := NewMasterAccumulator() + assert.NoError(t, err) + for _, val := range headerWithProofs { + head := types.Header{} + err := rlp.DecodeBytes(val.Header, &head) + assert.NoError(t, err) + valid, err := masterAcc.VerifyHeader(head, *val.Proof) + assert.NoError(t, err) + assert.True(t, valid) + } +} + +func TestBuildAndVerifyProof(t *testing.T) { + masterAcc, err := NewMasterAccumulator() + assert.NoError(t, err) + epochIndex := GetEpochIndex(1000003) + epochStr := hexutil.Encode(masterAcc.HistoricalEpochs[epochIndex]) + epochAccumulator, err := getEpochAccu(epochStr) + assert.NoError(t, err) + + for i := 1000001; i < 1000011; i++ { + header, err := getHeader(1000003) + assert.NoError(t, err) + + proof, err := BuildProof(*header, epochAccumulator) + assert.NoError(t, err) + + valid, err := masterAcc.VerifyAccumulatorProof(*header, proof) + assert.NoError(t, err) + assert.True(t, valid) + assert.True(t, valid) + } +} + +// all test blocks are in the same epoch +func parseHeaderWithProof() ([]BlockHeaderWithProof, error) { + headWithProofBytes, err := os.ReadFile("./testdata/header_with_proofs.json") + if err != nil { + return nil, err + } + headerMap := make(map[string]map[string]string) + + err = json.Unmarshal(headWithProofBytes, &headerMap) + if err != nil { + return nil, err + } + res := make([]BlockHeaderWithProof, 0) + for _, v := range headerMap { + val := v["value"] + bytes, err := hexutil.Decode(val) + if err != nil { + return nil, err + } + headWithProof := BlockHeaderWithProof{} + err = headWithProof.UnmarshalSSZ(bytes) + if err != nil { + return nil, err + } + res = append(res, headWithProof) + } + return res, nil +} + +func getEpochAccu(name string) (EpochAccumulator, error) { + epochAccu := EpochAccumulator{ + HeaderRecords: make([][]byte, 0), + } + epochData, err := os.ReadFile(fmt.Sprintf("./testdata/%s.bin", name)) + if err != nil { + return epochAccu, err + } + err = epochAccu.UnmarshalSSZ(epochData) + return epochAccu, err +} + +func getHeader(number uint64) (*types.Header, error) { + headerFile, err := os.ReadFile("./testdata/header_rlps.json") + if err != nil { + return nil, err + } + contentMap := make(map[string]string) + err = json.Unmarshal(headerFile, &contentMap) + if err != nil { + return nil, err + } + headerStr := contentMap[strconv.FormatUint(number, 10)] + headerBytes, err := hexutil.Decode(headerStr) + if err != nil { + return nil, err + } + reader := bytes.NewReader(headerBytes) + head := &types.Header{} + err = rlp.Decode(reader, head) + return head, err +} diff --git a/portalnetwork/history/assets/merge_macc.bin b/portalnetwork/history/assets/merge_macc.bin new file mode 100644 index 0000000000..32a7aa2c3c Binary files /dev/null and b/portalnetwork/history/assets/merge_macc.bin differ diff --git a/portalnetwork/history/testdata/0xcddbda3fd6f764602c06803ff083dbfc73f2bb396df17a31e5457329b9a0f38d.bin b/portalnetwork/history/testdata/0xcddbda3fd6f764602c06803ff083dbfc73f2bb396df17a31e5457329b9a0f38d.bin new file mode 100644 index 0000000000..70b15e48ff Binary files /dev/null and b/portalnetwork/history/testdata/0xcddbda3fd6f764602c06803ff083dbfc73f2bb396df17a31e5457329b9a0f38d.bin differ diff --git a/portalnetwork/history/testdata/header_rlps.json b/portalnetwork/history/testdata/header_rlps.json new file mode 100644 index 0000000000..5c01d3c1ea --- /dev/null +++ b/portalnetwork/history/testdata/header_rlps.json @@ -0,0 +1,18 @@ +{ + "0": "0xf90214a00000000000000000000000000000000000000000000000000000000000000000a01dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347940000000000000000000000000000000000000000a0d7f8974fb5ac78d9ac099b9ad5018bedc2ce0a72dad1827a1709da30580f0544a056e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421a056e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421b9010000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000850400000000808213888080a011bbe8db4e347b4e8c937c1c8370e4b5ed33adb3db69cbdb7a38e1e50b1b82faa00000000000000000000000000000000000000000000000000000000000000000880000000000000042", + "1": "0xf90211a0d4e56740f876aef8c010b86a40d5f56745a118d0906a34e69aec8c0db1cb8fa3a01dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d493479405a56e2d52c817161883f50c441c3228cfe54d9fa0d67e4d450343046425ae4271474353857ab860dbc0a1dde64b41b5cd3a532bf3a056e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421a056e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421b90100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000008503ff80000001821388808455ba422499476574682f76312e302e302f6c696e75782f676f312e342e32a0969b900de27b6ac6a67742365dd65f55a0526c41fd18e1b16f1a1215c2e66f5988539bd4979fef1ec4", + "2": "0xf90218a088e96d4537bea4d9c05d12549907b32561d3bf31f45aae734cdc119f13406cb6a01dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d4934794dd2f1e6e498202e86d8f5442af596580a4f03c2ca04943d941637411107494da9ec8bc04359d731bfd08b72b4d0edcbd4cd2ecb341a056e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421a056e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421b90100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000008503ff00100002821388808455ba4241a0476574682f76312e302e302d30636463373634372f6c696e75782f676f312e34a02f0790c5aa31ab94195e1f6443d645af5b75c46c04fbf9911711198a0ce8fdda88b853fa261a86aa9e", + "200000": "0xf90213a07f27ffbccbbf32b53697930c508137e451e8de080231008d945c6e3ed631b74aa01dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347941dcb8d1f0fcc8cbc8c2d76528e877f915e299fbea0632964149a2056cb246ccee21838d139516578712f13b2a7cbf0086969d0f4aba056e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421a056e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421b90100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000008605ae701ab58e83030d40832fefd8808455ee029596d583010102844765746885676f312e35856c696e7578a0f9d7884dab1938bd8100a4564a949256aedb8936ad3f72f48eaa679269560a65883ec79c2d077b8db2", + "669051": "0xf90217a092bccf7a38604c5441dffc5eb5a5ca295b3fbb7ff01cc92fb3b48f0d456e732ea01dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d4934794f8b483dba2c3b7176a3da549ad41a48bb3121069a08a779b9d52800c3f0fc2ec4f8388dd56e1fcf4685126466bc1a9832ab2ddf612a056e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421a056e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421b9010000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000860717d1b1cd0e830a357b832fefd88084566930a39ad983010203844765746887676f312e342e328777696e646f7773a0daa40d4b72000209b43526ada798b90b98f9cd6e4cdc5bebbad690208aa1728788e6b9441a5df2f6ad", + "15537393": "0xf9021ba02b3ea3cd4befcab070812443affb08bf17a91ce382c714a536ca3cacab82278ba01dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d4934794829bd824b016326a401d083b33d092293333a830a04919dafa6ac8becfbbd0c2808f6c9511a057c21e42839caff5dfb6d3ef514951a0dd5eec02b019ff76e359b09bfa19395a2a0e97bc01e70d8d5491e640167c96a8a0baa842cfd552321a9c2450576126311e071680a1258032219c6490b663c1dab8b90100000004000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000800000000000000000000000080000000000000000000000000000000000000000000000000200000000000000000008000000000040000000000000100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000084000000000010020000000000000000000000000000000000020000000200000000200000000000000000000000000000000000000000400000000000000000000000008727472e1db3626a83ed14f18401c9c3808401c9a205846322c96292e4b883e5bda9e7a59ee4bb99e9b1bc460021a04cbec03dddd4b939730a7fe6048729604d4266e82426d472a2b2024f3cc4043f8862a3ee77461d4fc9850a1a4e5f06", + "1000001": "0xf90217a08e38b4dbf6b11fcc3b9dee84fb7986e29ca0a02cecd8977c161ff7333329681ea01dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347942a65aca4d5fc5b5c859090a6c34d164135398226a07dd4aabb93795feba9866821c0c7d6a992eda7fbdd412ea0f715059f9654ef23a0c61c50a0a2800ddc5e9984af4e6668de96aee1584179b3141f458ffa7d4ecec6a0b873ddefdb56d448343d13b188241a4919b2de10cccea2ea573acf8dbc839befb9010000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000860b6b4bbd735f830f4241832fefd88252088456bfb41a98d783010303844765746887676f312e352e31856c696e7578a0d5332614a151dd917b84fc5ff62580d7099edb7c37e0ac843d873de978d50352889112b8c2b377fbe8", + "1000002": "0xf90217a0cb5cab7266694daa0d28cbf40496c08dd30bf732c41e0455e7ad389c10d79f4fa01dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d493479495581ea0c5b362933f3523138f54d51eae817211a0643430d1afc3f02ce5249e4ba5979fb8601b1907a5923a4a74d36d66321a27e5a0dbdf7457111e50e435853974d5412c2151fde6e3c2e3f5aecc253aa4cb21fce2a097097902b6b4d6b695ef16b923e33b8780d95cf4bd54540ac450deb019d07647b9010000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000860b69de53fcb1830f4242832fefd882f6188456bfb42e98d783010303844765746887676f312e352e31856c696e7578a0a01f9d00ac510a726f883459834e30cfe085f47b04e22f72207f5a9e9d652ca6881c080c4ec6f2553b", + "1000003": "0xf90217a095c3a05973fec7bf98f1131a72e607b4eba171d0576571cf83ee7162bbcdb7d9a01dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347942a65aca4d5fc5b5c859090a6c34d164135398226a0651bd0c6ad32da06a732db9797ced42e01ca607b3d049832486ce0f98b2ac517a0eef5869831e31e8e92a812916adfe27b2902f7b9e10246e38beec7df23e818dca06eaba9039ef6c055a3796d90f2ab1eeb86cfb4f9fec56c1eb097188950f35ec5b9010000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000860b6b4b8fc830830f4243832fefd88252088456bfb43098d783010303844765746887676f312e352e31856c696e7578a00b52aa3b442bc0e85c53a9708ee14a2f7f9fdf87b4ed52dced8fcdc0ffbd0e2e88b69d3fa0a7107603", + "1000004": "0xf90217a0ed08bd684ca0167101054b8e8baaef5b28663a9936e9347424a810e493250d25a01dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347942a65aca4d5fc5b5c859090a6c34d164135398226a09bb6ebcf9d87354039fdcdf1ebbd8aae154155e57fcb38a371cdcfec533ead51a04d115b466f31be0c927a80eafa9e3e04ba612fa3578eb2b7bf2b284d297d9cf9a00a60403314e4be4fcea22907e4c57b3a887aae6a5b4490298b0cec4837c6693bb9010000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000860b69de265737830f4244832fefd882a4108456bfb44498d783010303844765746887676f312e352e31856c696e7578a038bd108c803e477efe1053b5b82875150f221aa95ea38623da13dad53aa2634688cfedf9cf294baade", + "1000005": "0xf90217a05c2689d27bfeded9faa0d52e7301bb425e0758ee2b550b852557776e5453ed48a01dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347942a65aca4d5fc5b5c859090a6c34d164135398226a0eb6e181798a9f28e1549d5818ae9e2b89f2d12e80d52e43fb6afbe0d876d2755a0678a5351a2bc45773aed24446d87ef7a0a67c0e6005a4c945c1ab9f4124b8baea067766475549b952e6ab6c973dbddbab8cf017cfcc43e56c08b7ee4494b05a053b9010000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000860b6b4b621d01830f4245832fefd88252088456bfb44c98d783010303844765746887676f312e352e31856c696e7578a0577dfcb7885b10af0b1f3c9ce059fe10f1f4f25b4ec6fc33fc916b861dc7e11d8871f6405556868e15", + "1000006": "0xf90215a0de9808464da8c76074e77ceb53917fbb58ef8057472c9b24f1332cc293215b91a01dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d493479463a9975ba31b0b9626b34300f7f627147df1f526a05f15197e6511710c05e2474b0f2cc9b24edae8d1221bf66f2c348657a47b1dc8a056e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421a056e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421b9010000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000860b6cb8cb8a44830f4246832fefd8808456bfb44e98d783010400844765746887676f312e352e31856c696e7578a082e43f95bfaf9aa2e9d106f34bfc1bb0e127c51cf476dd224e81e304ceaab0fc88863127de92b0e7e9", + "1000007": "0xf9021aa03962187c363ce329fd05a41b74017a0a693f0cc5383eb790afad37dcfd1a4b3ca01dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d4934794f8b483dba2c3b7176a3da549ad41a48bb3121069a03d30cf33487586dc69cc29227e031519b9196b0f6f62f5432d56a949eaf41deba0334799df0c6e58fa0fc8a12065faa9669d81b41befc35de295e1688d24a9e4eda0c1f5d246ba496e41b3a47ae8da0e8c23381c3ee5b09128805c7a4630a2651394b9010000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000860b6b4b3471d3830f4247832fefd883019a288456bfb47d9ad983010302844765746887676f312e342e328777696e646f7773a0181d92d747842e835f2749c6c270a140bf19b2145c210e901f7b70a2b988259888b5afeac367d84d68", + "1000008": "0xf90217a07d4fbba665d462a39a06d98e2c57df0d5e34fc7660a064e44617e20143e3c78ca01dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d493479468795c4aa09d6f4ed3e5deddf8c2ad3049a601daa08da9a5b0d31d90c6aee4d3a29f80f026425ab967bb50b3a75b363ffde1c9c882a0b23c3d805f1e1002471aa5aff5a4fa60795c163ca288dc77c3b8870ddba989e7a05cbfe86e7c01bf19215d9a6398665e84bf38b6c76ccc87107df469e8827c6962b9010000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000860b6cb89dd961830f4248832fefd88252088456bfb48098d783010400844765746887676f312e352e31856c696e7578a0a4fe220f13171d30b40f76b0f891310923f742e2370318e50eaf3324720bba0588b23301ed5b0c8e67", + "1000009": "0xf90215a05d1a17185e3b28bb6d6e6bacb37ea2164f4167c9738a23f802a629af1bdf17d9a01dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d493479452dc504a422f0e2a9e7632a34a50f1a82f8224c7a0c8566a988385f3998e4704d464b4cff65a91a0fa4a22de4e8335e536eaadd1a1a056e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421a056e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421b9010000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000860b6b4b06c6a6830f4249832fefd8808456bfb48e98d783010303844765746887676f312e352e31856c696e7578a0a746fd5b8dc7c8f8771e6e5a9d90774152421842fd66a353ecfa8013f512803a8833eb6f003aace9d9", + "1000010": "0xf90218a00409be8253ad6ac0eb2056bc94194c6ccb83c74f4292c40c82e2dc8203bdc759a01dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347942a65aca4d5fc5b5c859090a6c34d164135398226a0afbf9bfd23008e8df44a83bb51ade45b993b3253fbce69cf7cec5d628eca6d45a0a7120e4bd136c0b6bdb0fa4990649f8c34d10d180dbd5ad6d03502ae92d32308a0d78aa953fedc7f7c112b2686d0b2b7e37eba716dd1f5d74ef3c8a37005f35215b9010000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000008000000000000000000000000000000000000000000000000000000004000000000000000000040000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000400000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000400000000000000000860b69dd9d66ce830f424a832fefd88303a68c8456bfb4e398d783010303844765746887676f312e352e31856c696e7578a0e962efb883f91286e4fc6fd12989a70f24c174bd087f472528137c4134af0a1a88e857c5acc15dd827" +} diff --git a/portalnetwork/history/testdata/header_with_proofs.json b/portalnetwork/history/testdata/header_with_proofs.json new file mode 100644 index 0000000000..c568daad8e --- /dev/null +++ b/portalnetwork/history/testdata/header_with_proofs.json @@ -0,0 +1,42 @@ +{ + "1000001": { + "content_key": "0x00cb5cab7266694daa0d28cbf40496c08dd30bf732c41e0455e7ad389c10d79f4f", + "value": "0x0800000022020000f90217a08e38b4dbf6b11fcc3b9dee84fb7986e29ca0a02cecd8977c161ff7333329681ea01dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347942a65aca4d5fc5b5c859090a6c34d164135398226a07dd4aabb93795feba9866821c0c7d6a992eda7fbdd412ea0f715059f9654ef23a0c61c50a0a2800ddc5e9984af4e6668de96aee1584179b3141f458ffa7d4ecec6a0b873ddefdb56d448343d13b188241a4919b2de10cccea2ea573acf8dbc839befb9010000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000860b6b4bbd735f830f4241832fefd88252088456bfb41a98d783010303844765746887676f312e352e31856c696e7578a0d5332614a151dd917b84fc5ff62580d7099edb7c37e0ac843d873de978d50352889112b8c2b377fbe801c971eaaa41600563000000000000000000000000000000000000000000000000629f9dbe275316ef21073133b8ecec062a44e20201be7b24a22c56db91df336f0c71aaaec1b3526027a54b15387ef014fcd18bb46e90e05657b46418fd326e785392c40ec6d38f000042798fee52ed833ff376b1d5a95dc7c2356dc8d8d02e30b704e9ee8e4d712920a18fd4e8833a7979a14e5b972d4b27958dcfa5187e3aa14d61c29c3fda0fb425078a0479c5ea375ff95ad7780d0cdc87012009fd4a3dd003b06c7a28d6188e6be50ac544548cc7e3ee6cd07a8129f5c6d4d494b62ee8d96d26d0875bc87b56be0bf3e45846c0e3773abfccc239fdab29640b4e2aef297efcc6cb89b00a2566221cb4197ece3f66c24ea89969bd16265a74910aaf08d775116191117416b8799d0984f452a6fba19623442a7f199ef1627f1ae7295963a67db5534a292f98edbfb419ed85756abe76cd2d2bff8eb9b848b1e7b80b8274bbc469a36dce58b48ae57be6312bca843463ac45c54122a9f3fa9dca124b0fd50bce300708549c77b81b031278b9d193464f5e4b14769f6018055a457a577c508e811bcf55b297df3509f3db7e66ec68451e25acfbf935200e246f71e3c48240d00020000000000000000000000000000000000000000000000000000000000000" + }, + "1000002": { + "content_key": "0x0095c3a05973fec7bf98f1131a72e607b4eba171d0576571cf83ee7162bbcdb7d9", + "value": "0x0800000022020000f90217a0cb5cab7266694daa0d28cbf40496c08dd30bf732c41e0455e7ad389c10d79f4fa01dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d493479495581ea0c5b362933f3523138f54d51eae817211a0643430d1afc3f02ce5249e4ba5979fb8601b1907a5923a4a74d36d66321a27e5a0dbdf7457111e50e435853974d5412c2151fde6e3c2e3f5aecc253aa4cb21fce2a097097902b6b4d6b695ef16b923e33b8780d95cf4bd54540ac450deb019d07647b9010000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000860b69de53fcb1830f4242832fefd882f6188456bfb42e98d783010303844765746887676f312e352e31856c696e7578a0a01f9d00ac510a726f883459834e30cfe085f47b04e22f72207f5a9e9d652ca6881c080c4ec6f2553b017a6e3e89ab6b056300000000000000000000000000000000000000000000000030a7f33265c53f74e978e394ce395aaf1247e8d878ad7924c730beedf21f997ef4cb3507d87cf63a4e94fd8d559a5aa29598a0fbc997b3d7abb68cb9239d83c35392c40ec6d38f000042798fee52ed833ff376b1d5a95dc7c2356dc8d8d02e30b704e9ee8e4d712920a18fd4e8833a7979a14e5b972d4b27958dcfa5187e3aa14d61c29c3fda0fb425078a0479c5ea375ff95ad7780d0cdc87012009fd4a3dd003b06c7a28d6188e6be50ac544548cc7e3ee6cd07a8129f5c6d4d494b62ee8d96d26d0875bc87b56be0bf3e45846c0e3773abfccc239fdab29640b4e2aef297efcc6cb89b00a2566221cb4197ece3f66c24ea89969bd16265a74910aaf08d775116191117416b8799d0984f452a6fba19623442a7f199ef1627f1ae7295963a67db5534a292f98edbfb419ed85756abe76cd2d2bff8eb9b848b1e7b80b8274bbc469a36dce58b48ae57be6312bca843463ac45c54122a9f3fa9dca124b0fd50bce300708549c77b81b031278b9d193464f5e4b14769f6018055a457a577c508e811bcf55b297df3509f3db7e66ec68451e25acfbf935200e246f71e3c48240d00020000000000000000000000000000000000000000000000000000000000000" + }, + "1000003": { + "content_key": "0x00ed08bd684ca0167101054b8e8baaef5b28663a9936e9347424a810e493250d25", + "value": "0x0800000022020000f90217a095c3a05973fec7bf98f1131a72e607b4eba171d0576571cf83ee7162bbcdb7d9a01dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347942a65aca4d5fc5b5c859090a6c34d164135398226a0651bd0c6ad32da06a732db9797ced42e01ca607b3d049832486ce0f98b2ac517a0eef5869831e31e8e92a812916adfe27b2902f7b9e10246e38beec7df23e818dca06eaba9039ef6c055a3796d90f2ab1eeb86cfb4f9fec56c1eb097188950f35ec5b9010000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000860b6b4b8fc830830f4243832fefd88252088456bfb43098d783010303844765746887676f312e352e31856c696e7578a00b52aa3b442bc0e85c53a9708ee14a2f7f9fdf87b4ed52dced8fcdc0ffbd0e2e88b69d3fa0a710760301aa36ced416770563000000000000000000000000000000000000000000000000cf640afdac3593c1cf722ad68a5a536688c110d5d862390cedd25f42ce03faaef4cb3507d87cf63a4e94fd8d559a5aa29598a0fbc997b3d7abb68cb9239d83c35392c40ec6d38f000042798fee52ed833ff376b1d5a95dc7c2356dc8d8d02e30b704e9ee8e4d712920a18fd4e8833a7979a14e5b972d4b27958dcfa5187e3aa14d61c29c3fda0fb425078a0479c5ea375ff95ad7780d0cdc87012009fd4a3dd003b06c7a28d6188e6be50ac544548cc7e3ee6cd07a8129f5c6d4d494b62ee8d96d26d0875bc87b56be0bf3e45846c0e3773abfccc239fdab29640b4e2aef297efcc6cb89b00a2566221cb4197ece3f66c24ea89969bd16265a74910aaf08d775116191117416b8799d0984f452a6fba19623442a7f199ef1627f1ae7295963a67db5534a292f98edbfb419ed85756abe76cd2d2bff8eb9b848b1e7b80b8274bbc469a36dce58b48ae57be6312bca843463ac45c54122a9f3fa9dca124b0fd50bce300708549c77b81b031278b9d193464f5e4b14769f6018055a457a577c508e811bcf55b297df3509f3db7e66ec68451e25acfbf935200e246f71e3c48240d00020000000000000000000000000000000000000000000000000000000000000" + }, + "1000004": { + "content_key": "0x005c2689d27bfeded9faa0d52e7301bb425e0758ee2b550b852557776e5453ed48", + "value": "0x0800000022020000f90217a0ed08bd684ca0167101054b8e8baaef5b28663a9936e9347424a810e493250d25a01dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347942a65aca4d5fc5b5c859090a6c34d164135398226a09bb6ebcf9d87354039fdcdf1ebbd8aae154155e57fcb38a371cdcfec533ead51a04d115b466f31be0c927a80eafa9e3e04ba612fa3578eb2b7bf2b284d297d9cf9a00a60403314e4be4fcea22907e4c57b3a887aae6a5b4490298b0cec4837c6693bb9010000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000860b69de265737830f4244832fefd882a4108456bfb44498d783010303844765746887676f312e352e31856c696e7578a038bd108c803e477efe1053b5b82875150f221aa95ea38623da13dad53aa2634688cfedf9cf294baade01e18df4b2808205630000000000000000000000000000000000000000000000003adbb422354ef244812ab70e2d9bb1c48461a93df635a1423d36f49d67790deb1dfb82c1fc4a6632d8d41f0e6ba37172d240fb052f1f1c2bfc9a5a7bf03e3b059349d18c2f925a07d81acea8e46e9e12746357cdd21ffcd42bae5957404ee757b704e9ee8e4d712920a18fd4e8833a7979a14e5b972d4b27958dcfa5187e3aa14d61c29c3fda0fb425078a0479c5ea375ff95ad7780d0cdc87012009fd4a3dd003b06c7a28d6188e6be50ac544548cc7e3ee6cd07a8129f5c6d4d494b62ee8d96d26d0875bc87b56be0bf3e45846c0e3773abfccc239fdab29640b4e2aef297efcc6cb89b00a2566221cb4197ece3f66c24ea89969bd16265a74910aaf08d775116191117416b8799d0984f452a6fba19623442a7f199ef1627f1ae7295963a67db5534a292f98edbfb419ed85756abe76cd2d2bff8eb9b848b1e7b80b8274bbc469a36dce58b48ae57be6312bca843463ac45c54122a9f3fa9dca124b0fd50bce300708549c77b81b031278b9d193464f5e4b14769f6018055a457a577c508e811bcf55b297df3509f3db7e66ec68451e25acfbf935200e246f71e3c48240d00020000000000000000000000000000000000000000000000000000000000000" + }, + "1000005": { + "content_key": "0x00de9808464da8c76074e77ceb53917fbb58ef8057472c9b24f1332cc293215b91", + "value": "0x0800000022020000f90217a05c2689d27bfeded9faa0d52e7301bb425e0758ee2b550b852557776e5453ed48a01dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347942a65aca4d5fc5b5c859090a6c34d164135398226a0eb6e181798a9f28e1549d5818ae9e2b89f2d12e80d52e43fb6afbe0d876d2755a0678a5351a2bc45773aed24446d87ef7a0a67c0e6005a4c945c1ab9f4124b8baea067766475549b952e6ab6c973dbddbab8cf017cfcc43e56c08b7ee4494b05a053b9010000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000860b6b4b621d01830f4245832fefd88252088456bfb44c98d783010303844765746887676f312e352e31856c696e7578a0577dfcb7885b10af0b1f3c9ce059fe10f1f4f25b4ec6fc33fc916b861dc7e11d8871f6405556868e1501e2aa56feeb8d0563000000000000000000000000000000000000000000000000b158b0a4fea8d2f5094a4e4263dde3478263805d0a5674b23ad9b2fa42d7deca1dfb82c1fc4a6632d8d41f0e6ba37172d240fb052f1f1c2bfc9a5a7bf03e3b059349d18c2f925a07d81acea8e46e9e12746357cdd21ffcd42bae5957404ee757b704e9ee8e4d712920a18fd4e8833a7979a14e5b972d4b27958dcfa5187e3aa14d61c29c3fda0fb425078a0479c5ea375ff95ad7780d0cdc87012009fd4a3dd003b06c7a28d6188e6be50ac544548cc7e3ee6cd07a8129f5c6d4d494b62ee8d96d26d0875bc87b56be0bf3e45846c0e3773abfccc239fdab29640b4e2aef297efcc6cb89b00a2566221cb4197ece3f66c24ea89969bd16265a74910aaf08d775116191117416b8799d0984f452a6fba19623442a7f199ef1627f1ae7295963a67db5534a292f98edbfb419ed85756abe76cd2d2bff8eb9b848b1e7b80b8274bbc469a36dce58b48ae57be6312bca843463ac45c54122a9f3fa9dca124b0fd50bce300708549c77b81b031278b9d193464f5e4b14769f6018055a457a577c508e811bcf55b297df3509f3db7e66ec68451e25acfbf935200e246f71e3c48240d00020000000000000000000000000000000000000000000000000000000000000" + }, + "1000006": { + "content_key": "0x003962187c363ce329fd05a41b74017a0a693f0cc5383eb790afad37dcfd1a4b3c", + "value": "0x0800000020020000f90215a0de9808464da8c76074e77ceb53917fbb58ef8057472c9b24f1332cc293215b91a01dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d493479463a9975ba31b0b9626b34300f7f627147df1f526a05f15197e6511710c05e2474b0f2cc9b24edae8d1221bf66f2c348657a47b1dc8a056e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421a056e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421b9010000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000860b6cb8cb8a44830f4246832fefd8808456bfb44e98d783010400844765746887676f312e352e31856c696e7578a082e43f95bfaf9aa2e9d106f34bfc1bb0e127c51cf476dd224e81e304ceaab0fc88863127de92b0e7e901263522b7589905630000000000000000000000000000000000000000000000006b23456915f5fc5be0c705797ba9f3d47c099c26b7593875642dfd899fc36a01145d3c2df0e829c55d10be53a01706ff92e445c3870b819d0333feadda3edf8c9349d18c2f925a07d81acea8e46e9e12746357cdd21ffcd42bae5957404ee757b704e9ee8e4d712920a18fd4e8833a7979a14e5b972d4b27958dcfa5187e3aa14d61c29c3fda0fb425078a0479c5ea375ff95ad7780d0cdc87012009fd4a3dd003b06c7a28d6188e6be50ac544548cc7e3ee6cd07a8129f5c6d4d494b62ee8d96d26d0875bc87b56be0bf3e45846c0e3773abfccc239fdab29640b4e2aef297efcc6cb89b00a2566221cb4197ece3f66c24ea89969bd16265a74910aaf08d775116191117416b8799d0984f452a6fba19623442a7f199ef1627f1ae7295963a67db5534a292f98edbfb419ed85756abe76cd2d2bff8eb9b848b1e7b80b8274bbc469a36dce58b48ae57be6312bca843463ac45c54122a9f3fa9dca124b0fd50bce300708549c77b81b031278b9d193464f5e4b14769f6018055a457a577c508e811bcf55b297df3509f3db7e66ec68451e25acfbf935200e246f71e3c48240d00020000000000000000000000000000000000000000000000000000000000000" + }, + "1000007": { + "content_key": "0x007d4fbba665d462a39a06d98e2c57df0d5e34fc7660a064e44617e20143e3c78c", + "value": "0x0800000025020000f9021aa03962187c363ce329fd05a41b74017a0a693f0cc5383eb790afad37dcfd1a4b3ca01dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d4934794f8b483dba2c3b7176a3da549ad41a48bb3121069a03d30cf33487586dc69cc29227e031519b9196b0f6f62f5432d56a949eaf41deba0334799df0c6e58fa0fc8a12065faa9669d81b41befc35de295e1688d24a9e4eda0c1f5d246ba496e41b3a47ae8da0e8c23381c3ee5b09128805c7a4630a2651394b9010000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000860b6b4b3471d3830f4247832fefd883019a288456bfb47d9ad983010302844765746887676f312e342e328777696e646f7773a0181d92d747842e835f2749c6c270a140bf19b2145c210e901f7b70a2b988259888b5afeac367d84d6801f9a65602c4a4056300000000000000000000000000000000000000000000000061410e3978de33e61cf96b22d14763e4b5c5a6ad901d89ac0cd3323dc406b918145d3c2df0e829c55d10be53a01706ff92e445c3870b819d0333feadda3edf8c9349d18c2f925a07d81acea8e46e9e12746357cdd21ffcd42bae5957404ee757b704e9ee8e4d712920a18fd4e8833a7979a14e5b972d4b27958dcfa5187e3aa14d61c29c3fda0fb425078a0479c5ea375ff95ad7780d0cdc87012009fd4a3dd003b06c7a28d6188e6be50ac544548cc7e3ee6cd07a8129f5c6d4d494b62ee8d96d26d0875bc87b56be0bf3e45846c0e3773abfccc239fdab29640b4e2aef297efcc6cb89b00a2566221cb4197ece3f66c24ea89969bd16265a74910aaf08d775116191117416b8799d0984f452a6fba19623442a7f199ef1627f1ae7295963a67db5534a292f98edbfb419ed85756abe76cd2d2bff8eb9b848b1e7b80b8274bbc469a36dce58b48ae57be6312bca843463ac45c54122a9f3fa9dca124b0fd50bce300708549c77b81b031278b9d193464f5e4b14769f6018055a457a577c508e811bcf55b297df3509f3db7e66ec68451e25acfbf935200e246f71e3c48240d00020000000000000000000000000000000000000000000000000000000000000" + }, + "1000008": { + "content_key": "0x005d1a17185e3b28bb6d6e6bacb37ea2164f4167c9738a23f802a629af1bdf17d9", + "value": "0x0800000022020000f90217a07d4fbba665d462a39a06d98e2c57df0d5e34fc7660a064e44617e20143e3c78ca01dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d493479468795c4aa09d6f4ed3e5deddf8c2ad3049a601daa08da9a5b0d31d90c6aee4d3a29f80f026425ab967bb50b3a75b363ffde1c9c882a0b23c3d805f1e1002471aa5aff5a4fa60795c163ca288dc77c3b8870ddba989e7a05cbfe86e7c01bf19215d9a6398665e84bf38b6c76ccc87107df469e8827c6962b9010000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000860b6cb89dd961830f4248832fefd88252088456bfb48098d783010400844765746887676f312e352e31856c696e7578a0a4fe220f13171d30b40f76b0f891310923f742e2370318e50eaf3324720bba0588b23301ed5b0c8e67015a80f4ba30b0056300000000000000000000000000000000000000000000000052ef50f0cc153776ad48d638b1ac79178f6452299d4c3e6be8014a03a27b1e60d1fd24ef33b3f7c8d15cd0d92ce0aa9d84d3492d0b24e5e65e2f5e5567e858086d800f67f5331ee2e511dc20e169c644b3df0f4c6b7c1717fc29d4844050b74044b506bf91edd14825aaec4f36fc5ad97b9eed9773aa2df15f80dff21eb668e24d61c29c3fda0fb425078a0479c5ea375ff95ad7780d0cdc87012009fd4a3dd003b06c7a28d6188e6be50ac544548cc7e3ee6cd07a8129f5c6d4d494b62ee8d96d26d0875bc87b56be0bf3e45846c0e3773abfccc239fdab29640b4e2aef297efcc6cb89b00a2566221cb4197ece3f66c24ea89969bd16265a74910aaf08d775116191117416b8799d0984f452a6fba19623442a7f199ef1627f1ae7295963a67db5534a292f98edbfb419ed85756abe76cd2d2bff8eb9b848b1e7b80b8274bbc469a36dce58b48ae57be6312bca843463ac45c54122a9f3fa9dca124b0fd50bce300708549c77b81b031278b9d193464f5e4b14769f6018055a457a577c508e811bcf55b297df3509f3db7e66ec68451e25acfbf935200e246f71e3c48240d00020000000000000000000000000000000000000000000000000000000000000" + }, + "1000009": { + "content_key": "0x000409be8253ad6ac0eb2056bc94194c6ccb83c74f4292c40c82e2dc8203bdc759", + "value": "0x0800000020020000f90215a05d1a17185e3b28bb6d6e6bacb37ea2164f4167c9738a23f802a629af1bdf17d9a01dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d493479452dc504a422f0e2a9e7632a34a50f1a82f8224c7a0c8566a988385f3998e4704d464b4cff65a91a0fa4a22de4e8335e536eaadd1a1a056e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421a056e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421b9010000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000860b6b4b06c6a6830f4249832fefd8808456bfb48e98d783010303844765746887676f312e352e31856c696e7578a0a746fd5b8dc7c8f8771e6e5a9d90774152421842fd66a353ecfa8013f512803a8833eb6f003aace9d9010047fb059cbb0563000000000000000000000000000000000000000000000000e17b024ddb03e64d58a1797016fe2de5a78b243b84778fe8dba4480515c0bb01d1fd24ef33b3f7c8d15cd0d92ce0aa9d84d3492d0b24e5e65e2f5e5567e858086d800f67f5331ee2e511dc20e169c644b3df0f4c6b7c1717fc29d4844050b74044b506bf91edd14825aaec4f36fc5ad97b9eed9773aa2df15f80dff21eb668e24d61c29c3fda0fb425078a0479c5ea375ff95ad7780d0cdc87012009fd4a3dd003b06c7a28d6188e6be50ac544548cc7e3ee6cd07a8129f5c6d4d494b62ee8d96d26d0875bc87b56be0bf3e45846c0e3773abfccc239fdab29640b4e2aef297efcc6cb89b00a2566221cb4197ece3f66c24ea89969bd16265a74910aaf08d775116191117416b8799d0984f452a6fba19623442a7f199ef1627f1ae7295963a67db5534a292f98edbfb419ed85756abe76cd2d2bff8eb9b848b1e7b80b8274bbc469a36dce58b48ae57be6312bca843463ac45c54122a9f3fa9dca124b0fd50bce300708549c77b81b031278b9d193464f5e4b14769f6018055a457a577c508e811bcf55b297df3509f3db7e66ec68451e25acfbf935200e246f71e3c48240d00020000000000000000000000000000000000000000000000000000000000000" + }, + "1000010": { + "content_key": "0x006251d65b8a8668efabe2f89c96a5b6332d83b3bbe585089ea6b2ab9b6754f5e9", + "value": "0x0800000023020000f90218a00409be8253ad6ac0eb2056bc94194c6ccb83c74f4292c40c82e2dc8203bdc759a01dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347942a65aca4d5fc5b5c859090a6c34d164135398226a0afbf9bfd23008e8df44a83bb51ade45b993b3253fbce69cf7cec5d628eca6d45a0a7120e4bd136c0b6bdb0fa4990649f8c34d10d180dbd5ad6d03502ae92d32308a0d78aa953fedc7f7c112b2686d0b2b7e37eba716dd1f5d74ef3c8a37005f35215b9010000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000008000000000000000000000000000000000000000000000000000000004000000000000000000040000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000400000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000400000000000000000860b69dd9d66ce830f424a832fefd88303a68c8456bfb4e398d783010303844765746887676f312e352e31856c696e7578a0e962efb883f91286e4fc6fd12989a70f24c174bd087f472528137c4134af0a1a88e857c5acc15dd82701cead98e305c70563000000000000000000000000000000000000000000000000be1b4a7a57f5316eea09c5e3e349141c46c1cb43664a815d28644cd74f282ca122360456d89447c0d586a8f5490922ea86b20e056879d64d87d104c14c0e594a6d800f67f5331ee2e511dc20e169c644b3df0f4c6b7c1717fc29d4844050b74044b506bf91edd14825aaec4f36fc5ad97b9eed9773aa2df15f80dff21eb668e24d61c29c3fda0fb425078a0479c5ea375ff95ad7780d0cdc87012009fd4a3dd003b06c7a28d6188e6be50ac544548cc7e3ee6cd07a8129f5c6d4d494b62ee8d96d26d0875bc87b56be0bf3e45846c0e3773abfccc239fdab29640b4e2aef297efcc6cb89b00a2566221cb4197ece3f66c24ea89969bd16265a74910aaf08d775116191117416b8799d0984f452a6fba19623442a7f199ef1627f1ae7295963a67db5534a292f98edbfb419ed85756abe76cd2d2bff8eb9b848b1e7b80b8274bbc469a36dce58b48ae57be6312bca843463ac45c54122a9f3fa9dca124b0fd50bce300708549c77b81b031278b9d193464f5e4b14769f6018055a457a577c508e811bcf55b297df3509f3db7e66ec68451e25acfbf935200e246f71e3c48240d00020000000000000000000000000000000000000000000000000000000000000" + } +} diff --git a/portalnetwork/history/types.go b/portalnetwork/history/types.go index 336978967b..7798996139 100644 --- a/portalnetwork/history/types.go +++ b/portalnetwork/history/types.go @@ -1,10 +1,27 @@ package history +import ( + "errors" + + ssz "github.com/ferranbt/fastssz" +) + +//go:generate sszgen --path types.go --exclude-objs BlockHeaderProof + +type BlockHeaderProofType uint8 + +const ( + none BlockHeaderProofType = 0 + accumulatorProof BlockHeaderProofType = 1 +) + type HeaderRecord struct { BlockHash []byte `ssz-size:"32"` TotalDifficulty []byte `ssz-size:"32"` } - +type EpochAccumulator struct { + HeaderRecords [][]byte `ssz-size:"8192,64"` +} type BlockBodyLegacy struct { Transactions [][]byte `ssz-max:"16384,16777216"` Uncles []byte `ssz-max:"131072"` @@ -17,8 +34,8 @@ type PortalBlockBodyShanghai struct { } type BlockHeaderWithProof struct { - Header []byte `ssz-max:"8192"` - Proof []byte `ssz-max:"512"` + Header []byte `ssz-max:"8192"` + Proof *BlockHeaderProof `ssz-max:"512"` } type SSZProof struct { @@ -29,3 +46,63 @@ type SSZProof struct { type MasterAccumulator struct { HistoricalEpochs [][]byte `ssz-max:"1897,32" ssz-size:"?,32"` } + +// BlockHeaderProof is a ssz union type +// Union[None, AccumulatorProof] +type BlockHeaderProof struct { + Selector BlockHeaderProofType + Proof [][]byte `ssz-size:"15,32"` +} + +func (p *BlockHeaderProof) MarshalSSZ() ([]byte, error) { + return ssz.MarshalSSZ(p) +} + +func (p *BlockHeaderProof) MarshalSSZTo(buf []byte) (dst []byte, err error) { + return ssz.MarshalSSZ(p) +} + +func (p *BlockHeaderProof) UnmarshalSSZ(buf []byte) (err error) { + p.Selector = BlockHeaderProofType(buf[0]) + if p.Selector == none { + return + } + + if p.Selector != accumulatorProof { + return errors.New("unknown accumulatorProofType, shoud be 0x00 or 0x01") + } + + proofBytes := buf[1:] + + if len(proofBytes) != 32*15 { + return ssz.ErrBytesLengthFn("AccumulatorProof", len(proofBytes), 32*15) + } + proof := make([][]byte, 15) + + for i := 0; i < 15; i++ { + proof[i] = proofBytes[i*32 : (i+1)*32] + } + + p.Proof = AccumulatorProof(proof) + return +} + +func (p *BlockHeaderProof) SizeSSZ() (size int) { + size = 0 + + // Field (0) 'Selector' + size += 1 + + if p.Selector == none { + return size + } + + // Field (1) 'Proof' + size += 15 * 32 + + return size +} + +func (p *BlockHeaderProof) HashTreeRootWith(hh ssz.HashWalker) (err error) { + panic("implement me") +} diff --git a/portalnetwork/history/types_encoding.go b/portalnetwork/history/types_encoding.go index 4fd39adb38..8b591cc5a0 100644 --- a/portalnetwork/history/types_encoding.go +++ b/portalnetwork/history/types_encoding.go @@ -1,5 +1,5 @@ // Code generated by fastssz. DO NOT EDIT. -// Hash: e3ef9ad54d5a37e7d7a39c518f58dfad310dfc9218e4637043f4ea458dd89b91 +// Hash: e363d89d6737d1848b24978171e257d960f85a212d73a7dddcfa56d76800f527 // Version: 0.1.3 package history @@ -94,6 +94,92 @@ func (h *HeaderRecord) GetTree() (*ssz.Node, error) { return ssz.ProofTree(h) } +// MarshalSSZ ssz marshals the EpochAccumulator object +func (e *EpochAccumulator) MarshalSSZ() ([]byte, error) { + return ssz.MarshalSSZ(e) +} + +// MarshalSSZTo ssz marshals the EpochAccumulator object to a target array +func (e *EpochAccumulator) MarshalSSZTo(buf []byte) (dst []byte, err error) { + dst = buf + + // Field (0) 'HeaderRecords' + if size := len(e.HeaderRecords); size != 8192 { + err = ssz.ErrVectorLengthFn("EpochAccumulator.HeaderRecords", size, 8192) + return + } + for ii := 0; ii < 8192; ii++ { + if size := len(e.HeaderRecords[ii]); size != 64 { + err = ssz.ErrBytesLengthFn("EpochAccumulator.HeaderRecords[ii]", size, 64) + return + } + dst = append(dst, e.HeaderRecords[ii]...) + } + + return +} + +// UnmarshalSSZ ssz unmarshals the EpochAccumulator object +func (e *EpochAccumulator) UnmarshalSSZ(buf []byte) error { + var err error + size := uint64(len(buf)) + if size != 524288 { + return ssz.ErrSize + } + + // Field (0) 'HeaderRecords' + e.HeaderRecords = make([][]byte, 8192) + for ii := 0; ii < 8192; ii++ { + if cap(e.HeaderRecords[ii]) == 0 { + e.HeaderRecords[ii] = make([]byte, 0, len(buf[0:524288][ii*64:(ii+1)*64])) + } + e.HeaderRecords[ii] = append(e.HeaderRecords[ii], buf[0:524288][ii*64:(ii+1)*64]...) + } + + return err +} + +// SizeSSZ returns the ssz encoded size in bytes for the EpochAccumulator object +func (e *EpochAccumulator) SizeSSZ() (size int) { + size = 524288 + return +} + +// HashTreeRoot ssz hashes the EpochAccumulator object +func (e *EpochAccumulator) HashTreeRoot() ([32]byte, error) { + return ssz.HashWithDefaultHasher(e) +} + +// HashTreeRootWith ssz hashes the EpochAccumulator object with a hasher +func (e *EpochAccumulator) HashTreeRootWith(hh ssz.HashWalker) (err error) { + indx := hh.Index() + + // Field (0) 'HeaderRecords' + { + if size := len(e.HeaderRecords); size != 8192 { + err = ssz.ErrVectorLengthFn("EpochAccumulator.HeaderRecords", size, 8192) + return + } + subIndx := hh.Index() + for _, i := range e.HeaderRecords { + if len(i) != 64 { + err = ssz.ErrBytesLength + return + } + hh.PutBytes(i) + } + hh.Merkleize(subIndx) + } + + hh.Merkleize(indx) + return +} + +// GetTree ssz hashes the EpochAccumulator object +func (e *EpochAccumulator) GetTree() (*ssz.Node, error) { + return ssz.ProofTree(e) +} + // MarshalSSZ ssz marshals the BlockBodyLegacy object func (b *BlockBodyLegacy) MarshalSSZ() ([]byte, error) { return ssz.MarshalSSZ(b) @@ -558,7 +644,10 @@ func (b *BlockHeaderWithProof) MarshalSSZTo(buf []byte) (dst []byte, err error) // Offset (1) 'Proof' dst = ssz.WriteOffset(dst, offset) - offset += len(b.Proof) + if b.Proof == nil { + b.Proof = new(BlockHeaderProof) + } + offset += b.Proof.SizeSSZ() // Field (0) 'Header' if size := len(b.Header); size > 8192 { @@ -568,11 +657,9 @@ func (b *BlockHeaderWithProof) MarshalSSZTo(buf []byte) (dst []byte, err error) dst = append(dst, b.Header...) // Field (1) 'Proof' - if size := len(b.Proof); size > 512 { - err = ssz.ErrBytesLengthFn("BlockHeaderWithProof.Proof", size, 512) + if dst, err = b.Proof.MarshalSSZTo(dst); err != nil { return } - dst = append(dst, b.Proof...) return } @@ -617,13 +704,12 @@ func (b *BlockHeaderWithProof) UnmarshalSSZ(buf []byte) error { // Field (1) 'Proof' { buf = tail[o1:] - if len(buf) > 512 { - return ssz.ErrBytesLength + if b.Proof == nil { + b.Proof = new(BlockHeaderProof) } - if cap(b.Proof) == 0 { - b.Proof = make([]byte, 0, len(buf)) + if err = b.Proof.UnmarshalSSZ(buf); err != nil { + return err } - b.Proof = append(b.Proof, buf...) } return err } @@ -636,7 +722,10 @@ func (b *BlockHeaderWithProof) SizeSSZ() (size int) { size += len(b.Header) // Field (1) 'Proof' - size += len(b.Proof) + if b.Proof == nil { + b.Proof = new(BlockHeaderProof) + } + size += b.Proof.SizeSSZ() return } @@ -663,15 +752,8 @@ func (b *BlockHeaderWithProof) HashTreeRootWith(hh ssz.HashWalker) (err error) { } // Field (1) 'Proof' - { - elemIndx := hh.Index() - byteLen := uint64(len(b.Proof)) - if byteLen > 512 { - err = ssz.ErrIncorrectListSize - return - } - hh.Append(b.Proof) - hh.MerkleizeWithMixin(elemIndx, byteLen, (512+31)/32) + if err = b.Proof.HashTreeRootWith(hh); err != nil { + return } hh.Merkleize(indx) diff --git a/test.py b/test.py new file mode 100644 index 0000000000..a7a721828a --- /dev/null +++ b/test.py @@ -0,0 +1,22 @@ +def bitstring_to_bytes(bitstring): + # 创建一个长度为 (len(value) // 8) + 1 的数组,用于存储字节值,初始化为 0 + array = [0] * ((len(bitstring) // 8) + 1) + + # 遍历位数组 bitstring,将每个位的值设置到相应的字节中 + for i in range(len(bitstring)): + # 计算当前位在字节数组中的索引 + byte_index = i // 8 + + # 将当前位的值按位或到相应的字节上,通过左移 (i % 8) 位来设置对应的位置 + array[byte_index] |= int(bitstring[i]) << (i % 8) + print(array) + + # 将最后一个字节的最高位设置为 1 + array[len(bitstring) // 8] |= 1 << (len(bitstring) % 8) + print(array) + + # 将字节数组转换为 bytes 类型并返回 + return bytes(array) + + +bitstring_to_bytes("111100001011") \ No newline at end of file