Skip to content

Commit d280f37

Browse files
authored
feat: rely on the block store solely to generate QGB commitments (#1020)
* feat: rely on the block store solely to generate QGB commitments * Update rpc/core/blocks.go
1 parent 904ca9e commit d280f37

File tree

1 file changed

+57
-42
lines changed

1 file changed

+57
-42
lines changed

rpc/core/blocks.go

Lines changed: 57 additions & 42 deletions
Original file line numberDiff line numberDiff line change
@@ -182,20 +182,19 @@ func DataCommitment(ctx *rpctypes.Context, start, end uint64) (*ctypes.ResultDat
182182
if err != nil {
183183
return nil, err
184184
}
185-
heights := generateHeightsList(start, end)
186-
blockResults := fetchBlocks(heights, len(heights), 0)
187-
if len(blockResults) != len(heights) {
188-
return nil, fmt.Errorf("couldn't fetch all the blocks in the provided range")
185+
tuples, err := fetchDataRootTuples(start, end)
186+
if err != nil {
187+
return nil, err
189188
}
190-
root, err := hashDataRootTuples(blockResults)
189+
root, err := hashDataRootTuples(tuples)
191190
if err != nil {
192191
return nil, err
193192
}
194193
// Create data commitment
195194
return &ctypes.ResultDataCommitment{DataCommitment: root}, nil
196195
}
197196

198-
// DataRootInclusionProof creates an inclusion proof of the data root of block
197+
// DataRootInclusionProof creates an inclusion proof for the data root of block
199198
// height `height` in the set of blocks defined by `start` and `end`. The range
200199
// is end exclusive.
201200
func DataRootInclusionProof(
@@ -208,12 +207,11 @@ func DataRootInclusionProof(
208207
if err != nil {
209208
return nil, err
210209
}
211-
heights := generateHeightsList(start, end)
212-
blockResults := fetchBlocks(heights, len(heights), 0)
213-
if len(blockResults) != len(heights) {
214-
return nil, fmt.Errorf("couldn't fetch all the blocks in the provided range")
210+
tuples, err := fetchDataRootTuples(start, end)
211+
if err != nil {
212+
return nil, err
215213
}
216-
proof, err := proveDataRootTuples(blockResults, height)
214+
proof, err := proveDataRootTuples(tuples, height)
217215
if err != nil {
218216
return nil, err
219217
}
@@ -260,6 +258,15 @@ func To32PaddedHexBytes(number uint64) ([]byte, error) {
260258
return paddedBytes, nil
261259
}
262260

261+
// DataRootTuple contains the data that will be used to create the QGB commitments.
262+
// The commitments will be signed by orchestrators and submitted to an EVM chain via a relayer.
263+
// For more information: https://github.com/celestiaorg/quantum-gravity-bridge/blob/master/src/DataRootTuple.sol
264+
type DataRootTuple struct {
265+
height uint64
266+
dataRoot [32]byte
267+
squareSize uint64
268+
}
269+
263270
// EncodeDataRootTuple takes a height, a data root and the square size, and returns the equivalent of
264271
// `abi.encode(...)` in Ethereum.
265272
// The encoded type is a DataRootTuple, which has the following ABI:
@@ -306,16 +313,6 @@ func EncodeDataRootTuple(height uint64, dataRoot [32]byte, squareSize uint64) ([
306313
return append(paddedHeight, append(dataSlice, paddedSquareSize...)...), nil
307314
}
308315

309-
// generateHeightsList takes a begin and end block, then generates a list of heights
310-
// containing the elements of the range [beginBlock, endBlock].
311-
func generateHeightsList(beginBlock uint64, endBlock uint64) []int64 {
312-
heights := make([]int64, endBlock-beginBlock)
313-
for i := beginBlock; i < endBlock; i++ {
314-
heights[i-beginBlock] = int64(i)
315-
}
316-
return heights
317-
}
318-
319316
// validateDataCommitmentRange runs basic checks on the asc sorted list of
320317
// heights that will be used subsequently in generating data commitments over
321318
// the defined set of heights.
@@ -341,24 +338,19 @@ func validateDataCommitmentRange(start uint64, end uint64) error {
341338
env.BlockStore.Height(),
342339
)
343340
}
344-
has, err := env.BlockIndexer.Has(int64(end))
345-
if err != nil {
346-
return err
347-
}
348-
if !has {
349-
return fmt.Errorf(
350-
"last block %d is still not indexed",
351-
end,
352-
)
353-
}
354341
return nil
355342
}
356343

357-
// hashDataRootTuples hashes a list of blocks data root tuples, i.e. height and data root, and returns their merkle root.
358-
func hashDataRootTuples(blocks []*ctypes.ResultBlock) ([]byte, error) {
359-
dataRootEncodedTuples := make([][]byte, 0, len(blocks))
360-
for _, block := range blocks {
361-
encodedTuple, err := EncodeDataRootTuple(uint64(block.Block.Height), *(*[32]byte)(block.Block.DataHash), block.Block.SquareSize)
344+
// hashDataRootTuples hashes a list of blocks data root tuples, i.e. height, data root and square size,
345+
// then returns their merkle root.
346+
func hashDataRootTuples(tuples []DataRootTuple) ([]byte, error) {
347+
dataRootEncodedTuples := make([][]byte, 0, len(tuples))
348+
for _, tuple := range tuples {
349+
encodedTuple, err := EncodeDataRootTuple(
350+
tuple.height,
351+
tuple.dataRoot,
352+
tuple.squareSize,
353+
)
362354
if err != nil {
363355
return nil, err
364356
}
@@ -377,7 +369,7 @@ func validateDataRootInclusionProofRequest(height uint64, start uint64, end uint
377369
}
378370
if height < start || height >= end {
379371
return fmt.Errorf(
380-
"height %d should be in the interval first_block %d last_block %d",
372+
"height %d should be in the end exclusive interval first_block %d last_block %d",
381373
height,
382374
start,
383375
end,
@@ -387,17 +379,21 @@ func validateDataRootInclusionProofRequest(height uint64, start uint64, end uint
387379
}
388380

389381
// proveDataRootTuples returns the merkle inclusion proof for a height.
390-
func proveDataRootTuples(blocks []*ctypes.ResultBlock, height int64) (*merkle.Proof, error) {
391-
dataRootEncodedTuples := make([][]byte, 0, len(blocks))
392-
for _, block := range blocks {
393-
encodedTuple, err := EncodeDataRootTuple(uint64(block.Block.Height), *(*[32]byte)(block.Block.DataHash), block.Block.SquareSize)
382+
func proveDataRootTuples(tuples []DataRootTuple, height int64) (*merkle.Proof, error) {
383+
dataRootEncodedTuples := make([][]byte, 0, len(tuples))
384+
for _, tuple := range tuples {
385+
encodedTuple, err := EncodeDataRootTuple(
386+
tuple.height,
387+
tuple.dataRoot,
388+
tuple.squareSize,
389+
)
394390
if err != nil {
395391
return nil, err
396392
}
397393
dataRootEncodedTuples = append(dataRootEncodedTuples, encodedTuple)
398394
}
399395
_, proofs := merkle.ProofsFromByteSlices(dataRootEncodedTuples)
400-
return proofs[height-blocks[0].Block.Height], nil
396+
return proofs[height-int64(tuples[0].height)], nil
401397
}
402398

403399
// BlockResults gets ABCIResults at a given height.
@@ -525,3 +521,22 @@ func fetchBlocks(results []int64, pageSize int, skipCount int) []*ctypes.ResultB
525521
}
526522
return apiResults
527523
}
524+
525+
// fetchDataRootTuples takes an end exclusive range of heights and fetches its
526+
// corresponding data root tuples.
527+
func fetchDataRootTuples(start, end uint64) ([]DataRootTuple, error) {
528+
env := GetEnvironment()
529+
tuples := make([]DataRootTuple, 0, end-start)
530+
for height := start; height < end; height++ {
531+
block := env.BlockStore.LoadBlock(int64(height))
532+
if block == nil {
533+
return nil, fmt.Errorf("couldn't load block %d", height)
534+
}
535+
tuples = append(tuples, DataRootTuple{
536+
height: uint64(block.Height),
537+
dataRoot: *(*[32]byte)(block.DataHash),
538+
squareSize: block.SquareSize,
539+
})
540+
}
541+
return tuples, nil
542+
}

0 commit comments

Comments
 (0)