forked from TrueCloudLab/neoneo-go
Merge pull request #2010 from nspcc-dev/check-native-manifest
core: check stored native states against autogenerated ones on start
This commit is contained in:
commit
0f23f68dab
1 changed files with 37 additions and 0 deletions
|
@ -348,6 +348,43 @@ func (bc *Blockchain) init() error {
|
||||||
return fmt.Errorf("can't init cache for Management native contract: %w", err)
|
return fmt.Errorf("can't init cache for Management native contract: %w", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Check autogenerated native contracts' manifests and NEFs against the stored ones.
|
||||||
|
// Need to be done after native Management cache initialisation to be able to get
|
||||||
|
// contract state from DAO via high-level bc API.
|
||||||
|
for _, c := range bc.contracts.Contracts {
|
||||||
|
md := c.Metadata()
|
||||||
|
history := md.UpdateHistory
|
||||||
|
if len(history) == 0 || history[0] > bHeight {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
storedCS := bc.GetContractState(md.Hash)
|
||||||
|
if storedCS == nil {
|
||||||
|
return fmt.Errorf("native contract %s is not stored", md.Name)
|
||||||
|
}
|
||||||
|
w := io.NewBufBinWriter()
|
||||||
|
storedCS.EncodeBinary(w.BinWriter)
|
||||||
|
if w.Err != nil {
|
||||||
|
return fmt.Errorf("failed to check native %s state against autogenerated one: %w", md.Name, w.Err)
|
||||||
|
}
|
||||||
|
buff := w.Bytes()
|
||||||
|
storedCSBytes := make([]byte, len(buff))
|
||||||
|
copy(storedCSBytes, buff)
|
||||||
|
w.Reset()
|
||||||
|
autogenCS := &state.Contract{
|
||||||
|
ContractBase: md.ContractBase,
|
||||||
|
UpdateCounter: storedCS.UpdateCounter, // it can be restored only from the DB, so use the stored value.
|
||||||
|
}
|
||||||
|
autogenCS.EncodeBinary(w.BinWriter)
|
||||||
|
if w.Err != nil {
|
||||||
|
return fmt.Errorf("failed to check native %s state against autogenerated one: %w", md.Name, w.Err)
|
||||||
|
}
|
||||||
|
autogenCSBytes := w.Bytes()
|
||||||
|
if !bytes.Equal(storedCSBytes, autogenCSBytes) {
|
||||||
|
return fmt.Errorf("native %s: version mismatch (stored contract state differs from autogenerated one), "+
|
||||||
|
"try to resynchronize the node from the genesis", md.Name)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
return bc.updateExtensibleWhitelist(bHeight)
|
return bc.updateExtensibleWhitelist(bHeight)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue