diff --git a/contract/AElf.Contracts.Oracle/OracleContract.cs b/contract/AElf.Contracts.Oracle/OracleContract.cs index 67da7b14..eb889d99 100644 --- a/contract/AElf.Contracts.Oracle/OracleContract.cs +++ b/contract/AElf.Contracts.Oracle/OracleContract.cs @@ -86,7 +86,7 @@ public override Hash Query(QueryInput input) var callbackInfo = input.CallbackInfo ?? new CallbackInfo { ContractAddress = Context.Self, - MethodName = "NotSetCallbackInfo" + MethodName = NotSetCallbackInfo }; var queryRecord = new QueryRecord { @@ -120,6 +120,63 @@ public override Hash Query(QueryInput input) return queryId; } + public override Hash CreateQueryTask(CreateQueryTaskInput input) + { + // TODO: Pay tx fee to contract. + + var taskId = Context.TransactionId; + State.QueryTaskMap[taskId.ToHex()] = new QueryTask + { + Creator = Context.Sender, + CallbackInfo = input.CallbackInfo, + EachPayment = input.EachPayment, + SupposedQueryTimes = input.SupposedQueryTimes, + QueryInfo = input.QueryInfo, + EndTime = input.EndTime, + AggregatorContractAddress = input.AggregatorContractAddress + }; + return taskId; + } + + public override Empty CompleteQueryTask(CompleteQueryTaskInput input) + { + var queryTask = State.QueryTaskMap[input.TaskId.ToHex()]; + Assert(Context.Sender == queryTask.Creator, "No permission."); + + var designatedNodeList = GetActualDesignatedNodeList(input.DesignatedNodeList); + Assert(designatedNodeList.Value.Count >= State.MinimumOracleNodesCount.Value, + $"Invalid designated nodes count, should at least be {State.MinimumOracleNodesCount.Value}."); + + queryTask.DesignatedNodeList = input.DesignatedNodeList; + queryTask.AggregateThreshold = Math.Max(GetAggregateThreshold(designatedNodeList.Value.Count), + input.AggregateThreshold); + State.QueryTaskMap[input.TaskId.ToHex()] = queryTask; + return new Empty(); + } + + public override Hash TaskQuery(TaskQueryInput input) + { + var queryTask = State.QueryTaskMap[input.TaskId.ToHex()]; + if (queryTask == null) + { + throw new AssertionException("Query task not found."); + } + + Assert(Context.Sender == queryTask.Creator, "No permission."); + var queryInput = new QueryInput + { + Payment = queryTask.EachPayment, + AggregateThreshold = queryTask.AggregateThreshold, + AggregatorContractAddress = queryTask.AggregatorContractAddress, + CallbackInfo = queryTask.CallbackInfo, + DesignatedNodeList = queryTask.DesignatedNodeList, + QueryInfo = queryTask.QueryInfo, + Token = input.TaskId.ToHex() + }; + + return Query(queryInput); + } + private AddressList GetActualDesignatedNodeList(AddressList designatedNodeList) { if (designatedNodeList.Value.Count != 1) return designatedNodeList; @@ -172,12 +229,14 @@ public override Empty Commit(CommitInput input) var actualDesignatedNodeList = GetActualDesignatedNodeList(queryRecord.DesignatedNodeList); Assert(actualDesignatedNodeList.Value.Contains(Context.Sender), "Sender is not in designated node list."); - Assert(actualDesignatedNodeList.Value.Count >= State.MinimumOracleNodesCount.Value, "Invalid designated nodes count."); + Assert(actualDesignatedNodeList.Value.Count >= State.MinimumOracleNodesCount.Value, + "Invalid designated nodes count."); var updatedResponseCount = State.ResponseCount[input.QueryId].Add(1); State.CommitmentMap[input.QueryId][Context.Sender] = input.Commitment; - if (updatedResponseCount >= GetRevealThreshold(actualDesignatedNodeList.Value.Count, queryRecord.AggregateThreshold)) + if (updatedResponseCount >= + GetRevealThreshold(actualDesignatedNodeList.Value.Count, queryRecord.AggregateThreshold)) { // Move to next stage: Reveal queryRecord.IsSufficientCommitmentsCollected = true; @@ -230,7 +289,8 @@ public override Empty Reveal(RevealInput input) // Permission check. var actualDesignatedNodeList = GetActualDesignatedNodeList(queryRecord.DesignatedNodeList); - Assert(actualDesignatedNodeList.Value.Contains(Context.Sender), "Sender was removed from designated node list."); + Assert(actualDesignatedNodeList.Value.Contains(Context.Sender), + "Sender was removed from designated node list."); var dataHash = HashHelper.ComputeFrom(input.Data); @@ -275,7 +335,7 @@ public override Empty Reveal(RevealInput input) Assert(!helpfulNodeList.Value.Contains(Context.Sender), "Sender already revealed commitment."); helpfulNodeList.Value.Add(Context.Sender); State.HelpfulNodeListMap[input.QueryId] = helpfulNodeList; - + // Reorg helpful nodes list. helpfulNodeList = new AddressList { @@ -388,6 +448,14 @@ private void PayToNodesAndAggregateResults(QueryRecord queryRecord, AddressList OracleNodes = {queryRecord.DesignatedNodeList.Value} }); } + + // If this query is from a query task. + var maybeQueryTask = State.QueryTaskMap[queryRecord.Token]; + if (maybeQueryTask != null) + { + maybeQueryTask.ActualQueriedTimes = maybeQueryTask.ActualQueriedTimes.Add(1); + State.QueryTaskMap[queryRecord.Token] = maybeQueryTask; + } } public override Empty CancelQuery(Hash input) diff --git a/contract/AElf.Contracts.Oracle/OracleContractState.cs b/contract/AElf.Contracts.Oracle/OracleContractState.cs index 992e83a6..f1a6cd27 100644 --- a/contract/AElf.Contracts.Oracle/OracleContractState.cs +++ b/contract/AElf.Contracts.Oracle/OracleContractState.cs @@ -43,5 +43,7 @@ public partial class OracleContractState : ContractState public MappedState
LockedTokenFromAddressMap { get; set; } public BoolState IsChargeFee { get; set; } + + public MappedState