Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Submit feedback
Contribute to GitLab
Sign in
Toggle navigation
N
nebula
Project
Project
Details
Activity
Releases
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Boards
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
exchain
nebula
Commits
a4a3ff36
Unverified
Commit
a4a3ff36
authored
Jul 24, 2023
by
inphi
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Compute output pre-image in L2 source
parent
9c858501
Changes
9
Hide whitespace changes
Inline
Side-by-side
Showing
9 changed files
with
122 additions
and
36 deletions
+122
-36
api.go
op-node/node/api.go
+1
-2
l1_client.go
op-node/sources/l1_client.go
+0
-7
mock_l1.go
op-node/testutils/mock_l1.go
+0
-9
mock_l2.go
op-node/testutils/mock_l2.go
+9
-0
host.go
op-program/host/host.go
+2
-2
l2_client.go
op-program/host/l2_client.go
+85
-0
prefetcher.go
op-program/host/prefetcher/prefetcher.go
+2
-2
retry.go
op-program/host/prefetcher/retry.go
+14
-14
retry_test.go
op-program/host/prefetcher/retry_test.go
+9
-0
No files found.
op-node/node/api.go
View file @
a4a3ff36
...
@@ -120,7 +120,6 @@ func (n *nodeAPI) OutputAtBlock(ctx context.Context, number hexutil.Uint64) (*et
...
@@ -120,7 +120,6 @@ func (n *nodeAPI) OutputAtBlock(ctx context.Context, number hexutil.Uint64) (*et
return
nil
,
fmt
.
Errorf
(
"invalid withdrawal root hash, state root was %s: %w"
,
head
.
Root
(),
err
)
return
nil
,
fmt
.
Errorf
(
"invalid withdrawal root hash, state root was %s: %w"
,
head
.
Root
(),
err
)
}
}
var
l2OutputRootVersion
eth
.
Bytes32
// it's zero for now
l2OutputRoot
,
err
:=
rollup
.
ComputeL2OutputRootV0
(
head
,
proof
.
StorageHash
)
l2OutputRoot
,
err
:=
rollup
.
ComputeL2OutputRootV0
(
head
,
proof
.
StorageHash
)
if
err
!=
nil
{
if
err
!=
nil
{
n
.
log
.
Error
(
"Error computing L2 output root, nil ptr passed to hashing function"
)
n
.
log
.
Error
(
"Error computing L2 output root, nil ptr passed to hashing function"
)
...
@@ -128,7 +127,7 @@ func (n *nodeAPI) OutputAtBlock(ctx context.Context, number hexutil.Uint64) (*et
...
@@ -128,7 +127,7 @@ func (n *nodeAPI) OutputAtBlock(ctx context.Context, number hexutil.Uint64) (*et
}
}
return
&
eth
.
OutputResponse
{
return
&
eth
.
OutputResponse
{
Version
:
l2OutputRootVersion
,
Version
:
eth
.
OutputVersionV0
,
OutputRoot
:
l2OutputRoot
,
OutputRoot
:
l2OutputRoot
,
BlockRef
:
ref
,
BlockRef
:
ref
,
WithdrawalStorageRoot
:
proof
.
StorageHash
,
WithdrawalStorageRoot
:
proof
.
StorageHash
,
...
...
op-node/sources/l1_client.go
View file @
a4a3ff36
...
@@ -115,10 +115,3 @@ func (s *L1Client) L1BlockRefByHash(ctx context.Context, hash common.Hash) (eth.
...
@@ -115,10 +115,3 @@ func (s *L1Client) L1BlockRefByHash(ctx context.Context, hash common.Hash) (eth.
s
.
l1BlockRefsCache
.
Add
(
ref
.
Hash
,
ref
)
s
.
l1BlockRefsCache
.
Add
(
ref
.
Hash
,
ref
)
return
ref
,
nil
return
ref
,
nil
}
}
func
(
s
*
L1Client
)
L2OutputByRoot
(
ctx
context
.
Context
,
l2OutputRoot
common
.
Hash
)
(
eth
.
Output
,
error
)
{
// TODO(inphi): Fetch Output from preset. Or directly from the oracle
//return s.OutputByRoot(ctx, l2OutputRoot)
var
output
eth
.
Output
return
output
,
nil
}
op-node/testutils/mock_l1.go
View file @
a4a3ff36
...
@@ -37,12 +37,3 @@ func (m *MockL1Source) L1BlockRefByHash(ctx context.Context, hash common.Hash) (
...
@@ -37,12 +37,3 @@ func (m *MockL1Source) L1BlockRefByHash(ctx context.Context, hash common.Hash) (
func
(
m
*
MockL1Source
)
ExpectL1BlockRefByHash
(
hash
common
.
Hash
,
ref
eth
.
L1BlockRef
,
err
error
)
{
func
(
m
*
MockL1Source
)
ExpectL1BlockRefByHash
(
hash
common
.
Hash
,
ref
eth
.
L1BlockRef
,
err
error
)
{
m
.
Mock
.
On
(
"L1BlockRefByHash"
,
hash
)
.
Once
()
.
Return
(
ref
,
&
err
)
m
.
Mock
.
On
(
"L1BlockRefByHash"
,
hash
)
.
Once
()
.
Return
(
ref
,
&
err
)
}
}
func
(
m
*
MockL1Source
)
L2OutputByRoot
(
ctx
context
.
Context
,
root
common
.
Hash
)
(
eth
.
Output
,
error
)
{
out
:=
m
.
Mock
.
MethodCalled
(
"L2OutputByRoot"
,
root
)
return
out
[
0
]
.
(
eth
.
Output
),
*
out
[
1
]
.
(
*
error
)
}
func
(
m
*
MockL1Source
)
ExpectL2OutputByRoot
(
root
common
.
Hash
,
output
eth
.
Output
,
err
error
)
{
m
.
Mock
.
On
(
"L2OutputByRoot"
,
root
)
.
Once
()
.
Return
(
output
,
&
err
)
}
op-node/testutils/mock_l2.go
View file @
a4a3ff36
...
@@ -43,3 +43,12 @@ func (m *MockL2Client) SystemConfigByL2Hash(ctx context.Context, hash common.Has
...
@@ -43,3 +43,12 @@ func (m *MockL2Client) SystemConfigByL2Hash(ctx context.Context, hash common.Has
func
(
m
*
MockL2Client
)
ExpectSystemConfigByL2Hash
(
hash
common
.
Hash
,
cfg
eth
.
SystemConfig
,
err
error
)
{
func
(
m
*
MockL2Client
)
ExpectSystemConfigByL2Hash
(
hash
common
.
Hash
,
cfg
eth
.
SystemConfig
,
err
error
)
{
m
.
Mock
.
On
(
"SystemConfigByL2Hash"
,
hash
)
.
Once
()
.
Return
(
cfg
,
&
err
)
m
.
Mock
.
On
(
"SystemConfigByL2Hash"
,
hash
)
.
Once
()
.
Return
(
cfg
,
&
err
)
}
}
func
(
m
*
MockL2Client
)
L2OutputByRoot
(
ctx
context
.
Context
,
root
common
.
Hash
)
(
eth
.
Output
,
error
)
{
out
:=
m
.
Mock
.
MethodCalled
(
"L2OutputByRoot"
,
root
)
return
out
[
0
]
.
(
eth
.
Output
),
*
out
[
1
]
.
(
*
error
)
}
func
(
m
*
MockL2Client
)
ExpectL2OutputByRoot
(
root
common
.
Hash
,
output
eth
.
Output
,
err
error
)
{
m
.
Mock
.
On
(
"L2OutputByRoot"
,
root
)
.
Once
()
.
Return
(
output
,
&
err
)
}
op-program/host/host.go
View file @
a4a3ff36
...
@@ -26,7 +26,7 @@ import (
...
@@ -26,7 +26,7 @@ import (
)
)
type
L2Source
struct
{
type
L2Source
struct
{
*
sources
.
L2Client
*
L2Client
*
sources
.
DebugClient
*
sources
.
DebugClient
}
}
...
@@ -205,7 +205,7 @@ func makePrefetcher(ctx context.Context, logger log.Logger, kv kvstore.KV, cfg *
...
@@ -205,7 +205,7 @@ func makePrefetcher(ctx context.Context, logger log.Logger, kv kvstore.KV, cfg *
if
err
!=
nil
{
if
err
!=
nil
{
return
nil
,
fmt
.
Errorf
(
"failed to create L1 client: %w"
,
err
)
return
nil
,
fmt
.
Errorf
(
"failed to create L1 client: %w"
,
err
)
}
}
l2Cl
,
err
:=
sources
.
NewL2Client
(
l2RPC
,
logger
,
nil
,
l2ClCfg
)
l2Cl
,
err
:=
NewL2Client
(
l2RPC
,
logger
,
nil
,
&
L2ClientConfig
{
L2ClientConfig
:
l2ClCfg
,
L2Head
:
cfg
.
L2Head
}
)
if
err
!=
nil
{
if
err
!=
nil
{
return
nil
,
fmt
.
Errorf
(
"failed to create L2 client: %w"
,
err
)
return
nil
,
fmt
.
Errorf
(
"failed to create L2 client: %w"
,
err
)
}
}
...
...
op-program/host/l2_client.go
0 → 100644
View file @
a4a3ff36
package
host
import
(
"context"
"fmt"
"github.com/ethereum-optimism/optimism/op-bindings/predeploys"
"github.com/ethereum-optimism/optimism/op-node/client"
"github.com/ethereum-optimism/optimism/op-node/eth"
"github.com/ethereum-optimism/optimism/op-node/sources"
"github.com/ethereum-optimism/optimism/op-node/sources/caching"
"github.com/ethereum/go-ethereum"
"github.com/ethereum/go-ethereum/common"
"github.com/ethereum/go-ethereum/crypto"
"github.com/ethereum/go-ethereum/log"
)
type
L2Client
struct
{
*
sources
.
L2Client
l2Head
common
.
Hash
l2OutputOracleAddress
common
.
Address
}
var
(
L2OutputEventABI
=
"OutputProposed(bytes32,uint256,uint256,uint256)"
L2OutputEventABIHash
=
crypto
.
Keccak256Hash
([]
byte
(
L2OutputEventABI
))
)
type
L2ClientConfig
struct
{
*
sources
.
L2ClientConfig
L2Head
common
.
Hash
}
func
NewL2Client
(
client
client
.
RPC
,
log
log
.
Logger
,
metrics
caching
.
Metrics
,
config
*
L2ClientConfig
)
(
*
L2Client
,
error
)
{
l2Client
,
err
:=
sources
.
NewL2Client
(
client
,
log
,
metrics
,
config
.
L2ClientConfig
)
if
err
!=
nil
{
return
nil
,
err
}
return
&
L2Client
{
L2Client
:
l2Client
,
l2Head
:
config
.
L2Head
,
},
nil
}
func
(
s
*
L2Client
)
L2OutputByRoot
(
ctx
context
.
Context
,
l2OutputRoot
common
.
Hash
)
(
eth
.
Output
,
error
)
{
output
,
err
:=
s
.
outputAtBlock
(
ctx
,
s
.
l2Head
)
if
err
!=
nil
{
return
nil
,
err
}
if
eth
.
OutputRoot
(
output
)
!=
eth
.
Bytes32
(
l2OutputRoot
)
{
// For fault proofs, we only reference outputs at the l2 head at boot time
// The caller shouldn't be requesting outputs at any other block
return
nil
,
fmt
.
Errorf
(
"unknown output root"
)
}
return
output
,
nil
}
func
(
s
*
L2Client
)
outputAtBlock
(
ctx
context
.
Context
,
blockHash
common
.
Hash
)
(
eth
.
Output
,
error
)
{
head
,
err
:=
s
.
InfoByHash
(
ctx
,
blockHash
)
if
err
!=
nil
{
return
nil
,
fmt
.
Errorf
(
"failed to get L2 block by hash: %w"
,
err
)
}
if
head
==
nil
{
return
nil
,
ethereum
.
NotFound
}
proof
,
err
:=
s
.
GetProof
(
ctx
,
predeploys
.
L2ToL1MessagePasserAddr
,
[]
common
.
Hash
{},
blockHash
.
String
())
if
err
!=
nil
{
return
nil
,
fmt
.
Errorf
(
"failed to get contract proof at block %s: %w"
,
blockHash
,
err
)
}
if
proof
==
nil
{
return
nil
,
fmt
.
Errorf
(
"proof %w"
,
ethereum
.
NotFound
)
}
// make sure that the proof (including storage hash) that we retrieved is correct by verifying it against the state-root
if
err
:=
proof
.
Verify
(
head
.
Root
());
err
!=
nil
{
return
nil
,
fmt
.
Errorf
(
"invalid withdrawal root hash, state root was %s: %w"
,
head
.
Root
(),
err
)
}
stateRoot
:=
head
.
Root
()
return
&
eth
.
OutputV0
{
StateRoot
:
eth
.
Bytes32
(
stateRoot
),
MessagePasserStorageRoot
:
eth
.
Bytes32
(
proof
.
StorageHash
),
BlockHash
:
blockHash
,
},
nil
}
op-program/host/prefetcher/prefetcher.go
View file @
a4a3ff36
...
@@ -23,13 +23,13 @@ type L1Source interface {
...
@@ -23,13 +23,13 @@ type L1Source interface {
InfoByHash
(
ctx
context
.
Context
,
blockHash
common
.
Hash
)
(
eth
.
BlockInfo
,
error
)
InfoByHash
(
ctx
context
.
Context
,
blockHash
common
.
Hash
)
(
eth
.
BlockInfo
,
error
)
InfoAndTxsByHash
(
ctx
context
.
Context
,
blockHash
common
.
Hash
)
(
eth
.
BlockInfo
,
types
.
Transactions
,
error
)
InfoAndTxsByHash
(
ctx
context
.
Context
,
blockHash
common
.
Hash
)
(
eth
.
BlockInfo
,
types
.
Transactions
,
error
)
FetchReceipts
(
ctx
context
.
Context
,
blockHash
common
.
Hash
)
(
eth
.
BlockInfo
,
types
.
Receipts
,
error
)
FetchReceipts
(
ctx
context
.
Context
,
blockHash
common
.
Hash
)
(
eth
.
BlockInfo
,
types
.
Receipts
,
error
)
L2OutputByRoot
(
ctx
context
.
Context
,
l2OutputRoot
common
.
Hash
)
(
eth
.
Output
,
error
)
}
}
type
L2Source
interface
{
type
L2Source
interface
{
InfoAndTxsByHash
(
ctx
context
.
Context
,
blockHash
common
.
Hash
)
(
eth
.
BlockInfo
,
types
.
Transactions
,
error
)
InfoAndTxsByHash
(
ctx
context
.
Context
,
blockHash
common
.
Hash
)
(
eth
.
BlockInfo
,
types
.
Transactions
,
error
)
NodeByHash
(
ctx
context
.
Context
,
hash
common
.
Hash
)
([]
byte
,
error
)
NodeByHash
(
ctx
context
.
Context
,
hash
common
.
Hash
)
([]
byte
,
error
)
CodeByHash
(
ctx
context
.
Context
,
hash
common
.
Hash
)
([]
byte
,
error
)
CodeByHash
(
ctx
context
.
Context
,
hash
common
.
Hash
)
([]
byte
,
error
)
L2OutputByRoot
(
ctx
context
.
Context
,
root
common
.
Hash
)
(
eth
.
Output
,
error
)
}
}
type
Prefetcher
struct
{
type
Prefetcher
struct
{
...
@@ -100,7 +100,7 @@ func (p *Prefetcher) prefetch(ctx context.Context, hint string) error {
...
@@ -100,7 +100,7 @@ func (p *Prefetcher) prefetch(ctx context.Context, hint string) error {
}
}
return
p
.
storeReceipts
(
receipts
)
return
p
.
storeReceipts
(
receipts
)
case
l1
.
HintL2Output
:
case
l1
.
HintL2Output
:
output
,
err
:=
p
.
l
1
Fetcher
.
L2OutputByRoot
(
ctx
,
hash
)
output
,
err
:=
p
.
l
2
Fetcher
.
L2OutputByRoot
(
ctx
,
hash
)
if
err
!=
nil
{
if
err
!=
nil
{
return
fmt
.
Errorf
(
"failed to fetch L2 output root %s: %w"
,
hash
,
err
)
return
fmt
.
Errorf
(
"failed to fetch L2 output root %s: %w"
,
hash
,
err
)
}
}
...
...
op-program/host/prefetcher/retry.go
View file @
a4a3ff36
...
@@ -73,20 +73,6 @@ func (s *RetryingL1Source) FetchReceipts(ctx context.Context, blockHash common.H
...
@@ -73,20 +73,6 @@ func (s *RetryingL1Source) FetchReceipts(ctx context.Context, blockHash common.H
return
info
,
rcpts
,
err
return
info
,
rcpts
,
err
}
}
func
(
s
*
RetryingL1Source
)
L2OutputByRoot
(
ctx
context
.
Context
,
root
common
.
Hash
)
(
eth
.
Output
,
error
)
{
var
output
eth
.
Output
err
:=
backoff
.
DoCtx
(
ctx
,
maxAttempts
,
s
.
strategy
,
func
()
error
{
o
,
err
:=
s
.
source
.
L2OutputByRoot
(
ctx
,
root
)
if
err
!=
nil
{
s
.
logger
.
Warn
(
"Failed to fetch l2 output"
,
"root"
,
root
,
"err"
,
err
)
return
err
}
output
=
o
return
nil
})
return
output
,
err
}
var
_
L1Source
=
(
*
RetryingL1Source
)(
nil
)
var
_
L1Source
=
(
*
RetryingL1Source
)(
nil
)
type
RetryingL2Source
struct
{
type
RetryingL2Source
struct
{
...
@@ -139,6 +125,20 @@ func (s *RetryingL2Source) CodeByHash(ctx context.Context, hash common.Hash) ([]
...
@@ -139,6 +125,20 @@ func (s *RetryingL2Source) CodeByHash(ctx context.Context, hash common.Hash) ([]
return
code
,
err
return
code
,
err
}
}
func
(
s
*
RetryingL2Source
)
L2OutputByRoot
(
ctx
context
.
Context
,
root
common
.
Hash
)
(
eth
.
Output
,
error
)
{
var
output
eth
.
Output
err
:=
backoff
.
DoCtx
(
ctx
,
maxAttempts
,
s
.
strategy
,
func
()
error
{
o
,
err
:=
s
.
source
.
L2OutputByRoot
(
ctx
,
root
)
if
err
!=
nil
{
s
.
logger
.
Warn
(
"Failed to fetch l2 output"
,
"root"
,
root
,
"err"
,
err
)
return
err
}
output
=
o
return
nil
})
return
output
,
err
}
func
NewRetryingL2Source
(
logger
log
.
Logger
,
source
L2Source
)
*
RetryingL2Source
{
func
NewRetryingL2Source
(
logger
log
.
Logger
,
source
L2Source
)
*
RetryingL2Source
{
return
&
RetryingL2Source
{
return
&
RetryingL2Source
{
logger
:
logger
,
logger
:
logger
,
...
...
op-program/host/prefetcher/retry_test.go
View file @
a4a3ff36
...
@@ -229,4 +229,13 @@ func (m *MockL2Source) ExpectCodeByHash(hash common.Hash, code []byte, err error
...
@@ -229,4 +229,13 @@ func (m *MockL2Source) ExpectCodeByHash(hash common.Hash, code []byte, err error
m
.
Mock
.
On
(
"CodeByHash"
,
hash
)
.
Once
()
.
Return
(
code
,
&
err
)
m
.
Mock
.
On
(
"CodeByHash"
,
hash
)
.
Once
()
.
Return
(
code
,
&
err
)
}
}
func
(
m
*
MockL2Source
)
L2OutputByRoot
(
ctx
context
.
Context
,
root
common
.
Hash
)
(
eth
.
Output
,
error
)
{
out
:=
m
.
Mock
.
MethodCalled
(
"L2OutputByRoot"
,
root
)
return
out
[
0
]
.
(
eth
.
Output
),
*
out
[
1
]
.
(
*
error
)
}
func
(
m
*
MockL2Source
)
ExpectL2OutputByRoot
(
root
common
.
Hash
,
output
eth
.
Output
,
err
error
)
{
m
.
Mock
.
On
(
"L2OutputByRoot"
,
root
)
.
Once
()
.
Return
(
output
,
&
err
)
}
var
_
L2Source
=
(
*
MockL2Source
)(
nil
)
var
_
L2Source
=
(
*
MockL2Source
)(
nil
)
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment