Skip to content

Perform native contract initialization for the set of hardforks #3200

@AnnaShaleva

Description

@AnnaShaleva

Summary or problem description
I've finished the port of HF-based native contract update, and this is the last remaining issue connected with this functionality. Currently native contract initialization happens every time when native contract needs to be deployed or updated:

await contract.Initialize(engine, hf);

This code works perfectly for the current mainnet/testnet and for the current version of native contracts. However, there might be a case (in some private installations like I had for the tests) when several hardforks are being active starting from the same height. Technically it's a valid node configuration, so let's take as an example the case when all hardforks are enabled from the genesis block. In this case await contract.Initialize(engine, hf); will be called only once during Genesis block persist with nil hardfork value.

Let's take as an example the following Initialize override:

internal override ContractTask Initialize(ApplicationEngine engine, Hardfork? hardfork)
{
if (hardfork == ActiveIn)
{
UInt160 account = Contract.GetBFTAddress(engine.ProtocolSettings.StandbyValidators);
return Mint(engine, account, engine.ProtocolSettings.InitialGasDistribution, false);
}
return ContractTask.CompletedTask;
}

The problem is: if we ever decide to extend this Initialize method with some contract storage changes required on new HFDomovoy hardfork (that is different from the contract's ActiveIn), then the initialization code is not going to work properly in case when several hardforks are active starting from the same height.

Do you have any solution you want to propose?
Call await contract.Initialize(engine, hf); in cycle consequently for the range of hardforks, starting from the hf and ending with the last hardfork that is active starting from the current block. Then native contracts will be able to properly manage their storage inside the Initialize override based on the provided hardfork. This change won't affect the existing behaviour for mainnet/testnet.

Where in the software does this update applies to?

  • Native contracts

Additional information
See the nspcc-dev/neo-go#3402 (comment).

Please, note that currently it's not a bug/problem for mainnet/testnet, that's why I'm creating a discussion issue rather than bug. But it can easily become a bug in future on further native contracts code extension, so to me it's worth solving right now.

Metadata

Metadata

Assignees

Labels

DiscussionInitial issue state - proposed but not yet accepted

Type

No type

Projects

No projects

Milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions