Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

GetBlocks by block index #1397

Merged
merged 123 commits into from Jun 2, 2020
Merged
Show file tree
Hide file tree
Changes from 63 commits
Commits
Show all changes
123 commits
Select commit Hold shift + click to select a range
f74620b
Merge pull request #2 from neo-project/master
ShawnYun Nov 26, 2019
6f6cf5e
Merge pull request #5 from neo-project/master
ShawnYun Dec 2, 2019
4152a15
Merge pull request #6 from neo-project/master
ShawnYun Dec 3, 2019
e0ae6d7
Merge pull request #7 from neo-project/master
ShawnYun Dec 4, 2019
ca56875
Merge pull request #8 from neo-project/master
ShawnYun Dec 11, 2019
985bef4
get-full-block
Dec 17, 2019
702c6ac
Merge pull request #10 from neo-project/master
ShawnYun Dec 23, 2019
990cd12
update get-full-block
Dec 26, 2019
126dde0
fix
Dec 26, 2019
6cf3231
modify
Dec 27, 2019
05440f9
Merge pull request #14 from neo-project/master
ShawnYun Dec 27, 2019
49f4966
Merge branch 'master' into get-full-blocks
Dec 27, 2019
3a97136
fix
Dec 31, 2019
117f363
fix
Dec 31, 2019
dc5b117
fix
Dec 31, 2019
3d6cc46
Merge pull request #15 from neo-project/master
ShawnYun Dec 31, 2019
b907ad3
fix
Dec 31, 2019
74ab7d7
Merge branch 'get-full-blocks' of https://github.com/ShawnYun/neo int…
Dec 31, 2019
9120d1f
del blank
Dec 31, 2019
bd955a4
fix
Dec 31, 2019
af8bd41
modify
Jan 2, 2020
3fafae6
modify uncompleted tasks
Jan 3, 2020
74b0958
del merkleblockdata
Jan 8, 2020
c062bb4
modify highestBlock
Jan 8, 2020
fc697eb
Merge branch 'master' into get-full-blocks
shargon Jan 8, 2020
2acad27
Optimize
shargon Jan 8, 2020
be28125
Adding comment
vncoelho Jan 8, 2020
7ee60da
Renaming to unverified_blocks_candidates
vncoelho Jan 8, 2020
9e7ae62
Renaming II
vncoelho Jan 8, 2020
b925f4f
Renaming III
vncoelho Jan 8, 2020
ea825b6
add NodeSession
Jan 16, 2020
b9b1488
del header
Jan 16, 2020
1993044
fix
Jan 17, 2020
8322bcf
Merge pull request #16 from neo-project/master
ShawnYun Jan 17, 2020
191fadf
modify
Jan 17, 2020
a486a78
Merge branch 'master' into get-full-blocks
vncoelho Jan 19, 2020
5c20549
fix
Jan 20, 2020
71bb88d
Merge branch 'get-full-blocks' of https://github.com/ShawnYun/neo int…
Jan 20, 2020
e3f75a8
modify every task to get 1 block
Feb 5, 2020
1d9c6d7
Merge branch 'master' into get-full-blocks
vncoelho Feb 5, 2020
70f06ca
modify SyncManger
Feb 7, 2020
f6f1962
Merge branch 'get-full-blocks' of https://github.com/ShawnYun/neo int…
Feb 7, 2020
5162f17
fix
Feb 7, 2020
7d2d48e
fix
Feb 8, 2020
f7e9ff6
del MaxTaskPerSession
Feb 8, 2020
5148851
fix
Feb 10, 2020
8ac9129
fix
Feb 11, 2020
c2f725e
del TaskManager.Update
Feb 11, 2020
370bb9f
Merge branch 'master' into get-full-blocks
shargon Feb 11, 2020
2a584a4
fix assigntask bug
Feb 12, 2020
dc27f2f
Merge branch 'get-full-blocks' of https://github.com/ShawnYun/neo int…
Feb 12, 2020
45e6858
Merge pull request #18 from neo-project/master
ShawnYun Feb 17, 2020
c54eb7e
modify get headers
Feb 17, 2020
cb27dfb
test
Feb 17, 2020
adf1afe
Rename
erikzhang Feb 21, 2020
f15f73e
Fixes
erikzhang Feb 21, 2020
1ac378b
Fixes
erikzhang Feb 21, 2020
de3047a
Merge branch 'get-full-blocks' into modify-get-headers
ShawnYun Feb 21, 2020
6ddcba1
Merge pull request #20 from ShawnYun/modify-get-headers
ShawnYun Feb 21, 2020
f95bc62
Merge branch 'master' into get-full-blocks
shargon Mar 13, 2020
94655fc
update blockchain
Mar 25, 2020
fbfe4d7
use event stream
Mar 26, 2020
5826c36
Merge branch 'master' into get-full-blocks
erikzhang Mar 26, 2020
e5a8ecf
fix
Mar 26, 2020
0949e57
Merge branch 'get-full-blocks' of https://github.com/ShawnYun/neo int…
Mar 26, 2020
efb4c6b
Ignore Headers messages
erikzhang Mar 27, 2020
3815e26
Merge branch 'master' into get-full-blocks
vncoelho Mar 27, 2020
4802cba
rename GetBlockByIndexPayload
Mar 30, 2020
0ea71c6
Merge branch 'get-full-blocks' of https://github.com/ShawnYun/neo int…
Mar 30, 2020
d17dd27
Remove MaxBlocksCount
erikzhang Mar 31, 2020
4dcb72e
Optimize GetBlockByIndexPayload
erikzhang Mar 31, 2020
f7b0dc3
fix
Mar 31, 2020
0668722
Merge branch 'get-full-blocks' of https://github.com/ShawnYun/neo int…
Mar 31, 2020
1232b41
merge
Apr 10, 2020
da21bb1
fix
Apr 10, 2020
5a5c6e0
Merge branch 'master' into get-full-blocks
ShawnYun Apr 10, 2020
1121c5f
Merge branch 'master' into get-full-blocks
erikzhang Apr 10, 2020
b50d61a
Merge branch 'master' of https://github.com/neo-project/neo into get-…
Apr 10, 2020
b35b09b
del subscribe
Apr 10, 2020
7f4d41c
Merge branch 'get-full-blocks' of https://github.com/ShawnYun/neo int…
Apr 10, 2020
7db6571
Optimize
shargon Apr 11, 2020
fc16c11
Merge branch 'master' into get-full-blocks
vncoelho Apr 13, 2020
7855a62
Merge branch 'master' of https://github.com/neo-project/neo into get-…
Apr 23, 2020
2729447
merge SyncManager and TaskManager to one class
Apr 26, 2020
e79e910
merge to SyncManager and fix
Apr 28, 2020
51f30c5
Rename
erikzhang May 6, 2020
7c2a2ef
Merge branch 'master' into get-full-blocks
shargon May 6, 2020
f543017
fix
May 6, 2020
82df8f0
Merge branch 'master' into get-full-blocks
shargon May 7, 2020
1a9e590
Merge branch 'master' into get-full-blocks
shargon May 8, 2020
80bea1d
fix header_index
May 12, 2020
9ba203f
Merge branch 'get-full-blocks' of https://github.com/ShawnYun/neo int…
May 12, 2020
77485b4
modify header_index
May 13, 2020
dd1a9b7
Rename
erikzhang May 14, 2020
eb762b2
Optimize
erikzhang May 14, 2020
9eb5f18
Optimize
erikzhang May 14, 2020
4855a23
internal
erikzhang May 14, 2020
9c96d11
Remove useless code
erikzhang May 14, 2020
6302754
Reorder fields
erikzhang May 14, 2020
5a645a9
Format
erikzhang May 14, 2020
aaa1a0b
Reorder methods
erikzhang May 14, 2020
7b4b411
Merge branch 'master' into get-full-blocks
erikzhang May 14, 2020
a967ce1
fix
May 15, 2020
acd11c8
del not used
May 15, 2020
f7e1692
Merge branch 'master' into get-full-blocks
erikzhang May 15, 2020
502c5f4
Merge branch 'master' into get-full-blocks
vncoelho May 15, 2020
98f0855
resolve conflict and fix
May 18, 2020
a6e0000
add comment
May 18, 2020
de15cf9
Merge branch 'master' into get-full-blocks
erikzhang May 18, 2020
91b25b8
Merge branch 'master' into get-full-blocks
vncoelho May 19, 2020
b5cc115
Merge branch 'master' into get-full-blocks
erikzhang May 22, 2020
2529218
resolve conflicts
May 26, 2020
1149c03
format
May 26, 2020
189bd02
fix
May 26, 2020
9a69957
Optimize
erikzhang May 26, 2020
9543b27
Update TaskManager.cs
erikzhang May 26, 2020
77286f6
Update TaskManager.cs
erikzhang May 26, 2020
f93ba3a
Merge branch 'master' into get-full-blocks
erikzhang May 26, 2020
a1b6809
Improve global tasks
shargon May 26, 2020
cd41d38
Merge pull request #23 from shargon/improve-global-tasks
ShawnYun May 27, 2020
03cf387
resolve conflicts
May 27, 2020
423a7bd
Merge branch 'master' into get-full-blocks
shargon Jun 1, 2020
aec66f6
Revert counter
shargon Jun 1, 2020
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
103 changes: 13 additions & 90 deletions src/neo/Ledger/Blockchain.cs
Expand Up @@ -60,7 +60,6 @@ public class RelayResult { public IInventory Inventory; public VerifyResult Resu
private readonly NeoSystem system;
private readonly List<UInt256> header_index = new List<UInt256>();
private uint stored_header_count = 0;
private readonly Dictionary<UInt256, Block> block_cache = new Dictionary<UInt256, Block>();
erikzhang marked this conversation as resolved.
Show resolved Hide resolved
erikzhang marked this conversation as resolved.
Show resolved Hide resolved
private readonly Dictionary<uint, LinkedList<Block>> block_cache_unverified = new Dictionary<uint, LinkedList<Block>>();
internal readonly RelayCache ConsensusRelayCache = new RelayCache(100);
private SnapshotView currentSnapshot;
Expand Down Expand Up @@ -141,7 +140,6 @@ public Blockchain(NeoSystem system, IStore store)

public bool ContainsBlock(UInt256 hash)
{
if (block_cache.ContainsKey(hash)) return true;
return View.ContainsBlock(hash);
}

Expand Down Expand Up @@ -188,8 +186,6 @@ public Block GetBlock(uint index)

public Block GetBlock(UInt256 hash)
{
if (block_cache.TryGetValue(hash, out Block block))
return block;
return View.GetBlock(hash);
}

Expand All @@ -214,8 +210,6 @@ public Header GetHeader(uint index)

public Header GetHeader(UInt256 hash)
{
if (block_cache.TryGetValue(hash, out Block block))
return block.Header;
return View.GetHeader(hash);
}

Expand Down Expand Up @@ -255,12 +249,19 @@ private void OnImport(IEnumerable<Block> blocks, bool verify)

private void AddUnverifiedBlockToCache(Block block)
{
// Check if any block proposal for height `block.Index` exists
if (!block_cache_unverified.TryGetValue(block.Index, out LinkedList<Block> blocks))
{
// There are no blocks, a new LinkedList is created and, consequently, the current block is added to the list
blocks = new LinkedList<Block>();
block_cache_unverified.Add(block.Index, blocks);
}

// Check if any block with the hash being added already exists on possible candidates to be processed
foreach (var unverifiedBlock in blocks)
{
if (block.Hash == unverifiedBlock.Hash)
return;
}
blocks.AddLast(block);
}

Expand Down Expand Up @@ -311,78 +312,25 @@ private VerifyResult OnNewBlock(Block block)
{
if (block.Index <= Height)
return VerifyResult.AlreadyExists;
if (block_cache.ContainsKey(block.Hash))
return VerifyResult.AlreadyExists;
if (block.Index - 1 >= header_index.Count)
if (block.Index - 1 > Height)
{
AddUnverifiedBlockToCache(block);
return VerifyResult.UnableToVerify;
}
if (block.Index == header_index.Count)
if (block.Index == Height + 1)
{
if (!block.Verify(currentSnapshot))
return VerifyResult.Invalid;
}
else
{
if (!block.Hash.Equals(header_index[(int)block.Index]))
return VerifyResult.Invalid;
}
if (block.Index == Height + 1)
{
Block block_persist = block;
List<Block> blocksToPersistList = new List<Block>();
while (true)
{
blocksToPersistList.Add(block_persist);
if (block_persist.Index + 1 >= header_index.Count) break;
UInt256 hash = header_index[(int)block_persist.Index + 1];
if (!block_cache.TryGetValue(hash, out block_persist)) break;
}

int blocksPersisted = 0;
foreach (Block blockToPersist in blocksToPersistList)
{
block_cache_unverified.Remove(blockToPersist.Index);
Persist(blockToPersist);

// 15000 is the default among of seconds per block, while MilliSecondsPerBlock is the current
uint extraBlocks = (15000 - MillisecondsPerBlock) / 1000;

if (blocksPersisted++ < blocksToPersistList.Count - (2 + Math.Max(0, extraBlocks))) continue;
vncoelho marked this conversation as resolved.
Show resolved Hide resolved
// Empirically calibrated for relaying the most recent 2 blocks persisted with 15s network
// Increase in the rate of 1 block per second in configurations with faster blocks

if (blockToPersist.Index + 100 >= header_index.Count)
system.LocalNode.Tell(new LocalNode.RelayDirectly { Inventory = blockToPersist });
erikzhang marked this conversation as resolved.
Show resolved Hide resolved
}
block_cache_unverified.Remove(block.Index);
Persist(block);
SaveHeaderHashList();

if (block_cache_unverified.TryGetValue(Height + 1, out LinkedList<Block> unverifiedBlocks))
{
foreach (var unverifiedBlock in unverifiedBlocks)
Self.Tell(unverifiedBlock, ActorRefs.NoSender);
block_cache_unverified.Remove(Height + 1);
}
}
else
{
block_cache.Add(block.Hash, block);
if (block.Index + 100 >= header_index.Count)
system.LocalNode.Tell(new LocalNode.RelayDirectly { Inventory = block });
if (block.Index == header_index.Count)
{
header_index.Add(block.Hash);
using (SnapshotView snapshot = GetSnapshot())
{
snapshot.Blocks.Add(block.Hash, block.Header.Trim());
snapshot.HeaderHashIndex.GetAndChange().Set(block);
SaveHeaderHashList(snapshot);
snapshot.Commit();
}
UpdateCurrentSnapshot();
}
}
return VerifyResult.Succeed;
}

Expand All @@ -394,27 +342,6 @@ private VerifyResult OnNewConsensus(ConsensusPayload payload)
return VerifyResult.Succeed;
}

private void OnNewHeaders(Header[] headers)
{
using (SnapshotView snapshot = GetSnapshot())
{
foreach (Header header in headers)
{
if (header.Index - 1 >= header_index.Count) break;
if (header.Index < header_index.Count) continue;
if (!header.Verify(snapshot)) break;
header_index.Add(header.Hash);
snapshot.Blocks.Add(header.Hash, header.Trim());
snapshot.HeaderHashIndex.GetAndChange().Hash = header.Hash;
snapshot.HeaderHashIndex.GetAndChange().Index = header.Index;
}
SaveHeaderHashList(snapshot);
snapshot.Commit();
}
UpdateCurrentSnapshot();
system.TaskManager.Tell(new TaskManager.HeaderTaskCompleted(), Sender);
}

private VerifyResult OnNewTransaction(Transaction transaction)
{
if (ContainsTransaction(transaction.Hash)) return VerifyResult.AlreadyExists;
Expand All @@ -427,9 +354,9 @@ private VerifyResult OnNewTransaction(Transaction transaction)

private void OnPersistCompleted(Block block)
{
block_cache.Remove(block.Hash);
MemPool.UpdatePoolForBlockPersisted(block, currentSnapshot);
Context.System.EventStream.Publish(new PersistCompleted { Block = block });
system.LocalNode.Tell(Message.Create(MessageCommand.Ping, PingPayload.Create(Singleton.Height)));
}

protected override void OnReceive(object message)
Expand All @@ -442,9 +369,6 @@ protected override void OnReceive(object message)
case FillMemoryPool fill:
OnFillMemoryPool(fill.Transactions);
break;
case Header[] headers:
OnNewHeaders(headers);
break;
erikzhang marked this conversation as resolved.
Show resolved Hide resolved
case Block block:
OnInventory(block, false);
break;
Expand Down Expand Up @@ -593,7 +517,6 @@ internal protected override bool IsHighPriority(object message)
{
switch (message)
{
case Header[] _:
case Block _:
case ConsensusPayload _:
case Terminated _:
Expand Down
2 changes: 2 additions & 0 deletions src/neo/NeoSystem.cs
Expand Up @@ -21,6 +21,7 @@ public class NeoSystem : IDisposable
public IActorRef Blockchain { get; }
public IActorRef LocalNode { get; }
internal IActorRef TaskManager { get; }
internal IActorRef SyncManager { get; }
public IActorRef Consensus { get; private set; }

private readonly IStore store;
Expand All @@ -36,6 +37,7 @@ public NeoSystem(string storageEngine = null)
this.Blockchain = ActorSystem.ActorOf(Ledger.Blockchain.Props(this, store));
this.LocalNode = ActorSystem.ActorOf(Network.P2P.LocalNode.Props(this));
this.TaskManager = ActorSystem.ActorOf(Network.P2P.TaskManager.Props(this));
this.SyncManager = ActorSystem.ActorOf(Network.P2P.SyncManager.Props(this));
vncoelho marked this conversation as resolved.
Show resolved Hide resolved
foreach (var plugin in Plugin.Plugins)
plugin.OnPluginsLoaded();
}
Expand Down
2 changes: 1 addition & 1 deletion src/neo/Network/P2P/MessageCommand.cs
Expand Up @@ -20,7 +20,7 @@ public enum MessageCommand : byte
Pong = 0x19,

//synchronization
[ReflectionCache(typeof(GetBlocksPayload))]
[ReflectionCache(typeof(GetHeadersPayload))]
GetHeaders = 0x20,
[ReflectionCache(typeof(HeadersPayload))]
Headers = 0x21,
Expand Down
17 changes: 17 additions & 0 deletions src/neo/Network/P2P/NodeSession.cs
@@ -0,0 +1,17 @@
using System;
using System.Collections.Generic;

namespace Neo.Network.P2P
{
internal class NodeSession
{
public readonly Dictionary<UInt256, DateTime> InvTasks = new Dictionary<UInt256, DateTime>();
public Dictionary<uint, DateTime> IndexTasks = new Dictionary<uint, DateTime>();

public uint TimeoutTimes = 0;
public uint InvalidBlockCount = 0;

public bool HasInvTask => InvTasks.Count > 0;
public bool HasIndexTask => IndexTasks.Count > 0;
}
}
37 changes: 37 additions & 0 deletions src/neo/Network/P2P/Payloads/GetHeadersPayload.cs
@@ -0,0 +1,37 @@
using Neo.IO;
using System;
using System.IO;

namespace Neo.Network.P2P.Payloads
{
public class GetHeadersPayload : ISerializable
erikzhang marked this conversation as resolved.
Show resolved Hide resolved
{
public uint IndexStart;
public short Count;

public int Size => sizeof(uint) + sizeof(short);

public static GetHeadersPayload Create(uint index_start, short count = -1)
{
return new GetHeadersPayload
{
IndexStart = index_start,
Count = count
};
}

void ISerializable.Deserialize(BinaryReader reader)
{
IndexStart = reader.ReadUInt32();
Count = reader.ReadInt16();
if (Count < -1 || Count == 0 || Count > HeadersPayload.MaxHeadersCount)
throw new FormatException();
}

void ISerializable.Serialize(BinaryWriter writer)
{
writer.Write(IndexStart);
writer.Write(Count);
}
}
}
32 changes: 17 additions & 15 deletions src/neo/Network/P2P/ProtocolHandler.cs
Expand Up @@ -89,7 +89,7 @@ private void OnMessage(Message msg)
OnAddrMessageReceived((AddrPayload)msg.Payload);
break;
case MessageCommand.Block:
OnInventoryReceived((Block)msg.Payload);
OnBlockReceived((Block)msg.Payload);
ShawnYun marked this conversation as resolved.
Show resolved Hide resolved
break;
case MessageCommand.Consensus:
OnInventoryReceived((ConsensusPayload)msg.Payload);
Expand All @@ -116,7 +116,7 @@ private void OnMessage(Message msg)
OnGetDataMessageReceived((InvPayload)msg.Payload);
break;
case MessageCommand.GetHeaders:
OnGetHeadersMessageReceived((GetBlocksPayload)msg.Payload);
OnGetHeadersMessageReceived((GetHeadersPayload)msg.Payload);
break;
case MessageCommand.Headers:
OnHeadersMessageReceived((HeadersPayload)msg.Payload);
Expand Down Expand Up @@ -148,6 +148,12 @@ private void OnMessage(Message msg)
}
}

private void OnBlockReceived(Block payload)
{
if (payload != null)
ShawnYun marked this conversation as resolved.
Show resolved Hide resolved
system.SyncManager.Tell(payload, Context.Parent);
}

private void OnAddrMessageReceived(AddrPayload payload)
{
system.LocalNode.Tell(new Peer.Peers
Expand Down Expand Up @@ -282,24 +288,20 @@ private void OnGetDataMessageReceived(InvPayload payload)

/// <summary>
/// Will be triggered when a MessageCommand.GetHeaders message is received.
/// Tell the specified number of blocks' headers starting with the requested HashStart to RemoteNode actor.
/// Tell the specified number of blocks' headers starting with the requested IndexStart to RemoteNode actor.
/// A limit set by HeadersPayload.MaxHeadersCount is also applied to the number of requested Headers, namely payload.Count.
/// </summary>
/// <param name="payload">A GetBlocksPayload including start block Hash and number of blocks' headers requested.</param>
private void OnGetHeadersMessageReceived(GetBlocksPayload payload)
/// <param name="payload">A GetBlocksPayload including start block index and number of blocks' headers requested.</param>
private void OnGetHeadersMessageReceived(GetHeadersPayload payload)
{
UInt256 hash = payload.HashStart;
int count = payload.Count < 0 || payload.Count > HeadersPayload.MaxHeadersCount ? HeadersPayload.MaxHeadersCount : payload.Count;
DataCache<UInt256, TrimmedBlock> cache = Blockchain.Singleton.View.Blocks;
TrimmedBlock state = cache.TryGet(hash);
if (state == null) return;
uint index = payload.IndexStart;
int count = payload.Count < 0 ? HeadersPayload.MaxHeadersCount : payload.Count;
if (index > Blockchain.Singleton.HeaderHeight)
return;
List<Header> headers = new List<Header>();
for (uint i = 1; i <= count; i++)
for (uint i = 0; i < count; i++)
{
uint index = state.Index + i;
hash = Blockchain.Singleton.GetBlockHash(index);
if (hash == null) break;
Header header = cache.TryGet(hash)?.Header;
var header = Blockchain.Singleton.GetHeader(index + i);
if (header == null) break;
headers.Add(header);
}
Expand Down
6 changes: 4 additions & 2 deletions src/neo/Network/P2P/RemoteNode.cs
Expand Up @@ -16,6 +16,7 @@ namespace Neo.Network.P2P
public class RemoteNode : Connection
{
internal class Relay { public IInventory Inventory; }
internal NodeSession session = new NodeSession();

private readonly NeoSystem system;
private readonly IActorRef protocol;
Expand Down Expand Up @@ -161,7 +162,7 @@ private void OnPingPayload(PingPayload payload)
if (payload.LastBlockIndex > LastBlockIndex)
{
LastBlockIndex = payload.LastBlockIndex;
system.TaskManager.Tell(new TaskManager.Update { LastBlockIndex = LastBlockIndex });
system.SyncManager.Tell(new SyncManager.StartSync { });
}
}

Expand Down Expand Up @@ -195,7 +196,8 @@ private void OnSetFilter(BloomFilter filter)
private void OnVerack()
{
verack = true;
system.TaskManager.Tell(new TaskManager.Register { Version = Version });
system.TaskManager.Tell(new TaskManager.Register { Node = this });
system.SyncManager.Tell(new SyncManager.Register { Node = this });
CheckMessageQueue();
}

Expand Down