コード例 #1
0
        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);
        }
コード例 #2
0
        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);
        }
コード例 #3
0
        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);
                }
            }
        }
コード例 #4
0
        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);
                }
            }
        }