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);
            }
Ejemplo n.º 2
0
        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);
        }
Ejemplo n.º 3
0
        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:
                    ;
                }
            }
        }
Ejemplo n.º 4
0
 public abstract void ResolveCollision(UTXOIndex tablePrimary);