Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Oracle: Tx comunication #1540

Merged
merged 2 commits into from
Apr 6, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion src/neo/Oracle/OracleService.cs
Original file line number Diff line number Diff line change
Expand Up @@ -241,7 +241,7 @@ private void ProcessTransaction(Transaction tx)
/// <param name="oracle">Oracle</param>
/// <param name="requestTx">Request Hash</param>
/// <returns>Transaction</returns>
private Transaction CreateResponseTransaction(OracleExecutionCache oracle, Transaction requestTx)
public static Transaction CreateResponseTransaction(OracleExecutionCache oracle, Transaction requestTx)
{
using ScriptBuilder script = new ScriptBuilder();

Expand Down
20 changes: 15 additions & 5 deletions src/neo/SmartContract/InteropService.Oracle.cs
Original file line number Diff line number Diff line change
Expand Up @@ -22,15 +22,25 @@ private static bool Oracle_Get(ApplicationEngine engine)
{
if (engine.OracleCache == null)
{
// We should enter here only during OnPersist with the OracleRequestTx

if (engine.ScriptContainer is Transaction tx)
{
// Read Oracle Response, if exists
// Read Oracle Response

engine.OracleCache = NativeContract.Oracle.GetOracleResponse(engine.Snapshot, tx.Hash);
return engine.OracleCache == null;
}
engine.OracleCache = NativeContract.Oracle.ConsumeOracleResponse(engine.Snapshot, tx.Hash);

// If it doesn't exist, fault

return false;
if (engine.OracleCache == null)
{
return false;
}
}
else
{
return false;
}
}
if (!engine.TryPop(out string urlItem) || !Uri.TryCreate(urlItem, UriKind.Absolute, out var url)) return false;
if (!engine.TryPop(out StackItem filterContractItem)) return false;
Expand Down
27 changes: 17 additions & 10 deletions src/neo/SmartContract/Native/Oracle/OracleContract.cs
Original file line number Diff line number Diff line change
Expand Up @@ -48,34 +48,41 @@ internal override bool Initialize(ApplicationEngine engine)
}

/// <summary>
/// Oracle Response Only
/// Set Oracle Response Only
/// </summary>
[ContractMethod(0_03000000, ContractParameterType.Boolean, ParameterTypes = new[] { ContractParameterType.ByteArray, ContractParameterType.ByteArray }, ParameterNames = new[] { "transactionHash", "oracleResponse" })]
private StackItem SetOracleResponse(ApplicationEngine engine, Array args)
{
// TODO: Check witness oracle contract
if (args.Count != 2) return false;

UInt160 account = GetOracleMultiSigAddress(engine.Snapshot);
if (!InteropService.Runtime.CheckWitnessInternal(engine, account)) return false;

// This only can be called by the oracle's multi signature

var txHash = args[0].GetSpan().AsSerializable<UInt256>();
var response = args[1].GetSpan().AsSerializable<OracleExecutionCache>();

// TODO: Store or memory?

StorageItem storage = engine.Snapshot.Storages.GetAndChange(CreateStorageKey(Prefix_OracleResponse, txHash.ToArray()));
StorageItem storage = engine.Snapshot.Storages.GetAndChange(CreateStorageKey(Prefix_OracleResponse, txHash.ToArray()), () => new StorageItem());
storage.Value = IO.Helper.ToArray(response);

return false;
}

/// <summary>
/// Get Oracle Response
/// Consume Oracle Response
/// </summary>
/// <param name="snapshot">Snapshot</param>
/// <param name="txHash">Transaction Hash</param>
public OracleExecutionCache GetOracleResponse(StoreView snapshot, UInt256 txHash)
public OracleExecutionCache ConsumeOracleResponse(StoreView snapshot, UInt256 txHash)
{
StorageItem storage = snapshot.Storages.GetAndChange(CreateStorageKey(Prefix_OracleResponse, txHash.ToArray()));
return storage.Value.AsSerializable<OracleExecutionCache>();
StorageKey key = CreateStorageKey(Prefix_OracleResponse, txHash.ToArray());
StorageItem storage = snapshot.Storages.GetAndChange(key);
OracleExecutionCache ret = storage.Value.AsSerializable<OracleExecutionCache>();

// It should be cached by the ApplicationEngine so we can save space removing it

snapshot.Storages.Delete(key);
return ret;
}

/// <summary>
Expand Down