Skip to content

Commit b38e17e

Browse files
Implement PIP-33: Napoli Hardfork (#8975)
Initial support of the upcoming Napoli hard fork on Polygon – see [PIP-33](https://forum.polygon.technology/t/pip-33-napoli-upgrade). Per [PIP-31](https://github.com/maticnetwork/Polygon-Improvement-Proposals/blob/main/PIPs/PIP-31.md), it parallels the [Cancun](https://github.com/ethereum/execution-specs/blob/master/network-upgrades/mainnet-upgrades/cancun.md) upgrade of Ethereum, but does not include [EIP-4788](https://eips.ethereum.org/EIPS/eip-4788), [EIP-4844](https://eips.ethereum.org/EIPS/eip-4844), [EIP-7516](https://eips.ethereum.org/EIPS/eip-7516). In other words, Napoli includes [EIP-1153](https://eips.ethereum.org/EIPS/eip-1153), [EIP-5656](https://eips.ethereum.org/EIPS/eip-5656), [EIP-6780](https://eips.ethereum.org/EIPS/eip-6780) from Cancun. This PR implements [PIP-31](https://github.com/maticnetwork/Polygon-Improvement-Proposals/blob/main/PIPs/PIP-31.md), [PIP-16: Transaction Dependency Data](https://github.com/maticnetwork/Polygon-Improvement-Proposals/blob/main/PIPs/PIP-16.md) (by merging `ParallelUniverseBlock` into `NapoliBlock`; the bulk of PIP-16 was implemented in PR #8037), and [PIP-27: Precompiled for secp256r1 Curve Support](https://github.com/maticnetwork/Polygon-Improvement-Proposals/blob/main/PIPs/PIP-27.md) ([EIP-7212](https://eips.ethereum.org/EIPS/eip-7212); see also maticnetwork/bor#1069 & ethereum/go-ethereum#27540). --------- Co-authored-by: Anshal Shukla <[email protected]>
1 parent 8f6fe88 commit b38e17e

File tree

15 files changed

+231
-51
lines changed

15 files changed

+231
-51
lines changed

core/forkid/forkid.go

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -244,8 +244,13 @@ func GatherForks(config *chain.Config, genesisTime uint64) (heightForks []uint64
244244
heightForks = append(heightForks, *config.Aura.PosdaoTransition)
245245
}
246246

247-
if config.Bor != nil && config.Bor.GetAgraBlock() != nil {
248-
heightForks = append(heightForks, config.Bor.GetAgraBlock().Uint64())
247+
if config.Bor != nil {
248+
if config.Bor.GetAgraBlock() != nil {
249+
heightForks = append(heightForks, config.Bor.GetAgraBlock().Uint64())
250+
}
251+
if config.Bor.GetNapoliBlock() != nil {
252+
heightForks = append(heightForks, config.Bor.GetNapoliBlock().Uint64())
253+
}
249254
}
250255

251256
// Sort the fork block numbers & times to permit chronological XOR

core/types/block_test.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -42,7 +42,7 @@ import (
4242

4343
// the following 2 functions are replica for the test
4444
// This is a replica of `bor.GetValidatorBytes` function
45-
// This was needed because currently, `IsParallelUniverse` will always return false.
45+
// This was needed because currently, `IsNapoli` will always return false.
4646
func GetValidatorBytesTest(h *Header) []byte {
4747
if len(h.Extra) < ExtraVanityLength+ExtraSealLength {
4848
log.Error("length of extra is less than vanity and seal")

core/vm/contracts.go

Lines changed: 55 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -20,21 +20,21 @@ import (
2020
"crypto/sha256"
2121
"encoding/binary"
2222
"errors"
23-
"github.com/ledgerwatch/erigon-lib/crypto/blake2b"
2423
"math/big"
2524

2625
"github.com/holiman/uint256"
2726

2827
"github.com/ledgerwatch/erigon-lib/chain"
2928
libcommon "github.com/ledgerwatch/erigon-lib/common"
29+
"github.com/ledgerwatch/erigon-lib/crypto/blake2b"
3030
libkzg "github.com/ledgerwatch/erigon-lib/crypto/kzg"
3131

3232
"github.com/ledgerwatch/erigon/common"
3333
"github.com/ledgerwatch/erigon/common/math"
3434
"github.com/ledgerwatch/erigon/crypto"
3535
"github.com/ledgerwatch/erigon/crypto/bls12381"
3636
"github.com/ledgerwatch/erigon/crypto/bn256"
37-
37+
"github.com/ledgerwatch/erigon/crypto/secp256r1"
3838
"github.com/ledgerwatch/erigon/params"
3939

4040
//lint:ignore SA1019 Needed for precompile
@@ -112,6 +112,19 @@ var PrecompiledContractsCancun = map[libcommon.Address]PrecompiledContract{
112112
libcommon.BytesToAddress([]byte{0x0a}): &pointEvaluation{},
113113
}
114114

115+
var PrecompiledContractsNapoli = map[libcommon.Address]PrecompiledContract{
116+
libcommon.BytesToAddress([]byte{0x01}): &ecrecover{},
117+
libcommon.BytesToAddress([]byte{0x02}): &sha256hash{},
118+
libcommon.BytesToAddress([]byte{0x03}): &ripemd160hash{},
119+
libcommon.BytesToAddress([]byte{0x04}): &dataCopy{},
120+
libcommon.BytesToAddress([]byte{0x05}): &bigModExp{eip2565: true},
121+
libcommon.BytesToAddress([]byte{0x06}): &bn256AddIstanbul{},
122+
libcommon.BytesToAddress([]byte{0x07}): &bn256ScalarMulIstanbul{},
123+
libcommon.BytesToAddress([]byte{0x08}): &bn256PairingIstanbul{},
124+
libcommon.BytesToAddress([]byte{0x09}): &blake2F{},
125+
libcommon.BytesToAddress([]byte{0x01, 0x00}): &p256Verify{},
126+
}
127+
115128
// PrecompiledContractsBLS contains the set of pre-compiled Ethereum
116129
// contracts specified in EIP-2537. These are exported for testing purposes.
117130
var PrecompiledContractsBLS = map[libcommon.Address]PrecompiledContract{
@@ -127,6 +140,7 @@ var PrecompiledContractsBLS = map[libcommon.Address]PrecompiledContract{
127140
}
128141

129142
var (
143+
PrecompiledAddressesNapoli []libcommon.Address
130144
PrecompiledAddressesCancun []libcommon.Address
131145
PrecompiledAddressesBerlin []libcommon.Address
132146
PrecompiledAddressesIstanbul []libcommon.Address
@@ -150,11 +164,16 @@ func init() {
150164
for k := range PrecompiledContractsCancun {
151165
PrecompiledAddressesCancun = append(PrecompiledAddressesCancun, k)
152166
}
167+
for k := range PrecompiledContractsNapoli {
168+
PrecompiledAddressesNapoli = append(PrecompiledAddressesNapoli, k)
169+
}
153170
}
154171

155172
// ActivePrecompiles returns the precompiles enabled with the current configuration.
156173
func ActivePrecompiles(rules *chain.Rules) []libcommon.Address {
157174
switch {
175+
case rules.IsNapoli:
176+
return PrecompiledAddressesNapoli
158177
case rules.IsCancun:
159178
return PrecompiledAddressesCancun
160179
case rules.IsBerlin:
@@ -1098,3 +1117,37 @@ func (c *pointEvaluation) RequiredGas(input []byte) uint64 {
10981117
func (c *pointEvaluation) Run(input []byte) ([]byte, error) {
10991118
return libkzg.PointEvaluationPrecompile(input)
11001119
}
1120+
1121+
// P256VERIFY (secp256r1 signature verification)
1122+
// implemented as a native contract
1123+
type p256Verify struct{}
1124+
1125+
// RequiredGas returns the gas required to execute the precompiled contract
1126+
func (c *p256Verify) RequiredGas(input []byte) uint64 {
1127+
return params.P256VerifyGas
1128+
}
1129+
1130+
// Run executes the precompiled contract with given 160 bytes of param, returning the output and the used gas
1131+
func (c *p256Verify) Run(input []byte) ([]byte, error) {
1132+
// Required input length is 160 bytes
1133+
const p256VerifyInputLength = 160
1134+
// Check the input length
1135+
if len(input) != p256VerifyInputLength {
1136+
// Input length is invalid
1137+
return nil, nil
1138+
}
1139+
1140+
// Extract the hash, r, s, x, y from the input
1141+
hash := input[0:32]
1142+
r, s := new(big.Int).SetBytes(input[32:64]), new(big.Int).SetBytes(input[64:96])
1143+
x, y := new(big.Int).SetBytes(input[96:128]), new(big.Int).SetBytes(input[128:160])
1144+
1145+
// Verify the secp256r1 signature
1146+
if secp256r1.Verify(hash, r, s, x, y) {
1147+
// Signature is valid
1148+
return common.LeftPadBytes(big1.Bytes(), 32), nil
1149+
} else {
1150+
// Signature is invalid
1151+
return nil, nil
1152+
}
1153+
}

core/vm/contracts_test.go

Lines changed: 37 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -48,26 +48,27 @@ type precompiledFailureTest struct {
4848
// allPrecompiles does not map to the actual set of precompiles, as it also contains
4949
// repriced versions of precompiles at certain slots
5050
var allPrecompiles = map[libcommon.Address]PrecompiledContract{
51-
libcommon.BytesToAddress([]byte{1}): &ecrecover{},
52-
libcommon.BytesToAddress([]byte{2}): &sha256hash{},
53-
libcommon.BytesToAddress([]byte{3}): &ripemd160hash{},
54-
libcommon.BytesToAddress([]byte{4}): &dataCopy{},
55-
libcommon.BytesToAddress([]byte{5}): &bigModExp{eip2565: false},
56-
libcommon.BytesToAddress([]byte{0xf5}): &bigModExp{eip2565: true},
57-
libcommon.BytesToAddress([]byte{6}): &bn256AddIstanbul{},
58-
libcommon.BytesToAddress([]byte{7}): &bn256ScalarMulIstanbul{},
59-
libcommon.BytesToAddress([]byte{8}): &bn256PairingIstanbul{},
60-
libcommon.BytesToAddress([]byte{9}): &blake2F{},
61-
libcommon.BytesToAddress([]byte{10}): &bls12381G1Add{},
62-
libcommon.BytesToAddress([]byte{11}): &bls12381G1Mul{},
63-
libcommon.BytesToAddress([]byte{12}): &bls12381G1MultiExp{},
64-
libcommon.BytesToAddress([]byte{13}): &bls12381G2Add{},
65-
libcommon.BytesToAddress([]byte{14}): &bls12381G2Mul{},
66-
libcommon.BytesToAddress([]byte{15}): &bls12381G2MultiExp{},
67-
libcommon.BytesToAddress([]byte{16}): &bls12381Pairing{},
68-
libcommon.BytesToAddress([]byte{17}): &bls12381MapG1{},
69-
libcommon.BytesToAddress([]byte{18}): &bls12381MapG2{},
70-
libcommon.BytesToAddress([]byte{20}): &pointEvaluation{},
51+
libcommon.BytesToAddress([]byte{1}): &ecrecover{},
52+
libcommon.BytesToAddress([]byte{2}): &sha256hash{},
53+
libcommon.BytesToAddress([]byte{3}): &ripemd160hash{},
54+
libcommon.BytesToAddress([]byte{4}): &dataCopy{},
55+
libcommon.BytesToAddress([]byte{5}): &bigModExp{eip2565: false},
56+
libcommon.BytesToAddress([]byte{0xf5}): &bigModExp{eip2565: true},
57+
libcommon.BytesToAddress([]byte{6}): &bn256AddIstanbul{},
58+
libcommon.BytesToAddress([]byte{7}): &bn256ScalarMulIstanbul{},
59+
libcommon.BytesToAddress([]byte{8}): &bn256PairingIstanbul{},
60+
libcommon.BytesToAddress([]byte{9}): &blake2F{},
61+
libcommon.BytesToAddress([]byte{10}): &bls12381G1Add{},
62+
libcommon.BytesToAddress([]byte{11}): &bls12381G1Mul{},
63+
libcommon.BytesToAddress([]byte{12}): &bls12381G1MultiExp{},
64+
libcommon.BytesToAddress([]byte{13}): &bls12381G2Add{},
65+
libcommon.BytesToAddress([]byte{14}): &bls12381G2Mul{},
66+
libcommon.BytesToAddress([]byte{15}): &bls12381G2MultiExp{},
67+
libcommon.BytesToAddress([]byte{16}): &bls12381Pairing{},
68+
libcommon.BytesToAddress([]byte{17}): &bls12381MapG1{},
69+
libcommon.BytesToAddress([]byte{18}): &bls12381MapG2{},
70+
libcommon.BytesToAddress([]byte{20}): &pointEvaluation{},
71+
libcommon.BytesToAddress([]byte{0x01, 0x00}): &p256Verify{},
7172
}
7273

7374
// EIP-152 test vectors
@@ -400,3 +401,19 @@ func BenchmarkPrecompiledBLS12381G2MultiExpWorstCase(b *testing.B) {
400401
}
401402
benchmarkPrecompiled(b, "0f", testcase)
402403
}
404+
405+
// Benchmarks the sample inputs from the P256VERIFY precompile.
406+
func BenchmarkPrecompiledP256Verify(b *testing.B) {
407+
testcase := precompiledTest{
408+
Input: "4cee90eb86eaa050036147a12d49004b6b9c72bd725d39d4785011fe190f0b4da73bd4903f0ce3b639bbbf6e8e80d16931ff4bcf5993d58468e8fb19086e8cac36dbcd03009df8c59286b162af3bd7fcc0450c9aa81be5d10d312af6c66b1d604aebd3099c618202fcfe16ae7770b0c49ab5eadf74b754204a3bb6060e44eff37618b065f9832de4ca6ca971a7a1adc826d0f7c00181a5fb2ddf79ae00b4e10e",
409+
Expected: "0000000000000000000000000000000000000000000000000000000000000001",
410+
Name: "p256Verify",
411+
}
412+
benchmarkPrecompiled(b, "100", testcase)
413+
}
414+
415+
func TestPrecompiledP256Verify(t *testing.T) {
416+
t.Parallel()
417+
418+
testJson("p256Verify", "100", t)
419+
}

core/vm/evm.go

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,8 @@ var emptyCodeHash = crypto.Keccak256Hash(nil)
3737
func (evm *EVM) precompile(addr libcommon.Address) (PrecompiledContract, bool) {
3838
var precompiles map[libcommon.Address]PrecompiledContract
3939
switch {
40+
case evm.chainRules.IsNapoli:
41+
precompiles = PrecompiledContractsNapoli
4042
case evm.chainRules.IsCancun:
4143
precompiles = PrecompiledContractsCancun
4244
case evm.chainRules.IsBerlin:

core/vm/interpreter.go

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -128,6 +128,8 @@ func NewEVMInterpreter(evm *EVM, cfg Config) *EVMInterpreter {
128128
jt = &pragueInstructionSet
129129
case evm.ChainRules().IsCancun:
130130
jt = &cancunInstructionSet
131+
case evm.ChainRules().IsNapoli:
132+
jt = &napoliInstructionSet
131133
case evm.ChainRules().IsShanghai:
132134
jt = &shanghaiInstructionSet
133135
case evm.ChainRules().IsLondon:

core/vm/jump_table.go

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -61,6 +61,7 @@ var (
6161
berlinInstructionSet = newBerlinInstructionSet()
6262
londonInstructionSet = newLondonInstructionSet()
6363
shanghaiInstructionSet = newShanghaiInstructionSet()
64+
napoliInstructionSet = newNapoliInstructionSet()
6465
cancunInstructionSet = newCancunInstructionSet()
6566
pragueInstructionSet = newPragueInstructionSet()
6667
)
@@ -99,12 +100,18 @@ func newPragueInstructionSet() JumpTable {
99100
// constantinople, istanbul, petersburg, berlin, london, paris, shanghai,
100101
// and cancun instructions.
101102
func newCancunInstructionSet() JumpTable {
103+
instructionSet := newNapoliInstructionSet()
104+
enable4844(&instructionSet) // BLOBHASH opcode
105+
enable7516(&instructionSet) // BLOBBASEFEE opcode
106+
validateAndFillMaxStack(&instructionSet)
107+
return instructionSet
108+
}
109+
110+
func newNapoliInstructionSet() JumpTable {
102111
instructionSet := newShanghaiInstructionSet()
103112
enable1153(&instructionSet) // Transient storage opcodes
104-
enable4844(&instructionSet) // BLOBHASH opcode
105113
enable5656(&instructionSet) // MCOPY opcode
106114
enable6780(&instructionSet) // SELFDESTRUCT only in same transaction
107-
enable7516(&instructionSet) // BLOBBASEFEE opcode
108115
validateAndFillMaxStack(&instructionSet)
109116
return instructionSet
110117
}
Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
[
2+
{
3+
"Input": "4cee90eb86eaa050036147a12d49004b6b9c72bd725d39d4785011fe190f0b4da73bd4903f0ce3b639bbbf6e8e80d16931ff4bcf5993d58468e8fb19086e8cac36dbcd03009df8c59286b162af3bd7fcc0450c9aa81be5d10d312af6c66b1d604aebd3099c618202fcfe16ae7770b0c49ab5eadf74b754204a3bb6060e44eff37618b065f9832de4ca6ca971a7a1adc826d0f7c00181a5fb2ddf79ae00b4e10e",
4+
"Expected": "0000000000000000000000000000000000000000000000000000000000000001",
5+
"Gas": 3450,
6+
"Name": "CallP256Verify",
7+
"NoBenchmark": false
8+
},
9+
{
10+
"Input": "b94d27b9934d3e08a52e52d7da7dabfac484efe37a5380ee9088f7ace2efcde9414de3726ee4d237b410c1d85ebcb05553dc578561d9f7942b7250795beb9b9027b657067322fc00ab35263fde0acabf998cd9fcf1282df9555f85dba7bdbbe2dc90f74c9e210bc3e0c60aeaa03729c9e6acde4a048ee58fd2e466c1e7b0374e606b8c22ad2985df7d792ff344f03ce94a079da801006b13640bc5af7932a7b9",
11+
"Expected": "0000000000000000000000000000000000000000000000000000000000000001",
12+
"Gas": 3450,
13+
"Name": "CallP256Verify",
14+
"NoBenchmark": false
15+
},
16+
{
17+
"Input": "b94d27b9934d3e08a52e52d7da7dabfac484efe37a5380ee9088f7ace2efcde9b35d6a4f7f6fc5620c97d4287696f5174b3d37fa537b74b5fc26997ba79c725d62fe5e5fe6da76eec924e822c5ef853ede6c17069a9e9133a38f87d61599f68e7d5f3c812a255436846ee84a262b79ec4d0783afccf2433deabdca9ecf62bef5ff24e90988c7f139d378549c3a8bc6c94e6a1c911c1e02e6f48ed65aaf3d296e",
18+
"Expected": "0000000000000000000000000000000000000000000000000000000000000001",
19+
"Gas": 3450,
20+
"Name": "CallP256Verify",
21+
"NoBenchmark": false
22+
},
23+
{
24+
"Input": "b94d27b9934d3e08a52e52d7da7dabfac484efe37a5380ee9088f7ace2efcde9c29c3df6ce3431b6f030b1b68b1589508ad9d1a149830489c638653aa4b08af93f6e86a9a7643403b6f5c593410d9f7234a8cd27309bce90447073ce17476850615ff147863bc8652be1e369444f90bbc5f9df05a26362e609f73ab1f1839fe3cd34fd2ae672c110671d49115825fc56b5148321aabe5ba39f2b46f71149cff9",
25+
"Expected": "",
26+
"Gas": 3450,
27+
"Name": "CallP256Verify",
28+
"NoBenchmark": false
29+
},
30+
{
31+
"Input": "b94d27b9934d3e08a52e52d7da7dabfac484efe37a5380ee9088f7ace2efcde9",
32+
"Expected": "",
33+
"Gas": 3450,
34+
"Name": "CallP256Verify",
35+
"NoBenchmark": false
36+
}
37+
]

crypto/secp256r1/publickey.go

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
package secp256r1
2+
3+
import (
4+
"crypto/ecdsa"
5+
"crypto/elliptic"
6+
"math/big"
7+
)
8+
9+
// Generates approptiate public key format from given coordinates
10+
func newPublicKey(x, y *big.Int) *ecdsa.PublicKey {
11+
// Check if the given coordinates are valid
12+
if x == nil || y == nil || !elliptic.P256().IsOnCurve(x, y) {
13+
return nil
14+
}
15+
16+
// Check if the given coordinates are the reference point (infinity)
17+
if x.Sign() == 0 && y.Sign() == 0 {
18+
return nil
19+
}
20+
21+
return &ecdsa.PublicKey{
22+
Curve: elliptic.P256(),
23+
X: x,
24+
Y: y,
25+
}
26+
}

crypto/secp256r1/verifier.go

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
package secp256r1
2+
3+
import (
4+
"crypto/ecdsa"
5+
"math/big"
6+
)
7+
8+
// Verifies the given signature (r, s) for the given hash and public key (x, y).
9+
func Verify(hash []byte, r, s, x, y *big.Int) bool {
10+
// Create the public key format
11+
publicKey := newPublicKey(x, y)
12+
13+
// Check if they are invalid public key coordinates
14+
if publicKey == nil {
15+
return false
16+
}
17+
18+
// Verify the signature with the public key,
19+
// then return true if it's valid, false otherwise
20+
return ecdsa.Verify(publicKey, hash, r, s)
21+
}

erigon-lib/chain/chain_config.go

Lines changed: 15 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -90,6 +90,8 @@ type BorConfig interface {
9090
fmt.Stringer
9191
IsAgra(num uint64) bool
9292
GetAgraBlock() *big.Int
93+
IsNapoli(num uint64) bool
94+
GetNapoliBlock() *big.Int
9395
}
9496

9597
func (c *Config) String() string {
@@ -214,6 +216,11 @@ func (c *Config) IsAgra(num uint64) bool {
214216
return (c != nil) && (c.Bor != nil) && c.Bor.IsAgra(num)
215217
}
216218

219+
// Refer to https://forum.polygon.technology/t/pip-33-napoli-upgrade
220+
func (c *Config) IsNapoli(num uint64) bool {
221+
return (c != nil) && (c.Bor != nil) && c.Bor.IsNapoli(num)
222+
}
223+
217224
// IsCancun returns whether time is either equal to the Cancun fork time or greater.
218225
func (c *Config) IsCancun(time uint64) bool {
219226
return isForked(c.CancunTime, time)
@@ -484,11 +491,13 @@ func borKeyValueConfigHelper[T uint64 | common.Address](field map[string]T, numb
484491
// Rules is a one time interface meaning that it shouldn't be used in between transition
485492
// phases.
486493
type Rules struct {
487-
ChainID *big.Int
488-
IsHomestead, IsTangerineWhistle, IsSpuriousDragon bool
489-
IsByzantium, IsConstantinople, IsPetersburg, IsIstanbul bool
490-
IsBerlin, IsLondon, IsShanghai, IsCancun, IsPrague bool
491-
IsAura bool
494+
ChainID *big.Int
495+
IsHomestead, IsTangerineWhistle, IsSpuriousDragon bool
496+
IsByzantium, IsConstantinople, IsPetersburg bool
497+
IsIstanbul, IsBerlin, IsLondon, IsShanghai bool
498+
IsCancun, IsNapoli bool
499+
IsPrague bool
500+
IsAura bool
492501
}
493502

494503
// Rules ensures c's ChainID is not nil and returns a new Rules instance
@@ -511,6 +520,7 @@ func (c *Config) Rules(num uint64, time uint64) *Rules {
511520
IsLondon: c.IsLondon(num),
512521
IsShanghai: c.IsShanghai(time) || c.IsAgra(num),
513522
IsCancun: c.IsCancun(time),
523+
IsNapoli: c.IsNapoli(num),
514524
IsPrague: c.IsPrague(time),
515525
IsAura: c.Aura != nil,
516526
}

erigon-lib/txpool/pool.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -945,7 +945,7 @@ func (p *TxPool) isShanghai() bool {
945945
}
946946

947947
func (p *TxPool) isAgra() bool {
948-
// once this flag has been set for the first time we no longer need to check the timestamp
948+
// once this flag has been set for the first time we no longer need to check the block
949949
set := p.isPostAgra.Load()
950950
if set {
951951
return true

0 commit comments

Comments
 (0)