Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions builder/files/genesis-amoy.json
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@
"madhugiriProBlock": 29287400,
"dandeliBlock": 31890000,
"lisovoBlock": 33634700,
"lisovoProBlock": 34062000,
"skipValidatorByteCheck": [26160367, 26161087, 26171567, 26173743, 26175647],
"stateSyncConfirmationDelay": {
"0": 128
Expand Down
33 changes: 30 additions & 3 deletions core/vm/contracts.go
Original file line number Diff line number Diff line change
Expand Up @@ -134,7 +134,6 @@ var PrecompiledContractsPrague = PrecompiledContracts{
common.BytesToAddress([]byte{0x07}): &bn256ScalarMulIstanbul{},
common.BytesToAddress([]byte{0x08}): &bn256PairingIstanbul{},
common.BytesToAddress([]byte{0x09}): &blake2F{},
common.BytesToAddress([]byte{0x0a}): &kzgPointEvaluation{},
common.BytesToAddress([]byte{0x0b}): &bls12381G1Add{},
common.BytesToAddress([]byte{0x0c}): &bls12381G1MultiExp{},
common.BytesToAddress([]byte{0x0d}): &bls12381G2Add{},
Expand Down Expand Up @@ -191,7 +190,6 @@ var PrecompiledContractsMadhugiri = PrecompiledContracts{
common.BytesToAddress([]byte{0x07}): &bn256ScalarMulIstanbul{},
common.BytesToAddress([]byte{0x08}): &bn256PairingIstanbul{},
common.BytesToAddress([]byte{0x09}): &blake2F{},
common.BytesToAddress([]byte{0x0a}): &kzgPointEvaluation{},
common.BytesToAddress([]byte{0x0b}): &bls12381G1Add{},
common.BytesToAddress([]byte{0x0c}): &bls12381G1MultiExp{},
common.BytesToAddress([]byte{0x0d}): &bls12381G2Add{},
Expand All @@ -213,7 +211,6 @@ var PrecompiledContractsMadhugiriPro = PrecompiledContracts{
common.BytesToAddress([]byte{0x07}): &bn256ScalarMulIstanbul{},
common.BytesToAddress([]byte{0x08}): &bn256PairingIstanbul{},
common.BytesToAddress([]byte{0x09}): &blake2F{},
common.BytesToAddress([]byte{0x0a}): &kzgPointEvaluation{},
common.BytesToAddress([]byte{0x0b}): &bls12381G1Add{},
common.BytesToAddress([]byte{0x0c}): &bls12381G1MultiExp{},
common.BytesToAddress([]byte{0x0d}): &bls12381G2Add{},
Expand Down Expand Up @@ -247,7 +244,30 @@ var PrecompiledContractsLisovo = PrecompiledContracts{
common.BytesToAddress([]byte{0x01, 0x00}): &p256Verify{eip7951: true},
}

// PrecompiledContractsLisovoPro contains the set of pre-compiled Ethereum
// contracts used in the LisovoPro release (bor HF).
var PrecompiledContractsLisovoPro = PrecompiledContracts{
common.BytesToAddress([]byte{0x01}): &ecrecover{},
common.BytesToAddress([]byte{0x02}): &sha256hash{},
common.BytesToAddress([]byte{0x03}): &ripemd160hash{},
common.BytesToAddress([]byte{0x04}): &dataCopy{},
common.BytesToAddress([]byte{0x05}): &bigModExp{eip2565: true, eip7823: true, eip7883: true},
common.BytesToAddress([]byte{0x06}): &bn256AddIstanbul{},
common.BytesToAddress([]byte{0x07}): &bn256ScalarMulIstanbul{},
common.BytesToAddress([]byte{0x08}): &bn256PairingIstanbul{},
common.BytesToAddress([]byte{0x09}): &blake2F{},
common.BytesToAddress([]byte{0x0b}): &bls12381G1Add{},
common.BytesToAddress([]byte{0x0c}): &bls12381G1MultiExp{},
common.BytesToAddress([]byte{0x0d}): &bls12381G2Add{},
common.BytesToAddress([]byte{0x0e}): &bls12381G2MultiExp{},
common.BytesToAddress([]byte{0x0f}): &bls12381Pairing{},
common.BytesToAddress([]byte{0x10}): &bls12381MapG1{},
common.BytesToAddress([]byte{0x11}): &bls12381MapG2{},
common.BytesToAddress([]byte{0x01, 0x00}): &p256Verify{eip7951: true},
}

var (
PrecompiledAddressesLisovoPro []common.Address
PrecompiledAddressesLisovo []common.Address
PrecompiledAddressesMadhugiriPro []common.Address
PrecompiledAddressesMadhugiri []common.Address
Expand Down Expand Up @@ -294,10 +314,15 @@ func init() {
for k := range PrecompiledContractsLisovo {
PrecompiledAddressesLisovo = append(PrecompiledAddressesLisovo, k)
}
for k := range PrecompiledContractsLisovoPro {
PrecompiledAddressesLisovoPro = append(PrecompiledAddressesLisovoPro, k)
}
}

func activePrecompiledContracts(rules params.Rules) PrecompiledContracts {
switch {
case rules.IsLisovoPro:
return PrecompiledContractsLisovoPro
case rules.IsLisovo:
return PrecompiledContractsLisovo
case rules.IsMadhugiriPro:
Expand Down Expand Up @@ -331,6 +356,8 @@ func ActivePrecompiledContracts(rules params.Rules) PrecompiledContracts {
// ActivePrecompiles returns the precompile addresses enabled with the current configuration.
func ActivePrecompiles(rules params.Rules) []common.Address {
switch {
case rules.IsLisovoPro:
return PrecompiledAddressesLisovoPro
case rules.IsLisovo:
return PrecompiledAddressesLisovo
case rules.IsMadhugiriPro:
Expand Down
37 changes: 37 additions & 0 deletions core/vm/contracts_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -535,6 +535,7 @@ func TestReinforceMultiClientPreCompilesTest(t *testing.T) {
"IsMadhugiri",
"IsMadhugiriPro",
"IsLisovo",
"IsLisovoPro",
}

if len(actual) != len(expected) {
Expand Down Expand Up @@ -586,3 +587,39 @@ func TestLisovoCLZOpcode(t *testing.T) {
t.Errorf("CLZ gas: got %d, want %d", postLisovo[CLZ].constantGas, GasFastStep)
}
}

// TestKZGPointEvaluationPrecompileRemoval verifies that the kzgPointEvaluation precompile
// is present before LisovoPro and removed starting with LisovoPro.
func TestKZGPointEvaluationPrecompileRemoval(t *testing.T) {
t.Parallel()

kzgPointEvaluationAddr := common.BytesToAddress([]byte{0x0a})

// Test Lisovo: should have kzgPointEvaluation
lisovoRules := params.Rules{
IsLisovo: true,
IsMadhugiriPro: true,
IsMadhugiri: true,
}
lisovoPrecompiles := ActivePrecompiledContracts(lisovoRules)
if _, exists := lisovoPrecompiles[kzgPointEvaluationAddr]; !exists {
t.Error("kzgPointEvaluation (0x0a) should exist in Lisovo precompiles")
}

// Verify it's the correct type
if _, ok := lisovoPrecompiles[kzgPointEvaluationAddr].(*kzgPointEvaluation); !ok {
t.Error("precompile at 0x0a should be kzgPointEvaluation type in Lisovo")
}

// Test LisovoPro: should not have kzgPointEvaluation
lisovoProRules := params.Rules{
IsLisovoPro: true,
IsLisovo: true,
IsMadhugiriPro: true,
IsMadhugiri: true,
}
lisovoProPrecompiles := ActivePrecompiledContracts(lisovoProRules)
if _, exists := lisovoProPrecompiles[kzgPointEvaluationAddr]; exists {
t.Error("kzgPointEvaluation (0x0a) should not exist in LisovoPro precompiles")
}
}
2 changes: 2 additions & 0 deletions core/vm/evm.go
Original file line number Diff line number Diff line change
Expand Up @@ -150,6 +150,8 @@ func NewEVM(blockCtx BlockContext, statedb StateDB, chainConfig *params.ChainCon
evm.precompiles = activePrecompiledContracts(evm.chainRules)

switch {
case evm.chainRules.IsLisovoPro:
evm.table = &lisovoProInstructionSet
case evm.chainRules.IsLisovo:
evm.table = &lisovoInstructionSet
case evm.chainRules.IsOsaka:
Expand Down
7 changes: 7 additions & 0 deletions core/vm/jump_table.go
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,7 @@ var (
pragueInstructionSet = newPragueInstructionSet()
osakaInstructionSet = newOsakaInstructionSet()
lisovoInstructionSet = newLisovoInstructionSet()
lisovoProInstructionSet = newLisovoProInstructionSet()
)

// JumpTable contains the EVM opcodes supported at a given fork.
Expand Down Expand Up @@ -94,6 +95,12 @@ func newLisovoInstructionSet() JumpTable {
return validate(instructionSet)
}

func newLisovoProInstructionSet() JumpTable {
instructionSet := newPragueInstructionSet()
enable7939(&instructionSet) // EIP-7939 (CLZ opcode)
return validate(instructionSet)
}

func newOsakaInstructionSet() JumpTable {
instructionSet := newPragueInstructionSet()
enable7939(&instructionSet) // EIP-7939 (CLZ opcode)
Expand Down
2 changes: 2 additions & 0 deletions core/vm/jump_table_export.go
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,8 @@ func LookupInstructionSet(rules params.Rules) (JumpTable, error) {
switch {
// Note: geth only returns an error for the verkle-fork.
// Return nil for other forks.
case rules.IsLisovoPro:
return newLisovoProInstructionSet(), nil
case rules.IsLisovo:
return newLisovoInstructionSet(), nil
case rules.IsMadhugiriPro:
Expand Down
58 changes: 58 additions & 0 deletions core/vm/jump_table_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@
package vm

import (
"reflect"
"testing"

"github.com/stretchr/testify/require"
Expand All @@ -35,3 +36,60 @@ func TestJumpTableCopy(t *testing.T) {
require.Equal(t, uint64(100), deepCopy[SLOAD].constantGas)
require.Equal(t, uint64(0), tbl[SLOAD].constantGas)
}

// TestLisovoProMatchesLisovo verifies that lisovoPro instruction set is identical to lisovo
func TestLisovoProMatchesLisovo(t *testing.T) {
t.Parallel()

lisovo := newLisovoInstructionSet()
lisovoPro := newLisovoProInstructionSet()

// Compare all 256 operations in the jump table
for i := 0; i < 256; i++ {
opLisovo := lisovo[i]
opLisovoPro := lisovoPro[i]

// Both should be non-nil
require.NotNil(t, opLisovo, "lisovo operation at index %d is nil", i)
require.NotNil(t, opLisovoPro, "lisovoPro operation at index %d is nil", i)

// Compare all fields
require.Equal(t, opLisovo.constantGas, opLisovoPro.constantGas,
"constantGas mismatch at opcode %#x", i)
require.Equal(t, opLisovo.minStack, opLisovoPro.minStack,
"minStack mismatch at opcode %#x", i)
require.Equal(t, opLisovo.maxStack, opLisovoPro.maxStack,
"maxStack mismatch at opcode %#x", i)
require.Equal(t, opLisovo.undefined, opLisovoPro.undefined,
"undefined mismatch at opcode %#x", i)

// Compare function pointers using reflection
require.Equal(t, reflect.ValueOf(opLisovo.execute).Pointer(),
reflect.ValueOf(opLisovoPro.execute).Pointer(),
"execute function mismatch at opcode %#x", i)

// Compare dynamicGas (can be nil)
if opLisovo.dynamicGas == nil && opLisovoPro.dynamicGas == nil {
// Both nil, ok
} else if opLisovo.dynamicGas == nil || opLisovoPro.dynamicGas == nil {
t.Errorf("dynamicGas nil mismatch at opcode %#x: lisovo=%v, lisovoPro=%v",
i, opLisovo.dynamicGas == nil, opLisovoPro.dynamicGas == nil)
} else {
require.Equal(t, reflect.ValueOf(opLisovo.dynamicGas).Pointer(),
reflect.ValueOf(opLisovoPro.dynamicGas).Pointer(),
"dynamicGas function mismatch at opcode %#x", i)
}

// Compare memorySize (can be nil)
if opLisovo.memorySize == nil && opLisovoPro.memorySize == nil {
// Both nil, ok
} else if opLisovo.memorySize == nil || opLisovoPro.memorySize == nil {
t.Errorf("memorySize nil mismatch at opcode %#x: lisovo=%v, lisovoPro=%v",
i, opLisovo.memorySize == nil, opLisovoPro.memorySize == nil)
} else {
require.Equal(t, reflect.ValueOf(opLisovo.memorySize).Pointer(),
reflect.ValueOf(opLisovoPro.memorySize).Pointer(),
"memorySize function mismatch at opcode %#x", i)
}
}
}
1 change: 1 addition & 0 deletions internal/cli/server/chains/amoy.go
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,7 @@ var amoyTestnet = &Chain{
MadhugiriProBlock: big.NewInt(29287400),
DandeliBlock: big.NewInt(31890000),
LisovoBlock: big.NewInt(33634700),
LisovoProBlock: big.NewInt(34062000),
StateSyncConfirmationDelay: map[string]uint64{
"0": 128,
},
Expand Down
12 changes: 12 additions & 0 deletions params/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -344,6 +344,7 @@ var (
MadhugiriProBlock: big.NewInt(29287400),
DandeliBlock: big.NewInt(31890000),
LisovoBlock: big.NewInt(33634700),
LisovoProBlock: big.NewInt(34062000),
StateSyncConfirmationDelay: map[string]uint64{
"0": 128,
},
Expand Down Expand Up @@ -731,6 +732,7 @@ var (
MadhugiriProBlock: big.NewInt(0),
DandeliBlock: big.NewInt(0),
LisovoBlock: big.NewInt(0),
LisovoProBlock: big.NewInt(0),
},
}

Expand Down Expand Up @@ -931,6 +933,7 @@ type BorConfig struct {
MadhugiriProBlock *big.Int `json:"madhugiriProBlock"` // MadhugiriPro switch block (nil = no fork, 0 = already on madhugiriPro)
DandeliBlock *big.Int `json:"dandeliBlock"` // Dandeli switch block (nil = no fork, 0 = already on dandeli)
LisovoBlock *big.Int `json:"lisovoBlock"` // Lisovo switch block (nil = no fork, 0 = already on lisovo)
LisovoProBlock *big.Int `json:"lisovoProBlock"` // LisovoPro switch block (nil = no fork, 0 = already on lisovoPro)
}

// String implements the stringer interface, returning the consensus engine details.
Expand Down Expand Up @@ -998,6 +1001,10 @@ func (c *BorConfig) IsLisovo(number *big.Int) bool {
return isBlockForked(c.LisovoBlock, number)
}

func (c *BorConfig) IsLisovoPro(number *big.Int) bool {
return isBlockForked(c.LisovoProBlock, number)
}

// GetTargetGasPercentage returns the target gas percentage for gas limit calculation.
// After Lisovo hard fork, this value can be configured via CLI flags (stored in BorConfig at runtime).
// It validates the configured value and falls back to defaults if invalid or nil.
Expand Down Expand Up @@ -1134,6 +1141,9 @@ func (c *ChainConfig) Description() string {
if c.Bor.LisovoBlock != nil {
banner += fmt.Sprintf(" - Lisovo: #%-8v\n", c.Bor.LisovoBlock)
}
if c.Bor.LisovoProBlock != nil {
banner += fmt.Sprintf(" - Lisovo Pro: #%-8v\n", c.Bor.LisovoProBlock)
}
return banner
}

Expand Down Expand Up @@ -1771,6 +1781,7 @@ type Rules struct {
IsMadhugiri bool
IsMadhugiriPro bool
IsLisovo bool
IsLisovoPro bool
}

// Rules ensures c's ChainID is not nil.
Expand Down Expand Up @@ -1805,5 +1816,6 @@ func (c *ChainConfig) Rules(num *big.Int, isMerge bool, _ uint64) Rules {
IsMadhugiri: c.Bor != nil && c.Bor.IsMadhugiri(num),
IsMadhugiriPro: c.Bor != nil && c.Bor.IsMadhugiriPro(num),
IsLisovo: c.Bor != nil && c.Bor.IsLisovo(num),
IsLisovoPro: c.Bor != nil && c.Bor.IsLisovoPro(num),
}
}
8 changes: 4 additions & 4 deletions params/version.go
Original file line number Diff line number Diff line change
Expand Up @@ -23,10 +23,10 @@ import (
)

const (
VersionMajor = 2 // Major version component of the current release
VersionMinor = 6 // Minor version component of the current release
VersionPatch = 0 // Patch version component of the current release
VersionMeta = "beta" // Version metadata to append to the version string
VersionMajor = 2 // Major version component of the current release
VersionMinor = 6 // Minor version component of the current release
VersionPatch = 0 // Patch version component of the current release
VersionMeta = "beta2" // Version metadata to append to the version string
)

var (
Expand Down
Loading