native: implement HF-based update
A part of #3213. Signed-off-by: Anna Shaleva <shaleva.ann@nspcc.ru>
This commit is contained in:
parent
83fdcc8568
commit
d62fad1268
19 changed files with 416 additions and 105 deletions
|
@ -44,7 +44,7 @@ import (
|
|||
|
||||
// Tuning parameters.
|
||||
const (
|
||||
version = "0.2.10"
|
||||
version = "0.2.11"
|
||||
|
||||
// DefaultInitialGAS is the default amount of GAS emitted to the standby validators
|
||||
// multisignature account during native GAS contract initialization.
|
||||
|
@ -341,16 +341,36 @@ func (bc *Blockchain) GetDesignatedByRole(r noderoles.Role) (keys.PublicKeys, ui
|
|||
return res, h, err
|
||||
}
|
||||
|
||||
// getCurrentHF returns the latest currently enabled hardfork. In case if no hardforks are enabled, the
|
||||
// default config.Hardfork(0) value is returned.
|
||||
func (bc *Blockchain) getCurrentHF() config.Hardfork {
|
||||
var (
|
||||
height = bc.BlockHeight()
|
||||
current config.Hardfork
|
||||
)
|
||||
// Rely on the fact that hardforks list is continuous.
|
||||
for _, hf := range config.Hardforks {
|
||||
enableHeight, ok := bc.config.Hardforks[hf.String()]
|
||||
if !ok || height < enableHeight {
|
||||
break
|
||||
}
|
||||
current = hf
|
||||
}
|
||||
return current
|
||||
}
|
||||
|
||||
// SetOracle sets oracle module. It can safely be called on the running blockchain.
|
||||
// To unregister Oracle service use SetOracle(nil).
|
||||
func (bc *Blockchain) SetOracle(mod native.OracleService) {
|
||||
orc := bc.contracts.Oracle
|
||||
currentHF := bc.getCurrentHF()
|
||||
if mod != nil {
|
||||
md, ok := orc.GetMethod(manifest.MethodVerify, -1)
|
||||
orcMd := orc.HFSpecificContractMD(¤tHF)
|
||||
md, ok := orcMd.GetMethod(manifest.MethodVerify, -1)
|
||||
if !ok {
|
||||
panic(fmt.Errorf("%s method not found", manifest.MethodVerify))
|
||||
}
|
||||
mod.UpdateNativeContract(orc.NEF.Script, orc.GetOracleResponseScript(),
|
||||
mod.UpdateNativeContract(orcMd.NEF.Script, orc.GetOracleResponseScript(),
|
||||
orc.Hash, md.MD.Offset)
|
||||
keys, _, err := bc.GetDesignatedByRole(noderoles.Oracle)
|
||||
if err != nil {
|
||||
|
@ -487,6 +507,7 @@ func (bc *Blockchain) init() error {
|
|||
// Check autogenerated native contracts' manifests and NEFs against the stored ones.
|
||||
// Need to be done after native Management cache initialization to be able to get
|
||||
// contract state from DAO via high-level bc API.
|
||||
var current = bc.getCurrentHF()
|
||||
for _, c := range bc.contracts.Contracts {
|
||||
md := c.Metadata()
|
||||
storedCS := bc.GetContractState(md.Hash)
|
||||
|
@ -504,8 +525,9 @@ func (bc *Blockchain) init() error {
|
|||
if err != nil {
|
||||
return fmt.Errorf("failed to check native %s state against autogenerated one: %w", md.Name, err)
|
||||
}
|
||||
hfMD := md.HFSpecificContractMD(¤t)
|
||||
autogenCS := &state.Contract{
|
||||
ContractBase: md.ContractBase,
|
||||
ContractBase: hfMD.ContractBase,
|
||||
UpdateCounter: storedCS.UpdateCounter, // it can be restored only from the DB, so use the stored value.
|
||||
}
|
||||
autogenCSBytes, err := stackitem.SerializeConvertible(autogenCS)
|
||||
|
@ -2269,8 +2291,16 @@ func (bc *Blockchain) GetNativeContractScriptHash(name string) (util.Uint160, er
|
|||
// GetNatives returns list of native contracts.
|
||||
func (bc *Blockchain) GetNatives() []state.NativeContract {
|
||||
res := make([]state.NativeContract, 0, len(bc.contracts.Contracts))
|
||||
current := bc.getCurrentHF()
|
||||
for _, c := range bc.contracts.Contracts {
|
||||
res = append(res, c.Metadata().NativeContract)
|
||||
activeIn := c.ActiveIn()
|
||||
if !(activeIn == nil || activeIn.Cmp(current) <= 0) {
|
||||
continue
|
||||
}
|
||||
md := c.Metadata().HFSpecificContractMD(¤t)
|
||||
res = append(res, state.NativeContract{
|
||||
ContractBase: md.ContractBase,
|
||||
})
|
||||
}
|
||||
return res
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue