Skip to content

Commit 7251820

Browse files
committed
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>
1 parent 32983ca commit 7251820

File tree

15 files changed

+90
-116
lines changed

15 files changed

+90
-116
lines changed

ROADMAP.md

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -57,4 +57,14 @@ NeoGo retains certain deprecated error codes: `neorpc.ErrCompatGeneric`,
5757
`neorpc.ErrCompatNoOpenedWallet`. They returned by nodes not compliant with the
5858
neo-project/proposals#156 (NeoGo pre-0.102.0 and all known C# versions).
5959

60-
Removal of the deprecated RPC error codes is planned once all nodes adopt the new error standard.
60+
Removal of the deprecated RPC error codes is planned once all nodes adopt the new error standard.
61+
62+
## NotaryServiceFeePerKey native Notary contract functionality removal
63+
64+
`getNotaryServiceFeePerKey` and `setNotaryServiceFeePerKey` methods were moved from
65+
native Notary contract to the native PolicyContract contract to be a part of more
66+
generic attribute fees functionality (`getAttributeFee` and `setAttributeFee`
67+
methods for the NotaryAssisted attribute).
68+
69+
Removal of the related Notary-specific interop APIs and RPC Client Actor APIs
70+
is scheduled for Jan-Feb 2024 (~0.106.0 release).

pkg/compiler/native_test.go

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -207,8 +207,6 @@ func TestNativeHelpersCompile(t *testing.T) {
207207
{"expirationOf", []string{u160}},
208208
{"getMaxNotValidBeforeDelta", nil},
209209
{"setMaxNotValidBeforeDelta", []string{"42"}},
210-
{"getNotaryServiceFeePerKey", nil},
211-
{"setNotaryServiceFeePerKey", []string{"42"}},
212210
})
213211
runNativeTestCases(t, cs.Management.ContractMD, "management", []nativeTestCase{
214212
{"deploy", []string{"nil", "nil"}},

pkg/core/blockchain.go

Lines changed: 8 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -2054,10 +2054,10 @@ func (bc *Blockchain) GetNotaryBalance(acc util.Uint160) *big.Int {
20542054
return bc.contracts.Notary.BalanceOf(bc.dao, acc)
20552055
}
20562056

2057-
// GetNotaryServiceFeePerKey returns NotaryServiceFeePerKey which is a reward per
2058-
// notary request key for designated notary nodes.
2057+
// GetNotaryServiceFeePerKey returns a NotaryAssisted transaction attribute fee
2058+
// per key which is a reward per notary request key for designated notary nodes.
20592059
func (bc *Blockchain) GetNotaryServiceFeePerKey() int64 {
2060-
return bc.contracts.Notary.GetNotaryServiceFeePerKey(bc.dao)
2060+
return bc.contracts.Policy.GetAttributeFeeInternal(bc.dao, transaction.NotaryAssistedT)
20612061
}
20622062

20632063
// GetNotaryContractScriptHash returns Notary native contract hash.
@@ -2480,13 +2480,6 @@ func (bc *Blockchain) verifyAndPoolTx(t *transaction.Transaction, pool *mempool.
24802480
return fmt.Errorf("%w: (%d > MaxTransactionSize %d)", ErrTxTooBig, size, transaction.MaxTransactionSize)
24812481
}
24822482
needNetworkFee := int64(size)*bc.FeePerByte() + bc.CalculateAttributesFee(t)
2483-
if bc.P2PSigExtensionsEnabled() {
2484-
attrs := t.GetAttributes(transaction.NotaryAssistedT)
2485-
if len(attrs) != 0 {
2486-
na := attrs[0].Value.(*transaction.NotaryAssisted)
2487-
needNetworkFee += (int64(na.NKeys) + 1) * bc.contracts.Notary.GetNotaryServiceFeePerKey(bc.dao)
2488-
}
2489-
}
24902483
netFee := t.NetworkFee - needNetworkFee
24912484
if netFee < 0 {
24922485
return fmt.Errorf("%w: net fee is %v, need %v", ErrTxSmallNetworkFee, t.NetworkFee, needNetworkFee)
@@ -2549,6 +2542,11 @@ func (bc *Blockchain) CalculateAttributesFee(tx *transaction.Transaction) int64
25492542
switch attr.Type {
25502543
case transaction.ConflictsT:
25512544
feeSum += base * int64(len(tx.Signers))
2545+
case transaction.NotaryAssistedT:
2546+
if bc.P2PSigExtensionsEnabled() {
2547+
na := attr.Value.(*transaction.NotaryAssisted)
2548+
feeSum += base * (int64(na.NKeys) + 1)
2549+
}
25522550
default:
25532551
feeSum += base
25542552
}
@@ -2924,13 +2922,6 @@ func (bc *Blockchain) verifyTxWitnesses(t *transaction.Transaction, block *block
29242922
var gasLimit int64
29252923
if len(verificationFee) == 0 {
29262924
gasLimit = t.NetworkFee - int64(t.Size())*bc.FeePerByte() - bc.CalculateAttributesFee(t)
2927-
if bc.P2PSigExtensionsEnabled() {
2928-
attrs := t.GetAttributes(transaction.NotaryAssistedT)
2929-
if len(attrs) != 0 {
2930-
na := attrs[0].Value.(*transaction.NotaryAssisted)
2931-
gasLimit -= (int64(na.NKeys) + 1) * bc.contracts.Notary.GetNotaryServiceFeePerKey(bc.dao)
2932-
}
2933-
}
29342925
} else {
29352926
gasLimit = verificationFee[0]
29362927
}

pkg/core/native/contract.go

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -74,10 +74,11 @@ func NewContracts(cfg config.ProtocolConfiguration) *Contracts {
7474

7575
gas := newGAS(int64(cfg.InitialGASSupply), cfg.P2PSigExtensions)
7676
neo := newNEO(cfg)
77-
policy := newPolicy()
77+
policy := newPolicy(cfg.P2PSigExtensions)
7878
neo.GAS = gas
7979
neo.Policy = policy
8080
gas.NEO = neo
81+
gas.Policy = policy
8182
mgmt.NEO = neo
8283
mgmt.Policy = policy
8384
policy.NEO = neo
@@ -104,8 +105,8 @@ func NewContracts(cfg config.ProtocolConfiguration) *Contracts {
104105
notary.GAS = gas
105106
notary.NEO = neo
106107
notary.Desig = desig
108+
notary.Policy = policy
107109
cs.Notary = notary
108-
gas.Notary = notary
109110
cs.Contracts = append(cs.Contracts, notary)
110111
}
111112

pkg/core/native/management_test.go

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@ import (
1717

1818
func TestDeployGetUpdateDestroyContract(t *testing.T) {
1919
mgmt := newManagement()
20-
mgmt.Policy = newPolicy()
20+
mgmt.Policy = newPolicy(false)
2121
d := dao.NewSimple(storage.NewMemoryStore(), false)
2222
ic := &interop.Context{DAO: d}
2323
err := mgmt.Initialize(ic)
@@ -97,7 +97,7 @@ func TestManagement_Initialize(t *testing.T) {
9797

9898
func TestManagement_GetNEP17Contracts(t *testing.T) {
9999
mgmt := newManagement()
100-
mgmt.Policy = newPolicy()
100+
mgmt.Policy = newPolicy(false)
101101
d := dao.NewSimple(storage.NewMemoryStore(), false)
102102
err := mgmt.Initialize(&interop.Context{DAO: d})
103103
require.NoError(t, err)

pkg/core/native/native_gas.go

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -18,9 +18,8 @@ import (
1818
// GAS represents GAS native contract.
1919
type GAS struct {
2020
nep17TokenNative
21-
NEO *NEO
22-
// Notary is a native Notary contract. It is set only when P2PSigExtensions are on.
23-
Notary *Notary
21+
NEO *NEO
22+
Policy *Policy
2423

2524
initialSupply int64
2625
p2pSigExtensionsEnabled bool
@@ -124,7 +123,7 @@ func (g *GAS) OnPersist(ic *interop.Context) error {
124123
attrs := tx.GetAttributes(transaction.NotaryAssistedT)
125124
if len(attrs) != 0 {
126125
na := attrs[0].Value.(*transaction.NotaryAssisted)
127-
netFee -= (int64(na.NKeys) + 1) * g.Notary.GetNotaryServiceFeePerKey(ic.DAO)
126+
netFee -= (int64(na.NKeys) + 1) * g.Policy.GetAttributeFeeInternal(ic.DAO, transaction.NotaryAssistedT)
128127
}
129128
}
130129
}

pkg/core/native/native_test/notary_test.go

Lines changed: 0 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -38,16 +38,6 @@ func TestNotary_MaxNotValidBeforeDeltaCache(t *testing.T) {
3838
testGetSetCache(t, c, "MaxNotValidBeforeDelta", 140)
3939
}
4040

41-
func TestNotary_NotaryServiceFeePerKey(t *testing.T) {
42-
c := newNotaryClient(t)
43-
testGetSet(t, c, "NotaryServiceFeePerKey", 1000_0000, 0, 0)
44-
}
45-
46-
func TestNotary_NotaryServiceFeePerKeyCache(t *testing.T) {
47-
c := newNotaryClient(t)
48-
testGetSetCache(t, c, "NotaryServiceFeePerKey", 1000_0000)
49-
}
50-
5141
func TestNotary_Pipeline(t *testing.T) {
5242
notaryCommitteeInvoker := newNotaryClient(t)
5343
e := notaryCommitteeInvoker.Executor

pkg/core/native/notary.go

Lines changed: 8 additions & 51 deletions
Original file line numberDiff line numberDiff line change
@@ -28,14 +28,14 @@ import (
2828
// Notary represents Notary native contract.
2929
type Notary struct {
3030
interop.ContractMD
31-
GAS *GAS
32-
NEO *NEO
33-
Desig *Designate
31+
GAS *GAS
32+
NEO *NEO
33+
Desig *Designate
34+
Policy *Policy
3435
}
3536

3637
type NotaryCache struct {
3738
maxNotValidBeforeDelta uint32
38-
notaryServiceFeePerKey int64
3939
}
4040

4141
// NotaryService is a Notary module interface.
@@ -48,15 +48,10 @@ const (
4848
// prefixDeposit is a prefix for storing Notary deposits.
4949
prefixDeposit = 1
5050
defaultDepositDeltaTill = 5760
51-
defaultMaxNotValidBeforeDelta = 140 // 20 rounds for 7 validators, a little more than half an hour
52-
defaultNotaryServiceFeePerKey = 1000_0000 // 0.1 GAS
53-
maxNotaryServiceFeePerKey = 1_0000_0000 // 1 GAS
51+
defaultMaxNotValidBeforeDelta = 140 // 20 rounds for 7 validators, a little more than half an hour
5452
)
5553

56-
var (
57-
maxNotValidBeforeDeltaKey = []byte{10}
58-
notaryServiceFeeKey = []byte{5}
59-
)
54+
var maxNotValidBeforeDeltaKey = []byte{10}
6055

6156
var (
6257
_ interop.Contract = (*Notary)(nil)
@@ -122,15 +117,6 @@ func newNotary() *Notary {
122117
md = newMethodAndPrice(n.setMaxNotValidBeforeDelta, 1<<15, callflag.States)
123118
n.AddMethod(md, desc)
124119

125-
desc = newDescriptor("getNotaryServiceFeePerKey", smartcontract.IntegerType)
126-
md = newMethodAndPrice(n.getNotaryServiceFeePerKey, 1<<15, callflag.ReadStates)
127-
n.AddMethod(md, desc)
128-
129-
desc = newDescriptor("setNotaryServiceFeePerKey", smartcontract.VoidType,
130-
manifest.NewParameter("value", smartcontract.IntegerType))
131-
md = newMethodAndPrice(n.setNotaryServiceFeePerKey, 1<<15, callflag.States)
132-
n.AddMethod(md, desc)
133-
134120
return n
135121
}
136122

@@ -142,11 +128,9 @@ func (n *Notary) Metadata() *interop.ContractMD {
142128
// Initialize initializes Notary native contract and implements the Contract interface.
143129
func (n *Notary) Initialize(ic *interop.Context) error {
144130
setIntWithKey(n.ID, ic.DAO, maxNotValidBeforeDeltaKey, defaultMaxNotValidBeforeDelta)
145-
setIntWithKey(n.ID, ic.DAO, notaryServiceFeeKey, defaultNotaryServiceFeePerKey)
146131

147132
cache := &NotaryCache{
148133
maxNotValidBeforeDelta: defaultMaxNotValidBeforeDelta,
149-
notaryServiceFeePerKey: defaultNotaryServiceFeePerKey,
150134
}
151135
ic.DAO.SetCache(n.ID, cache)
152136
return nil
@@ -155,7 +139,6 @@ func (n *Notary) Initialize(ic *interop.Context) error {
155139
func (n *Notary) InitializeCache(blockHeight uint32, d *dao.Simple) error {
156140
cache := &NotaryCache{
157141
maxNotValidBeforeDelta: uint32(getIntWithKey(n.ID, d, maxNotValidBeforeDeltaKey)),
158-
notaryServiceFeePerKey: getIntWithKey(n.ID, d, notaryServiceFeeKey),
159142
}
160143

161144
d.SetCache(n.ID, cache)
@@ -197,7 +180,7 @@ func (n *Notary) OnPersist(ic *interop.Context) error {
197180
if nFees == 0 {
198181
return nil
199182
}
200-
feePerKey := n.GetNotaryServiceFeePerKey(ic.DAO)
183+
feePerKey := n.Policy.GetAttributeFeeInternal(ic.DAO, transaction.NotaryAssistedT)
201184
singleReward := calculateNotaryReward(nFees, feePerKey, len(notaries))
202185
for _, notary := range notaries {
203186
n.GAS.mint(ic, notary.GetScriptHash(), singleReward, false)
@@ -238,7 +221,7 @@ func (n *Notary) onPayment(ic *interop.Context, args []stackitem.Item) stackitem
238221
if deposit != nil && till < deposit.Till {
239222
panic(fmt.Errorf("`till` shouldn't be less then the previous value %d", deposit.Till))
240223
}
241-
feePerKey := n.GetNotaryServiceFeePerKey(ic.DAO)
224+
feePerKey := n.Policy.GetAttributeFeeInternal(ic.DAO, transaction.NotaryAssistedT)
242225
if deposit == nil {
243226
if amount.Cmp(big.NewInt(2*feePerKey)) < 0 {
244227
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
434417
return stackitem.Null{}
435418
}
436419

437-
// getNotaryServiceFeePerKey is a Notary contract method and returns a reward per notary request key for notary nodes.
438-
func (n *Notary) getNotaryServiceFeePerKey(ic *interop.Context, _ []stackitem.Item) stackitem.Item {
439-
return stackitem.NewBigInteger(big.NewInt(int64(n.GetNotaryServiceFeePerKey(ic.DAO))))
440-
}
441-
442-
// GetNotaryServiceFeePerKey is an internal representation of Notary getNotaryServiceFeePerKey method.
443-
func (n *Notary) GetNotaryServiceFeePerKey(dao *dao.Simple) int64 {
444-
cache := dao.GetROCache(n.ID).(*NotaryCache)
445-
return cache.notaryServiceFeePerKey
446-
}
447-
448-
// setNotaryServiceFeePerKey is a Notary contract method and sets a reward per notary request key for notary nodes.
449-
func (n *Notary) setNotaryServiceFeePerKey(ic *interop.Context, args []stackitem.Item) stackitem.Item {
450-
value := toInt64(args[0])
451-
if value < 0 || value > maxNotaryServiceFeePerKey {
452-
panic("NotaryServiceFeePerKey value is out of range")
453-
}
454-
if !n.NEO.checkCommittee(ic) {
455-
panic("invalid committee signature")
456-
}
457-
setIntWithKey(n.ID, ic.DAO, notaryServiceFeeKey, int64(value))
458-
cache := ic.DAO.GetRWCache(n.ID).(*NotaryCache)
459-
cache.notaryServiceFeePerKey = value
460-
return stackitem.Null{}
461-
}
462-
463420
// GetDepositFor returns state.Deposit for the account specified. It returns nil in case
464421
// the deposit is not found in the storage and panics in case of any other error.
465422
func (n *Notary) GetDepositFor(dao *dao.Simple, acc util.Uint160) *state.Deposit {

pkg/core/native/policy.go

Lines changed: 14 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,8 @@ const (
2828
defaultMaxVerificationGas = 1_50000000
2929
// defaultAttributeFee is a default fee for a transaction attribute those price wasn't set yet.
3030
defaultAttributeFee = 0
31+
// defaultNotaryAssistedFee is a default fee for a NotaryAssisted transaction attribute per key.
32+
defaultNotaryAssistedFee = 1000_0000 // 0.1 GAS
3133
// DefaultStoragePrice is the price to pay for 1 byte of storage.
3234
DefaultStoragePrice = 100000
3335

@@ -60,6 +62,9 @@ var (
6062
type Policy struct {
6163
interop.ContractMD
6264
NEO *NEO
65+
66+
// p2pSigExtensionsEnabled defines whether the P2P signature extensions logic is relevant.
67+
p2pSigExtensionsEnabled bool
6368
}
6469

6570
type PolicyCache struct {
@@ -94,8 +99,11 @@ func copyPolicyCache(src, dst *PolicyCache) {
9499
}
95100

96101
// newPolicy returns Policy native contract.
97-
func newPolicy() *Policy {
98-
p := &Policy{ContractMD: *interop.NewContractMD(nativenames.Policy, policyContractID)}
102+
func newPolicy(p2pSigExtensionsEnabled bool) *Policy {
103+
p := &Policy{
104+
ContractMD: *interop.NewContractMD(nativenames.Policy, policyContractID),
105+
p2pSigExtensionsEnabled: p2pSigExtensionsEnabled,
106+
}
99107
defer p.UpdateHash()
100108

101109
desc := newDescriptor("getFeePerByte", smartcontract.IntegerType)
@@ -173,6 +181,10 @@ func (p *Policy) Initialize(ic *interop.Context) error {
173181
attributeFee: map[transaction.AttrType]uint32{},
174182
blockedAccounts: make([]util.Uint160, 0),
175183
}
184+
if p.p2pSigExtensionsEnabled {
185+
setIntWithKey(p.ID, ic.DAO, []byte{attributeFeePrefix, byte(transaction.NotaryAssistedT)}, defaultNotaryAssistedFee)
186+
cache.attributeFee[transaction.NotaryAssistedT] = defaultNotaryAssistedFee
187+
}
176188
ic.DAO.SetCache(p.ID, cache)
177189

178190
return nil

pkg/interop/native/notary/notary.go

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -47,11 +47,19 @@ func SetMaxNotValidBeforeDelta(value int) {
4747
}
4848

4949
// GetNotaryServiceFeePerKey represents `getNotaryServiceFeePerKey` method of Notary native contract.
50+
//
51+
// Deprecated: this logic has been moved to native Policy contract since 0.102.1.
52+
// Please, use policy.GetAttributeFee(NotaryAssistedT) instead, this method will
53+
// be removed in future versions.
5054
func GetNotaryServiceFeePerKey() int {
5155
return neogointernal.CallWithToken(Hash, "getNotaryServiceFeePerKey", int(contract.ReadStates)).(int)
5256
}
5357

5458
// SetNotaryServiceFeePerKey represents `setNotaryServiceFeePerKey` method of Notary native contract.
59+
//
60+
// Deprecated: this logic has been moved to native Policy contract since 0.102.1.
61+
// Please, use policy.SetAttributeFee(NotaryAssistedT, value) instead, this method
62+
// will be removed in future versions.
5563
func SetNotaryServiceFeePerKey(value int) {
5664
neogointernal.CallWithTokenNoRet(Hash, "setNotaryServiceFeePerKey", int(contract.States), value)
5765
}

pkg/rpcclient/notary/contract.go

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -113,6 +113,10 @@ func (c *ContractReader) GetMaxNotValidBeforeDelta() (uint32, error) {
113113

114114
// GetNotaryServiceFeePerKey returns the per-key fee amount paid by transactions
115115
// for the NotaryAssisted attribute.
116+
//
117+
// Deprecated: this logic has been moved to native Policy contract since 0.102.1.
118+
// Please, use policy.GetAttributeFee(NotaryAssistedT) instead, this method will
119+
// be removed in future versions.
116120
func (c *ContractReader) GetNotaryServiceFeePerKey() (int64, error) {
117121
return unwrap.Int64(c.invoker.Call(Hash, "getNotaryServiceFeePerKey"))
118122
}
@@ -187,6 +191,10 @@ func (c *Contract) SetMaxNotValidBeforeDeltaUnsigned(blocks uint32) (*transactio
187191
// when transaction ends in HALT state. Notice that this setting can be changed
188192
// only by the network's committee, so use an appropriate Actor. The returned
189193
// values are transaction hash, its ValidUntilBlock value and an error if any.
194+
//
195+
// Deprecated: this logic has been moved to native Policy contract since 0.102.1.
196+
// Please, use policy.SetAttributeFee(NotaryAssistedT, fee) instead, this method
197+
// will be removed in future versions.
190198
func (c *Contract) SetNotaryServiceFeePerKey(fee int64) (util.Uint256, uint32, error) {
191199
return c.actor.SendCall(Hash, setFeePKMethod, fee)
192200
}
@@ -196,6 +204,10 @@ func (c *Contract) SetNotaryServiceFeePerKey(fee int64) (util.Uint256, uint32, e
196204
// when transaction ends in HALT state. Notice that this setting can be changed
197205
// only by the network's committee, so use an appropriate Actor. The transaction
198206
// is signed, but not sent to the network, instead it's returned to the caller.
207+
//
208+
// Deprecated: this logic has been moved to native Policy contract since 0.102.1.
209+
// Please, use policy.SetAttributeFeeTransaction(NotaryAssistedT, fee) instead,
210+
// this method will be removed in future versions.
199211
func (c *Contract) SetNotaryServiceFeePerKeyTransaction(fee int64) (*transaction.Transaction, error) {
200212
return c.actor.MakeCall(Hash, setFeePKMethod, fee)
201213
}
@@ -205,6 +217,10 @@ func (c *Contract) SetNotaryServiceFeePerKeyTransaction(fee int64) (*transaction
205217
// when transaction ends in HALT state. Notice that this setting can be changed
206218
// only by the network's committee, so use an appropriate Actor. The transaction
207219
// is not signed and just returned to the caller.
220+
//
221+
// Deprecated: this logic has been moved to native Policy contract since 0.102.1.
222+
// Please, use policy.SetAttributeFeeUnsigned(NotaryAssistedT, fee) instead, this
223+
// method will be removed in future versions.
208224
func (c *Contract) SetNotaryServiceFeePerKeyUnsigned(fee int64) (*transaction.Transaction, error) {
209225
return c.actor.MakeUnsignedCall(Hash, setFeePKMethod, nil, fee)
210226
}

0 commit comments

Comments
 (0)