github.com/nspcc-dev/neo-go@v0.105.2-0.20240517133400-6be757af3eba/pkg/core/native/native_test/policy_test.go (about) 1 package native_test 2 3 import ( 4 "fmt" 5 "testing" 6 7 "github.com/nspcc-dev/neo-go/pkg/core/interop" 8 "github.com/nspcc-dev/neo-go/pkg/core/native" 9 "github.com/nspcc-dev/neo-go/pkg/core/native/nativenames" 10 "github.com/nspcc-dev/neo-go/pkg/core/transaction" 11 "github.com/nspcc-dev/neo-go/pkg/io" 12 "github.com/nspcc-dev/neo-go/pkg/neotest" 13 "github.com/nspcc-dev/neo-go/pkg/smartcontract/callflag" 14 "github.com/nspcc-dev/neo-go/pkg/util" 15 "github.com/nspcc-dev/neo-go/pkg/vm/emit" 16 "github.com/nspcc-dev/neo-go/pkg/vm/opcode" 17 "github.com/nspcc-dev/neo-go/pkg/vm/stackitem" 18 ) 19 20 func newPolicyClient(t *testing.T) *neotest.ContractInvoker { 21 return newNativeClient(t, nativenames.Policy) 22 } 23 24 func TestPolicy_FeePerByte(t *testing.T) { 25 testGetSet(t, newPolicyClient(t), "FeePerByte", 1000, 0, 100_000_000) 26 } 27 28 func TestPolicy_FeePerByteCache(t *testing.T) { 29 testGetSetCache(t, newPolicyClient(t), "FeePerByte", 1000) 30 } 31 32 func TestPolicy_ExecFeeFactor(t *testing.T) { 33 testGetSet(t, newPolicyClient(t), "ExecFeeFactor", interop.DefaultBaseExecFee, 1, 1000) 34 } 35 36 func TestPolicy_ExecFeeFactorCache(t *testing.T) { 37 testGetSetCache(t, newPolicyClient(t), "ExecFeeFactor", interop.DefaultBaseExecFee) 38 } 39 40 func TestPolicy_StoragePrice(t *testing.T) { 41 testGetSet(t, newPolicyClient(t), "StoragePrice", native.DefaultStoragePrice, 1, 10000000) 42 } 43 44 func TestPolicy_StoragePriceCache(t *testing.T) { 45 testGetSetCache(t, newPolicyClient(t), "StoragePrice", native.DefaultStoragePrice) 46 } 47 48 func TestPolicy_AttributeFee(t *testing.T) { 49 c := newPolicyClient(t) 50 getName := "getAttributeFee" 51 setName := "setAttributeFee" 52 53 randomInvoker := c.WithSigners(c.NewAccount(t)) 54 committeeInvoker := c.WithSigners(c.Committee) 55 56 t.Run("set, not signed by committee", func(t *testing.T) { 57 randomInvoker.InvokeFail(t, "invalid committee signature", setName, byte(transaction.ConflictsT), 123) 58 }) 59 t.Run("get, unknown attribute", func(t *testing.T) { 60 randomInvoker.InvokeFail(t, "invalid attribute type: 84", getName, byte(0x54)) 61 }) 62 t.Run("get, default value", func(t *testing.T) { 63 randomInvoker.Invoke(t, 0, getName, byte(transaction.ConflictsT)) 64 }) 65 t.Run("set, too large value", func(t *testing.T) { 66 committeeInvoker.InvokeFail(t, "out of range", setName, byte(transaction.ConflictsT), 10_0000_0001) 67 }) 68 t.Run("set, unknown attribute", func(t *testing.T) { 69 committeeInvoker.InvokeFail(t, "invalid attribute type: 84", setName, 0x54, 5) 70 }) 71 t.Run("set, success", func(t *testing.T) { 72 // Set and get in the same block. 73 txSet := committeeInvoker.PrepareInvoke(t, setName, byte(transaction.ConflictsT), 1) 74 txGet := randomInvoker.PrepareInvoke(t, getName, byte(transaction.ConflictsT)) 75 c.AddNewBlock(t, txSet, txGet) 76 c.CheckHalt(t, txSet.Hash(), stackitem.Null{}) 77 c.CheckHalt(t, txGet.Hash(), stackitem.Make(1)) 78 // Get in the next block. 79 randomInvoker.Invoke(t, 1, getName, byte(transaction.ConflictsT)) 80 }) 81 } 82 83 func TestPolicy_AttributeFeeCache(t *testing.T) { 84 c := newPolicyClient(t) 85 getName := "getAttributeFee" 86 setName := "setAttributeFee" 87 88 committeeInvoker := c.WithSigners(c.Committee) 89 90 // Change fee, abort the transaction and check that contract cache wasn't persisted 91 // for FAULTed tx at the same block. 92 w := io.NewBufBinWriter() 93 emit.AppCall(w.BinWriter, committeeInvoker.Hash, setName, callflag.All, byte(transaction.ConflictsT), 5) 94 emit.Opcodes(w.BinWriter, opcode.ABORT) 95 tx1 := committeeInvoker.PrepareInvocation(t, w.Bytes(), committeeInvoker.Signers) 96 tx2 := committeeInvoker.PrepareInvoke(t, getName, byte(transaction.ConflictsT)) 97 committeeInvoker.AddNewBlock(t, tx1, tx2) 98 committeeInvoker.CheckFault(t, tx1.Hash(), "ABORT") 99 committeeInvoker.CheckHalt(t, tx2.Hash(), stackitem.Make(0)) 100 101 // Change fee and check that change is available for the next tx. 102 tx1 = committeeInvoker.PrepareInvoke(t, setName, byte(transaction.ConflictsT), 5) 103 tx2 = committeeInvoker.PrepareInvoke(t, getName, byte(transaction.ConflictsT)) 104 committeeInvoker.AddNewBlock(t, tx1, tx2) 105 committeeInvoker.CheckHalt(t, tx1.Hash()) 106 committeeInvoker.CheckHalt(t, tx2.Hash(), stackitem.Make(5)) 107 } 108 109 func TestPolicy_BlockedAccounts(t *testing.T) { 110 c := newPolicyClient(t) 111 e := c.Executor 112 randomInvoker := c.WithSigners(c.NewAccount(t)) 113 committeeInvoker := c.WithSigners(c.Committee) 114 unlucky := util.Uint160{1, 2, 3} 115 116 t.Run("isBlocked", func(t *testing.T) { 117 randomInvoker.Invoke(t, false, "isBlocked", unlucky) 118 }) 119 120 t.Run("block-unblock account", func(t *testing.T) { 121 committeeInvoker.Invoke(t, true, "blockAccount", unlucky) 122 randomInvoker.Invoke(t, true, "isBlocked", unlucky) 123 committeeInvoker.Invoke(t, true, "unblockAccount", unlucky) 124 randomInvoker.Invoke(t, false, "isBlocked", unlucky) 125 }) 126 127 t.Run("double-block", func(t *testing.T) { 128 // block 129 committeeInvoker.Invoke(t, true, "blockAccount", unlucky) 130 131 // double-block should fail 132 committeeInvoker.Invoke(t, false, "blockAccount", unlucky) 133 134 // unblock 135 committeeInvoker.Invoke(t, true, "unblockAccount", unlucky) 136 137 // unblock the same account should fail as we don't have it blocked 138 committeeInvoker.Invoke(t, false, "unblockAccount", unlucky) 139 }) 140 141 t.Run("not signed by committee", func(t *testing.T) { 142 randomInvoker.InvokeFail(t, "invalid committee signature", "blockAccount", unlucky) 143 randomInvoker.InvokeFail(t, "invalid committee signature", "unblockAccount", unlucky) 144 }) 145 146 t.Run("block-unblock contract", func(t *testing.T) { 147 committeeInvoker.InvokeFail(t, "cannot block native contract", "blockAccount", c.NativeHash(t, nativenames.Neo)) 148 149 helper := neotest.CompileFile(t, c.CommitteeHash, "./helpers/policyhelper", "./helpers/policyhelper/policyhelper.yml") 150 e.DeployContract(t, helper, nil) 151 helperInvoker := e.CommitteeInvoker(helper.Hash) 152 153 helperInvoker.Invoke(t, true, "do") 154 committeeInvoker.Invoke(t, true, "blockAccount", helper.Hash) 155 helperInvoker.InvokeFail(t, fmt.Sprintf("contract %s is blocked", helper.Hash.StringLE()), "do") 156 157 committeeInvoker.Invoke(t, true, "unblockAccount", helper.Hash) 158 helperInvoker.Invoke(t, true, "do") 159 }) 160 }