Skip to content

Commit

Permalink
SmartContract/Native: implement adjustable opcode pricing
Browse files Browse the repository at this point in the history
This defines a new Policy contract setting, BaseExecFee which contains a price
of basic VM execution unit --- NOP instruction. It then redefines all opcode
prices as coefficients applied to that base fee.

The following invariants hold for this:
 * transaction fees are expressed in GAS
 * BaseExecFee is expressed in GAS
 * opcode price is a coefficient now
 * syscall price is expressed in GAS
 * ApplicationEngine.AddGas() also accepts GAS values, so it's a caller's
   responsibility to calculate that in whatever fashion he likes.

Caveats:
 * while coefficients are based on table from neo-project#1875 (which is built on
   instruction execution time relations for two complete VM implementations),
   some modifications were applied:
   - it's impossible for SYSCALL to have non-0 cost now (tests just hang)
   - all slot operations have the same price
 * block and consensus payloads are adjusted to use BaseExecFee, but probably
   ECDsaVerifyPrice is still a constant
 * it's not really tested other than unit tests

In general, this allows to define any execution cost in NOPs and then use
BaseExecFee to get the price. The same principle could be applied to storage
pricing based on FeePerByte (StoragePrice could just be `100 * FeePerByte`),
but that's a bit different topic.

Closes neo-project#1875.
  • Loading branch information
roman-khimov committed Nov 3, 2020
1 parent 1d4db2c commit 20d5d4e
Show file tree
Hide file tree
Showing 8 changed files with 229 additions and 201 deletions.
5 changes: 4 additions & 1 deletion src/neo/Ledger/MemoryPool.cs
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,7 @@ public class MemoryPool : IReadOnlyCollection<Transaction>

private int _maxTxPerBlock;
private long _feePerByte;
private uint _baseExecFee;

/// <summary>
/// Total maximum capacity of transactions the pool can hold.
Expand Down Expand Up @@ -109,8 +110,10 @@ internal bool LoadPolicy(StoreView snapshot)
{
_maxTxPerBlock = (int)NativeContract.Policy.GetMaxTransactionsPerBlock(snapshot);
long newFeePerByte = NativeContract.Policy.GetFeePerByte(snapshot);
bool policyChanged = newFeePerByte > _feePerByte;
uint newBaseExecFee = NativeContract.Policy.GetBaseExecFee(snapshot);
bool policyChanged = newFeePerByte > _feePerByte || newBaseExecFee > _baseExecFee;
_feePerByte = newFeePerByte;
_baseExecFee = newBaseExecFee;
return policyChanged;
}

Expand Down
3 changes: 2 additions & 1 deletion src/neo/Network/P2P/Payloads/BlockBase.cs
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
using Neo.IO.Json;
using Neo.Persistence;
using Neo.SmartContract;
using Neo.SmartContract.Native;
using Neo.Wallets;
using System;
using System.IO;
Expand Down Expand Up @@ -118,7 +119,7 @@ public virtual bool Verify(StoreView snapshot)
if (prev_header == null) return false;
if (prev_header.Index + 1 != Index) return false;
if (prev_header.Timestamp >= Timestamp) return false;
if (!this.VerifyWitnesses(snapshot, 1_00000000)) return false;
if (!this.VerifyWitnesses(snapshot, 3000000 * NativeContract.Policy.GetBaseExecFee(snapshot))) return false;
return true;
}
}
Expand Down
2 changes: 1 addition & 1 deletion src/neo/Network/P2P/Payloads/ConsensusPayload.cs
Original file line number Diff line number Diff line change
Expand Up @@ -124,7 +124,7 @@ public bool Verify(StoreView snapshot)
{
if (BlockIndex <= snapshot.Height)
return false;
return this.VerifyWitnesses(snapshot, 0_02000000);
return this.VerifyWitnesses(snapshot, 60000 * NativeContract.Policy.GetBaseExecFee(snapshot));
}
}
}
Loading

0 comments on commit 20d5d4e

Please sign in to comment.