-
Notifications
You must be signed in to change notification settings - Fork 2.2k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
feat(taiko-client): enable proof aggregation (batch proofs) #18163
base: main
Are you sure you want to change the base?
Changes from 113 commits
453d730
5b802d3
5dd741d
937eeb6
1b4e58c
92b8e7b
45fa2a1
1f46ea9
64b9de1
66a3efb
d1d2d55
88d7a43
b5c5968
236e660
24add9c
dd4e626
e20e064
948c55d
73fc040
54124c8
f4a9ac8
62ac02b
a1818e4
e29ba96
0834514
d505ebe
008ac1d
804428e
b25ed1c
1a5014b
a385f99
0f86de8
603bc1a
023ff02
9e82059
b0b17c4
1afd4fe
9222d1c
f776a63
e35e7a6
f6d0ee2
56db4ce
04250f9
49c2972
fc667be
9c2271c
fd5c6ee
82cff3c
e52775c
51b885c
a2fe08d
2328487
4360b2a
af76a29
2ffe93a
209574e
b742583
d53c504
87be364
2cc63f0
11190cc
928363e
eb4ea5c
b60ce73
6f7736b
5409ad4
7cd5ee2
94d3787
83e9dce
6753450
9c0f5a5
1b3b961
98e5b6f
19cd84c
6e658d7
8c9bdca
6138b8b
1b7240f
ac19d34
3844048
1e68832
bd6482d
9d3ad02
c9f32fe
78cf58d
3681c38
26b2619
1b3123b
7e31f03
348a96d
99000b2
6441d62
095392b
25ecc2c
237b501
de53a2a
45890cd
80260a3
dd1bb5d
1e9d376
0eacfdf
8046b9f
f0f0a46
bcd1542
7c2b509
cf5dfe8
4f47f42
54ce66c
d704e13
50a71d4
0876fc1
8fe2889
d3cb491
4ce2d56
bd68a89
00bda1e
ff2228b
b9a719d
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -14,6 +14,7 @@ import ( | |
"github.com/ethereum/go-ethereum/core/types" | ||
"github.com/ethereum/go-ethereum/log" | ||
"github.com/ethereum/go-ethereum/params" | ||
"golang.org/x/sync/errgroup" | ||
|
||
"github.com/taikoxyz/taiko-mono/packages/taiko-client/bindings" | ||
"github.com/taikoxyz/taiko-mono/packages/taiko-client/bindings/encoding" | ||
|
@@ -62,7 +63,6 @@ func GetProtocolStateVariables( | |
} | ||
opts.Context, cancel = CtxWithTimeoutOrDefault(opts.Context, defaultTimeout) | ||
defer cancel() | ||
|
||
// Notice: sloB.LastProposedIn and slotB.LastUnpausedAt are always 0 | ||
// before upgrading contract, but we can ignore it since we won't use it. | ||
slotA, slotB, err := taikoL1Client.GetStateVariables(opts) | ||
|
@@ -248,6 +248,126 @@ func GetBlockProofStatus( | |
}, nil | ||
} | ||
|
||
// BatchGetBlocksProofStatus checks whether the batch of L2 blocks still need new proofs or new contests. | ||
// Here are the possible status: | ||
// 1. No proof on chain at all. | ||
// 2. A valid proof has been submitted. | ||
// 3. An invalid proof has been submitted, and there is no valid contest. | ||
// 4. An invalid proof has been submitted, and there is a valid contest. | ||
func BatchGetBlocksProofStatus( | ||
ctx context.Context, | ||
cli *Client, | ||
ids []*big.Int, | ||
proverAddress common.Address, | ||
proverSetAddress common.Address, | ||
) ([]*BlockProofStatus, error) { | ||
ctxWithTimeout, cancel := CtxWithTimeoutOrDefault(ctx, defaultTimeout) | ||
defer cancel() | ||
var ( | ||
parentHashes = make([][32]byte, len(ids)) | ||
parents = make([]*types.Header, len(ids)) | ||
blockIDs = make([]uint64, len(ids)) | ||
result = make([]*BlockProofStatus, len(ids)) | ||
) | ||
// Get the local L2 parent header. | ||
g, gCtx := errgroup.WithContext(ctxWithTimeout) | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. And after thinking twice, let's do batch requests https://geth.ethereum.org/docs/interacting-with-geth/rpc/batch here and some other places, to make the network requests always There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. OK, pretty good! |
||
for i, id := range ids { | ||
davidtaikocha marked this conversation as resolved.
Show resolved
Hide resolved
|
||
g.Go(func() error { | ||
parent, err := cli.L2.HeaderByNumber(gCtx, new(big.Int).Sub(id, common.Big1)) | ||
if err != nil { | ||
return err | ||
} | ||
parentHashes[i] = parent.Hash() | ||
parents[i] = parent | ||
blockIDs[i] = id.Uint64() | ||
return nil | ||
}) | ||
} | ||
if gErr := g.Wait(); gErr != nil { | ||
return nil, gErr | ||
} | ||
|
||
// Get the transition state from TaikoL1 contract. | ||
transitions, err := cli.TaikoL1.GetTransitions( | ||
&bind.CallOpts{Context: ctxWithTimeout}, | ||
blockIDs, | ||
parentHashes, | ||
) | ||
if err != nil { | ||
return nil, err | ||
} | ||
g, gCtx = errgroup.WithContext(ctxWithTimeout) | ||
for i, transition := range transitions { | ||
YoGhurt111 marked this conversation as resolved.
Show resolved
Hide resolved
davidtaikocha marked this conversation as resolved.
Show resolved
Hide resolved
|
||
// No proof on chain | ||
if transition.BlockHash == (common.Hash{}) { | ||
result[i] = &BlockProofStatus{IsSubmitted: false, ParentHeader: parents[i]} | ||
continue | ||
} | ||
g.Go(func() error { | ||
header, err := cli.WaitL2Header(gCtx, ids[i]) | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. We can just wait for the highest header here right? no need to send requests to check and wait every block? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Yes |
||
if err != nil { | ||
return err | ||
} | ||
if header.Hash() != transition.BlockHash || | ||
(transition.StateRoot != (common.Hash{}) && transition.StateRoot != header.Root) { | ||
log.Info( | ||
"Different block hash or state root detected, try submitting a contest", | ||
"localBlockHash", header.Hash(), | ||
"protocolTransitionBlockHash", common.BytesToHash(transition.BlockHash[:]), | ||
"localStateRoot", header.Root, | ||
"protocolTransitionStateRoot", common.BytesToHash(transition.StateRoot[:]), | ||
) | ||
result[i] = &BlockProofStatus{ | ||
IsSubmitted: true, | ||
Invalid: true, | ||
CurrentTransitionState: &transitions[i], | ||
ParentHeader: parents[i], | ||
} | ||
return nil | ||
} | ||
|
||
if proverAddress == transition.Prover || | ||
(proverSetAddress != ZeroAddress && transition.Prover == proverSetAddress) { | ||
log.Info( | ||
"📬 Block's proof has already been submitted by current prover", | ||
"blockID", ids[i], | ||
"parent", parents[i].Hash().Hex(), | ||
"hash", common.Bytes2Hex(transition.BlockHash[:]), | ||
"stateRoot", common.Bytes2Hex(transition.StateRoot[:]), | ||
"timestamp", transition.Timestamp, | ||
"contester", transition.Contester, | ||
) | ||
result[i] = &BlockProofStatus{ | ||
IsSubmitted: true, | ||
Invalid: transition.Contester != ZeroAddress, | ||
ParentHeader: parents[i], | ||
CurrentTransitionState: &transitions[i], | ||
} | ||
return nil | ||
} | ||
log.Info( | ||
"📬 Block's proof has already been submitted by another prover", | ||
"blockID", ids[i], | ||
"prover", transition.Prover, | ||
"parent", parents[i].Hash().Hex(), | ||
"hash", common.Bytes2Hex(transition.BlockHash[:]), | ||
"stateRoot", common.Bytes2Hex(transition.StateRoot[:]), | ||
"timestamp", transition.Timestamp, | ||
"contester", transition.Contester, | ||
) | ||
|
||
result[i] = &BlockProofStatus{ | ||
IsSubmitted: true, | ||
Invalid: transition.Contester != ZeroAddress, | ||
ParentHeader: parents[i], | ||
CurrentTransitionState: &transitions[i], | ||
} | ||
return nil | ||
}) | ||
} | ||
return result, g.Wait() | ||
} | ||
|
||
// SetHead makes a `debug_setHead` RPC call to set the chain's head, should only be used | ||
// for testing purpose. | ||
func SetHead(ctx context.Context, client *EthClient, headNum *big.Int) error { | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Let's change it back?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I want to build a new image to test in devnet first and then I will change it back.