Skip to content

Commit

Permalink
Merge pull request #3724 from nspcc-dev/hf-latest-stable
Browse files Browse the repository at this point in the history
Latest stable hardforks
  • Loading branch information
AnnaShaleva authored Dec 6, 2024
2 parents a68856c + 5f09e00 commit 2bc41db
Show file tree
Hide file tree
Showing 8 changed files with 42 additions and 18 deletions.
16 changes: 15 additions & 1 deletion docs/node-configuration.md
Original file line number Diff line number Diff line change
Expand Up @@ -385,7 +385,7 @@ protocol-related settings described in the table below.
| --- | --- | --- | --- | --- |
| CommitteeHistory | map[uint32]uint32 | none | Number of committee members after the given height, for example `{0: 1, 20: 4}` sets up a chain with one committee member since the genesis and then changes the setting to 4 committee members at the height of 20. `StandbyCommittee` committee setting must have the number of keys equal or exceeding the highest value in this option. Blocks numbers where the change happens must be divisible by the old and by the new values simultaneously. If not set, committee size is derived from the `StandbyCommittee` setting and never changes. |
| Genesis | [Genesis](#Genesis-Configuration) | none | The set of genesis block settings including NeoGo-specific protocol extensions that should be enabled at the genesis block or during native contracts initialisation. |
| Hardforks | `map[string]uint32` | [] | The set of incompatible changes that affect node behaviour starting from the specified height. The default value is an empty set which should be interpreted as "each known hard-fork is applied from the zero blockchain height". The list of valid hard-fork names:<br>• `Aspidochelone` represents hard-fork introduced in [#2469](https://github.com/nspcc-dev/neo-go/pull/2469) (ported from the [reference](https://github.com/neo-project/neo/pull/2712)). It adjusts the prices of `System.Contract.CreateStandardAccount` and `System.Contract.CreateMultisigAccount` interops so that the resulting prices are in accordance with `sha256` method of native `CryptoLib` contract. It also includes [#2519](https://github.com/nspcc-dev/neo-go/pull/2519) (ported from the [reference](https://github.com/neo-project/neo/pull/2749)) that adjusts the price of `System.Runtime.GetRandom` interop and fixes its vulnerability. A special NeoGo-specific change is included as well for ContractManagement's update/deploy call flags behaviour to be compatible with pre-0.99.0 behaviour that was changed because of the [3.2.0 protocol change](https://github.com/neo-project/neo/pull/2653).<br>• `Basilisk` represents hard-fork introduced in [#3056](https://github.com/nspcc-dev/neo-go/pull/3056) (ported from the [reference](https://github.com/neo-project/neo/pull/2881)). It enables strict smart contract script check against a set of JMP instructions and against method boundaries enabled on contract deploy or update. It also includes [#3080](https://github.com/nspcc-dev/neo-go/pull/3080) (ported from the [reference](https://github.com/neo-project/neo/pull/2883)) that increases `stackitem.Integer` JSON parsing precision up to the maximum value supported by the NeoVM. It also includes [#3085](https://github.com/nspcc-dev/neo-go/pull/3085) (ported from the [reference](https://github.com/neo-project/neo/pull/2810)) that enables strict check for notifications emitted by a contract to precisely match the events specified in the contract manifest. <br>• `Cockatrice` represents hard-fork introduced in [#3402](https://github.com/nspcc-dev/neo-go/pull/3402) (ported from the [reference](https://github.com/neo-project/neo/pull/2942)). Initially it is introduced along with the ability to update native contracts. This hard-fork also includes a couple of new native smart contract APIs: `keccak256` of native CryptoLib contract introduced in [#3301](https://github.com/nspcc-dev/neo-go/pull/3301) (ported from the [reference](https://github.com/neo-project/neo/pull/2925)) and `getCommitteeAddress` of native NeoToken contract inctroduced in [#3362](https://github.com/nspcc-dev/neo-go/pull/3362) (ported from the [reference](https://github.com/neo-project/neo/pull/3154)).<br>• `Domovoi` represents hard-fork introduced in [#3476](https://github.com/nspcc-dev/neo-go/pull/3476) (ported from the [reference](https://github.com/neo-project/neo/pull/3290)). This hard-fork makes the node use executing contract state for the contract call permissions check instead of the state stored in the native Management. This change was introduced in [#3473](https://github.com/nspcc-dev/neo-go/pull/3473) and ported to the [reference](https://github.com/neo-project/neo/pull/3290). Also, this hard-fork makes the System.Runtime.GetNotifications interop properly count stack references of notification parameters which prevents users from creating objects that exceed [vm.MaxStackSize] constraint. This change is implemented in the [reference](https://github.com/neo-project/neo/pull/3301), but NeoGo has never had this bug, thus proper behaviour is preserved even before HFDomovoi. It results in the fact that some T5 transactions have different ApplicationLogs comparing to the C# node, but the node states match. See [#3485](https://github.com/nspcc-dev/neo-go/pull/3485) for details on NeoGo behaviour. |
| Hardforks | `map[string]uint32` | [] | The set of incompatible changes that affect node behaviour starting from the specified height. The default value is an empty set which should be interpreted as "each known stable hard-fork is applied from the zero blockchain height". See [Hardforks](#Hardforks) section for a list of supported keys. |
| Magic | `uint32` | `0` | Magic number which uniquely identifies Neo network. |
| MaxBlockSize | `uint32` | `262144` | Maximum block size in bytes. |
| MaxBlockSystemFee | `int64` | `900000000000` | Maximum overall transactions system fee per block. |
Expand Down Expand Up @@ -457,6 +457,20 @@ where:
Note that `Transaction` is a NeoGo extension that isn't supported by the NeoC#
node and must be disabled on the public Neo N3 networks.

### Hardforks

The latest stable hardfork as per 0.107.1 release is Domovoi. Echidna is still
in development and can change in an incompatible way.

| Name | Changes | References |
| --- | --- | --- |
| `Aspidochelone` | Adjusts the price of `System.Contract.CreateStandardAccount` and `System.Contract.CreateMultisigAccount` interops so that the resulting prices are in accordance with `sha256` method of native `CryptoLib` contract. Also adjusts the price of `System.Runtime.GetRandom` interop and fixes its vulnerability. A special NeoGo-specific change is included as well for ContractManagement's update/deploy call flags behaviour to be compatible with pre-0.99.0 behaviour that was changed because of the 3.2.0 protocol change | https://github.com/nspcc-dev/neo-go/pull/2469 <br> https://github.com/neo-project/neo/pull/2712 <br> https://github.com/nspcc-dev/neo-go/pull/2519 <br> https://github.com/neo-project/neo/pull/2749 <br> https://github.com/neo-project/neo/pull/2653 |
| `Basilisk` | Enables strict smart contract script check against a set of JMP instructions and against method boundaries enabled on contract deploy or update. Increases `stackitem.Integer` JSON parsing precision up to the maximum value supported by the NeoVM. Enables strict check for notifications emitted by a contract to precisely match the events specified in the contract manifest. | https://github.com/nspcc-dev/neo-go/pull/3056 <br> https://github.com/neo-project/neo/pull/2881 <br> https://github.com/nspcc-dev/neo-go/pull/3080 <br> https://github.com/neo-project/neo/pull/2883 <br> https://github.com/nspcc-dev/neo-go/pull/3085 <br> https://github.com/neo-project/neo/pull/2810 |
| `Cockatrice` | Introduces the ability to update native contracts. Includes a couple of new native smart contract APIs: `keccak256` of native CryptoLib contract and `getCommitteeAddress` of native NeoToken contract. | https://github.com/nspcc-dev/neo-go/pull/3402 <br> https://github.com/neo-project/neo/pull/2942 <br> https://github.com/nspcc-dev/neo-go/pull/3301 <br> https://github.com/neo-project/neo/pull/2925 <br> https://github.com/nspcc-dev/neo-go/pull/3362 <br> https://github.com/neo-project/neo/pull/3154 |
| `Domovoi` | Makes node use executing contract state for the contract call permissions check instead of the state stored in the native Management contract. In C# also makes System.Runtime.GetNotifications interop properly count stack references of notification parameters which prevents users from creating objects that exceed MaxStackSize constraint, but NeoGo has never had this bug, thus proper behaviour is preserved even before HFDomovoi. It results in the fact that some T5 testnet transactions have different ApplicationLogs compared to the C# node, but the node states match. | https://github.com/nspcc-dev/neo-go/pull/3476 <br> https://github.com/neo-project/neo/pull/3290 <br> https://github.com/nspcc-dev/neo-go/pull/3473 <br> https://github.com/neo-project/neo/pull/3290 <br> https://github.com/neo-project/neo/pull/3301 <br> https://github.com/nspcc-dev/neo-go/pull/3485 |
| `Echidna` | No changes for now | https://github.com/nspcc-dev/neo-go/pull/3554 |


## DB compatibility

Real networks with large number of blocks require a substantial amount of time
Expand Down
2 changes: 1 addition & 1 deletion pkg/compiler/native_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -310,7 +310,7 @@ func getMethod(t *testing.T, ctr interop.ContractMD, name string, params []strin
name = strings.TrimSuffix(name, "WithData")
}

latestHF := config.LatestHardfork()
latestHF := config.HFLatestKnown
cMD := ctr.HFSpecificContractMD(&latestHF)
md, ok := cMD.GetMethod(name, paramLen)
require.True(t, ok, cMD.Manifest.Name, name, paramLen)
Expand Down
31 changes: 21 additions & 10 deletions pkg/config/hardfork.go
Original file line number Diff line number Diff line change
Expand Up @@ -51,20 +51,36 @@ const (
hfLast
)

// HFLatestStable is the latest known stable hardfork that is enabled by
// default. The set above can contain other hardforks and even some name
// placeholders, but they need to be enabled manually then. It can change
// between releases even if the set of known hardforks is the same.
const HFLatestStable = HFDomovoi

// HFLatestKnown is the latest known hardfork.
const HFLatestKnown = hfLast >> 1

// StableHardforks is an ordered slice of all stable hardforks (before or
// equal [HFLatestStable]).
var StableHardforks []Hardfork

// Hardforks represents the ordered slice of all possible hardforks.
var Hardforks []Hardfork

// hardforks holds a map of Hardfork string representation to its type.
var hardforks map[string]Hardfork
var hardforks = make(map[string]Hardfork)

func init() {
var stableIndex int

for i := HFAspidochelone; i < hfLast; i = i << 1 {
if i <= HFLatestStable {
stableIndex++
}
Hardforks = append(Hardforks, i)
hardforks[i.String()] = i
}
hardforks = make(map[string]Hardfork, len(Hardforks))
for _, hf := range Hardforks {
hardforks[hf.String()] = hf
}
StableHardforks = Hardforks[:stableIndex]
}

// Cmp returns the result of hardforks comparison. It returns:
Expand Down Expand Up @@ -97,8 +113,3 @@ func IsHardforkValid(s string) bool {
_, ok := hardforks[s]
return ok
}

// LatestHardfork returns latest known hardfork.
func LatestHardfork() Hardfork {
return hfLast >> 1
}
4 changes: 2 additions & 2 deletions pkg/core/blockchain.go
Original file line number Diff line number Diff line change
Expand Up @@ -285,10 +285,10 @@ func NewBlockchain(s storage.Store, cfg config.Blockchain, log *zap.Logger) (*Bl
}
if cfg.Hardforks == nil {
cfg.Hardforks = map[string]uint32{}
for _, hf := range config.Hardforks {
for _, hf := range config.StableHardforks {
cfg.Hardforks[hf.String()] = 0
}
log.Info("Hardforks are not set, using default value")
log.Info("Hardforks are not set, enabling all stable ones", zap.Stringer("latest", config.HFLatestStable))
} else if len(cfg.Hardforks) != 0 {
// Explicitly set the height of all old omitted hardforks to 0 for proper
// IsHardforkEnabled behaviour.
Expand Down
1 change: 0 additions & 1 deletion pkg/core/blockchain_core_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -373,7 +373,6 @@ func TestNewBlockchain_InitHardforks(t *testing.T) {
config.HFBasilisk.String(): 0,
config.HFCockatrice.String(): 0,
config.HFDomovoi.String(): 0,
config.HFEchidna.String(): 0,
}, bc.GetConfig().Hardforks)
})
t.Run("empty set", func(t *testing.T) {
Expand Down
2 changes: 1 addition & 1 deletion pkg/core/blockchain_neotest_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -272,7 +272,7 @@ func TestBlockchain_StartFromExistingDB(t *testing.T) {

_, _, _, err = chain.NewMultiWithCustomConfigAndStoreNoCheck(t, customConfig, cache)
require.Error(t, err)
require.True(t, strings.Contains(err.Error(), fmt.Sprintf("native %s: version mismatch for the latest hardfork Echidna (stored contract state differs from autogenerated one)", nativenames.CryptoLib)), err)
require.True(t, strings.Contains(err.Error(), fmt.Sprintf("native %s: version mismatch for the latest hardfork Domovoi (stored contract state differs from autogenerated one)", nativenames.CryptoLib)), err)
})

t.Run("good", func(t *testing.T) {
Expand Down
2 changes: 1 addition & 1 deletion pkg/core/native/compatibility_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ import (
func TestNamesASCII(t *testing.T) {
cfg := config.ProtocolConfiguration{P2PSigExtensions: true}
cs := NewContracts(cfg)
latestHF := config.LatestHardfork()
latestHF := config.HFLatestKnown
for _, c := range cs.Contracts {
require.True(t, isASCII(c.Metadata().Name))
hfMD := c.Metadata().HFSpecificContractMD(&latestHF)
Expand Down
2 changes: 1 addition & 1 deletion pkg/core/native/contract_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ import (
func TestNativeGetMethod(t *testing.T) {
cfg := config.ProtocolConfiguration{P2PSigExtensions: true}
cs := NewContracts(cfg)
latestHF := config.LatestHardfork()
latestHF := config.HFLatestKnown
for _, c := range cs.Contracts {
hfMD := c.Metadata().HFSpecificContractMD(&latestHF)
t.Run(c.Metadata().Name, func(t *testing.T) {
Expand Down

0 comments on commit 2bc41db

Please sign in to comment.