var inputsKey = new COutPoint(item.TransactionHash, item.nOut);
-// item.IsSpent = true;
-
// Add output data to dictionary
- inputs.Add(inputsKey, (TxOutItem)item);
+ inputs.Add(inputsKey, item.getTxOutItem());
}
if (queryResults.Count < tx.vin.Length)
inputs.Add(outPoint, queued[outPoint]);
// Mark output as spent
- queued[outPoint].IsSpent = true;
+ // queued[outPoint].IsSpent = true;
}
}
else
uint nSigOps = 0;
var queuedMerkleNodes = new Dictionary<uint256, CMerkleNode>();
- var queued = new Dictionary<COutPoint, TxOutItem>();
+ var queuedOutputs = new Dictionary<COutPoint, TxOutItem>();
for (var nTx = 0; nTx < block.vtx.Length; nTx++)
{
var tx = block.vtx[nTx];
var hashTx = tx.Hash;
- var nTxPos = cursor.nBlockPos + block.GetTxOffset(nTx);
+
+ if (!queuedMerkleNodes.ContainsKey(hashTx))
+ {
+ var nTxPos = cursor.nBlockPos + block.GetTxOffset(nTx);
+ var mNode = new CMerkleNode(cursor.ItemID, nTxPos, tx);
+
+ queuedMerkleNodes.Add(hashTx, mNode);
+ }
Dictionary<COutPoint, TxOutItem> txouts;
if (GetOutputs(hashTx, out txouts))
else
{
bool Invalid;
- if (!FetchInputs(tx, ref queued, ref inputs, true, out Invalid))
+ if (!FetchInputs(tx, ref queuedOutputs, ref inputs, true, out Invalid))
{
return false; // Unable to fetch some inputs.
}
nFees += nTxValueIn - nTxValueOut;
}
- if (!ConnectInputs(tx, ref inputs, ref queued, ref cursor, true, fScriptChecks, scriptFlags))
+ if (!ConnectInputs(tx, ref inputs, ref queuedOutputs, ref cursor, true, fScriptChecks, scriptFlags))
{
return false;
}
for (var i = 0u; i < tx.vout.Length; i++)
{
- if (!queuedMerkleNodes.ContainsKey(hashTx))
- {
- var mNode = new CMerkleNode(cursor.ItemID, nTxPos, tx);
- queuedMerkleNodes.Add(hashTx, mNode);
- }
-
var outKey = new COutPoint(hashTx, i);
- var outData = new TxOutItem();
-
- outData.nValue = tx.vout[i].nValue;
- outData.scriptPubKey = tx.vout[i].scriptPubKey;
- outData.nOut = i;
-
- outData.IsSpent = false;
+ var outData = new TxOutItem()
+ {
+ nMerkleNodeID = -1,
+ nValue = tx.vout[i].nValue,
+ scriptPubKey = tx.vout[i].scriptPubKey,
+ IsSpent = false,
+ nOut = i
+ };
- queued.Add(outKey, outData);
+ queuedOutputs.Add(outKey, outData);
}
}
return true;
}
+ // Flush merkle nodes.
+ var savedMerkleNodes = new Dictionary<uint256, CMerkleNode>();
+ foreach (var merklePair in queuedMerkleNodes)
+ {
+ var merkleNode = merklePair.Value;
+
+ if (!SaveMerkleNode(ref merkleNode))
+ {
+ // Unable to save merkle tree cursor.
+ return false;
+ }
+
+ savedMerkleNodes.Add(merklePair.Key, merkleNode);
+ }
+
// Write queued transaction changes
- var actualMerkleNodes = new Dictionary<uint256, CMerkleNode>();
- var queuedOutpointItems = new List<TxOutItem>();
- foreach (KeyValuePair<COutPoint, TxOutItem> outPair in queued)
+ var newOutpointItems = new List<TxOutItem>();
+ var updatedOutpointItems = new List<TxOutItem>();
+ foreach (var outPair in queuedOutputs)
{
- uint256 txID = outPair.Key.hash;
- CMerkleNode merkleNode;
+ var outItem = outPair.Value;
- if (actualMerkleNodes.ContainsKey(txID))
+ if (outItem.nMerkleNodeID == -1)
{
- merkleNode = actualMerkleNodes[txID];
+ // This outpoint doesn't exist yet, adding to insert list.
+
+ outItem.nMerkleNodeID = savedMerkleNodes[outPair.Key.hash].nMerkleNodeID;
+ newOutpointItems.Add(outItem);
}
else
{
- // TODO: Bug here, we shouldn't mix new and already existent outpoints in the same dictionary.
+ // This outpount already exists, adding to update list.
-
- merkleNode = queuedMerkleNodes[txID];
- if (!SaveMerkleNode(ref merkleNode))
- {
- // Unable to save merkle tree cursor.
- return false;
- }
- actualMerkleNodes.Add(txID, merkleNode);
+ updatedOutpointItems.Add(outItem);
}
+ }
- var outItem = outPair.Value;
- outItem.nMerkleNodeID = merkleNode.nMerkleNodeID;
-
- queuedOutpointItems.Add(outItem);
+ if (updatedOutpointItems.Count != 0 && !UpdateOutpoints(ref updatedOutpointItems))
+ {
+ return false; // Unable to update outpoints
}
- if (!SaveOutpoints(ref queuedOutpointItems))
+ if (newOutpointItems.Count != 0 && !InsertOutpoints(ref newOutpointItems))
{
- return false; // Unable to save outpoints
+ return false; // Unable to insert outpoints
}
return true;
}
/// <summary>
- /// Insert set of outpoints
+ /// Insert set of new outpoints
+ /// </summary>
+ /// <param name="newOutpointItems">List of TxOutItem objects.</param>
+ /// <returns>Result</returns>
+ private bool InsertOutpoints(ref List<TxOutItem> newOutpointItems)
+ {
+ return (dbConn.InsertAll(newOutpointItems, false) != 0);
+ }
+
+
+ /// <summary>
+ /// Update set of outpoints
/// </summary>
/// <param name="queuedOutpointItems">List of TxOutItem objects.</param>
/// <returns>Result</returns>
- private bool SaveOutpoints(ref List<TxOutItem> queuedOutpointItems)
+ private bool UpdateOutpoints(ref List<TxOutItem> updatedOutpointItems)
{
- return dbConn.InsertAll(queuedOutpointItems, false) != 0;
+ return (dbConn.UpdateAll(updatedOutpointItems, false) != 0);
}
/// <summary>