Skip to content

Commit

Permalink
fix block buffer
Browse files Browse the repository at this point in the history
  • Loading branch information
BrandonKoerner committed Feb 29, 2024
1 parent de2256d commit ad3c614
Show file tree
Hide file tree
Showing 3 changed files with 88 additions and 83 deletions.
147 changes: 70 additions & 77 deletions Discreet/DB/BlockBuffer.cs
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,7 @@ public static BlockBuffer Instance
private List<Block> buffer = new List<Block>();
private HashSet<Key> spentKeys = new HashSet<Key>();
private ConcurrentDictionary<long, Block> blockCache = new ConcurrentDictionary<long, Block>();
private ConcurrentDictionary<SHA256, long> hashesToHeights = new ConcurrentDictionary<SHA256, long>(new SHA256EqualityComparer());
private ConcurrentDictionary<uint, TXOutput> outputCache = new ConcurrentDictionary<uint, TXOutput>();
private ConcurrentDictionary<SHA256, FullTransaction> transactionCache = new ConcurrentDictionary<SHA256, FullTransaction>(new SHA256EqualityComparer());
private ConcurrentDictionary<TTXInput, TTXOutput> inputCache = new ConcurrentDictionary<TTXInput, TTXOutput>(new TTXInputEqualityComparer());
Expand Down Expand Up @@ -71,10 +72,18 @@ public bool TryGetBlockHeader(SHA256 hash, out BlockHeader header)
else
{
// try getting it from the cache
Block blk = null;
lock (buffer)
var success = hashesToHeights.TryGetValue(hash, out var height);
if (!success)
{
blk = buffer.Where(x => x.Header.BlockHash == hash).FirstOrDefault();
header = null;
return false;
}

success = blockCache.TryGetValue(height, out var blk);
if (!success)
{
header = null;
return false;
}

if (blk == null)
Expand Down Expand Up @@ -106,21 +115,20 @@ public BlockHeader GetBlockHeader(SHA256 hash)
}
catch (Exception e)
{
try
var success = hashesToHeights.TryGetValue(hash, out var height);
if (!success)
{
Block blk = null;
lock (buffer)
{
blk = buffer.Where(x => x.Header.BlockHash == hash).FirstOrDefault();
}

if (blk == null) throw new Exception();
return blk.Header;
throw;
}
catch

success = blockCache.TryGetValue(height, out var blk);
if (!success)
{
throw e;
throw;
}

if (blk == null) throw;
return blk.Header;
}
}

Expand All @@ -132,21 +140,14 @@ public BlockHeader GetBlockHeader(long height)
}
catch (Exception e)
{
try
var success = blockCache.TryGetValue(height, out var blk);
if (!success)
{
Block blk = null;
lock (buffer)
{
blk = buffer.Where(x => x.Header.Height == height).FirstOrDefault();
}

if (blk == null) throw new Exception();
return blk.Header;
}
catch
{
throw e;
throw;
}

if (blk == null) throw;
return blk.Header;
}
}

Expand All @@ -160,13 +161,7 @@ public bool BlockExists(SHA256 hash)
}
else
{
Block blk = null;
lock (buffer)
{
blk = buffer.Where(x => x.Header.BlockHash == hash).FirstOrDefault();
}

return blk != null;
return hashesToHeights.ContainsKey(hash);
}
}

Expand Down Expand Up @@ -248,16 +243,24 @@ public BlockBuffer()

public long GetChainHeight()
{
lock (buffer)
{
if (buffer.Count == 0) return DataView.GetView().GetChainHeight();
return Math.Max(DataView.GetView().GetChainHeight(), buffer.Select(x => x.Header.Height).Max());
}
if (hashesToHeights.IsEmpty) return DataView.GetView().GetChainHeight();
return Math.Max(DataView.GetView().GetChainHeight(), hashesToHeights.Values.Max());
}

public void WriteToBuffer(Block blk)
{
_buffer.Enqueue(blk);

if (_flushEveryBlock)
{
lock (buffer)
{
buffer.Add(blk);
}

ForceFlush();
}

UpdateBuffers(blk);
}

Expand All @@ -284,6 +287,10 @@ public async Task Start()
_pIndex = DataView.GetView().GetOutputIndex();

var timer = new PeriodicTimer(_flushInterval);
if (_flushEveryBlock)
{
return;
}
while (await timer.WaitForNextTickAsync())
{
lock (buffer)
Expand Down Expand Up @@ -353,21 +360,14 @@ public Block GetBlock(long height)
}
catch (Exception e)
{
try
var success = blockCache.TryGetValue(height, out var blk);
if (!success)
{
Block blk = null;
lock (buffer)
{
blk = buffer.Where(x => x.Header.Height == height).FirstOrDefault();
}

if (blk == null) throw new Exception();
return blk;
}
catch
{
throw e;
throw;
}

if (blk == null) throw;
return blk;
}
}

Expand All @@ -379,21 +379,20 @@ public Block GetBlock(SHA256 hash)
}
catch (Exception e)
{
try
var success = hashesToHeights.TryGetValue(hash, out var height);
if (!success)
{
Block blk = null;
lock (buffer)
{
blk = buffer.Where(x => x.Header.BlockHash == hash).FirstOrDefault();
}

if (blk == null) throw new Exception();
return blk;
throw;
}
catch

success = blockCache.TryGetValue(height, out var blk);
if (!success)
{
throw e;
throw;
}

if (blk == null) throw;
return blk;
}
}

Expand All @@ -409,29 +408,21 @@ public long GetBlockHeight(SHA256 hash)
}
catch (Exception e)
{
try
var success = hashesToHeights.TryGetValue(hash, out var height);
if (!success)
{
Block blk = null;
lock (buffer)
{
blk = buffer.Where(x => x.Header.BlockHash == hash).FirstOrDefault();
}

if (blk == null) throw new Exception();
return blk.Header.Height;
}
catch
{
throw e;
throw;
}

return height;
}
}

public bool BlockHeightExists(long h)
{
lock (buffer)
{
return _view.BlockHeightExists(h) || buffer.Any(x => x.Header.Height == h);
return _view.BlockHeightExists(h) || blockCache.Keys.Any(x => x == h);
}
}

Expand All @@ -442,6 +433,7 @@ private void UpdateBuffers(Block block)
if (blockCache.ContainsKey(block.Header.Height)) return;

blockCache[block.Header.Height] = block;
hashesToHeights[block.Header.BlockHash] = block.Header.Height;

foreach (var tx in block.Transactions)
{
Expand Down Expand Up @@ -570,6 +562,7 @@ private void Flush(List<Block> _blocks)
inputCache.Clear();
transactionCache.Clear();
outputCache.Clear();
hashesToHeights.Clear();
}
}
}
2 changes: 1 addition & 1 deletion Discreet/DB/ValidationCache.cs
Original file line number Diff line number Diff line change
Expand Up @@ -620,7 +620,7 @@ public async Task Flush(List<Block> goodBlocks = null, bool force = false)
{
// We no longer flush updates here; TODO: remove updates from ValidationCache
//dataView.Flush(updates);
if (blocks != null)
if (blocks != null && blocks.Count > 0)
{
if (goodBlocks != null)
{
Expand Down
22 changes: 17 additions & 5 deletions Discreet/Network/Handler.cs
Original file line number Diff line number Diff line change
Expand Up @@ -1247,9 +1247,10 @@ public async Task HandleSendBlock(SendBlockPacket p, Peerbloom.Connection conn,
Daemon.Logger.Warn($"HandleSendBlock: orphan block ({p.Block.Header.BlockHash.ToHexShort()}, height {p.Block.Header.Height}) added", verbose: 3);
MessageCache.GetMessageCache().OrphanBlocks[p.Block.Header.PreviousBlock] = p.Block;
MessageCache.GetMessageCache().OrphanBlockParents[p.Block.Header.BlockHash] = p.Block.Header.PreviousBlock;
CheckRoot(p.Block, conn);

MessageCache.GetMessageCache().OrphanLock.Release();
await CheckRoot(p.Block, conn);

return;
}
}
Expand Down Expand Up @@ -1424,10 +1425,10 @@ public async Task HandleBlocks(BlocksPacket p, Peerbloom.Connection conn)

MessageCache.GetMessageCache().OrphanBlocks[p.Blocks[0].Header.PreviousBlock] = p.Blocks[0];
MessageCache.GetMessageCache().OrphanBlockParents[p.Blocks[0].Header.BlockHash] = p.Blocks[0].Header.PreviousBlock;
CheckRoot(p.Blocks[0], conn);

MessageCache.GetMessageCache().OrphanLock.Release();

await CheckRoot(p.Blocks[0], conn);

return;
}
}
Expand Down Expand Up @@ -1629,7 +1630,7 @@ public void TossOrphans(Cipher.SHA256 bHash)
}
}

public void CheckRoot(Block block, Peerbloom.Connection conn)
public async Task CheckRoot(Block block, Peerbloom.Connection conn)
{
MessageCache mCache = MessageCache.GetMessageCache();
var hash = block.Header.PreviousBlock;
Expand All @@ -1638,8 +1639,19 @@ public void CheckRoot(Block block, Peerbloom.Connection conn)
hash = mCache.OrphanBlockParents[hash];
}

if (DB.BlockBuffer.Instance.BlockExists(hash))
{
Daemon.Logger.Info($"HandleBlocks: Root found for orphan branch beginning with block {hash.ToHexShort()}", verbose: 1);
MessageCache.GetMessageCache().OrphanBlockParents.Remove(hash, out _);

await AcceptOrphans(hash);
}

// request previous block
Peerbloom.Network.GetNetwork().SendRequest(conn, new Packet(PacketType.GETBLOCKS, new GetBlocksPacket { Blocks = new Cipher.SHA256[] { hash } }), durationMilliseconds: 60000);
if (!mCache.OrphanBlockParents.ContainsKey(hash) && !DB.BlockBuffer.Instance.BlockExists(hash))
{
Peerbloom.Network.GetNetwork().SendRequest(conn, new Packet(PacketType.GETBLOCKS, new GetBlocksPacket { Blocks = new Cipher.SHA256[] { hash } }), durationMilliseconds: 60000);
}
}

/// <summary>
Expand Down

0 comments on commit ad3c614

Please sign in to comment.