From e3443b82a4e45d0e9b1b87f7fe0c6aae7f1c9dfb Mon Sep 17 00:00:00 2001 From: AnnaShaleva Date: Wed, 27 Oct 2021 17:48:31 +0300 Subject: [PATCH] *: remove fees logic --- pkg/core/blockchain.go | 30 ++---------------------------- pkg/core/fee/calculate.go | 13 +++---------- pkg/core/interop/context.go | 5 +---- pkg/core/interop/crypto/ecdsa.go | 4 ---- pkg/core/interop_system.go | 14 -------------- pkg/core/native/interop.go | 5 ----- pkg/core/native/management.go | 12 +----------- pkg/core/native/native_gas.go | 7 ------- pkg/core/native/native_neo.go | 14 +------------- pkg/core/native/native_nep17.go | 4 ++-- pkg/core/native/notary.go | 7 ------- pkg/core/native/oracle.go | 28 +--------------------------- pkg/core/native/policy.go | 4 +++- pkg/core/native_policy_test.go | 2 +- pkg/rpc/client/rpc.go | 9 +-------- pkg/rpc/server/server.go | 11 +++-------- pkg/services/oracle/response.go | 2 +- pkg/vm/vm.go | 7 ------- 18 files changed, 20 insertions(+), 158 deletions(-) diff --git a/pkg/core/blockchain.go b/pkg/core/blockchain.go index a5d9aeecd..130591887 100644 --- a/pkg/core/blockchain.go +++ b/pkg/core/blockchain.go @@ -1818,18 +1818,6 @@ func (bc *Blockchain) verifyAndPoolTx(t *transaction.Transaction, pool *mempool. if size > transaction.MaxTransactionSize { return fmt.Errorf("%w: (%d > MaxTransactionSize %d)", ErrTxTooBig, size, transaction.MaxTransactionSize) } - needNetworkFee := int64(size) * bc.FeePerByte() - if bc.P2PSigExtensionsEnabled() { - attrs := t.GetAttributes(transaction.NotaryAssistedT) - if len(attrs) != 0 { - na := attrs[0].Value.(*transaction.NotaryAssisted) - needNetworkFee += (int64(na.NKeys) + 1) * transaction.NotaryServiceFeePerKey - } - } - netFee := t.NetworkFee - needNetworkFee - if netFee < 0 { - return fmt.Errorf("%w: net fee is %v, need %v", ErrTxSmallNetworkFee, t.NetworkFee, needNetworkFee) - } // check that current tx wasn't included in the conflicts attributes of some other transaction which is already in the chain if err := bc.dao.HasTransaction(t.Hash()); err != nil { switch { @@ -2129,15 +2117,10 @@ func (bc *Blockchain) VerifyWitness(h util.Uint160, c hash.Hashable, w *transact // verifyHashAgainstScript verifies given hash against the given witness and returns the amount of GAS consumed. func (bc *Blockchain) verifyHashAgainstScript(hash util.Uint160, witness *transaction.Witness, interopCtx *interop.Context, gas int64) (int64, error) { - gasPolicy := bc.contracts.Policy.GetMaxVerificationGas(interopCtx.DAO) - if gas > gasPolicy { - gas = gasPolicy - } - vm := interopCtx.SpawnVM() vm.SetPriceGetter(interopCtx.GetPrice) vm.LoadToken = contract.LoadToken(interopCtx) - vm.GasLimit = gas + vm.GasLimit = -1 if err := bc.InitVerificationVM(vm, interopCtx.GetContract, hash, witness); err != nil { return 0, err } @@ -2172,21 +2155,12 @@ func (bc *Blockchain) verifyHashAgainstScript(hash util.Uint160, witness *transa // Golang implementation of VerifyWitnesses method in C# (https://github.com/neo-project/neo/blob/master/neo/SmartContract/Helper.cs#L87). func (bc *Blockchain) verifyTxWitnesses(t *transaction.Transaction, block *block.Block, isPartialTx bool) error { interopCtx := bc.newInteropContext(trigger.Verification, bc.dao, block, t) - gasLimit := t.NetworkFee - int64(t.Size())*bc.FeePerByte() - if bc.P2PSigExtensionsEnabled() { - attrs := t.GetAttributes(transaction.NotaryAssistedT) - if len(attrs) != 0 { - na := attrs[0].Value.(*transaction.NotaryAssisted) - gasLimit -= (int64(na.NKeys) + 1) * transaction.NotaryServiceFeePerKey - } - } for i := range t.Signers { - gasConsumed, err := bc.verifyHashAgainstScript(t.Signers[i].Account, &t.Scripts[i], interopCtx, gasLimit) + _, err := bc.verifyHashAgainstScript(t.Signers[i].Account, &t.Scripts[i], interopCtx, -1) if err != nil && !(i == 0 && isPartialTx && errors.Is(err, ErrInvalidSignature)) { // it's OK for partially-filled transaction with dummy first witness. return fmt.Errorf("witness #%d: %w", i, err) } - gasLimit -= gasConsumed } return nil diff --git a/pkg/core/fee/calculate.go b/pkg/core/fee/calculate.go index 4942f3f89..4ed92f40c 100644 --- a/pkg/core/fee/calculate.go +++ b/pkg/core/fee/calculate.go @@ -12,23 +12,16 @@ const ECDSAVerifyPrice = 1 << 15 // Calculate returns network fee for transaction. func Calculate(base int64, script []byte) (int64, int) { - var ( - netFee int64 - size int - ) + var size int if vm.IsSignatureContract(script) { size += 67 + io.GetVarSize(script) - netFee += Opcode(base, opcode.PUSHDATA1, opcode.PUSHDATA1) + base*ECDSAVerifyPrice - } else if m, pubs, ok := vm.ParseMultiSigContract(script); ok { - n := len(pubs) + } else if m, _, ok := vm.ParseMultiSigContract(script); ok { sizeInv := 66 * m size += io.GetVarSize(sizeInv) + sizeInv + io.GetVarSize(script) - netFee += calculateMultisig(base, m) + calculateMultisig(base, n) - netFee += base * ECDSAVerifyPrice * int64(n) } /*else { // We can support more contract types in the future. }*/ - return netFee, size + return 0, size } func calculateMultisig(base int64, n int) int64 { diff --git a/pkg/core/interop/context.go b/pkg/core/interop/context.go index 908b8a6ac..632426ae5 100644 --- a/pkg/core/interop/context.go +++ b/pkg/core/interop/context.go @@ -29,7 +29,7 @@ import ( const ( // DefaultBaseExecFee specifies default multiplier for opcode and syscall prices. - DefaultBaseExecFee = 30 + DefaultBaseExecFee = 30 // TODO: still 30 in C#, but it's unused or multiplied by 0, so keep it as is. ) // Context represents context in which interops are executed. @@ -271,9 +271,6 @@ func (ic *Context) SyscallHandler(_ *vm.VM, id uint32) error { if !cf.Has(f.RequiredFlags) { return fmt.Errorf("missing call flags: %05b vs %05b", cf, f.RequiredFlags) } - if !ic.VM.AddGas(f.Price * ic.BaseExecFee()) { - return errors.New("insufficient amount of gas") - } return f.Func(ic) } diff --git a/pkg/core/interop/crypto/ecdsa.go b/pkg/core/interop/crypto/ecdsa.go index 668bda363..1358f8317 100644 --- a/pkg/core/interop/crypto/ecdsa.go +++ b/pkg/core/interop/crypto/ecdsa.go @@ -5,7 +5,6 @@ import ( "errors" "fmt" - "github.com/nspcc-dev/neo-go/pkg/core/fee" "github.com/nspcc-dev/neo-go/pkg/core/interop" "github.com/nspcc-dev/neo-go/pkg/crypto/hash" "github.com/nspcc-dev/neo-go/pkg/crypto/keys" @@ -20,9 +19,6 @@ func ECDSASecp256r1CheckMultisig(ic *interop.Context) error { if err != nil { return fmt.Errorf("wrong parameters: %w", err) } - if !ic.VM.AddGas(ic.BaseExecFee() * fee.ECDSAVerifyPrice * int64(len(pkeys))) { - return errors.New("gas limit exceeded") - } sigs, err := ic.VM.Estack().PopSigElements() if err != nil { return fmt.Errorf("wrong parameters: %w", err) diff --git a/pkg/core/interop_system.go b/pkg/core/interop_system.go index a56ef18cd..16fd82033 100644 --- a/pkg/core/interop_system.go +++ b/pkg/core/interop_system.go @@ -115,20 +115,6 @@ func putWithContext(ic *interop.Context, stc *StorageContext, key []byte, value if stc.ReadOnly { return errors.New("StorageContext is read only") } - si := ic.DAO.GetStorageItem(stc.ID, key) - sizeInc := len(value) - if si == nil { - sizeInc = len(key) + len(value) - } else if len(value) != 0 { - if len(value) <= len(si) { - sizeInc = (len(value)-1)/4 + 1 - } else if len(si) != 0 { - sizeInc = (len(si)-1)/4 + 1 + len(value) - len(si) - } - } - if !ic.VM.AddGas(int64(sizeInc) * ic.Chain.GetPolicer().GetStoragePrice()) { - return errGasLimitExceeded - } return ic.DAO.PutStorageItem(stc.ID, key, value) } diff --git a/pkg/core/native/interop.go b/pkg/core/native/interop.go index cf12a419b..08dd83f9e 100644 --- a/pkg/core/native/interop.go +++ b/pkg/core/native/interop.go @@ -41,11 +41,6 @@ func Call(ic *interop.Context) error { return fmt.Errorf("missing call flags for native %d `%s` operation call: %05b vs %05b", version, m.MD.Name, ic.VM.Context().GetCallFlags(), m.RequiredFlags) } - invokeFee := m.CPUFee*ic.Chain.GetPolicer().GetBaseExecFee() + - m.StorageFee*ic.Chain.GetPolicer().GetStoragePrice() - if !ic.VM.AddGas(invokeFee) { - return errors.New("gas limit exceeded") - } ctx := ic.VM.Context() args := make([]stackitem.Item, len(m.MD.Parameters)) for i := range args { diff --git a/pkg/core/native/management.go b/pkg/core/native/management.go index c66e9dc8d..5d33a1291 100644 --- a/pkg/core/native/management.go +++ b/pkg/core/native/management.go @@ -42,7 +42,7 @@ const ( prefixContract = 8 - defaultMinimumDeploymentFee = 10_00000000 + defaultMinimumDeploymentFee = 0 contractDeployNotificationName = "Deploy" contractUpdateNotificationName = "Update" contractDestroyNotificationName = "Destroy" @@ -195,16 +195,6 @@ func (m *Management) getNefAndManifestFromItems(ic *interop.Context, args []stac return nil, nil, fmt.Errorf("invalid manifest: %w", err) } - gas := ic.Chain.GetPolicer().GetStoragePrice() * int64(len(nefBytes)+len(manifestBytes)) - if isDeploy { - fee := m.GetMinimumDeploymentFee(ic.DAO) - if fee > gas { - gas = fee - } - } - if !ic.VM.AddGas(gas) { - return nil, nil, errGasLimitExceeded - } var resManifest *manifest.Manifest var resNef *nef.File if nefBytes != nil { diff --git a/pkg/core/native/native_gas.go b/pkg/core/native/native_gas.go index 2903e10f9..2b492dbfc 100644 --- a/pkg/core/native/native_gas.go +++ b/pkg/core/native/native_gas.go @@ -100,13 +100,6 @@ func (g *GAS) OnPersist(ic *interop.Context) error { absAmount := big.NewInt(tx.SystemFee + tx.NetworkFee) g.burn(ic, tx.Sender(), absAmount) } - validators := g.NEO.GetNextBlockValidatorsInternal() - primary := validators[ic.Block.PrimaryIndex].GetScriptHash() - var netFee int64 - for _, tx := range ic.Block.Transactions { - netFee += tx.NetworkFee - } - g.mint(ic, primary, big.NewInt(int64(netFee)), false) return nil } diff --git a/pkg/core/native/native_neo.go b/pkg/core/native/native_neo.go index 9df6e468b..4d6f1680d 100644 --- a/pkg/core/native/native_neo.go +++ b/pkg/core/native/native_neo.go @@ -313,11 +313,7 @@ func (n *NEO) OnPersist(ic *interop.Context) error { // PostPersist implements Contract interface. func (n *NEO) PostPersist(ic *interop.Context) error { gas := n.GetGASPerBlock(ic.DAO, ic.Block.Index) - pubs := n.GetCommitteeMembers() committeeSize := len(ic.Chain.GetConfig().StandbyCommittee) - index := int(ic.Block.Index) % committeeSize - committeeReward := new(big.Int).Mul(gas, big.NewInt(committeeRewardRatio)) - n.GAS.mint(ic, pubs[index].GetScriptHash(), committeeReward.Div(committeeReward, big.NewInt(100)), false) if ShouldUpdateCommittee(ic.Block.Index, ic.Chain) { var voterReward = big.NewInt(voterRewardRatio) @@ -437,21 +433,16 @@ func (n *NEO) distributeGas(ic *interop.Context, h util.Uint160, acc *state.NEOB if ic.Block == nil || ic.Block.Index == 0 || ic.Block.Index == acc.BalanceHeight { return nil } - gen, err := n.calculateBonus(ic.DAO, acc.VoteTo, &acc.Balance, acc.BalanceHeight, ic.Block.Index) - if err != nil { - return err - } acc.BalanceHeight = ic.Block.Index // Must store acc before GAS distribution to fix acc's BalanceHeight value in the storage for // further acc's queries from `onNEP17Payment` if so, see https://github.com/nspcc-dev/neo-go/pull/2181. key := makeAccountKey(h) - err = ic.DAO.PutStorageItem(n.ID, key, acc.Bytes()) + err := ic.DAO.PutStorageItem(n.ID, key, acc.Bytes()) if err != nil { return fmt.Errorf("failed to store acc before gas distribution: %w", err) } - n.GAS.mint(ic, h, gen, true) return nil } @@ -690,9 +681,6 @@ func (n *NEO) registerCandidate(ic *interop.Context, args []stackitem.Item) stac } else if !ok { return stackitem.NewBool(false) } - if !ic.VM.AddGas(n.getRegisterPriceInternal(ic.DAO)) { - panic("insufficient gas") - } err = n.RegisterCandidateInternal(ic, pub) return stackitem.NewBool(err == nil) } diff --git a/pkg/core/native/native_nep17.go b/pkg/core/native/native_nep17.go index ca5a5bc7d..5806b8394 100644 --- a/pkg/core/native/native_nep17.go +++ b/pkg/core/native/native_nep17.go @@ -74,7 +74,7 @@ func newNEP17Native(name string, id int32) *nep17TokenNative { append(transferParams, manifest.NewParameter("data", smartcontract.AnyType))..., ) md = newMethodAndPrice(n.Transfer, 1<<17, callflag.States|callflag.AllowCall|callflag.AllowNotify) - md.StorageFee = 50 + md.StorageFee = 0 n.AddMethod(md, desc) n.AddEvent("Transfer", transferParams...) @@ -311,7 +311,7 @@ func newDescriptor(name string, ret smartcontract.ParamType, ps ...manifest.Para func newMethodAndPrice(f interop.Method, cpuFee int64, flags callflag.CallFlag) *interop.MethodAndPrice { return &interop.MethodAndPrice{ Func: f, - CPUFee: cpuFee, + CPUFee: 0, RequiredFlags: flags, } } diff --git a/pkg/core/native/notary.go b/pkg/core/native/notary.go index 36d268a3e..53646d79e 100644 --- a/pkg/core/native/notary.go +++ b/pkg/core/native/notary.go @@ -154,13 +154,6 @@ func (n *Notary) OnPersist(ic *interop.Context) error { } } } - if nFees == 0 { - return nil - } - singleReward := calculateNotaryReward(nFees, len(notaries)) - for _, notary := range notaries { - n.GAS.mint(ic, notary.GetScriptHash(), singleReward, false) - } return nil } diff --git a/pkg/core/native/oracle.go b/pkg/core/native/oracle.go index c060a9739..ac0e1c8ae 100644 --- a/pkg/core/native/oracle.go +++ b/pkg/core/native/oracle.go @@ -156,9 +156,6 @@ func (o *Oracle) PostPersist(ic *interop.Context) error { o.requestPriceChanged.Store(false) } - var nodes keys.PublicKeys - var reward []big.Int - single := big.NewInt(p) var removedIDs []uint64 orc, _ := o.Module.Load().(services.Oracle) @@ -197,22 +194,6 @@ func (o *Oracle) PostPersist(ic *interop.Context) error { if err != nil { return err } - - if nodes == nil { - nodes, err = o.GetOracleNodes(ic.DAO) - if err != nil { - return err - } - reward = make([]big.Int, len(nodes)) - } - - if len(reward) > 0 { - index := resp.ID % uint64(len(nodes)) - reward[index].Add(&reward[index], single) - } - } - for i := range reward { - o.GAS.mint(ic, nodes[i].GetScriptHash(), &reward[i], false) } if len(removedIDs) != 0 && orc != nil { @@ -317,9 +298,6 @@ func (o *Oracle) request(ic *interop.Context, args []stackitem.Item) stackitem.I if err != nil { panic(err) } - if !ic.VM.AddGas(o.getPriceInternal(ic.DAO)) { - panic("insufficient gas") - } if err := o.RequestInternal(ic, url, filter, cb, userData, gas); err != nil { panic(err) } @@ -331,18 +309,14 @@ func (o *Oracle) RequestInternal(ic *interop.Context, url string, filter *string if len(url) > maxURLLength || (filter != nil && len(*filter) > maxFilterLength) || len(cb) > maxCallbackLength || !gas.IsInt64() { return ErrBigArgument } - if gas.Int64() < MinimumResponseGas { + if gas.Int64() < MinimumResponseGas { // TODO: this constraint is still in the C#, although we don't use this GAS return ErrLowResponseGas } if strings.HasPrefix(cb, "_") { return errors.New("disallowed callback method (starts with '_')") } - if !ic.VM.AddGas(gas.Int64()) { - return ErrNotEnoughGas - } callingHash := ic.VM.GetCallingScriptHash() - o.GAS.mint(ic, o.Hash, gas, false) si := ic.DAO.GetStorageItem(o.ID, prefixRequestID) itemID := bigint.FromBytes(si) id := itemID.Uint64() diff --git a/pkg/core/native/policy.go b/pkg/core/native/policy.go index e377f0447..0b6958b20 100644 --- a/pkg/core/native/policy.go +++ b/pkg/core/native/policy.go @@ -22,7 +22,7 @@ const ( policyContractID = -7 defaultExecFeeFactor = interop.DefaultBaseExecFee - defaultFeePerByte = 1000 + defaultFeePerByte = 1000 // TODO: it is still in the storage, but GetFeePerByte() returns 0 in C#. defaultMaxVerificationGas = 1_50000000 // DefaultStoragePrice is the price to pay for 1 byte of storage. DefaultStoragePrice = 100000 @@ -189,6 +189,7 @@ func (p *Policy) getFeePerByte(ic *interop.Context, _ []stackitem.Item) stackite // GetFeePerByteInternal returns required transaction's fee per byte. func (p *Policy) GetFeePerByteInternal(dao dao.DAO) int64 { + return 0 p.lock.RLock() defer p.lock.RUnlock() if p.isValid { @@ -267,6 +268,7 @@ func (p *Policy) getStoragePrice(ic *interop.Context, _ []stackitem.Item) stacki // GetStoragePriceInternal returns current execution fee factor. func (p *Policy) GetStoragePriceInternal(d dao.DAO) int64 { + // TODO: this method still returns non-zero value (unlike getFeePerByte) p.lock.RLock() defer p.lock.RUnlock() if p.isValid { diff --git a/pkg/core/native_policy_test.go b/pkg/core/native_policy_test.go index 5a041121c..5929752ff 100644 --- a/pkg/core/native_policy_test.go +++ b/pkg/core/native_policy_test.go @@ -89,7 +89,7 @@ func TestFeePerByte(t *testing.T) { require.Equal(t, 1000, int(n)) }) - testGetSet(t, chain, chain.contracts.Policy.Hash, "FeePerByte", 1000, 0, 100_000_000) + testGetSet(t, chain, chain.contracts.Policy.Hash, "FeePerByte", 0, 0, 100_000_000) } func TestExecFeeFactor(t *testing.T) { diff --git a/pkg/rpc/client/rpc.go b/pkg/rpc/client/rpc.go index b0a02824e..50ccdb381 100644 --- a/pkg/rpc/client/rpc.go +++ b/pkg/rpc/client/rpc.go @@ -872,7 +872,6 @@ func (c *Client) AddNetworkFee(tx *transaction.Transaction, extraFee int64, accs if r == 0 { return fmt.Errorf("signer #%d: `verify` returned `false`", i) } - tx.NetworkFee += res.GasConsumed size += io.GetVarSize([]byte{}) * 2 // both scripts are empty continue } @@ -884,15 +883,9 @@ func (c *Client) AddNetworkFee(tx *transaction.Transaction, extraFee int64, accs return fmt.Errorf("can't get `ExecFeeFactor`: %w", err) } } - netFee, sizeDelta := fee.Calculate(ef, accs[i].Contract.Script) - tx.NetworkFee += netFee + _, sizeDelta := fee.Calculate(ef, accs[i].Contract.Script) size += sizeDelta } - fee, err := c.GetFeePerByte() - if err != nil { - return err - } - tx.NetworkFee += int64(size)*fee + extraFee return nil } diff --git a/pkg/rpc/server/server.go b/pkg/rpc/server/server.go index ab9ac6ce1..c53ab6ce4 100644 --- a/pkg/rpc/server/server.go +++ b/pkg/rpc/server/server.go @@ -600,8 +600,7 @@ func (s *Server) calculateNetworkFee(reqParams request.Params) (interface{}, *re } size := len(hashablePart) + io.GetVarSize(len(tx.Signers)) var ( - ef int64 - netFee int64 + ef int64 ) for i, signer := range tx.Signers { var verificationScript []byte @@ -641,7 +640,6 @@ func (s *Server) calculateNetworkFee(reqParams request.Params) (interface{}, *re cause := errors.New("`verify` method returned `false` on stack") return 0, response.NewRPCError(verificationErr, cause.Error(), cause) } - netFee += res.GasConsumed size += io.GetVarSize([]byte{}) + // verification script is empty (contract-based witness) io.GetVarSize(tx.Scripts[i].InvocationScript) // invocation script might not be empty (args for `verify`) continue @@ -650,13 +648,10 @@ func (s *Server) calculateNetworkFee(reqParams request.Params) (interface{}, *re if ef == 0 { ef = s.chain.GetPolicer().GetBaseExecFee() } - fee, sizeDelta := fee.Calculate(ef, verificationScript) - netFee += fee + _, sizeDelta := fee.Calculate(ef, verificationScript) size += sizeDelta } - fee := s.chain.GetPolicer().FeePerByte() - netFee += int64(size) * fee - return result.NetworkFee{Value: netFee}, nil + return result.NetworkFee{Value: 0}, nil } // getApplicationLog returns the contract log based on the specified txid or blockid. diff --git a/pkg/services/oracle/response.go b/pkg/services/oracle/response.go index 6b5f9d541..d5d1f6307 100644 --- a/pkg/services/oracle/response.go +++ b/pkg/services/oracle/response.go @@ -119,7 +119,7 @@ func (o *Oracle) CreateResponseTx(gasForResponse int64, vub uint32, resp *transa tx.NetworkFee += netFee size += sizeDelta - currNetFee := tx.NetworkFee + int64(size)*o.Chain.FeePerByte() + currNetFee := tx.NetworkFee + int64(size)*o.Chain.FeePerByte() // TODO: this logic remains the same in C# if currNetFee > gasForResponse { attrSize := io.GetVarSize(tx.Attributes) resp.Code = transaction.InsufficientFunds diff --git a/pkg/vm/vm.go b/pkg/vm/vm.go index 943e781bf..b98d489f2 100644 --- a/pkg/vm/vm.go +++ b/pkg/vm/vm.go @@ -535,13 +535,6 @@ func (v *VM) execute(ctx *Context, op opcode.Opcode, parameter []byte) (err erro } }() - if v.getPrice != nil && ctx.ip < len(ctx.prog) { - v.gasConsumed += v.getPrice(op, parameter) - if v.GasLimit >= 0 && v.gasConsumed > v.GasLimit { - panic("gas limit is exceeded") - } - } - if op <= opcode.PUSHINT256 { v.estack.PushItem(stackitem.NewBigInteger(bigint.FromBytes(parameter))) return