Skip to content

Commit ec3f4bb

Browse files
committed
interop: use the pending time instead of the unsafe time for executing descriptors
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 e3f85bf commit ec3f4bb

File tree

1 file changed

+23
-1
lines changed

1 file changed

+23
-1
lines changed

eth/interop.go

Lines changed: 23 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,21 @@ 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+
penultimate := s.BlockChain().GetHeaderByHash(current.ParentHash)
23+
if penultimate == nil {
24+
// We could use a for loop and retry, but this function is used
25+
// in the ingress filters, which should fail fast to maintain uptime.
26+
if current.Number.Uint64() == 0 {
27+
return 0, errors.New("current head is at genesis: penultimate header is nil")
28+
} else {
29+
return 0, errors.New("a reorg probably occurred: penultimate header is nil")
30+
}
31+
}
32+
blockTime := current.Time - penultimate.Time
33+
return current.Time + blockTime, nil
34+
}
35+
2036
// CurrentInteropBlockTime returns the current block time,
2137
// or an error if Interop is not enabled.
2238
func (s *Ethereum) CurrentInteropBlockTime() (uint64, error) {
@@ -27,7 +43,13 @@ func (s *Ethereum) CurrentInteropBlockTime() (uint64, error) {
2743
if chainConfig.InteropTime == nil {
2844
return 0, errors.New("interop time not set in chain config")
2945
}
30-
return s.BlockChain().CurrentBlock().Time, nil
46+
// The pending block may be aliased to the current block in op-geth. Infer the pending time instead.
47+
currentHeader := s.BlockChain().CurrentHeader()
48+
blockTime, err := s.inferBlockTime(currentHeader)
49+
if err != nil {
50+
return 0, fmt.Errorf("infer block time: %v", err)
51+
}
52+
return currentHeader.Time + blockTime, nil
3153
}
3254

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

0 commit comments

Comments
 (0)