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

modify get headers #19

Open
wants to merge 50 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
50 commits
Select commit Hold shift + click to select a range
985bef4
get-full-block
Dec 17, 2019
990cd12
update get-full-block
Dec 26, 2019
126dde0
fix
Dec 26, 2019
6cf3231
modify
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
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
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
105 changes: 16 additions & 89 deletions src/neo/Ledger/Blockchain.cs
Original file line number Diff line number Diff line change
Expand Up @@ -61,7 +61,6 @@ private class ParallelVerified { public Transaction Transaction; public bool Sho
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>();
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 @@ -142,7 +141,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 @@ -189,8 +187,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 @@ -215,8 +211,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 @@ -256,12 +250,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 @@ -294,78 +295,30 @@ private RelayResultReason OnNewBlock(Block block)
{
if (block.Index <= Height)
return RelayResultReason.AlreadyExists;
if (block_cache.ContainsKey(block.Hash))
return RelayResultReason.AlreadyExists;
if (block.Index - 1 >= header_index.Count)
if (block.Index - 1 > Height)
{
AddUnverifiedBlockToCache(block);
return RelayResultReason.UnableToVerify;
}
if (block.Index == header_index.Count)
{
if (!block.Verify(currentSnapshot))
return RelayResultReason.Invalid;
}
else
{
if (!block.Hash.Equals(header_index[(int)block.Index]))
return RelayResultReason.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)
if (!block.Verify(currentSnapshot))
{
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;
// 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 });
system.SyncManager.Tell(new SyncManager.InvalidBlockIndex { InvalidIndex = block.Index });
return RelayResultReason.Invalid;
}
block_cache_unverified.Remove(block.Index);
Persist(block);
system.LocalNode.Tell(Message.Create(MessageCommand.Ping, PingPayload.Create(Singleton.Height)));
system.SyncManager.Tell(new SyncManager.PersistedBlockIndex { PersistedIndex = block.Index });
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 RelayResultReason.Succeed;
}

Expand All @@ -378,27 +331,6 @@ private RelayResultReason OnNewConsensus(ConsensusPayload payload)
return RelayResultReason.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 void OnNewTransaction(Transaction transaction, bool relay)
{
RelayResultReason reason;
Expand Down Expand Up @@ -445,7 +377,6 @@ private void OnParallelVerified(ParallelVerified parallelVerified)

private void OnPersistCompleted(Block block)
{
block_cache.Remove(block.Hash);
MemPool.UpdatePoolForBlockPersisted(block, currentSnapshot);
Context.System.EventStream.Publish(new PersistCompleted { Block = block });
}
Expand All @@ -460,9 +391,6 @@ protected override void OnReceive(object message)
case FillMemoryPool fill:
OnFillMemoryPool(fill.Transactions);
break;
case Header[] headers:
OnNewHeaders(headers);
break;
case Block block:
Sender.Tell(OnNewBlock(block));
break;
Expand Down Expand Up @@ -614,7 +542,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
Original file line number Diff line number Diff line change
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));
foreach (var plugin in Plugin.Plugins)
plugin.OnPluginsLoaded();
}
Expand Down
2 changes: 1 addition & 1 deletion src/neo/Network/P2P/MessageCommand.cs
Original file line number Diff line number Diff line change
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
Original file line number Diff line number Diff line change
@@ -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
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
using Neo.IO;
using System;
using System.IO;

namespace Neo.Network.P2P.Payloads
{
public class GetHeadersPayload : ISerializable
{
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
Original file line number Diff line number Diff line change
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);
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)
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
Original file line number Diff line number Diff line change
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
Loading