Ejemplo n.º 1
0
        public CacheContext(IStorageContext storageContext)
        {
            this._storageContext = storageContext;

            this._blockStorage = new BlockStorage(this);
            this._blockCache = new BlockCache
            (
                cacheContext: this,
                maxFlushMemorySize: 10.MILLION(),
                maxCacheMemorySize: 1.MILLION()
            );

            this._blockHeaderCache = new BlockHeaderCache
            (
                cacheContext: this,
                maxFlushMemorySize: 10.MILLION(),
                maxCacheMemorySize: 1.MILLION()
            );

            this._chainedBlockCache = new ChainedBlockCache
            (
                cacheContext: this,
                maxFlushMemorySize: 1.MILLION(),
                maxCacheMemorySize: 100.MILLION()
            );

            this._transactionCache = new TransactionCache
            (
                cacheContext: this,
                maxCacheMemorySize: 1.MILLION()
            );
        }
Ejemplo n.º 2
0
        public ChainingWorker(WorkerConfig workerConfig, Logger logger, IBlockchainRules rules, BlockHeaderCache blockHeaderCache, ChainedHeaderCache chainedHeaderCache, BlockCache blockCache)
            : base("ChainingWorker", workerConfig.initialNotify, workerConfig.minIdleTime, workerConfig.maxIdleTime, logger)
        {
            this.rules              = rules;
            this.blockHeaderCache   = blockHeaderCache;
            this.chainedHeaderCache = chainedHeaderCache;
            this.blockCache         = blockCache;

            this.blockHeaders        = new ConcurrentQueue <BlockHeader>();
            this.unchainedByPrevious = new Dictionary <UInt256, Dictionary <UInt256, BlockHeader> >();

            this.blockHeaderCache.OnAddition += ChainBlockHeader;
            this.blockCache.OnAddition       += ChainBlock;
        }
Ejemplo n.º 3
0
        public HeadersRequestWorker(Logger logger, WorkerConfig workerConfig, LocalClient localClient, CoreDaemon blockchainDaemon, BlockHeaderCache blockHeaderCache)
            : base("HeadersRequestWorker", workerConfig.initialNotify, workerConfig.minIdleTime, workerConfig.maxIdleTime, logger)
        {
            this.logger           = logger;
            this.localClient      = localClient;
            this.blockchainDaemon = blockchainDaemon;
            this.blockHeaderCache = blockHeaderCache;

            this.headersRequestsByPeer = new ConcurrentDictionary <IPEndPoint, DateTime>();

            this.localClient.OnBlockHeaders            += HandleBlockHeaders;
            this.blockchainDaemon.OnTargetChainChanged += HandleTargetChainChanged;

            this.flushWorker = new WorkerMethod("HeadersRequestWorker.FlushWorker", FlushWorkerMethod, initialNotify: true, minIdleTime: TimeSpan.Zero, maxIdleTime: TimeSpan.MaxValue, logger: this.logger);
            this.flushQueue  = new ConcurrentQueue <Tuple <RemoteNode, IImmutableList <BlockHeader> > >();
        }
Ejemplo n.º 4
0
        public LocalClient(Logger logger, RulesEnum type, IKernel kernel, IBlockchainRules rules, CoreDaemon blockchainDaemon, BlockHeaderCache blockHeaderCache, ChainedHeaderCache chainedHeaderCache, TransactionCache transactionCache, BlockCache blockCache, NetworkPeerCache networkPeerCache)
        {
            this.shutdownToken = new CancellationTokenSource();

            this.logger             = logger;
            this.type               = type;
            this.kernel             = kernel;
            this.rules              = rules;
            this.blockchainDaemon   = blockchainDaemon;
            this.blockHeaderCache   = blockHeaderCache;
            this.chainedHeaderCache = chainedHeaderCache;
            this.transactionCache   = transactionCache;
            this.blockCache         = blockCache;
            this.networkPeerCache   = networkPeerCache;

            this.messageRateMeasure = new RateMeasure();

            this.connectWorker        = new WorkerMethod("LocalClient.ConnectWorker", ConnectWorker, true, TimeSpan.FromSeconds(1), TimeSpan.FromSeconds(1), this.logger);
            this.headersRequestWorker = kernel.Get <HeadersRequestWorker>(
                new ConstructorArgument("workerConfig", new WorkerConfig(initialNotify: true, minIdleTime: TimeSpan.FromMilliseconds(50), maxIdleTime: TimeSpan.FromSeconds(30))),
                new ConstructorArgument("localClient", this));
            this.blockRequestWorker = kernel.Get <BlockRequestWorker>(
                new ConstructorArgument("workerConfig", new WorkerConfig(initialNotify: true, minIdleTime: TimeSpan.FromMilliseconds(50), maxIdleTime: TimeSpan.FromSeconds(30))),
                new ConstructorArgument("localClient", this));
            this.statsWorker = new WorkerMethod("LocalClient.StatsWorker", StatsWorker, true, TimeSpan.FromSeconds(1), TimeSpan.FromSeconds(30), this.logger);

            switch (this.Type)
            {
            case RulesEnum.MainNet:
                Messaging.Port  = 8333;
                Messaging.Magic = Messaging.MAGIC_MAIN;
                break;

            case RulesEnum.TestNet3:
                Messaging.Port  = 18333;
                Messaging.Magic = Messaging.MAGIC_TESTNET3;
                break;

            case RulesEnum.ComparisonToolTestNet:
                Messaging.Port  = 18444;
                Messaging.Magic = Messaging.MAGIC_COMPARISON_TOOL;
                break;
            }
        }
Ejemplo n.º 5
0
        public ChainStateBuilder(ChainBuilder chain, Utxo parentUtxo, Logger logger, IKernel kernel, IBlockchainRules rules, BlockHeaderCache blockHeaderCache, BlockCache blockCache, SpentTransactionsCache spentTransactionsCache, SpentOutputsCache spentOutputsCache)
        {
            this.logger                 = logger;
            this.sha256                 = new SHA256Managed();
            this.rules                  = rules;
            this.blockHeaderCache       = blockHeaderCache;
            this.blockCache             = blockCache;
            this.spentTransactionsCache = spentTransactionsCache;
            this.spentOutputsCache      = spentOutputsCache;

            this.chainStateMonitor = new ChainStateMonitor(this.logger);
            this.scriptValidator   = new ScriptValidator(this.logger, this.rules);
            this.chainStateMonitor.Subscribe(this.scriptValidator);

            this.chain = chain;
            this.chainStateBuilderStorage = kernel.Get <IChainStateBuilderStorage>(new ConstructorArgument("parentUtxo", parentUtxo.Storage));

            this.spentTransactions = ImmutableList.CreateBuilder <KeyValuePair <UInt256, SpentTx> >();
            this.spentOutputs      = ImmutableList.CreateBuilder <KeyValuePair <TxOutputKey, TxOutput> >();

            this.stats = new BuilderStats();
        }
Ejemplo n.º 6
0
        public Testnet3Rules(Logger logger, BlockHeaderCache blockHeaderCache)
            : base(logger, blockHeaderCache)
        {
            this._genesisBlock =
                new Block
                (
                    header: new BlockHeader
                    (
                        version: 1,
                        previousBlock: 0,
                        merkleRoot: UInt256.Parse("4a5e1e4baab89f3a32518a88c31bc87f618f76673e2cc77ab2127b7afdeda33b", NumberStyles.HexNumber),
                        time: 1296688602,
                        bits: 0x1D00FFFF,
                        nonce: 414098458
                    ),
                    transactions: ImmutableArray.Create
                    (
                        new Transaction
                        (
                            version: 1,
                            inputs: ImmutableArray.Create
                            (
                                new TxInput
                                (
                                    previousTxOutputKey: new TxOutputKey
                                    (
                                        txHash: 0,
                                        txOutputIndex: 0xFFFFFFFF
                                    ),
                                    scriptSignature: ImmutableArray.Create <byte>
                                    (
                                        0x04, 0xFF, 0xFF, 0x00, 0x1D, 0x01, 0x04, 0x45, 0x54, 0x68, 0x65, 0x20, 0x54, 0x69, 0x6D, 0x65,
                                        0x73, 0x20, 0x30, 0x33, 0x2F, 0x4A, 0x61, 0x6E, 0x2F, 0x32, 0x30, 0x30, 0x39, 0x20, 0x43, 0x68,
                                        0x61, 0x6E, 0x63, 0x65, 0x6C, 0x6C, 0x6F, 0x72, 0x20, 0x6F, 0x6E, 0x20, 0x62, 0x72, 0x69, 0x6E,
                                        0x6B, 0x20, 0x6F, 0x66, 0x20, 0x73, 0x65, 0x63, 0x6F, 0x6E, 0x64, 0x20, 0x62, 0x61, 0x69, 0x6C,
                                        0x6F, 0x75, 0x74, 0x20, 0x66, 0x6F, 0x72, 0x20, 0x62, 0x61, 0x6E, 0x6B, 0x73
                                    ),
                                    sequence: 0xFFFFFFFF
                                )
                            ),
                            outputs: ImmutableArray.Create
                            (
                                new TxOutput
                                (
                                    value: (UInt64)(50L * 100.MILLION()),
                                    scriptPublicKey: ImmutableArray.Create <byte>
                                    (
                                        0x41, 0x04, 0x67, 0x8A, 0xFD, 0xB0, 0xFE, 0x55, 0x48, 0x27, 0x19, 0x67, 0xF1, 0xA6, 0x71, 0x30,
                                        0xB7, 0x10, 0x5C, 0xD6, 0xA8, 0x28, 0xE0, 0x39, 0x09, 0xA6, 0x79, 0x62, 0xE0, 0xEA, 0x1F, 0x61,
                                        0xDE, 0xB6, 0x49, 0xF6, 0xBC, 0x3F, 0x4C, 0xEF, 0x38, 0xC4, 0xF3, 0x55, 0x04, 0xE5, 0x1E, 0xC1,
                                        0x12, 0xDE, 0x5C, 0x38, 0x4D, 0xF7, 0xBA, 0x0B, 0x8D, 0x57, 0x8A, 0x4C, 0x70, 0x2B, 0x6B, 0xF1,
                                        0x1D, 0x5F, 0xAC
                                    )
                                )
                            ),
                            lockTime: 0
                        )
                    )
                );

            Debug.Assert(_genesisBlock.Hash == UInt256.Parse("000000000933ea01ad0ee984209779baaec3ced90fa3f408719526f8d77f4943", NumberStyles.HexNumber));

            this._genesisChainedHeader = ChainedHeader.CreateForGenesisBlock(this._genesisBlock.Header);
        }
Ejemplo n.º 7
0
        public CoreDaemon(Logger logger, IKernel kernel, IBlockchainRules rules, BlockHeaderCache blockHeaderCache, ChainedHeaderCache chainedHeaderCache, BlockTxHashesCache blockTxHashesCache, TransactionCache transactionCache, BlockCache blockCache)
        {
            this.logger        = logger;
            this.shutdownToken = new CancellationTokenSource();

            this.kernel             = kernel;
            this.rules              = rules;
            this.blockHeaderCache   = blockHeaderCache;
            this.chainedHeaderCache = chainedHeaderCache;
            this.blockTxHashesCache = blockTxHashesCache;
            this.transactionCache   = transactionCache;
            this.blockCache         = blockCache;

            // write genesis block out to storage
            this.blockHeaderCache[this.rules.GenesisBlock.Hash]           = this.rules.GenesisBlock.Header;
            this.blockCache[this.rules.GenesisBlock.Hash]                 = this.rules.GenesisBlock;
            this.chainedHeaderCache[this.rules.GenesisChainedHeader.Hash] = this.rules.GenesisChainedHeader;

            // wire up cache events
            this.blockHeaderCache.OnAddition       += OnBlockHeaderAddition;
            this.blockHeaderCache.OnModification   += OnBlockHeaderModification;
            this.blockCache.OnAddition             += OnBlockAddition;
            this.blockCache.OnModification         += OnBlockModification;
            this.blockTxHashesCache.OnAddition     += OnBlockTxHashesAddition;
            this.blockTxHashesCache.OnModification += OnBlockTxHashesModification;
            this.chainedHeaderCache.OnAddition     += OnChainedHeaderAddition;
            this.chainedHeaderCache.OnModification += OnChainedHeaderModification;

            // create chain state builder
            this.chainStateBuilder =
                this.kernel.Get <ChainStateBuilder>(
                    new ConstructorArgument("chain", Chain.CreateForGenesisBlock(this.rules.GenesisChainedHeader).ToBuilder()),
                    new ConstructorArgument("parentUtxo", Utxo.CreateForGenesisBlock(this.rules.GenesisBlock.Hash)));

            this.chainStateLock = new ReaderWriterLockSlim();

            // create workers
            this.chainingWorker = kernel.Get <ChainingWorker>(
                new ConstructorArgument("workerConfig", new WorkerConfig(initialNotify: true, minIdleTime: TimeSpan.FromSeconds(0), maxIdleTime: TimeSpan.FromSeconds(30))));

            this.targetChainWorker = kernel.Get <TargetChainWorker>(
                new ConstructorArgument("workerConfig", new WorkerConfig(initialNotify: true, minIdleTime: TimeSpan.FromSeconds(0), maxIdleTime: TimeSpan.FromSeconds(30))));

            this.chainStateWorker = kernel.Get <ChainStateWorker>(
                new ConstructorArgument("workerConfig", new WorkerConfig(initialNotify: true, minIdleTime: TimeSpan.Zero, maxIdleTime: TimeSpan.FromSeconds(5))),
                new ConstructorArgument("getTargetChain", (Func <Chain>)(() => this.targetChainWorker.TargetChain)),
                new ConstructorArgument("targetChainWorker", this.targetChainWorker),
                new ConstructorArgument("chainStateBuilder", this.chainStateBuilder));

            this.targetChainWorker.OnTargetBlockChanged +=
                () =>
            {
                var handler = this.OnTargetBlockChanged;
                if (handler != null)
                {
                    handler(this, EventArgs.Empty);
                }
            };

            this.targetChainWorker.OnTargetChainChanged +=
                () =>
            {
                this.chainStateWorker.NotifyWork();

                var handler = this.OnTargetChainChanged;
                if (handler != null)
                {
                    handler(this, EventArgs.Empty);
                }
            };

            this.chainStateWorker.OnChainStateChanged +=
                () =>
            {
                this.utxoScanWorker.NotifyWork();

                //TODO once fully synced, this should save off the immutable snapshot immediately
                //TODO this will allow there to always be an active chain state once synced
                this.chainStateLock.DoWrite(() =>
                                            this.chainState = null);

                var handler = this.OnChainStateChanged;
                if (handler != null)
                {
                    handler(this, EventArgs.Empty);
                }
            };

            this.gcWorker = new WorkerMethod("GC Worker",
                                             () =>
            {
                this.logger.Info(
                    string.Join("\n",
                                new string('-', 80),
                                "GC Memory:      {0,10:#,##0.00} MB",
                                "Process Memory: {1,10:#,##0.00} MB",
                                new string('-', 80)
                                )
                    .Format2
                    (
                        /*0*/ (float)GC.GetTotalMemory(false) / 1.MILLION(),
                        /*1*/ (float)Process.GetCurrentProcess().PrivateMemorySize64 / 1.MILLION()
                    ));
            }, initialNotify: true, minIdleTime: TimeSpan.FromSeconds(30), maxIdleTime: TimeSpan.FromSeconds(30), logger: this.logger);

            this.utxoScanWorker = new WorkerMethod("UTXO Scan Worker",
                                                   () =>
            {
                var chainStateLocal = this.GetChainState();
                if (chainStateLocal == null)
                {
                    return;
                }

                new MethodTimer().Time("Full UTXO Scan: {0:#,##0}".Format2(chainStateLocal.Utxo.OutputCount), () =>
                {
                    var sha256 = new SHA256Managed();
                    foreach (var output in chainStateLocal.Utxo.GetUnspentOutputs())
                    {
                        if (new UInt256(sha256.ComputeDoubleHash(output.Value.ScriptPublicKey.ToArray())) == UInt256.Zero)
                        {
                        }
                    }
                });
            }, initialNotify: true, minIdleTime: TimeSpan.Zero, maxIdleTime: TimeSpan.MaxValue, logger: this.logger);
        }
Ejemplo n.º 8
0
 public UnitTestRules(Logger logger, BlockHeaderCache blockHeaderCache)
     : base(logger, blockHeaderCache)
 {
     this._highestTarget = Target0;
 }
Ejemplo n.º 9
0
        public MainnetRules(Logger logger, BlockHeaderCache blockHeaderCache)
        {
            this.logger           = logger;
            this.blockHeaderCache = blockHeaderCache;

            this.highestTarget = UInt256.Parse("00000000FFFF0000000000000000000000000000000000000000000000000000", NumberStyles.HexNumber);

            this.genesisBlock =
                new Block
                (
                    header: new BlockHeader
                    (
                        version: 1,
                        previousBlock: 0,
                        merkleRoot: UInt256.Parse("4a5e1e4baab89f3a32518a88c31bc87f618f76673e2cc77ab2127b7afdeda33b", NumberStyles.HexNumber),
                        time: 1231006505,
                        bits: 0x1D00FFFF,
                        nonce: 2083236893
                    ),
                    transactions: ImmutableArray.Create
                    (
                        new Transaction
                        (
                            version: 1,
                            inputs: ImmutableArray.Create
                            (
                                new TxInput
                                (
                                    previousTxOutputKey: new TxOutputKey
                                    (
                                        txHash: 0,
                                        txOutputIndex: 0xFFFFFFFF
                                    ),
                                    scriptSignature: ImmutableArray.Create <byte>
                                    (
                                        0x04, 0xFF, 0xFF, 0x00, 0x1D, 0x01, 0x04, 0x45, 0x54, 0x68, 0x65, 0x20, 0x54, 0x69, 0x6D, 0x65,
                                        0x73, 0x20, 0x30, 0x33, 0x2F, 0x4A, 0x61, 0x6E, 0x2F, 0x32, 0x30, 0x30, 0x39, 0x20, 0x43, 0x68,
                                        0x61, 0x6E, 0x63, 0x65, 0x6C, 0x6C, 0x6F, 0x72, 0x20, 0x6F, 0x6E, 0x20, 0x62, 0x72, 0x69, 0x6E,
                                        0x6B, 0x20, 0x6F, 0x66, 0x20, 0x73, 0x65, 0x63, 0x6F, 0x6E, 0x64, 0x20, 0x62, 0x61, 0x69, 0x6C,
                                        0x6F, 0x75, 0x74, 0x20, 0x66, 0x6F, 0x72, 0x20, 0x62, 0x61, 0x6E, 0x6B, 0x73
                                    ),
                                    sequence: 0xFFFFFFFF
                                )
                            ),
                            outputs: ImmutableArray.Create
                            (
                                new TxOutput
                                (
                                    value: 50 * SATOSHI_PER_BTC,
                                    scriptPublicKey: ImmutableArray.Create <byte>
                                    (
                                        0x41, 0x04, 0x67, 0x8A, 0xFD, 0xB0, 0xFE, 0x55, 0x48, 0x27, 0x19, 0x67, 0xF1, 0xA6, 0x71, 0x30,
                                        0xB7, 0x10, 0x5C, 0xD6, 0xA8, 0x28, 0xE0, 0x39, 0x09, 0xA6, 0x79, 0x62, 0xE0, 0xEA, 0x1F, 0x61,
                                        0xDE, 0xB6, 0x49, 0xF6, 0xBC, 0x3F, 0x4C, 0xEF, 0x38, 0xC4, 0xF3, 0x55, 0x04, 0xE5, 0x1E, 0xC1,
                                        0x12, 0xDE, 0x5C, 0x38, 0x4D, 0xF7, 0xBA, 0x0B, 0x8D, 0x57, 0x8A, 0x4C, 0x70, 0x2B, 0x6B, 0xF1,
                                        0x1D, 0x5F, 0xAC
                                    )
                                )
                            ),
                            lockTime: 0
                        )
                    )
                );

            this.genesisChainedHeader = ChainedHeader.CreateForGenesisBlock(this.genesisBlock.Header);
        }
Ejemplo n.º 10
0
 public RevalidateWorker(Logger logger, BlockHeaderCache blockHeaderCache)
     : base("RevalidateWorker", initialNotify: false, minIdleTime: TimeSpan.Zero, maxIdleTime: TimeSpan.MaxValue, logger: logger)
 {
     this.logger           = logger;
     this.blockHeaderCache = blockHeaderCache;
 }