forked from TrueCloudLab/neoneo-go
rpcclient: add policy package for the PolicyContract contract
And test it with the RPC server. Notice that getters still return int64 instead of *big.Int, that's because these values are very limited and technically could even fit into an int (but that seems to be too dangerous to use for long-term compatibility).
This commit is contained in:
parent
ee72b2fa29
commit
5d5455312a
4 changed files with 490 additions and 0 deletions
|
@ -9,16 +9,22 @@ import (
|
||||||
)
|
)
|
||||||
|
|
||||||
// GetFeePerByte invokes `getFeePerByte` method on a native Policy contract.
|
// GetFeePerByte invokes `getFeePerByte` method on a native Policy contract.
|
||||||
|
//
|
||||||
|
// Deprecated: please use policy subpackage.
|
||||||
func (c *Client) GetFeePerByte() (int64, error) {
|
func (c *Client) GetFeePerByte() (int64, error) {
|
||||||
return c.invokeNativePolicyMethod("getFeePerByte")
|
return c.invokeNativePolicyMethod("getFeePerByte")
|
||||||
}
|
}
|
||||||
|
|
||||||
// GetExecFeeFactor invokes `getExecFeeFactor` method on a native Policy contract.
|
// GetExecFeeFactor invokes `getExecFeeFactor` method on a native Policy contract.
|
||||||
|
//
|
||||||
|
// Deprecated: please use policy subpackage.
|
||||||
func (c *Client) GetExecFeeFactor() (int64, error) {
|
func (c *Client) GetExecFeeFactor() (int64, error) {
|
||||||
return c.invokeNativePolicyMethod("getExecFeeFactor")
|
return c.invokeNativePolicyMethod("getExecFeeFactor")
|
||||||
}
|
}
|
||||||
|
|
||||||
// GetStoragePrice invokes `getStoragePrice` method on a native Policy contract.
|
// GetStoragePrice invokes `getStoragePrice` method on a native Policy contract.
|
||||||
|
//
|
||||||
|
// Deprecated: please use policy subpackage.
|
||||||
func (c *Client) GetStoragePrice() (int64, error) {
|
func (c *Client) GetStoragePrice() (int64, error) {
|
||||||
return c.invokeNativePolicyMethod("getStoragePrice")
|
return c.invokeNativePolicyMethod("getStoragePrice")
|
||||||
}
|
}
|
||||||
|
@ -46,6 +52,8 @@ func (c *Client) invokeNativeGetMethod(hash util.Uint160, operation string) (int
|
||||||
}
|
}
|
||||||
|
|
||||||
// IsBlocked invokes `isBlocked` method on native Policy contract.
|
// IsBlocked invokes `isBlocked` method on native Policy contract.
|
||||||
|
//
|
||||||
|
// Deprecated: please use policy subpackage.
|
||||||
func (c *Client) IsBlocked(hash util.Uint160) (bool, error) {
|
func (c *Client) IsBlocked(hash util.Uint160) (bool, error) {
|
||||||
policyHash, err := c.GetNativeContractHash(nativenames.Policy)
|
policyHash, err := c.GetNativeContractHash(nativenames.Policy)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
|
219
pkg/rpcclient/policy/policy.go
Normal file
219
pkg/rpcclient/policy/policy.go
Normal file
|
@ -0,0 +1,219 @@
|
||||||
|
/*
|
||||||
|
Package policy allows to work with the native PolicyContract contract via RPC.
|
||||||
|
|
||||||
|
Safe methods are encapsulated into ContractReader structure while Contract provides
|
||||||
|
various methods to perform PolicyContract state-changing calls.
|
||||||
|
*/
|
||||||
|
package policy
|
||||||
|
|
||||||
|
import (
|
||||||
|
"github.com/nspcc-dev/neo-go/pkg/core/native/nativenames"
|
||||||
|
"github.com/nspcc-dev/neo-go/pkg/core/state"
|
||||||
|
"github.com/nspcc-dev/neo-go/pkg/core/transaction"
|
||||||
|
"github.com/nspcc-dev/neo-go/pkg/neorpc/result"
|
||||||
|
"github.com/nspcc-dev/neo-go/pkg/rpcclient/unwrap"
|
||||||
|
"github.com/nspcc-dev/neo-go/pkg/smartcontract"
|
||||||
|
"github.com/nspcc-dev/neo-go/pkg/util"
|
||||||
|
)
|
||||||
|
|
||||||
|
// Invoker is used by ContractReader to call various methods.
|
||||||
|
type Invoker interface {
|
||||||
|
Call(contract util.Uint160, operation string, params ...interface{}) (*result.Invoke, error)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Actor is used by Contract to create and send transactions.
|
||||||
|
type Actor interface {
|
||||||
|
Invoker
|
||||||
|
|
||||||
|
MakeCall(contract util.Uint160, method string, params ...interface{}) (*transaction.Transaction, error)
|
||||||
|
MakeRun(script []byte) (*transaction.Transaction, error)
|
||||||
|
MakeUnsignedCall(contract util.Uint160, method string, attrs []transaction.Attribute, params ...interface{}) (*transaction.Transaction, error)
|
||||||
|
MakeUnsignedRun(script []byte, attrs []transaction.Attribute) (*transaction.Transaction, error)
|
||||||
|
SendCall(contract util.Uint160, method string, params ...interface{}) (util.Uint256, uint32, error)
|
||||||
|
SendRun(script []byte) (util.Uint256, uint32, error)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Hash stores the hash of the native PolicyContract contract.
|
||||||
|
var Hash = state.CreateNativeContractHash(nativenames.Policy)
|
||||||
|
|
||||||
|
const (
|
||||||
|
execFeeSetter = "setExecFeeFactor"
|
||||||
|
feePerByteSetter = "setFeePerByte"
|
||||||
|
storagePriceSetter = "setStoragePrice"
|
||||||
|
)
|
||||||
|
|
||||||
|
// ContractReader provides an interface to call read-only PolicyContract
|
||||||
|
// contract's methods.
|
||||||
|
type ContractReader struct {
|
||||||
|
invoker Invoker
|
||||||
|
}
|
||||||
|
|
||||||
|
// Contract represents a PolicyContract contract client that can be used to
|
||||||
|
// invoke all of its methods.
|
||||||
|
type Contract struct {
|
||||||
|
ContractReader
|
||||||
|
|
||||||
|
actor Actor
|
||||||
|
}
|
||||||
|
|
||||||
|
// NewReader creates an instance of ContractReader that can be used to read
|
||||||
|
// data from the contract.
|
||||||
|
func NewReader(invoker Invoker) *ContractReader {
|
||||||
|
return &ContractReader{invoker}
|
||||||
|
}
|
||||||
|
|
||||||
|
// New creates an instance of Contract to perform actions using
|
||||||
|
// the given Actor. Notice that PolicyContract's state can be changed
|
||||||
|
// only by the network's committee, so the Actor provided must be a committee
|
||||||
|
// actor for all methods to work properly.
|
||||||
|
func New(actor Actor) *Contract {
|
||||||
|
return &Contract{*NewReader(actor), actor}
|
||||||
|
}
|
||||||
|
|
||||||
|
// GetExecFeeFactor returns current execution fee factor used by the network.
|
||||||
|
// This setting affects all executions of all transactions.
|
||||||
|
func (c *ContractReader) GetExecFeeFactor() (int64, error) {
|
||||||
|
return unwrap.Int64(c.invoker.Call(Hash, "getExecFeeFactor"))
|
||||||
|
}
|
||||||
|
|
||||||
|
// GetFeePerByte returns current minimal per-byte network fee value which
|
||||||
|
// affects all transactions on the network.
|
||||||
|
func (c *ContractReader) GetFeePerByte() (int64, error) {
|
||||||
|
return unwrap.Int64(c.invoker.Call(Hash, "getFeePerByte"))
|
||||||
|
}
|
||||||
|
|
||||||
|
// GetStoragePrice returns current per-byte storage price. Any contract saving
|
||||||
|
// data to the storage pays for it according to this value.
|
||||||
|
func (c *ContractReader) GetStoragePrice() (int64, error) {
|
||||||
|
return unwrap.Int64(c.invoker.Call(Hash, "getStoragePrice"))
|
||||||
|
}
|
||||||
|
|
||||||
|
// IsBlocked checks if the given account is blocked in the PolicyContract.
|
||||||
|
func (c *ContractReader) IsBlocked(account util.Uint160) (bool, error) {
|
||||||
|
return unwrap.Bool(c.invoker.Call(Hash, "isBlocked", account))
|
||||||
|
}
|
||||||
|
|
||||||
|
// SetExecFeeFactor creates and sends a transaction that sets the new
|
||||||
|
// execution fee factor for the network to use. The action is successful when
|
||||||
|
// transaction ends in HALT state. The returned values are transaction hash, its
|
||||||
|
// ValidUntilBlock value and an error if any.
|
||||||
|
func (c *Contract) SetExecFeeFactor(value int64) (util.Uint256, uint32, error) {
|
||||||
|
return c.actor.SendCall(Hash, execFeeSetter, value)
|
||||||
|
}
|
||||||
|
|
||||||
|
// SetExecFeeFactorTransaction creates a transaction that sets the new execution
|
||||||
|
// fee factor. This transaction is signed, but not sent to the network,
|
||||||
|
// instead it's returned to the caller.
|
||||||
|
func (c *Contract) SetExecFeeFactorTransaction(value int64) (*transaction.Transaction, error) {
|
||||||
|
return c.actor.MakeCall(Hash, execFeeSetter, value)
|
||||||
|
}
|
||||||
|
|
||||||
|
// SetExecFeeFactorUnsigned creates a transaction that sets the new execution
|
||||||
|
// fee factor. This transaction is not signed and just returned to the caller.
|
||||||
|
func (c *Contract) SetExecFeeFactorUnsigned(value int64) (*transaction.Transaction, error) {
|
||||||
|
return c.actor.MakeUnsignedCall(Hash, execFeeSetter, nil, value)
|
||||||
|
}
|
||||||
|
|
||||||
|
// SetFeePerByte creates and sends a transaction that sets the new minimal
|
||||||
|
// per-byte network fee value. The action is successful when transaction ends in
|
||||||
|
// HALT state. The returned values are transaction hash, its ValidUntilBlock
|
||||||
|
// value and an error if any.
|
||||||
|
func (c *Contract) SetFeePerByte(value int64) (util.Uint256, uint32, error) {
|
||||||
|
return c.actor.SendCall(Hash, feePerByteSetter, value)
|
||||||
|
}
|
||||||
|
|
||||||
|
// SetFeePerByteTransaction creates a transaction that sets the new minimal
|
||||||
|
// per-byte network fee value. This transaction is signed, but not sent to the
|
||||||
|
// network, instead it's returned to the caller.
|
||||||
|
func (c *Contract) SetFeePerByteTransaction(value int64) (*transaction.Transaction, error) {
|
||||||
|
return c.actor.MakeCall(Hash, feePerByteSetter, value)
|
||||||
|
}
|
||||||
|
|
||||||
|
// SetFeePerByteUnsigned creates a transaction that sets the new minimal per-byte
|
||||||
|
// network fee value. This transaction is not signed and just returned to the
|
||||||
|
// caller.
|
||||||
|
func (c *Contract) SetFeePerByteUnsigned(value int64) (*transaction.Transaction, error) {
|
||||||
|
return c.actor.MakeUnsignedCall(Hash, feePerByteSetter, nil, value)
|
||||||
|
}
|
||||||
|
|
||||||
|
// SetStoragePrice creates and sends a transaction that sets the storage price
|
||||||
|
// for contracts. The action is successful when transaction ends in HALT
|
||||||
|
// state. The returned values are transaction hash, its ValidUntilBlock value
|
||||||
|
// and an error if any.
|
||||||
|
func (c *Contract) SetStoragePrice(value int64) (util.Uint256, uint32, error) {
|
||||||
|
return c.actor.SendCall(Hash, storagePriceSetter, value)
|
||||||
|
}
|
||||||
|
|
||||||
|
// SetStoragePriceTransaction creates a transaction that sets the storage price
|
||||||
|
// for contracts. This transaction is signed, but not sent to the network,
|
||||||
|
// instead it's returned to the caller.
|
||||||
|
func (c *Contract) SetStoragePriceTransaction(value int64) (*transaction.Transaction, error) {
|
||||||
|
return c.actor.MakeCall(Hash, storagePriceSetter, value)
|
||||||
|
}
|
||||||
|
|
||||||
|
// SetStoragePriceUnsigned creates a transaction that sets the storage price
|
||||||
|
// for contracts. This transaction is not signed and just returned to the
|
||||||
|
// caller.
|
||||||
|
func (c *Contract) SetStoragePriceUnsigned(value int64) (*transaction.Transaction, error) {
|
||||||
|
return c.actor.MakeUnsignedCall(Hash, storagePriceSetter, nil, value)
|
||||||
|
}
|
||||||
|
|
||||||
|
// BlockAccount creates and sends a transaction that blocks an account on the
|
||||||
|
// network (via `blockAccount` method), it fails (with FAULT state) if it's not
|
||||||
|
// successful. The returned values are transaction hash, its
|
||||||
|
// ValidUntilBlock value and an error if any.
|
||||||
|
func (c *Contract) BlockAccount(account util.Uint160) (util.Uint256, uint32, error) {
|
||||||
|
return c.actor.SendRun(blockScript(account))
|
||||||
|
}
|
||||||
|
|
||||||
|
// BlockAccountTransaction creates a transaction that blocks an account on the
|
||||||
|
// network and checks for the result of the appropriate call, failing the
|
||||||
|
// transaction if it's not true. This transaction is signed, but not sent to the
|
||||||
|
// network, instead it's returned to the caller.
|
||||||
|
func (c *Contract) BlockAccountTransaction(account util.Uint160) (*transaction.Transaction, error) {
|
||||||
|
return c.actor.MakeRun(blockScript(account))
|
||||||
|
}
|
||||||
|
|
||||||
|
// BlockAccountUnsigned creates a transaction that blocks an account on the
|
||||||
|
// network and checks for the result of the appropriate call, failing the
|
||||||
|
// transaction if it's not true. This transaction is not signed and just returned
|
||||||
|
// to the caller.
|
||||||
|
func (c *Contract) BlockAccountUnsigned(account util.Uint160) (*transaction.Transaction, error) {
|
||||||
|
return c.actor.MakeUnsignedRun(blockScript(account), nil)
|
||||||
|
}
|
||||||
|
|
||||||
|
func blockScript(account util.Uint160) []byte {
|
||||||
|
// We know parameters exactly (unlike with nep17.Transfer), so this can't fail.
|
||||||
|
script, _ := smartcontract.CreateCallWithAssertScript(Hash, "blockAccount", account)
|
||||||
|
return script
|
||||||
|
}
|
||||||
|
|
||||||
|
// UnblockAccount creates and sends a transaction that removes previously blocked
|
||||||
|
// account from the stop list. It uses `unblockAccount` method and checks for the
|
||||||
|
// result returned, failing the transaction if it's not true. The returned values
|
||||||
|
// are transaction hash, its ValidUntilBlock value and an error if any.
|
||||||
|
func (c *Contract) UnblockAccount(account util.Uint160) (util.Uint256, uint32, error) {
|
||||||
|
return c.actor.SendRun(unblockScript(account))
|
||||||
|
}
|
||||||
|
|
||||||
|
// UnblockAccountTransaction creates a transaction that unblocks previously
|
||||||
|
// blocked account via `unblockAccount` method and checks for the result returned,
|
||||||
|
// failing the transaction if it's not true. This transaction is signed, but not
|
||||||
|
// sent to the network, instead it's returned to the caller.
|
||||||
|
func (c *Contract) UnblockAccountTransaction(account util.Uint160) (*transaction.Transaction, error) {
|
||||||
|
return c.actor.MakeRun(unblockScript(account))
|
||||||
|
}
|
||||||
|
|
||||||
|
// UnblockAccountUnsigned creates a transaction that unblocks the given account
|
||||||
|
// if it was blocked previously. It uses `unblockAccount` method and checks for
|
||||||
|
// its return value, failing the transaction if it's not true. This transaction
|
||||||
|
// is not signed and just returned to the caller.
|
||||||
|
func (c *Contract) UnblockAccountUnsigned(account util.Uint160) (*transaction.Transaction, error) {
|
||||||
|
return c.actor.MakeUnsignedRun(unblockScript(account), nil)
|
||||||
|
}
|
||||||
|
|
||||||
|
func unblockScript(account util.Uint160) []byte {
|
||||||
|
// We know parameters exactly (unlike with nep17.Transfer), so this can't fail.
|
||||||
|
script, _ := smartcontract.CreateCallWithAssertScript(Hash, "unblockAccount", account)
|
||||||
|
return script
|
||||||
|
}
|
182
pkg/rpcclient/policy/policy_test.go
Normal file
182
pkg/rpcclient/policy/policy_test.go
Normal file
|
@ -0,0 +1,182 @@
|
||||||
|
package policy
|
||||||
|
|
||||||
|
import (
|
||||||
|
"errors"
|
||||||
|
"testing"
|
||||||
|
|
||||||
|
"github.com/nspcc-dev/neo-go/pkg/core/transaction"
|
||||||
|
"github.com/nspcc-dev/neo-go/pkg/neorpc/result"
|
||||||
|
"github.com/nspcc-dev/neo-go/pkg/util"
|
||||||
|
"github.com/nspcc-dev/neo-go/pkg/vm/stackitem"
|
||||||
|
"github.com/stretchr/testify/require"
|
||||||
|
)
|
||||||
|
|
||||||
|
type testAct struct {
|
||||||
|
err error
|
||||||
|
res *result.Invoke
|
||||||
|
tx *transaction.Transaction
|
||||||
|
txh util.Uint256
|
||||||
|
vub uint32
|
||||||
|
}
|
||||||
|
|
||||||
|
func (t *testAct) Call(contract util.Uint160, operation string, params ...interface{}) (*result.Invoke, error) {
|
||||||
|
return t.res, t.err
|
||||||
|
}
|
||||||
|
func (t *testAct) MakeCall(contract util.Uint160, method string, params ...interface{}) (*transaction.Transaction, error) {
|
||||||
|
return t.tx, t.err
|
||||||
|
}
|
||||||
|
func (t *testAct) MakeUnsignedCall(contract util.Uint160, method string, attrs []transaction.Attribute, params ...interface{}) (*transaction.Transaction, error) {
|
||||||
|
return t.tx, t.err
|
||||||
|
}
|
||||||
|
func (t *testAct) SendCall(contract util.Uint160, method string, params ...interface{}) (util.Uint256, uint32, error) {
|
||||||
|
return t.txh, t.vub, t.err
|
||||||
|
}
|
||||||
|
func (t *testAct) MakeRun(script []byte) (*transaction.Transaction, error) {
|
||||||
|
return t.tx, t.err
|
||||||
|
}
|
||||||
|
func (t *testAct) MakeUnsignedRun(script []byte, attrs []transaction.Attribute) (*transaction.Transaction, error) {
|
||||||
|
return t.tx, t.err
|
||||||
|
}
|
||||||
|
func (t *testAct) SendRun(script []byte) (util.Uint256, uint32, error) {
|
||||||
|
return t.txh, t.vub, t.err
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestReader(t *testing.T) {
|
||||||
|
ta := new(testAct)
|
||||||
|
pc := NewReader(ta)
|
||||||
|
|
||||||
|
meth := []func() (int64, error){
|
||||||
|
pc.GetExecFeeFactor,
|
||||||
|
pc.GetFeePerByte,
|
||||||
|
pc.GetStoragePrice,
|
||||||
|
}
|
||||||
|
|
||||||
|
ta.err = errors.New("")
|
||||||
|
for _, m := range meth {
|
||||||
|
_, err := m()
|
||||||
|
require.Error(t, err)
|
||||||
|
}
|
||||||
|
_, err := pc.IsBlocked(util.Uint160{1, 2, 3})
|
||||||
|
require.Error(t, err)
|
||||||
|
|
||||||
|
ta.err = nil
|
||||||
|
ta.res = &result.Invoke{
|
||||||
|
State: "HALT",
|
||||||
|
Stack: []stackitem.Item{
|
||||||
|
stackitem.Make(42),
|
||||||
|
},
|
||||||
|
}
|
||||||
|
for _, m := range meth {
|
||||||
|
val, err := m()
|
||||||
|
require.NoError(t, err)
|
||||||
|
require.Equal(t, int64(42), val)
|
||||||
|
}
|
||||||
|
ta.res = &result.Invoke{
|
||||||
|
State: "HALT",
|
||||||
|
Stack: []stackitem.Item{
|
||||||
|
stackitem.Make(true),
|
||||||
|
},
|
||||||
|
}
|
||||||
|
val, err := pc.IsBlocked(util.Uint160{1, 2, 3})
|
||||||
|
require.NoError(t, err)
|
||||||
|
require.True(t, val)
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestIntSetters(t *testing.T) {
|
||||||
|
ta := new(testAct)
|
||||||
|
pc := New(ta)
|
||||||
|
|
||||||
|
meth := []func(int64) (util.Uint256, uint32, error){
|
||||||
|
pc.SetExecFeeFactor,
|
||||||
|
pc.SetFeePerByte,
|
||||||
|
pc.SetStoragePrice,
|
||||||
|
}
|
||||||
|
|
||||||
|
ta.err = errors.New("")
|
||||||
|
for _, m := range meth {
|
||||||
|
_, _, err := m(42)
|
||||||
|
require.Error(t, err)
|
||||||
|
}
|
||||||
|
|
||||||
|
ta.err = nil
|
||||||
|
ta.txh = util.Uint256{1, 2, 3}
|
||||||
|
ta.vub = 42
|
||||||
|
for _, m := range meth {
|
||||||
|
h, vub, err := m(100)
|
||||||
|
require.NoError(t, err)
|
||||||
|
require.Equal(t, ta.txh, h)
|
||||||
|
require.Equal(t, ta.vub, vub)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestUint160Setters(t *testing.T) {
|
||||||
|
ta := new(testAct)
|
||||||
|
pc := New(ta)
|
||||||
|
|
||||||
|
meth := []func(util.Uint160) (util.Uint256, uint32, error){
|
||||||
|
pc.BlockAccount,
|
||||||
|
pc.UnblockAccount,
|
||||||
|
}
|
||||||
|
|
||||||
|
ta.err = errors.New("")
|
||||||
|
for _, m := range meth {
|
||||||
|
_, _, err := m(util.Uint160{})
|
||||||
|
require.Error(t, err)
|
||||||
|
}
|
||||||
|
|
||||||
|
ta.err = nil
|
||||||
|
ta.txh = util.Uint256{1, 2, 3}
|
||||||
|
ta.vub = 42
|
||||||
|
for _, m := range meth {
|
||||||
|
h, vub, err := m(util.Uint160{})
|
||||||
|
require.NoError(t, err)
|
||||||
|
require.Equal(t, ta.txh, h)
|
||||||
|
require.Equal(t, ta.vub, vub)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestIntTransactions(t *testing.T) {
|
||||||
|
ta := new(testAct)
|
||||||
|
pc := New(ta)
|
||||||
|
|
||||||
|
for _, fun := range []func(int64) (*transaction.Transaction, error){
|
||||||
|
pc.SetExecFeeFactorTransaction,
|
||||||
|
pc.SetExecFeeFactorUnsigned,
|
||||||
|
pc.SetFeePerByteTransaction,
|
||||||
|
pc.SetFeePerByteUnsigned,
|
||||||
|
pc.SetStoragePriceTransaction,
|
||||||
|
pc.SetStoragePriceUnsigned,
|
||||||
|
} {
|
||||||
|
ta.err = errors.New("")
|
||||||
|
_, err := fun(1)
|
||||||
|
require.Error(t, err)
|
||||||
|
|
||||||
|
ta.err = nil
|
||||||
|
ta.tx = &transaction.Transaction{Nonce: 100500, ValidUntilBlock: 42}
|
||||||
|
tx, err := fun(1)
|
||||||
|
require.NoError(t, err)
|
||||||
|
require.Equal(t, ta.tx, tx)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestUint160Transactions(t *testing.T) {
|
||||||
|
ta := new(testAct)
|
||||||
|
pc := New(ta)
|
||||||
|
|
||||||
|
for _, fun := range []func(util.Uint160) (*transaction.Transaction, error){
|
||||||
|
pc.BlockAccountTransaction,
|
||||||
|
pc.BlockAccountUnsigned,
|
||||||
|
pc.UnblockAccountTransaction,
|
||||||
|
pc.UnblockAccountUnsigned,
|
||||||
|
} {
|
||||||
|
ta.err = errors.New("")
|
||||||
|
_, err := fun(util.Uint160{1})
|
||||||
|
require.Error(t, err)
|
||||||
|
|
||||||
|
ta.err = nil
|
||||||
|
ta.tx = &transaction.Transaction{Nonce: 100500, ValidUntilBlock: 42}
|
||||||
|
tx, err := fun(util.Uint160{1})
|
||||||
|
require.NoError(t, err)
|
||||||
|
require.Equal(t, ta.tx, tx)
|
||||||
|
}
|
||||||
|
}
|
|
@ -34,6 +34,7 @@ import (
|
||||||
"github.com/nspcc-dev/neo-go/pkg/rpcclient/invoker"
|
"github.com/nspcc-dev/neo-go/pkg/rpcclient/invoker"
|
||||||
"github.com/nspcc-dev/neo-go/pkg/rpcclient/nep17"
|
"github.com/nspcc-dev/neo-go/pkg/rpcclient/nep17"
|
||||||
"github.com/nspcc-dev/neo-go/pkg/rpcclient/nns"
|
"github.com/nspcc-dev/neo-go/pkg/rpcclient/nns"
|
||||||
|
"github.com/nspcc-dev/neo-go/pkg/rpcclient/policy"
|
||||||
"github.com/nspcc-dev/neo-go/pkg/rpcclient/rolemgmt"
|
"github.com/nspcc-dev/neo-go/pkg/rpcclient/rolemgmt"
|
||||||
"github.com/nspcc-dev/neo-go/pkg/smartcontract"
|
"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/callflag"
|
||||||
|
@ -144,6 +145,86 @@ func TestClientRoleManagement(t *testing.T) {
|
||||||
require.Equal(t, testKeys, ks)
|
require.Equal(t, testKeys, ks)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestClientPolicyContract(t *testing.T) {
|
||||||
|
chain, rpcSrv, httpSrv := initServerWithInMemoryChain(t)
|
||||||
|
defer chain.Close()
|
||||||
|
defer rpcSrv.Shutdown()
|
||||||
|
|
||||||
|
c, err := rpcclient.New(context.Background(), httpSrv.URL, rpcclient.Options{})
|
||||||
|
require.NoError(t, err)
|
||||||
|
require.NoError(t, c.Init())
|
||||||
|
|
||||||
|
polizei := policy.NewReader(invoker.New(c, nil))
|
||||||
|
|
||||||
|
val, err := polizei.GetExecFeeFactor()
|
||||||
|
require.NoError(t, err)
|
||||||
|
require.Equal(t, int64(30), val)
|
||||||
|
|
||||||
|
val, err = polizei.GetFeePerByte()
|
||||||
|
require.NoError(t, err)
|
||||||
|
require.Equal(t, int64(1000), val)
|
||||||
|
|
||||||
|
val, err = polizei.GetStoragePrice()
|
||||||
|
require.NoError(t, err)
|
||||||
|
require.Equal(t, int64(100000), val)
|
||||||
|
|
||||||
|
ret, err := polizei.IsBlocked(util.Uint160{})
|
||||||
|
require.NoError(t, err)
|
||||||
|
require.False(t, ret)
|
||||||
|
|
||||||
|
act, err := actor.New(c, []actor.SignerAccount{{
|
||||||
|
Signer: transaction.Signer{
|
||||||
|
Account: testchain.CommitteeScriptHash(),
|
||||||
|
Scopes: transaction.CalledByEntry,
|
||||||
|
},
|
||||||
|
Account: &wallet.Account{
|
||||||
|
Address: testchain.CommitteeAddress(),
|
||||||
|
Contract: &wallet.Contract{
|
||||||
|
Script: testchain.CommitteeVerificationScript(),
|
||||||
|
},
|
||||||
|
},
|
||||||
|
}})
|
||||||
|
require.NoError(t, err)
|
||||||
|
|
||||||
|
polis := policy.New(act)
|
||||||
|
|
||||||
|
txexec, err := polis.SetExecFeeFactorUnsigned(100)
|
||||||
|
require.NoError(t, err)
|
||||||
|
|
||||||
|
txnetfee, err := polis.SetFeePerByteUnsigned(500)
|
||||||
|
require.NoError(t, err)
|
||||||
|
|
||||||
|
txstorage, err := polis.SetStoragePriceUnsigned(100500)
|
||||||
|
require.NoError(t, err)
|
||||||
|
|
||||||
|
txblock, err := polis.BlockAccountUnsigned(util.Uint160{1, 2, 3})
|
||||||
|
require.NoError(t, err)
|
||||||
|
|
||||||
|
for _, tx := range []*transaction.Transaction{txblock, txstorage, txnetfee, txexec} {
|
||||||
|
tx.Scripts[0].InvocationScript = testchain.SignCommittee(tx)
|
||||||
|
}
|
||||||
|
|
||||||
|
bl := testchain.NewBlock(t, chain, 1, 0, txblock, txstorage, txnetfee, txexec)
|
||||||
|
_, err = c.SubmitBlock(*bl)
|
||||||
|
require.NoError(t, err)
|
||||||
|
|
||||||
|
val, err = polizei.GetExecFeeFactor()
|
||||||
|
require.NoError(t, err)
|
||||||
|
require.Equal(t, int64(100), val)
|
||||||
|
|
||||||
|
val, err = polizei.GetFeePerByte()
|
||||||
|
require.NoError(t, err)
|
||||||
|
require.Equal(t, int64(500), val)
|
||||||
|
|
||||||
|
val, err = polizei.GetStoragePrice()
|
||||||
|
require.NoError(t, err)
|
||||||
|
require.Equal(t, int64(100500), val)
|
||||||
|
|
||||||
|
ret, err = polizei.IsBlocked(util.Uint160{1, 2, 3})
|
||||||
|
require.NoError(t, err)
|
||||||
|
require.True(t, ret)
|
||||||
|
}
|
||||||
|
|
||||||
func TestAddNetworkFeeCalculateNetworkFee(t *testing.T) {
|
func TestAddNetworkFeeCalculateNetworkFee(t *testing.T) {
|
||||||
chain, rpcSrv, httpSrv := initServerWithInMemoryChain(t)
|
chain, rpcSrv, httpSrv := initServerWithInMemoryChain(t)
|
||||||
defer chain.Close()
|
defer chain.Close()
|
||||||
|
|
Loading…
Reference in a new issue