예제 #1
0
        public void SyncWithNode(CronAPI api)
        {
            var max = api.GetBlockHeight();

            var min = (uint)_blocks.Count;

            for (uint i = min; i <= max; i++)
            {
                var block = api.GetBlock(i);
                AddBlock(block);
            }
        }
예제 #2
0
        private static uint FindBlock(CronAPI api, uint timestamp, uint min, uint max)
        {
            var mid = (1 + max - min) / 2;

            do
            {
                var block     = api.GetBlock(mid);
                var blockTime = block.Date.ToTimestamp();

                if (blockTime == timestamp)
                {
                    return(block.Height);
                }
                else
                if (blockTime < timestamp)
                {
                    var next     = api.GetBlock(mid + 1);
                    var nextTime = next.Date.ToTimestamp();
                    if (nextTime == timestamp)
                    {
                        return(next.Height);
                    }
                    else
                    if (nextTime > timestamp)
                    {
                        return(block.Height);
                    }
                    else
                    {
                        return(FindBlock(api, timestamp, mid + 1, max));
                    }
                }
                else
                {
                    return(FindBlock(api, timestamp, min, mid - 1));
                }
            } while (true);
        }
예제 #3
0
        public Snapshot(UInt160 scriptHash, CronAPI api, uint startBlock, uint endBlock = 0)
        {
            if (endBlock == 0)
            {
                endBlock = api.GetBlockHeight();
            }

            if (endBlock < startBlock)
            {
                throw new ArgumentException("End block cannot be smaller than start block");
            }

            for (uint height = startBlock; height <= endBlock; height++)
            {
                var block = api.GetBlock(height);

                var snapCount = 0;

                foreach (var tx in block.transactions)
                {
                    switch (tx.type)
                    {
                    case TransactionType.ContractTransaction:
                    {
                        foreach (var output in tx.outputs)
                        {
                            if (output.scriptHash == scriptHash)
                            {
                                MergeTransaction(api, tx);
                                snapCount++;
                                break;
                            }
                        }

                        break;
                    }

                    case TransactionType.InvocationTransaction:
                    {
                        List <AVMInstruction> ops;
                        try
                        {
                            ops = CronTools.Disassemble(tx.script);
                        }
                        catch
                        {
                            continue;
                        }

                        for (int i = 0; i < ops.Count; i++)
                        {
                            var op = ops[i];

                            if (op.opcode == OpCode.APPCALL && op.data != null && op.data.Length == 20)
                            {
                                var otherScriptHash = new UInt160(op.data);

                                if (otherScriptHash == scriptHash)
                                {
                                    MergeTransaction(api, tx);
                                    snapCount++;
                                    break;
                                }
                            }
                        }

                        break;
                    }
                    }
                }

                if (snapCount > 0)
                {
                    blocks[block.Hash] = block;
                }
            }
        }