Example #1
0
        public override void Execute()
        {
            // load headers form file (or genesis)
            if (File.Exists(this.Context.Config.File("headers.dat")))
            {
                this.logger.LogInformation("Loading headers form disk...");
                this.ChainIndex.Load(File.ReadAllBytes(this.Context.Config.File("headers.dat")));
            }
            else
            {
                this.logger.LogInformation("Loading headers no file found...");
                var genesis = this.Context.Network.GetGenesis();
                this.ChainIndex.SetTip(new ChainedBlock(genesis.Header, 0));
                // validate the block to generate the pos params
                BlockValidator.CheckAndComputeStake(this.ChainIndex, this.ChainIndex, this.ChainIndex, this.ChainIndex,
                                                    this.ChainIndex.Tip, genesis);
                //this.ChainIndex.ValidateBlock(genesis);
            }

            // load the index chain this will
            // add each block index to memory for fast lookup
            this.ChainIndex.Initialize(this.Context);

            // sync the headers chain
            this.logger.LogInformation("Sync chain headers with network...");
            this.chainSyncService.SyncChain();

            // persist the chain
            this.logger.LogInformation("Persist headers...");
            this.chainSyncService.SaveToDisk();
        }
Example #2
0
        public void CheckBlockProofOfStake()
        {
            var totalblocks = 5000;              // fill only a small portion so test wont be too long
            var mainStore   = new BlockStore(TestDataLocations.BlockFolderLocation, Network.Main);

            // create the stores
            var store = CreateBlockStore();

            var index      = 0;
            var blockStore = new NoSqlBlockRepository();

            foreach (var storedBlock in mainStore.Enumerate(false).Take(totalblocks))
            {
                store.Append(storedBlock.Item);
                blockStore.PutAsync(storedBlock.Item);
                index++;
            }

            // build the chain
            var chain = store.GetChain();

            // fill the transaction store
            var trxStore = new NoSqlTransactionRepository();
            var mapStore = new BlockTransactionMapStore();

            foreach (var chainedBlock in chain.ToEnumerable(false).Take(totalblocks))
            {
                var block = blockStore.GetBlock(chainedBlock.HashBlock);
                foreach (var blockTransaction in block.Transactions)
                {
                    trxStore.Put(blockTransaction);
                    mapStore.PutAsync(blockTransaction.GetHash(), block.GetHash());
                }
            }

            RPCClient client = null;            // new RPCClient(new NetworkCredential("rpcuser", "rpcpassword"), new Uri("http://127.0.0.1:" + Network.Main.RPCPort), Network.Main);

            // validate the stake trasnaction
            foreach (var item in chain.ToEnumerable(false).Take(totalblocks).ToList())
            {
                var block = blockStore.GetBlock(item.HashBlock);
                Assert.True(BlockValidator.CheckAndComputeStake(blockStore, trxStore, mapStore, chain, item, block));

                if (item.Height == 1125)
                {
                    var g = block.ToHex();
                }

                if (client != null)
                {
                    var fetched = client.GetRPCBlock(item.HashBlock).Result;
                    Assert.Equal(uint256.Parse(fetched.modifierv2), item.Header.PosParameters.StakeModifierV2);
                    Assert.Equal(uint256.Parse(fetched.proofhash), item.Header.PosParameters.HashProof);
                }
            }
        }
Example #3
0
        public bool ProcessBlock(Node node, Block block, out ChainedBlock chainedBlock)
        {
            chainedBlock = null;
            var blockHash = block.GetHash();


            // ppcoin: check proof-of-stake
            // Limited duplicity on stake: prevents block flood attack
            // Duplicate stake allowed only when there is orphan child block
            //if (!fReindex && !fImporting && pblock->IsProofOfStake() && setStakeSeen.count(pblock->GetProofOfStake()) && !mapOrphanBlocksByPrev.count(hash))
            //	return error("ProcessBlock() : duplicate proof-of-stake (%s, %d) for block %s", pblock->GetProofOfStake().first.ToString(), pblock->GetProofOfStake().second, hash.ToString());

            if (block.Header.HashPrevBlock != this.chainIndex.Tip.HashBlock)
            {
                // Extra checks to prevent "fill up memory by spamming with bogus blocks"
                //const CBlockIndex* pcheckpoint = Checkpoints::AutoSelectSyncCheckpoint();
                //var deltaTime = pblock->GetBlockTime() - pcheckpoint->nTime;
                //if (deltaTime < 0)
                //{
                //	if (pfrom)
                //		pfrom->Misbehaving(1);
                //	return error("ProcessBlock() : block with timestamp before last checkpoint");
                //}
            }

            if (!BlockValidator.IsCanonicalBlockSignature(block, false))
            {
                //if (node != null && (int)node.Version >= CANONICAL_BLOCK_SIG_VERSION)
                //node.Misbehaving(100);

                //return false; //error("ProcessBlock(): bad block signature encoding");
            }

            if (!BlockValidator.IsCanonicalBlockSignature(block, true))
            {
                //if (pfrom && pfrom->nVersion >= CANONICAL_BLOCK_SIG_LOW_S_VERSION)
                //{
                //	pfrom->Misbehaving(100);
                //	return error("ProcessBlock(): bad block signature encoding (low-s)");
                //}

                if (!BlockValidator.EnsureLowS(block.BlockSignatur))
                {
                    return(false);                    // error("ProcessBlock(): EnsureLowS failed");
                }
            }

            // Preliminary checks
            if (!BlockValidator.CheckBlock(block))
            {
                return(false);                //error("ProcessBlock() : CheckBlock FAILED");
            }
            var prevChainedBlock = this.chainIndex.GetAnyTip(block.Header.HashPrevBlock);

            if (prevChainedBlock == null)
            {
                throw new InvalidBlockException();
            }

            chainedBlock = new ChainedBlock(block.Header, blockHash, prevChainedBlock);

            if (!block.Header.PosParameters.IsSet())
            {
                chainedBlock.Header.PosParameters = block.SetPosParams();
            }

            // ensure the previous chainedBlock has
            // the POS parameters set if not load its
            // block and set the pos params
            if (!prevChainedBlock.Header.PosParameters.IsSet())
            {
                var prevBlock = this.chainIndex.GetFullBlock(prevChainedBlock.HashBlock);
                prevChainedBlock.Header.PosParameters = prevBlock.Header.PosParameters;
            }

            // do some checks
            if (!chainedBlock.Validate(this.Context.Network))
            {
                return(false);
            }

            // todo: implement this checks

            //if (IsProtocolV2(nHeight) && nVersion < 7)
            //	return DoS(100, error("AcceptBlock() : reject too old nVersion = %d", nVersion));
            //else if (!IsProtocolV2(nHeight) && nVersion > 6)
            //	return DoS(100, error("AcceptBlock() : reject too new nVersion = %d", nVersion));

            //if (IsProofOfWork() && nHeight > Params().LastPOWBlock())
            //	return DoS(100, error("AcceptBlock() : reject proof-of-work at height %d", nHeight));

            //// Check coinbase timestamp
            //if (GetBlockTime() > FutureDrift((int64_t)vtx[0].nTime, nHeight))
            //	return DoS(50, error("AcceptBlock() : coinbase timestamp is too early"));

            // Check coinstake timestamp
            if (block.IsProofOfStake() && !BlockValidator.CheckCoinStakeTimestamp(chainedBlock.Height, block.Header.Time, block.Transactions[1].Time))
            {
                return(false);                //DoS(50, error("AcceptBlock() : coinstake timestamp violation nTimeBlock=%d nTimeTx=%u", GetBlockTime(), vtx[1].nTime));
            }
            //// Check proof-of-work or proof-of-stake
            //if (nBits != GetNextTargetRequired(pindexPrev, IsProofOfStake()))
            //	return DoS(100, error("AcceptBlock() : incorrect %s", IsProofOfWork() ? "proof-of-work" : "proof-of-stake"));

            //// Check timestamp against prev
            //if (GetBlockTime() <= pindexPrev->GetPastTimeLimit() || FutureDrift(GetBlockTime(), nHeight) < pindexPrev->GetBlockTime())
            //	return error("AcceptBlock() : block's timestamp is too early");

            //// Check that all transactions are finalized
            //BOOST_FOREACH(const CTransaction&tx, vtx)
            //     if (!IsFinalTx(tx, nHeight, GetBlockTime()))
            //	return DoS(10, error("AcceptBlock() : contains a non-final transaction"));

            //// Check that the block chain matches the known block chain up to a checkpoint
            //if (!Checkpoints::CheckHardened(nHeight, hash))
            //	return DoS(100, error("AcceptBlock() : rejected by hardened checkpoint lock-in at %d", nHeight));



            if (!BlockValidator.CheckAndComputeStake(this.chainIndex, this.chainIndex, this.chainIndex, this.chainIndex, chainedBlock, block))
            {
                return(false);
            }

            // all validations passed
            return(true);
        }