core, rpcsrv: apply generic attributes fee logic to NotaryServiceFeePerKey

Remove related methods from native Notary and add relevant code to native
Policy.

Signed-off-by: Anna Shaleva <shaleva.ann@nspcc.ru>
This commit is contained in:
Anna Shaleva 2023-09-21 18:22:32 +03:00
parent 82cb2e718d
commit 474225d425
15 changed files with 55 additions and 188 deletions

View file

@ -207,8 +207,6 @@ func TestNativeHelpersCompile(t *testing.T) {
{"expirationOf", []string{u160}}, {"expirationOf", []string{u160}},
{"getMaxNotValidBeforeDelta", nil}, {"getMaxNotValidBeforeDelta", nil},
{"setMaxNotValidBeforeDelta", []string{"42"}}, {"setMaxNotValidBeforeDelta", []string{"42"}},
{"getNotaryServiceFeePerKey", nil},
{"setNotaryServiceFeePerKey", []string{"42"}},
}) })
runNativeTestCases(t, cs.Management.ContractMD, "management", []nativeTestCase{ runNativeTestCases(t, cs.Management.ContractMD, "management", []nativeTestCase{
{"deploy", []string{"nil", "nil"}}, {"deploy", []string{"nil", "nil"}},

View file

@ -2054,10 +2054,10 @@ func (bc *Blockchain) GetNotaryBalance(acc util.Uint160) *big.Int {
return bc.contracts.Notary.BalanceOf(bc.dao, acc) return bc.contracts.Notary.BalanceOf(bc.dao, acc)
} }
// GetNotaryServiceFeePerKey returns NotaryServiceFeePerKey which is a reward per // GetNotaryServiceFeePerKey returns a NotaryAssisted transaction attribute fee
// notary request key for designated notary nodes. // per key which is a reward per notary request key for designated notary nodes.
func (bc *Blockchain) GetNotaryServiceFeePerKey() int64 { func (bc *Blockchain) GetNotaryServiceFeePerKey() int64 {
return bc.contracts.Notary.GetNotaryServiceFeePerKey(bc.dao) return bc.contracts.Policy.GetAttributeFeeInternal(bc.dao, transaction.NotaryAssistedT)
} }
// GetNotaryContractScriptHash returns Notary native contract hash. // GetNotaryContractScriptHash returns Notary native contract hash.
@ -2480,13 +2480,6 @@ func (bc *Blockchain) verifyAndPoolTx(t *transaction.Transaction, pool *mempool.
return fmt.Errorf("%w: (%d > MaxTransactionSize %d)", ErrTxTooBig, size, transaction.MaxTransactionSize) return fmt.Errorf("%w: (%d > MaxTransactionSize %d)", ErrTxTooBig, size, transaction.MaxTransactionSize)
} }
needNetworkFee := int64(size)*bc.FeePerByte() + bc.CalculateAttributesFee(t) needNetworkFee := int64(size)*bc.FeePerByte() + bc.CalculateAttributesFee(t)
if bc.P2PSigExtensionsEnabled() {
attrs := t.GetAttributes(transaction.NotaryAssistedT)
if len(attrs) != 0 {
na := attrs[0].Value.(*transaction.NotaryAssisted)
needNetworkFee += (int64(na.NKeys) + 1) * bc.contracts.Notary.GetNotaryServiceFeePerKey(bc.dao)
}
}
netFee := t.NetworkFee - needNetworkFee netFee := t.NetworkFee - needNetworkFee
if netFee < 0 { if netFee < 0 {
return fmt.Errorf("%w: net fee is %v, need %v", ErrTxSmallNetworkFee, t.NetworkFee, needNetworkFee) return fmt.Errorf("%w: net fee is %v, need %v", ErrTxSmallNetworkFee, t.NetworkFee, needNetworkFee)
@ -2539,6 +2532,11 @@ func (bc *Blockchain) CalculateAttributesFee(tx *transaction.Transaction) int64
switch attr.Type { switch attr.Type {
case transaction.ConflictsT: case transaction.ConflictsT:
feeSum += base * int64(len(tx.Signers)) feeSum += base * int64(len(tx.Signers))
case transaction.NotaryAssistedT:
if bc.P2PSigExtensionsEnabled() {
na := attr.Value.(*transaction.NotaryAssisted)
feeSum += base * (int64(na.NKeys) + 1)
}
default: default:
feeSum += base feeSum += base
} }
@ -2914,13 +2912,6 @@ func (bc *Blockchain) verifyTxWitnesses(t *transaction.Transaction, block *block
var gasLimit int64 var gasLimit int64
if len(verificationFee) == 0 { if len(verificationFee) == 0 {
gasLimit = t.NetworkFee - int64(t.Size())*bc.FeePerByte() - bc.CalculateAttributesFee(t) gasLimit = t.NetworkFee - int64(t.Size())*bc.FeePerByte() - bc.CalculateAttributesFee(t)
if bc.P2PSigExtensionsEnabled() {
attrs := t.GetAttributes(transaction.NotaryAssistedT)
if len(attrs) != 0 {
na := attrs[0].Value.(*transaction.NotaryAssisted)
gasLimit -= (int64(na.NKeys) + 1) * bc.contracts.Notary.GetNotaryServiceFeePerKey(bc.dao)
}
}
} else { } else {
gasLimit = verificationFee[0] gasLimit = verificationFee[0]
} }

View file

@ -74,10 +74,11 @@ func NewContracts(cfg config.ProtocolConfiguration) *Contracts {
gas := newGAS(int64(cfg.InitialGASSupply), cfg.P2PSigExtensions) gas := newGAS(int64(cfg.InitialGASSupply), cfg.P2PSigExtensions)
neo := newNEO(cfg) neo := newNEO(cfg)
policy := newPolicy() policy := newPolicy(cfg.P2PSigExtensions)
neo.GAS = gas neo.GAS = gas
neo.Policy = policy neo.Policy = policy
gas.NEO = neo gas.NEO = neo
gas.Policy = policy
mgmt.NEO = neo mgmt.NEO = neo
mgmt.Policy = policy mgmt.Policy = policy
policy.NEO = neo policy.NEO = neo
@ -104,8 +105,8 @@ func NewContracts(cfg config.ProtocolConfiguration) *Contracts {
notary.GAS = gas notary.GAS = gas
notary.NEO = neo notary.NEO = neo
notary.Desig = desig notary.Desig = desig
notary.Policy = policy
cs.Notary = notary cs.Notary = notary
gas.Notary = notary
cs.Contracts = append(cs.Contracts, notary) cs.Contracts = append(cs.Contracts, notary)
} }

View file

@ -17,7 +17,7 @@ import (
func TestDeployGetUpdateDestroyContract(t *testing.T) { func TestDeployGetUpdateDestroyContract(t *testing.T) {
mgmt := newManagement() mgmt := newManagement()
mgmt.Policy = newPolicy() mgmt.Policy = newPolicy(false)
d := dao.NewSimple(storage.NewMemoryStore(), false) d := dao.NewSimple(storage.NewMemoryStore(), false)
ic := &interop.Context{DAO: d} ic := &interop.Context{DAO: d}
err := mgmt.Initialize(ic) err := mgmt.Initialize(ic)
@ -97,7 +97,7 @@ func TestManagement_Initialize(t *testing.T) {
func TestManagement_GetNEP17Contracts(t *testing.T) { func TestManagement_GetNEP17Contracts(t *testing.T) {
mgmt := newManagement() mgmt := newManagement()
mgmt.Policy = newPolicy() mgmt.Policy = newPolicy(false)
d := dao.NewSimple(storage.NewMemoryStore(), false) d := dao.NewSimple(storage.NewMemoryStore(), false)
err := mgmt.Initialize(&interop.Context{DAO: d}) err := mgmt.Initialize(&interop.Context{DAO: d})
require.NoError(t, err) require.NoError(t, err)

View file

@ -19,8 +19,7 @@ import (
type GAS struct { type GAS struct {
nep17TokenNative nep17TokenNative
NEO *NEO NEO *NEO
// Notary is a native Notary contract. It is set only when P2PSigExtensions are on. Policy *Policy
Notary *Notary
initialSupply int64 initialSupply int64
p2pSigExtensionsEnabled bool p2pSigExtensionsEnabled bool
@ -124,7 +123,7 @@ func (g *GAS) OnPersist(ic *interop.Context) error {
attrs := tx.GetAttributes(transaction.NotaryAssistedT) attrs := tx.GetAttributes(transaction.NotaryAssistedT)
if len(attrs) != 0 { if len(attrs) != 0 {
na := attrs[0].Value.(*transaction.NotaryAssisted) na := attrs[0].Value.(*transaction.NotaryAssisted)
netFee -= (int64(na.NKeys) + 1) * g.Notary.GetNotaryServiceFeePerKey(ic.DAO) netFee -= (int64(na.NKeys) + 1) * g.Policy.GetAttributeFeeInternal(ic.DAO, transaction.NotaryAssistedT)
} }
} }
} }

View file

@ -38,16 +38,6 @@ func TestNotary_MaxNotValidBeforeDeltaCache(t *testing.T) {
testGetSetCache(t, c, "MaxNotValidBeforeDelta", 140) testGetSetCache(t, c, "MaxNotValidBeforeDelta", 140)
} }
func TestNotary_NotaryServiceFeePerKey(t *testing.T) {
c := newNotaryClient(t)
testGetSet(t, c, "NotaryServiceFeePerKey", 1000_0000, 0, 0)
}
func TestNotary_NotaryServiceFeePerKeyCache(t *testing.T) {
c := newNotaryClient(t)
testGetSetCache(t, c, "NotaryServiceFeePerKey", 1000_0000)
}
func TestNotary_Pipeline(t *testing.T) { func TestNotary_Pipeline(t *testing.T) {
notaryCommitteeInvoker := newNotaryClient(t) notaryCommitteeInvoker := newNotaryClient(t)
e := notaryCommitteeInvoker.Executor e := notaryCommitteeInvoker.Executor

View file

@ -31,11 +31,11 @@ type Notary struct {
GAS *GAS GAS *GAS
NEO *NEO NEO *NEO
Desig *Designate Desig *Designate
Policy *Policy
} }
type NotaryCache struct { type NotaryCache struct {
maxNotValidBeforeDelta uint32 maxNotValidBeforeDelta uint32
notaryServiceFeePerKey int64
} }
// NotaryService is a Notary module interface. // NotaryService is a Notary module interface.
@ -49,14 +49,9 @@ const (
prefixDeposit = 1 prefixDeposit = 1
defaultDepositDeltaTill = 5760 defaultDepositDeltaTill = 5760
defaultMaxNotValidBeforeDelta = 140 // 20 rounds for 7 validators, a little more than half an hour defaultMaxNotValidBeforeDelta = 140 // 20 rounds for 7 validators, a little more than half an hour
defaultNotaryServiceFeePerKey = 1000_0000 // 0.1 GAS
maxNotaryServiceFeePerKey = 1_0000_0000 // 1 GAS
) )
var ( var maxNotValidBeforeDeltaKey = []byte{10}
maxNotValidBeforeDeltaKey = []byte{10}
notaryServiceFeeKey = []byte{5}
)
var ( var (
_ interop.Contract = (*Notary)(nil) _ interop.Contract = (*Notary)(nil)
@ -122,15 +117,6 @@ func newNotary() *Notary {
md = newMethodAndPrice(n.setMaxNotValidBeforeDelta, 1<<15, callflag.States) md = newMethodAndPrice(n.setMaxNotValidBeforeDelta, 1<<15, callflag.States)
n.AddMethod(md, desc) n.AddMethod(md, desc)
desc = newDescriptor("getNotaryServiceFeePerKey", smartcontract.IntegerType)
md = newMethodAndPrice(n.getNotaryServiceFeePerKey, 1<<15, callflag.ReadStates)
n.AddMethod(md, desc)
desc = newDescriptor("setNotaryServiceFeePerKey", smartcontract.VoidType,
manifest.NewParameter("value", smartcontract.IntegerType))
md = newMethodAndPrice(n.setNotaryServiceFeePerKey, 1<<15, callflag.States)
n.AddMethod(md, desc)
return n return n
} }
@ -142,11 +128,9 @@ func (n *Notary) Metadata() *interop.ContractMD {
// Initialize initializes Notary native contract and implements the Contract interface. // Initialize initializes Notary native contract and implements the Contract interface.
func (n *Notary) Initialize(ic *interop.Context) error { func (n *Notary) Initialize(ic *interop.Context) error {
setIntWithKey(n.ID, ic.DAO, maxNotValidBeforeDeltaKey, defaultMaxNotValidBeforeDelta) setIntWithKey(n.ID, ic.DAO, maxNotValidBeforeDeltaKey, defaultMaxNotValidBeforeDelta)
setIntWithKey(n.ID, ic.DAO, notaryServiceFeeKey, defaultNotaryServiceFeePerKey)
cache := &NotaryCache{ cache := &NotaryCache{
maxNotValidBeforeDelta: defaultMaxNotValidBeforeDelta, maxNotValidBeforeDelta: defaultMaxNotValidBeforeDelta,
notaryServiceFeePerKey: defaultNotaryServiceFeePerKey,
} }
ic.DAO.SetCache(n.ID, cache) ic.DAO.SetCache(n.ID, cache)
return nil return nil
@ -155,7 +139,6 @@ func (n *Notary) Initialize(ic *interop.Context) error {
func (n *Notary) InitializeCache(blockHeight uint32, d *dao.Simple) error { func (n *Notary) InitializeCache(blockHeight uint32, d *dao.Simple) error {
cache := &NotaryCache{ cache := &NotaryCache{
maxNotValidBeforeDelta: uint32(getIntWithKey(n.ID, d, maxNotValidBeforeDeltaKey)), maxNotValidBeforeDelta: uint32(getIntWithKey(n.ID, d, maxNotValidBeforeDeltaKey)),
notaryServiceFeePerKey: getIntWithKey(n.ID, d, notaryServiceFeeKey),
} }
d.SetCache(n.ID, cache) d.SetCache(n.ID, cache)
@ -197,7 +180,7 @@ func (n *Notary) OnPersist(ic *interop.Context) error {
if nFees == 0 { if nFees == 0 {
return nil return nil
} }
feePerKey := n.GetNotaryServiceFeePerKey(ic.DAO) feePerKey := n.Policy.GetAttributeFeeInternal(ic.DAO, transaction.NotaryAssistedT)
singleReward := calculateNotaryReward(nFees, feePerKey, len(notaries)) singleReward := calculateNotaryReward(nFees, feePerKey, len(notaries))
for _, notary := range notaries { for _, notary := range notaries {
n.GAS.mint(ic, notary.GetScriptHash(), singleReward, false) n.GAS.mint(ic, notary.GetScriptHash(), singleReward, false)
@ -238,7 +221,7 @@ func (n *Notary) onPayment(ic *interop.Context, args []stackitem.Item) stackitem
if deposit != nil && till < deposit.Till { if deposit != nil && till < deposit.Till {
panic(fmt.Errorf("`till` shouldn't be less then the previous value %d", deposit.Till)) panic(fmt.Errorf("`till` shouldn't be less then the previous value %d", deposit.Till))
} }
feePerKey := n.GetNotaryServiceFeePerKey(ic.DAO) feePerKey := n.Policy.GetAttributeFeeInternal(ic.DAO, transaction.NotaryAssistedT)
if deposit == nil { if deposit == nil {
if amount.Cmp(big.NewInt(2*feePerKey)) < 0 { if amount.Cmp(big.NewInt(2*feePerKey)) < 0 {
panic(fmt.Errorf("first deposit can not be less then %d, got %d", 2*feePerKey, amount.Int64())) panic(fmt.Errorf("first deposit can not be less then %d, got %d", 2*feePerKey, amount.Int64()))
@ -434,32 +417,6 @@ func (n *Notary) setMaxNotValidBeforeDelta(ic *interop.Context, args []stackitem
return stackitem.Null{} return stackitem.Null{}
} }
// getNotaryServiceFeePerKey is a Notary contract method and returns a reward per notary request key for notary nodes.
func (n *Notary) getNotaryServiceFeePerKey(ic *interop.Context, _ []stackitem.Item) stackitem.Item {
return stackitem.NewBigInteger(big.NewInt(int64(n.GetNotaryServiceFeePerKey(ic.DAO))))
}
// GetNotaryServiceFeePerKey is an internal representation of Notary getNotaryServiceFeePerKey method.
func (n *Notary) GetNotaryServiceFeePerKey(dao *dao.Simple) int64 {
cache := dao.GetROCache(n.ID).(*NotaryCache)
return cache.notaryServiceFeePerKey
}
// setNotaryServiceFeePerKey is a Notary contract method and sets a reward per notary request key for notary nodes.
func (n *Notary) setNotaryServiceFeePerKey(ic *interop.Context, args []stackitem.Item) stackitem.Item {
value := toInt64(args[0])
if value < 0 || value > maxNotaryServiceFeePerKey {
panic("NotaryServiceFeePerKey value is out of range")
}
if !n.NEO.checkCommittee(ic) {
panic("invalid committee signature")
}
setIntWithKey(n.ID, ic.DAO, notaryServiceFeeKey, int64(value))
cache := ic.DAO.GetRWCache(n.ID).(*NotaryCache)
cache.notaryServiceFeePerKey = value
return stackitem.Null{}
}
// GetDepositFor returns state.Deposit for the account specified. It returns nil in case // GetDepositFor returns state.Deposit for the account specified. It returns nil in case
// the deposit is not found in the storage and panics in case of any other error. // the deposit is not found in the storage and panics in case of any other error.
func (n *Notary) GetDepositFor(dao *dao.Simple, acc util.Uint160) *state.Deposit { func (n *Notary) GetDepositFor(dao *dao.Simple, acc util.Uint160) *state.Deposit {

View file

@ -28,6 +28,8 @@ const (
defaultMaxVerificationGas = 1_50000000 defaultMaxVerificationGas = 1_50000000
// defaultAttributeFee is a default fee for a transaction attribute those price wasn't set yet. // defaultAttributeFee is a default fee for a transaction attribute those price wasn't set yet.
defaultAttributeFee = 0 defaultAttributeFee = 0
// defaultNotaryAssistedFee is a default fee for a NotaryAssisted transaction attribute per key.
defaultNotaryAssistedFee = 1000_0000 // 0.1 GAS
// DefaultStoragePrice is the price to pay for 1 byte of storage. // DefaultStoragePrice is the price to pay for 1 byte of storage.
DefaultStoragePrice = 100000 DefaultStoragePrice = 100000
@ -60,6 +62,9 @@ var (
type Policy struct { type Policy struct {
interop.ContractMD interop.ContractMD
NEO *NEO NEO *NEO
// p2pSigExtensionsEnabled defines whether the P2P signature extensions logic is relevant.
p2pSigExtensionsEnabled bool
} }
type PolicyCache struct { type PolicyCache struct {
@ -94,8 +99,11 @@ func copyPolicyCache(src, dst *PolicyCache) {
} }
// newPolicy returns Policy native contract. // newPolicy returns Policy native contract.
func newPolicy() *Policy { func newPolicy(p2pSigExtensionsEnabled bool) *Policy {
p := &Policy{ContractMD: *interop.NewContractMD(nativenames.Policy, policyContractID)} p := &Policy{
ContractMD: *interop.NewContractMD(nativenames.Policy, policyContractID),
p2pSigExtensionsEnabled: p2pSigExtensionsEnabled,
}
defer p.UpdateHash() defer p.UpdateHash()
desc := newDescriptor("getFeePerByte", smartcontract.IntegerType) desc := newDescriptor("getFeePerByte", smartcontract.IntegerType)
@ -173,6 +181,10 @@ func (p *Policy) Initialize(ic *interop.Context) error {
attributeFee: map[transaction.AttrType]uint32{}, attributeFee: map[transaction.AttrType]uint32{},
blockedAccounts: make([]util.Uint160, 0), blockedAccounts: make([]util.Uint160, 0),
} }
if p.p2pSigExtensionsEnabled {
setIntWithKey(p.ID, ic.DAO, []byte{attributeFeePrefix, byte(transaction.NotaryAssistedT)}, defaultNotaryAssistedFee)
cache.attributeFee[transaction.NotaryAssistedT] = defaultNotaryAssistedFee
}
ic.DAO.SetCache(p.ID, cache) ic.DAO.SetCache(p.ID, cache)
return nil return nil

View file

@ -45,13 +45,3 @@ func GetMaxNotValidBeforeDelta() int {
func SetMaxNotValidBeforeDelta(value int) { func SetMaxNotValidBeforeDelta(value int) {
neogointernal.CallWithTokenNoRet(Hash, "setMaxNotValidBeforeDelta", int(contract.States), value) neogointernal.CallWithTokenNoRet(Hash, "setMaxNotValidBeforeDelta", int(contract.States), value)
} }
// GetNotaryServiceFeePerKey represents `getNotaryServiceFeePerKey` method of Notary native contract.
func GetNotaryServiceFeePerKey() int {
return neogointernal.CallWithToken(Hash, "getNotaryServiceFeePerKey", int(contract.ReadStates)).(int)
}
// SetNotaryServiceFeePerKey represents `setNotaryServiceFeePerKey` method of Notary native contract.
func SetNotaryServiceFeePerKey(value int) {
neogointernal.CallWithTokenNoRet(Hash, "setNotaryServiceFeePerKey", int(contract.States), value)
}

View file

@ -111,12 +111,6 @@ func (c *ContractReader) GetMaxNotValidBeforeDelta() (uint32, error) {
return uint32(ret), err return uint32(ret), err
} }
// GetNotaryServiceFeePerKey returns the per-key fee amount paid by transactions
// for the NotaryAssisted attribute.
func (c *ContractReader) GetNotaryServiceFeePerKey() (int64, error) {
return unwrap.Int64(c.invoker.Call(Hash, "getNotaryServiceFeePerKey"))
}
// LockDepositUntil creates and sends a transaction that extends the deposit lock // LockDepositUntil creates and sends a transaction that extends the deposit lock
// time for the given account. The return result from the "lockDepositUntil" // time for the given account. The return result from the "lockDepositUntil"
// method is checked to be true, so transaction fails (with FAULT state) if not // method is checked to be true, so transaction fails (with FAULT state) if not
@ -182,33 +176,6 @@ func (c *Contract) SetMaxNotValidBeforeDeltaUnsigned(blocks uint32) (*transactio
return c.actor.MakeUnsignedCall(Hash, setMaxNVBDeltaMethod, nil, blocks) return c.actor.MakeUnsignedCall(Hash, setMaxNVBDeltaMethod, nil, blocks)
} }
// SetNotaryServiceFeePerKey creates and sends a transaction that sets the new
// per-key fee value paid for using the notary service. The action is successful
// when transaction ends in HALT state. Notice that this setting can be changed
// only by the network's committee, so use an appropriate Actor. The returned
// values are transaction hash, its ValidUntilBlock value and an error if any.
func (c *Contract) SetNotaryServiceFeePerKey(fee int64) (util.Uint256, uint32, error) {
return c.actor.SendCall(Hash, setFeePKMethod, fee)
}
// SetNotaryServiceFeePerKeyTransaction creates a transaction that sets the new
// per-key fee value paid for using the notary service. The action is successful
// when transaction ends in HALT state. Notice that this setting can be changed
// only by the network's committee, so use an appropriate Actor. The transaction
// is signed, but not sent to the network, instead it's returned to the caller.
func (c *Contract) SetNotaryServiceFeePerKeyTransaction(fee int64) (*transaction.Transaction, error) {
return c.actor.MakeCall(Hash, setFeePKMethod, fee)
}
// SetNotaryServiceFeePerKeyUnsigned creates a transaction that sets the new
// per-key fee value paid for using the notary service. The action is successful
// when transaction ends in HALT state. Notice that this setting can be changed
// only by the network's committee, so use an appropriate Actor. The transaction
// is not signed and just returned to the caller.
func (c *Contract) SetNotaryServiceFeePerKeyUnsigned(fee int64) (*transaction.Transaction, error) {
return c.actor.MakeUnsignedCall(Hash, setFeePKMethod, nil, fee)
}
// Withdraw creates and sends a transaction that withdraws the deposit belonging // Withdraw creates and sends a transaction that withdraws the deposit belonging
// to "from" account and sends it to "to" account. The return result from the // to "from" account and sends it to "to" account. The return result from the
// "withdraw" method is checked to be true, so transaction fails (with FAULT // "withdraw" method is checked to be true, so transaction fails (with FAULT

View file

@ -103,26 +103,6 @@ func TestUint32Getters(t *testing.T) {
} }
} }
func TestGetNotaryServiceFeePerKey(t *testing.T) {
ta := &testAct{}
ntr := NewReader(ta)
ta.err = errors.New("")
_, err := ntr.GetNotaryServiceFeePerKey()
require.Error(t, err)
ta.err = nil
ta.res = &result.Invoke{
State: "HALT",
Stack: []stackitem.Item{
stackitem.Make(42),
},
}
res, err := ntr.GetNotaryServiceFeePerKey()
require.NoError(t, err)
require.Equal(t, int64(42), res)
}
func TestTxSenders(t *testing.T) { func TestTxSenders(t *testing.T) {
ta := new(testAct) ta := new(testAct)
ntr := New(ta) ntr := New(ta)
@ -134,9 +114,6 @@ func TestTxSenders(t *testing.T) {
"SetMaxNotValidBeforeDelta": func() (util.Uint256, uint32, error) { "SetMaxNotValidBeforeDelta": func() (util.Uint256, uint32, error) {
return ntr.SetMaxNotValidBeforeDelta(42) return ntr.SetMaxNotValidBeforeDelta(42)
}, },
"SetNotaryServiceFeePerKey": func() (util.Uint256, uint32, error) {
return ntr.SetNotaryServiceFeePerKey(100500)
},
"Withdraw": func() (util.Uint256, uint32, error) { "Withdraw": func() (util.Uint256, uint32, error) {
return ntr.Withdraw(util.Uint160{1, 2, 3}, util.Uint160{3, 2, 1}) return ntr.Withdraw(util.Uint160{1, 2, 3}, util.Uint160{3, 2, 1})
}, },
@ -174,12 +151,6 @@ func TestTxMakers(t *testing.T) {
"SetMaxNotValidBeforeDeltaUnsigned": func() (*transaction.Transaction, error) { "SetMaxNotValidBeforeDeltaUnsigned": func() (*transaction.Transaction, error) {
return ntr.SetMaxNotValidBeforeDeltaUnsigned(42) return ntr.SetMaxNotValidBeforeDeltaUnsigned(42)
}, },
"SetNotaryServiceFeePerKeyTransaction": func() (*transaction.Transaction, error) {
return ntr.SetNotaryServiceFeePerKeyTransaction(100500)
},
"SetNotaryServiceFeePerKeyUnsigned": func() (*transaction.Transaction, error) {
return ntr.SetNotaryServiceFeePerKeyUnsigned(100500)
},
"WithdrawTransaction": func() (*transaction.Transaction, error) { "WithdrawTransaction": func() (*transaction.Transaction, error) {
return ntr.WithdrawTransaction(util.Uint160{1, 2, 3}, util.Uint160{3, 2, 1}) return ntr.WithdrawTransaction(util.Uint160{1, 2, 3}, util.Uint160{3, 2, 1})
}, },

View file

@ -183,6 +183,10 @@ func TestClientPolicyContract(t *testing.T) {
require.NoError(t, err) require.NoError(t, err)
require.Equal(t, int64(100000), val) require.Equal(t, int64(100000), val)
val, err = polizei.GetAttributeFee(transaction.NotaryAssistedT)
require.NoError(t, err)
require.Equal(t, int64(1000_0000), val)
ret, err := polizei.IsBlocked(util.Uint160{}) ret, err := polizei.IsBlocked(util.Uint160{})
require.NoError(t, err) require.NoError(t, err)
require.False(t, ret) require.False(t, ret)
@ -212,14 +216,17 @@ func TestClientPolicyContract(t *testing.T) {
txstorage, err := polis.SetStoragePriceUnsigned(100500) txstorage, err := polis.SetStoragePriceUnsigned(100500)
require.NoError(t, err) require.NoError(t, err)
txattr, err := polis.SetAttributeFeeUnsigned(transaction.NotaryAssistedT, 100500)
require.NoError(t, err)
txblock, err := polis.BlockAccountUnsigned(util.Uint160{1, 2, 3}) txblock, err := polis.BlockAccountUnsigned(util.Uint160{1, 2, 3})
require.NoError(t, err) require.NoError(t, err)
for _, tx := range []*transaction.Transaction{txblock, txstorage, txnetfee, txexec} { for _, tx := range []*transaction.Transaction{txattr, txblock, txstorage, txnetfee, txexec} {
tx.Scripts[0].InvocationScript = testchain.SignCommittee(tx) tx.Scripts[0].InvocationScript = testchain.SignCommittee(tx)
} }
bl := testchain.NewBlock(t, chain, 1, 0, txblock, txstorage, txnetfee, txexec) bl := testchain.NewBlock(t, chain, 1, 0, txattr, txblock, txstorage, txnetfee, txexec)
_, err = c.SubmitBlock(*bl) _, err = c.SubmitBlock(*bl)
require.NoError(t, err) require.NoError(t, err)
@ -235,6 +242,10 @@ func TestClientPolicyContract(t *testing.T) {
require.NoError(t, err) require.NoError(t, err)
require.Equal(t, int64(100500), val) require.Equal(t, int64(100500), val)
val, err = polizei.GetAttributeFee(transaction.NotaryAssistedT)
require.NoError(t, err)
require.Equal(t, int64(100500), val)
ret, err = polizei.IsBlocked(util.Uint160{1, 2, 3}) ret, err = polizei.IsBlocked(util.Uint160{1, 2, 3})
require.NoError(t, err) require.NoError(t, err)
require.True(t, ret) require.True(t, ret)
@ -480,10 +491,6 @@ func TestClientNotary(t *testing.T) {
require.NoError(t, err) require.NoError(t, err)
require.Equal(t, uint32(140), maxNVBd) require.Equal(t, uint32(140), maxNVBd)
feePerKey, err := notaReader.GetNotaryServiceFeePerKey()
require.NoError(t, err)
require.Equal(t, int64(1000_0000), feePerKey)
commAct, err := actor.New(c, []actor.SignerAccount{{ commAct, err := actor.New(c, []actor.SignerAccount{{
Signer: transaction.Signer{ Signer: transaction.Signer{
Account: testchain.CommitteeScriptHash(), Account: testchain.CommitteeScriptHash(),
@ -501,12 +508,9 @@ func TestClientNotary(t *testing.T) {
txNVB, err := notaComm.SetMaxNotValidBeforeDeltaUnsigned(210) txNVB, err := notaComm.SetMaxNotValidBeforeDeltaUnsigned(210)
require.NoError(t, err) require.NoError(t, err)
txFee, err := notaComm.SetNotaryServiceFeePerKeyUnsigned(500_0000)
require.NoError(t, err)
txNVB.Scripts[0].InvocationScript = testchain.SignCommittee(txNVB) txNVB.Scripts[0].InvocationScript = testchain.SignCommittee(txNVB)
txFee.Scripts[0].InvocationScript = testchain.SignCommittee(txFee) bl := testchain.NewBlock(t, chain, 1, 0, txNVB)
bl := testchain.NewBlock(t, chain, 1, 0, txNVB, txFee)
_, err = c.SubmitBlock(*bl) _, err = c.SubmitBlock(*bl)
require.NoError(t, err) require.NoError(t, err)
@ -514,10 +518,6 @@ func TestClientNotary(t *testing.T) {
require.NoError(t, err) require.NoError(t, err)
require.Equal(t, uint32(210), maxNVBd) require.Equal(t, uint32(210), maxNVBd)
feePerKey, err = notaReader.GetNotaryServiceFeePerKey()
require.NoError(t, err)
require.Equal(t, int64(500_0000), feePerKey)
privAct, err := actor.New(c, []actor.SignerAccount{{ privAct, err := actor.New(c, []actor.SignerAccount{{
Signer: transaction.Signer{ Signer: transaction.Signer{
Account: priv0Hash, Account: priv0Hash,

View file

@ -90,7 +90,6 @@ type (
GetNatives() []state.NativeContract GetNatives() []state.NativeContract
GetNextBlockValidators() ([]*keys.PublicKey, error) GetNextBlockValidators() ([]*keys.PublicKey, error)
GetNotaryContractScriptHash() util.Uint160 GetNotaryContractScriptHash() util.Uint160
GetNotaryServiceFeePerKey() int64
GetStateModule() core.StateRoot GetStateModule() core.StateRoot
GetStorageItem(id int32, key []byte) state.StorageItem GetStorageItem(id int32, key []byte) state.StorageItem
GetTestHistoricVM(t trigger.Type, tx *transaction.Transaction, nextBlockHeight uint32) (*interop.Context, error) GetTestHistoricVM(t trigger.Type, tx *transaction.Transaction, nextBlockHeight uint32) (*interop.Context, error)
@ -976,15 +975,7 @@ func (s *Server) calculateNetworkFee(reqParams params.Params) (any, *neorpc.Erro
netFee += gasConsumed netFee += gasConsumed
size += io.GetVarSize(w.VerificationScript) + io.GetVarSize(w.InvocationScript) size += io.GetVarSize(w.VerificationScript) + io.GetVarSize(w.InvocationScript)
} }
if s.chain.P2PSigExtensionsEnabled() { netFee += int64(size)*s.chain.FeePerByte() + s.chain.CalculateAttributesFee(tx)
attrs := tx.GetAttributes(transaction.NotaryAssistedT)
if len(attrs) != 0 {
na := attrs[0].Value.(*transaction.NotaryAssisted)
netFee += (int64(na.NKeys) + 1) * s.chain.GetNotaryServiceFeePerKey()
}
}
fee := s.chain.FeePerByte()
netFee += int64(size)*fee + s.chain.CalculateAttributesFee(tx)
return result.NetworkFee{Value: netFee}, nil return result.NetworkFee{Value: netFee}, nil
} }

View file

@ -138,7 +138,7 @@ func initClearServerWithCustomConfig(t testing.TB, ccfg func(configuration *conf
} }
func initClearServerWithInMemoryChain(t testing.TB) (*core.Blockchain, *Server, *httptest.Server) { func initClearServerWithInMemoryChain(t testing.TB) (*core.Blockchain, *Server, *httptest.Server) {
return initClearServerWithServices(t, false, false, false) return initClearServerWithServices(t, false, true, false)
} }
func initServerWithInMemoryChain(t *testing.T) (*core.Blockchain, *Server, *httptest.Server) { func initServerWithInMemoryChain(t *testing.T) (*core.Blockchain, *Server, *httptest.Server) {

View file

@ -87,7 +87,7 @@ const (
faultedTxHashLE = "82279bfe9bada282ca0f8cb8e0bb124b921af36f00c69a518320322c6f4fef60" faultedTxHashLE = "82279bfe9bada282ca0f8cb8e0bb124b921af36f00c69a518320322c6f4fef60"
faultedTxBlock uint32 = 23 faultedTxBlock uint32 = 23
invokescriptContractAVM = "VwIADBQBDAMOBQYMDQIODw0DDgcJAAAAAErZMCQE2zBwaEH4J+yMqiYEEUAMFA0PAwIJAAIBAwcDBAUCAQAOBgwJStkwJATbMHFpQfgn7IyqJgQSQBNA" invokescriptContractAVM = "VwIADBQBDAMOBQYMDQIODw0DDgcJAAAAAErZMCQE2zBwaEH4J+yMqiYEEUAMFA0PAwIJAAIBAwcDBAUCAQAOBgwJStkwJATbMHFpQfgn7IyqJgQSQBNA"
block20StateRootLE = "66900c59a718d76cc754635aa49b714cc79dc820b4a34290a19c6dfecd56b03a" block20StateRootLE = "858c873539d6d24a70f2be13f9dafc61aef2b63c2aa16bb440676de6e44e3cf1"
) )
var ( var (