core: update verified state root height

Signed-off-by: Evgenii Stratonikov <evgeniy@nspcc.ru>
This commit is contained in:
Evgenii Stratonikov 2020-06-22 10:42:46 +03:00
parent ab802cdd5f
commit 5ee3ecf381
2 changed files with 38 additions and 2 deletions

View file

@ -1235,7 +1235,7 @@ func (bc *Blockchain) AddStateRoot(r *state.MPTRoot) error {
our, err := bc.GetStateRoot(r.Index)
if err == nil {
if our.Flag == state.Verified {
return nil
return bc.updateStateHeight(r.Index)
} else if r.Witness == nil && our.Witness != nil {
r.Witness = our.Witness
}
@ -1257,10 +1257,24 @@ func (bc *Blockchain) AddStateRoot(r *state.MPTRoot) error {
}
flag = state.Verified
}
return bc.dao.PutStateRoot(&state.MPTRootState{
err = bc.dao.PutStateRoot(&state.MPTRootState{
MPTRoot: *r,
Flag: flag,
})
if err != nil {
return err
}
return bc.updateStateHeight(r.Index)
}
func (bc *Blockchain) updateStateHeight(newHeight uint32) error {
h, err := bc.dao.GetCurrentStateRootHeight()
if err != nil {
return errors.WithMessage(err, "can't get current state root height")
} else if newHeight == h+1 {
return bc.dao.PutCurrentStateRootHeight(h + 1)
}
return nil
}
// verifyStateRoot checks if state root is valid.

View file

@ -30,6 +30,7 @@ type DAO interface {
GetContractState(hash util.Uint160) (*state.Contract, error)
GetCurrentBlockHeight() (uint32, error)
GetCurrentHeaderHeight() (i uint32, h util.Uint256, err error)
GetCurrentStateRootHeight() (uint32, error)
GetHeaderHashes() ([]util.Uint256, error)
GetNEP5Balances(acc util.Uint160) (*state.NEP5Balances, error)
GetNEP5TransferLog(acc util.Uint160, index uint32) (*state.NEP5TransferLog, error)
@ -316,6 +317,27 @@ func (dao *Simple) InitMPT(height uint32) error {
return nil
}
// GetCurrentStateRootHeight returns current state root height.
func (dao *Simple) GetCurrentStateRootHeight() (uint32, error) {
key := []byte{byte(storage.DataMPT)}
val, err := dao.Store.Get(key)
if err != nil {
if err == storage.ErrKeyNotFound {
err = nil
}
return 0, err
}
return binary.LittleEndian.Uint32(val), nil
}
// PutCurrentStateRootHeight updates current state root height.
func (dao *Simple) PutCurrentStateRootHeight(height uint32) error {
key := []byte{byte(storage.DataMPT)}
val := make([]byte, 4)
binary.LittleEndian.PutUint32(val, height)
return dao.Store.Put(key, val)
}
// GetStateRoot returns state root of a given height.
func (dao *Simple) GetStateRoot(height uint32) (*state.MPTRootState, error) {
r := new(state.MPTRootState)