@@ -3,6 +3,7 @@ package eth
3
3
import (
4
4
"context"
5
5
"errors"
6
+ "fmt"
6
7
7
8
"github.com/ethereum/go-ethereum/common"
8
9
"github.com/ethereum/go-ethereum/core/types"
@@ -17,6 +18,19 @@ func (s *Ethereum) CheckAccessList(ctx context.Context, inboxEntries []common.Ha
17
18
return s .interopRPC .CheckAccessList (ctx , inboxEntries , minSafety , execDesc )
18
19
}
19
20
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
+
20
34
// CurrentInteropBlockTime returns the current block time,
21
35
// or an error if Interop is not enabled.
22
36
func (s * Ethereum ) CurrentInteropBlockTime () (uint64 , error ) {
@@ -27,7 +41,13 @@ func (s *Ethereum) CurrentInteropBlockTime() (uint64, error) {
27
41
if chainConfig .InteropTime == nil {
28
42
return 0 , errors .New ("interop time not set in chain config" )
29
43
}
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
31
51
}
32
52
33
53
// TxToInteropAccessList returns the interop specific access list storage keys for a transaction.
0 commit comments