Skip to content

Commit

Permalink
saving more progress
Browse files Browse the repository at this point in the history
  • Loading branch information
alecps committed Jan 7, 2025
1 parent 407e103 commit d7b3f80
Show file tree
Hide file tree
Showing 4 changed files with 134 additions and 93 deletions.
16 changes: 3 additions & 13 deletions op-chain-ops/cmd/celo-migrate/ancients.go
Original file line number Diff line number Diff line change
Expand Up @@ -121,19 +121,8 @@ func readAncientBlocks(ctx context.Context, freezer *rawdb.Freezer, startBlock,
return fmt.Errorf("failed to load ancient block range: %w", err)
}

// Check continuity between blocks
var prevElement *RLPBlockElement
for i := uint64(0); i < count; i++ {
currElement, err := blockRange.Element(i)
if err != nil {
return err
}
if prevElement != nil {
if err := currElement.Follows(prevElement); err != nil {
return err
}
}
prevElement = currElement
if err = blockRange.CheckContinuity(nil); err != nil {
return err
}

if start > 0 {
Expand Down Expand Up @@ -177,6 +166,7 @@ func loadAncientRange(freezer *rawdb.Freezer, start, count uint64) (*RLPBlockRan
return nil, fmt.Errorf("failed to read tds from old freezer: %w", err)
}

// TODO(Alec): Should this be moved to CheckContinuity?
// Make sure the number of elements retrieved from each table matches the expected length
if uint64(len(blockRange.hashes)) != count {
err = fmt.Errorf("Expected count mismatch in block range hashes: expected %d, actual %d", count, len(blockRange.hashes))
Expand Down
89 changes: 89 additions & 0 deletions op-chain-ops/cmd/celo-migrate/continuity.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,89 @@
package main

import (
"fmt"

"github.com/ethereum/go-ethereum/common"
"github.com/ethereum/go-ethereum/core/types"
"github.com/ethereum/go-ethereum/rlp"
)

// RLPBlockRange is a range of blocks in RLP format
type RLPBlockRange struct {
start uint64
hashes [][]byte
headers [][]byte
bodies [][]byte
receipts [][]byte
tds [][]byte
}

// RLPBlockElement contains all relevant block data in RLP format
type RLPBlockElement struct {
decodedHeader *types.Header
number uint64
hash []byte
header []byte // TODO(Alec): why this?
body []byte
receipts []byte
td []byte
}

func (r *RLPBlockRange) Element(i uint64) (*RLPBlockElement, error) {
header := types.Header{}
err := rlp.DecodeBytes(r.headers[i], &header)
if err != nil {
return nil, fmt.Errorf("can't decode header: %w", err)
}
return &RLPBlockElement{
decodedHeader: &header,
number: r.start + i, // TODO(Alec): how to use this?
hash: r.hashes[i],
header: r.headers[i],
body: r.bodies[i],
receipts: r.receipts[i],
td: r.tds[i],
}, nil
}

func (r *RLPBlockRange) DropFirst() {
r.start = r.start + 1
r.hashes = r.hashes[1:]
r.headers = r.headers[1:]
r.bodies = r.bodies[1:]
r.receipts = r.receipts[1:]
r.tds = r.tds[1:]
}

func (r *RLPBlockRange) CheckContinuity(prevElement *RLPBlockElement) error {
for i := range r.hashes { // TODO(Alec): what if there are different lengths?
currElement, err := r.Element(uint64(i))
if err != nil {
return err
}
if prevElement != nil {
if err := currElement.Follows(prevElement); err != nil {
return err
}
}
prevElement = currElement
}
return nil
}

func (e *RLPBlockElement) Follows(prev *RLPBlockElement) error {
if e.Header().Number.Uint64() != prev.Header().Number.Uint64()+1 {
return fmt.Errorf("header number mismatch: expected %d, actual %d", prev.Header().Number.Uint64()+1, e.Header().Number.Uint64())
}
// We compare the parent hash with the stored hash of the previous block because
// at this point the header object will not calculate the correct hash since it
// first needs to be transformed.
if e.Header().ParentHash != common.Hash(prev.hash) {
return fmt.Errorf("parent hash mismatch between blocks %d and %d", e.Header().Number.Uint64(), prev.Header().Number.Uint64())
}
return nil
}

func (e *RLPBlockElement) Header() *types.Header {
return e.decodedHeader
}
65 changes: 0 additions & 65 deletions op-chain-ops/cmd/celo-migrate/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -21,12 +21,10 @@ import (

"github.com/urfave/cli/v2"

"github.com/ethereum/go-ethereum/common"
"github.com/ethereum/go-ethereum/core/rawdb"
"github.com/ethereum/go-ethereum/core/types"
"github.com/ethereum/go-ethereum/ethclient"
"github.com/ethereum/go-ethereum/log"
"github.com/ethereum/go-ethereum/rlp"
"github.com/ethereum/go-ethereum/rpc"

"golang.org/x/sync/errgroup"
Expand Down Expand Up @@ -232,69 +230,6 @@ func main() {
}
}

// RLPBlockRange is a range of blocks in RLP format
type RLPBlockRange struct {
start uint64
hashes [][]byte
headers [][]byte
bodies [][]byte
receipts [][]byte
tds [][]byte
}

type RLPBlockElement struct {
decodedHeader *types.Header
number uint64
hash []byte
header []byte // TODO(Alec): why this?
body []byte
receipts []byte
td []byte
}

func (r *RLPBlockRange) Element(i uint64) (*RLPBlockElement, error) {
header := types.Header{}
err := rlp.DecodeBytes(r.headers[i], &header)
if err != nil {
return nil, fmt.Errorf("can't decode header: %w", err)
}
return &RLPBlockElement{
decodedHeader: &header,
number: r.start + i, // TODO(Alec): how to use this?
hash: r.hashes[i],
header: r.headers[i],
body: r.bodies[i],
receipts: r.receipts[i],
td: r.tds[i],
}, nil
}

func (r *RLPBlockRange) DropFirst() {
r.start = r.start + 1
r.hashes = r.hashes[1:]
r.headers = r.headers[1:]
r.bodies = r.bodies[1:]
r.receipts = r.receipts[1:]
r.tds = r.tds[1:]
}

func (e *RLPBlockElement) Header() *types.Header {
return e.decodedHeader
}

func (e *RLPBlockElement) Follows(prev *RLPBlockElement) error {
if e.Header().Number.Uint64() != prev.Header().Number.Uint64()+1 {
return fmt.Errorf("header number mismatch: expected %d, actual %d", prev.Header().Number.Uint64()+1, e.Header().Number.Uint64())
}
// We compare the parent hash with the stored hash of the previous block because
// at this point the header object will not calculate the correct hash since it
// first needs to be transformed.
if e.Header().ParentHash != common.Hash(prev.hash) {
return fmt.Errorf("parent hash mismatch between blocks %d and %d", e.Header().Number.Uint64(), prev.Header().Number.Uint64())
}
return nil
}

func runFullMigration(opts fullMigrationOptions) error {
defer timer("full migration")()

Expand Down
57 changes: 42 additions & 15 deletions op-chain-ops/cmd/celo-migrate/non-ancients.go
Original file line number Diff line number Diff line change
Expand Up @@ -87,26 +87,25 @@ func migrateNonAncientsDb(newDB ethdb.Database, lastBlock, numAncients, batchSiz

prevBlockElement := lastAncient
for i := numAncients; i <= lastBlock; i += batchSize {
numbersHash := rawdb.ReadAllHashesInRange(newDB, i, i+batchSize-1) // TODO(Alec)
blockRange, err := loadNonAncientRange(newDB, i, batchSize)
if err != nil {
return 0, err
}

log.Info("Processing Block Range", "process", "non-ancients", "from", i, "to(inclusve)", i+batchSize-1, "count", len(numbersHash))
for _, numberHash := range numbersHash {
log.Info("Processing Block Range", "process", "non-ancients", "from", i, "to(inclusve)", i+batchSize-1, "count", len(blockRange.hashes))

blockElement, err := readRLPBlockElement(newDB, numberHash.Number, numberHash.Hash)
if err != nil {
return 0, fmt.Errorf("failed to read RLP block element for non-ancient block %d - %x: %w", numberHash.Number, numberHash.Hash, err)
}
if err := blockRange.CheckContinuity(prevBlockElement); err != nil {
return 0, fmt.Errorf("failed continuity check for non-ancient blocks: %w", err)
}

if prevBlockElement != nil {
if err := blockElement.Follows(prevBlockElement); err != nil {
return 0, err
}
for i := range blockRange.hashes {
blockElement, err := blockRange.Element(uint64(i))
if err != nil {
return 0, err
}

if err := migrateNonAncientBlock(newDB, blockElement); err != nil {
return 0, fmt.Errorf("failed to migrate non-ancient block %d - %x: %w", numberHash.Number, numberHash.Hash, err)
if err = migrateNonAncientBlock(newDB, blockElement); err != nil {
return 0, err
}

prevBlockElement = blockElement
}
}
Expand All @@ -115,6 +114,34 @@ func migrateNonAncientsDb(newDB ethdb.Database, lastBlock, numAncients, batchSiz
return migratedCount, nil
}

func loadNonAncientRange(newDB ethdb.Database, start, count uint64) (*RLPBlockRange, error) {
blockRange := &RLPBlockRange{
start: start,
hashes: make([][]byte, count),
headers: make([][]byte, count),
bodies: make([][]byte, count),
receipts: make([][]byte, count),
tds: make([][]byte, count),
}

numbersHash := rawdb.ReadAllHashesInRange(newDB, start, start+count-1) // minus 1 because start is included in count

for i, numberHash := range numbersHash {
blockElement, err := readRLPBlockElement(newDB, numberHash.Number, numberHash.Hash)
if err != nil {
return nil, fmt.Errorf("failed to read RLP block element for non-ancient block %d - %x: %w", numberHash.Number, numberHash.Hash, err)
}

blockRange.hashes[i] = blockElement.hash
blockRange.headers[i] = blockElement.header
blockRange.bodies[i] = blockElement.body
blockRange.receipts[i] = blockElement.receipts
blockRange.tds[i] = blockElement.td
}

return blockRange, nil
}

func migrateNonAncientBlock(newDB ethdb.Database, block *RLPBlockElement) error {
// transform header and body
newHeader, err := transformHeader(block.header)
Expand Down

0 comments on commit d7b3f80

Please sign in to comment.