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

[neox] consensus #1719

Merged
merged 60 commits into from
Jul 13, 2020
Merged
Show file tree
Hide file tree
Changes from 57 commits
Commits
Show all changes
60 commits
Select commit Hold shift + click to select a range
3f083d2
Merge pull request #1 from neo-project/master
ZhangTao1596 Jan 20, 2020
05aaade
Merge pull request #2 from neo-project/master
ZhangTao1596 Feb 4, 2020
39da07b
Merge pull request #5 from neo-project/master
ZhangTao1596 Feb 12, 2020
caa9426
Merge branch 'master' of github.com:neo-project/neo
ZhangTao1596 Mar 24, 2020
aa06d4c
Merge branch 'master' of github.com:neo-project/neo
ZhangTao1596 Apr 23, 2020
144d8d1
Merge branch 'master' of github.com:neo-project/neo
ZhangTao1596 Jun 1, 2020
71dc2e8
Merge branch 'master' of github.com:neo-project/neo
ZhangTao1596 Jun 2, 2020
62d34b3
Merge branch 'master' of github.com:neo-project/neo
ZhangTao1596 Jun 4, 2020
f114093
don't use snapshot directly in plugin
ZhangTao1596 Jun 5, 2020
b85d68e
Merge branch 'master' of github.com:neo-project/neo
ZhangTao1596 Jun 8, 2020
b81db5b
Merge branch 'master' of github.com:neo-project/neo
ZhangTao1596 Jun 12, 2020
b05068f
recover
ZhangTao1596 Jun 12, 2020
9749c90
Merge branch 'master' of github.com:neo-project/neo
ZhangTao1596 Jun 15, 2020
8594d13
consensus state root
ZhangTao1596 Jun 15, 2020
49a0d5e
fix build error
ZhangTao1596 Jun 15, 2020
345f581
rename
ZhangTao1596 Jun 15, 2020
237622f
remerge
ZhangTao1596 Jun 15, 2020
459f2a0
rm GetMessage
ZhangTao1596 Jun 15, 2020
2bacc69
rename
ZhangTao1596 Jun 16, 2020
e54714c
Merge branch 'master' into neox-consensus
ZhangTao1596 Jun 16, 2020
58fb74f
throw exception when no script hash in state root
ZhangTao1596 Jun 16, 2020
8dc3650
Merge branch 'neox-consensus' of github.com:KickSeason/neo into neox-…
ZhangTao1596 Jun 16, 2020
ba1f143
Clean double enter
shargon Jun 16, 2020
9526939
Clean big line
shargon Jun 16, 2020
9fb7143
format
ZhangTao1596 Jun 16, 2020
b6ecba7
put root sig into request and response
ZhangTao1596 Jun 17, 2020
1e6ecf6
update consensus ut
ZhangTao1596 Jun 18, 2020
821fd73
Check Json.Serialize map keys (#1705)
shargon Jun 17, 2020
52272ec
don't use snapshot directly in plugin
ZhangTao1596 Jun 5, 2020
f029dde
recover
ZhangTao1596 Jun 12, 2020
d04529a
consensus state root
ZhangTao1596 Jun 15, 2020
82c11a5
fix build error
ZhangTao1596 Jun 15, 2020
c87bc17
rename
ZhangTao1596 Jun 15, 2020
44d7210
remerge
ZhangTao1596 Jun 15, 2020
0d8723c
rm GetMessage
ZhangTao1596 Jun 15, 2020
9c2415d
rename
ZhangTao1596 Jun 16, 2020
2db1fbe
throw exception when no script hash in state root
ZhangTao1596 Jun 16, 2020
96db344
Clean double enter
shargon Jun 16, 2020
a9bc94b
Clean big line
shargon Jun 16, 2020
cfe7322
format
ZhangTao1596 Jun 16, 2020
880957d
put root sig into request and response
ZhangTao1596 Jun 17, 2020
d24c43c
update consensus ut
ZhangTao1596 Jun 18, 2020
014d9a1
Merge branch 'neox-consensus' of github.com:KickSeason/neo into neox-…
ZhangTao1596 Jun 18, 2020
56ea966
fix some
ZhangTao1596 Jun 18, 2020
1d30bb0
fix some
ZhangTao1596 Jun 18, 2020
32fed3c
format
ZhangTao1596 Jun 18, 2020
d33d445
comment
ZhangTao1596 Jun 18, 2020
a797876
fix
ZhangTao1596 Jun 18, 2020
5567612
requst in recovery
ZhangTao1596 Jun 18, 2020
7dfb06d
StateRootSignature fixed size
ZhangTao1596 Jun 18, 2020
2caf3af
no need ?
ZhangTao1596 Jun 18, 2020
98af51a
format
ZhangTao1596 Jun 18, 2020
90de06a
Merge branch 'master' into neox-consensus
ZhangTao1596 Jun 18, 2020
605a2e4
Merge branch 'master' into neox-consensus
ZhangTao1596 Jun 19, 2020
5d9d0aa
Merge branch 'master' into neox-consensus
ZhangTao1596 Jun 20, 2020
eafe588
Merge branch 'master' into neox-consensus
ZhangTao1596 Jun 22, 2020
3474168
Merge branch 'neox' into neox-consensus
shargon Jun 29, 2020
d87934d
Update ConsensusContext.cs
shargon Jul 8, 2020
e1e0fc2
Check sc.Complete
shargon Jul 8, 2020
5b5c772
Merge remote-tracking branch 'KickSeason/neox-consensus' into neox-co…
shargon Jul 8, 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
48 changes: 39 additions & 9 deletions src/neo/Consensus/ConsensusContext.cs
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ internal class ConsensusContext : IDisposable, ISerializable
private const byte ConsensusStatePrefix = 0xf4;

public Block Block;
public StateRoot PreviousBlockStateRoot;
public byte ViewNumber;
public ECPoint[] Validators;
public int MyIndex;
Expand Down Expand Up @@ -96,6 +97,24 @@ public Block CreateBlock()
return Block;
}

public StateRoot CreateStateRoot()
{
EnsureHeader();
Contract contract = Contract.CreateMultiSigContract(M, Validators);
ContractParametersContext sc = new ContractParametersContext(PreviousBlockStateRoot);
for (int i = 0, j = 0; i < Validators.Length && j < M; i++)
{
if (PreparationPayloads[i]?.ConsensusMessage.ViewNumber != ViewNumber) continue;
if (i == GetPrimaryIndex(ViewNumber))
sc.AddSignature(contract, Validators[i], PreparationPayloads[i].GetDeserializedMessage<PrepareRequest>().StateRootSignature);
else
sc.AddSignature(contract, Validators[i], PreparationPayloads[i].GetDeserializedMessage<PrepareResponse>().StateRootSignature);
j++;
}
PreviousBlockStateRoot.Witness = sc.GetWitnesses()[0];
shargon marked this conversation as resolved.
Show resolved Hide resolved
return PreviousBlockStateRoot;
}

public void Deserialize(BinaryReader reader)
{
Reset(0);
Expand Down Expand Up @@ -137,6 +156,20 @@ public Block EnsureHeader()
return Block;
}

public StateRoot EnsureStateRoot()
{
if (PreviousBlockStateRoot is null)
{
PreviousBlockStateRoot = new StateRoot
{
Version = 0,
Index = Block.Index - 1,
RootHash = Blockchain.Singleton.GetLocalStateRoot(Block.Index - 1)
};
}
return PreviousBlockStateRoot;
}

[MethodImpl(MethodImplOptions.AggressiveInlining)]
public uint GetPrimaryIndex(byte viewNumber)
{
Expand Down Expand Up @@ -304,7 +337,8 @@ public ConsensusPayload MakePrepareRequest()
{
Timestamp = Block.Timestamp,
Nonce = Block.ConsensusData.Nonce,
TransactionHashes = TransactionHashes
TransactionHashes = TransactionHashes,
StateRootSignature = EnsureStateRoot().Sign(keyPair)
});
}

Expand All @@ -321,13 +355,7 @@ public ConsensusPayload MakeRecoveryMessage()
PrepareRequest prepareRequestMessage = null;
if (TransactionHashes != null)
{
prepareRequestMessage = new PrepareRequest
{
ViewNumber = ViewNumber,
Timestamp = Block.Timestamp,
Nonce = Block.ConsensusData.Nonce,
TransactionHashes = TransactionHashes
};
prepareRequestMessage = PreparationPayloads[GetPrimaryIndex(ViewNumber)].GetDeserializedMessage<PrepareRequest>();
}
return MakeSignedPayload(new RecoveryMessage()
{
Expand All @@ -346,7 +374,8 @@ public ConsensusPayload MakePrepareResponse()
{
return PreparationPayloads[MyIndex] = MakeSignedPayload(new PrepareResponse
{
PreparationHash = PreparationPayloads[Block.ConsensusData.PrimaryIndex].Hash
PreparationHash = PreparationPayloads[Block.ConsensusData.PrimaryIndex].Hash,
StateRootSignature = EnsureStateRoot().Sign(keyPair)
});
}

Expand Down Expand Up @@ -399,6 +428,7 @@ public void Reset(byte viewNumber)
keyPair = account.GetKey();
break;
}
PreviousBlockStateRoot = null;
}
else
{
Expand Down
16 changes: 16 additions & 0 deletions src/neo/Consensus/ConsensusService.cs
Original file line number Diff line number Diff line change
Expand Up @@ -165,6 +165,10 @@ private void CheckPreparations()
localNode.Tell(new LocalNode.SendDirectly { Inventory = payload });
// Set timer, so we will resend the commit in case of a networking issue
ChangeTimer(TimeSpan.FromMilliseconds(Blockchain.MillisecondsPerBlock));

StateRoot stateRoot = context.CreateStateRoot();
Log($"relay state root, index={stateRoot.Index}, root_hash={stateRoot.RootHash}");
blockchain.Tell(stateRoot);
CheckCommits();
}
}
Expand Down Expand Up @@ -424,6 +428,12 @@ private void OnPrepareRequestReceived(ConsensusPayload payload, PrepareRequest m
Log($"Invalid request: transaction already exists", LogLevel.Warning);
return;
}
var stateRootHashData = context.EnsureStateRoot().GetHashData();
if (!Crypto.VerifySignature(stateRootHashData, message.StateRootSignature, context.Validators[payload.ValidatorIndex]))
{
Log($"Invalid request: invalid state root signature", LogLevel.Warning);
return;
}

// Timeout extension: prepare request has been received with success
// around 2*15/M=30.0/5 ~ 40% block time (for M=5)
Expand Down Expand Up @@ -486,6 +496,12 @@ private void OnPrepareResponseReceived(ConsensusPayload payload, PrepareResponse
if (context.PreparationPayloads[payload.ValidatorIndex] != null || context.NotAcceptingPayloadsDueToViewChanging) return;
if (context.PreparationPayloads[context.Block.ConsensusData.PrimaryIndex] != null && !message.PreparationHash.Equals(context.PreparationPayloads[context.Block.ConsensusData.PrimaryIndex].Hash))
return;
byte[] stateRootHashData = context.EnsureStateRoot().GetHashData();
if (!Crypto.VerifySignature(stateRootHashData, message.StateRootSignature, context.Validators[payload.ValidatorIndex]))
{
Log($"Invalid response: invalid state root signature, height={payload.BlockIndex} view={message.ViewNumber} index={payload.ValidatorIndex}", LogLevel.Warning);
return;
}

// Timeout extension: prepare response has been received with success
// around 2*15/M=30.0/5 ~ 40% block time (for M=5)
Expand Down
8 changes: 6 additions & 2 deletions src/neo/Consensus/PrepareRequest.cs
Original file line number Diff line number Diff line change
Expand Up @@ -11,11 +11,13 @@ public class PrepareRequest : ConsensusMessage
public ulong Timestamp;
public ulong Nonce;
public UInt256[] TransactionHashes;
public byte[] StateRootSignature;

public override int Size => base.Size
+ sizeof(ulong) //Timestamp
+ sizeof(ulong) //Timestamp
+ sizeof(ulong) //Nonce
+ TransactionHashes.GetVarSize(); //TransactionHashes
+ TransactionHashes.GetVarSize() //TransactionHashes
+ StateRootSignature.Length; //StateRootSignature

public PrepareRequest()
: base(ConsensusMessageType.PrepareRequest)
Expand All @@ -30,6 +32,7 @@ public override void Deserialize(BinaryReader reader)
TransactionHashes = reader.ReadSerializableArray<UInt256>(Block.MaxTransactionsPerBlock);
if (TransactionHashes.Distinct().Count() != TransactionHashes.Length)
throw new FormatException();
StateRootSignature = reader.ReadFixedBytes(64);
}

public override void Serialize(BinaryWriter writer)
Expand All @@ -38,6 +41,7 @@ public override void Serialize(BinaryWriter writer)
writer.Write(Timestamp);
writer.Write(Nonce);
writer.Write(TransactionHashes);
writer.Write(StateRootSignature);
}
}
}
5 changes: 4 additions & 1 deletion src/neo/Consensus/PrepareResponse.cs
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,9 @@ namespace Neo.Consensus
public class PrepareResponse : ConsensusMessage
{
public UInt256 PreparationHash;
public byte[] StateRootSignature;

public override int Size => base.Size + PreparationHash.Size;
public override int Size => base.Size + PreparationHash.Size + StateRootSignature.Length;

public PrepareResponse()
: base(ConsensusMessageType.PrepareResponse)
Expand All @@ -18,12 +19,14 @@ public override void Deserialize(BinaryReader reader)
{
base.Deserialize(reader);
PreparationHash = reader.ReadSerializable<UInt256>();
StateRootSignature = reader.ReadFixedBytes(64);
}

public override void Serialize(BinaryWriter writer)
{
base.Serialize(writer);
writer.Write(PreparationHash);
writer.Write(StateRootSignature);
}
}
}
17 changes: 14 additions & 3 deletions src/neo/Consensus/RecoveryMessage.PreparationPayloadCompact.cs
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
using Neo.IO;
using Neo.Network.P2P.Payloads;
using System;
using System.IO;

namespace Neo.Consensus
Expand All @@ -10,30 +11,40 @@ public class PreparationPayloadCompact : ISerializable
{
public ushort ValidatorIndex;
public byte[] InvocationScript;
public byte[] StateRootSignature;

int ISerializable.Size =>
sizeof(ushort) + //ValidatorIndex
InvocationScript.GetVarSize(); //InvocationScript
sizeof(ushort) + //ValidatorIndex
InvocationScript.GetVarSize() + //InvocationScript
StateRootSignature.Length; //StateRootSignature

void ISerializable.Deserialize(BinaryReader reader)
{
ValidatorIndex = reader.ReadUInt16();
InvocationScript = reader.ReadVarBytes(1024);
StateRootSignature = reader.ReadFixedBytes(64);
}

public static PreparationPayloadCompact FromPayload(ConsensusPayload payload)
{
byte[] state_root_sig = Array.Empty<byte>();
if (payload.ConsensusMessage is PrepareResponse req)
state_root_sig = req.StateRootSignature;
else if (payload.ConsensusMessage is PrepareResponse resp)
state_root_sig = resp.StateRootSignature;
return new PreparationPayloadCompact
{
ValidatorIndex = payload.ValidatorIndex,
InvocationScript = payload.Witness.InvocationScript
InvocationScript = payload.Witness.InvocationScript,
StateRootSignature = state_root_sig
};
}

void ISerializable.Serialize(BinaryWriter writer)
{
writer.Write(ValidatorIndex);
writer.WriteVarBytes(InvocationScript);
writer.Write(StateRootSignature);
}
}
}
Expand Down
3 changes: 2 additions & 1 deletion src/neo/Consensus/RecoveryMessage.cs
Original file line number Diff line number Diff line change
Expand Up @@ -120,7 +120,8 @@ internal ConsensusPayload[] GetPrepareResponsePayloads(ConsensusContext context,
ConsensusMessage = new PrepareResponse
{
ViewNumber = ViewNumber,
PreparationHash = preparationHash
PreparationHash = preparationHash,
StateRootSignature = p.StateRootSignature
},
Witness = new Witness
{
Expand Down
12 changes: 12 additions & 0 deletions src/neo/Ledger/Blockchain.state.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
using Akka.Actor;

namespace Neo.Ledger
{
public sealed partial class Blockchain : UntypedActor
{
public UInt256 GetLocalStateRoot(uint index)
{
return UInt256.Zero;
}
}
}
8 changes: 4 additions & 4 deletions src/neo/Network/P2P/Payloads/StateRoot.cs
Original file line number Diff line number Diff line change
Expand Up @@ -47,10 +47,10 @@ Witness[] IVerifiable.Witnesses
}

public int Size =>
sizeof(byte) + //Version
sizeof(uint) + //Index
UInt256.Length + //Root
Witness.Size; //Witness
sizeof(byte) + //Version
sizeof(uint) + //Index
UInt256.Length + //RootHash
Witness.Size; //Witness

StateRoot ICloneable<StateRoot>.Clone()
{
Expand Down
Loading