public ChainTask GetTask(StorageContext storage, BigInteger taskID) { var taskKey = GetTaskKey(taskID, "task_info"); var taskBytes = this.Storage.Get(taskKey); var task = ChainTask.FromBytes(taskID, taskBytes); return(task); }
public ITask StartTask(StorageContext storage, Address from, string contractName, ContractMethod method, int frequency, TaskFrequencyMode mode, BigInteger gasLimit) { if (!IsContractDeployed(storage, contractName)) { return(null); } var taskID = GenerateUID(storage); var task = new ChainTask(taskID, from, contractName, method.name, (uint)frequency, mode, gasLimit, true); var taskKey = GetTaskKey(taskID, "task_info"); var taskBytes = task.ToByteArray(); this.Storage.Put(taskKey, taskBytes); var taskList = new StorageList(TaskListTag, this.Storage); taskList.Add <BigInteger>(taskID); return(task); }
private TaskResult ProcessPendingTask(Block block, OracleReader oracle, BigInteger minimumFee, StorageChangeSetContext changeSet, bool allowModify, ChainTask task, out Transaction transaction) { transaction = null; if (task.Mode != TaskFrequencyMode.Always) { var taskKey = GetTaskKey(task.ID, "task_run"); BigInteger lastRun = changeSet.Has(taskKey) ? changeSet.Get <BigInteger>(taskKey) : 0; switch (task.Mode) { case TaskFrequencyMode.Blocks: { var diff = block.Height - lastRun; if (diff < task.Frequency) { return(TaskResult.Skipped); // skip execution for now } break; } case TaskFrequencyMode.Time: { var diff = block.Timestamp.Value - lastRun; if (diff < task.Frequency) { return(TaskResult.Skipped); // skip execution for now } break; } } } using (var m = new ProfileMarker("ExecuteTask")) { var taskScript = new ScriptBuilder() .AllowGas(task.Owner, Address.Null, minimumFee, task.GasLimit) .CallContract(task.ContextName, task.Method) .SpendGas(task.Owner) .EndScript(); transaction = new Transaction(this.Nexus.Name, this.Name, taskScript, block.Timestamp.Value + 1, "TASK"); VMObject vmResult; if (ExecuteTransaction(-1, transaction, transaction.Script, block.Validator, block.Timestamp, changeSet, block.Notify, oracle, task, minimumFee, out vmResult, allowModify)) { // merge transaction oracle data oracle.MergeTxData(); var resultBytes = Serialization.Serialize(vmResult); block.SetResultForHash(transaction.Hash, resultBytes); var shouldStop = vmResult.AsBool(); return(shouldStop ? TaskResult.Halted : TaskResult.Running); } else { transaction = null; return(TaskResult.Crashed); } } }
private TaskResult ProcessPendingTask(Block block, OracleReader oracle, BigInteger minimumFee, StorageChangeSetContext changeSet, bool allowModify, ChainTask task, out Transaction transaction) { transaction = null; BigInteger currentRun = GetTaskTimeFromBlock(task.Mode, block); var taskKey = GetTaskKey(task.ID, "task_run"); if (task.Mode != TaskFrequencyMode.Always) { bool isFirstRun = !changeSet.Has(taskKey); if (isFirstRun) { var taskBlockHash = GetBlockHashAtHeight(task.Height); var taskBlock = GetBlockByHash(taskBlockHash); BigInteger firstRun = GetTaskTimeFromBlock(task.Mode, taskBlock) + task.Delay; if (currentRun < firstRun) { return(TaskResult.Skipped); // skip execution for now } } else { BigInteger lastRun = isFirstRun ? changeSet.Get <BigInteger>(taskKey) : 0; var diff = currentRun - lastRun; if (diff < task.Frequency) { return(TaskResult.Skipped); // skip execution for now } } } else { currentRun = 0; } using (var m = new ProfileMarker("ExecuteTask")) { var taskScript = new ScriptBuilder() .AllowGas(task.Owner, Address.Null, minimumFee, task.GasLimit) .CallContract(task.ContextName, task.Method) .SpendGas(task.Owner) .EndScript(); transaction = new Transaction(this.Nexus.Name, this.Name, taskScript, block.Timestamp.Value + 1, "TASK"); VMObject vmResult; if (ExecuteTransaction(-1, transaction, transaction.Script, block.Validator, block.Timestamp, changeSet, block.Notify, oracle, task, minimumFee, out vmResult, allowModify)) { var resultBytes = Serialization.Serialize(vmResult); block.SetResultForHash(transaction.Hash, resultBytes); // update last_run value in storage if (currentRun > 0) { changeSet.Put <BigInteger>(taskKey, currentRun); } var shouldStop = vmResult.AsBool(); return(shouldStop ? TaskResult.Halted : TaskResult.Running); } else { transaction = null; return(TaskResult.Crashed); } } }