Skip to content

Commit

Permalink
Add PostPersist()
Browse files Browse the repository at this point in the history
  • Loading branch information
erikzhang committed Jul 6, 2020
1 parent b2a2b52 commit f8d3362
Show file tree
Hide file tree
Showing 3 changed files with 52 additions and 19 deletions.
40 changes: 27 additions & 13 deletions src/neo/Ledger/Blockchain.cs
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,7 @@ public class RelayResult { public IInventory Inventory; public VerifyResult Resu
Transactions = new[] { DeployNativeContracts() }
};

private readonly static Script onPersistNativeContractScript;
private readonly static Script onPersistScript, postPersistScript;
private const int MaxTxToReverifyPerIdle = 10;
private static readonly object lockObj = new object();
private readonly NeoSystem system;
Expand Down Expand Up @@ -87,16 +87,23 @@ static Blockchain()
{
GenesisBlock.RebuildMerkleRoot();

NativeContract[] contracts = { NativeContract.GAS, NativeContract.NEO };
using (ScriptBuilder sb = new ScriptBuilder())
{
foreach (NativeContract contract in contracts)
foreach (NativeContract contract in new NativeContract[] { NativeContract.GAS, NativeContract.NEO })
{
sb.EmitAppCall(contract.Hash, "onPersist");
sb.Emit(OpCode.DROP);
}

onPersistNativeContractScript = sb.ToArray();
onPersistScript = sb.ToArray();
}
using (ScriptBuilder sb = new ScriptBuilder())
{
foreach (NativeContract contract in new NativeContract[] { NativeContract.Oracle })
{
sb.EmitAppCall(contract.Hash, "postPersist");
sb.Emit(OpCode.DROP);
}
postPersistScript = sb.ToArray();
}
}

Expand Down Expand Up @@ -404,14 +411,12 @@ private void Persist(Block block)
snapshot.PersistingBlock = block;
if (block.Index > 0)
{
using (ApplicationEngine engine = new ApplicationEngine(TriggerType.System, null, snapshot, 0, true))
{
engine.LoadScript(onPersistNativeContractScript);
if (engine.Execute() != VMState.HALT) throw new InvalidOperationException();
ApplicationExecuted application_executed = new ApplicationExecuted(engine);
Context.System.EventStream.Publish(application_executed);
all_application_executed.Add(application_executed);
}
using ApplicationEngine engine = new ApplicationEngine(TriggerType.System, null, snapshot, 0, true);
engine.LoadScript(onPersistScript);
if (engine.Execute() != VMState.HALT) throw new InvalidOperationException();
ApplicationExecuted application_executed = new ApplicationExecuted(engine);
Context.System.EventStream.Publish(application_executed);
all_application_executed.Add(application_executed);
}
snapshot.Blocks.Add(block.Hash, block.Trim());
StoreView clonedSnapshot = snapshot.Clone();
Expand Down Expand Up @@ -445,6 +450,15 @@ private void Persist(Block block)
}
}
snapshot.BlockHashIndex.GetAndChange().Set(block);
if (block.Index > 0)
{
using ApplicationEngine engine = new ApplicationEngine(TriggerType.System, null, snapshot, 0, true);
engine.LoadScript(postPersistScript);
if (engine.Execute() != VMState.HALT) throw new InvalidOperationException();
ApplicationExecuted application_executed = new ApplicationExecuted(engine);
Context.System.EventStream.Publish(application_executed);
all_application_executed.Add(application_executed);
}
foreach (IPersistencePlugin plugin in Plugin.PersistencePlugins)
plugin.OnPersist(snapshot, all_application_executed);
snapshot.Commit();
Expand Down
7 changes: 7 additions & 0 deletions src/neo/SmartContract/Native/NativeContract.cs
Original file line number Diff line number Diff line change
Expand Up @@ -143,6 +143,13 @@ protected virtual void OnPersist(ApplicationEngine engine)
throw new InvalidOperationException();
}

[ContractMethod(0, CallFlags.AllowModifyStates)]
protected virtual void PostPersist(ApplicationEngine engine)
{
if (engine.Trigger != TriggerType.System)
throw new InvalidOperationException();
}

public ApplicationEngine TestCall(string operation, params object[] args)
{
using (ScriptBuilder sb = new ScriptBuilder())
Expand Down
24 changes: 18 additions & 6 deletions src/neo/SmartContract/Native/Oracle/OracleContract.cs
Original file line number Diff line number Diff line change
Expand Up @@ -42,12 +42,6 @@ private void Finish(ApplicationEngine engine)
OracleResponse response = tx.Attributes.OfType<OracleResponse>().First();
StorageKey key = CreateStorageKey(Prefix_Request).Add(response.Id);
OracleRequest request = engine.Snapshot.Storages[key].GetInteroperable<OracleRequest>();
engine.Snapshot.Storages.Delete(key);
key = CreateStorageKey(Prefix_IdList).Add(GetUrlHash(request.Url));
IdList list = engine.Snapshot.Storages.GetAndChange(key).GetInteroperable<IdList>();
if (!list.Remove(response.Id)) throw new InvalidOperationException();
if (list.Count == 0) engine.Snapshot.Storages.Delete(key);
MintGasForOracleNode(engine, response.Id);
StackItem userData = BinarySerializer.Deserialize(request.UserData, engine.MaxStackSize, engine.MaxItemSize, engine.ReferenceCounter);
engine.CallFromNativeContract(null, request.CallbackContract, request.CallbackMethod, request.Url, userData, response.Success, response.Result);
}
Expand Down Expand Up @@ -95,6 +89,24 @@ private void MintGasForOracleNode(ApplicationEngine engine, ulong id)
GAS.Mint(engine, account, OracleRequestPrice);
}

protected override void PostPersist(ApplicationEngine engine)
{
base.PostPersist(engine);
foreach (Transaction tx in engine.Snapshot.PersistingBlock.Transactions)
{
OracleResponse response = tx.Attributes.OfType<OracleResponse>().FirstOrDefault();
if (response is null) continue;
StorageKey key = CreateStorageKey(Prefix_Request).Add(response.Id);
OracleRequest request = engine.Snapshot.Storages[key].GetInteroperable<OracleRequest>();
engine.Snapshot.Storages.Delete(key);
key = CreateStorageKey(Prefix_IdList).Add(GetUrlHash(request.Url));
IdList list = engine.Snapshot.Storages.GetAndChange(key).GetInteroperable<IdList>();
if (!list.Remove(response.Id)) throw new InvalidOperationException();
if (list.Count == 0) engine.Snapshot.Storages.Delete(key);
MintGasForOracleNode(engine, response.Id);
}
}

[ContractMethod(OracleRequestPrice, CallFlags.AllowModifyStates)]
private void Request(ApplicationEngine engine, string url, string filter, string callback, StackItem userData)
{
Expand Down

0 comments on commit f8d3362

Please sign in to comment.