diff --git a/core/forkid/forkid.go b/core/forkid/forkid.go index f5c51cb3c1e..7e5202657cd 100644 --- a/core/forkid/forkid.go +++ b/core/forkid/forkid.go @@ -244,8 +244,13 @@ func GatherForks(config *chain.Config, genesisTime uint64) (heightForks []uint64 heightForks = append(heightForks, *config.Aura.PosdaoTransition) } - if config.Bor != nil && config.Bor.GetAgraBlock() != nil { - heightForks = append(heightForks, config.Bor.GetAgraBlock().Uint64()) + if config.Bor != nil { + if config.Bor.GetAgraBlock() != nil { + heightForks = append(heightForks, config.Bor.GetAgraBlock().Uint64()) + } + if config.Bor.GetNapoliBlock() != nil { + heightForks = append(heightForks, config.Bor.GetNapoliBlock().Uint64()) + } } // Sort the fork block numbers & times to permit chronological XOR diff --git a/core/types/block_test.go b/core/types/block_test.go index 4e2a8303d3f..9db421134ac 100644 --- a/core/types/block_test.go +++ b/core/types/block_test.go @@ -42,7 +42,7 @@ import ( // the following 2 functions are replica for the test // This is a replica of `bor.GetValidatorBytes` function -// This was needed because currently, `IsParallelUniverse` will always return false. +// This was needed because currently, `IsNapoli` will always return false. func GetValidatorBytesTest(h *Header) []byte { if len(h.Extra) < ExtraVanityLength+ExtraSealLength { log.Error("length of extra is less than vanity and seal") diff --git a/core/vm/contracts.go b/core/vm/contracts.go index ccc55074486..b71f949ef1f 100644 --- a/core/vm/contracts.go +++ b/core/vm/contracts.go @@ -20,13 +20,13 @@ import ( "crypto/sha256" "encoding/binary" "errors" - "github.com/ledgerwatch/erigon-lib/crypto/blake2b" "math/big" "github.com/holiman/uint256" "github.com/ledgerwatch/erigon-lib/chain" libcommon "github.com/ledgerwatch/erigon-lib/common" + "github.com/ledgerwatch/erigon-lib/crypto/blake2b" libkzg "github.com/ledgerwatch/erigon-lib/crypto/kzg" "github.com/ledgerwatch/erigon/common" @@ -34,7 +34,7 @@ import ( "github.com/ledgerwatch/erigon/crypto" "github.com/ledgerwatch/erigon/crypto/bls12381" "github.com/ledgerwatch/erigon/crypto/bn256" - + "github.com/ledgerwatch/erigon/crypto/secp256r1" "github.com/ledgerwatch/erigon/params" //lint:ignore SA1019 Needed for precompile @@ -112,6 +112,19 @@ var PrecompiledContractsCancun = map[libcommon.Address]PrecompiledContract{ libcommon.BytesToAddress([]byte{0x0a}): &pointEvaluation{}, } +var PrecompiledContractsNapoli = map[libcommon.Address]PrecompiledContract{ + libcommon.BytesToAddress([]byte{0x01}): &ecrecover{}, + libcommon.BytesToAddress([]byte{0x02}): &sha256hash{}, + libcommon.BytesToAddress([]byte{0x03}): &ripemd160hash{}, + libcommon.BytesToAddress([]byte{0x04}): &dataCopy{}, + libcommon.BytesToAddress([]byte{0x05}): &bigModExp{eip2565: true}, + libcommon.BytesToAddress([]byte{0x06}): &bn256AddIstanbul{}, + libcommon.BytesToAddress([]byte{0x07}): &bn256ScalarMulIstanbul{}, + libcommon.BytesToAddress([]byte{0x08}): &bn256PairingIstanbul{}, + libcommon.BytesToAddress([]byte{0x09}): &blake2F{}, + libcommon.BytesToAddress([]byte{0x01, 0x00}): &p256Verify{}, +} + // PrecompiledContractsBLS contains the set of pre-compiled Ethereum // contracts specified in EIP-2537. These are exported for testing purposes. var PrecompiledContractsBLS = map[libcommon.Address]PrecompiledContract{ @@ -127,6 +140,7 @@ var PrecompiledContractsBLS = map[libcommon.Address]PrecompiledContract{ } var ( + PrecompiledAddressesNapoli []libcommon.Address PrecompiledAddressesCancun []libcommon.Address PrecompiledAddressesBerlin []libcommon.Address PrecompiledAddressesIstanbul []libcommon.Address @@ -150,11 +164,16 @@ func init() { for k := range PrecompiledContractsCancun { PrecompiledAddressesCancun = append(PrecompiledAddressesCancun, k) } + for k := range PrecompiledContractsNapoli { + PrecompiledAddressesNapoli = append(PrecompiledAddressesNapoli, k) + } } // ActivePrecompiles returns the precompiles enabled with the current configuration. func ActivePrecompiles(rules *chain.Rules) []libcommon.Address { switch { + case rules.IsNapoli: + return PrecompiledAddressesNapoli case rules.IsCancun: return PrecompiledAddressesCancun case rules.IsBerlin: @@ -1098,3 +1117,37 @@ func (c *pointEvaluation) RequiredGas(input []byte) uint64 { func (c *pointEvaluation) Run(input []byte) ([]byte, error) { return libkzg.PointEvaluationPrecompile(input) } + +// P256VERIFY (secp256r1 signature verification) +// implemented as a native contract +type p256Verify struct{} + +// RequiredGas returns the gas required to execute the precompiled contract +func (c *p256Verify) RequiredGas(input []byte) uint64 { + return params.P256VerifyGas +} + +// Run executes the precompiled contract with given 160 bytes of param, returning the output and the used gas +func (c *p256Verify) Run(input []byte) ([]byte, error) { + // Required input length is 160 bytes + const p256VerifyInputLength = 160 + // Check the input length + if len(input) != p256VerifyInputLength { + // Input length is invalid + return nil, nil + } + + // Extract the hash, r, s, x, y from the input + hash := input[0:32] + r, s := new(big.Int).SetBytes(input[32:64]), new(big.Int).SetBytes(input[64:96]) + x, y := new(big.Int).SetBytes(input[96:128]), new(big.Int).SetBytes(input[128:160]) + + // Verify the secp256r1 signature + if secp256r1.Verify(hash, r, s, x, y) { + // Signature is valid + return common.LeftPadBytes(big1.Bytes(), 32), nil + } else { + // Signature is invalid + return nil, nil + } +} diff --git a/core/vm/contracts_test.go b/core/vm/contracts_test.go index a9ca23ef1b6..d9b05437a71 100644 --- a/core/vm/contracts_test.go +++ b/core/vm/contracts_test.go @@ -48,26 +48,27 @@ type precompiledFailureTest struct { // allPrecompiles does not map to the actual set of precompiles, as it also contains // repriced versions of precompiles at certain slots var allPrecompiles = map[libcommon.Address]PrecompiledContract{ - libcommon.BytesToAddress([]byte{1}): &ecrecover{}, - libcommon.BytesToAddress([]byte{2}): &sha256hash{}, - libcommon.BytesToAddress([]byte{3}): &ripemd160hash{}, - libcommon.BytesToAddress([]byte{4}): &dataCopy{}, - libcommon.BytesToAddress([]byte{5}): &bigModExp{eip2565: false}, - libcommon.BytesToAddress([]byte{0xf5}): &bigModExp{eip2565: true}, - libcommon.BytesToAddress([]byte{6}): &bn256AddIstanbul{}, - libcommon.BytesToAddress([]byte{7}): &bn256ScalarMulIstanbul{}, - libcommon.BytesToAddress([]byte{8}): &bn256PairingIstanbul{}, - libcommon.BytesToAddress([]byte{9}): &blake2F{}, - libcommon.BytesToAddress([]byte{10}): &bls12381G1Add{}, - libcommon.BytesToAddress([]byte{11}): &bls12381G1Mul{}, - libcommon.BytesToAddress([]byte{12}): &bls12381G1MultiExp{}, - libcommon.BytesToAddress([]byte{13}): &bls12381G2Add{}, - libcommon.BytesToAddress([]byte{14}): &bls12381G2Mul{}, - libcommon.BytesToAddress([]byte{15}): &bls12381G2MultiExp{}, - libcommon.BytesToAddress([]byte{16}): &bls12381Pairing{}, - libcommon.BytesToAddress([]byte{17}): &bls12381MapG1{}, - libcommon.BytesToAddress([]byte{18}): &bls12381MapG2{}, - libcommon.BytesToAddress([]byte{20}): &pointEvaluation{}, + libcommon.BytesToAddress([]byte{1}): &ecrecover{}, + libcommon.BytesToAddress([]byte{2}): &sha256hash{}, + libcommon.BytesToAddress([]byte{3}): &ripemd160hash{}, + libcommon.BytesToAddress([]byte{4}): &dataCopy{}, + libcommon.BytesToAddress([]byte{5}): &bigModExp{eip2565: false}, + libcommon.BytesToAddress([]byte{0xf5}): &bigModExp{eip2565: true}, + libcommon.BytesToAddress([]byte{6}): &bn256AddIstanbul{}, + libcommon.BytesToAddress([]byte{7}): &bn256ScalarMulIstanbul{}, + libcommon.BytesToAddress([]byte{8}): &bn256PairingIstanbul{}, + libcommon.BytesToAddress([]byte{9}): &blake2F{}, + libcommon.BytesToAddress([]byte{10}): &bls12381G1Add{}, + libcommon.BytesToAddress([]byte{11}): &bls12381G1Mul{}, + libcommon.BytesToAddress([]byte{12}): &bls12381G1MultiExp{}, + libcommon.BytesToAddress([]byte{13}): &bls12381G2Add{}, + libcommon.BytesToAddress([]byte{14}): &bls12381G2Mul{}, + libcommon.BytesToAddress([]byte{15}): &bls12381G2MultiExp{}, + libcommon.BytesToAddress([]byte{16}): &bls12381Pairing{}, + libcommon.BytesToAddress([]byte{17}): &bls12381MapG1{}, + libcommon.BytesToAddress([]byte{18}): &bls12381MapG2{}, + libcommon.BytesToAddress([]byte{20}): &pointEvaluation{}, + libcommon.BytesToAddress([]byte{0x01, 0x00}): &p256Verify{}, } // EIP-152 test vectors @@ -400,3 +401,19 @@ func BenchmarkPrecompiledBLS12381G2MultiExpWorstCase(b *testing.B) { } benchmarkPrecompiled(b, "0f", testcase) } + +// Benchmarks the sample inputs from the P256VERIFY precompile. +func BenchmarkPrecompiledP256Verify(b *testing.B) { + testcase := precompiledTest{ + Input: "4cee90eb86eaa050036147a12d49004b6b9c72bd725d39d4785011fe190f0b4da73bd4903f0ce3b639bbbf6e8e80d16931ff4bcf5993d58468e8fb19086e8cac36dbcd03009df8c59286b162af3bd7fcc0450c9aa81be5d10d312af6c66b1d604aebd3099c618202fcfe16ae7770b0c49ab5eadf74b754204a3bb6060e44eff37618b065f9832de4ca6ca971a7a1adc826d0f7c00181a5fb2ddf79ae00b4e10e", + Expected: "0000000000000000000000000000000000000000000000000000000000000001", + Name: "p256Verify", + } + benchmarkPrecompiled(b, "100", testcase) +} + +func TestPrecompiledP256Verify(t *testing.T) { + t.Parallel() + + testJson("p256Verify", "100", t) +} diff --git a/core/vm/evm.go b/core/vm/evm.go index dc5dce586c8..56ffc3bc2fa 100644 --- a/core/vm/evm.go +++ b/core/vm/evm.go @@ -37,6 +37,8 @@ var emptyCodeHash = crypto.Keccak256Hash(nil) func (evm *EVM) precompile(addr libcommon.Address) (PrecompiledContract, bool) { var precompiles map[libcommon.Address]PrecompiledContract switch { + case evm.chainRules.IsNapoli: + precompiles = PrecompiledContractsNapoli case evm.chainRules.IsCancun: precompiles = PrecompiledContractsCancun case evm.chainRules.IsBerlin: diff --git a/core/vm/interpreter.go b/core/vm/interpreter.go index 161068229bf..e2cf325c105 100644 --- a/core/vm/interpreter.go +++ b/core/vm/interpreter.go @@ -128,6 +128,8 @@ func NewEVMInterpreter(evm *EVM, cfg Config) *EVMInterpreter { jt = &pragueInstructionSet case evm.ChainRules().IsCancun: jt = &cancunInstructionSet + case evm.ChainRules().IsNapoli: + jt = &napoliInstructionSet case evm.ChainRules().IsShanghai: jt = &shanghaiInstructionSet case evm.ChainRules().IsLondon: diff --git a/core/vm/jump_table.go b/core/vm/jump_table.go index 047c9f53845..806ae494133 100644 --- a/core/vm/jump_table.go +++ b/core/vm/jump_table.go @@ -61,6 +61,7 @@ var ( berlinInstructionSet = newBerlinInstructionSet() londonInstructionSet = newLondonInstructionSet() shanghaiInstructionSet = newShanghaiInstructionSet() + napoliInstructionSet = newNapoliInstructionSet() cancunInstructionSet = newCancunInstructionSet() pragueInstructionSet = newPragueInstructionSet() ) @@ -99,12 +100,18 @@ func newPragueInstructionSet() JumpTable { // constantinople, istanbul, petersburg, berlin, london, paris, shanghai, // and cancun instructions. func newCancunInstructionSet() JumpTable { + instructionSet := newNapoliInstructionSet() + enable4844(&instructionSet) // BLOBHASH opcode + enable7516(&instructionSet) // BLOBBASEFEE opcode + validateAndFillMaxStack(&instructionSet) + return instructionSet +} + +func newNapoliInstructionSet() JumpTable { instructionSet := newShanghaiInstructionSet() enable1153(&instructionSet) // Transient storage opcodes - enable4844(&instructionSet) // BLOBHASH opcode enable5656(&instructionSet) // MCOPY opcode enable6780(&instructionSet) // SELFDESTRUCT only in same transaction - enable7516(&instructionSet) // BLOBBASEFEE opcode validateAndFillMaxStack(&instructionSet) return instructionSet } diff --git a/core/vm/testdata/precompiles/p256Verify.json b/core/vm/testdata/precompiles/p256Verify.json new file mode 100644 index 00000000000..54723147a51 --- /dev/null +++ b/core/vm/testdata/precompiles/p256Verify.json @@ -0,0 +1,37 @@ +[ + { + "Input": "4cee90eb86eaa050036147a12d49004b6b9c72bd725d39d4785011fe190f0b4da73bd4903f0ce3b639bbbf6e8e80d16931ff4bcf5993d58468e8fb19086e8cac36dbcd03009df8c59286b162af3bd7fcc0450c9aa81be5d10d312af6c66b1d604aebd3099c618202fcfe16ae7770b0c49ab5eadf74b754204a3bb6060e44eff37618b065f9832de4ca6ca971a7a1adc826d0f7c00181a5fb2ddf79ae00b4e10e", + "Expected": "0000000000000000000000000000000000000000000000000000000000000001", + "Gas": 3450, + "Name": "CallP256Verify", + "NoBenchmark": false + }, + { + "Input": "b94d27b9934d3e08a52e52d7da7dabfac484efe37a5380ee9088f7ace2efcde9414de3726ee4d237b410c1d85ebcb05553dc578561d9f7942b7250795beb9b9027b657067322fc00ab35263fde0acabf998cd9fcf1282df9555f85dba7bdbbe2dc90f74c9e210bc3e0c60aeaa03729c9e6acde4a048ee58fd2e466c1e7b0374e606b8c22ad2985df7d792ff344f03ce94a079da801006b13640bc5af7932a7b9", + "Expected": "0000000000000000000000000000000000000000000000000000000000000001", + "Gas": 3450, + "Name": "CallP256Verify", + "NoBenchmark": false + }, + { + "Input": "b94d27b9934d3e08a52e52d7da7dabfac484efe37a5380ee9088f7ace2efcde9b35d6a4f7f6fc5620c97d4287696f5174b3d37fa537b74b5fc26997ba79c725d62fe5e5fe6da76eec924e822c5ef853ede6c17069a9e9133a38f87d61599f68e7d5f3c812a255436846ee84a262b79ec4d0783afccf2433deabdca9ecf62bef5ff24e90988c7f139d378549c3a8bc6c94e6a1c911c1e02e6f48ed65aaf3d296e", + "Expected": "0000000000000000000000000000000000000000000000000000000000000001", + "Gas": 3450, + "Name": "CallP256Verify", + "NoBenchmark": false + }, + { + "Input": "b94d27b9934d3e08a52e52d7da7dabfac484efe37a5380ee9088f7ace2efcde9c29c3df6ce3431b6f030b1b68b1589508ad9d1a149830489c638653aa4b08af93f6e86a9a7643403b6f5c593410d9f7234a8cd27309bce90447073ce17476850615ff147863bc8652be1e369444f90bbc5f9df05a26362e609f73ab1f1839fe3cd34fd2ae672c110671d49115825fc56b5148321aabe5ba39f2b46f71149cff9", + "Expected": "", + "Gas": 3450, + "Name": "CallP256Verify", + "NoBenchmark": false + }, + { + "Input": "b94d27b9934d3e08a52e52d7da7dabfac484efe37a5380ee9088f7ace2efcde9", + "Expected": "", + "Gas": 3450, + "Name": "CallP256Verify", + "NoBenchmark": false + } +] \ No newline at end of file diff --git a/crypto/secp256r1/publickey.go b/crypto/secp256r1/publickey.go new file mode 100644 index 00000000000..9b84044efa0 --- /dev/null +++ b/crypto/secp256r1/publickey.go @@ -0,0 +1,26 @@ +package secp256r1 + +import ( + "crypto/ecdsa" + "crypto/elliptic" + "math/big" +) + +// Generates approptiate public key format from given coordinates +func newPublicKey(x, y *big.Int) *ecdsa.PublicKey { + // Check if the given coordinates are valid + if x == nil || y == nil || !elliptic.P256().IsOnCurve(x, y) { + return nil + } + + // Check if the given coordinates are the reference point (infinity) + if x.Sign() == 0 && y.Sign() == 0 { + return nil + } + + return &ecdsa.PublicKey{ + Curve: elliptic.P256(), + X: x, + Y: y, + } +} diff --git a/crypto/secp256r1/verifier.go b/crypto/secp256r1/verifier.go new file mode 100644 index 00000000000..ccc0786610b --- /dev/null +++ b/crypto/secp256r1/verifier.go @@ -0,0 +1,21 @@ +package secp256r1 + +import ( + "crypto/ecdsa" + "math/big" +) + +// Verifies the given signature (r, s) for the given hash and public key (x, y). +func Verify(hash []byte, r, s, x, y *big.Int) bool { + // Create the public key format + publicKey := newPublicKey(x, y) + + // Check if they are invalid public key coordinates + if publicKey == nil { + return false + } + + // Verify the signature with the public key, + // then return true if it's valid, false otherwise + return ecdsa.Verify(publicKey, hash, r, s) +} diff --git a/erigon-lib/chain/chain_config.go b/erigon-lib/chain/chain_config.go index bb5125660a3..4d2069ee396 100644 --- a/erigon-lib/chain/chain_config.go +++ b/erigon-lib/chain/chain_config.go @@ -90,6 +90,8 @@ type BorConfig interface { fmt.Stringer IsAgra(num uint64) bool GetAgraBlock() *big.Int + IsNapoli(num uint64) bool + GetNapoliBlock() *big.Int } func (c *Config) String() string { @@ -214,6 +216,11 @@ func (c *Config) IsAgra(num uint64) bool { return (c != nil) && (c.Bor != nil) && c.Bor.IsAgra(num) } +// Refer to https://forum.polygon.technology/t/pip-33-napoli-upgrade +func (c *Config) IsNapoli(num uint64) bool { + return (c != nil) && (c.Bor != nil) && c.Bor.IsNapoli(num) +} + // IsCancun returns whether time is either equal to the Cancun fork time or greater. func (c *Config) IsCancun(time uint64) bool { return isForked(c.CancunTime, time) @@ -484,11 +491,13 @@ func borKeyValueConfigHelper[T uint64 | common.Address](field map[string]T, numb // Rules is a one time interface meaning that it shouldn't be used in between transition // phases. type Rules struct { - ChainID *big.Int - IsHomestead, IsTangerineWhistle, IsSpuriousDragon bool - IsByzantium, IsConstantinople, IsPetersburg, IsIstanbul bool - IsBerlin, IsLondon, IsShanghai, IsCancun, IsPrague bool - IsAura bool + ChainID *big.Int + IsHomestead, IsTangerineWhistle, IsSpuriousDragon bool + IsByzantium, IsConstantinople, IsPetersburg bool + IsIstanbul, IsBerlin, IsLondon, IsShanghai bool + IsCancun, IsNapoli bool + IsPrague bool + IsAura bool } // 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 { IsLondon: c.IsLondon(num), IsShanghai: c.IsShanghai(time) || c.IsAgra(num), IsCancun: c.IsCancun(time), + IsNapoli: c.IsNapoli(num), IsPrague: c.IsPrague(time), IsAura: c.Aura != nil, } diff --git a/erigon-lib/txpool/pool.go b/erigon-lib/txpool/pool.go index 88026073a99..a3eb55f255f 100644 --- a/erigon-lib/txpool/pool.go +++ b/erigon-lib/txpool/pool.go @@ -945,7 +945,7 @@ func (p *TxPool) isShanghai() bool { } func (p *TxPool) isAgra() bool { - // once this flag has been set for the first time we no longer need to check the timestamp + // once this flag has been set for the first time we no longer need to check the block set := p.isPostAgra.Load() if set { return true diff --git a/params/protocol_params.go b/params/protocol_params.go index 33ffda9a94c..8b8c37325ae 100644 --- a/params/protocol_params.go +++ b/params/protocol_params.go @@ -168,6 +168,9 @@ const ( // EIP-4844: Shard Blob Transactions PointEvaluationGas uint64 = 50000 + + // PIP-27: secp256r1 elliptic curve signature verifier gas price + P256VerifyGas uint64 = 3450 ) // EIP-4788: Beacon block root in the EVM diff --git a/polygon/bor/bor.go b/polygon/bor/bor.go index d37f9888004..aef97e200cb 100644 --- a/polygon/bor/bor.go +++ b/polygon/bor/bor.go @@ -550,7 +550,7 @@ func ValidateHeaderUnusedFields(header *types.Header) error { return consensus.ErrUnexpectedWithdrawals } - return nil + return misc.VerifyAbsenceOfCancunHeaderFields(header) } // verifyCascadingFields verifies all the header fields that are not standalone, @@ -897,7 +897,7 @@ func (c *Bor) Prepare(chain consensus.ChainHeaderReader, header *types.Header, s // sort validator by address sort.Sort(valset.ValidatorsByAddress(newValidators)) - if c.config.IsParallelUniverse(header.Number.Uint64()) { + if c.config.IsNapoli(header.Number.Uint64()) { // PIP-16: Transaction Dependency Data var tempValidatorBytes []byte for _, validator := range newValidators { @@ -921,7 +921,7 @@ func (c *Bor) Prepare(chain consensus.ChainHeaderReader, header *types.Header, s header.Extra = append(header.Extra, validator.HeaderBytes()...) } } - } else if c.config.IsParallelUniverse(header.Number.Uint64()) { + } else if c.config.IsNapoli(header.Number.Uint64()) { // PIP-16: Transaction Dependency Data blockExtraData := &BlockExtraData{ ValidatorBytes: nil, TxDependency: nil, @@ -1584,7 +1584,7 @@ func GetTxDependency(b *types.Block) [][]uint64 { func GetValidatorBytes(h *types.Header, config *borcfg.BorConfig) []byte { tempExtra := h.Extra - if !config.IsParallelUniverse(h.Number.Uint64()) { + if !config.IsNapoli(h.Number.Uint64()) { return tempExtra[types.ExtraVanityLength : len(tempExtra)-types.ExtraSealLength] } diff --git a/polygon/bor/borcfg/bor_config.go b/polygon/bor/borcfg/bor_config.go index d73f20a830a..6c02f069b82 100644 --- a/polygon/bor/borcfg/bor_config.go +++ b/polygon/bor/borcfg/bor_config.go @@ -20,14 +20,13 @@ type BorConfig struct { OverrideStateSyncRecords map[string]int `json:"overrideStateSyncRecords"` // override state records count BlockAlloc map[string]interface{} `json:"blockAlloc"` - JaipurBlock *big.Int `json:"jaipurBlock"` // Jaipur switch block (nil = no fork, 0 = already on jaipur) - DelhiBlock *big.Int `json:"delhiBlock"` // Delhi switch block (nil = no fork, 0 = already on delhi) - IndoreBlock *big.Int `json:"indoreBlock"` // Indore switch block (nil = no fork, 0 = already on indore) - AgraBlock *big.Int `json:"agraBlock"` // Agra switch block (nil = no fork, 0 = already in agra) + JaipurBlock *big.Int `json:"jaipurBlock"` // Jaipur switch block (nil = no fork, 0 = already on Jaipur) + DelhiBlock *big.Int `json:"delhiBlock"` // Delhi switch block (nil = no fork, 0 = already on Delhi) + IndoreBlock *big.Int `json:"indoreBlock"` // Indore switch block (nil = no fork, 0 = already on Indore) + AgraBlock *big.Int `json:"agraBlock"` // Agra switch block (nil = no fork, 0 = already on Agra) + NapoliBlock *big.Int `json:"napoliBlock"` // Napoli switch block (nil = no fork, 0 = already on Napoli) StateSyncConfirmationDelay map[string]uint64 `json:"stateSyncConfirmationDelay"` // StateSync Confirmation Delay, in seconds, to calculate `to` - ParallelUniverseBlock *big.Int `json:"parallelUniverseBlock"` // TODO: update all occurrence, change name and finalize number (hardfork for block-stm related changes) - sprints sprints } @@ -126,15 +125,13 @@ func (c *BorConfig) GetAgraBlock() *big.Int { return c.AgraBlock } -// TODO: modify this function once the block number is finalized -func (c *BorConfig) IsParallelUniverse(number uint64) bool { - if c.ParallelUniverseBlock != nil { - if c.ParallelUniverseBlock.Cmp(big.NewInt(0)) == 0 { - return false - } - } +// Refer to https://forum.polygon.technology/t/pip-33-napoli-upgrade +func (c *BorConfig) IsNapoli(num uint64) bool { + return isForked(c.NapoliBlock, num) +} - return isForked(c.ParallelUniverseBlock, number) +func (c *BorConfig) GetNapoliBlock() *big.Int { + return c.NapoliBlock } func (c *BorConfig) CalculateStateSyncDelay(number uint64) uint64 {