Skip to content

Commit

Permalink
Remove PersistingBlock from snapshot (neo-project#2209)
Browse files Browse the repository at this point in the history
  • Loading branch information
erikzhang authored and cloud8little committed Jan 24, 2021
1 parent 5b4abe2 commit 56691dc
Show file tree
Hide file tree
Showing 30 changed files with 218 additions and 252 deletions.
7 changes: 3 additions & 4 deletions src/neo/Ledger/Blockchain.cs
Original file line number Diff line number Diff line change
Expand Up @@ -397,8 +397,7 @@ private void Persist(Block block)
snapshot.HeaderHashIndex.GetAndChange().Set(block);
}
List<ApplicationExecuted> all_application_executed = new List<ApplicationExecuted>();
snapshot.PersistingBlock = block;
using (ApplicationEngine engine = ApplicationEngine.Create(TriggerType.OnPersist, null, snapshot))
using (ApplicationEngine engine = ApplicationEngine.Create(TriggerType.OnPersist, null, snapshot, block))
{
engine.LoadScript(onPersistScript);
if (engine.Execute() != VMState.HALT) throw new InvalidOperationException();
Expand All @@ -420,7 +419,7 @@ private void Persist(Block block)
clonedSnapshot.Transactions.Add(tx.Hash, state);
clonedSnapshot.Transactions.Commit();

using (ApplicationEngine engine = ApplicationEngine.Create(TriggerType.Application, tx, clonedSnapshot, tx.SystemFee))
using (ApplicationEngine engine = ApplicationEngine.Create(TriggerType.Application, tx, clonedSnapshot, block, tx.SystemFee))
{
engine.LoadScript(tx.Script);
state.VMState = engine.Execute();
Expand All @@ -438,7 +437,7 @@ private void Persist(Block block)
}
}
snapshot.BlockHashIndex.GetAndChange().Set(block);
using (ApplicationEngine engine = ApplicationEngine.Create(TriggerType.PostPersist, null, snapshot))
using (ApplicationEngine engine = ApplicationEngine.Create(TriggerType.PostPersist, null, snapshot, block))
{
engine.LoadScript(postPersistScript);
if (engine.Execute() != VMState.HALT) throw new InvalidOperationException();
Expand Down
2 changes: 1 addition & 1 deletion src/neo/Network/P2P/Payloads/ExtensiblePayload.cs
Original file line number Diff line number Diff line change
Expand Up @@ -91,7 +91,7 @@ void IVerifiable.SerializeUnsigned(BinaryWriter writer)

public bool Verify(StoreView snapshot)
{
if (snapshot.PersistingBlock.Index < ValidBlockStart || snapshot.PersistingBlock.Index > ValidBlockEnd) return false;
if (snapshot.Height < ValidBlockStart || snapshot.Height >= ValidBlockEnd) return false;
if (!Blockchain.Singleton.IsExtensibleWitnessWhiteListed(Sender)) return false;
return this.VerifyWitnesses(snapshot, 0_02000000);
}
Expand Down
1 change: 0 additions & 1 deletion src/neo/Persistence/ClonedView.cs
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,6 @@ internal class ClonedView : StoreView

public ClonedView(StoreView view)
{
this.PersistingBlock = view.PersistingBlock;
this.Blocks = view.Blocks.CreateSnapshot();
this.Transactions = view.Transactions.CreateSnapshot();
this.Storages = view.Storages.CreateSnapshot();
Expand Down
1 change: 0 additions & 1 deletion src/neo/Persistence/StoreView.cs
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,6 @@ namespace Neo.Persistence
/// </summary>
public abstract class StoreView
{
public Block PersistingBlock { get; internal set; }
public abstract DataCache<UInt256, TrimmedBlock> Blocks { get; }
public abstract DataCache<UInt256, TransactionState> Transactions { get; }
public abstract DataCache<StorageKey, StorageItem> Storages { get; }
Expand Down
2 changes: 1 addition & 1 deletion src/neo/Plugins/IApplicationEngineProvider.cs
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,6 @@ namespace Neo.Plugins
{
public interface IApplicationEngineProvider
{
ApplicationEngine Create(TriggerType trigger, IVerifiable container, StoreView snapshot, long gas);
ApplicationEngine Create(TriggerType trigger, IVerifiable container, StoreView snapshot, Block persistingBlock, long gas);
}
}
4 changes: 2 additions & 2 deletions src/neo/SmartContract/ApplicationEngine.Contract.cs
Original file line number Diff line number Diff line change
Expand Up @@ -132,7 +132,7 @@ protected internal void NativeOnPersist()
if (Trigger != TriggerType.OnPersist)
throw new InvalidOperationException();
foreach (NativeContract contract in NativeContract.Contracts)
if (contract.ActiveBlockIndex <= Snapshot.PersistingBlock.Index)
if (contract.ActiveBlockIndex <= PersistingBlock.Index)
contract.OnPersist(this);
}

Expand All @@ -141,7 +141,7 @@ protected internal void NativePostPersist()
if (Trigger != TriggerType.PostPersist)
throw new InvalidOperationException();
foreach (NativeContract contract in NativeContract.Contracts)
if (contract.ActiveBlockIndex <= Snapshot.PersistingBlock.Index)
if (contract.ActiveBlockIndex <= PersistingBlock.Index)
contract.PostPersist(this);
}
}
Expand Down
2 changes: 1 addition & 1 deletion src/neo/SmartContract/ApplicationEngine.Runtime.cs
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@ protected internal string GetPlatform()

protected internal ulong GetTime()
{
return Snapshot.PersistingBlock.Timestamp;
return PersistingBlock.Timestamp;
}

protected internal IInteroperable GetScriptContainer()
Expand Down
13 changes: 7 additions & 6 deletions src/neo/SmartContract/ApplicationEngine.cs
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,7 @@ public partial class ApplicationEngine : ExecutionEngine
public TriggerType Trigger { get; }
public IVerifiable ScriptContainer { get; }
public StoreView Snapshot { get; }
public Block PersistingBlock { get; }
public long GasConsumed { get; private set; } = 0;
public long GasLeft => gas_amount - GasConsumed;
public Exception FaultException { get; private set; }
Expand All @@ -51,11 +52,12 @@ public partial class ApplicationEngine : ExecutionEngine
public UInt160 EntryScriptHash => EntryContext?.GetScriptHash();
public IReadOnlyList<NotifyEventArgs> Notifications => notifications ?? (IReadOnlyList<NotifyEventArgs>)Array.Empty<NotifyEventArgs>();

protected ApplicationEngine(TriggerType trigger, IVerifiable container, StoreView snapshot, long gas)
protected ApplicationEngine(TriggerType trigger, IVerifiable container, StoreView snapshot, Block persistingBlock, long gas)
{
this.Trigger = trigger;
this.ScriptContainer = container;
this.Snapshot = snapshot;
this.PersistingBlock = persistingBlock;
this.gas_amount = gas;
this.exec_fee_factor = snapshot is null ? PolicyContract.DefaultExecFeeFactor : NativeContract.Policy.GetExecFeeFactor(Snapshot);
this.StoragePrice = snapshot is null ? PolicyContract.DefaultStoragePrice : NativeContract.Policy.GetStoragePrice(Snapshot);
Expand Down Expand Up @@ -91,10 +93,10 @@ internal T CallFromNativeContract<T>(UInt160 callingScriptHash, UInt160 hash, st
return (T)Convert(Pop(), new InteropParameterDescriptor(typeof(T)));
}

public static ApplicationEngine Create(TriggerType trigger, IVerifiable container, StoreView snapshot, long gas = TestModeGas)
public static ApplicationEngine Create(TriggerType trigger, IVerifiable container, StoreView snapshot, Block persistingBlock = null, long gas = TestModeGas)
{
return applicationEngineProvider?.Create(trigger, container, snapshot, gas)
?? new ApplicationEngine(trigger, container, snapshot, gas);
return applicationEngineProvider?.Create(trigger, container, snapshot, persistingBlock, gas)
?? new ApplicationEngine(trigger, container, snapshot, persistingBlock, gas);
}

protected override void LoadContext(ExecutionContext context)
Expand Down Expand Up @@ -296,8 +298,7 @@ public static ApplicationEngine Run(byte[] script, StoreView snapshot = null, IV
disposable = Blockchain.Singleton.GetSnapshot();
snapshot = disposable;
}
snapshot.PersistingBlock = persistingBlock ?? snapshot.PersistingBlock ?? CreateDummyBlock(snapshot);
ApplicationEngine engine = Create(TriggerType.Application, container, snapshot, gas);
ApplicationEngine engine = Create(TriggerType.Application, container, snapshot, persistingBlock ?? CreateDummyBlock(snapshot), gas);
if (disposable != null) engine.Disposables.Add(disposable);
engine.LoadScript(script, initialPosition: offset);
engine.Execute();
Expand Down
2 changes: 1 addition & 1 deletion src/neo/SmartContract/Helper.cs
Original file line number Diff line number Diff line change
Expand Up @@ -178,7 +178,7 @@ public static bool VerifyWitnesses(this IVerifiable verifiable, StoreView snapsh
internal static bool VerifyWitness(this IVerifiable verifiable, StoreView snapshot, UInt160 hash, Witness witness, long gas, out long fee)
{
fee = 0;
using (ApplicationEngine engine = ApplicationEngine.Create(TriggerType.Verification, verifiable, snapshot?.Clone(), gas))
using (ApplicationEngine engine = ApplicationEngine.Create(TriggerType.Verification, verifiable, snapshot?.Clone(), null, gas))
{
CallFlags callFlags = !witness.VerificationScript.IsStandardContract() ? CallFlags.ReadStates : CallFlags.None;
byte[] verification = witness.VerificationScript;
Expand Down
2 changes: 1 addition & 1 deletion src/neo/SmartContract/Native/ContractManagement.cs
Original file line number Diff line number Diff line change
Expand Up @@ -82,7 +82,7 @@ internal override void OnPersist(ApplicationEngine engine)
{
foreach (NativeContract contract in Contracts)
{
if (contract.ActiveBlockIndex != engine.Snapshot.PersistingBlock.Index)
if (contract.ActiveBlockIndex != engine.PersistingBlock.Index)
continue;
engine.Snapshot.Storages.Add(CreateStorageKey(Prefix_Contract).Add(contract.Hash), new StorageItem(new ContractState
{
Expand Down
4 changes: 2 additions & 2 deletions src/neo/SmartContract/Native/GasToken.cs
Original file line number Diff line number Diff line change
Expand Up @@ -23,13 +23,13 @@ internal override void Initialize(ApplicationEngine engine)
internal override void OnPersist(ApplicationEngine engine)
{
long totalNetworkFee = 0;
foreach (Transaction tx in engine.Snapshot.PersistingBlock.Transactions)
foreach (Transaction tx in engine.PersistingBlock.Transactions)
{
Burn(engine, tx.Sender, tx.SystemFee + tx.NetworkFee);
totalNetworkFee += tx.NetworkFee;
}
ECPoint[] validators = NEO.GetNextBlockValidators(engine.Snapshot);
UInt160 primary = Contract.CreateSignatureRedeemScript(validators[engine.Snapshot.PersistingBlock.ConsensusData.PrimaryIndex]).ToScriptHash();
UInt160 primary = Contract.CreateSignatureRedeemScript(validators[engine.PersistingBlock.ConsensusData.PrimaryIndex]).ToScriptHash();
Mint(engine, primary, totalNetworkFee, false);
}
}
Expand Down
18 changes: 9 additions & 9 deletions src/neo/SmartContract/Native/NeoToken.cs
Original file line number Diff line number Diff line change
Expand Up @@ -59,10 +59,10 @@ protected override void OnBalanceChanging(ApplicationEngine engine, UInt160 acco
private void DistributeGas(ApplicationEngine engine, UInt160 account, NeoAccountState state)
{
// PersistingBlock is null when running under the debugger
if (engine.Snapshot.PersistingBlock == null) return;
if (engine.PersistingBlock is null) return;

BigInteger gas = CalculateBonus(engine.Snapshot, state.VoteTo, state.Balance, state.BalanceHeight, engine.Snapshot.PersistingBlock.Index);
state.BalanceHeight = engine.Snapshot.PersistingBlock.Index;
BigInteger gas = CalculateBonus(engine.Snapshot, state.VoteTo, state.Balance, state.BalanceHeight, engine.PersistingBlock.Index);
state.BalanceHeight = engine.PersistingBlock.Index;
GAS.Mint(engine, account, gas, true);
}

Expand Down Expand Up @@ -132,7 +132,7 @@ internal override void Initialize(ApplicationEngine engine)
internal override void OnPersist(ApplicationEngine engine)
{
// Set next committee
if (ShouldRefreshCommittee(engine.Snapshot.PersistingBlock.Index))
if (ShouldRefreshCommittee(engine.PersistingBlock.Index))
{
StorageItem storageItem = engine.Snapshot.Storages.GetAndChange(CreateStorageKey(Prefix_Committee));
var cachedCommittee = storageItem.GetInteroperable<CachedCommittee>();
Expand All @@ -147,7 +147,7 @@ internal override void PostPersist(ApplicationEngine engine)

int m = ProtocolSettings.Default.CommitteeMembersCount;
int n = ProtocolSettings.Default.ValidatorsCount;
int index = (int)(engine.Snapshot.PersistingBlock.Index % (uint)m);
int index = (int)(engine.PersistingBlock.Index % (uint)m);
var gasPerBlock = GetGasPerBlock(engine.Snapshot);
var committee = GetCommitteeFromCache(engine.Snapshot);
var pubkey = committee.ElementAt(index).PublicKey;
Expand All @@ -156,7 +156,7 @@ internal override void PostPersist(ApplicationEngine engine)

// Record the cumulative reward of the voters of committee

if (ShouldRefreshCommittee(engine.Snapshot.PersistingBlock.Index))
if (ShouldRefreshCommittee(engine.PersistingBlock.Index))
{
BigInteger voterRewardOfEachCommittee = gasPerBlock * VoterRewardRatio * 100000000L * m / (m + n) / 100; // Zoom in 100000000 times, and the final calculation should be divided 100000000L
for (index = 0; index < committee.Count; index++)
Expand All @@ -166,7 +166,7 @@ internal override void PostPersist(ApplicationEngine engine)
if (member.Votes > 0)
{
BigInteger voterSumRewardPerNEO = factor * voterRewardOfEachCommittee / member.Votes;
StorageKey voterRewardKey = CreateStorageKey(Prefix_VoterRewardPerCommittee).Add(member.PublicKey).AddBigEndian(engine.Snapshot.PersistingBlock.Index + 1);
StorageKey voterRewardKey = CreateStorageKey(Prefix_VoterRewardPerCommittee).Add(member.PublicKey).AddBigEndian(engine.PersistingBlock.Index + 1);
byte[] border = CreateStorageKey(Prefix_VoterRewardPerCommittee).Add(member.PublicKey).ToArray();
(_, var item) = engine.Snapshot.Storages.FindRange(voterRewardKey.ToArray(), border, SeekDirection.Backward).FirstOrDefault();
voterSumRewardPerNEO += (item ?? BigInteger.Zero);
Expand All @@ -183,7 +183,7 @@ private bool SetGasPerBlock(ApplicationEngine engine, BigInteger gasPerBlock)
throw new ArgumentOutOfRangeException(nameof(gasPerBlock));
if (!CheckCommittee(engine)) return false;

uint index = engine.Snapshot.PersistingBlock.Index + 1;
uint index = engine.PersistingBlock.Index + 1;
StorageItem entry = engine.Snapshot.Storages.GetAndChange(CreateStorageKey(Prefix_GasPerBlock).AddBigEndian(index), () => new StorageItem(gasPerBlock));
entry.Set(gasPerBlock);
return true;
Expand All @@ -192,7 +192,7 @@ private bool SetGasPerBlock(ApplicationEngine engine, BigInteger gasPerBlock)
[ContractMethod(0_01000000, CallFlags.ReadStates)]
public BigInteger GetGasPerBlock(StoreView snapshot)
{
return GetSortedGasRecords(snapshot, snapshot.PersistingBlock.Index).First().GasPerBlock;
return GetSortedGasRecords(snapshot, snapshot.Height + 1).First().GasPerBlock;
}

private IEnumerable<(uint Index, BigInteger GasPerBlock)> GetSortedGasRecords(StoreView snapshot, uint end)
Expand Down
4 changes: 2 additions & 2 deletions src/neo/SmartContract/Native/OracleContract.cs
Original file line number Diff line number Diff line change
Expand Up @@ -136,7 +136,7 @@ internal override void Initialize(ApplicationEngine engine)
internal override void PostPersist(ApplicationEngine engine)
{
(UInt160 Account, BigInteger GAS)[] nodes = null;
foreach (Transaction tx in engine.Snapshot.PersistingBlock.Transactions)
foreach (Transaction tx in engine.PersistingBlock.Transactions)
{
//Filter the response transactions
OracleResponse response = tx.GetAttribute<OracleResponse>();
Expand All @@ -155,7 +155,7 @@ internal override void PostPersist(ApplicationEngine engine)
if (list.Count == 0) engine.Snapshot.Storages.Delete(key);

//Mint GAS for oracle nodes
nodes ??= RoleManagement.GetDesignatedByRole(engine.Snapshot, Role.Oracle, engine.Snapshot.PersistingBlock.Index).Select(p => (Contract.CreateSignatureRedeemScript(p).ToScriptHash(), BigInteger.Zero)).ToArray();
nodes ??= RoleManagement.GetDesignatedByRole(engine.Snapshot, Role.Oracle, engine.PersistingBlock.Index).Select(p => (Contract.CreateSignatureRedeemScript(p).ToScriptHash(), BigInteger.Zero)).ToArray();
if (nodes.Length > 0)
{
int index = (int)(response.Id % (ulong)nodes.Length);
Expand Down
4 changes: 2 additions & 2 deletions src/neo/SmartContract/Native/RoleManagement.cs
Original file line number Diff line number Diff line change
Expand Up @@ -43,9 +43,9 @@ private void DesignateAsRole(ApplicationEngine engine, Role role, ECPoint[] node
throw new ArgumentOutOfRangeException(nameof(role));
if (!CheckCommittee(engine))
throw new InvalidOperationException(nameof(DesignateAsRole));
if (engine.Snapshot.PersistingBlock is null)
if (engine.PersistingBlock is null)
throw new InvalidOperationException(nameof(DesignateAsRole));
uint index = engine.Snapshot.PersistingBlock.Index + 1;
uint index = engine.PersistingBlock.Index + 1;
var key = CreateStorageKey((byte)role).AddBigEndian(index);
if (engine.Snapshot.Storages.Contains(key))
throw new InvalidOperationException();
Expand Down
8 changes: 4 additions & 4 deletions tests/neo.UnitTests/Extensions/NativeContractExtensions.cs
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ public static ContractState DeployContract(this StoreView snapshot, UInt160 send
script.EmitDynamicCall(NativeContract.ContractManagement.Hash, "deploy", true, nefFile, manifest);

var engine = ApplicationEngine.Create(TriggerType.Application,
sender != null ? new Transaction() { Signers = new Signer[] { new Signer() { Account = sender } } } : null, snapshot, gas);
sender != null ? new Transaction() { Signers = new Signer[] { new Signer() { Account = sender } } } : null, snapshot, null, gas);
engine.LoadScript(script.ToArray());

if (engine.Execute() != VMState.HALT)
Expand Down Expand Up @@ -91,12 +91,12 @@ public static void DeleteContract(this StoreView snapshot, UInt160 hash)

public static StackItem Call(this NativeContract contract, StoreView snapshot, string method, params ContractParameter[] args)
{
return Call(contract, snapshot, null, method, args);
return Call(contract, snapshot, null, null, method, args);
}

public static StackItem Call(this NativeContract contract, StoreView snapshot, IVerifiable container, string method, params ContractParameter[] args)
public static StackItem Call(this NativeContract contract, StoreView snapshot, IVerifiable container, Block persistingBlock, string method, params ContractParameter[] args)
{
var engine = ApplicationEngine.Create(TriggerType.Application, container, snapshot);
var engine = ApplicationEngine.Create(TriggerType.Application, container, snapshot, persistingBlock);
var contractState = NativeContract.ContractManagement.GetContract(snapshot, contract.Hash);
if (contractState == null) throw new InvalidOperationException();

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -35,10 +35,10 @@ public void Serialize(BinaryWriter writer) { }
public void SerializeUnsigned(BinaryWriter writer) { }
}

public static bool Transfer(this NativeContract contract, StoreView snapshot, byte[] from, byte[] to, BigInteger amount, bool signFrom)
public static bool Transfer(this NativeContract contract, StoreView snapshot, byte[] from, byte[] to, BigInteger amount, bool signFrom, Block persistingBlock)
{
var engine = ApplicationEngine.Create(TriggerType.Application,
new ManualWitness(signFrom ? new UInt160(from) : null), snapshot);
new ManualWitness(signFrom ? new UInt160(from) : null), snapshot, persistingBlock);

engine.LoadScript(contract.Script, pcount: 4, configureState: p => p.ScriptHash = contract.Hash);

Expand Down
Loading

0 comments on commit 56691dc

Please sign in to comment.