From 368844ad2a28ec07848e3c0169cf2b83b579a2e8 Mon Sep 17 00:00:00 2001 From: Aaron Buchwald Date: Mon, 23 Nov 2020 20:46:35 -0500 Subject: Add native asset precompiled contracts for apricot release --- params/config.go | 67 ++++++++++++++++++++++++++++++++++++++++++++--- params/protocol_params.go | 2 ++ 2 files changed, 65 insertions(+), 4 deletions(-) (limited to 'params') diff --git a/params/config.go b/params/config.go index e5ec64b..1e14c40 100644 --- a/params/config.go +++ b/params/config.go @@ -53,6 +53,49 @@ var CheckpointOracles = map[common.Hash]*CheckpointOracleConfig{ } var ( + // AvalancheMainnetChainID ... + AvalancheMainnetChainID = big.NewInt(43114) + // AvalancheFujiChainID ... + AvalancheFujiChainID = big.NewInt(43113) +) + +var ( + // AvalancheApricotMainnetChainConfig is the configuration for Avalanche Main Network + AvalancheApricotMainnetChainConfig = &ChainConfig{ + ChainID: AvalancheMainnetChainID, + HomesteadBlock: big.NewInt(0), + DAOForkBlock: big.NewInt(0), + DAOForkSupport: true, + EIP150Block: big.NewInt(0), + EIP150Hash: common.HexToHash("0x2086799aeebeae135c246c65021c82b4e15a2c451340993aacfd2751886514f0"), + EIP155Block: big.NewInt(0), + ByzantiumBlock: big.NewInt(0), + ConstantinopleBlock: big.NewInt(0), + PetersburgBlock: big.NewInt(0), + IstanbulBlock: big.NewInt(0), + MuirGlacierBlock: big.NewInt(0), + ApricotBlock: big.NewInt(0), // TODO specify correct block height + } + + // AvalancheApricotFujiChainConfig is the configuration for the Fuji Test Network + AvalancheApricotFujiChainConfig = &ChainConfig{ + ChainID: AvalancheFujiChainID, + HomesteadBlock: big.NewInt(0), + DAOForkBlock: big.NewInt(0), + DAOForkSupport: true, + EIP150Block: big.NewInt(0), + EIP150Hash: common.HexToHash("0x2086799aeebeae135c246c65021c82b4e15a2c451340993aacfd2751886514f0"), + EIP155Block: big.NewInt(0), + ByzantiumBlock: big.NewInt(0), + ConstantinopleBlock: big.NewInt(0), + PetersburgBlock: big.NewInt(0), + IstanbulBlock: big.NewInt(0), + MuirGlacierBlock: big.NewInt(0), + ApricotBlock: big.NewInt(0), // TODO specify correct block height + } + + // TODO update local network genesis to enable Apricot + // MainnetChainConfig is the chain parameters to run a node on the main network. MainnetChainConfig = &ChainConfig{ ChainID: big.NewInt(1), @@ -239,16 +282,16 @@ var ( // // This configuration is intentionally not using keyed fields to force anyone // adding flags to the config to also have to set these fields. - AllEthashProtocolChanges = &ChainConfig{big.NewInt(1337), big.NewInt(0), nil, false, big.NewInt(0), common.Hash{}, big.NewInt(0), big.NewInt(0), big.NewInt(0), big.NewInt(0), big.NewInt(0), big.NewInt(0), nil, nil, nil, new(EthashConfig), nil} + AllEthashProtocolChanges = &ChainConfig{big.NewInt(1337), big.NewInt(0), nil, false, big.NewInt(0), common.Hash{}, big.NewInt(0), big.NewInt(0), big.NewInt(0), big.NewInt(0), big.NewInt(0), big.NewInt(0), nil, nil, nil, nil, new(EthashConfig), nil} // AllCliqueProtocolChanges contains every protocol change (EIPs) introduced // and accepted by the Ethereum core developers into the Clique consensus. // // This configuration is intentionally not using keyed fields to force anyone // adding flags to the config to also have to set these fields. - AllCliqueProtocolChanges = &ChainConfig{big.NewInt(1337), big.NewInt(0), nil, false, big.NewInt(0), common.Hash{}, big.NewInt(0), big.NewInt(0), big.NewInt(0), big.NewInt(0), big.NewInt(0), big.NewInt(0), nil, nil, nil, nil, &CliqueConfig{Period: 0, Epoch: 30000}} + AllCliqueProtocolChanges = &ChainConfig{big.NewInt(1337), big.NewInt(0), nil, false, big.NewInt(0), common.Hash{}, big.NewInt(0), big.NewInt(0), big.NewInt(0), big.NewInt(0), big.NewInt(0), big.NewInt(0), nil, nil, nil, nil, nil, &CliqueConfig{Period: 0, Epoch: 30000}} - TestChainConfig = &ChainConfig{big.NewInt(1), big.NewInt(0), nil, false, big.NewInt(0), common.Hash{}, big.NewInt(0), big.NewInt(0), big.NewInt(0), big.NewInt(0), big.NewInt(0), big.NewInt(0), nil, nil, nil, new(EthashConfig), nil} + TestChainConfig = &ChainConfig{big.NewInt(1), big.NewInt(0), nil, false, big.NewInt(0), common.Hash{}, big.NewInt(0), big.NewInt(0), big.NewInt(0), big.NewInt(0), big.NewInt(0), big.NewInt(0), nil, nil, nil, nil, new(EthashConfig), nil} TestRules = TestChainConfig.Rules(new(big.Int)) ) @@ -323,6 +366,8 @@ type ChainConfig struct { YoloV1Block *big.Int `json:"yoloV1Block,omitempty"` // YOLO v1: https://github.com/ethereum/EIPs/pull/2657 (Ephemeral testnet) EWASMBlock *big.Int `json:"ewasmBlock,omitempty"` // EWASM switch block (nil = no fork, 0 = already activated) + ApricotBlock *big.Int `json:"apricotBlock,omitempty"` // Apricot switch block (nil = no fork, 0 = already activated) + // Various consensus engines Ethash *EthashConfig `json:"ethash,omitempty"` Clique *CliqueConfig `json:"clique,omitempty"` @@ -358,7 +403,7 @@ func (c *ChainConfig) String() string { default: engine = "unknown" } - return fmt.Sprintf("{ChainID: %v Homestead: %v DAO: %v DAOSupport: %v EIP150: %v EIP155: %v EIP158: %v Byzantium: %v Constantinople: %v Petersburg: %v Istanbul: %v, Muir Glacier: %v, YOLO v1: %v, Engine: %v}", + return fmt.Sprintf("{ChainID: %v Homestead: %v DAO: %v DAOSupport: %v EIP150: %v EIP155: %v EIP158: %v Byzantium: %v Constantinople: %v Petersburg: %v Istanbul: %v, Muir Glacier: %v, YOLO v1: %v, Apricot: %v, Engine: %v}", c.ChainID, c.HomesteadBlock, c.DAOForkBlock, @@ -372,6 +417,7 @@ func (c *ChainConfig) String() string { c.IstanbulBlock, c.MuirGlacierBlock, c.YoloV1Block, + c.ApricotBlock, engine, ) } @@ -438,6 +484,12 @@ func (c *ChainConfig) IsEWASM(num *big.Int) bool { return isForked(c.EWASMBlock, num) } +// IsApricot returns whether num represents a block number after the Apricot fork +func (c *ChainConfig) IsApricot(num *big.Int) bool { + return isForked(c.ApricotBlock, num) +} + +// TODO review how this works and see if it will work for a live transition // CheckCompatible checks whether scheduled fork transitions have been imported // with a mismatching chain configuration. func (c *ChainConfig) CheckCompatible(newcfg *ChainConfig, height uint64) *ConfigCompatError { @@ -477,6 +529,10 @@ func (c *ChainConfig) CheckConfigForkOrder() error { {name: "istanbulBlock", block: c.IstanbulBlock}, {name: "muirGlacierBlock", block: c.MuirGlacierBlock, optional: true}, {name: "yoloV1Block", block: c.YoloV1Block}, + // TODO figure out how Apricot fits in here. + // Precompiled contracts start from other end so they are compatible + // but it may be incompatible (and it was before Apricot as well) due + // to how the instruction sets are created } { if lastFork.name != "" { // Next one must be higher number @@ -610,6 +666,8 @@ type Rules struct { IsHomestead, IsEIP150, IsEIP155, IsEIP158 bool IsByzantium, IsConstantinople, IsPetersburg, IsIstanbul bool IsYoloV1 bool + // Avalanche Releases + IsApricot bool } // Rules ensures c's ChainID is not nil. @@ -629,5 +687,6 @@ func (c *ChainConfig) Rules(num *big.Int) Rules { IsPetersburg: c.IsPetersburg(num), IsIstanbul: c.IsIstanbul(num), IsYoloV1: c.IsYoloV1(num), + IsApricot: c.IsApricot(num), } } diff --git a/params/protocol_params.go b/params/protocol_params.go index 3536c83..fdfb9a5 100644 --- a/params/protocol_params.go +++ b/params/protocol_params.go @@ -95,6 +95,8 @@ const ( ExtcodeHashGasConstantinople uint64 = 400 // Cost of EXTCODEHASH (introduced in Constantinople) ExtcodeHashGasEIP1884 uint64 = 700 // Cost of EXTCODEHASH after EIP 1884 (part in Istanbul) SelfdestructGasEIP150 uint64 = 5000 // Cost of SELFDESTRUCT post EIP 150 (Tangerine) + AssetBalanceApricot uint64 = 20 // Cost of calling PrecompiledContract AssetBalance (Apricot) + AssetCallApricot uint64 = 40 // Cost of calling PrecompiledContract AssetCall (Apricot) // EXP has a dynamic portion depending on the size of the exponent ExpByteFrontier uint64 = 10 // was set to 10 in Frontier -- cgit v1.2.3-70-g09d2 From cc2a13f91f95bd377f5c3efb86ebbcc7096f6d97 Mon Sep 17 00:00:00 2001 From: Aaron Buchwald Date: Tue, 15 Dec 2020 17:30:03 -0500 Subject: Set chain rules based on block times for mainnet/fuji --- contracts/arc20.sol | 2 +- core/vm/evm.go | 2 +- params/config.go | 84 +++++++++++++++++++++++++++++++---------------------- plugin/evm/vm.go | 5 ++-- 4 files changed, 53 insertions(+), 40 deletions(-) (limited to 'params') diff --git a/contracts/arc20.sol b/contracts/arc20.sol index a7fc997..d1af6a3 100644 --- a/contracts/arc20.sol +++ b/contracts/arc20.sol @@ -2,7 +2,7 @@ pragma solidity >=0.6.0 <0.8.0; -import {NativeAssets} from "./NativeAssets.sol"; +import {NativeAssets} from "./nativeAssets.sol"; contract ARC20 { diff --git a/core/vm/evm.go b/core/vm/evm.go index ab04790..fe840da 100644 --- a/core/vm/evm.go +++ b/core/vm/evm.go @@ -152,7 +152,7 @@ func NewEVM(ctx Context, statedb StateDB, chainConfig *params.ChainConfig, vmCon StateDB: statedb, vmConfig: vmConfig, chainConfig: chainConfig, - chainRules: chainConfig.Rules(ctx.BlockNumber), + chainRules: chainConfig.AvalancheRules(ctx.BlockNumber, ctx.Time), interpreters: make([]Interpreter, 0, 1), } diff --git a/params/config.go b/params/config.go index 1e14c40..d5db94f 100644 --- a/params/config.go +++ b/params/config.go @@ -20,6 +20,7 @@ import ( "encoding/binary" "fmt" "math/big" + "time" "github.com/ethereum/go-ethereum/common" "github.com/ethereum/go-ethereum/crypto" @@ -62,40 +63,38 @@ var ( var ( // AvalancheApricotMainnetChainConfig is the configuration for Avalanche Main Network AvalancheApricotMainnetChainConfig = &ChainConfig{ - ChainID: AvalancheMainnetChainID, - HomesteadBlock: big.NewInt(0), - DAOForkBlock: big.NewInt(0), - DAOForkSupport: true, - EIP150Block: big.NewInt(0), - EIP150Hash: common.HexToHash("0x2086799aeebeae135c246c65021c82b4e15a2c451340993aacfd2751886514f0"), - EIP155Block: big.NewInt(0), - ByzantiumBlock: big.NewInt(0), - ConstantinopleBlock: big.NewInt(0), - PetersburgBlock: big.NewInt(0), - IstanbulBlock: big.NewInt(0), - MuirGlacierBlock: big.NewInt(0), - ApricotBlock: big.NewInt(0), // TODO specify correct block height + ChainID: AvalancheMainnetChainID, + HomesteadBlock: big.NewInt(0), + DAOForkBlock: big.NewInt(0), + DAOForkSupport: true, + EIP150Block: big.NewInt(0), + EIP150Hash: common.HexToHash("0x2086799aeebeae135c246c65021c82b4e15a2c451340993aacfd2751886514f0"), + EIP155Block: big.NewInt(0), + ByzantiumBlock: big.NewInt(0), + ConstantinopleBlock: big.NewInt(0), + PetersburgBlock: big.NewInt(0), + IstanbulBlock: big.NewInt(0), + MuirGlacierBlock: big.NewInt(0), + ApricotBlockTimestamp: new(big.Int).SetUint64(uint64(time.Date(2021, 1, 7, 5, 00, 0, 0, time.UTC).Unix())), } // AvalancheApricotFujiChainConfig is the configuration for the Fuji Test Network AvalancheApricotFujiChainConfig = &ChainConfig{ - ChainID: AvalancheFujiChainID, - HomesteadBlock: big.NewInt(0), - DAOForkBlock: big.NewInt(0), - DAOForkSupport: true, - EIP150Block: big.NewInt(0), - EIP150Hash: common.HexToHash("0x2086799aeebeae135c246c65021c82b4e15a2c451340993aacfd2751886514f0"), - EIP155Block: big.NewInt(0), - ByzantiumBlock: big.NewInt(0), - ConstantinopleBlock: big.NewInt(0), - PetersburgBlock: big.NewInt(0), - IstanbulBlock: big.NewInt(0), - MuirGlacierBlock: big.NewInt(0), - ApricotBlock: big.NewInt(0), // TODO specify correct block height + ChainID: AvalancheFujiChainID, + HomesteadBlock: big.NewInt(0), + DAOForkBlock: big.NewInt(0), + DAOForkSupport: true, + EIP150Block: big.NewInt(0), + EIP150Hash: common.HexToHash("0x2086799aeebeae135c246c65021c82b4e15a2c451340993aacfd2751886514f0"), + EIP155Block: big.NewInt(0), + ByzantiumBlock: big.NewInt(0), + ConstantinopleBlock: big.NewInt(0), + PetersburgBlock: big.NewInt(0), + IstanbulBlock: big.NewInt(0), + MuirGlacierBlock: big.NewInt(0), + ApricotBlockTimestamp: new(big.Int).SetUint64(uint64(time.Date(2020, 12, 23, 5, 00, 0, 0, time.UTC).Unix())), } - // TODO update local network genesis to enable Apricot - // MainnetChainConfig is the chain parameters to run a node on the main network. MainnetChainConfig = &ChainConfig{ ChainID: big.NewInt(1), @@ -366,7 +365,11 @@ type ChainConfig struct { YoloV1Block *big.Int `json:"yoloV1Block,omitempty"` // YOLO v1: https://github.com/ethereum/EIPs/pull/2657 (Ephemeral testnet) EWASMBlock *big.Int `json:"ewasmBlock,omitempty"` // EWASM switch block (nil = no fork, 0 = already activated) - ApricotBlock *big.Int `json:"apricotBlock,omitempty"` // Apricot switch block (nil = no fork, 0 = already activated) + // Avalanche Network Upgrade Block Timestamps: + + // Apricot switch block timestamp (nil = no fork, 0 = already activated) + // Apricot rules go into effect for blocks with a timestamp >= ApricotBlockTimestamp + ApricotBlockTimestamp *big.Int `json:"apricotBlock,omitempty"` // Various consensus engines Ethash *EthashConfig `json:"ethash,omitempty"` @@ -403,7 +406,7 @@ func (c *ChainConfig) String() string { default: engine = "unknown" } - return fmt.Sprintf("{ChainID: %v Homestead: %v DAO: %v DAOSupport: %v EIP150: %v EIP155: %v EIP158: %v Byzantium: %v Constantinople: %v Petersburg: %v Istanbul: %v, Muir Glacier: %v, YOLO v1: %v, Apricot: %v, Engine: %v}", + return fmt.Sprintf("{ChainID: %v Homestead: %v DAO: %v DAOSupport: %v EIP150: %v EIP155: %v EIP158: %v Byzantium: %v Constantinople: %v Petersburg: %v Istanbul: %v, Muir Glacier: %v, YOLO v1: %v, ApricotTimestamp: %v, Engine: %v}", c.ChainID, c.HomesteadBlock, c.DAOForkBlock, @@ -417,7 +420,7 @@ func (c *ChainConfig) String() string { c.IstanbulBlock, c.MuirGlacierBlock, c.YoloV1Block, - c.ApricotBlock, + c.ApricotBlockTimestamp, engine, ) } @@ -484,9 +487,12 @@ func (c *ChainConfig) IsEWASM(num *big.Int) bool { return isForked(c.EWASMBlock, num) } -// IsApricot returns whether num represents a block number after the Apricot fork -func (c *ChainConfig) IsApricot(num *big.Int) bool { - return isForked(c.ApricotBlock, num) +// Avalanche Forks: + +// IsApricot returns whether num represents a block with a timestamp +// after the Apricot fork time. +func (c *ChainConfig) IsApricot(blockTimestamp *big.Int) bool { + return isForked(c.ApricotBlockTimestamp, blockTimestamp) } // TODO review how this works and see if it will work for a live transition @@ -687,6 +693,14 @@ func (c *ChainConfig) Rules(num *big.Int) Rules { IsPetersburg: c.IsPetersburg(num), IsIstanbul: c.IsIstanbul(num), IsYoloV1: c.IsYoloV1(num), - IsApricot: c.IsApricot(num), } } + +// AvalancheRules returns the Avalanche modified rules to support Avalanche +// network upgrades +func (c *ChainConfig) AvalancheRules(blockNum, blockTimestamp *big.Int) Rules { + rules := c.Rules(blockNum) + + rules.IsApricot = c.IsApricot(blockTimestamp) + return rules +} diff --git a/plugin/evm/vm.go b/plugin/evm/vm.go index fc571b9..2732a79 100644 --- a/plugin/evm/vm.go +++ b/plugin/evm/vm.go @@ -243,11 +243,10 @@ func (vm *VM) Initialize( // TODO switch to correct block number of the fork switch { case g.Config.ChainID.Cmp(params.AvalancheMainnetChainID) == 0: - g.Config.ApricotBlock = nil + g.Config = params.AvalancheApricotMainnetChainConfig case g.Config.ChainID.Cmp(params.AvalancheFujiChainID) == 0: - g.Config.ApricotBlock = nil + g.Config = params.AvalancheApricotFujiChainConfig } - vm.acceptedDB = prefixdb.New([]byte(acceptedPrefix), db) vm.chainID = g.Config.ChainID -- cgit v1.2.3-70-g09d2 From faf845717a170e1c4baebaafef051d32058e2f99 Mon Sep 17 00:00:00 2001 From: Aaron Buchwald Date: Tue, 15 Dec 2020 17:34:48 -0500 Subject: Move params for network upgrade --- params/config.go | 11 +++++++++-- plugin/evm/vm.go | 8 ++++---- 2 files changed, 13 insertions(+), 6 deletions(-) (limited to 'params') diff --git a/params/config.go b/params/config.go index d5db94f..a0b4a51 100644 --- a/params/config.go +++ b/params/config.go @@ -53,6 +53,7 @@ var CheckpointOracles = map[common.Hash]*CheckpointOracleConfig{ GoerliGenesisHash: GoerliCheckpointOracle, } +// Avalanche ChainIDs var ( // AvalancheMainnetChainID ... AvalancheMainnetChainID = big.NewInt(43114) @@ -60,6 +61,12 @@ var ( AvalancheFujiChainID = big.NewInt(43113) ) +// Network upgrade block timestamps +var ( + AvalancheMainnetApricotTimestamp = new(big.Int).SetUint64(uint64(time.Date(2021, 1, 7, 5, 00, 0, 0, time.UTC).Unix())) + AvalancheFujiApricotTimestamp = new(big.Int).SetUint64(uint64(time.Date(2020, 12, 23, 5, 00, 0, 0, time.UTC).Unix())) +) + var ( // AvalancheApricotMainnetChainConfig is the configuration for Avalanche Main Network AvalancheApricotMainnetChainConfig = &ChainConfig{ @@ -75,7 +82,7 @@ var ( PetersburgBlock: big.NewInt(0), IstanbulBlock: big.NewInt(0), MuirGlacierBlock: big.NewInt(0), - ApricotBlockTimestamp: new(big.Int).SetUint64(uint64(time.Date(2021, 1, 7, 5, 00, 0, 0, time.UTC).Unix())), + ApricotBlockTimestamp: AvalancheMainnetApricotTimestamp, } // AvalancheApricotFujiChainConfig is the configuration for the Fuji Test Network @@ -92,7 +99,7 @@ var ( PetersburgBlock: big.NewInt(0), IstanbulBlock: big.NewInt(0), MuirGlacierBlock: big.NewInt(0), - ApricotBlockTimestamp: new(big.Int).SetUint64(uint64(time.Date(2020, 12, 23, 5, 00, 0, 0, time.UTC).Unix())), + ApricotBlockTimestamp: AvalancheFujiApricotTimestamp, } // MainnetChainConfig is the chain parameters to run a node on the main network. diff --git a/plugin/evm/vm.go b/plugin/evm/vm.go index 2732a79..9f5607a 100644 --- a/plugin/evm/vm.go +++ b/plugin/evm/vm.go @@ -239,13 +239,13 @@ func (vm *VM) Initialize( return err } - // Set the Apricot Fork Block on the ChainConfig - // TODO switch to correct block number of the fork + // If Mainnet or Fuji ChainID is present then switch + // manually set the config switch { case g.Config.ChainID.Cmp(params.AvalancheMainnetChainID) == 0: - g.Config = params.AvalancheApricotMainnetChainConfig + g.Config.ApricotBlockTimestamp = params.AvalancheMainnetApricotTimestamp case g.Config.ChainID.Cmp(params.AvalancheFujiChainID) == 0: - g.Config = params.AvalancheApricotFujiChainConfig + g.Config.ApricotBlockTimestamp = params.AvalancheFujiApricotTimestamp } vm.acceptedDB = prefixdb.New([]byte(acceptedPrefix), db) -- cgit v1.2.3-70-g09d2 From 8026c5f6c44a02ff44bb25cb941915f53cdc9e1c Mon Sep 17 00:00:00 2001 From: Aaron Buchwald Date: Tue, 15 Dec 2020 21:24:34 -0500 Subject: Change name of apricot block in config --- params/config.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'params') diff --git a/params/config.go b/params/config.go index a0b4a51..2f59170 100644 --- a/params/config.go +++ b/params/config.go @@ -376,7 +376,7 @@ type ChainConfig struct { // Apricot switch block timestamp (nil = no fork, 0 = already activated) // Apricot rules go into effect for blocks with a timestamp >= ApricotBlockTimestamp - ApricotBlockTimestamp *big.Int `json:"apricotBlock,omitempty"` + ApricotBlockTimestamp *big.Int `json:"apricotBlockTimestamp,omitempty"` // Various consensus engines Ethash *EthashConfig `json:"ethash,omitempty"` -- cgit v1.2.3-70-g09d2