Merge pull request #1139 from maticnetwork/v1.2.3-candidate

v1.2.3
This commit is contained in:
Manav Darji 2024-01-23 12:15:10 +05:30 committed by GitHub
commit 241af1fa1e
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
34 changed files with 352 additions and 192 deletions

View file

@ -23,3 +23,4 @@ borDockerBuildContext: "../../bor"
heimdallDockerBuildContext: "https://github.com/maticnetwork/heimdall.git#develop" heimdallDockerBuildContext: "https://github.com/maticnetwork/heimdall.git#develop"
sprintSizeBlockNumber: sprintSizeBlockNumber:
- '0' - '0'
devnetBorFlags: config,config,config

View file

@ -17,7 +17,6 @@
"bor": { "bor": {
"jaipurBlock": 23850000, "jaipurBlock": 23850000,
"delhiBlock": 38189056, "delhiBlock": 38189056,
"parallelUniverseBlock": 0,
"indoreBlock": 44934656, "indoreBlock": 44934656,
"stateSyncConfirmationDelay": { "stateSyncConfirmationDelay": {
"44934656": 128 "44934656": 128

View file

@ -17,7 +17,6 @@
"bor": { "bor": {
"jaipurBlock": 22770000, "jaipurBlock": 22770000,
"delhiBlock": 29638656, "delhiBlock": 29638656,
"parallelUniverseBlock": 0,
"indoreBlock": 37075456, "indoreBlock": 37075456,
"stateSyncConfirmationDelay": { "stateSyncConfirmationDelay": {
"37075456": 128 "37075456": 128

View file

@ -353,7 +353,7 @@ func (c *Bor) verifyHeader(chain consensus.ChainHeaderReader, header *types.Head
isSprintEnd := IsSprintStart(number+1, c.config.CalculateSprint(number)) isSprintEnd := IsSprintStart(number+1, c.config.CalculateSprint(number))
// Ensure that the extra-data contains a signer list on checkpoint, but none otherwise // Ensure that the extra-data contains a signer list on checkpoint, but none otherwise
signersBytes := len(header.GetValidatorBytes(c.config)) signersBytes := len(header.GetValidatorBytes(c.chainConfig))
if !isSprintEnd && signersBytes != 0 { if !isSprintEnd && signersBytes != 0 {
return errExtraValidators return errExtraValidators
@ -472,7 +472,7 @@ func (c *Bor) verifyCascadingFields(chain consensus.ChainHeaderReader, header *t
sort.Sort(valset.ValidatorsByAddress(newValidators)) sort.Sort(valset.ValidatorsByAddress(newValidators))
headerVals, err := valset.ParseValidators(header.GetValidatorBytes(c.config)) headerVals, err := valset.ParseValidators(header.GetValidatorBytes(c.chainConfig))
if err != nil { if err != nil {
return err return err
} }
@ -490,7 +490,7 @@ func (c *Bor) verifyCascadingFields(chain consensus.ChainHeaderReader, header *t
// verify the validator list in the last sprint block // verify the validator list in the last sprint block
if IsSprintStart(number, c.config.CalculateSprint(number)) { if IsSprintStart(number, c.config.CalculateSprint(number)) {
parentValidatorBytes := parent.GetValidatorBytes(c.config) parentValidatorBytes := parent.GetValidatorBytes(c.chainConfig)
validatorsBytes := make([]byte, len(snap.ValidatorSet.Validators)*validatorHeaderBytesLength) validatorsBytes := make([]byte, len(snap.ValidatorSet.Validators)*validatorHeaderBytesLength)
currentValidators := snap.ValidatorSet.Copy().Validators currentValidators := snap.ValidatorSet.Copy().Validators
@ -521,7 +521,7 @@ func (c *Bor) snapshot(chain consensus.ChainHeaderReader, number uint64, hash co
val := valset.NewValidator(signer, 1000) val := valset.NewValidator(signer, 1000)
validatorset := valset.NewValidatorSet([]*valset.Validator{val}) validatorset := valset.NewValidatorSet([]*valset.Validator{val})
snapshot := newSnapshot(c.config, c.signatures, number, hash, validatorset.Validators) snapshot := newSnapshot(c.chainConfig, c.signatures, number, hash, validatorset.Validators)
return snapshot, nil return snapshot, nil
} }
@ -541,7 +541,7 @@ func (c *Bor) snapshot(chain consensus.ChainHeaderReader, number uint64, hash co
// If an on-disk checkpoint snapshot can be found, use that // If an on-disk checkpoint snapshot can be found, use that
if number%checkpointInterval == 0 { if number%checkpointInterval == 0 {
if s, err := loadSnapshot(c.config, c.signatures, c.db, hash); err == nil { if s, err := loadSnapshot(c.chainConfig, c.config, c.signatures, c.db, hash); err == nil {
log.Trace("Loaded snapshot from disk", "number", number, "hash", hash) log.Trace("Loaded snapshot from disk", "number", number, "hash", hash)
snap = s snap = s
@ -570,7 +570,7 @@ func (c *Bor) snapshot(chain consensus.ChainHeaderReader, number uint64, hash co
} }
// new snap shot // new snap shot
snap = newSnapshot(c.config, c.signatures, number, hash, validators) snap = newSnapshot(c.chainConfig, c.signatures, number, hash, validators)
if err := snap.store(c.db); err != nil { if err := snap.store(c.db); err != nil {
return nil, err return nil, err
} }
@ -742,7 +742,7 @@ func (c *Bor) Prepare(chain consensus.ChainHeaderReader, header *types.Header) e
// sort validator by address // sort validator by address
sort.Sort(valset.ValidatorsByAddress(newValidators)) sort.Sort(valset.ValidatorsByAddress(newValidators))
if c.config.IsParallelUniverse(header.Number) { if c.chainConfig.IsCancun(header.Number) {
var tempValidatorBytes []byte var tempValidatorBytes []byte
for _, validator := range newValidators { for _, validator := range newValidators {
@ -766,7 +766,7 @@ func (c *Bor) Prepare(chain consensus.ChainHeaderReader, header *types.Header) e
header.Extra = append(header.Extra, validator.HeaderBytes()...) header.Extra = append(header.Extra, validator.HeaderBytes()...)
} }
} }
} else if c.config.IsParallelUniverse(header.Number) { } else if c.chainConfig.IsCancun(header.Number) {
blockExtraData := &types.BlockExtraData{ blockExtraData := &types.BlockExtraData{
ValidatorBytes: nil, ValidatorBytes: nil,
TxDependency: nil, TxDependency: nil,

View file

@ -15,7 +15,8 @@ import (
// Snapshot is the state of the authorization voting at a given point in time. // Snapshot is the state of the authorization voting at a given point in time.
type Snapshot struct { type Snapshot struct {
config *params.BorConfig // Consensus engine parameters to fine tune behavior chainConfig *params.ChainConfig
sigcache *lru.ARCCache // Cache of recent block signatures to speed up ecrecover sigcache *lru.ARCCache // Cache of recent block signatures to speed up ecrecover
Number uint64 `json:"number"` // Block number where the snapshot was created Number uint64 `json:"number"` // Block number where the snapshot was created
@ -28,14 +29,14 @@ type Snapshot struct {
// method does not initialize the set of recent signers, so only ever use if for // method does not initialize the set of recent signers, so only ever use if for
// the genesis block. // the genesis block.
func newSnapshot( func newSnapshot(
config *params.BorConfig, chainConfig *params.ChainConfig,
sigcache *lru.ARCCache, sigcache *lru.ARCCache,
number uint64, number uint64,
hash common.Hash, hash common.Hash,
validators []*valset.Validator, validators []*valset.Validator,
) *Snapshot { ) *Snapshot {
snap := &Snapshot{ snap := &Snapshot{
config: config, chainConfig: chainConfig,
sigcache: sigcache, sigcache: sigcache,
Number: number, Number: number,
Hash: hash, Hash: hash,
@ -47,7 +48,7 @@ func newSnapshot(
} }
// loadSnapshot loads an existing snapshot from the database. // loadSnapshot loads an existing snapshot from the database.
func loadSnapshot(config *params.BorConfig, sigcache *lru.ARCCache, db ethdb.Database, hash common.Hash) (*Snapshot, error) { func loadSnapshot(chainConfig *params.ChainConfig, config *params.BorConfig, sigcache *lru.ARCCache, db ethdb.Database, hash common.Hash) (*Snapshot, error) {
blob, err := db.Get(append([]byte("bor-"), hash[:]...)) blob, err := db.Get(append([]byte("bor-"), hash[:]...))
if err != nil { if err != nil {
return nil, err return nil, err
@ -61,7 +62,7 @@ func loadSnapshot(config *params.BorConfig, sigcache *lru.ARCCache, db ethdb.Dat
snap.ValidatorSet.UpdateValidatorMap() snap.ValidatorSet.UpdateValidatorMap()
snap.config = config snap.chainConfig = chainConfig
snap.sigcache = sigcache snap.sigcache = sigcache
// update total voting power // update total voting power
@ -85,7 +86,7 @@ func (s *Snapshot) store(db ethdb.Database) error {
// copy creates a deep copy of the snapshot, though not the individual votes. // copy creates a deep copy of the snapshot, though not the individual votes.
func (s *Snapshot) copy() *Snapshot { func (s *Snapshot) copy() *Snapshot {
cpy := &Snapshot{ cpy := &Snapshot{
config: s.config, chainConfig: s.chainConfig,
sigcache: s.sigcache, sigcache: s.sigcache,
Number: s.Number, Number: s.Number,
Hash: s.Hash, Hash: s.Hash,
@ -122,12 +123,12 @@ func (s *Snapshot) apply(headers []*types.Header) (*Snapshot, error) {
number := header.Number.Uint64() number := header.Number.Uint64()
// Delete the oldest signer from the recent list to allow it signing again // Delete the oldest signer from the recent list to allow it signing again
if number >= s.config.CalculateSprint(number) { if number >= s.chainConfig.Bor.CalculateSprint(number) {
delete(snap.Recents, number-s.config.CalculateSprint(number)) delete(snap.Recents, number-s.chainConfig.Bor.CalculateSprint(number))
} }
// Resolve the authorization key and check against signers // Resolve the authorization key and check against signers
signer, err := ecrecover(header, s.sigcache, s.config) signer, err := ecrecover(header, s.sigcache, s.chainConfig.Bor)
if err != nil { if err != nil {
return nil, err return nil, err
} }
@ -145,12 +146,12 @@ func (s *Snapshot) apply(headers []*types.Header) (*Snapshot, error) {
snap.Recents[number] = signer snap.Recents[number] = signer
// change validator set and change proposer // change validator set and change proposer
if number > 0 && (number+1)%s.config.CalculateSprint(number) == 0 { if number > 0 && (number+1)%s.chainConfig.Bor.CalculateSprint(number) == 0 {
if err := validateHeaderExtraField(header.Extra); err != nil { if err := validateHeaderExtraField(header.Extra); err != nil {
return nil, err return nil, err
} }
validatorBytes := header.GetValidatorBytes(s.config) validatorBytes := header.GetValidatorBytes(s.chainConfig)
// get validators from headers and use that for new validator set // get validators from headers and use that for new validator set
newVals, _ := valset.ParseValidators(validatorBytes) newVals, _ := valset.ParseValidators(validatorBytes)

View file

@ -121,34 +121,23 @@ func (mv *MVHashMap) Write(k Key, v Version, data interface{}) {
return return
}) })
cells.rw.RLock()
ci, ok := cells.tm.Get(v.TxnIndex)
cells.rw.RUnlock()
if ok {
if ci.(*WriteCell).incarnation > v.Incarnation {
panic(fmt.Errorf("existing transaction value does not have lower incarnation: %v, %v",
k, v.TxnIndex))
}
ci.(*WriteCell).flag = FlagDone
ci.(*WriteCell).incarnation = v.Incarnation
ci.(*WriteCell).data = data
} else {
cells.rw.Lock() cells.rw.Lock()
if ci, ok = cells.tm.Get(v.TxnIndex); !ok { if ci, ok := cells.tm.Get(v.TxnIndex); !ok {
cells.tm.Put(v.TxnIndex, &WriteCell{ cells.tm.Put(v.TxnIndex, &WriteCell{
flag: FlagDone, flag: FlagDone,
incarnation: v.Incarnation, incarnation: v.Incarnation,
data: data, data: data,
}) })
} else { } else {
if ci.(*WriteCell).incarnation > v.Incarnation {
panic(fmt.Errorf("existing transaction value does not have lower incarnation: %v, %v",
k, v.TxnIndex))
}
ci.(*WriteCell).flag = FlagDone ci.(*WriteCell).flag = FlagDone
ci.(*WriteCell).incarnation = v.Incarnation ci.(*WriteCell).incarnation = v.Incarnation
ci.(*WriteCell).data = data ci.(*WriteCell).data = data
} }
cells.rw.Unlock() cells.rw.Unlock()
}
} }
func (mv *MVHashMap) ReadStorage(k Key, fallBack func() any) any { func (mv *MVHashMap) ReadStorage(k Key, fallBack func() any) any {
@ -166,13 +155,13 @@ func (mv *MVHashMap) MarkEstimate(k Key, txIdx int) {
panic(fmt.Errorf("path must already exist")) panic(fmt.Errorf("path must already exist"))
}) })
cells.rw.RLock() cells.rw.Lock()
if ci, ok := cells.tm.Get(txIdx); !ok { if ci, ok := cells.tm.Get(txIdx); !ok {
panic(fmt.Sprintf("should not happen - cell should be present for path. TxIdx: %v, path, %x, cells keys: %v", txIdx, k, cells.tm.Keys())) panic(fmt.Sprintf("should not happen - cell should be present for path. TxIdx: %v, path, %x, cells keys: %v", txIdx, k, cells.tm.Keys()))
} else { } else {
ci.(*WriteCell).flag = FlagEstimate ci.(*WriteCell).flag = FlagEstimate
} }
cells.rw.RUnlock() cells.rw.Unlock()
} }
func (mv *MVHashMap) Delete(k Key, txIdx int) { func (mv *MVHashMap) Delete(k Key, txIdx int) {
@ -233,8 +222,8 @@ func (mv *MVHashMap) Read(k Key, txIdx int) (res MVReadResult) {
} }
cells.rw.RLock() cells.rw.RLock()
fk, fv := cells.tm.Floor(txIdx - 1) fk, fv := cells.tm.Floor(txIdx - 1)
cells.rw.RUnlock()
if fk != nil && fv != nil { if fk != nil && fv != nil {
c := fv.(*WriteCell) c := fv.(*WriteCell)
@ -253,6 +242,8 @@ func (mv *MVHashMap) Read(k Key, txIdx int) (res MVReadResult) {
} }
} }
cells.rw.RUnlock()
return return
} }

View file

@ -288,6 +288,11 @@ func (p *ParallelStateProcessor) Process(block *types.Block, statedb *state.Stat
deps := GetDeps(blockTxDependency) deps := GetDeps(blockTxDependency)
if !VerifyDeps(deps) || len(blockTxDependency) != len(block.Transactions()) {
blockTxDependency = nil
deps = make(map[int][]int)
}
if blockTxDependency != nil { if blockTxDependency != nil {
metadata = true metadata = true
} }
@ -308,7 +313,6 @@ func (p *ParallelStateProcessor) Process(block *types.Block, statedb *state.Stat
shouldDelayFeeCal = false shouldDelayFeeCal = false
} }
if len(blockTxDependency) != len(block.Transactions()) {
task := &ExecutionTask{ task := &ExecutionTask{
msg: *msg, msg: *msg,
config: p.config, config: p.config,
@ -333,32 +337,6 @@ func (p *ParallelStateProcessor) Process(block *types.Block, statedb *state.Stat
} }
tasks = append(tasks, task) tasks = append(tasks, task)
} else {
task := &ExecutionTask{
msg: *msg,
config: p.config,
gasLimit: block.GasLimit(),
blockNumber: blockNumber,
blockHash: blockHash,
tx: tx,
index: i,
cleanStateDB: cleansdb,
finalStateDB: statedb,
blockChain: p.bc,
header: header,
evmConfig: cfg,
shouldDelayFeeCal: &shouldDelayFeeCal,
sender: msg.From,
totalUsedGas: usedGas,
receipts: &receipts,
allLogs: &allLogs,
dependencies: nil,
coinbase: coinbase,
blockContext: blockContext,
}
tasks = append(tasks, task)
}
} }
backupStateDB := statedb.Copy() backupStateDB := statedb.Copy()
@ -427,3 +405,21 @@ func GetDeps(txDependency [][]uint64) map[int][]int {
return deps return deps
} }
// returns true if dependencies are correct
func VerifyDeps(deps map[int][]int) bool {
// number of transactions in the block
n := len(deps)
// Handle out-of-range and circular dependency problem
for i := 0; i <= n-1; i++ {
val := deps[i]
for _, depTx := range val {
if depTx >= n || depTx >= i {
return false
}
}
}
return true
}

View file

@ -0,0 +1,30 @@
package core
import (
"testing"
"github.com/stretchr/testify/assert"
)
func TestMetadata(t *testing.T) {
t.Parallel()
correctTxDependency := [][]uint64{{}, {0}, {}, {1}, {3}, {}, {0, 2}, {5}, {}, {8}}
wrongTxDependency := [][]uint64{{0}}
wrongTxDependencyCircular := [][]uint64{{}, {2}, {1}}
wrongTxDependencyOutOfRange := [][]uint64{{}, {}, {3}}
var temp map[int][]int
temp = GetDeps(correctTxDependency)
assert.Equal(t, true, VerifyDeps(temp))
temp = GetDeps(wrongTxDependency)
assert.Equal(t, false, VerifyDeps(temp))
temp = GetDeps(wrongTxDependencyCircular)
assert.Equal(t, false, VerifyDeps(temp))
temp = GetDeps(wrongTxDependencyOutOfRange)
assert.Equal(t, false, VerifyDeps(temp))
}

View file

@ -456,8 +456,8 @@ func (b *Block) GetTxDependency() [][]uint64 {
return blockExtraData.TxDependency return blockExtraData.TxDependency
} }
func (h *Header) GetValidatorBytes(config *params.BorConfig) []byte { func (h *Header) GetValidatorBytes(chainConfig *params.ChainConfig) []byte {
if !config.IsParallelUniverse(h.Number) { if !chainConfig.IsCancun(h.Number) {
return h.Extra[ExtraVanityLength : len(h.Extra)-ExtraSealLength] return h.Extra[ExtraVanityLength : len(h.Extra)-ExtraSealLength]
} }

View file

@ -74,7 +74,6 @@ func TestBlockEncoding(t *testing.T) {
} }
// This is a replica of `(h *Header) GetValidatorBytes` function // This is a replica of `(h *Header) GetValidatorBytes` function
// This was needed because currently, `IsParallelUniverse` will always return false.
func GetValidatorBytesTest(h *Header) []byte { func GetValidatorBytesTest(h *Header) []byte {
if len(h.Extra) < ExtraVanityLength+ExtraSealLength { if len(h.Extra) < ExtraVanityLength+ExtraSealLength {
log.Error("length of extra less is than vanity and seal") log.Error("length of extra less is than vanity and seal")

View file

@ -30,6 +30,7 @@ import (
"github.com/ethereum/go-ethereum/crypto/bls12381" "github.com/ethereum/go-ethereum/crypto/bls12381"
"github.com/ethereum/go-ethereum/crypto/bn256" "github.com/ethereum/go-ethereum/crypto/bn256"
"github.com/ethereum/go-ethereum/crypto/kzg4844" "github.com/ethereum/go-ethereum/crypto/kzg4844"
"github.com/ethereum/go-ethereum/crypto/secp256r1"
"github.com/ethereum/go-ethereum/params" "github.com/ethereum/go-ethereum/params"
"golang.org/x/crypto/ripemd160" "golang.org/x/crypto/ripemd160"
) )
@ -104,7 +105,7 @@ var PrecompiledContractsCancun = map[common.Address]PrecompiledContract{
common.BytesToAddress([]byte{7}): &bn256ScalarMulIstanbul{}, common.BytesToAddress([]byte{7}): &bn256ScalarMulIstanbul{},
common.BytesToAddress([]byte{8}): &bn256PairingIstanbul{}, common.BytesToAddress([]byte{8}): &bn256PairingIstanbul{},
common.BytesToAddress([]byte{9}): &blake2F{}, common.BytesToAddress([]byte{9}): &blake2F{},
common.BytesToAddress([]byte{0x0a}): &kzgPointEvaluation{}, common.BytesToAddress([]byte{0x01, 0x00}): &p256Verify{},
} }
// PrecompiledContractsBLS contains the set of pre-compiled Ethereum // PrecompiledContractsBLS contains the set of pre-compiled Ethereum
@ -1194,3 +1195,37 @@ func kZGToVersionedHash(kzg kzg4844.Commitment) common.Hash {
return h return h
} }
// 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(common.Big1.Bytes(), 32), nil
} else {
// Signature is invalid
return nil, nil
}
}

View file

@ -67,6 +67,7 @@ var allPrecompiles = map[common.Address]PrecompiledContract{
common.BytesToAddress([]byte{0x0f, 0x10}): &bls12381Pairing{}, common.BytesToAddress([]byte{0x0f, 0x10}): &bls12381Pairing{},
common.BytesToAddress([]byte{0x0f, 0x11}): &bls12381MapG1{}, common.BytesToAddress([]byte{0x0f, 0x11}): &bls12381MapG1{},
common.BytesToAddress([]byte{0x0f, 0x12}): &bls12381MapG2{}, common.BytesToAddress([]byte{0x0f, 0x12}): &bls12381MapG2{},
common.BytesToAddress([]byte{0x01, 0x00}): &p256Verify{},
} }
// EIP-152 test vectors // EIP-152 test vectors
@ -415,3 +416,19 @@ func BenchmarkPrecompiledBLS12381G2MultiExpWorstCase(b *testing.B) {
} }
benchmarkPrecompiled("0f", testcase, b) benchmarkPrecompiled("0f", testcase, b)
} }
// Benchmarks the sample inputs from the P256VERIFY precompile.
func BenchmarkPrecompiledP256Verify(bench *testing.B) {
t := precompiledTest{
Input: "4cee90eb86eaa050036147a12d49004b6b9c72bd725d39d4785011fe190f0b4da73bd4903f0ce3b639bbbf6e8e80d16931ff4bcf5993d58468e8fb19086e8cac36dbcd03009df8c59286b162af3bd7fcc0450c9aa81be5d10d312af6c66b1d604aebd3099c618202fcfe16ae7770b0c49ab5eadf74b754204a3bb6060e44eff37618b065f9832de4ca6ca971a7a1adc826d0f7c00181a5fb2ddf79ae00b4e10e",
Expected: "0000000000000000000000000000000000000000000000000000000000000001",
Name: "p256Verify",
}
benchmarkPrecompiled("100", t, bench)
}
func TestPrecompiledP256Verify(t *testing.T) {
t.Parallel()
testJson("p256Verify", "100", t)
}

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

@ -1121,7 +1121,7 @@ func (c *CallResult) Status() hexutil.Uint64 {
func (b *Block) Call(ctx context.Context, args struct { func (b *Block) Call(ctx context.Context, args struct {
Data ethapi.TransactionArgs Data ethapi.TransactionArgs
}) (*CallResult, error) { }) (*CallResult, error) {
result, err := ethapi.DoCall(ctx, b.r.backend, args.Data, *b.numberOrHash, nil, nil, b.r.backend.RPCEVMTimeout(), b.r.backend.RPCGasCap()) result, err := ethapi.DoCall(ctx, b.r.backend, args.Data, *b.numberOrHash, nil, nil, nil, b.r.backend.RPCEVMTimeout(), b.r.backend.RPCGasCap())
if err != nil { if err != nil {
return nil, err return nil, err
} }
@ -1184,7 +1184,7 @@ func (p *Pending) Call(ctx context.Context, args struct {
Data ethapi.TransactionArgs Data ethapi.TransactionArgs
}) (*CallResult, error) { }) (*CallResult, error) {
pendingBlockNr := rpc.BlockNumberOrHashWithNumber(rpc.PendingBlockNumber) pendingBlockNr := rpc.BlockNumberOrHashWithNumber(rpc.PendingBlockNumber)
result, err := ethapi.DoCall(ctx, p.r.backend, args.Data, pendingBlockNr, nil, nil, p.r.backend.RPCEVMTimeout(), p.r.backend.RPCGasCap()) result, err := ethapi.DoCall(ctx, p.r.backend, args.Data, pendingBlockNr, nil, nil, nil, p.r.backend.RPCEVMTimeout(), p.r.backend.RPCGasCap())
if err != nil { if err != nil {
return nil, err return nil, err
} }

View file

@ -3,8 +3,8 @@ set -e
while true while true
do do
peers=$(docker exec bor0 bash -c "bor attach /root/.bor/data/bor.ipc -exec 'admin.peers'") peers=$(docker exec bor0 bash -c "bor attach /root/var/lib/bor/data/bor.ipc -exec 'admin.peers'")
block=$(docker exec bor0 bash -c "bor attach /root/.bor/data/bor.ipc -exec 'eth.blockNumber'") block=$(docker exec bor0 bash -c "bor attach /root/var/lib/bor/data/bor.ipc -exec 'eth.blockNumber'")
if [[ -n "$peers" ]] && [[ -n "$block" ]]; then if [[ -n "$peers" ]] && [[ -n "$block" ]]; then
break break

View file

@ -1,7 +1,7 @@
#!/bin/bash #!/bin/bash
set -e set -e
balanceInit=$(docker exec bor0 bash -c "bor attach /root/.bor/data/bor.ipc -exec 'Math.round(web3.fromWei(eth.getBalance(eth.accounts[0])))'") balanceInit=$(docker exec bor0 bash -c "bor attach /root/var/lib/bor/data/bor.ipc -exec 'Math.round(web3.fromWei(eth.getBalance(eth.accounts[0])))'")
stateSyncFound="false" stateSyncFound="false"
checkpointFound="false" checkpointFound="false"
@ -11,7 +11,7 @@ start_time=$SECONDS
while true while true
do do
balance=$(docker exec bor0 bash -c "bor attach /root/.bor/data/bor.ipc -exec 'Math.round(web3.fromWei(eth.getBalance(eth.accounts[0])))'") balance=$(docker exec bor0 bash -c "bor attach /root/var/lib/bor/data/bor.ipc -exec 'Math.round(web3.fromWei(eth.getBalance(eth.accounts[0])))'")
if ! [[ "$balance" =~ ^[0-9]+$ ]]; then if ! [[ "$balance" =~ ^[0-9]+$ ]]; then
echo "Something is wrong! Can't find the balance of first account in bor network." echo "Something is wrong! Can't find the balance of first account in bor network."

View file

@ -31,7 +31,6 @@ var mainnetBor = &Chain{
Bor: &params.BorConfig{ Bor: &params.BorConfig{
JaipurBlock: big.NewInt(23850000), JaipurBlock: big.NewInt(23850000),
DelhiBlock: big.NewInt(38189056), DelhiBlock: big.NewInt(38189056),
ParallelUniverseBlock: big.NewInt(0),
IndoreBlock: big.NewInt(44934656), IndoreBlock: big.NewInt(44934656),
StateSyncConfirmationDelay: map[string]uint64{ StateSyncConfirmationDelay: map[string]uint64{
"44934656": 128, "44934656": 128,

View file

@ -31,7 +31,6 @@ var mumbaiTestnet = &Chain{
Bor: &params.BorConfig{ Bor: &params.BorConfig{
JaipurBlock: big.NewInt(22770000), JaipurBlock: big.NewInt(22770000),
DelhiBlock: big.NewInt(29638656), DelhiBlock: big.NewInt(29638656),
ParallelUniverseBlock: big.NewInt(0),
IndoreBlock: big.NewInt(37075456), IndoreBlock: big.NewInt(37075456),
StateSyncConfirmationDelay: map[string]uint64{ StateSyncConfirmationDelay: map[string]uint64{
"37075456": 128, "37075456": 128,

View file

@ -57,7 +57,6 @@
}, },
"jaipurBlock": 22770000, "jaipurBlock": 22770000,
"delhiBlock": 29638656, "delhiBlock": 29638656,
"parallelUniverseBlock": 0,
"indoreBlock": 37075456, "indoreBlock": 37075456,
"stateSyncConfirmationDelay": { "stateSyncConfirmationDelay": {
"37075456": 128 "37075456": 128

View file

@ -59,7 +59,6 @@
}, },
"jaipurBlock":22770000, "jaipurBlock":22770000,
"delhiBlock": 29638656, "delhiBlock": 29638656,
"parallelUniverseBlock": 0,
"indoreBlock": 37075456, "indoreBlock": 37075456,
"stateSyncConfirmationDelay": { "stateSyncConfirmationDelay": {
"37075456": 128 "37075456": 128

View file

@ -1264,13 +1264,32 @@ func doCallWithState(ctx context.Context, b Backend, args TransactionArgs, heade
return result, nil return result, nil
} }
func DoCall(ctx context.Context, b Backend, args TransactionArgs, blockNrOrHash rpc.BlockNumberOrHash, overrides *StateOverride, blockOverrides *BlockOverrides, timeout time.Duration, globalGasCap uint64) (*core.ExecutionResult, error) { func DoCall(ctx context.Context, b Backend, args TransactionArgs, blockNrOrHash rpc.BlockNumberOrHash, state *state.StateDB, overrides *StateOverride, blockOverrides *BlockOverrides, timeout time.Duration, globalGasCap uint64) (*core.ExecutionResult, error) {
defer func(start time.Time) { log.Debug("Executing EVM call finished", "runtime", time.Since(start)) }(time.Now()) defer func(start time.Time) { log.Debug("Executing EVM call finished", "runtime", time.Since(start)) }(time.Now())
state, header, err := b.StateAndHeaderByNumberOrHash(ctx, blockNrOrHash) var (
header *types.Header
err error
)
// BOR: This is used by bor consensus to fetch data from genesis contracts for state-sync
// Fetch the state and header from blockNumberOrHash if it's coming from normal eth_call path.
if state == nil {
state, header, err = b.StateAndHeaderByNumberOrHash(ctx, blockNrOrHash)
if state == nil || err != nil { if state == nil || err != nil {
return nil, err return nil, err
} }
} else {
// Fetch the header from the given blockNumberOrHash. Note that this path is only taken
// when we're doing a call from bor consensus to fetch data from genesis contracts. It's
// necessary to fetch header using header hash as we might be experiencing a reorg and there
// can be multiple headers with same number.
header, err = b.HeaderByHash(ctx, *blockNrOrHash.BlockHash)
if header == nil || err != nil {
log.Warn("Error fetching header on CallWithState", "err", err)
return nil, err
}
}
return doCall(ctx, b, args, state, header, overrides, blockOverrides, timeout, globalGasCap) return doCall(ctx, b, args, state, header, overrides, blockOverrides, timeout, globalGasCap)
} }
@ -1327,7 +1346,7 @@ func (s *BlockChainAPI) Call(ctx context.Context, args TransactionArgs, blockNrO
// Note, this function doesn't make and changes in the state/blockchain and is // Note, this function doesn't make and changes in the state/blockchain and is
// useful to execute and retrieve values. // useful to execute and retrieve values.
func (s *BlockChainAPI) CallWithState(ctx context.Context, args TransactionArgs, blockNrOrHash rpc.BlockNumberOrHash, state *state.StateDB, overrides *StateOverride, blockOverrides *BlockOverrides) (hexutil.Bytes, error) { func (s *BlockChainAPI) CallWithState(ctx context.Context, args TransactionArgs, blockNrOrHash rpc.BlockNumberOrHash, state *state.StateDB, overrides *StateOverride, blockOverrides *BlockOverrides) (hexutil.Bytes, error) {
result, err := DoCall(ctx, s.b, args, blockNrOrHash, overrides, blockOverrides, s.b.RPCEVMTimeout(), s.b.RPCGasCap()) result, err := DoCall(ctx, s.b, args, blockNrOrHash, state, overrides, blockOverrides, s.b.RPCEVMTimeout(), s.b.RPCGasCap())
if err != nil { if err != nil {
return nil, err return nil, err
} }

View file

@ -109,6 +109,9 @@ type environment struct {
header *types.Header header *types.Header
txs []*types.Transaction txs []*types.Transaction
receipts []*types.Receipt receipts []*types.Receipt
depsMVFullWriteList [][]blockstm.WriteDescriptor
mvReadMapList []map[blockstm.Key]blockstm.ReadDescriptor
} }
// copy creates a deep copy of environment. // copy creates a deep copy of environment.
@ -120,6 +123,8 @@ func (env *environment) copy() *environment {
coinbase: env.coinbase, coinbase: env.coinbase,
header: types.CopyHeader(env.header), header: types.CopyHeader(env.header),
receipts: copyReceipts(env.receipts), receipts: copyReceipts(env.receipts),
depsMVFullWriteList: env.depsMVFullWriteList,
mvReadMapList: env.mvReadMapList,
} }
if env.gasPool != nil { if env.gasPool != nil {
@ -854,6 +859,9 @@ func (w *worker) makeEnv(parent *types.Header, header *types.Header, coinbase co
// Keep track of transactions which return errors so they can be removed // Keep track of transactions which return errors so they can be removed
env.tcount = 0 env.tcount = 0
env.depsMVFullWriteList = [][]blockstm.WriteDescriptor{}
env.mvReadMapList = []map[blockstm.Key]blockstm.ReadDescriptor{}
return env, nil return env, nil
} }
@ -903,36 +911,20 @@ func (w *worker) commitTransactions(env *environment, txs *transactionsByPriceAn
var coalescedLogs []*types.Log var coalescedLogs []*types.Log
var depsMVReadList [][]blockstm.ReadDescriptor
var depsMVFullWriteList [][]blockstm.WriteDescriptor
var mvReadMapList []map[blockstm.Key]blockstm.ReadDescriptor
var deps map[int]map[int]bool var deps map[int]map[int]bool
chDeps := make(chan blockstm.TxDep) chDeps := make(chan blockstm.TxDep)
var count int
var depsWg sync.WaitGroup var depsWg sync.WaitGroup
EnableMVHashMap := w.chainConfig.Bor.IsParallelUniverse(env.header.Number) EnableMVHashMap := w.chainConfig.IsCancun(env.header.Number)
// create and add empty mvHashMap in statedb // create and add empty mvHashMap in statedb
if EnableMVHashMap { if EnableMVHashMap {
depsMVReadList = [][]blockstm.ReadDescriptor{}
depsMVFullWriteList = [][]blockstm.WriteDescriptor{}
mvReadMapList = []map[blockstm.Key]blockstm.ReadDescriptor{}
deps = map[int]map[int]bool{} deps = map[int]map[int]bool{}
chDeps = make(chan blockstm.TxDep) chDeps = make(chan blockstm.TxDep)
count = 0
depsWg.Add(1) depsWg.Add(1)
go func(chDeps chan blockstm.TxDep) { go func(chDeps chan blockstm.TxDep) {
@ -1064,18 +1056,20 @@ mainloop:
env.tcount++ env.tcount++
if EnableMVHashMap { if EnableMVHashMap {
depsMVReadList = append(depsMVReadList, env.state.MVReadList()) env.depsMVFullWriteList = append(env.depsMVFullWriteList, env.state.MVFullWriteList())
depsMVFullWriteList = append(depsMVFullWriteList, env.state.MVFullWriteList()) env.mvReadMapList = append(env.mvReadMapList, env.state.MVReadMap())
mvReadMapList = append(mvReadMapList, env.state.MVReadMap())
if env.tcount > len(env.depsMVFullWriteList) {
log.Warn("blockstm - env.tcount > len(env.depsMVFullWriteList)", "env.tcount", env.tcount, "len(depsMVFullWriteList)", len(env.depsMVFullWriteList))
}
temp := blockstm.TxDep{ temp := blockstm.TxDep{
Index: env.tcount - 1, Index: env.tcount - 1,
ReadList: depsMVReadList[count], ReadList: env.state.MVReadList(),
FullWriteList: depsMVFullWriteList, FullWriteList: env.depsMVFullWriteList,
} }
chDeps <- temp chDeps <- temp
count++
} }
txs.Shift() txs.Shift()
@ -1107,8 +1101,8 @@ mainloop:
tempVanity := env.header.Extra[:types.ExtraVanityLength] tempVanity := env.header.Extra[:types.ExtraVanityLength]
tempSeal := env.header.Extra[len(env.header.Extra)-types.ExtraSealLength:] tempSeal := env.header.Extra[len(env.header.Extra)-types.ExtraSealLength:]
if len(mvReadMapList) > 0 { if len(env.mvReadMapList) > 0 {
tempDeps := make([][]uint64, len(mvReadMapList)) tempDeps := make([][]uint64, len(env.mvReadMapList))
for j := range deps[0] { for j := range deps[0] {
tempDeps[0] = append(tempDeps[0], uint64(j)) tempDeps[0] = append(tempDeps[0], uint64(j))
@ -1116,14 +1110,15 @@ mainloop:
delayFlag := true delayFlag := true
for i := 1; i <= len(mvReadMapList)-1; i++ { for i := 1; i <= len(env.mvReadMapList)-1; i++ {
reads := mvReadMapList[i-1] reads := env.mvReadMapList[i-1]
_, ok1 := reads[blockstm.NewSubpathKey(env.coinbase, state.BalancePath)] _, ok1 := reads[blockstm.NewSubpathKey(env.coinbase, state.BalancePath)]
_, ok2 := reads[blockstm.NewSubpathKey(common.HexToAddress(w.chainConfig.Bor.CalculateBurntContract(env.header.Number.Uint64())), state.BalancePath)] _, ok2 := reads[blockstm.NewSubpathKey(common.HexToAddress(w.chainConfig.Bor.CalculateBurntContract(env.header.Number.Uint64())), state.BalancePath)]
if ok1 || ok2 { if ok1 || ok2 {
delayFlag = false delayFlag = false
break
} }
for j := range deps[i] { for j := range deps[i] {

View file

@ -909,7 +909,7 @@ func BenchmarkBorMining(b *testing.B) {
} }
// uses core.NewParallelBlockChain to use the dependencies present in the block header // uses core.NewParallelBlockChain to use the dependencies present in the block header
// params.BorUnittestChainConfig contains the ParallelUniverseBlock ad big.NewInt(5), so the first 4 blocks will not have metadata. // params.BorUnittestChainConfig contains the NapoliBlock as big.NewInt(5), so the first 4 blocks will not have metadata.
// nolint: gocognit // nolint: gocognit
func BenchmarkBorMiningBlockSTMMetadata(b *testing.B) { func BenchmarkBorMiningBlockSTMMetadata(b *testing.B) {
chainConfig := params.BorUnittestChainConfig chainConfig := params.BorUnittestChainConfig

View file

@ -1,5 +1,5 @@
Source: bor Source: bor
Version: 1.2.2 Version: 1.2.3
Section: develop Section: develop
Priority: standard Priority: standard
Maintainer: Polygon <release-team@polygon.technology> Maintainer: Polygon <release-team@polygon.technology>

View file

@ -1,5 +1,5 @@
Source: bor Source: bor
Version: 1.2.2 Version: 1.2.3
Section: develop Section: develop
Priority: standard Priority: standard
Maintainer: Polygon <release-team@polygon.technology> Maintainer: Polygon <release-team@polygon.technology>

View file

@ -1,5 +1,5 @@
Source: bor-profile Source: bor-profile
Version: 1.2.2 Version: 1.2.3
Section: develop Section: develop
Priority: standard Priority: standard
Maintainer: Polygon <release-team@polygon.technology> Maintainer: Polygon <release-team@polygon.technology>

View file

@ -1,5 +1,5 @@
Source: bor-profile Source: bor-profile
Version: 1.2.2 Version: 1.2.3
Section: develop Section: develop
Priority: standard Priority: standard
Maintainer: Polygon <release-team@polygon.technology> Maintainer: Polygon <release-team@polygon.technology>

View file

@ -1,5 +1,5 @@
Source: bor-profile Source: bor-profile
Version: 1.2.2 Version: 1.2.3
Section: develop Section: develop
Priority: standard Priority: standard
Maintainer: Polygon <release-team@polygon.technology> Maintainer: Polygon <release-team@polygon.technology>

View file

@ -1,5 +1,5 @@
Source: bor-profile Source: bor-profile
Version: 1.2.2 Version: 1.2.3
Section: develop Section: develop
Priority: standard Priority: standard
Maintainer: Polygon <release-team@polygon.technology> Maintainer: Polygon <release-team@polygon.technology>

View file

@ -159,7 +159,6 @@ var (
BerlinBlock: big.NewInt(0), BerlinBlock: big.NewInt(0),
LondonBlock: big.NewInt(0), LondonBlock: big.NewInt(0),
Bor: &BorConfig{ Bor: &BorConfig{
ParallelUniverseBlock: big.NewInt(5),
Period: map[string]uint64{ Period: map[string]uint64{
"0": 1, "0": 1,
}, },
@ -200,7 +199,6 @@ var (
Bor: &BorConfig{ Bor: &BorConfig{
JaipurBlock: big.NewInt(22770000), JaipurBlock: big.NewInt(22770000),
DelhiBlock: big.NewInt(29638656), DelhiBlock: big.NewInt(29638656),
ParallelUniverseBlock: big.NewInt(0),
IndoreBlock: big.NewInt(37075456), IndoreBlock: big.NewInt(37075456),
StateSyncConfirmationDelay: map[string]uint64{ StateSyncConfirmationDelay: map[string]uint64{
"37075456": 128, "37075456": 128,
@ -266,7 +264,6 @@ var (
Bor: &BorConfig{ Bor: &BorConfig{
JaipurBlock: big.NewInt(23850000), JaipurBlock: big.NewInt(23850000),
DelhiBlock: big.NewInt(38189056), DelhiBlock: big.NewInt(38189056),
ParallelUniverseBlock: big.NewInt(0),
IndoreBlock: big.NewInt(44934656), IndoreBlock: big.NewInt(44934656),
StateSyncConfirmationDelay: map[string]uint64{ StateSyncConfirmationDelay: map[string]uint64{
"44934656": 128, "44934656": 128,
@ -567,7 +564,6 @@ type BorConfig struct {
BurntContract map[string]string `json:"burntContract"` // governance contract where the token will be sent to and burnt in london fork BurntContract map[string]string `json:"burntContract"` // governance contract where the token will be sent to and burnt in london fork
JaipurBlock *big.Int `json:"jaipurBlock"` // Jaipur switch block (nil = no fork, 0 = already on jaipur) 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) DelhiBlock *big.Int `json:"delhiBlock"` // Delhi switch block (nil = no fork, 0 = already on delhi)
ParallelUniverseBlock *big.Int `json:"parallelUniverseBlock"` // TODO: update all occurrence, change name and finalize number (hardfork for block-stm related changes)
IndoreBlock *big.Int `json:"indoreBlock"` // Indore switch block (nil = no fork, 0 = already on indore) IndoreBlock *big.Int `json:"indoreBlock"` // Indore switch block (nil = no fork, 0 = already on indore)
StateSyncConfirmationDelay map[string]uint64 `json:"stateSyncConfirmationDelay"` // StateSync Confirmation Delay, in seconds, to calculate `to` StateSyncConfirmationDelay map[string]uint64 `json:"stateSyncConfirmationDelay"` // StateSync Confirmation Delay, in seconds, to calculate `to`
} }
@ -609,16 +605,16 @@ func (c *BorConfig) CalculateStateSyncDelay(number uint64) uint64 {
return borKeyValueConfigHelper(c.StateSyncConfirmationDelay, number) return borKeyValueConfigHelper(c.StateSyncConfirmationDelay, number)
} }
// TODO: modify this function once the block number is finalized // // TODO: modify this function once the block number is finalized
func (c *BorConfig) IsParallelUniverse(number *big.Int) bool { // func (c *BorConfig) IsNapoli(number *big.Int) bool {
if c.ParallelUniverseBlock != nil { // if c.NapoliBlock != nil {
if c.ParallelUniverseBlock.Cmp(big.NewInt(0)) == 0 { // if c.NapoliBlock.Cmp(big.NewInt(0)) == 0 {
return false // return false
} // }
} // }
return isBlockForked(c.ParallelUniverseBlock, number) // return isBlockForked(c.NapoliBlock, number)
} // }
func (c *BorConfig) IsSprintStart(number uint64) bool { func (c *BorConfig) IsSprintStart(number uint64) bool {
return number%c.CalculateSprint(number) == 0 return number%c.CalculateSprint(number) == 0
@ -842,17 +838,17 @@ func (c *ChainConfig) IsTerminalPoWBlock(parentTotalDiff *big.Int, totalDiff *bi
return parentTotalDiff.Cmp(c.TerminalTotalDifficulty) < 0 && totalDiff.Cmp(c.TerminalTotalDifficulty) >= 0 return parentTotalDiff.Cmp(c.TerminalTotalDifficulty) < 0 && totalDiff.Cmp(c.TerminalTotalDifficulty) >= 0
} }
// IsShanghai returns whether time is either equal to the Shanghai fork time or greater. // IsShanghai returns whether num is either equal to the Shanghai fork block or greater.
func (c *ChainConfig) IsShanghai(num *big.Int) bool { func (c *ChainConfig) IsShanghai(num *big.Int) bool {
return isBlockForked(c.ShanghaiBlock, num) return isBlockForked(c.ShanghaiBlock, num)
} }
// IsCancun returns whether num is either equal to the Cancun fork time or greater. // IsCancun returns whether num is either equal to the Cancun fork block or greater.
func (c *ChainConfig) IsCancun(num *big.Int) bool { func (c *ChainConfig) IsCancun(num *big.Int) bool {
return isBlockForked(c.CancunBlock, num) return isBlockForked(c.CancunBlock, num)
} }
// IsPrague returns whether num is either equal to the Prague fork time or greater. // IsPrague returns whether num is either equal to the Prague fork block or greater.
func (c *ChainConfig) IsPrague(num *big.Int) bool { func (c *ChainConfig) IsPrague(num *big.Int) bool {
return isBlockForked(c.PragueBlock, num) return isBlockForked(c.PragueBlock, num)
} }

View file

@ -160,6 +160,8 @@ const (
Bls12381MapG1Gas uint64 = 5500 // Gas price for BLS12-381 mapping field element to G1 operation Bls12381MapG1Gas uint64 = 5500 // Gas price for BLS12-381 mapping field element to G1 operation
Bls12381MapG2Gas uint64 = 110000 // Gas price for BLS12-381 mapping field element to G2 operation Bls12381MapG2Gas uint64 = 110000 // Gas price for BLS12-381 mapping field element to G2 operation
P256VerifyGas uint64 = 3450 // secp256r1 elliptic curve signature verifier gas price
// The Refund Quotient is the cap on how much of the used gas can be refunded. Before EIP-3529, // The Refund Quotient is the cap on how much of the used gas can be refunded. Before EIP-3529,
// up to half the consumed gas could be refunded. Redefined as 1/5th in EIP-3529 // up to half the consumed gas could be refunded. Redefined as 1/5th in EIP-3529
RefundQuotient uint64 = 2 RefundQuotient uint64 = 2

View file

@ -23,7 +23,7 @@ import (
const ( const (
VersionMajor = 1 // Major version component of the current release VersionMajor = 1 // Major version component of the current release
VersionMinor = 2 // Minor version component of the current release VersionMinor = 2 // Minor version component of the current release
VersionPatch = 2 // Patch version component of the current release VersionPatch = 3 // Patch version component of the current release
VersionMeta = "" // Version metadata to append to the version string VersionMeta = "" // Version metadata to append to the version string
) )