X-Git-Url: https://git.novaco.in/?a=blobdiff_plain;f=Novacoin%2FCBlockStore.cs;h=1b600b9de4d9d19bd70df2897d84933bddb3b17a;hb=d171cc68784f580b4dd334944014930f638eab89;hp=f4342a27adf41ca1af2a7baec7dce6230ef39b51;hpb=7179624be052575a50fe87ce5a380c0dd803a689;p=NovacoinLibrary.git diff --git a/Novacoin/CBlockStore.cs b/Novacoin/CBlockStore.cs index f4342a2..1b600b9 100644 --- a/Novacoin/CBlockStore.cs +++ b/Novacoin/CBlockStore.cs @@ -274,6 +274,11 @@ namespace Novacoin { var outPoint = txin.prevout; + if (inputs.ContainsKey(outPoint)) + { + continue; // We have already seen this input. + } + if (!queued.ContainsKey(outPoint)) { return false; // No such transaction @@ -836,10 +841,8 @@ namespace Novacoin private bool ConnectInputs(CTransaction tx, ref Dictionary inputs, ref Dictionary queued, ref CBlockStoreItem cursorBlock, bool fBlock, bool fScriptChecks, scriptflag scriptFlags) { - // Take over previous transactions' spent pointers + // Take over previous transactions' spent items // fBlock is true when this is called from AcceptBlock when a new best-block is added to the blockchain - // fMiner is true when called from the internal bitcoin miner - // ... both are false when called from CTransaction::AcceptToMemoryPool if (!tx.IsCoinBase) { @@ -852,26 +855,44 @@ namespace Novacoin var input = inputs[prevout]; CBlockStoreItem parentBlockCursor; - var merkleItem = GetMerkleCursor(input, out parentBlockCursor); - if (merkleItem == null) + if (input.nMerkleNodeID == -1) { - return false; // Unable to find merkle node - } + // This input seems as is confirmed by the same block. - // If prev is coinbase or coinstake, check that it's matured - if (merkleItem.IsCoinBase || merkleItem.IsCoinStake) - { - if (cursorBlock.nHeight - parentBlockCursor.nHeight < NetInfo.nGeneratedMaturity) + if (!queued.ContainsKey(prevout)) { - return false; // tried to spend non-matured generation input. + return false; // No such output has been queued by this block. } - } - // check transaction timestamp - if (merkleItem.nTime > tx.nTime) + // TODO: Ensure that neither coinbase nor coinstake outputs are + // available for spending in the generation block. + } + else { - return false; // transaction timestamp earlier than input transaction + // This input has been confirmed by one of the earlier accepted blocks. + + var merkleItem = GetMerkleCursor(input, out parentBlockCursor); + + if (merkleItem == null) + { + return false; // Unable to find merkle node + } + + // If prev is coinbase or coinstake, check that it's matured + if (merkleItem.IsCoinBase || merkleItem.IsCoinStake) + { + if (cursorBlock.nHeight - parentBlockCursor.nHeight < NetInfo.nGeneratedMaturity) + { + return false; // tried to spend non-matured generation input. + } + } + + // check transaction timestamp + if (merkleItem.nTime > tx.nTime) + { + return false; // transaction timestamp earlier than input transaction + } } // Check for negative or overflow input values @@ -917,7 +938,16 @@ namespace Novacoin // Write back if (fBlock) { - queued.Add(prevout, input); + if (input.nMerkleNodeID != -1) + { + // Input has been confirmed earlier. + queued.Add(prevout, input); + } + else + { + // Input has been confirmed by current block. + queued[prevout] = input; + } } } @@ -1362,7 +1392,7 @@ namespace Novacoin } int nCount = blockMap.Count; - Console.WriteLine("nCount={0}, Hash={1}, Time={2}", nCount, block.header.Hash, DateTime.Now); // Commit on each 100th block + Console.WriteLine("nCount={0}, Hash={1}, NumTx={2}, Time={3}", nCount, block.header.Hash, block.vtx.Length, DateTime.Now); // Commit on each 100th block /* if (nCount % 100 == 0 && nCount != 0)