Skip to content

Commit

Permalink
native: check candidates againt Policy blocked list
Browse files Browse the repository at this point in the history
  • Loading branch information
roman-khimov authored and AnnaShaleva committed Apr 29, 2022
1 parent d84a222 commit 869b7cf
Show file tree
Hide file tree
Showing 3 changed files with 28 additions and 21 deletions.
10 changes: 4 additions & 6 deletions pkg/core/native/contract.go
Original file line number Diff line number Diff line change
Expand Up @@ -77,19 +77,17 @@ func NewContracts(cfg config.ProtocolConfiguration) *Contracts {

gas := newGAS(int64(cfg.InitialGASSupply), cfg.P2PSigExtensions)
neo := newNEO()
policy := newPolicy()
neo.GAS = gas
neo.Policy = policy
gas.NEO = neo
mgmt.NEO = neo
policy.NEO = neo

cs.GAS = gas
cs.NEO = neo
cs.Contracts = append(cs.Contracts, neo)
cs.Contracts = append(cs.Contracts, gas)

policy := newPolicy()
policy.NEO = neo
cs.Policy = policy
cs.Contracts = append(cs.Contracts, policy)
cs.Contracts = append(cs.Contracts, neo, gas, policy)

desig := newDesignate(cfg.P2PSigExtensions)
desig.NEO = neo
Expand Down
10 changes: 8 additions & 2 deletions pkg/core/native/native_neo.go
Original file line number Diff line number Diff line change
Expand Up @@ -20,17 +20,20 @@ import (
"github.com/nspcc-dev/neo-go/pkg/crypto/hash"
"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/io"
"github.com/nspcc-dev/neo-go/pkg/smartcontract"
"github.com/nspcc-dev/neo-go/pkg/smartcontract/callflag"
"github.com/nspcc-dev/neo-go/pkg/smartcontract/manifest"
"github.com/nspcc-dev/neo-go/pkg/util"
"github.com/nspcc-dev/neo-go/pkg/vm/emit"
"github.com/nspcc-dev/neo-go/pkg/vm/stackitem"
)

// NEO represents NEO native contract.
type NEO struct {
nep17TokenNative
GAS *GAS
GAS *GAS
Policy *Policy

// gasPerBlock represents current value of generated gas per block.
// It is append-only and doesn't need to be copied when used.
Expand Down Expand Up @@ -822,11 +825,14 @@ func (n *NEO) ModifyAccountVotes(acc *state.NEOBalance, d *dao.Simple, value *bi

func (n *NEO) getCandidates(d *dao.Simple, sortByKey bool) ([]keyWithVotes, error) {
arr := make([]keyWithVotes, 0)
buf := io.NewBufBinWriter()
d.Seek(n.ID, storage.SeekRange{Prefix: []byte{prefixCandidate}}, func(k, v []byte) bool {
c := new(candidate).FromBytes(v)
if c.Registered {
emit.CheckSig(buf.BinWriter, k)
if c.Registered && !n.Policy.IsBlockedInternal(d, hash.Hash160(buf.Bytes())) {
arr = append(arr, keyWithVotes{Key: string(k), Votes: &c.Votes})
}
buf.Reset()
return true
})

Expand Down
29 changes: 16 additions & 13 deletions pkg/core/native/native_test/neo_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,7 @@ func TestNEO_RegisterPrice(t *testing.T) {
func TestNEO_Vote(t *testing.T) {
neoCommitteeInvoker := newNeoCommitteeClient(t, 100_0000_0000)
neoValidatorsInvoker := neoCommitteeInvoker.WithSigners(neoCommitteeInvoker.Validator)
policyInvoker := neoCommitteeInvoker.CommitteeInvoker(neoCommitteeInvoker.NativeHash(t, nativenames.Policy))
e := neoCommitteeInvoker.Executor

cfg := e.Chain.GetConfig()
Expand All @@ -71,23 +72,23 @@ func TestNEO_Vote(t *testing.T) {

// voters vote for candidates. The aim of this test is to check that voting
// reward is proportional to the NEO balance.
voters := make([]neotest.Signer, committeeSize)
voters := make([]neotest.Signer, committeeSize+1)
// referenceAccounts perform the same actions as voters except voting, i.e. we
// will transfer the same amount of NEO to referenceAccounts and see how much
// GAS they receive for NEO ownership. We need these values to be able to define
// how much GAS voters receive for NEO ownership.
referenceAccounts := make([]neotest.Signer, committeeSize)
candidates := make([]neotest.Signer, committeeSize)
for i := 0; i < committeeSize; i++ {
referenceAccounts := make([]neotest.Signer, committeeSize+1)
candidates := make([]neotest.Signer, committeeSize+1)
for i := 0; i < committeeSize+1; i++ {
voters[i] = e.NewAccount(t, 10_0000_0000)
referenceAccounts[i] = e.NewAccount(t, 10_0000_0000)
candidates[i] = e.NewAccount(t, 2000_0000_0000) // enough for one registration
}
txes := make([]*transaction.Transaction, 0, committeeSize*4-2)
for i := 0; i < committeeSize; i++ {
transferTx := neoValidatorsInvoker.PrepareInvoke(t, "transfer", e.Validator.ScriptHash(), voters[i].(neotest.SingleSigner).Account().PrivateKey().GetScriptHash(), int64(committeeSize-i)*1000000, nil)
for i := 0; i < committeeSize+1; i++ {
transferTx := neoValidatorsInvoker.PrepareInvoke(t, "transfer", e.Validator.ScriptHash(), voters[i].(neotest.SingleSigner).Account().PrivateKey().GetScriptHash(), int64(committeeSize+1-i)*1000000, nil)
txes = append(txes, transferTx)
transferTx = neoValidatorsInvoker.PrepareInvoke(t, "transfer", e.Validator.ScriptHash(), referenceAccounts[i].(neotest.SingleSigner).Account().PrivateKey().GetScriptHash(), int64(committeeSize-i)*1000000, nil)
transferTx = neoValidatorsInvoker.PrepareInvoke(t, "transfer", e.Validator.ScriptHash(), referenceAccounts[i].(neotest.SingleSigner).Account().PrivateKey().GetScriptHash(), int64(committeeSize+1-i)*1000000, nil)
txes = append(txes, transferTx)
if i > 0 {
registerTx := neoValidatorsInvoker.WithSigners(candidates[i]).PrepareInvoke(t, "registerCandidate", candidates[i].(neotest.SingleSigner).Account().PrivateKey().PublicKey().Bytes())
Expand All @@ -96,6 +97,7 @@ func TestNEO_Vote(t *testing.T) {
txes = append(txes, voteTx)
}
}
txes = append(txes, policyInvoker.PrepareInvoke(t, "blockAccount", candidates[len(candidates)-1].(neotest.SingleSigner).Account().PrivateKey().PublicKey().GetScriptHash()))
neoValidatorsInvoker.AddNewBlock(t, txes...)
for _, tx := range txes {
e.CheckHalt(t, tx.Hash(), stackitem.Make(true)) // luckily, both `transfer`, `registerCandidate` and `vote` return boolean values
Expand Down Expand Up @@ -137,12 +139,12 @@ func TestNEO_Vote(t *testing.T) {
require.EqualValues(t, sortedCandidates, pubs)

t.Run("check voter rewards", func(t *testing.T) {
gasBalance := make([]*big.Int, len(voters))
referenceGASBalance := make([]*big.Int, len(referenceAccounts))
neoBalance := make([]*big.Int, len(voters))
txes = make([]*transaction.Transaction, 0, len(voters))
gasBalance := make([]*big.Int, len(voters)-1)
referenceGASBalance := make([]*big.Int, len(referenceAccounts)-1)
neoBalance := make([]*big.Int, len(voters)-1)
txes = make([]*transaction.Transaction, 0, len(voters)-1)
var refTxFee int64
for i := range voters {
for i := range voters[:len(voters)-1] {
h := voters[i].ScriptHash()
refH := referenceAccounts[i].ScriptHash()
gasBalance[i] = e.Chain.GetUtilityTokenBalance(h)
Expand All @@ -169,7 +171,7 @@ func TestNEO_Vote(t *testing.T) {

// GAS increase consists of 2 parts: NEO holding + voting for committee nodes.
// Here we check that 2-nd part exists and is proportional to the amount of NEO given.
for i := range voters {
for i := range voters[:len(voters)-1] {
newGAS := e.Chain.GetUtilityTokenBalance(voters[i].ScriptHash())
newGAS.Sub(newGAS, gasBalance[i])
gasForHold := referenceGASBalance[i]
Expand Down Expand Up @@ -197,6 +199,7 @@ func TestNEO_Vote(t *testing.T) {
require.NoError(t, err)
for i := range pubs {
require.NotEqual(t, candidates[0], pubs[i])
require.NotEqual(t, candidates[len(candidates)-1], pubs[i])
}
}

Expand Down

0 comments on commit 869b7cf

Please sign in to comment.