public override void ResolveCollision(UTXOIndex tablePrimary) { KeyValuePair <byte[], uint[]> collisionItem = CollisionTable.First(k => BitConverter.ToInt32(k.Key, 0) == tablePrimary.PrimaryKey); CollisionTable.Remove(collisionItem.Key); if (!tablePrimary.AreCollisionBitsFull() || !HasCountCollisions(tablePrimary.PrimaryKey, COUNT_COLLISIONS_MAX)) { tablePrimary.DecrementCollisionBits(Address); } collisionItem.Value[0] |= tablePrimary.GetCollisionBits(); PrimaryTable.Add(tablePrimary.PrimaryKey, collisionItem.Value); }
void InsertUTXO( byte[] uTXOKey, int primaryKey, UTXOIndex table) { for (int c = 0; c < Tables.Length; c += 1) { if (Tables[c].PrimaryTableContainsKey(primaryKey)) { Tables[c].IncrementCollisionBits( primaryKey, table.Address); table.AddUTXOAsCollision(uTXOKey); return; } } table.AddUTXOAsPrimary(primaryKey); }
public void InsertBlock( Block block, int indexArchive) { foreach (TX tX in block.TXs) { int lengthUTXOBits = COUNT_NON_OUTPUT_BITS + tX.TXOutputs.Count; if (LENGTH_BITS_UINT >= lengthUTXOBits) { uint uTXOIndex = 0; if (LENGTH_BITS_UINT > lengthUTXOBits) { uTXOIndex |= (uint.MaxValue << lengthUTXOBits); } TableUInt32.UTXO = uTXOIndex | ((uint)indexArchive & MaskBatchIndexUInt32); try { InsertUTXO( tX.Hash, tX.TXIDShort, TableUInt32); } catch (ArgumentException) { // BIP 30 if (tX.Hash.ToHexString() == "D5D27987D2A3DFC724E359870C6644B40E497BDC0589A033220FE15429D88599" || tX.Hash.ToHexString() == "E3BF3D07D4B0375638D5F1DB5255FE07BA2C4CB067CD81B84EE974B6585FB468") { Console.WriteLine("Implement BIP 30."); } } } else if (LENGTH_BITS_ULONG >= lengthUTXOBits) { ulong uTXOIndex = 0; if (LENGTH_BITS_ULONG > lengthUTXOBits) { uTXOIndex |= (ulong.MaxValue << lengthUTXOBits); } TableULong64.UTXO = uTXOIndex | ((ulong)indexArchive & MaskBatchIndexULong64); InsertUTXO( tX.Hash, tX.TXIDShort, TableULong64); } else { uint[] uTXOIndex = new uint[(lengthUTXOBits + 31) / 32]; int countUTXORemainderBits = lengthUTXOBits % 32; if (countUTXORemainderBits > 0) { uTXOIndex[uTXOIndex.Length - 1] |= (uint.MaxValue << countUTXORemainderBits); } TableUInt32Array.UTXO = uTXOIndex; TableUInt32Array.UTXO[0] |= (uint)indexArchive & MaskBatchIndexUInt32; InsertUTXO( tX.Hash, tX.TXIDShort, TableUInt32Array); } Wallet.DetectTXOutputsSpendable(tX); } foreach (TX tX in block.TXs) { foreach (TXInput tXInput in tX.TXInputs) { bool checkSig = Wallet.TrySpend(tXInput); foreach (UTXOIndex tablePrimary in Tables) { if (tablePrimary.TryGetValueInPrimaryTable( tXInput.TXIDOutputShort)) { UTXOIndex tableCollision = null; for (int cc = 0; cc < Tables.Length; cc += 1) { if (tablePrimary.HasCollision(cc)) { tableCollision = Tables[cc]; if (tableCollision .TrySpendCollision(tXInput, tablePrimary)) { goto LABEL_LoopNextInput; } } } tablePrimary.SpendPrimaryUTXO( tXInput, out bool allOutputsSpent); if (allOutputsSpent) { tablePrimary.RemovePrimary(); if (tableCollision != null) { tableCollision.ResolveCollision(tablePrimary); } } goto LABEL_LoopNextInput; } } throw new ProtocolException( string.Format( "Referenced TX {0} not found in UTXO table.", tXInput.TXIDOutputShort)); LABEL_LoopNextInput: ; } } }
public abstract void ResolveCollision(UTXOIndex tablePrimary);