Skip to content

Commit

Permalink
debug rpc: debug_setL1Head and better l1 timestamp management (ethere…
Browse files Browse the repository at this point in the history
…um#184)

* debug rpc: debug_setL1Head and better l1 timestamp management

* tests: add

* rollup: set l1 head fix

* rpc: fix set l1 head

* build: fix

* test: unbreak
  • Loading branch information
tynes authored Jan 13, 2021
1 parent 4d8f7ba commit f7326de
Show file tree
Hide file tree
Showing 5 changed files with 64 additions and 1 deletion.
31 changes: 30 additions & 1 deletion eth/api_backend.go
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,7 @@ import (
"github.com/ethereum/go-ethereum/eth/gasprice"
"github.com/ethereum/go-ethereum/ethdb"
"github.com/ethereum/go-ethereum/event"
"github.com/ethereum/go-ethereum/log"
"github.com/ethereum/go-ethereum/params"
"github.com/ethereum/go-ethereum/rpc"
)
Expand Down Expand Up @@ -104,8 +105,36 @@ func (b *EthAPIBackend) GetDiff(block *big.Int) (diffdb.Diff, error) {
}

func (b *EthAPIBackend) SetHead(number uint64) {
b.eth.protocolManager.downloader.Cancel()
if number == 0 {
log.Info("Cannot reset to genesis")
return
}
if !b.UsingOVM {
b.eth.protocolManager.downloader.Cancel()
}
b.eth.blockchain.SetHead(number)

// Make sure to reset the LatestL1{Timestamp,BlockNumber}
block := b.eth.blockchain.CurrentBlock()
txs := block.Transactions()
if len(txs) == 0 {
log.Error("No transactions found in block", "number", number)
return
}

tx := txs[0]
blockNumber := tx.L1BlockNumber()
if blockNumber == nil {
log.Error("No L1BlockNumber found in transaction", "number", number)
return
}

b.eth.syncService.SetLatestL1Timestamp(tx.L1Timestamp())
b.eth.syncService.SetLatestL1BlockNumber(blockNumber.Uint64())
}

func (b *EthAPIBackend) SetL1Head(number uint64) error {
return b.eth.syncService.SetL1Head(number)
}

func (b *EthAPIBackend) HeaderByNumber(ctx context.Context, number rpc.BlockNumber) (*types.Header, error) {
Expand Down
4 changes: 4 additions & 0 deletions internal/ethapi/api.go
Original file line number Diff line number Diff line change
Expand Up @@ -1966,6 +1966,10 @@ func (api *PrivateDebugAPI) SetHead(number hexutil.Uint64) {
api.b.SetHead(uint64(number))
}

func (api *PrivateDebugAPI) SetL1Head(number hexutil.Uint64) {
api.b.SetL1Head(uint64(number))
}

// PublicNetAPI offers network related RPC methods
type PublicNetAPI struct {
net *p2p.Server
Expand Down
1 change: 1 addition & 0 deletions internal/ethapi/backend.go
Original file line number Diff line number Diff line change
Expand Up @@ -92,6 +92,7 @@ type Backend interface {
GetRollupContractAddresses() map[string]*common.Address
GetLatestL1BlockNumber() uint64
GetLatestL1Timestamp() uint64
SetL1Head(number uint64) error

ChainConfig() *params.ChainConfig
CurrentBlock() *types.Block
Expand Down
4 changes: 4 additions & 0 deletions les/api_backend.go
Original file line number Diff line number Diff line change
Expand Up @@ -91,6 +91,10 @@ func (b *LesApiBackend) SetHead(number uint64) {
b.eth.blockchain.SetHead(number)
}

func (b *LesApiBackend) SetL1Head(number uint64) error {
panic("unimplemented")
}

func (b *LesApiBackend) HeaderByNumber(ctx context.Context, number rpc.BlockNumber) (*types.Header, error) {
if number == rpc.LatestBlockNumber || number == rpc.PendingBlockNumber {
return b.eth.blockchain.CurrentHeader(), nil
Expand Down
25 changes: 25 additions & 0 deletions rollup/sync_service.go
Original file line number Diff line number Diff line change
Expand Up @@ -1286,6 +1286,31 @@ func (s *SyncService) SubscribeNewTxsEvent(ch chan<- core.NewTxsEvent) event.Sub
return s.scope.Track(s.txFeed.Subscribe(ch))
}

// SetL1Head resets the Eth1Data
// and the LatestL1BlockNumber and LatestL1Timestamp
func (s *SyncService) SetL1Head(number uint64) error {
header, err := s.ethclient.HeaderByNumber(s.ctx, new(big.Int).SetUint64(number))
if err != nil {
return fmt.Errorf("Cannot fetch block in SetL1Head: %w", err)
}

// Reset the header cache
for i := 0; i < len(s.HeaderCache); i++ {
s.HeaderCache[i] = nil
}

// Reset the last synced L1 heights
rawdb.WriteHeadEth1HeaderHash(s.db, header.Hash())
rawdb.WriteHeadEth1HeaderHeight(s.db, header.Number.Uint64())
s.HeaderCache[number%headerCacheSize] = header

s.Eth1Data = Eth1Data{
BlockHeight: header.Number.Uint64(),
BlockHash: header.Hash(),
}
return nil
}

// Adds the transaction to the mempool so that downstream services
// can apply it to the state. This should directly play against
// the state eventually, skipping the mempool.
Expand Down

0 comments on commit f7326de

Please sign in to comment.