native: simplify votes saving in NEO contract

Follow C# behavior and fix state mismatch at block 11561 of preview2 testnet.
This commit is contained in:
Roman Khimov 2020-06-23 18:30:42 +03:00
parent e5f05790d5
commit d0331bf21b

View file

@ -11,6 +11,7 @@ import (
"github.com/nspcc-dev/neo-go/pkg/core/interop/runtime" "github.com/nspcc-dev/neo-go/pkg/core/interop/runtime"
"github.com/nspcc-dev/neo-go/pkg/core/state" "github.com/nspcc-dev/neo-go/pkg/core/state"
"github.com/nspcc-dev/neo-go/pkg/crypto/keys" "github.com/nspcc-dev/neo-go/pkg/crypto/keys"
"github.com/nspcc-dev/neo-go/pkg/encoding/bigint"
"github.com/nspcc-dev/neo-go/pkg/smartcontract" "github.com/nspcc-dev/neo-go/pkg/smartcontract"
"github.com/nspcc-dev/neo-go/pkg/smartcontract/manifest" "github.com/nspcc-dev/neo-go/pkg/smartcontract/manifest"
"github.com/nspcc-dev/neo-go/pkg/util" "github.com/nspcc-dev/neo-go/pkg/util"
@ -218,10 +219,8 @@ func (n *NEO) registerValidatorInternal(ic *interop.Context, pub *keys.PublicKey
return errors.New("already registered") return errors.New("already registered")
} }
si = new(state.StorageItem) si = new(state.StorageItem)
// It's the same simple counter, calling it `Votes` instead of `Balance` // Zero value.
// doesn't help a lot. si.Value = []byte{}
votes := state.NEP5BalanceState{}
si.Value = votes.Bytes()
return ic.DAO.PutStorageItem(n.ContractID, key, si) return ic.DAO.PutStorageItem(n.ContractID, key, si)
} }
@ -319,12 +318,9 @@ func (n *NEO) ModifyAccountVotes(acc *state.NEOBalanceState, d dao.DAO, value *b
if si == nil { if si == nil {
return errors.New("invalid validator") return errors.New("invalid validator")
} }
votes, err := state.NEP5BalanceStateFromBytes(si.Value) votes := bigint.FromBytes(si.Value)
if err != nil { votes.Add(votes, value)
return err si.Value = bigint.ToPreallocatedBytes(votes, si.Value[:0])
}
votes.Balance.Add(&votes.Balance, value)
si.Value = votes.Bytes()
if err := d.PutStorageItem(n.ContractID, key, si); err != nil { if err := d.PutStorageItem(n.ContractID, key, si); err != nil {
return err return err
} }
@ -339,11 +335,8 @@ func (n *NEO) getRegisteredValidators(d dao.DAO) ([]keyWithVotes, error) {
} }
arr := make([]keyWithVotes, 0, len(siMap)) arr := make([]keyWithVotes, 0, len(siMap))
for key, si := range siMap { for key, si := range siMap {
votes, err := state.NEP5BalanceStateFromBytes(si.Value) votes := bigint.FromBytes(si.Value)
if err != nil { arr = append(arr, keyWithVotes{key, votes})
return nil, err
}
arr = append(arr, keyWithVotes{key, &votes.Balance})
} }
sort.Slice(arr, func(i, j int) bool { return strings.Compare(arr[i].Key, arr[j].Key) == -1 }) sort.Slice(arr, func(i, j int) bool { return strings.Compare(arr[i].Key, arr[j].Key) == -1 })
return arr, nil return arr, nil