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
https://github.com/maticnetwork/bor/pull/1069 &
https://github.com/ethereum/go-ethereum/pull/27540).

---------

Co-authored-by: Anshal Shukla <shukla.anshal85@gmail.com>
This commit is contained in:
Andrew Ashikhmin 2024-01-17 14:13:16 +01:00 committed by GitHub
parent 8f6fe88b29
commit b38e17e393
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
15 changed files with 231 additions and 51 deletions

View File

@ -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

View File

@ -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")

View File

@ -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
}
}

View File

@ -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)
}

View File

@ -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:

View File

@ -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:

View File

@ -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
}

View File

@ -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
}
]

View File

@ -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,
}
}

View File

@ -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)
}

View File

@ -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,
}

View File

@ -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

View File

@ -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

View File

@ -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]
}

View File

@ -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 {