mirror of
https://gitlab.com/pulsechaincom/erigon-pulse.git
synced 2024-12-21 19:20:39 +00:00
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:
parent
8f6fe88b29
commit
b38e17e393
@ -244,8 +244,13 @@ func GatherForks(config *chain.Config, genesisTime uint64) (heightForks []uint64
|
|||||||
heightForks = append(heightForks, *config.Aura.PosdaoTransition)
|
heightForks = append(heightForks, *config.Aura.PosdaoTransition)
|
||||||
}
|
}
|
||||||
|
|
||||||
if config.Bor != nil && config.Bor.GetAgraBlock() != nil {
|
if config.Bor != nil {
|
||||||
heightForks = append(heightForks, config.Bor.GetAgraBlock().Uint64())
|
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
|
// Sort the fork block numbers & times to permit chronological XOR
|
||||||
|
@ -42,7 +42,7 @@ import (
|
|||||||
|
|
||||||
// the following 2 functions are replica for the test
|
// the following 2 functions are replica for the test
|
||||||
// This is a replica of `bor.GetValidatorBytes` function
|
// 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 {
|
func GetValidatorBytesTest(h *Header) []byte {
|
||||||
if len(h.Extra) < ExtraVanityLength+ExtraSealLength {
|
if len(h.Extra) < ExtraVanityLength+ExtraSealLength {
|
||||||
log.Error("length of extra is less than vanity and seal")
|
log.Error("length of extra is less than vanity and seal")
|
||||||
|
@ -20,13 +20,13 @@ import (
|
|||||||
"crypto/sha256"
|
"crypto/sha256"
|
||||||
"encoding/binary"
|
"encoding/binary"
|
||||||
"errors"
|
"errors"
|
||||||
"github.com/ledgerwatch/erigon-lib/crypto/blake2b"
|
|
||||||
"math/big"
|
"math/big"
|
||||||
|
|
||||||
"github.com/holiman/uint256"
|
"github.com/holiman/uint256"
|
||||||
|
|
||||||
"github.com/ledgerwatch/erigon-lib/chain"
|
"github.com/ledgerwatch/erigon-lib/chain"
|
||||||
libcommon "github.com/ledgerwatch/erigon-lib/common"
|
libcommon "github.com/ledgerwatch/erigon-lib/common"
|
||||||
|
"github.com/ledgerwatch/erigon-lib/crypto/blake2b"
|
||||||
libkzg "github.com/ledgerwatch/erigon-lib/crypto/kzg"
|
libkzg "github.com/ledgerwatch/erigon-lib/crypto/kzg"
|
||||||
|
|
||||||
"github.com/ledgerwatch/erigon/common"
|
"github.com/ledgerwatch/erigon/common"
|
||||||
@ -34,7 +34,7 @@ import (
|
|||||||
"github.com/ledgerwatch/erigon/crypto"
|
"github.com/ledgerwatch/erigon/crypto"
|
||||||
"github.com/ledgerwatch/erigon/crypto/bls12381"
|
"github.com/ledgerwatch/erigon/crypto/bls12381"
|
||||||
"github.com/ledgerwatch/erigon/crypto/bn256"
|
"github.com/ledgerwatch/erigon/crypto/bn256"
|
||||||
|
"github.com/ledgerwatch/erigon/crypto/secp256r1"
|
||||||
"github.com/ledgerwatch/erigon/params"
|
"github.com/ledgerwatch/erigon/params"
|
||||||
|
|
||||||
//lint:ignore SA1019 Needed for precompile
|
//lint:ignore SA1019 Needed for precompile
|
||||||
@ -112,6 +112,19 @@ var PrecompiledContractsCancun = map[libcommon.Address]PrecompiledContract{
|
|||||||
libcommon.BytesToAddress([]byte{0x0a}): &pointEvaluation{},
|
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
|
// PrecompiledContractsBLS contains the set of pre-compiled Ethereum
|
||||||
// contracts specified in EIP-2537. These are exported for testing purposes.
|
// contracts specified in EIP-2537. These are exported for testing purposes.
|
||||||
var PrecompiledContractsBLS = map[libcommon.Address]PrecompiledContract{
|
var PrecompiledContractsBLS = map[libcommon.Address]PrecompiledContract{
|
||||||
@ -127,6 +140,7 @@ var PrecompiledContractsBLS = map[libcommon.Address]PrecompiledContract{
|
|||||||
}
|
}
|
||||||
|
|
||||||
var (
|
var (
|
||||||
|
PrecompiledAddressesNapoli []libcommon.Address
|
||||||
PrecompiledAddressesCancun []libcommon.Address
|
PrecompiledAddressesCancun []libcommon.Address
|
||||||
PrecompiledAddressesBerlin []libcommon.Address
|
PrecompiledAddressesBerlin []libcommon.Address
|
||||||
PrecompiledAddressesIstanbul []libcommon.Address
|
PrecompiledAddressesIstanbul []libcommon.Address
|
||||||
@ -150,11 +164,16 @@ func init() {
|
|||||||
for k := range PrecompiledContractsCancun {
|
for k := range PrecompiledContractsCancun {
|
||||||
PrecompiledAddressesCancun = append(PrecompiledAddressesCancun, k)
|
PrecompiledAddressesCancun = append(PrecompiledAddressesCancun, k)
|
||||||
}
|
}
|
||||||
|
for k := range PrecompiledContractsNapoli {
|
||||||
|
PrecompiledAddressesNapoli = append(PrecompiledAddressesNapoli, k)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// ActivePrecompiles returns the precompiles enabled with the current configuration.
|
// ActivePrecompiles returns the precompiles enabled with the current configuration.
|
||||||
func ActivePrecompiles(rules *chain.Rules) []libcommon.Address {
|
func ActivePrecompiles(rules *chain.Rules) []libcommon.Address {
|
||||||
switch {
|
switch {
|
||||||
|
case rules.IsNapoli:
|
||||||
|
return PrecompiledAddressesNapoli
|
||||||
case rules.IsCancun:
|
case rules.IsCancun:
|
||||||
return PrecompiledAddressesCancun
|
return PrecompiledAddressesCancun
|
||||||
case rules.IsBerlin:
|
case rules.IsBerlin:
|
||||||
@ -1098,3 +1117,37 @@ func (c *pointEvaluation) RequiredGas(input []byte) uint64 {
|
|||||||
func (c *pointEvaluation) Run(input []byte) ([]byte, error) {
|
func (c *pointEvaluation) Run(input []byte) ([]byte, error) {
|
||||||
return libkzg.PointEvaluationPrecompile(input)
|
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
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@ -48,26 +48,27 @@ type precompiledFailureTest struct {
|
|||||||
// allPrecompiles does not map to the actual set of precompiles, as it also contains
|
// allPrecompiles does not map to the actual set of precompiles, as it also contains
|
||||||
// repriced versions of precompiles at certain slots
|
// repriced versions of precompiles at certain slots
|
||||||
var allPrecompiles = map[libcommon.Address]PrecompiledContract{
|
var allPrecompiles = map[libcommon.Address]PrecompiledContract{
|
||||||
libcommon.BytesToAddress([]byte{1}): &ecrecover{},
|
libcommon.BytesToAddress([]byte{1}): &ecrecover{},
|
||||||
libcommon.BytesToAddress([]byte{2}): &sha256hash{},
|
libcommon.BytesToAddress([]byte{2}): &sha256hash{},
|
||||||
libcommon.BytesToAddress([]byte{3}): &ripemd160hash{},
|
libcommon.BytesToAddress([]byte{3}): &ripemd160hash{},
|
||||||
libcommon.BytesToAddress([]byte{4}): &dataCopy{},
|
libcommon.BytesToAddress([]byte{4}): &dataCopy{},
|
||||||
libcommon.BytesToAddress([]byte{5}): &bigModExp{eip2565: false},
|
libcommon.BytesToAddress([]byte{5}): &bigModExp{eip2565: false},
|
||||||
libcommon.BytesToAddress([]byte{0xf5}): &bigModExp{eip2565: true},
|
libcommon.BytesToAddress([]byte{0xf5}): &bigModExp{eip2565: true},
|
||||||
libcommon.BytesToAddress([]byte{6}): &bn256AddIstanbul{},
|
libcommon.BytesToAddress([]byte{6}): &bn256AddIstanbul{},
|
||||||
libcommon.BytesToAddress([]byte{7}): &bn256ScalarMulIstanbul{},
|
libcommon.BytesToAddress([]byte{7}): &bn256ScalarMulIstanbul{},
|
||||||
libcommon.BytesToAddress([]byte{8}): &bn256PairingIstanbul{},
|
libcommon.BytesToAddress([]byte{8}): &bn256PairingIstanbul{},
|
||||||
libcommon.BytesToAddress([]byte{9}): &blake2F{},
|
libcommon.BytesToAddress([]byte{9}): &blake2F{},
|
||||||
libcommon.BytesToAddress([]byte{10}): &bls12381G1Add{},
|
libcommon.BytesToAddress([]byte{10}): &bls12381G1Add{},
|
||||||
libcommon.BytesToAddress([]byte{11}): &bls12381G1Mul{},
|
libcommon.BytesToAddress([]byte{11}): &bls12381G1Mul{},
|
||||||
libcommon.BytesToAddress([]byte{12}): &bls12381G1MultiExp{},
|
libcommon.BytesToAddress([]byte{12}): &bls12381G1MultiExp{},
|
||||||
libcommon.BytesToAddress([]byte{13}): &bls12381G2Add{},
|
libcommon.BytesToAddress([]byte{13}): &bls12381G2Add{},
|
||||||
libcommon.BytesToAddress([]byte{14}): &bls12381G2Mul{},
|
libcommon.BytesToAddress([]byte{14}): &bls12381G2Mul{},
|
||||||
libcommon.BytesToAddress([]byte{15}): &bls12381G2MultiExp{},
|
libcommon.BytesToAddress([]byte{15}): &bls12381G2MultiExp{},
|
||||||
libcommon.BytesToAddress([]byte{16}): &bls12381Pairing{},
|
libcommon.BytesToAddress([]byte{16}): &bls12381Pairing{},
|
||||||
libcommon.BytesToAddress([]byte{17}): &bls12381MapG1{},
|
libcommon.BytesToAddress([]byte{17}): &bls12381MapG1{},
|
||||||
libcommon.BytesToAddress([]byte{18}): &bls12381MapG2{},
|
libcommon.BytesToAddress([]byte{18}): &bls12381MapG2{},
|
||||||
libcommon.BytesToAddress([]byte{20}): &pointEvaluation{},
|
libcommon.BytesToAddress([]byte{20}): &pointEvaluation{},
|
||||||
|
libcommon.BytesToAddress([]byte{0x01, 0x00}): &p256Verify{},
|
||||||
}
|
}
|
||||||
|
|
||||||
// EIP-152 test vectors
|
// EIP-152 test vectors
|
||||||
@ -400,3 +401,19 @@ func BenchmarkPrecompiledBLS12381G2MultiExpWorstCase(b *testing.B) {
|
|||||||
}
|
}
|
||||||
benchmarkPrecompiled(b, "0f", testcase)
|
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)
|
||||||
|
}
|
||||||
|
@ -37,6 +37,8 @@ var emptyCodeHash = crypto.Keccak256Hash(nil)
|
|||||||
func (evm *EVM) precompile(addr libcommon.Address) (PrecompiledContract, bool) {
|
func (evm *EVM) precompile(addr libcommon.Address) (PrecompiledContract, bool) {
|
||||||
var precompiles map[libcommon.Address]PrecompiledContract
|
var precompiles map[libcommon.Address]PrecompiledContract
|
||||||
switch {
|
switch {
|
||||||
|
case evm.chainRules.IsNapoli:
|
||||||
|
precompiles = PrecompiledContractsNapoli
|
||||||
case evm.chainRules.IsCancun:
|
case evm.chainRules.IsCancun:
|
||||||
precompiles = PrecompiledContractsCancun
|
precompiles = PrecompiledContractsCancun
|
||||||
case evm.chainRules.IsBerlin:
|
case evm.chainRules.IsBerlin:
|
||||||
|
@ -128,6 +128,8 @@ func NewEVMInterpreter(evm *EVM, cfg Config) *EVMInterpreter {
|
|||||||
jt = &pragueInstructionSet
|
jt = &pragueInstructionSet
|
||||||
case evm.ChainRules().IsCancun:
|
case evm.ChainRules().IsCancun:
|
||||||
jt = &cancunInstructionSet
|
jt = &cancunInstructionSet
|
||||||
|
case evm.ChainRules().IsNapoli:
|
||||||
|
jt = &napoliInstructionSet
|
||||||
case evm.ChainRules().IsShanghai:
|
case evm.ChainRules().IsShanghai:
|
||||||
jt = &shanghaiInstructionSet
|
jt = &shanghaiInstructionSet
|
||||||
case evm.ChainRules().IsLondon:
|
case evm.ChainRules().IsLondon:
|
||||||
|
@ -61,6 +61,7 @@ var (
|
|||||||
berlinInstructionSet = newBerlinInstructionSet()
|
berlinInstructionSet = newBerlinInstructionSet()
|
||||||
londonInstructionSet = newLondonInstructionSet()
|
londonInstructionSet = newLondonInstructionSet()
|
||||||
shanghaiInstructionSet = newShanghaiInstructionSet()
|
shanghaiInstructionSet = newShanghaiInstructionSet()
|
||||||
|
napoliInstructionSet = newNapoliInstructionSet()
|
||||||
cancunInstructionSet = newCancunInstructionSet()
|
cancunInstructionSet = newCancunInstructionSet()
|
||||||
pragueInstructionSet = newPragueInstructionSet()
|
pragueInstructionSet = newPragueInstructionSet()
|
||||||
)
|
)
|
||||||
@ -99,12 +100,18 @@ func newPragueInstructionSet() JumpTable {
|
|||||||
// constantinople, istanbul, petersburg, berlin, london, paris, shanghai,
|
// constantinople, istanbul, petersburg, berlin, london, paris, shanghai,
|
||||||
// and cancun instructions.
|
// and cancun instructions.
|
||||||
func newCancunInstructionSet() JumpTable {
|
func newCancunInstructionSet() JumpTable {
|
||||||
|
instructionSet := newNapoliInstructionSet()
|
||||||
|
enable4844(&instructionSet) // BLOBHASH opcode
|
||||||
|
enable7516(&instructionSet) // BLOBBASEFEE opcode
|
||||||
|
validateAndFillMaxStack(&instructionSet)
|
||||||
|
return instructionSet
|
||||||
|
}
|
||||||
|
|
||||||
|
func newNapoliInstructionSet() JumpTable {
|
||||||
instructionSet := newShanghaiInstructionSet()
|
instructionSet := newShanghaiInstructionSet()
|
||||||
enable1153(&instructionSet) // Transient storage opcodes
|
enable1153(&instructionSet) // Transient storage opcodes
|
||||||
enable4844(&instructionSet) // BLOBHASH opcode
|
|
||||||
enable5656(&instructionSet) // MCOPY opcode
|
enable5656(&instructionSet) // MCOPY opcode
|
||||||
enable6780(&instructionSet) // SELFDESTRUCT only in same transaction
|
enable6780(&instructionSet) // SELFDESTRUCT only in same transaction
|
||||||
enable7516(&instructionSet) // BLOBBASEFEE opcode
|
|
||||||
validateAndFillMaxStack(&instructionSet)
|
validateAndFillMaxStack(&instructionSet)
|
||||||
return instructionSet
|
return instructionSet
|
||||||
}
|
}
|
||||||
|
37
core/vm/testdata/precompiles/p256Verify.json
vendored
Normal file
37
core/vm/testdata/precompiles/p256Verify.json
vendored
Normal 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
|
||||||
|
}
|
||||||
|
]
|
26
crypto/secp256r1/publickey.go
Normal file
26
crypto/secp256r1/publickey.go
Normal 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,
|
||||||
|
}
|
||||||
|
}
|
21
crypto/secp256r1/verifier.go
Normal file
21
crypto/secp256r1/verifier.go
Normal 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)
|
||||||
|
}
|
@ -90,6 +90,8 @@ type BorConfig interface {
|
|||||||
fmt.Stringer
|
fmt.Stringer
|
||||||
IsAgra(num uint64) bool
|
IsAgra(num uint64) bool
|
||||||
GetAgraBlock() *big.Int
|
GetAgraBlock() *big.Int
|
||||||
|
IsNapoli(num uint64) bool
|
||||||
|
GetNapoliBlock() *big.Int
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *Config) String() string {
|
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)
|
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.
|
// IsCancun returns whether time is either equal to the Cancun fork time or greater.
|
||||||
func (c *Config) IsCancun(time uint64) bool {
|
func (c *Config) IsCancun(time uint64) bool {
|
||||||
return isForked(c.CancunTime, time)
|
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
|
// Rules is a one time interface meaning that it shouldn't be used in between transition
|
||||||
// phases.
|
// phases.
|
||||||
type Rules struct {
|
type Rules struct {
|
||||||
ChainID *big.Int
|
ChainID *big.Int
|
||||||
IsHomestead, IsTangerineWhistle, IsSpuriousDragon bool
|
IsHomestead, IsTangerineWhistle, IsSpuriousDragon bool
|
||||||
IsByzantium, IsConstantinople, IsPetersburg, IsIstanbul bool
|
IsByzantium, IsConstantinople, IsPetersburg bool
|
||||||
IsBerlin, IsLondon, IsShanghai, IsCancun, IsPrague bool
|
IsIstanbul, IsBerlin, IsLondon, IsShanghai bool
|
||||||
IsAura bool
|
IsCancun, IsNapoli bool
|
||||||
|
IsPrague bool
|
||||||
|
IsAura bool
|
||||||
}
|
}
|
||||||
|
|
||||||
// Rules ensures c's ChainID is not nil and returns a new Rules instance
|
// 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),
|
IsLondon: c.IsLondon(num),
|
||||||
IsShanghai: c.IsShanghai(time) || c.IsAgra(num),
|
IsShanghai: c.IsShanghai(time) || c.IsAgra(num),
|
||||||
IsCancun: c.IsCancun(time),
|
IsCancun: c.IsCancun(time),
|
||||||
|
IsNapoli: c.IsNapoli(num),
|
||||||
IsPrague: c.IsPrague(time),
|
IsPrague: c.IsPrague(time),
|
||||||
IsAura: c.Aura != nil,
|
IsAura: c.Aura != nil,
|
||||||
}
|
}
|
||||||
|
@ -945,7 +945,7 @@ func (p *TxPool) isShanghai() bool {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (p *TxPool) isAgra() 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()
|
set := p.isPostAgra.Load()
|
||||||
if set {
|
if set {
|
||||||
return true
|
return true
|
||||||
|
@ -168,6 +168,9 @@ const (
|
|||||||
|
|
||||||
// EIP-4844: Shard Blob Transactions
|
// EIP-4844: Shard Blob Transactions
|
||||||
PointEvaluationGas uint64 = 50000
|
PointEvaluationGas uint64 = 50000
|
||||||
|
|
||||||
|
// PIP-27: secp256r1 elliptic curve signature verifier gas price
|
||||||
|
P256VerifyGas uint64 = 3450
|
||||||
)
|
)
|
||||||
|
|
||||||
// EIP-4788: Beacon block root in the EVM
|
// EIP-4788: Beacon block root in the EVM
|
||||||
|
@ -550,7 +550,7 @@ func ValidateHeaderUnusedFields(header *types.Header) error {
|
|||||||
return consensus.ErrUnexpectedWithdrawals
|
return consensus.ErrUnexpectedWithdrawals
|
||||||
}
|
}
|
||||||
|
|
||||||
return nil
|
return misc.VerifyAbsenceOfCancunHeaderFields(header)
|
||||||
}
|
}
|
||||||
|
|
||||||
// verifyCascadingFields verifies all the header fields that are not standalone,
|
// 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 validator by address
|
||||||
sort.Sort(valset.ValidatorsByAddress(newValidators))
|
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
|
var tempValidatorBytes []byte
|
||||||
|
|
||||||
for _, validator := range newValidators {
|
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()...)
|
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{
|
blockExtraData := &BlockExtraData{
|
||||||
ValidatorBytes: nil,
|
ValidatorBytes: nil,
|
||||||
TxDependency: nil,
|
TxDependency: nil,
|
||||||
@ -1584,7 +1584,7 @@ func GetTxDependency(b *types.Block) [][]uint64 {
|
|||||||
func GetValidatorBytes(h *types.Header, config *borcfg.BorConfig) []byte {
|
func GetValidatorBytes(h *types.Header, config *borcfg.BorConfig) []byte {
|
||||||
tempExtra := h.Extra
|
tempExtra := h.Extra
|
||||||
|
|
||||||
if !config.IsParallelUniverse(h.Number.Uint64()) {
|
if !config.IsNapoli(h.Number.Uint64()) {
|
||||||
return tempExtra[types.ExtraVanityLength : len(tempExtra)-types.ExtraSealLength]
|
return tempExtra[types.ExtraVanityLength : len(tempExtra)-types.ExtraSealLength]
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -20,14 +20,13 @@ type BorConfig struct {
|
|||||||
OverrideStateSyncRecords map[string]int `json:"overrideStateSyncRecords"` // override state records count
|
OverrideStateSyncRecords map[string]int `json:"overrideStateSyncRecords"` // override state records count
|
||||||
BlockAlloc map[string]interface{} `json:"blockAlloc"`
|
BlockAlloc map[string]interface{} `json:"blockAlloc"`
|
||||||
|
|
||||||
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)
|
||||||
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)
|
||||||
AgraBlock *big.Int `json:"agraBlock"` // Agra switch block (nil = no fork, 0 = already in agra)
|
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`
|
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
|
sprints sprints
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -126,15 +125,13 @@ func (c *BorConfig) GetAgraBlock() *big.Int {
|
|||||||
return c.AgraBlock
|
return c.AgraBlock
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO: modify this function once the block number is finalized
|
// Refer to https://forum.polygon.technology/t/pip-33-napoli-upgrade
|
||||||
func (c *BorConfig) IsParallelUniverse(number uint64) bool {
|
func (c *BorConfig) IsNapoli(num uint64) bool {
|
||||||
if c.ParallelUniverseBlock != nil {
|
return isForked(c.NapoliBlock, num)
|
||||||
if c.ParallelUniverseBlock.Cmp(big.NewInt(0)) == 0 {
|
}
|
||||||
return false
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return isForked(c.ParallelUniverseBlock, number)
|
func (c *BorConfig) GetNapoliBlock() *big.Int {
|
||||||
|
return c.NapoliBlock
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *BorConfig) CalculateStateSyncDelay(number uint64) uint64 {
|
func (c *BorConfig) CalculateStateSyncDelay(number uint64) uint64 {
|
||||||
|
Loading…
Reference in New Issue
Block a user