Skip to content

Commit 0e1b4a1

Browse files
authored
Merge pull request #3 from astriaorg/bharath/implement-optimistic-fork-creation
feat: Trusted auctioneer: Maintain a separate optimistic block fork
2 parents 4eb1eee + 2e26e91 commit 0e1b4a1

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

50 files changed

+5637
-1030
lines changed

.github/workflows/astria-build-and-publish-image.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -72,4 +72,4 @@ jobs:
7272
push: true
7373
tags: ${{ steps.metadata.outputs.tags }}
7474
labels: ${{ steps.metadata.outputs.labels }}
75-
project: w2d6w0spqz
75+
project: w2d6w0spqz

cmd/devp2p/internal/ethtest/suite_test.go

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -61,6 +61,7 @@ func TestEthSuite(t *testing.T) {
6161
if err != nil {
6262
t.Fatalf("could not create new test suite: %v", err)
6363
}
64+
6465
for _, test := range suite.EthTests() {
6566
t.Run(test.Name, func(t *testing.T) {
6667
if test.Slow && testing.Short() {
@@ -149,5 +150,6 @@ func setupGeth(stack *node.Node, dir string) error {
149150
return fmt.Errorf("failed to register catalyst service: %v", err)
150151
}
151152
_, err = backend.BlockChain().InsertChain(chain.blocks[1:])
153+
backend.BlockChain().SetOptimistic(chain.blocks[len(chain.blocks)-1])
152154
return err
153155
}

cmd/geth/config.go

Lines changed: 10 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,8 @@ import (
2121
"errors"
2222
"fmt"
2323
"github.com/ethereum/go-ethereum/eth/catalyst"
24+
"github.com/ethereum/go-ethereum/grpc/optimistic"
25+
"github.com/ethereum/go-ethereum/grpc/shared"
2426
"os"
2527
"reflect"
2628
"runtime"
@@ -206,11 +208,16 @@ func makeFullNode(ctx *cli.Context) *node.Node {
206208

207209
// Configure gRPC if requested.
208210
if ctx.IsSet(utils.GRPCEnabledFlag.Name) {
209-
serviceV1, err := execution.NewExecutionServiceServerV1(eth)
211+
sharedService, err := shared.NewSharedServiceContainer(eth)
210212
if err != nil {
211-
utils.Fatalf("failed to create execution service: %v", err)
213+
utils.Fatalf("failed to create shared service container: %v", err)
212214
}
213-
utils.RegisterGRPCExecutionService(stack, serviceV1, &cfg.Node)
215+
216+
serviceV1a2 := execution.NewExecutionServiceServerV1(sharedService)
217+
218+
optimisticServiceV1a1 := optimistic.NewOptimisticServiceV1Alpha(sharedService)
219+
220+
utils.RegisterGRPCServices(stack, serviceV1a2, optimisticServiceV1a1, optimisticServiceV1a1, &cfg.Node)
214221
}
215222

216223
// Add the Ethereum Stats daemon if requested.

cmd/geth/main.go

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -123,6 +123,7 @@ var (
123123
utils.MinerRecommitIntervalFlag,
124124
utils.MinerPendingFeeRecipientFlag,
125125
utils.MinerNewPayloadTimeoutFlag, // deprecated
126+
utils.AuctioneerEnabledFlag,
126127
utils.NATFlag,
127128
utils.NoDiscoverFlag,
128129
utils.DiscoveryV4Flag,

cmd/utils/flags.go

Lines changed: 17 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@
1818
package utils
1919

2020
import (
21+
optimisticGrpc "buf.build/gen/go/astria/execution-apis/grpc/go/astria/auction/v1alpha1/auctionv1alpha1grpc"
2122
"context"
2223
"crypto/ecdsa"
2324
"encoding/hex"
@@ -769,6 +770,13 @@ var (
769770
Category: flags.APICategory,
770771
}
771772

773+
// auctioneer
774+
AuctioneerEnabledFlag = &cli.BoolFlag{
775+
Name: "auctioneer",
776+
Usage: "Enable the auctioneer server",
777+
Category: flags.MinerCategory,
778+
}
779+
772780
// Network Settings
773781
MaxPeersFlag = &cli.IntFlag{
774782
Name: "maxpeers",
@@ -1438,6 +1446,12 @@ func SetNodeConfig(ctx *cli.Context, cfg *node.Config) {
14381446
SetDataDir(ctx, cfg)
14391447
setSmartCard(ctx, cfg)
14401448

1449+
if ctx.Bool(AuctioneerEnabledFlag.Name) {
1450+
cfg.EnableAuctioneer = true
1451+
} else {
1452+
cfg.EnableAuctioneer = false
1453+
}
1454+
14411455
if ctx.IsSet(JWTSecretFlag.Name) {
14421456
cfg.JWTSecret = ctx.String(JWTSecretFlag.Name)
14431457
}
@@ -1987,10 +2001,10 @@ func RegisterGraphQLService(stack *node.Node, backend ethapi.Backend, filterSyst
19872001
}
19882002
}
19892003

1990-
// RegisterGRPCExecutionService adds the gRPC API to the node.
2004+
// RegisterGRPCServices adds the gRPC API to the node.
19912005
// It was done this way so that our grpc execution server can access the ethapi.Backend
1992-
func RegisterGRPCExecutionService(stack *node.Node, execServ astriaGrpc.ExecutionServiceServer, cfg *node.Config) {
1993-
if err := node.NewGRPCServerHandler(stack, execServ, cfg); err != nil {
2006+
func RegisterGRPCServices(stack *node.Node, execServ astriaGrpc.ExecutionServiceServer, optimisticExecutionServ optimisticGrpc.OptimisticExecutionServiceServer, auctionServiceServer optimisticGrpc.AuctionServiceServer, cfg *node.Config) {
2007+
if err := node.NewGRPCServerHandler(stack, execServ, optimisticExecutionServ, auctionServiceServer, cfg); err != nil {
19942008
Fatalf("Failed to register the gRPC service: %v", err)
19952009
}
19962010
}

core/blockchain.go

Lines changed: 36 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -54,11 +54,12 @@ import (
5454
)
5555

5656
var (
57-
headBlockGauge = metrics.NewRegisteredGauge("chain/head/block", nil)
58-
headHeaderGauge = metrics.NewRegisteredGauge("chain/head/header", nil)
59-
headFastBlockGauge = metrics.NewRegisteredGauge("chain/head/receipt", nil)
60-
headFinalizedBlockGauge = metrics.NewRegisteredGauge("chain/head/finalized", nil)
61-
headSafeBlockGauge = metrics.NewRegisteredGauge("chain/head/safe", nil)
57+
headBlockGauge = metrics.NewRegisteredGauge("chain/head/block", nil)
58+
headHeaderGauge = metrics.NewRegisteredGauge("chain/head/header", nil)
59+
headFastBlockGauge = metrics.NewRegisteredGauge("chain/head/receipt", nil)
60+
headFinalizedBlockGauge = metrics.NewRegisteredGauge("chain/head/finalized", nil)
61+
headSafeBlockGauge = metrics.NewRegisteredGauge("chain/head/safe", nil)
62+
headOptimisticBlockGauge = metrics.NewRegisteredGauge("chain/head/optimistic", nil)
6263

6364
chainInfoGauge = metrics.NewRegisteredGaugeInfo("chain/info", nil)
6465

@@ -219,24 +220,26 @@ type BlockChain struct {
219220
stateCache state.Database // State database to reuse between imports (contains state cache)
220221
txIndexer *txIndexer // Transaction indexer, might be nil if not enabled
221222

222-
hc *HeaderChain
223-
rmLogsFeed event.Feed
224-
chainFeed event.Feed
225-
chainSideFeed event.Feed
226-
chainHeadFeed event.Feed
227-
logsFeed event.Feed
228-
blockProcFeed event.Feed
229-
scope event.SubscriptionScope
230-
genesisBlock *types.Block
223+
hc *HeaderChain
224+
rmLogsFeed event.Feed
225+
chainFeed event.Feed
226+
chainSideFeed event.Feed
227+
chainHeadFeed event.Feed
228+
chainOptimisticHeadFeed event.Feed
229+
logsFeed event.Feed
230+
blockProcFeed event.Feed
231+
scope event.SubscriptionScope
232+
genesisBlock *types.Block
231233

232234
// This mutex synchronizes chain write operations.
233235
// Readers don't need to take it, they can just read the database.
234236
chainmu *syncx.ClosableMutex
235237

236-
currentBlock atomic.Pointer[types.Header] // Current head of the chain
237-
currentSnapBlock atomic.Pointer[types.Header] // Current head of snap-sync
238-
currentFinalBlock atomic.Pointer[types.Header] // Latest (consensus) finalized block
239-
currentSafeBlock atomic.Pointer[types.Header] // Latest (consensus) safe block
238+
currentBlock atomic.Pointer[types.Header] // Current head of the chain
239+
currentSnapBlock atomic.Pointer[types.Header] // Current head of snap-sync
240+
currentFinalBlock atomic.Pointer[types.Header] // Latest (consensus) finalized block
241+
currentSafeBlock atomic.Pointer[types.Header] // Latest (consensus) safe block
242+
currentOptimisticBlock atomic.Pointer[types.Header] // Latest optimistic block
240243

241244
currentBaseCelestiaHeight atomic.Uint64 // Latest finalized block height on Celestia
242245

@@ -325,6 +328,7 @@ func NewBlockChain(db ethdb.Database, cacheConfig *CacheConfig, genesis *Genesis
325328
bc.currentBlock.Store(bc.genesisBlock.Header())
326329
bc.currentFinalBlock.Store(bc.genesisBlock.Header())
327330
bc.currentSafeBlock.Store(bc.genesisBlock.Header())
331+
bc.currentOptimisticBlock.Store(bc.genesisBlock.Header())
328332
bc.currentBaseCelestiaHeight.Store(bc.Config().AstriaCelestiaInitialHeight)
329333

330334
// Update chain info data metrics
@@ -532,6 +536,7 @@ func (bc *BlockChain) loadLastState() error {
532536
bc.currentFinalBlock.Store(block.Header())
533537
headFinalizedBlockGauge.Update(int64(block.NumberU64()))
534538
bc.currentSafeBlock.Store(block.Header())
539+
bc.currentOptimisticBlock.Store(block.Header())
535540
headSafeBlockGauge.Update(int64(block.NumberU64()))
536541
}
537542
}
@@ -639,6 +644,19 @@ func (bc *BlockChain) SetSafe(header *types.Header) {
639644
}
640645
}
641646

647+
// SetOptimistic sets the optimistic block.
648+
func (bc *BlockChain) SetOptimistic(block *types.Block) {
649+
header := block.Header()
650+
bc.currentOptimisticBlock.Store(header)
651+
if header != nil {
652+
headOptimisticBlockGauge.Update(int64(header.Number.Uint64()))
653+
} else {
654+
headOptimisticBlockGauge.Update(0)
655+
}
656+
657+
bc.chainOptimisticHeadFeed.Send(ChainOptimisticHeadEvent{Block: block})
658+
}
659+
642660
// rewindHashHead implements the logic of rewindHead in the context of hash scheme.
643661
func (bc *BlockChain) rewindHashHead(head *types.Header, root common.Hash) (*types.Header, uint64) {
644662
var (

core/blockchain_reader.go

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -63,6 +63,12 @@ func (bc *BlockChain) CurrentSafeBlock() *types.Header {
6363
return bc.currentSafeBlock.Load()
6464
}
6565

66+
// CurrentOptimisticBlock retrieves the current optimistic block of the canonical
67+
// chain. The block is retrieved from the blockchain's internal cache.
68+
func (bc *BlockChain) CurrentOptimisticBlock() *types.Header {
69+
return bc.currentOptimisticBlock.Load()
70+
}
71+
6672
// CurrentBaseCelestiaHeight retrieves the current base celestia height of the
6773
// canonical chain. The height is retrieved from the blockchain's internal cache.
6874
func (bc *BlockChain) CurrentBaseCelestiaHeight() uint64 {
@@ -439,6 +445,11 @@ func (bc *BlockChain) SubscribeChainHeadEvent(ch chan<- ChainHeadEvent) event.Su
439445
return bc.scope.Track(bc.chainHeadFeed.Subscribe(ch))
440446
}
441447

448+
// SubscribeChainOptimisticHeadEvent registers a subscription of ChainOptimisticHeadEvent.
449+
func (bc *BlockChain) SubscribeChainOptimisticHeadEvent(ch chan<- ChainOptimisticHeadEvent) event.Subscription {
450+
return bc.scope.Track(bc.chainOptimisticHeadFeed.Subscribe(ch))
451+
}
452+
442453
// SubscribeChainSideEvent registers a subscription of ChainSideEvent.
443454
func (bc *BlockChain) SubscribeChainSideEvent(ch chan<- ChainSideEvent) event.Subscription {
444455
return bc.scope.Track(bc.chainSideFeed.Subscribe(ch))

core/events.go

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,12 @@ import (
2424
// NewTxsEvent is posted when a batch of transactions enter the transaction pool.
2525
type NewTxsEvent struct{ Txs []*types.Transaction }
2626

27+
// NewMempoolClearedEvent is posted when the mempool is cleared after a head reset for trusted auctioneer
28+
type NewMempoolCleared struct {
29+
// the new head to which the mempool state was reset to before clearing the mempool
30+
NewHead *types.Header
31+
}
32+
2733
// NewMinedBlockEvent is posted when a block has been imported.
2834
type NewMinedBlockEvent struct{ Block *types.Block }
2935

@@ -41,3 +47,7 @@ type ChainSideEvent struct {
4147
}
4248

4349
type ChainHeadEvent struct{ Block *types.Block }
50+
51+
type ChainOptimisticHeadEvent struct {
52+
Block *types.Block
53+
}

core/txpool/blobpool/blobpool.go

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -339,6 +339,7 @@ func (p *BlobPool) ClearAstriaOrdered() {}
339339
func (p *BlobPool) AddToAstriaExcludedFromBlock(*types.Transaction) {}
340340
func (p *BlobPool) AstriaExcludedFromBlock() *types.Transactions { return &types.Transactions{} }
341341
func (p *BlobPool) AstriaOrdered() *types.Transactions { return &types.Transactions{} }
342+
func (p *BlobPool) ValidateTx(tx *types.Transaction) error { return nil }
342343

343344
// Filter returns whether the given transaction can be consumed by the blob pool.
344345
func (p *BlobPool) Filter(tx *types.Transaction) bool {
@@ -1601,6 +1602,10 @@ func (p *BlobPool) SubscribeTransactions(ch chan<- core.NewTxsEvent, reorgs bool
16011602
}
16021603
}
16031604

1605+
func (p *BlobPool) SubscribeMempoolClearance(ch chan<- core.NewMempoolCleared) event.Subscription {
1606+
return nil
1607+
}
1608+
16041609
// Nonce returns the next nonce of an account, with all transactions executable
16051610
// by the pool already applied on top.
16061611
func (p *BlobPool) Nonce(addr common.Address) uint64 {

0 commit comments

Comments
 (0)