From 5456d9c3cc139e6b74ef7ce36472bb8cbd903770 Mon Sep 17 00:00:00 2001 From: Ekaterina Pavlova Date: Wed, 13 Mar 2024 23:11:45 +0300 Subject: [PATCH] native: clear LastGasPerVote when voting for NULL Port neo-project/neo#3173. Close #3345 Signed-off-by: Ekaterina Pavlova --- pkg/core/native/native_neo.go | 3 ++ pkg/core/native/native_test/neo_test.go | 41 +++++++++++++++++++++++++ 2 files changed, 44 insertions(+) diff --git a/pkg/core/native/native_neo.go b/pkg/core/native/native_neo.go index 620174a7fc..13d7d94f96 100644 --- a/pkg/core/native/native_neo.go +++ b/pkg/core/native/native_neo.go @@ -932,6 +932,9 @@ func (n *NEO) VoteInternal(ic *interop.Context, h util.Uint160, pub *keys.Public } ic.DAO.PutStorageItem(n.ID, key, acc.Bytes(ic.DAO.GetItemCtx())) + if pub == nil { + acc.LastGasPerVote = *big.NewInt(0) + } ic.AddNotification(n.Hash, "Vote", stackitem.NewArray([]stackitem.Item{ stackitem.NewByteArray(h.BytesBE()), keyToStackItem(oldVote), diff --git a/pkg/core/native/native_test/neo_test.go b/pkg/core/native/native_test/neo_test.go index bd8c2b43e4..cb6348fda3 100644 --- a/pkg/core/native/native_test/neo_test.go +++ b/pkg/core/native/native_test/neo_test.go @@ -118,6 +118,47 @@ func TestNEO_CandidateEvents(t *testing.T) { require.Equal(t, 0, len(aer.Events)) } +func TestNEO_VoteForNull(t *testing.T) { + neoCommitteeInvoker := newNeoCommitteeClient(t, 100_0000_0000) + neoValidatorsInvoker := neoCommitteeInvoker.WithSigners(neoCommitteeInvoker.Validator) + e := neoCommitteeInvoker.Executor + voter := e.NewAccount(t, 100_0000_0000) + candidate := e.NewAccount(t) + cfg := e.Chain.GetConfig() + committeeSize := cfg.GetCommitteeSize(0) + validatorsCount := cfg.GetNumOfCNs(0) + freq := validatorsCount + committeeSize + getAccountState := func(t *testing.T, account util.Uint160) *state.NEOBalance { + stack, err := neoCommitteeInvoker.TestInvoke(t, "getAccountState", account) + require.NoError(t, err) + as := new(state.NEOBalance) + err = as.FromStackItem(stack.Pop().Item()) + require.NoError(t, err) + return as + } + advanceChain := func(t *testing.T) { + for i := 0; i < freq; i++ { + neoCommitteeInvoker.AddNewBlock(t) + } + } + txes := make([]*transaction.Transaction, 0, committeeSize*4-2) + transferTx := neoValidatorsInvoker.PrepareInvoke(t, "transfer", e.Validator.ScriptHash(), candidate.(neotest.SingleSigner).Account().PrivateKey().GetScriptHash(), int64(committeeSize+1)*1000000, nil) + txes = append(txes, transferTx) + registerTx := neoValidatorsInvoker.WithSigners(candidate).PrepareInvoke(t, "registerCandidate", candidate.(neotest.SingleSigner).Account().PublicKey().Bytes()) + txes = append(txes, registerTx) + voteTx := neoValidatorsInvoker.WithSigners(voter).PrepareInvoke(t, "vote", voter.(neotest.SingleSigner).Account().PrivateKey().GetScriptHash(), nil) + txes = append(txes, voteTx) + advanceChain(t) + for _, tx := range txes { + e.CheckHalt(t, tx.Hash(), stackitem.Make(true)) + } + stateBefore := getAccountState(t, voter.ScriptHash()) + require.NotEqual(t, big.NewInt(0), stateBefore.LastGasPerVote) + + stateAfter := getAccountState(t, voter.ScriptHash()) + require.Equal(t, big.NewInt(0), stateAfter.LastGasPerVote) +} + func TestNEO_Vote(t *testing.T) { neoCommitteeInvoker := newNeoCommitteeClient(t, 100_0000_0000) neoValidatorsInvoker := neoCommitteeInvoker.WithSigners(neoCommitteeInvoker.Validator)