Skip to content

Commit a2cbf90

Browse files
davidtaikochamask-ppcyberhorsey
authored
feat(beacon): introduce soft blocks (ethereum#342)
* feat(beacon): introduce soft blocks * feat: update api.go * chore(ci): update CI * feat: update L1Origin * feat: update `verifyHeader` * test: update tests * feat: update consensus * feat: update consensus * feat: update genesis * feat: remove timestamp check in prepareWork * feat: merge changes in ethereum#281 * Update eth/catalyst/api.go Co-authored-by: maskpp <maskpp266@gmail.com> * Update internal/ethapi/taiko_preconf.go Co-authored-by: maskpp <maskpp266@gmail.com> * fix consensus test * revert commit f1df58 * fix consensus test (ethereum#349) * Update eth/catalyst/api.go Co-authored-by: maskpp <maskpp266@gmail.com> * feat: add back timestamp check in worker * add genesis * temp fix for old l1origin * nil value * feat: rename to `L1OriginLegacy` * feat: change `common.Big0` as the default value for legacy l1Origin, to make `IsSoftblock` return `false` * feat(beacon): change the reorg log level (ethereum#350) * use debug log level to avoid logging too many logs when frequently soft block reorg. * use debug log level to avoid logging too many logs when frequently soft block reorg. * feat: check --taiko flag --------- Co-authored-by: David <david@taiko.xyz> * add rlp optional flag (ethereum#353) * fix lint * fix test case * feat(l1Origin): remove the reverted l1Origins (ethereum#355) * remove the reverted l1Origins * feat: add more comments --------- Co-authored-by: David <david@taiko.xyz> * only forward txs * chore: update ci --------- Co-authored-by: maskpp <maskpp266@gmail.com> Co-authored-by: Jeffery Walsh <cyberhorsey@gmail.com>
1 parent 5ef7421 commit a2cbf90

26 files changed

+562
-79
lines changed

.github/workflows/docker.yml

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ name: "Push multi-arch docker image to GAR"
22

33
on:
44
push:
5-
branches: [ taiko ]
5+
branches: [taiko]
66
tags:
77
- "v*"
88

@@ -19,9 +19,9 @@ jobs:
1919
platform: linux/amd64
2020
- runner: arc-runner-set-arm64
2121
platform: linux/arm64
22-
22+
2323
runs-on: ${{ matrix.runner }}
24-
24+
2525
steps:
2626
- name: Prepare Environment
2727
run: |
@@ -80,7 +80,7 @@ jobs:
8080
with:
8181
context: .
8282
cache-from: type=gha
83-
cache-to: type=gha,mode=max
83+
cache-to: type=gha,mode=max
8484
platforms: ${{ matrix.platform }}
8585
push: true
8686
tags: ${{ env.REGISTRY_IMAGE }}

cmd/geth/config.go

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -192,6 +192,11 @@ func makeFullNode(ctx *cli.Context) *node.Node {
192192
cfg.Eth.OverrideVerkle = &v
193193
}
194194

195+
// CHANGE(taiko): set preconfirmation forwarding URL.
196+
if ctx.IsSet(utils.PreconfirmationForwardingURLFlag.Name) {
197+
cfg.Eth.PreconfirmationForwardingURL = ctx.String(utils.PreconfirmationForwardingURLFlag.Name)
198+
}
199+
195200
backend, eth := utils.RegisterEthService(stack, &cfg.Eth)
196201

197202
// CHANGE(TAIKO): register Taiko RPC APIs.

cmd/geth/main.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -261,7 +261,7 @@ func init() {
261261
metricsFlags,
262262
)
263263
// CHANGE(taiko): append Taiko flags into the original GETH flags
264-
app.Flags = append(app.Flags, &utils.TaikoFlag)
264+
app.Flags = append(app.Flags, utils.TaikoFlag, utils.PreconfirmationForwardingURLFlag)
265265

266266
flags.AutoEnvVars(app.Flags, "GETH")
267267

cmd/utils/taiko_flags.go

Lines changed: 10 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -5,16 +5,23 @@ import (
55

66
"github.com/ethereum/go-ethereum/eth"
77
"github.com/ethereum/go-ethereum/eth/ethconfig"
8+
"github.com/ethereum/go-ethereum/internal/flags"
89
"github.com/ethereum/go-ethereum/node"
910
"github.com/ethereum/go-ethereum/params"
1011
"github.com/ethereum/go-ethereum/rpc"
1112
"github.com/urfave/cli/v2"
1213
)
1314

1415
var (
15-
TaikoFlag = cli.BoolFlag{
16-
Name: "taiko",
17-
Usage: "Taiko network",
16+
TaikoFlag = &cli.BoolFlag{
17+
Name: "taiko",
18+
Usage: "Taiko network",
19+
Category: flags.TaikoCategory,
20+
}
21+
PreconfirmationForwardingURLFlag = &cli.StringFlag{
22+
Name: "taiko.preconfirmationForwardingUrl",
23+
Usage: "URL to forward RPC requests before confirmation",
24+
Category: flags.TaikoCategory,
1825
}
1926
)
2027

consensus/taiko/consensus.go

Lines changed: 18 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -10,10 +10,12 @@ import (
1010

1111
"github.com/ethereum/go-ethereum/common"
1212
"github.com/ethereum/go-ethereum/consensus"
13+
"github.com/ethereum/go-ethereum/core/rawdb"
1314
"github.com/ethereum/go-ethereum/core/state"
1415
"github.com/ethereum/go-ethereum/core/tracing"
1516
"github.com/ethereum/go-ethereum/core/types"
1617
"github.com/ethereum/go-ethereum/crypto"
18+
"github.com/ethereum/go-ethereum/ethdb"
1719
"github.com/ethereum/go-ethereum/log"
1820
"github.com/ethereum/go-ethereum/params"
1921
"github.com/ethereum/go-ethereum/rpc"
@@ -40,12 +42,13 @@ var (
4042
// Taiko is a consensus engine used by L2 rollup.
4143
type Taiko struct {
4244
chainConfig *params.ChainConfig
45+
chainDB ethdb.Database
4346
taikoL2Address common.Address
4447
}
4548

4649
var _ = new(Taiko)
4750

48-
func New(chainConfig *params.ChainConfig) *Taiko {
51+
func New(chainConfig *params.ChainConfig, chainDB ethdb.Database) *Taiko {
4952
taikoL2AddressPrefix := strings.TrimPrefix(chainConfig.ChainID.String(), "0")
5053

5154
return &Taiko{
@@ -56,6 +59,7 @@ func New(chainConfig *params.ChainConfig) *Taiko {
5659
strings.Repeat("0", common.AddressLength*2-len(taikoL2AddressPrefix)-len(TaikoL2AddressSuffix)) +
5760
TaikoL2AddressSuffix,
5861
),
62+
chainDB: chainDB,
5963
}
6064
}
6165

@@ -82,7 +86,7 @@ func (t *Taiko) VerifyHeader(chain consensus.ChainHeaderReader, header *types.He
8286
return consensus.ErrUnknownAncestor
8387
}
8488
// Sanity checks passed, do a proper verification
85-
return t.verifyHeader(chain, header, parent, time.Now().Unix())
89+
return t.verifyHeader(header, parent, time.Now().Unix())
8690
}
8791

8892
// VerifyHeaders is similar to VerifyHeader, but verifies a batch of headers
@@ -109,7 +113,7 @@ func (t *Taiko) VerifyHeaders(chain consensus.ChainHeaderReader, headers []*type
109113
if parent == nil {
110114
err = consensus.ErrUnknownAncestor
111115
} else {
112-
err = t.verifyHeader(chain, header, parent, unixNow)
116+
err = t.verifyHeader(header, parent, unixNow)
113117
}
114118
select {
115119
case <-abort:
@@ -121,11 +125,7 @@ func (t *Taiko) VerifyHeaders(chain consensus.ChainHeaderReader, headers []*type
121125
return abort, results
122126
}
123127

124-
func (t *Taiko) verifyHeader(chain consensus.ChainHeaderReader, header, parent *types.Header, unixNow int64) error {
125-
if header.Time > uint64(unixNow) {
126-
return consensus.ErrFutureBlock
127-
}
128-
128+
func (t *Taiko) verifyHeader(header, parent *types.Header, unixNow int64) error {
129129
// Ensure that the header's extra-data section is of a reasonable size (<= 32 bytes)
130130
if uint64(len(header.Extra)) > params.MaximumExtraDataSize {
131131
return fmt.Errorf("extra-data too long: %d > %d", len(header.Extra), params.MaximumExtraDataSize)
@@ -171,6 +171,16 @@ func (t *Taiko) verifyHeader(chain consensus.ChainHeaderReader, header, parent *
171171
return ErrEmptyWithdrawalsHash
172172
}
173173

174+
l1Origin, err := rawdb.ReadL1Origin(t.chainDB, header.Number)
175+
if err != nil {
176+
return err
177+
}
178+
179+
// If the current block is not a soft block, then check the timestamp.
180+
if l1Origin != nil && !l1Origin.IsSoftBlock() && header.Time > uint64(unixNow) {
181+
return consensus.ErrFutureBlock
182+
}
183+
174184
return nil
175185
}
176186

consensus/taiko/consensus_test.go

Lines changed: 42 additions & 39 deletions
Original file line numberDiff line numberDiff line change
@@ -39,7 +39,7 @@ func init() {
3939
config.ArrowGlacierBlock = nil
4040
config.Ethash = nil
4141
config.Taiko = true
42-
testEngine = taiko.New(config)
42+
testEngine = taiko.New(config, rawdb.NewMemoryDatabase())
4343

4444
taikoL2AddressPrefix := strings.TrimPrefix(config.ChainID.String(), "0")
4545

@@ -93,70 +93,73 @@ func init() {
9393
}
9494
}
9595

96-
func newTestBackend(t *testing.T) (*eth.Ethereum, []*types.Block) {
97-
// Generate test chain.
98-
blocks := generateTestChain()
96+
func generateTestChain(t *testing.T) ([]*types.Block, *eth.Ethereum) {
97+
generate := func(i int, g *core.BlockGen) {
98+
g.OffsetTime(5)
99+
100+
g.SetExtra([]byte("test_taiko"))
101+
g.SetDifficulty(common.Big0)
102+
103+
for i, tx := range txs {
104+
if i == 0 {
105+
if err := tx.MarkAsAnchor(); err != nil {
106+
panic(err)
107+
}
108+
}
109+
g.AddTx(tx)
110+
}
111+
}
99112

100113
// Create node
101-
n, err := node.New(&node.Config{})
114+
n, err := node.New(&node.Config{
115+
DataDir: t.TempDir(),
116+
})
102117
if err != nil {
103118
t.Fatalf("can't create new node: %v", err)
104119
}
105120

106121
// Create Ethereum Service
107-
config := &ethconfig.Config{
122+
ethService, err := eth.New(n, &ethconfig.Config{
108123
Genesis: genesis,
109-
}
110-
111-
ethservice, err := eth.New(n, config)
124+
})
112125
if err != nil {
113126
t.Fatalf("can't create new ethereum service: %v", err)
114127
}
115128

129+
db := ethService.ChainDb()
130+
131+
gblock := genesis.MustCommit(db, triedb.NewDatabase(db, triedb.HashDefaults))
132+
blocks, _ := core.GenerateChain(genesis.Config, gblock, testEngine, db, 1, generate)
133+
blocks = append([]*types.Block{gblock}, blocks...)
134+
135+
// Insert L1Origins.
136+
for _, block := range blocks {
137+
rawdb.WriteL1Origin(db, block.Number(), &rawdb.L1Origin{
138+
BlockID: block.Number(),
139+
L1BlockHeight: block.Number(),
140+
L1BlockHash: block.Hash(),
141+
})
142+
}
143+
116144
// Import the test chain.
117145
if err := n.Start(); err != nil {
118146
t.Fatalf("can't start test node: %v", err)
119147
}
120148

121-
if _, err := ethservice.BlockChain().InsertChain(blocks[1:]); err != nil {
149+
if _, err := ethService.BlockChain().InsertChain(blocks[1:]); err != nil {
122150
t.Fatalf("can't import test blocks: %v", err)
123151
}
124152

125-
if _, ok := ethservice.Engine().(*taiko.Taiko); !ok {
153+
if _, ok := ethService.Engine().(*taiko.Taiko); !ok {
126154
t.Fatalf("not use taiko engine")
127155
}
128156

129-
return ethservice, blocks
130-
}
131-
132-
func generateTestChain() []*types.Block {
133-
db := rawdb.NewMemoryDatabase()
134-
generate := func(i int, g *core.BlockGen) {
135-
g.OffsetTime(5)
136-
137-
g.SetExtra([]byte("test_taiko"))
138-
g.SetDifficulty(common.Big0)
139-
140-
for i, tx := range txs {
141-
if i == 0 {
142-
if err := tx.MarkAsAnchor(); err != nil {
143-
panic(err)
144-
}
145-
}
146-
g.AddTx(tx)
147-
}
148-
}
149-
150-
gblock := genesis.MustCommit(db, triedb.NewDatabase(db, triedb.HashDefaults))
151-
152-
blocks, _ := core.GenerateChain(genesis.Config, gblock, testEngine, db, 1, generate)
153-
154-
blocks = append([]*types.Block{gblock}, blocks...)
155-
return blocks
157+
return blocks, ethService
156158
}
157159

158160
func TestVerifyHeader(t *testing.T) {
159-
ethService, blocks := newTestBackend(t)
161+
// Generate test chain.
162+
blocks, ethService := generateTestChain(t)
160163

161164
for _, b := range blocks {
162165
err := testEngine.VerifyHeader(ethService.BlockChain(), b.Header())

core/blockchain.go

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2269,7 +2269,12 @@ func (bc *BlockChain) reorg(oldHead *types.Header, newHead *types.Block) error {
22692269
} else {
22702270
// len(newChain) == 0 && len(oldChain) > 0
22712271
// rewind the canonical chain to a lower point.
2272-
log.Error("Impossible reorg, please file an issue", "oldnum", oldBlock.Number(), "oldhash", oldBlock.Hash(), "oldblocks", len(oldChain), "newnum", newBlock.Number(), "newhash", newBlock.Hash(), "newblocks", len(newChain))
2272+
// CHANGE(taiko): use debug log level to avoid logging too many logs when frequently soft block rollback.
2273+
if bc.chainConfig.Taiko {
2274+
log.Debug("Impossible reorg, please file an issue", "oldnum", oldBlock.Number(), "oldhash", oldBlock.Hash(), "oldblocks", len(oldChain), "newnum", newBlock.Number(), "newhash", newBlock.Hash(), "newblocks", len(newChain))
2275+
} else {
2276+
log.Error("Impossible reorg, please file an issue", "oldnum", oldBlock.Number(), "oldhash", oldBlock.Hash(), "oldblocks", len(oldChain), "newnum", newBlock.Number(), "newhash", newBlock.Hash(), "newblocks", len(newChain))
2277+
}
22732278
}
22742279
// Acquire the tx-lookup lock before mutation. This step is essential
22752280
// as the txlookups should be changed atomically, and all subsequent

core/rawdb/gen_taiko_l1_origin.go

Lines changed: 32 additions & 10 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

0 commit comments

Comments
 (0)