@@ -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,21 @@ 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
+ 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
+
20
36
// CurrentInteropBlockTime returns the current block time,
21
37
// or an error if Interop is not enabled.
22
38
func (s * Ethereum ) CurrentInteropBlockTime () (uint64 , error ) {
@@ -27,7 +43,13 @@ func (s *Ethereum) CurrentInteropBlockTime() (uint64, error) {
27
43
if chainConfig .InteropTime == nil {
28
44
return 0 , errors .New ("interop time not set in chain config" )
29
45
}
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
31
53
}
32
54
33
55
// TxToInteropAccessList returns the interop specific access list storage keys for a transaction.
0 commit comments