forked from TrueCloudLab/neoneo-go
native: do not rewrite NextValidators in (*NEO).OnPersist()
There is no need in writing the same value again and again. Closes #1337.
This commit is contained in:
parent
1809076dc6
commit
4782a94200
2 changed files with 34 additions and 1 deletions
|
@ -26,7 +26,9 @@ type NEO struct {
|
||||||
nep5TokenNative
|
nep5TokenNative
|
||||||
GAS *GAS
|
GAS *GAS
|
||||||
|
|
||||||
validators atomic.Value
|
votesChanged atomic.Value
|
||||||
|
nextValidators atomic.Value
|
||||||
|
validators atomic.Value
|
||||||
}
|
}
|
||||||
|
|
||||||
// keyWithVotes is a serialized key with votes balance. It's not deserialized
|
// keyWithVotes is a serialized key with votes balance. It's not deserialized
|
||||||
|
@ -79,6 +81,8 @@ func NewNEO() *NEO {
|
||||||
nep5.ContractID = neoContractID
|
nep5.ContractID = neoContractID
|
||||||
|
|
||||||
n.nep5TokenNative = *nep5
|
n.nep5TokenNative = *nep5
|
||||||
|
n.votesChanged.Store(true)
|
||||||
|
n.nextValidators.Store(keys.PublicKeys(nil))
|
||||||
n.validators.Store(keys.PublicKeys(nil))
|
n.validators.Store(keys.PublicKeys(nil))
|
||||||
|
|
||||||
onp := n.Methods["onPersist"]
|
onp := n.Methods["onPersist"]
|
||||||
|
@ -152,10 +156,28 @@ func (n *NEO) Initialize(ic *interop.Context) error {
|
||||||
|
|
||||||
// OnPersist implements Contract interface.
|
// OnPersist implements Contract interface.
|
||||||
func (n *NEO) OnPersist(ic *interop.Context) error {
|
func (n *NEO) OnPersist(ic *interop.Context) error {
|
||||||
|
if !n.votesChanged.Load().(bool) {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
pubs, err := n.GetValidatorsInternal(ic.Chain, ic.DAO)
|
pubs, err := n.GetValidatorsInternal(ic.Chain, ic.DAO)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
prev := n.nextValidators.Load().(keys.PublicKeys)
|
||||||
|
if len(prev) == len(pubs) {
|
||||||
|
var needUpdate bool
|
||||||
|
for i := range pubs {
|
||||||
|
if !pubs[i].Equal(prev[i]) {
|
||||||
|
needUpdate = true
|
||||||
|
break
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if !needUpdate {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
}
|
||||||
|
n.votesChanged.Store(false)
|
||||||
|
n.nextValidators.Store(pubs)
|
||||||
si := new(state.StorageItem)
|
si := new(state.StorageItem)
|
||||||
si.Value = pubs.Bytes()
|
si.Value = pubs.Bytes()
|
||||||
return ic.DAO.PutStorageItem(n.ContractID, nextValidatorsKey, si)
|
return ic.DAO.PutStorageItem(n.ContractID, nextValidatorsKey, si)
|
||||||
|
@ -328,6 +350,7 @@ const (
|
||||||
// ModifyAccountVotes modifies votes of the specified account by value (can be negative).
|
// ModifyAccountVotes modifies votes of the specified account by value (can be negative).
|
||||||
// typ specifies if this modify is occurring during transfer or vote (with old or new validator).
|
// typ specifies if this modify is occurring during transfer or vote (with old or new validator).
|
||||||
func (n *NEO) ModifyAccountVotes(acc *state.NEOBalanceState, d dao.DAO, value *big.Int, typ int) error {
|
func (n *NEO) ModifyAccountVotes(acc *state.NEOBalanceState, d dao.DAO, value *big.Int, typ int) error {
|
||||||
|
n.votesChanged.Store(true)
|
||||||
if acc.VoteTo != nil {
|
if acc.VoteTo != nil {
|
||||||
key := makeValidatorKey(acc.VoteTo)
|
key := makeValidatorKey(acc.VoteTo)
|
||||||
si := d.GetStorageItem(n.ContractID, key)
|
si := d.GetStorageItem(n.ContractID, key)
|
||||||
|
|
|
@ -70,6 +70,11 @@ func TestNEO_Vote(t *testing.T) {
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
require.Equal(t, standBySorted, pubs)
|
require.Equal(t, standBySorted, pubs)
|
||||||
|
|
||||||
|
require.NoError(t, neo.OnPersist(ic))
|
||||||
|
pubs, err = neo.GetNextBlockValidatorsInternal(bc, ic.DAO)
|
||||||
|
require.NoError(t, err)
|
||||||
|
require.EqualValues(t, standBySorted, pubs)
|
||||||
|
|
||||||
// Register and give some value to the last validator.
|
// Register and give some value to the last validator.
|
||||||
require.NoError(t, neo.RegisterCandidateInternal(ic, candidates[0]))
|
require.NoError(t, neo.RegisterCandidateInternal(ic, candidates[0]))
|
||||||
priv := testchain.PrivateKeyByID(0)
|
priv := testchain.PrivateKeyByID(0)
|
||||||
|
@ -84,6 +89,11 @@ func TestNEO_Vote(t *testing.T) {
|
||||||
sort.Sort(sortedCandidates)
|
sort.Sort(sortedCandidates)
|
||||||
require.EqualValues(t, sortedCandidates, pubs)
|
require.EqualValues(t, sortedCandidates, pubs)
|
||||||
|
|
||||||
|
require.NoError(t, neo.OnPersist(ic))
|
||||||
|
pubs, err = neo.GetNextBlockValidatorsInternal(bc, ic.DAO)
|
||||||
|
require.NoError(t, err)
|
||||||
|
require.EqualValues(t, sortedCandidates, pubs)
|
||||||
|
|
||||||
require.NoError(t, neo.UnregisterCandidateInternal(ic, candidates[0]))
|
require.NoError(t, neo.UnregisterCandidateInternal(ic, candidates[0]))
|
||||||
require.Error(t, neo.VoteInternal(ic, h, candidates[0]))
|
require.Error(t, neo.VoteInternal(ic, h, candidates[0]))
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue