core/native: move NextValidators storage to NEO contract

This commit is contained in:
Roman Khimov 2020-04-26 13:42:05 +03:00
parent 66c80d429e
commit bc4a6a6bab
4 changed files with 40 additions and 62 deletions

View file

@ -34,7 +34,6 @@ type DAO interface {
GetHeaderHashes() ([]util.Uint256, error)
GetNEP5Balances(acc util.Uint160) (*state.NEP5Balances, error)
GetNEP5TransferLog(acc util.Uint160, index uint32) (*state.NEP5TransferLog, error)
GetNextBlockValidators() (keys.PublicKeys, error)
GetStorageItem(scripthash util.Uint160, key []byte) *state.StorageItem
GetStorageItems(hash util.Uint160) (map[string]*state.StorageItem, error)
GetStorageItemsWithPrefix(hash util.Uint160, prefix []byte) (map[string]*state.StorageItem, error)
@ -56,7 +55,6 @@ type DAO interface {
PutCurrentHeader(hashAndIndex []byte) error
PutNEP5Balances(acc util.Uint160, bs *state.NEP5Balances) error
PutNEP5TransferLog(acc util.Uint160, index uint32, lg *state.NEP5TransferLog) error
PutNextBlockValidators(keys.PublicKeys) error
PutStorageItem(scripthash util.Uint160, key []byte, si *state.StorageItem) error
PutUnspentCoinState(hash util.Uint256, ucs *state.UnspentCoin) error
PutValidatorState(vs *state.Validator) error
@ -311,38 +309,6 @@ func (dao *Simple) putUnspentCoinState(hash util.Uint256, ucs *state.UnspentCoin
// -- start validator.
// GetNextBlockValidators retrieves next block validators from store or nil if they are missing.
func (dao *Simple) GetNextBlockValidators() (keys.PublicKeys, error) {
key := []byte{byte(storage.STNextValidators)}
buf, err := dao.Store.Get(key)
if err != nil {
if err == storage.ErrKeyNotFound {
return nil, nil
}
return nil, err
}
var pubs keys.PublicKeys
r := io.NewBinReaderFromBuf(buf)
r.ReadArray(&pubs)
if r.Err != nil {
return nil, r.Err
}
return pubs, nil
}
// PutNextBlockValidators puts next block validators to store.
func (dao *Simple) PutNextBlockValidators(pubs keys.PublicKeys) error {
w := io.NewBufBinWriter()
w.WriteArray(pubs)
if w.Err != nil {
return w.Err
}
key := []byte{byte(storage.STNextValidators)}
return dao.Store.Put(key, w.Bytes())
}
// GetValidatorStateOrNew gets validator from store or created new one in case of error.
func (dao *Simple) GetValidatorStateOrNew(publicKey *keys.PublicKey) (*state.Validator, error) {
validatorState, err := dao.GetValidatorState(publicKey)

View file

@ -147,10 +147,9 @@ func (n *NEO) OnPersist(ic *interop.Context) error {
if err != nil {
return err
}
if err := ic.DAO.PutNextBlockValidators(pubs); err != nil {
return err
}
return nil
si := new(state.StorageItem)
si.Value = pubs.Bytes()
return ic.DAO.PutStorageItem(n.Hash, nextValidatorsKey, si)
}
func (n *NEO) increaseBalance(ic *interop.Context, h util.Uint160, si *state.StorageItem, amount *big.Int) error {
@ -171,23 +170,24 @@ func (n *NEO) increaseBalance(ic *interop.Context, h util.Uint160, si *state.Sto
if err != nil {
return err
}
if err := n.ModifyAccountVotes(oldAcc, ic.DAO, new(big.Int).Neg(&acc.Balance)); err != nil {
return err
if len(oldAcc.Votes) > 0 {
if err := n.ModifyAccountVotes(oldAcc, ic.DAO, new(big.Int).Neg(&acc.Balance)); err != nil {
return err
}
siVC := ic.DAO.GetStorageItem(n.Hash, validatorsCountKey)
if siVC == nil {
return errors.New("validators count uninitialized")
}
vc, err := ValidatorsCountFromBytes(siVC.Value)
if err != nil {
return err
}
vc[len(oldAcc.Votes)-1].Add(&vc[len(oldAcc.Votes)-1], amount)
siVC.Value = vc.Bytes()
if err := ic.DAO.PutStorageItem(n.Hash, validatorsCountKey, siVC); err != nil {
return err
}
}
siVC := ic.DAO.GetStorageItem(n.Hash, validatorsCountKey)
if siVC == nil {
return errors.New("validators count uninitialized")
}
vc, err := ValidatorsCountFromBytes(siVC.Value)
if err != nil {
return err
}
vc[len(oldAcc.Votes)-1].Add(&vc[len(oldAcc.Votes)-1], amount)
siVC.Value = vc.Bytes()
if err := ic.DAO.PutStorageItem(n.Hash, validatorsCountKey, siVC); err != nil {
return err
}
acc.Balance.Add(&acc.Balance, amount)
si.Value = acc.Bytes()
return nil
@ -372,7 +372,7 @@ func (n *NEO) getRegisteredValidatorsCall(ic *interop.Context, _ []vm.StackItem)
}
// GetValidatorsInternal returns a list of current validators.
func (n *NEO) GetValidatorsInternal(bc blockchainer.Blockchainer, d dao.DAO) ([]*keys.PublicKey, error) {
func (n *NEO) GetValidatorsInternal(bc blockchainer.Blockchainer, d dao.DAO) (keys.PublicKeys, error) {
si := d.GetStorageItem(n.Hash, validatorsCountKey)
if si == nil {
return nil, errors.New("validators count uninitialized")
@ -450,14 +450,17 @@ func (n *NEO) getNextBlockValidators(ic *interop.Context, _ []vm.StackItem) vm.S
}
// GetNextBlockValidatorsInternal returns next block validators.
func (n *NEO) GetNextBlockValidatorsInternal(bc blockchainer.Blockchainer, d dao.DAO) ([]*keys.PublicKey, error) {
result, err := d.GetNextBlockValidators()
if err != nil {
return nil, err
} else if result == nil {
func (n *NEO) GetNextBlockValidatorsInternal(bc blockchainer.Blockchainer, d dao.DAO) (keys.PublicKeys, error) {
si := d.GetStorageItem(n.Hash, nextValidatorsKey)
if si == nil {
return bc.GetStandByValidators()
}
return result, nil
pubs := keys.PublicKeys{}
err := pubs.DecodeBytes(si.Value)
if err != nil {
return nil, err
}
return pubs, nil
}
func pubsToArray(pubs keys.PublicKeys) vm.StackItem {

View file

@ -12,7 +12,6 @@ const (
STAccount KeyPrefix = 0x40
STCoin KeyPrefix = 0x44
STSpentCoin KeyPrefix = 0x45
STNextValidators KeyPrefix = 0x47
STValidator KeyPrefix = 0x48
STAsset KeyPrefix = 0x4c
STNotification KeyPrefix = 0x4d

View file

@ -35,6 +35,16 @@ func (keys *PublicKeys) DecodeBytes(data []byte) error {
return b.Err
}
// Bytes encodes PublicKeys to the new slice of bytes.
func (keys *PublicKeys) Bytes() []byte {
buf := io.NewBufBinWriter()
buf.WriteArray(*keys)
if buf.Err != nil {
panic(buf.Err)
}
return buf.Bytes()
}
// Contains checks whether passed param contained in PublicKeys.
func (keys PublicKeys) Contains(pKey *PublicKey) bool {
for _, key := range keys {