Skip to content

Commit 590da9f

Browse files
authored
interop: use the pending time instead of the unsafe time for executing descriptors (#604)
Previously, the ingress filter [assigned] the [latest timestamp] to exec descriptors. This unnecessarily delayed executing messages by one block when the supervisor used a stringent [access list policy], as in the [reference implementation]. This commit fixes the issue by using the pending timestamp instead of the unsafe timestamp. [assigned]: https://github.com/ethereum-optimism/op-geth/blob/e605d07bde55b02f9e0309c330fb87500d80d06f/core/txpool/ingress_filters.go#L48-L58 [latest timestamp]: https://github.com/ethereum-optimism/op-geth/blob/e605d07bde55b02f9e0309c330fb87500d80d06f/eth/interop.go#L20-L31 [access list policy]: https://specs.optimism.io/interop/supervisor.html#access-list-checks [reference implementation]: https://github.com/ethereum-optimism/optimism/blob/23c1fef1f0fe6b626c987eecbfa91fd5e0b66fb0/op-supervisor/supervisor/types/types.go#L344-L346
1 parent 3e5073a commit 590da9f

File tree

1 file changed

+21
-1
lines changed

1 file changed

+21
-1
lines changed

eth/interop.go

Lines changed: 21 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ package eth
33
import (
44
"context"
55
"errors"
6+
"fmt"
67

78
"github.com/ethereum/go-ethereum/common"
89
"github.com/ethereum/go-ethereum/core/types"
@@ -17,6 +18,19 @@ func (s *Ethereum) CheckAccessList(ctx context.Context, inboxEntries []common.Ha
1718
return s.interopRPC.CheckAccessList(ctx, inboxEntries, minSafety, execDesc)
1819
}
1920

21+
func (s *Ethereum) inferBlockTime(current *types.Header) (uint64, error) {
22+
if current.Number.Uint64() == 0 {
23+
return 0, errors.New("current head is at genesis: penultimate header is nil")
24+
}
25+
penultimate := s.BlockChain().GetHeaderByHash(current.ParentHash)
26+
if penultimate == nil {
27+
// We could use a for loop and retry, but this function is used
28+
// in the ingress filters, which should fail fast to maintain uptime.
29+
return 0, errors.New("penultimate header is nil")
30+
}
31+
return current.Time - penultimate.Time, nil
32+
}
33+
2034
// CurrentInteropBlockTime returns the current block time,
2135
// or an error if Interop is not enabled.
2236
func (s *Ethereum) CurrentInteropBlockTime() (uint64, error) {
@@ -27,7 +41,13 @@ func (s *Ethereum) CurrentInteropBlockTime() (uint64, error) {
2741
if chainConfig.InteropTime == nil {
2842
return 0, errors.New("interop time not set in chain config")
2943
}
30-
return s.BlockChain().CurrentBlock().Time, nil
44+
// The pending block may be aliased to the current block in op-geth. Infer the pending time instead.
45+
currentHeader := s.BlockChain().CurrentHeader()
46+
blockTime, err := s.inferBlockTime(currentHeader)
47+
if err != nil {
48+
return 0, fmt.Errorf("infer block time: %v", err)
49+
}
50+
return currentHeader.Time + blockTime, nil
3151
}
3252

3353
// TxToInteropAccessList returns the interop specific access list storage keys for a transaction.

0 commit comments

Comments
 (0)