From bd8690d8f89364ff0c35a1572c82d4ea0bfb8460 Mon Sep 17 00:00:00 2001 From: Chanhyuck Ko Date: Thu, 11 Apr 2024 18:41:17 +0900 Subject: [PATCH] feat: implement vote power --- Libplanet.Action.Tests/ActionContextTest.cs | 2 + .../ActionEvaluationTest.cs | 2 + Libplanet.Action.Tests/Sys/InitializeTest.cs | 1 + Libplanet.Benchmarks/Commit.cs | 2 + .../GeneratedBlockChainFixture.cs | 2 + .../GraphTypes/BlockCommitTypeTest.cs | 2 + .../GraphTypes/BlockTypeTest.cs | 4 + .../GraphTypes/VoteTypeTest.cs | 4 + .../Indexing/BlockChainIndexTest.cs | 2 + Libplanet.Explorer/GraphTypes/VoteType.cs | 4 + .../ConsensusContextNonProposerTest.cs | 13 +- .../Consensus/ConsensusContextProposerTest.cs | 8 + .../Consensus/ConsensusContextTest.cs | 43 ++++- .../Consensus/ContextNonProposerTest.cs | 170 +++++++++++++++--- .../Consensus/ContextProposerTest.cs | 57 +++++- .../ContextProposerValidRoundTest.cs | 11 ++ Libplanet.Net.Tests/Consensus/ContextTest.cs | 14 ++ .../GossipConsensusMessageCommunicatorTest.cs | 75 ++++++-- .../Consensus/HeightVoteSetTest.cs | 36 +++- Libplanet.Net.Tests/Consensus/VoteSetTest.cs | 12 +- Libplanet.Net.Tests/Messages/MessageTest.cs | 4 +- .../Messages/NetMQMessageCodecTest.cs | 3 + Libplanet.Net.Tests/SwarmTest.Preload.cs | 9 +- Libplanet.Net.Tests/SwarmTest.cs | 6 +- Libplanet.Net.Tests/TestUtils.cs | 40 +++-- Libplanet.Net/Consensus/Context.cs | 1 + Libplanet.Net/Consensus/VoteSet.cs | 1 + Libplanet.Tests/Action/ActionEvaluatorTest.cs | 6 +- .../Blockchain/BlockChainTest.ProposeBlock.cs | 2 + .../BlockChainTest.ValidateNextBlock.cs | 37 ++-- Libplanet.Tests/Blockchain/BlockChainTest.cs | 57 +++--- Libplanet.Tests/Blocks/BlockCommitTest.cs | 35 +++- Libplanet.Tests/Blocks/BlockFixture.cs | 1 + Libplanet.Tests/Blocks/BlockMetadataTest.cs | 4 +- Libplanet.Tests/Blocks/BlockTest.cs | 10 +- Libplanet.Tests/Consensus/ValidatorSetTest.cs | 24 ++- Libplanet.Tests/Consensus/VoteMetadataTest.cs | 20 ++- Libplanet.Tests/Consensus/VoteTest.cs | 9 + Libplanet.Tests/Store/StoreFixture.cs | 4 + Libplanet.Tests/Store/StoreTest.cs | 5 + Libplanet.Tests/TestUtils.cs | 23 ++- .../Blocks/PreEvaluationBlockHeader.cs | 2 +- Libplanet.Types/Consensus/IVoteMetadata.cs | 6 + Libplanet.Types/Consensus/Vote.cs | 4 + Libplanet.Types/Consensus/VoteMetadata.cs | 19 ++ 45 files changed, 640 insertions(+), 156 deletions(-) diff --git a/Libplanet.Action.Tests/ActionContextTest.cs b/Libplanet.Action.Tests/ActionContextTest.cs index 85990cf5193..d341fdefa2b 100644 --- a/Libplanet.Action.Tests/ActionContextTest.cs +++ b/Libplanet.Action.Tests/ActionContextTest.cs @@ -1,4 +1,5 @@ using System.Collections.Immutable; +using System.Numerics; using Libplanet.Action.State; using Libplanet.Action.Tests.Mocks; using Libplanet.Crypto; @@ -35,6 +36,7 @@ public ActionContextTest() hash, DateTimeOffset.UtcNow, key.PublicKey, + BigInteger.One, VoteFlag.PreCommit).Sign(key), }.ToImmutableArray()); } diff --git a/Libplanet.Action.Tests/ActionEvaluationTest.cs b/Libplanet.Action.Tests/ActionEvaluationTest.cs index 851d2894445..849feb0733e 100644 --- a/Libplanet.Action.Tests/ActionEvaluationTest.cs +++ b/Libplanet.Action.Tests/ActionEvaluationTest.cs @@ -1,4 +1,5 @@ using System.Collections.Immutable; +using System.Numerics; using Bencodex.Types; using Libplanet.Action.State; using Libplanet.Action.Tests.Common; @@ -46,6 +47,7 @@ public void Constructor() hash, DateTimeOffset.UtcNow, key.PublicKey, + BigInteger.One, VoteFlag.PreCommit).Sign(key), }.ToImmutableArray()); IWorld world = new World(new MockWorldState()); diff --git a/Libplanet.Action.Tests/Sys/InitializeTest.cs b/Libplanet.Action.Tests/Sys/InitializeTest.cs index 624ba7ba630..09d9242c70f 100644 --- a/Libplanet.Action.Tests/Sys/InitializeTest.cs +++ b/Libplanet.Action.Tests/Sys/InitializeTest.cs @@ -91,6 +91,7 @@ public void ExecuteInNonGenesis() hash, DateTimeOffset.UtcNow, key.PublicKey, + BigInteger.One, VoteFlag.PreCommit).Sign(key), }.ToImmutableArray()); var context = new ActionContext( diff --git a/Libplanet.Benchmarks/Commit.cs b/Libplanet.Benchmarks/Commit.cs index 4318b481620..6af0c370898 100644 --- a/Libplanet.Benchmarks/Commit.cs +++ b/Libplanet.Benchmarks/Commit.cs @@ -1,6 +1,7 @@ using System; using System.Collections.Immutable; using System.Linq; +using System.Numerics; using BenchmarkDotNet.Attributes; using Libplanet.Crypto; using Libplanet.Types.Blocks; @@ -65,6 +66,7 @@ private void SetupVotes() _blockHash, DateTimeOffset.UtcNow, _privateKeys[x].PublicKey, + BigInteger.One, VoteFlag.PreCommit).Sign(_privateKeys[x])) .ToArray(); } diff --git a/Libplanet.Explorer.Tests/GeneratedBlockChainFixture.cs b/Libplanet.Explorer.Tests/GeneratedBlockChainFixture.cs index 2f2157cac10..34baa7bbe01 100644 --- a/Libplanet.Explorer.Tests/GeneratedBlockChainFixture.cs +++ b/Libplanet.Explorer.Tests/GeneratedBlockChainFixture.cs @@ -1,6 +1,7 @@ using System; using System.Collections.Immutable; using System.Linq; +using System.Numerics; using Bencodex.Types; using Libplanet.Action; using Libplanet.Action.Loader; @@ -196,6 +197,7 @@ private void AddBlock(ImmutableArray transactions) block.Hash, DateTimeOffset.UtcNow, pk.PublicKey, + BigInteger.One, VoteFlag.PreCommit).Sign(pk)).ToImmutableArray())); MinedBlocks = MinedBlocks .SetItem( diff --git a/Libplanet.Explorer.Tests/GraphTypes/BlockCommitTypeTest.cs b/Libplanet.Explorer.Tests/GraphTypes/BlockCommitTypeTest.cs index 08b0ac49d3c..860a24a06a2 100644 --- a/Libplanet.Explorer.Tests/GraphTypes/BlockCommitTypeTest.cs +++ b/Libplanet.Explorer.Tests/GraphTypes/BlockCommitTypeTest.cs @@ -1,6 +1,7 @@ using System; using System.Collections.Generic; using System.Collections.Immutable; +using System.Numerics; using GraphQL; using GraphQL.Types; using GraphQL.Execution; @@ -28,6 +29,7 @@ public async void Query() blockHash, DateTimeOffset.Now, privateKey.PublicKey, + BigInteger.One, VoteFlag.PreCommit).Sign(privateKey); var blockCommit = new BlockCommit(1, 0, blockHash, ImmutableArray.Create(vote)); diff --git a/Libplanet.Explorer.Tests/GraphTypes/BlockTypeTest.cs b/Libplanet.Explorer.Tests/GraphTypes/BlockTypeTest.cs index bfaa8bc8077..98a786506f9 100644 --- a/Libplanet.Explorer.Tests/GraphTypes/BlockTypeTest.cs +++ b/Libplanet.Explorer.Tests/GraphTypes/BlockTypeTest.cs @@ -1,6 +1,7 @@ using System; using System.Collections.Generic; using System.Collections.Immutable; +using System.Numerics; using System.Security.Cryptography; using GraphQL; using GraphQL.Execution; @@ -31,6 +32,7 @@ public async void Query() lastBlockHash, DateTimeOffset.Now, privateKey.PublicKey, + BigInteger.One, VoteFlag.PreCommit).Sign(privateKey)); var lastBlockCommit = new BlockCommit(1, 0, lastBlockHash, lastVotes); var preEval = new BlockContent( @@ -70,6 +72,7 @@ public async void Query() blockHash timestamp validatorPublicKey + validatorPower flag signature } @@ -117,6 +120,7 @@ public async void Query() { "blockHash", lastVotes[0].BlockHash.ToString() }, { "timestamp", new DateTimeOffsetGraphType().Serialize(lastVotes[0].Timestamp) }, { "validatorPublicKey", lastVotes[0].ValidatorPublicKey.ToString() }, + { "validatorPower", lastVotes[0].ValidatorPower }, { "flag", lastVotes[0].Flag.ToString() }, { "signature", ByteUtil.Hex(lastVotes[0].Signature) }, } diff --git a/Libplanet.Explorer.Tests/GraphTypes/VoteTypeTest.cs b/Libplanet.Explorer.Tests/GraphTypes/VoteTypeTest.cs index 24cc0213752..475928c556f 100644 --- a/Libplanet.Explorer.Tests/GraphTypes/VoteTypeTest.cs +++ b/Libplanet.Explorer.Tests/GraphTypes/VoteTypeTest.cs @@ -1,5 +1,6 @@ using System; using System.Collections.Generic; +using System.Numerics; using GraphQL; using GraphQL.Types; using GraphQL.Execution; @@ -27,6 +28,7 @@ public async void Query() blockHash, DateTimeOffset.Now, privateKey.PublicKey, + 123, VoteFlag.PreCommit).Sign(privateKey); var query = @@ -36,6 +38,7 @@ public async void Query() blockHash timestamp validatorPublicKey + validatorPower flag signature }"; @@ -54,6 +57,7 @@ public async void Query() Assert.Equal(vote.BlockHash.ToString(), resultData["blockHash"]); Assert.Equal(new DateTimeOffsetGraphType().Serialize(vote.Timestamp), resultData["timestamp"]); Assert.Equal(vote.ValidatorPublicKey.ToString(), resultData["validatorPublicKey"]); + Assert.Equal(vote.ValidatorPower, resultData["validatorPower"]); Assert.Equal(vote.Flag.ToString(), resultData["flag"]); Assert.Equal(ByteUtil.Hex(vote.Signature), resultData["signature"]); } diff --git a/Libplanet.Explorer.Tests/Indexing/BlockChainIndexTest.cs b/Libplanet.Explorer.Tests/Indexing/BlockChainIndexTest.cs index 8a8ae4aaf89..cbc4ee73beb 100644 --- a/Libplanet.Explorer.Tests/Indexing/BlockChainIndexTest.cs +++ b/Libplanet.Explorer.Tests/Indexing/BlockChainIndexTest.cs @@ -2,6 +2,7 @@ using System.Collections.Generic; using System.Collections.Immutable; using System.Linq; +using System.Numerics; using System.Threading; using System.Threading.Tasks; using Libplanet.Crypto; @@ -57,6 +58,7 @@ await index.SynchronizeAsync( divergentBlock.Hash, DateTimeOffset.UtcNow, pk.PublicKey, + BigInteger.One, VoteFlag.PreCommit) .Sign(pk)) .ToImmutableArray())); diff --git a/Libplanet.Explorer/GraphTypes/VoteType.cs b/Libplanet.Explorer/GraphTypes/VoteType.cs index d7f1e188b3c..cc0fede8e59 100644 --- a/Libplanet.Explorer/GraphTypes/VoteType.cs +++ b/Libplanet.Explorer/GraphTypes/VoteType.cs @@ -30,6 +30,10 @@ public VoteType() "ValidatorPublicKey", description: "Public key of the validator which is subject of the vote.", resolve: ctx => ctx.Source.ValidatorPublicKey); + Field>( + "ValidatorPower", + description: "Power of the validator which is subject of the vote.", + resolve: ctx => ctx.Source.ValidatorPower); Field>( "Flag", description: "Flag of the vote", diff --git a/Libplanet.Net.Tests/Consensus/ConsensusContextNonProposerTest.cs b/Libplanet.Net.Tests/Consensus/ConsensusContextNonProposerTest.cs index fb1caf88646..6ad253338e3 100644 --- a/Libplanet.Net.Tests/Consensus/ConsensusContextNonProposerTest.cs +++ b/Libplanet.Net.Tests/Consensus/ConsensusContextNonProposerTest.cs @@ -1,6 +1,7 @@ using System; using System.Collections.Immutable; using System.Linq; +using System.Numerics; using Bencodex; using Bencodex.Types; using Libplanet.Crypto; @@ -72,6 +73,7 @@ public async void NewHeightWithLastCommit() block1.Hash, DateTimeOffset.UtcNow, TestUtils.ValidatorSet[i].PublicKey, + TestUtils.ValidatorSet[i].Power, VoteFlag.PreVote).Sign(TestUtils.PrivateKeys[i]); consensusContext.HandleMessage(new ConsensusPreVoteMsg(expectedVotes[i])); } @@ -86,6 +88,7 @@ public async void NewHeightWithLastCommit() block1.Hash, DateTimeOffset.UtcNow, TestUtils.ValidatorSet[i].PublicKey, + TestUtils.ValidatorSet[i].Power, VoteFlag.PreCommit).Sign(TestUtils.PrivateKeys[i]); consensusContext.HandleMessage(new ConsensusPreCommitMsg(expectedVotes[i])); } @@ -174,9 +177,9 @@ public async void HandleMessageFromHigherHeight() throw new Exception("Proposal is null."); } - foreach ((PrivateKey privateKey, BoundPeer peer) + foreach ((PrivateKey privateKey, BigInteger power) in TestUtils.PrivateKeys.Zip( - TestUtils.Peers, + TestUtils.ValidatorSet.Validators.Select(v => v.Power), (first, second) => (first, second))) { if (privateKey == TestUtils.PrivateKeys[2]) @@ -193,12 +196,13 @@ in TestUtils.PrivateKeys.Zip( proposal!.BlockHash, DateTimeOffset.UtcNow, privateKey.PublicKey, + power, VoteFlag.PreVote).Sign(privateKey))); } - foreach ((PrivateKey privateKey, BoundPeer peer) + foreach ((PrivateKey privateKey, BigInteger power) in TestUtils.PrivateKeys.Zip( - TestUtils.Peers, + TestUtils.ValidatorSet.Validators.Select(v => v.Power), (first, second) => (first, second))) { if (privateKey == TestUtils.PrivateKeys[2]) @@ -215,6 +219,7 @@ in TestUtils.PrivateKeys.Zip( proposal!.BlockHash, DateTimeOffset.UtcNow, privateKey.PublicKey, + power, VoteFlag.PreCommit).Sign(privateKey))); } diff --git a/Libplanet.Net.Tests/Consensus/ConsensusContextProposerTest.cs b/Libplanet.Net.Tests/Consensus/ConsensusContextProposerTest.cs index 9b93e649317..4b7128a9cf1 100644 --- a/Libplanet.Net.Tests/Consensus/ConsensusContextProposerTest.cs +++ b/Libplanet.Net.Tests/Consensus/ConsensusContextProposerTest.cs @@ -56,7 +56,9 @@ public async void IncreaseRoundWhenTimeout() new ConsensusPreVoteMsg( TestUtils.CreateVote( TestUtils.PrivateKeys[2], + TestUtils.ValidatorSet[2].Power, 1, + 0, hash: default, flag: VoteFlag.PreVote))); @@ -64,7 +66,9 @@ public async void IncreaseRoundWhenTimeout() new ConsensusPreVoteMsg( vote: TestUtils.CreateVote( TestUtils.PrivateKeys[3], + TestUtils.ValidatorSet[3].Power, 1, + 0, hash: default, flag: VoteFlag.PreVote))); @@ -74,7 +78,9 @@ public async void IncreaseRoundWhenTimeout() new ConsensusPreCommitMsg( TestUtils.CreateVote( TestUtils.PrivateKeys[2], + TestUtils.ValidatorSet[2].Power, 1, + 0, hash: default, flag: VoteFlag.PreCommit))); @@ -82,7 +88,9 @@ public async void IncreaseRoundWhenTimeout() new ConsensusPreCommitMsg( vote: TestUtils.CreateVote( TestUtils.PrivateKeys[3], + TestUtils.ValidatorSet[3].Power, 1, + 0, hash: default, flag: VoteFlag.PreCommit))); diff --git a/Libplanet.Net.Tests/Consensus/ConsensusContextTest.cs b/Libplanet.Net.Tests/Consensus/ConsensusContextTest.cs index 6068a2703cc..f1b8a6fc7a8 100644 --- a/Libplanet.Net.Tests/Consensus/ConsensusContextTest.cs +++ b/Libplanet.Net.Tests/Consensus/ConsensusContextTest.cs @@ -1,6 +1,7 @@ using System; using System.Collections.Generic; using System.Linq; +using System.Numerics; using System.Threading.Tasks; using Bencodex; using Libplanet.Consensus; @@ -91,12 +92,33 @@ public async void NewHeightIncreasing() await proposalMessageSent.WaitAsync(); BlockHash proposedblockHash = Assert.IsType(proposal?.BlockHash); - consensusContext.HandleMessage(new ConsensusPreCommitMsg(TestUtils.CreateVote( - TestUtils.PrivateKeys[0], 3, hash: proposedblockHash, flag: VoteFlag.PreCommit))); - consensusContext.HandleMessage(new ConsensusPreCommitMsg(TestUtils.CreateVote( - TestUtils.PrivateKeys[1], 3, hash: proposedblockHash, flag: VoteFlag.PreCommit))); - consensusContext.HandleMessage(new ConsensusPreCommitMsg(TestUtils.CreateVote( - TestUtils.PrivateKeys[2], 3, hash: proposedblockHash, flag: VoteFlag.PreCommit))); + consensusContext.HandleMessage( + new ConsensusPreCommitMsg( + TestUtils.CreateVote( + TestUtils.PrivateKeys[0], + TestUtils.ValidatorSet[0].Power, + 3, + 0, + hash: proposedblockHash, + flag: VoteFlag.PreCommit))); + consensusContext.HandleMessage( + new ConsensusPreCommitMsg( + TestUtils.CreateVote( + TestUtils.PrivateKeys[1], + TestUtils.ValidatorSet[1].Power, + 3, + 0, + hash: proposedblockHash, + flag: VoteFlag.PreCommit))); + consensusContext.HandleMessage( + new ConsensusPreCommitMsg( + TestUtils.CreateVote( + TestUtils.PrivateKeys[2], + TestUtils.ValidatorSet[2].Power, + 3, + 0, + hash: proposedblockHash, + flag: VoteFlag.PreCommit))); // Waiting for commit. await heightThreeStepChangedToEndCommit.WaitAsync(); @@ -228,12 +250,14 @@ public async void VoteSetGetOnlyProposeCommitHash() votes.Add(TestUtils.CreateVote( TestUtils.PrivateKeys[0], + TestUtils.ValidatorSet[0].Power, 1, 0, new BlockHash(TestUtils.GetRandomBytes(BlockHash.Size)), VoteFlag.PreCommit)); votes.AddRange(Enumerable.Range(1, 3).Select(x => TestUtils.CreateVote( TestUtils.PrivateKeys[x], + TestUtils.ValidatorSet[x].Power, 1, 0, proposedblockHash, @@ -265,6 +289,7 @@ public async void VoteSetGetOnlyProposeCommitHash() public async void GetVoteSetBits() { PrivateKey proposer = TestUtils.PrivateKeys[1]; + BigInteger proposerPower = TestUtils.ValidatorSet[1].Power; AsyncAutoResetEvent stepChanged = new AsyncAutoResetEvent(); AsyncAutoResetEvent committed = new AsyncAutoResetEvent(); var (blockChain, consensusContext) = TestUtils.CreateDummyConsensusContext( @@ -287,6 +312,7 @@ public async void GetVoteSetBits() block.Hash, DateTimeOffset.UtcNow, proposer.PublicKey, + proposerPower, VoteFlag.PreVote).Sign(proposer); var preVote2 = new VoteMetadata( 1, @@ -294,6 +320,7 @@ public async void GetVoteSetBits() block.Hash, DateTimeOffset.UtcNow, TestUtils.PrivateKeys[2].PublicKey, + TestUtils.ValidatorSet[2].Power, VoteFlag.PreVote).Sign(TestUtils.PrivateKeys[2]); var preVote3 = new VoteMetadata( 1, @@ -301,6 +328,7 @@ public async void GetVoteSetBits() block.Hash, DateTimeOffset.UtcNow, TestUtils.PrivateKeys[3].PublicKey, + TestUtils.ValidatorSet[3].Power, VoteFlag.PreVote).Sign(TestUtils.PrivateKeys[3]); consensusContext.StateChanged += (_, eventArgs) => { @@ -338,6 +366,7 @@ public async void GetVoteSetBits() public async void HandleVoteSetBits() { PrivateKey proposer = TestUtils.PrivateKeys[1]; + BigInteger proposerPower = TestUtils.ValidatorSet[1].Power; ConsensusStep step = ConsensusStep.Default; var stepChanged = new AsyncAutoResetEvent(); var (blockChain, consensusContext) = TestUtils.CreateDummyConsensusContext( @@ -368,6 +397,7 @@ public async void HandleVoteSetBits() block.Hash, DateTimeOffset.UtcNow, proposer.PublicKey, + proposerPower, VoteFlag.PreVote).Sign(proposer); var preVote2 = new VoteMetadata( 1, @@ -375,6 +405,7 @@ public async void HandleVoteSetBits() block.Hash, DateTimeOffset.UtcNow, TestUtils.PrivateKeys[2].PublicKey, + TestUtils.ValidatorSet[2].Power, VoteFlag.PreVote).Sign(TestUtils.PrivateKeys[2]); consensusContext.HandleMessage(new ConsensusProposalMsg(proposal)); consensusContext.HandleMessage(new ConsensusPreVoteMsg(preVote1)); diff --git a/Libplanet.Net.Tests/Consensus/ContextNonProposerTest.cs b/Libplanet.Net.Tests/Consensus/ContextNonProposerTest.cs index 8dcbc7ce6f1..86e75a4e5c6 100644 --- a/Libplanet.Net.Tests/Consensus/ContextNonProposerTest.cs +++ b/Libplanet.Net.Tests/Consensus/ContextNonProposerTest.cs @@ -63,11 +63,21 @@ public async Task EnterPreVoteBlockOneThird() context.ProduceMessage( new ConsensusPreVoteMsg( TestUtils.CreateVote( - TestUtils.PrivateKeys[2], 1, 1, hash: block.Hash, flag: VoteFlag.PreVote))); + TestUtils.PrivateKeys[2], + TestUtils.ValidatorSet[2].Power, + 1, + 1, + hash: block.Hash, + flag: VoteFlag.PreVote))); context.ProduceMessage( new ConsensusPreVoteMsg( TestUtils.CreateVote( - TestUtils.PrivateKeys[3], 1, 1, hash: block.Hash, flag: VoteFlag.PreVote))); + TestUtils.PrivateKeys[3], + TestUtils.ValidatorSet[3].Power, + 1, + 1, + hash: block.Hash, + flag: VoteFlag.PreVote))); // Wait for round 1 prevote step. await stateChangedToRoundOnePreVote.WaitAsync(); @@ -110,15 +120,30 @@ public async Task EnterPreCommitBlockTwoThird() context.ProduceMessage( new ConsensusPreVoteMsg( TestUtils.CreateVote( - TestUtils.PrivateKeys[1], 1, 0, hash: block.Hash, VoteFlag.PreVote))); + TestUtils.PrivateKeys[1], + TestUtils.ValidatorSet[1].Power, + 1, + 0, + hash: block.Hash, + VoteFlag.PreVote))); context.ProduceMessage( new ConsensusPreVoteMsg( TestUtils.CreateVote( - TestUtils.PrivateKeys[2], 1, 0, hash: block.Hash, VoteFlag.PreVote))); + TestUtils.PrivateKeys[2], + TestUtils.ValidatorSet[2].Power, + 1, + 0, + hash: block.Hash, + VoteFlag.PreVote))); context.ProduceMessage( new ConsensusPreVoteMsg( TestUtils.CreateVote( - TestUtils.PrivateKeys[3], 1, 0, hash: block.Hash, VoteFlag.PreVote))); + TestUtils.PrivateKeys[3], + TestUtils.ValidatorSet[3].Power, + 1, + 0, + hash: block.Hash, + VoteFlag.PreVote))); await Task.WhenAll(preCommitSent.WaitAsync(), stepChangedToPreCommit.WaitAsync()); Assert.Equal(block.Hash, preCommit?.BlockHash); @@ -179,15 +204,30 @@ public async void EnterPreCommitNilTwoThird() context.ProduceMessage( new ConsensusPreVoteMsg( TestUtils.CreateVote( - TestUtils.PrivateKeys[1], 1, 0, hash: default, VoteFlag.PreVote))); + TestUtils.PrivateKeys[1], + TestUtils.ValidatorSet[1].Power, + 1, + 0, + hash: default, + VoteFlag.PreVote))); context.ProduceMessage( new ConsensusPreVoteMsg( TestUtils.CreateVote( - TestUtils.PrivateKeys[2], 1, 0, hash: default, VoteFlag.PreVote))); + TestUtils.PrivateKeys[2], + TestUtils.ValidatorSet[2].Power, + 1, + 0, + hash: default, + VoteFlag.PreVote))); context.ProduceMessage( new ConsensusPreVoteMsg( TestUtils.CreateVote( - TestUtils.PrivateKeys[3], 1, 0, hash: default, VoteFlag.PreVote))); + TestUtils.PrivateKeys[3], + TestUtils.ValidatorSet[3].Power, + 1, + 0, + hash: default, + VoteFlag.PreVote))); await Task.WhenAll(preCommitSent.WaitAsync(), stepChangedToPreCommit.WaitAsync()); Assert.Equal(ConsensusStep.PreCommit, context.Step); @@ -413,15 +453,30 @@ message is ConsensusPreCommitMsg commit && context.ProduceMessage( new ConsensusPreVoteMsg( TestUtils.CreateVote( - TestUtils.PrivateKeys[1], 1, 0, invalidBlock.Hash, VoteFlag.PreVote))); + TestUtils.PrivateKeys[1], + TestUtils.ValidatorSet[1].Power, + 1, + 0, + invalidBlock.Hash, + VoteFlag.PreVote))); context.ProduceMessage( new ConsensusPreVoteMsg( TestUtils.CreateVote( - TestUtils.PrivateKeys[2], 1, 0, default, VoteFlag.PreVote))); + TestUtils.PrivateKeys[2], + TestUtils.ValidatorSet[2].Power, + 1, + 0, + default, + VoteFlag.PreVote))); context.ProduceMessage( new ConsensusPreVoteMsg( TestUtils.CreateVote( - TestUtils.PrivateKeys[3], 1, 0, default, VoteFlag.PreVote))); + TestUtils.PrivateKeys[3], + TestUtils.ValidatorSet[3].Power, + 1, + 0, + default, + VoteFlag.PreVote))); await nilPreCommitSent.WaitAsync(); Assert.Equal(ConsensusStep.PreCommit, context.Step); } @@ -446,11 +501,21 @@ public async Task EnterPreVoteNilOneThird() context.ProduceMessage( new ConsensusPreVoteMsg( TestUtils.CreateVote( - TestUtils.PrivateKeys[2], 1, 1, hash: default, flag: VoteFlag.PreVote))); + TestUtils.PrivateKeys[2], + TestUtils.ValidatorSet[2].Power, + 1, + 1, + hash: default, + flag: VoteFlag.PreVote))); context.ProduceMessage( new ConsensusPreVoteMsg( TestUtils.CreateVote( - TestUtils.PrivateKeys[3], 1, 1, hash: default, flag: VoteFlag.PreVote))); + TestUtils.PrivateKeys[3], + TestUtils.ValidatorSet[3].Power, + 1, + 1, + hash: default, + flag: VoteFlag.PreVote))); await stepChangedToRoundOnePreVote.WaitAsync(); Assert.Equal(ConsensusStep.PreVote, context.Step); @@ -522,21 +587,41 @@ public async Task UponRulesCheckAfterTimeout() context.ProduceMessage( new ConsensusPreVoteMsg( TestUtils.CreateVote( - TestUtils.PrivateKeys[2], 1, 0, hash: default, flag: VoteFlag.PreVote))); + TestUtils.PrivateKeys[2], + TestUtils.ValidatorSet[2].Power, + 1, + 0, + hash: default, + flag: VoteFlag.PreVote))); context.ProduceMessage( new ConsensusPreVoteMsg( TestUtils.CreateVote( - TestUtils.PrivateKeys[3], 1, 0, hash: default, flag: VoteFlag.PreVote))); + TestUtils.PrivateKeys[3], + TestUtils.ValidatorSet[3].Power, + 1, + 0, + hash: default, + flag: VoteFlag.PreVote))); // Two additional votes should be enough to trigger precommit timeout timer. context.ProduceMessage( new ConsensusPreCommitMsg( TestUtils.CreateVote( - TestUtils.PrivateKeys[2], 1, 0, hash: default, flag: VoteFlag.PreCommit))); + TestUtils.PrivateKeys[2], + TestUtils.ValidatorSet[2].Power, + 1, + 0, + hash: default, + flag: VoteFlag.PreCommit))); context.ProduceMessage( new ConsensusPreCommitMsg( TestUtils.CreateVote( - TestUtils.PrivateKeys[3], 1, 0, hash: default, flag: VoteFlag.PreCommit))); + TestUtils.PrivateKeys[3], + TestUtils.ValidatorSet[3].Power, + 1, + 0, + hash: default, + flag: VoteFlag.PreCommit))); context.Start(); @@ -571,15 +656,30 @@ public async Task TimeoutPreVote() context.ProduceMessage( new ConsensusPreVoteMsg( TestUtils.CreateVote( - TestUtils.PrivateKeys[1], 1, 0, hash: block.Hash, flag: VoteFlag.PreVote))); + TestUtils.PrivateKeys[1], + TestUtils.ValidatorSet[1].Power, + 1, + 0, + hash: block.Hash, + flag: VoteFlag.PreVote))); context.ProduceMessage( new ConsensusPreVoteMsg( TestUtils.CreateVote( - TestUtils.PrivateKeys[2], 1, 0, hash: default, flag: VoteFlag.PreVote))); + TestUtils.PrivateKeys[2], + TestUtils.ValidatorSet[2].Power, + 1, + 0, + hash: default, + flag: VoteFlag.PreVote))); context.ProduceMessage( new ConsensusPreVoteMsg( TestUtils.CreateVote( - TestUtils.PrivateKeys[3], 1, 0, hash: default, flag: VoteFlag.PreVote))); + TestUtils.PrivateKeys[3], + TestUtils.ValidatorSet[3].Power, + 1, + 0, + hash: default, + flag: VoteFlag.PreVote))); // Wait for timeout. await timeoutProcessed.WaitAsync(); @@ -605,14 +705,32 @@ public async Task TimeoutPreCommit() block, TestUtils.PrivateKeys[1], round: 0)); context.ProduceMessage( - new ConsensusPreCommitMsg(TestUtils.CreateVote( - TestUtils.PrivateKeys[1], 1, 0, hash: block.Hash, flag: VoteFlag.PreCommit))); + new ConsensusPreCommitMsg( + TestUtils.CreateVote( + TestUtils.PrivateKeys[1], + TestUtils.ValidatorSet[1].Power, + 1, + 0, + hash: block.Hash, + flag: VoteFlag.PreCommit))); context.ProduceMessage( - new ConsensusPreCommitMsg(TestUtils.CreateVote( - TestUtils.PrivateKeys[2], 1, 0, hash: default, flag: VoteFlag.PreCommit))); + new ConsensusPreCommitMsg( + TestUtils.CreateVote( + TestUtils.PrivateKeys[2], + TestUtils.ValidatorSet[2].Power, + 1, + 0, + hash: default, + flag: VoteFlag.PreCommit))); context.ProduceMessage( - new ConsensusPreCommitMsg(TestUtils.CreateVote( - TestUtils.PrivateKeys[3], 1, 0, hash: default, flag: VoteFlag.PreCommit))); + new ConsensusPreCommitMsg( + TestUtils.CreateVote( + TestUtils.PrivateKeys[3], + TestUtils.ValidatorSet[3].Power, + 1, + 0, + hash: default, + flag: VoteFlag.PreCommit))); // Wait for timeout. await timeoutProcessed.WaitAsync(); diff --git a/Libplanet.Net.Tests/Consensus/ContextProposerTest.cs b/Libplanet.Net.Tests/Consensus/ContextProposerTest.cs index 84057b46f6c..a0c2781fb2f 100644 --- a/Libplanet.Net.Tests/Consensus/ContextProposerTest.cs +++ b/Libplanet.Net.Tests/Consensus/ContextProposerTest.cs @@ -55,14 +55,32 @@ public async Task EnterPreCommitNil() context.Start(); context.ProduceMessage( - new ConsensusPreVoteMsg(TestUtils.CreateVote( - TestUtils.PrivateKeys[0], 1, hash: default, flag: VoteFlag.PreVote))); + new ConsensusPreVoteMsg( + TestUtils.CreateVote( + TestUtils.PrivateKeys[0], + TestUtils.ValidatorSet[0].Power, + 1, + 0, + hash: default, + flag: VoteFlag.PreVote))); context.ProduceMessage( - new ConsensusPreVoteMsg(TestUtils.CreateVote( - TestUtils.PrivateKeys[2], 1, hash: default, flag: VoteFlag.PreVote))); + new ConsensusPreVoteMsg( + TestUtils.CreateVote( + TestUtils.PrivateKeys[2], + TestUtils.ValidatorSet[2].Power, + 1, + 0, + hash: default, + flag: VoteFlag.PreVote))); context.ProduceMessage( - new ConsensusPreVoteMsg(TestUtils.CreateVote( - TestUtils.PrivateKeys[3], 1, hash: default, flag: VoteFlag.PreVote))); + new ConsensusPreVoteMsg( + TestUtils.CreateVote( + TestUtils.PrivateKeys[3], + TestUtils.ValidatorSet[3].Power, + 1, + 0, + hash: default, + flag: VoteFlag.PreVote))); await Task.WhenAll(preCommitSent.WaitAsync(), stepChangedToPreCommit.WaitAsync()); Assert.Equal(default(BlockHash), preCommit?.BlockHash); @@ -111,19 +129,25 @@ public async void EnterPreCommitBlock() context.ProduceMessage( new ConsensusPreVoteMsg(TestUtils.CreateVote( TestUtils.PrivateKeys[0], + TestUtils.ValidatorSet[0].Power, 1, + 0, hash: proposedblockHash, flag: VoteFlag.PreVote))); context.ProduceMessage( new ConsensusPreVoteMsg(TestUtils.CreateVote( TestUtils.PrivateKeys[2], + TestUtils.ValidatorSet[2].Power, 1, + 0, hash: proposedblockHash, flag: VoteFlag.PreVote))); context.ProduceMessage( new ConsensusPreVoteMsg(TestUtils.CreateVote( TestUtils.PrivateKeys[3], + TestUtils.ValidatorSet[3].Power, 1, + 0, hash: proposedblockHash, flag: VoteFlag.PreVote))); @@ -152,15 +176,30 @@ public async void EnterNewRoundNil() context.ProduceMessage( new ConsensusPreCommitMsg( TestUtils.CreateVote( - TestUtils.PrivateKeys[0], 1, hash: default, flag: VoteFlag.PreCommit))); + TestUtils.PrivateKeys[0], + TestUtils.ValidatorSet[0].Power, + 1, + 0, + hash: default, + flag: VoteFlag.PreCommit))); context.ProduceMessage( new ConsensusPreCommitMsg( TestUtils.CreateVote( - TestUtils.PrivateKeys[2], 1, hash: default, flag: VoteFlag.PreCommit))); + TestUtils.PrivateKeys[2], + TestUtils.ValidatorSet[2].Power, + 1, + 0, + hash: default, + flag: VoteFlag.PreCommit))); context.ProduceMessage( new ConsensusPreCommitMsg( TestUtils.CreateVote( - TestUtils.PrivateKeys[3], 1, hash: default, flag: VoteFlag.PreCommit))); + TestUtils.PrivateKeys[3], + TestUtils.ValidatorSet[3].Power, + 1, + 0, + hash: default, + flag: VoteFlag.PreCommit))); await roundChangedToOne.WaitAsync(); Assert.Equal(1, context.Height); diff --git a/Libplanet.Net.Tests/Consensus/ContextProposerValidRoundTest.cs b/Libplanet.Net.Tests/Consensus/ContextProposerValidRoundTest.cs index 5ff5a10143a..bdfabd21282 100644 --- a/Libplanet.Net.Tests/Consensus/ContextProposerValidRoundTest.cs +++ b/Libplanet.Net.Tests/Consensus/ContextProposerValidRoundTest.cs @@ -75,6 +75,7 @@ prevote.BlockHash is { } hash && context.ProduceMessage( new ConsensusPreVoteMsg(TestUtils.CreateVote( TestUtils.PrivateKeys[0], + TestUtils.ValidatorSet[0].Power, 1, round: 2, hash: proposedBlock.Hash, @@ -82,6 +83,7 @@ prevote.BlockHash is { } hash && context.ProduceMessage( new ConsensusPreVoteMsg(TestUtils.CreateVote( TestUtils.PrivateKeys[2], + TestUtils.ValidatorSet[2].Power, height: 1, round: 2, hash: proposedBlock.Hash, @@ -94,6 +96,7 @@ prevote.BlockHash is { } hash && context.ProduceMessage( new ConsensusPreVoteMsg(TestUtils.CreateVote( TestUtils.PrivateKeys[0], + TestUtils.ValidatorSet[0].Power, height: 1, round: 1, hash: proposedBlock.Hash, @@ -101,6 +104,7 @@ prevote.BlockHash is { } hash && context.ProduceMessage( new ConsensusPreVoteMsg(TestUtils.CreateVote( TestUtils.PrivateKeys[2], + TestUtils.ValidatorSet[2].Power, height: 1, round: 1, hash: proposedBlock.Hash, @@ -108,6 +112,7 @@ prevote.BlockHash is { } hash && context.ProduceMessage( new ConsensusPreVoteMsg(TestUtils.CreateVote( TestUtils.PrivateKeys[3], + TestUtils.ValidatorSet[3].Power, 1, round: 1, hash: proposedBlock.Hash, @@ -189,6 +194,7 @@ public async void EnterValidRoundPreVoteNil() context.ProduceMessage( new ConsensusPreVoteMsg(TestUtils.CreateVote( TestUtils.PrivateKeys[0], + TestUtils.ValidatorSet[0].Power, height: 1, round: 2, hash: proposedBlock!.Hash, @@ -196,6 +202,7 @@ public async void EnterValidRoundPreVoteNil() context.ProduceMessage( new ConsensusPreVoteMsg(TestUtils.CreateVote( TestUtils.PrivateKeys[2], + TestUtils.ValidatorSet[2].Power, height: 1, round: 2, hash: proposedBlock!.Hash, @@ -215,6 +222,7 @@ public async void EnterValidRoundPreVoteNil() context.ProduceMessage( new ConsensusPreVoteMsg(TestUtils.CreateVote( TestUtils.PrivateKeys[3], + TestUtils.ValidatorSet[3].Power, height: 1, round: 2, hash: proposedBlock!.Hash, @@ -225,6 +233,7 @@ public async void EnterValidRoundPreVoteNil() context.ProduceMessage( new ConsensusPreVoteMsg(TestUtils.CreateVote( TestUtils.PrivateKeys[0], + TestUtils.ValidatorSet[0].Power, height: 1, round: 3, hash: differentBlock.Hash, @@ -232,6 +241,7 @@ public async void EnterValidRoundPreVoteNil() context.ProduceMessage( new ConsensusPreVoteMsg(TestUtils.CreateVote( TestUtils.PrivateKeys[2], + TestUtils.ValidatorSet[2].Power, height: 1, round: 3, hash: differentBlock.Hash, @@ -244,6 +254,7 @@ public async void EnterValidRoundPreVoteNil() context.ProduceMessage( new ConsensusPreVoteMsg(TestUtils.CreateVote( TestUtils.PrivateKeys[3], + TestUtils.ValidatorSet[3].Power, height: 1, round: 3, hash: differentBlock.Hash, diff --git a/Libplanet.Net.Tests/Consensus/ContextTest.cs b/Libplanet.Net.Tests/Consensus/ContextTest.cs index 5c61f4bc776..0f1e0d68377 100644 --- a/Libplanet.Net.Tests/Consensus/ContextTest.cs +++ b/Libplanet.Net.Tests/Consensus/ContextTest.cs @@ -1,6 +1,7 @@ using System; using System.Collections.Immutable; using System.Linq; +using System.Numerics; using System.Text.Json; using System.Threading.Tasks; using Bencodex; @@ -189,6 +190,7 @@ public async Task CanAcceptMessagesAfterCommitFailure() proposedBlock!.Hash, DateTimeOffset.UtcNow, TestUtils.PrivateKeys[i].PublicKey, + TestUtils.ValidatorSet[i].Power, VoteFlag.PreVote).Sign(TestUtils.PrivateKeys[i]))); } @@ -201,6 +203,7 @@ public async Task CanAcceptMessagesAfterCommitFailure() proposedBlock!.Hash, DateTimeOffset.UtcNow, TestUtils.PrivateKeys[i].PublicKey, + TestUtils.ValidatorSet[i].Power, VoteFlag.PreCommit).Sign(TestUtils.PrivateKeys[i]))); } @@ -218,6 +221,7 @@ public async Task CanAcceptMessagesAfterCommitFailure() proposedBlock!.Hash, DateTimeOffset.UtcNow, TestUtils.PrivateKeys[3].PublicKey, + TestUtils.ValidatorSet[3].Power, VoteFlag.PreCommit).Sign(TestUtils.PrivateKeys[3]))); await Task.Delay(100); // Wait for the new message to be added to the message log. @@ -272,6 +276,7 @@ public async Task ThrowOnDifferentHeightMessage() new ConsensusPreVoteMsg( TestUtils.CreateVote( TestUtils.PrivateKeys[2], + TestUtils.ValidatorSet[2].Power, 2, 0, block.Hash, @@ -389,6 +394,7 @@ void BroadcastMessage(ConsensusMsg message) => block.Hash, DateTimeOffset.UtcNow, TestUtils.PrivateKeys[i].PublicKey, + TestUtils.ValidatorSet[i].Power, VoteFlag.PreVote).Sign(TestUtils.PrivateKeys[i]))); } @@ -402,6 +408,7 @@ void BroadcastMessage(ConsensusMsg message) => block.Hash, DateTimeOffset.UtcNow, TestUtils.PrivateKeys[i].PublicKey, + TestUtils.ValidatorSet[i].Power, VoteFlag.PreCommit).Sign(TestUtils.PrivateKeys[i]))); } @@ -465,6 +472,9 @@ public async void CanReplaceProposal() var proposer = privateKeys[1]; var key1 = privateKeys[2]; var key2 = privateKeys[3]; + BigInteger proposerPower = TestUtils.ValidatorSet[1].Power; + BigInteger power1 = TestUtils.ValidatorSet[2].Power; + BigInteger power2 = TestUtils.ValidatorSet[3].Power; var stepChanged = new AsyncAutoResetEvent(); var proposalModified = new AsyncAutoResetEvent(); var prevStep = ConsensusStep.Default; @@ -519,6 +529,7 @@ public async void CanReplaceProposal() blockA.Hash, DateTimeOffset.UtcNow, key2.PublicKey, + power2, VoteFlag.PreVote).Sign(key2)); var proposalB = new ProposalMetadata( 1, @@ -556,6 +567,7 @@ public async void CanReplaceProposal() blockB.Hash, DateTimeOffset.UtcNow, proposer.PublicKey, + proposerPower, VoteFlag.PreVote).Sign(proposer)); var preVoteB1 = new ConsensusPreVoteMsg( new VoteMetadata( @@ -564,6 +576,7 @@ public async void CanReplaceProposal() blockB.Hash, DateTimeOffset.UtcNow, key1.PublicKey, + power1, VoteFlag.PreVote).Sign(key1)); var preVoteB2 = new ConsensusPreVoteMsg( new VoteMetadata( @@ -572,6 +585,7 @@ public async void CanReplaceProposal() blockB.Hash, DateTimeOffset.UtcNow, key2.PublicKey, + power2, VoteFlag.PreVote).Sign(key2)); context.ProduceMessage(preVoteB0); context.ProduceMessage(preVoteB1); diff --git a/Libplanet.Net.Tests/Consensus/GossipConsensusMessageCommunicatorTest.cs b/Libplanet.Net.Tests/Consensus/GossipConsensusMessageCommunicatorTest.cs index aac0cfd2fef..030524a1e74 100644 --- a/Libplanet.Net.Tests/Consensus/GossipConsensusMessageCommunicatorTest.cs +++ b/Libplanet.Net.Tests/Consensus/GossipConsensusMessageCommunicatorTest.cs @@ -3,6 +3,7 @@ using System.Collections.Immutable; using System.Linq; using System.Net; +using System.Numerics; using System.Threading.Tasks; using Libplanet.Crypto; using Libplanet.Net.Consensus; @@ -85,12 +86,24 @@ public async void SendHigherMessage() // Add message of higher round to communicator1 communicator1.Gossip.AddMessage( new ConsensusPreVoteMsg( - TestUtils.CreateVote(new PrivateKey(), 1, 3, fx.Hash1, VoteFlag.PreVote))); + TestUtils.CreateVote( + new PrivateKey(), + BigInteger.One, + 1, + 3, + fx.Hash1, + VoteFlag.PreVote))); // Add message of same round to communicator1 communicator1.Gossip.AddMessage( new ConsensusPreVoteMsg( - TestUtils.CreateVote(new PrivateKey(), 1, 2, fx.Hash1, VoteFlag.PreVote))); + TestUtils.CreateVote( + new PrivateKey(), + BigInteger.One, + 1, + 2, + fx.Hash1, + VoteFlag.PreVote))); await receivedPreVotes.WaitAsync(); await Task.Delay(1500); @@ -191,23 +204,47 @@ async Task CheckDeniedAsync() transport2.BroadcastMessage( peer1, new ConsensusPreVoteMsg( - TestUtils.CreateVote(new PrivateKey(), 1, 2, fx.Hash1, VoteFlag.PreVote))); + TestUtils.CreateVote( + new PrivateKey(), + BigInteger.One, + 1, + 2, + fx.Hash1, + VoteFlag.PreVote))); // Higher round messages. These will trigger spam filter, // and only two will be received. transport2.BroadcastMessage( peer1, new ConsensusPreVoteMsg( - TestUtils.CreateVote(new PrivateKey(), 1, 3, fx.Hash1, VoteFlag.PreVote))); + TestUtils.CreateVote( + new PrivateKey(), + BigInteger.One, + 1, + 3, + fx.Hash1, + VoteFlag.PreVote))); transport2.BroadcastMessage( peer1, new ConsensusPreVoteMsg( - TestUtils.CreateVote(new PrivateKey(), 1, 4, fx.Hash1, VoteFlag.PreVote))); + TestUtils.CreateVote( + new PrivateKey(), + BigInteger.One, + 1, + 4, + fx.Hash1, + VoteFlag.PreVote))); // Higher round message. This will trigger spam filter, if encounter three times. transport2.BroadcastMessage( peer1, new ConsensusPreVoteMsg( - TestUtils.CreateVote(new PrivateKey(), 1, 5, fx.Hash1, VoteFlag.PreVote))); + TestUtils.CreateVote( + new PrivateKey(), + BigInteger.One, + 1, + 5, + fx.Hash1, + VoteFlag.PreVote))); // Wait for third higher round message encounter. await receivedTwoHigherPreVotes.WaitAsync(); @@ -218,19 +255,35 @@ async Task CheckDeniedAsync() transport2.BroadcastMessage( peer1, new ConsensusPreVoteMsg( - TestUtils.CreateVote(new PrivateKey(), 1, 1, fx.Hash1, VoteFlag.PreVote))); + TestUtils.CreateVote( + new PrivateKey(), + BigInteger.One, + 1, + 1, + fx.Hash1, + VoteFlag.PreVote))); transport2.BroadcastMessage( peer1, new ConsensusPreCommitMsg( - TestUtils.CreateVote(new PrivateKey(), 1, 1, fx.Hash1, VoteFlag.PreCommit)) - ); + TestUtils.CreateVote( + new PrivateKey(), + BigInteger.One, + 1, + 1, + fx.Hash1, + VoteFlag.PreCommit))); // Since communicator3 wasn't denied, this message will be received without block. transport3.BroadcastMessage( peer1, new ConsensusPreCommitMsg( - TestUtils.CreateVote(new PrivateKey(), 1, 2, fx.Hash1, VoteFlag.PreCommit)) - ); + TestUtils.CreateVote( + new PrivateKey(), + BigInteger.One, + 1, + 2, + fx.Hash1, + VoteFlag.PreCommit))); // Wait for message from communicator1's precommit encounter, // but this message will be rejected by spam filter logic. diff --git a/Libplanet.Net.Tests/Consensus/HeightVoteSetTest.cs b/Libplanet.Net.Tests/Consensus/HeightVoteSetTest.cs index cf200cbb8db..fcf0f830cf8 100644 --- a/Libplanet.Net.Tests/Consensus/HeightVoteSetTest.cs +++ b/Libplanet.Net.Tests/Consensus/HeightVoteSetTest.cs @@ -1,5 +1,6 @@ using System; using System.Linq; +using System.Numerics; using Libplanet.Blockchain; using Libplanet.Crypto; using Libplanet.Net.Consensus; @@ -41,6 +42,7 @@ public void CannotAddDifferentHeight() default, DateTimeOffset.UtcNow, TestUtils.PrivateKeys[0].PublicKey, + TestUtils.ValidatorSet[0].Power, VoteFlag.PreVote).Sign(TestUtils.PrivateKeys[0]); Assert.Throws(() => _heightVoteSet.AddVote(preVote)); @@ -51,7 +53,13 @@ public void CannotAddUnknownValidator() { var key = new PrivateKey(); var preVote = new VoteMetadata( - 2, 0, default, DateTimeOffset.UtcNow, key.PublicKey, VoteFlag.PreVote).Sign(key); + 2, + 0, + default, + DateTimeOffset.UtcNow, + key.PublicKey, + BigInteger.One, + VoteFlag.PreVote).Sign(key); Assert.Throws(() => _heightVoteSet.AddVote(preVote)); } @@ -66,6 +74,7 @@ public void CannotAddMultipleVotesPerRoundPerValidator() default, DateTimeOffset.UtcNow, TestUtils.PrivateKeys[0].PublicKey, + TestUtils.ValidatorSet[0].Power, VoteFlag.PreVote).Sign(TestUtils.PrivateKeys[0]); var preVote1 = new VoteMetadata( 2, @@ -73,6 +82,7 @@ public void CannotAddMultipleVotesPerRoundPerValidator() new BlockHash(TestUtils.GetRandomBytes(BlockHash.Size)), DateTimeOffset.UtcNow, TestUtils.PrivateKeys[0].PublicKey, + TestUtils.ValidatorSet[0].Power, VoteFlag.PreVote).Sign(TestUtils.PrivateKeys[0]); var preCommit0 = new VoteMetadata( 2, @@ -80,6 +90,7 @@ public void CannotAddMultipleVotesPerRoundPerValidator() default, DateTimeOffset.UtcNow, TestUtils.PrivateKeys[0].PublicKey, + TestUtils.ValidatorSet[0].Power, VoteFlag.PreCommit).Sign(TestUtils.PrivateKeys[0]); var preCommit1 = new VoteMetadata( 2, @@ -87,6 +98,7 @@ public void CannotAddMultipleVotesPerRoundPerValidator() new BlockHash(TestUtils.GetRandomBytes(BlockHash.Size)), DateTimeOffset.UtcNow, TestUtils.PrivateKeys[0].PublicKey, + TestUtils.ValidatorSet[0].Power, VoteFlag.PreCommit).Sign(TestUtils.PrivateKeys[0]); _heightVoteSet.AddVote(preVote0); @@ -99,19 +111,27 @@ public void CannotAddMultipleVotesPerRoundPerValidator() [Fact] public void GetCount() { - var preVotes = TestUtils.PrivateKeys.Select(key => - new VoteMetadata( - 2, 0, default, DateTimeOffset.UtcNow, key.PublicKey, VoteFlag.PreVote) - .Sign(key)).ToList(); - var privateKey = TestUtils.PrivateKeys[0]; + var preVotes = Enumerable.Range(0, TestUtils.PrivateKeys.Count) + .Select( + index => new VoteMetadata( + 2, + 0, + default, + DateTimeOffset.UtcNow, + TestUtils.PrivateKeys[index].PublicKey, + TestUtils.ValidatorSet[index].Power, + VoteFlag.PreVote) + .Sign(TestUtils.PrivateKeys[index])) + .ToList(); var preCommit = new VoteMetadata( 2, 0, default, DateTimeOffset.UtcNow, - privateKey.PublicKey, + TestUtils.PrivateKeys[0].PublicKey, + TestUtils.ValidatorSet[0].Power, VoteFlag.PreCommit) - .Sign(privateKey); + .Sign(TestUtils.PrivateKeys[0]); foreach (var preVote in preVotes) { diff --git a/Libplanet.Net.Tests/Consensus/VoteSetTest.cs b/Libplanet.Net.Tests/Consensus/VoteSetTest.cs index 98c03e693cc..8390a50a306 100644 --- a/Libplanet.Net.Tests/Consensus/VoteSetTest.cs +++ b/Libplanet.Net.Tests/Consensus/VoteSetTest.cs @@ -24,7 +24,8 @@ public void Majority() 0, blockHash, DateTimeOffset.UtcNow, - TestUtils.PrivateKeys[0].PublicKey, + TestUtils.ValidatorSet[0].PublicKey, + TestUtils.ValidatorSet[0].Power, VoteFlag.PreCommit).Sign(TestUtils.PrivateKeys[0])); Assert.False(voteSet.HasOneThirdsAny()); Assert.False(voteSet.HasTwoThirdsAny()); @@ -37,7 +38,8 @@ public void Majority() 0, blockHash, DateTimeOffset.UtcNow, - TestUtils.PrivateKeys[1].PublicKey, + TestUtils.ValidatorSet[1].PublicKey, + TestUtils.ValidatorSet[1].Power, VoteFlag.PreCommit).Sign(TestUtils.PrivateKeys[1])); Assert.True(voteSet.HasOneThirdsAny()); Assert.False(voteSet.HasTwoThirdsAny()); @@ -50,7 +52,8 @@ public void Majority() 0, new BlockHash(TestUtils.GetRandomBytes(BlockHash.Size)), DateTimeOffset.UtcNow, - TestUtils.PrivateKeys[2].PublicKey, + TestUtils.ValidatorSet[2].PublicKey, + TestUtils.ValidatorSet[2].Power, VoteFlag.PreCommit).Sign(TestUtils.PrivateKeys[2])); Assert.True(voteSet.HasOneThirdsAny()); Assert.True(voteSet.HasTwoThirdsAny()); @@ -63,7 +66,8 @@ public void Majority() 0, blockHash, DateTimeOffset.UtcNow, - TestUtils.PrivateKeys[3].PublicKey, + TestUtils.ValidatorSet[3].PublicKey, + TestUtils.ValidatorSet[3].Power, VoteFlag.PreCommit).Sign(TestUtils.PrivateKeys[3])); Assert.True(voteSet.HasOneThirdsAny()); Assert.True(voteSet.HasTwoThirdsAny()); diff --git a/Libplanet.Net.Tests/Messages/MessageTest.cs b/Libplanet.Net.Tests/Messages/MessageTest.cs index ed331684a91..5e131871cad 100644 --- a/Libplanet.Net.Tests/Messages/MessageTest.cs +++ b/Libplanet.Net.Tests/Messages/MessageTest.cs @@ -115,7 +115,7 @@ public void GetId() var message = new BlockHeaderMsg(genesis.Hash, genesis.Header); Assert.Equal( new MessageId(ByteUtil.ParseHex( - "53278bbaa07aa9559569f3a37eef7cf9820bff84e14a472f417b80a42d312f09")), + "a087b6a3a5c8697d4e4c289db2c35be7277efac170faf3eed250f758d2aa230f")), message.Id); } @@ -126,6 +126,7 @@ public void InvalidVoteFlagConsensus() var preVote = TestUtils.CreateVote( TestUtils.PrivateKeys[0], + TestUtils.ValidatorSet[0].Power, 1, 0, blockHash, @@ -133,6 +134,7 @@ public void InvalidVoteFlagConsensus() var preCommit = TestUtils.CreateVote( TestUtils.PrivateKeys[0], + TestUtils.ValidatorSet[0].Power, 1, 0, blockHash, diff --git a/Libplanet.Net.Tests/Messages/NetMQMessageCodecTest.cs b/Libplanet.Net.Tests/Messages/NetMQMessageCodecTest.cs index 11eec0dd9ca..2a935cf54e9 100644 --- a/Libplanet.Net.Tests/Messages/NetMQMessageCodecTest.cs +++ b/Libplanet.Net.Tests/Messages/NetMQMessageCodecTest.cs @@ -2,6 +2,7 @@ using System; using System.Collections.Immutable; using System.Net; +using System.Numerics; using Bencodex; using Libplanet.Action.Loader; using Libplanet.Action.Tests.Common; @@ -152,6 +153,7 @@ private MessageContent CreateMessage(MessageContent.MessageType type) genesis.Hash, DateTimeOffset.UtcNow, privateKey.PublicKey, + BigInteger.One, VoteFlag.PreVote).Sign(privateKey)); case MessageContent.MessageType.ConsensusCommit: return new ConsensusPreCommitMsg( @@ -161,6 +163,7 @@ private MessageContent CreateMessage(MessageContent.MessageType type) genesis.Hash, DateTimeOffset.UtcNow, privateKey.PublicKey, + BigInteger.One, VoteFlag.PreCommit).Sign(privateKey)); case MessageContent.MessageType.ConsensusMaj23Msg: return new ConsensusMaj23Msg( diff --git a/Libplanet.Net.Tests/SwarmTest.Preload.cs b/Libplanet.Net.Tests/SwarmTest.Preload.cs index 422def21c41..96c2b325acb 100644 --- a/Libplanet.Net.Tests/SwarmTest.Preload.cs +++ b/Libplanet.Net.Tests/SwarmTest.Preload.cs @@ -137,9 +137,9 @@ public async Task Preload() Block block = minerChain.EvaluateAndSign( ProposeNext( previousBlock: i == 0 ? minerChain.Genesis : blocks[i - 1], - miner: ChainPrivateKey.PublicKey, + miner: GenesisProposer.PublicKey, lastCommit: CreateBlockCommit(minerChain.Tip)), - ChainPrivateKey); + GenesisProposer); blocks.Add(block); if (i != 11) { @@ -321,6 +321,7 @@ public async Task PreloadWithMaliciousPeer() specialBlock.Hash, DateTimeOffset.UtcNow, TestUtils.PrivateKeys[0].PublicKey, + TestUtils.ValidatorSet[0].Power, VoteFlag.PreCommit).Sign(TestUtils.PrivateKeys[0]))); var validBlockCommit = TestUtils.CreateBlockCommit(specialBlock); chainB.Append(specialBlock, invalidBlockCommit); @@ -485,7 +486,7 @@ public async Task PreloadWithFailedActions() DateTimeOffset.UtcNow); Block block = minerChain.ProposeBlock( - ChainPrivateKey, + GenesisProposer, new[] { tx }.ToImmutableList(), CreateBlockCommit(minerChain.Tip)); minerSwarm.BlockChain.Append(block, CreateBlockCommit(block), true); @@ -1002,7 +1003,7 @@ public async Task PreloadFromTheHighestTipIndexChain() minerChain1.Append(block2, CreateBlockCommit(block2)); Block block = minerChain2.ProposeBlock( - ChainPrivateKey, CreateBlockCommit(minerChain2.Tip)); + GenesisProposer, CreateBlockCommit(minerChain2.Tip)); minerChain2.Append(block, CreateBlockCommit(block)); Assert.True(minerChain1.Count > minerChain2.Count); diff --git a/Libplanet.Net.Tests/SwarmTest.cs b/Libplanet.Net.Tests/SwarmTest.cs index a447ff1e757..a3cbd0e5380 100644 --- a/Libplanet.Net.Tests/SwarmTest.cs +++ b/Libplanet.Net.Tests/SwarmTest.cs @@ -1630,7 +1630,7 @@ public async Task DoNotFillWhenGetAllBlockAtFirstTimeFromSender() for (int i = 0; i < 6; i++) { Block block = chain.ProposeBlock( - ChainPrivateKey, TestUtils.CreateBlockCommit(chain.Tip)); + GenesisProposer, TestUtils.CreateBlockCommit(chain.Tip)); chain.Append(block, TestUtils.CreateBlockCommit(block)); } @@ -1670,7 +1670,7 @@ public async Task FillWhenGetAChunkOfBlocksFromSender() for (int i = 0; i < 6; i++) { Block block = chain.ProposeBlock( - ChainPrivateKey, TestUtils.CreateBlockCommit(chain.Tip)); + GenesisProposer, TestUtils.CreateBlockCommit(chain.Tip)); chain.Append(block, TestUtils.CreateBlockCommit(block)); } @@ -1711,7 +1711,7 @@ public async Task FillWhenGetAllBlocksFromSender() for (int i = 0; i < 6; i++) { Block block = chain.ProposeBlock( - ChainPrivateKey, CreateBlockCommit(chain.Tip)); + GenesisProposer, CreateBlockCommit(chain.Tip)); chain.Append(block, TestUtils.CreateBlockCommit(block)); } diff --git a/Libplanet.Net.Tests/TestUtils.cs b/Libplanet.Net.Tests/TestUtils.cs index 84e0bef6408..7f55d192fef 100644 --- a/Libplanet.Net.Tests/TestUtils.cs +++ b/Libplanet.Net.Tests/TestUtils.cs @@ -3,6 +3,7 @@ using System.Collections.Immutable; using System.Linq; using System.Net; +using System.Numerics; using System.Threading.Tasks; using Bencodex; using Libplanet.Action; @@ -33,7 +34,7 @@ public static class TestUtils BlockHash.FromString( "042b81bef7d4bca6e01f5975ce9ac7ed9f75248903d08836bed6566488c8089d"); - public static readonly List PrivateKeys = + public static readonly ImmutableList PrivateKeys = Libplanet.Tests.TestUtils.ValidatorPrivateKeys; public static readonly List Peers = new List() @@ -63,16 +64,18 @@ public static class TestUtils public static Vote CreateVote( PrivateKey privateKey, - long height = 0, - int round = 0, - BlockHash hash = default, - VoteFlag flag = VoteFlag.Null) => + BigInteger power, + long height, + int round, + BlockHash hash, + VoteFlag flag) => new VoteMetadata( height, round, hash, DateTimeOffset.Now, privateKey.PublicKey, + power, flag).Sign(privateKey); public static PrivateKey GeneratePrivateKeyOfBucketIndex(Address tableAddress, int target) @@ -133,8 +136,10 @@ public static void HandleFourPeersPreCommitMessages( PrivateKey nodePrivateKey, BlockHash roundBlockHash) { - foreach ((PrivateKey privateKey, BoundPeer peer) - in PrivateKeys.Zip(Peers, (first, second) => (first, second))) + foreach ((PrivateKey privateKey, BigInteger power) + in PrivateKeys.Zip( + ValidatorSet.Validators.Select(v => v.Power), + (first, second) => (first, second))) { if (privateKey == nodePrivateKey) { @@ -149,6 +154,7 @@ in PrivateKeys.Zip(Peers, (first, second) => (first, second))) roundBlockHash, DateTimeOffset.UtcNow, privateKey.PublicKey, + power, VoteFlag.PreCommit).Sign(privateKey))); } } @@ -158,8 +164,10 @@ public static void HandleFourPeersPreCommitMessages( PrivateKey nodePrivateKey, BlockHash roundBlockHash) { - foreach ((PrivateKey privateKey, BoundPeer peer) - in PrivateKeys.Zip(Peers, (first, second) => (first, second))) + foreach ((PrivateKey privateKey, BigInteger power) + in PrivateKeys.Zip( + ValidatorSet.Validators.Select(v => v.Power), + (first, second) => (first, second))) { if (privateKey == nodePrivateKey) { @@ -174,6 +182,7 @@ in PrivateKeys.Zip(Peers, (first, second) => (first, second))) roundBlockHash, DateTimeOffset.UtcNow, privateKey.PublicKey, + power, VoteFlag.PreCommit).Sign(privateKey))); } } @@ -183,8 +192,10 @@ public static void HandleFourPeersPreVoteMessages( PrivateKey nodePrivateKey, BlockHash roundBlockHash) { - foreach ((PrivateKey privateKey, BoundPeer peer) - in PrivateKeys.Zip(Peers, (first, second) => (first, second))) + foreach ((PrivateKey privateKey, BigInteger power) + in PrivateKeys.Zip( + ValidatorSet.Validators.Select(v => v.Power), + (first, second) => (first, second))) { if (privateKey == nodePrivateKey) { @@ -199,6 +210,7 @@ in PrivateKeys.Zip(Peers, (first, second) => (first, second))) roundBlockHash, DateTimeOffset.UtcNow, privateKey.PublicKey, + power, VoteFlag.PreVote).Sign(privateKey))); } } @@ -208,7 +220,10 @@ public static void HandleFourPeersPreVoteMessages( PrivateKey nodePrivateKey, BlockHash roundBlockHash) { - foreach (PrivateKey privateKey in PrivateKeys) + foreach ((PrivateKey privateKey, BigInteger power) + in PrivateKeys.Zip( + ValidatorSet.Validators.Select(v => v.Power), + (first, second) => (first, second))) { if (privateKey == nodePrivateKey) { @@ -223,6 +238,7 @@ public static void HandleFourPeersPreVoteMessages( roundBlockHash, DateTimeOffset.UtcNow, privateKey.PublicKey, + power, VoteFlag.PreVote).Sign(privateKey))); } } diff --git a/Libplanet.Net/Consensus/Context.cs b/Libplanet.Net/Consensus/Context.cs index 008ad294281..9bb44b261b9 100644 --- a/Libplanet.Net/Consensus/Context.cs +++ b/Libplanet.Net/Consensus/Context.cs @@ -561,6 +561,7 @@ private Vote MakeVote(int round, BlockHash hash, VoteFlag flag) hash, DateTimeOffset.UtcNow, _privateKey.PublicKey, + _validatorSet.GetValidator(_privateKey.PublicKey).Power, flag).Sign(_privateKey); } diff --git a/Libplanet.Net/Consensus/VoteSet.cs b/Libplanet.Net/Consensus/VoteSet.cs index 23531b03aa8..bcc615f7b88 100644 --- a/Libplanet.Net/Consensus/VoteSet.cs +++ b/Libplanet.Net/Consensus/VoteSet.cs @@ -507,6 +507,7 @@ public List MappedList(long height, int round, ValidatorSet validatorSet) BlockHash, DateTimeOffset.UtcNow, key, + validatorSet.GetValidator(key).Power, VoteFlag.Null).Sign(null)) .ToList(); } diff --git a/Libplanet.Tests/Action/ActionEvaluatorTest.cs b/Libplanet.Tests/Action/ActionEvaluatorTest.cs index efde4fe5b84..44614d994db 100644 --- a/Libplanet.Tests/Action/ActionEvaluatorTest.cs +++ b/Libplanet.Tests/Action/ActionEvaluatorTest.cs @@ -839,7 +839,7 @@ public void EvaluatePolicyBeginBlockActions() stateStore: _storeFx.StateStore, actionLoader: new SingleActionLoader(typeof(DumbAction)), genesisBlock: _storeFx.GenesisBlock, - privateKey: ChainPrivateKey); + privateKey: GenesisProposer); (_, Transaction[] txs) = MakeFixturesForAppendTests(); var genesis = chain.Genesis; var block = chain.ProposeBlock( @@ -887,7 +887,7 @@ public void EvaluatePolicyEndBlockActions() stateStore: _storeFx.StateStore, actionLoader: new SingleActionLoader(typeof(DumbAction)), genesisBlock: _storeFx.GenesisBlock, - privateKey: ChainPrivateKey); + privateKey: GenesisProposer); (_, Transaction[] txs) = MakeFixturesForAppendTests(); var genesis = chain.Genesis; var block = chain.ProposeBlock( @@ -1056,7 +1056,7 @@ public void TotalUpdatedFungibleAssets() stateStore: _storeFx.StateStore, actionLoader: new SingleActionLoader(typeof(UseGasAction)), actions: gasFillActions, - privateKey: ChainPrivateKey); + privateKey: GenesisProposer); var addresses = privateKeys.Select(privateKey => privateKey.Address).ToList(); // Only addresses[0] and addresses[1] are able to mint diff --git a/Libplanet.Tests/Blockchain/BlockChainTest.ProposeBlock.cs b/Libplanet.Tests/Blockchain/BlockChainTest.ProposeBlock.cs index e70a2da63af..06954c9dd95 100644 --- a/Libplanet.Tests/Blockchain/BlockChainTest.ProposeBlock.cs +++ b/Libplanet.Tests/Blockchain/BlockChainTest.ProposeBlock.cs @@ -2,6 +2,7 @@ using System.Collections.Generic; using System.Collections.Immutable; using System.Linq; +using System.Numerics; using Bencodex.Types; using Libplanet.Action; using Libplanet.Action.Loader; @@ -617,6 +618,7 @@ public void ProposeBlockWithLastCommit() _blockChain.Tip.Hash, DateTimeOffset.UtcNow, key.PublicKey, + BigInteger.One, VoteFlag.PreCommit).Sign(key)).ToImmutableArray(); var blockCommit = new BlockCommit( _blockChain.Tip.Index, 0, _blockChain.Tip.Hash, votes); diff --git a/Libplanet.Tests/Blockchain/BlockChainTest.ValidateNextBlock.cs b/Libplanet.Tests/Blockchain/BlockChainTest.ValidateNextBlock.cs index 455d49402f1..bf5910cd633 100644 --- a/Libplanet.Tests/Blockchain/BlockChainTest.ValidateNextBlock.cs +++ b/Libplanet.Tests/Blockchain/BlockChainTest.ValidateNextBlock.cs @@ -1,6 +1,7 @@ using System; using System.Collections.Immutable; using System.Linq; +using System.Numerics; using Bencodex.Types; using Libplanet.Action; using Libplanet.Action.Loader; @@ -302,13 +303,17 @@ public void ValidateNextBlockLastCommitFailsUnexpectedValidator() var invalidValidator = new PrivateKey(); var validators = TestUtils.ValidatorPrivateKeys.Append(invalidValidator).ToList(); - var votes = validators.Select(key => new VoteMetadata( + var validatorPowers = TestUtils.ValidatorSet.Validators.Select(v => v.Power) + .Append(BigInteger.One) + .ToList(); + var votes = Enumerable.Range(0, validators.Count).Select(index => new VoteMetadata( 1, 0, block1.Hash, DateTimeOffset.UtcNow, - key.PublicKey, - VoteFlag.PreCommit).Sign(key)).ToImmutableArray(); + validators[index].PublicKey, + validatorPowers[index], + VoteFlag.PreCommit).Sign(validators[index])).ToImmutableArray(); var blockCommit = new BlockCommit(1, 0, block1.Hash, votes); Block block2 = _blockChain.EvaluateAndSign( @@ -348,6 +353,7 @@ public void ValidateNextBlockLastCommitFailsDropExpectedValidator() block1.Hash, DateTimeOffset.UtcNow, key.PublicKey, + TestUtils.ValidatorSet.GetValidator(key.PublicKey).Power, VoteFlag.PreCommit).Sign(key)).ToImmutableArray(); var blockCommit = new BlockCommit(1, 0, block1.Hash, votes); Block block2 = _blockChain.EvaluateAndSign( @@ -383,6 +389,7 @@ public void ValidateBlockCommitGenesis() _fx.GenesisBlock.Hash, DateTimeOffset.UtcNow, x.PublicKey, + TestUtils.ValidatorSet.GetValidator(x.PublicKey).Power, VoteFlag.PreCommit).Sign(x)).ToImmutableArray()))); } @@ -461,6 +468,7 @@ public void ValidateBlockCommitFailsDifferentValidatorSet() validNextBlock.Hash, DateTimeOffset.UtcNow, x.PublicKey, + BigInteger.One, VoteFlag.PreCommit).Sign(x)).ToImmutableArray()))); } @@ -512,15 +520,16 @@ public void ValidateBlockCommitFailsInsufficientPower() lastCommit: null)).Propose(), _fx.Proposer); - Vote GenerateVote(PrivateKey key, VoteFlag flag) + Vote GenerateVote(PrivateKey key, BigInteger power, VoteFlag flag) { var metadata = new VoteMetadata( - 1, - 0, - validNextBlock.Hash, - DateTimeOffset.UtcNow, - key.PublicKey, - flag); + 1, + 0, + validNextBlock.Hash, + DateTimeOffset.UtcNow, + key.PublicKey, + power, + flag); return metadata.Sign(flag == VoteFlag.Null ? null : key); } @@ -532,10 +541,10 @@ ImmutableArray GenerateVotes( { return new[] { - GenerateVote(privateKey1, flag1), - GenerateVote(privateKey2, flag2), - GenerateVote(privateKey3, flag3), - GenerateVote(privateKey4, flag4), + GenerateVote(privateKey1, validator1.Power, flag1), + GenerateVote(privateKey2, validator2.Power, flag2), + GenerateVote(privateKey3, validator3.Power, flag3), + GenerateVote(privateKey4, validator4.Power, flag4), }.OrderBy(vote => vote.ValidatorPublicKey.Address).ToImmutableArray(); } diff --git a/Libplanet.Tests/Blockchain/BlockChainTest.cs b/Libplanet.Tests/Blockchain/BlockChainTest.cs index 020670e9ebb..e4827c842d7 100644 --- a/Libplanet.Tests/Blockchain/BlockChainTest.cs +++ b/Libplanet.Tests/Blockchain/BlockChainTest.cs @@ -2211,8 +2211,10 @@ private void ValidateNextBlockCommitOnValidatorSetChange() .Add(storeFixture.Address2) .Add(storeFixture.Address3); - var newValidatorPrivKey = new PrivateKey(); - var newValidators = ValidatorPrivateKeys.Append(newValidatorPrivKey); + var newValidatorPrivateKey = new PrivateKey(); + var newValidators = ValidatorPrivateKeys.Append(newValidatorPrivateKey).ToArray(); + var newValidatorPowers = TestUtils.ValidatorSet.Validators.Select(v => v.Power) + .Append(BigInteger.One).ToArray(); var initialValidatorSet = new ValidatorSet( ValidatorPrivateKeys.Select( pk => new Validator(pk.PublicKey, BigInteger.One) @@ -2255,7 +2257,8 @@ private void ValidateNextBlockCommitOnValidatorSetChange() new PrivateKey(), new[] { - new SetValidator(new Validator(newValidatorPrivKey.PublicKey, BigInteger.One)), + new SetValidator( + new Validator(newValidatorPrivateKey.PublicKey, BigInteger.One)), } ); var newBlock = blockChain.ProposeBlock(new PrivateKey()); @@ -2267,6 +2270,7 @@ private void ValidateNextBlockCommitOnValidatorSetChange() newBlock.Hash, DateTimeOffset.UtcNow, pk.PublicKey, + TestUtils.ValidatorSet.GetValidator(pk.PublicKey).Power, VoteFlag.PreCommit).Sign(pk)) .OrderBy(vote => vote.ValidatorPublicKey.Address) .ToImmutableArray()); @@ -2282,16 +2286,21 @@ private void ValidateNextBlockCommitOnValidatorSetChange() var nextBlock = blockChain.ProposeBlock( new PrivateKey(), lastCommit: newBlockCommit); var nextBlockCommit = new BlockCommit( - nextBlock.Index, 0, nextBlock.Hash, newValidators.Select( - pk => new VoteMetadata( - nextBlock.Index, - 0, - nextBlock.Hash, - DateTimeOffset.UtcNow, - pk.PublicKey, - VoteFlag.PreCommit).Sign(pk)) - .OrderBy(vote => vote.ValidatorPublicKey.Address) - .ToImmutableArray()); + nextBlock.Index, + 0, + nextBlock.Hash, + Enumerable.Range(0, newValidators.Length) + .Select( + index => new VoteMetadata( + nextBlock.Index, + 0, + nextBlock.Hash, + DateTimeOffset.UtcNow, + newValidators[index].PublicKey, + newValidatorPowers[index], + VoteFlag.PreCommit).Sign(newValidators[index])) + .OrderBy(vote => vote.ValidatorPublicKey.Address) + .ToImmutableArray()); blockChain.Append(nextBlock, nextBlockCommit); blockChain.MakeTransaction( @@ -2308,14 +2317,20 @@ private void ValidateNextBlockCommitOnValidatorSetChange() () => blockChain.Append( invalidCommitBlock, new BlockCommit( - invalidCommitBlock.Index, 0, invalidCommitBlock.Hash, newValidators.Select( - pk => new VoteMetadata( - invalidCommitBlock.Index, - 0, - invalidCommitBlock.Hash, - DateTimeOffset.UtcNow, - pk.PublicKey, - VoteFlag.PreCommit).Sign(pk)).ToImmutableArray()))); + invalidCommitBlock.Index, + 0, + invalidCommitBlock.Hash, + Enumerable.Range(0, newValidators.Length) + .Select( + index => new VoteMetadata( + invalidCommitBlock.Index, + 0, + invalidCommitBlock.Hash, + DateTimeOffset.UtcNow, + newValidators[index].PublicKey, + newValidatorPowers[index], + VoteFlag.PreCommit).Sign(newValidators[index])) + .ToImmutableArray()))); Assert.Equal( blockChain diff --git a/Libplanet.Tests/Blocks/BlockCommitTest.cs b/Libplanet.Tests/Blocks/BlockCommitTest.cs index af85ccc1b0d..4f94e460504 100644 --- a/Libplanet.Tests/Blocks/BlockCommitTest.cs +++ b/Libplanet.Tests/Blocks/BlockCommitTest.cs @@ -1,6 +1,7 @@ using System; using System.Collections.Immutable; using System.Linq; +using System.Numerics; using System.Security.Cryptography; using Libplanet.Common; using Libplanet.Crypto; @@ -34,6 +35,7 @@ public void ToHash() randomHash, DateTimeOffset.UtcNow, key.PublicKey, + BigInteger.One, VoteFlag.PreCommit).Sign(key)) .ToImmutableArray(); var blockCommit = new BlockCommit(1, 0, randomHash, votes); @@ -50,8 +52,15 @@ public void HeightAndRoundMustNotBeNegative() var hash = new BlockHash(TestUtils.GetRandomBytes(BlockHash.Size)); var key = new PrivateKey(); var votes = ImmutableArray.Empty - .Add(new VoteMetadata( - 0, 0, hash, DateTimeOffset.UtcNow, key.PublicKey, VoteFlag.PreCommit) + .Add( + new VoteMetadata( + 0, + 0, + hash, + DateTimeOffset.UtcNow, + key.PublicKey, + BigInteger.One, + VoteFlag.PreCommit) .Sign(key)); // Negative height is not allowed. @@ -89,6 +98,7 @@ public void EveryVoteMustHaveSameHeightAndRoundAsBlockCommit() hash, DateTimeOffset.UtcNow, key.PublicKey, + BigInteger.One, VoteFlag.PreCommit).Sign(key)); Assert.Throws(() => new BlockCommit(height, round, hash, votes)); @@ -101,6 +111,7 @@ public void EveryVoteMustHaveSameHeightAndRoundAsBlockCommit() hash, DateTimeOffset.UtcNow, key.PublicKey, + BigInteger.One, VoteFlag.PreCommit).Sign(key)); Assert.Throws(() => new BlockCommit(height, round, hash, votes)); @@ -122,6 +133,7 @@ public void EveryVoteMustHaveSameHashAsBlockCommit() badHash, DateTimeOffset.UtcNow, key.PublicKey, + BigInteger.One, VoteFlag.PreCommit).Sign(key)); Assert.Throws(() => new BlockCommit(height, round, hash, votes)); } @@ -133,9 +145,17 @@ public void EveryVoteFlagMustBeNullOrPreCommit() var round = 3; var hash = new BlockHash(TestUtils.GetRandomBytes(BlockHash.Size)); var keys = Enumerable.Range(0, 4).Select(_ => new PrivateKey()).ToList(); - var preCommitVotes = keys.Select(key => new VoteMetadata( - height, round, hash, DateTimeOffset.UtcNow, key.PublicKey, VoteFlag.PreCommit) - .Sign(key)).ToList(); + var preCommitVotes = keys.Select( + key => new VoteMetadata( + height, + round, + hash, + DateTimeOffset.UtcNow, + key.PublicKey, + BigInteger.One, + VoteFlag.PreCommit) + .Sign(key)) + .ToList(); var votes = ImmutableArray.Empty .Add(new VoteMetadata( @@ -144,6 +164,7 @@ public void EveryVoteFlagMustBeNullOrPreCommit() hash, DateTimeOffset.UtcNow, keys[0].PublicKey, + BigInteger.One, VoteFlag.Null).Sign(null)) .AddRange(preCommitVotes.Skip(1)); _ = new BlockCommit(height, round, hash, votes); @@ -155,6 +176,7 @@ public void EveryVoteFlagMustBeNullOrPreCommit() hash, DateTimeOffset.UtcNow, keys[0].PublicKey, + BigInteger.One, VoteFlag.Unknown).Sign(null)) .AddRange(preCommitVotes.Skip(1)); Assert.Throws(() => new BlockCommit(height, round, hash, votes)); @@ -166,6 +188,7 @@ public void EveryVoteFlagMustBeNullOrPreCommit() hash, DateTimeOffset.UtcNow, keys[0].PublicKey, + BigInteger.One, VoteFlag.PreVote).Sign(keys[0])) .AddRange(preCommitVotes.Skip(1)); Assert.Throws(() => new BlockCommit(height, round, hash, votes)); @@ -177,6 +200,7 @@ public void EveryVoteFlagMustBeNullOrPreCommit() hash, DateTimeOffset.UtcNow, keys[0].PublicKey, + BigInteger.One, VoteFlag.PreCommit).Sign(keys[0])) .AddRange(preCommitVotes.Skip(1)); _ = new BlockCommit(height, round, hash, votes); @@ -194,6 +218,7 @@ public void Bencoded() fx.Hash1, DateTimeOffset.Now, key.PublicKey, + BigInteger.One, VoteFlag.PreCommit).Sign(key)) .ToImmutableArray(); var expected = new BlockCommit(1, 0, fx.Hash1, votes); diff --git a/Libplanet.Tests/Blocks/BlockFixture.cs b/Libplanet.Tests/Blocks/BlockFixture.cs index bde5aa9beec..80c772711c9 100644 --- a/Libplanet.Tests/Blocks/BlockFixture.cs +++ b/Libplanet.Tests/Blocks/BlockFixture.cs @@ -54,6 +54,7 @@ public BlockFixture() Next.Hash, Next.Timestamp, Miner.PublicKey, + TestUtils.ValidatorSet.GetValidator(Miner.PublicKey).Power, VoteFlag.PreCommit).Sign(Miner), }.ToImmutableArray()) ); diff --git a/Libplanet.Tests/Blocks/BlockMetadataTest.cs b/Libplanet.Tests/Blocks/BlockMetadataTest.cs index a4c6ca2bfe0..05d736a5dfd 100644 --- a/Libplanet.Tests/Blocks/BlockMetadataTest.cs +++ b/Libplanet.Tests/Blocks/BlockMetadataTest.cs @@ -1,5 +1,6 @@ using System; using System.Collections.Immutable; +using System.Numerics; using System.Security.Cryptography; using Bencodex.Types; using Libplanet.Common; @@ -316,6 +317,7 @@ public void ValidateLastCommit() blockHash, timestamp, validatorB.PublicKey, + BigInteger.One, VoteFlag.Null).Sign(null), }.ToImmutableArray()); var validMetadata = new BlockMetadata( @@ -333,7 +335,7 @@ private static Vote GenerateVote(BlockHash hash, long height, int round, VoteFla { var key = new PrivateKey(); var voteMetadata = new VoteMetadata( - height, round, hash, DateTimeOffset.UtcNow, key.PublicKey, flag); + height, round, hash, DateTimeOffset.UtcNow, key.PublicKey, BigInteger.One, flag); return flag == VoteFlag.PreVote || flag == VoteFlag.PreCommit ? voteMetadata.Sign(key) : voteMetadata.Sign(null); diff --git a/Libplanet.Tests/Blocks/BlockTest.cs b/Libplanet.Tests/Blocks/BlockTest.cs index 8284accd61f..e977e28d063 100644 --- a/Libplanet.Tests/Blocks/BlockTest.cs +++ b/Libplanet.Tests/Blocks/BlockTest.cs @@ -70,8 +70,14 @@ public void TransactionOrderIdempotent() { new RandomAction(signer.Address), }.ToPlainValues())).ToImmutableArray(); - var blockA = ProposeGenesis(timestamp: timestamp, transactions: txs); - var blockB = ProposeGenesis(timestamp: timestamp, transactions: txs); + var blockA = ProposeGenesis( + GenesisProposer.PublicKey, + timestamp: timestamp, + transactions: txs); + var blockB = ProposeGenesis( + GenesisProposer.PublicKey, + timestamp: timestamp, + transactions: txs); Assert.True(blockA.Transactions.SequenceEqual(blockB.Transactions)); } diff --git a/Libplanet.Tests/Consensus/ValidatorSetTest.cs b/Libplanet.Tests/Consensus/ValidatorSetTest.cs index de75c01330b..e8a90ce4392 100644 --- a/Libplanet.Tests/Consensus/ValidatorSetTest.cs +++ b/Libplanet.Tests/Consensus/ValidatorSetTest.cs @@ -131,14 +131,26 @@ public void ValidateBlockCommitValidators() var validatorSet = new ValidatorSet(unorderedPrivateKeys.Select( key => new Validator(key.PublicKey, BigInteger.One)).ToList()); var unorderedVotes = unorderedPrivateKeys - .Select(key => new VoteMetadata( - height, round, hash, DateTimeOffset.UtcNow, key.PublicKey, VoteFlag.PreCommit) - .Sign(key)) + .Select( + key => new VoteMetadata( + height, + round, + hash, + DateTimeOffset.UtcNow, + key.PublicKey, + BigInteger.One, + VoteFlag.PreCommit).Sign(key)) .ToImmutableArray(); var orderedVotes = orderedPrivateKeys - .Select(key => new VoteMetadata( - height, round, hash, DateTimeOffset.UtcNow, key.PublicKey, VoteFlag.PreCommit) - .Sign(key)) + .Select( + key => new VoteMetadata( + height, + round, + hash, + DateTimeOffset.UtcNow, + key.PublicKey, + BigInteger.One, + VoteFlag.PreCommit).Sign(key)) .ToImmutableArray(); var blockCommitWithUnorderedVotes = diff --git a/Libplanet.Tests/Consensus/VoteMetadataTest.cs b/Libplanet.Tests/Consensus/VoteMetadataTest.cs index 3cd0330e5df..af25df1bbe8 100644 --- a/Libplanet.Tests/Consensus/VoteMetadataTest.cs +++ b/Libplanet.Tests/Consensus/VoteMetadataTest.cs @@ -1,4 +1,5 @@ using System; +using System.Numerics; using Libplanet.Crypto; using Libplanet.Types.Blocks; using Libplanet.Types.Consensus; @@ -17,9 +18,21 @@ public void NullBlockHashNotAllowedForNullAndUnknown() // Works with some hash value. _ = new VoteMetadata( - 2, 2, hash, DateTimeOffset.UtcNow, new PrivateKey().PublicKey, VoteFlag.Null); + 2, + 2, + hash, + DateTimeOffset.UtcNow, + new PrivateKey().PublicKey, + BigInteger.One, + VoteFlag.Null); _ = new VoteMetadata( - 2, 2, hash, DateTimeOffset.UtcNow, new PrivateKey().PublicKey, VoteFlag.Unknown); + 2, + 2, + hash, + DateTimeOffset.UtcNow, + new PrivateKey().PublicKey, + BigInteger.One, + VoteFlag.Unknown); // Null hash is not allowed. Assert.Throws(() => new VoteMetadata( @@ -28,6 +41,7 @@ public void NullBlockHashNotAllowedForNullAndUnknown() default, DateTimeOffset.UtcNow, new PrivateKey().PublicKey, + BigInteger.One, VoteFlag.Null)); Assert.Throws(() => new VoteMetadata( 2, @@ -35,6 +49,7 @@ public void NullBlockHashNotAllowedForNullAndUnknown() default, DateTimeOffset.UtcNow, new PrivateKey().PublicKey, + BigInteger.One, VoteFlag.Unknown)); } @@ -49,6 +64,7 @@ public void Bencoded() hash, DateTimeOffset.UtcNow, key.PublicKey, + BigInteger.One, VoteFlag.PreCommit); var decoded = new VoteMetadata(expected.Bencoded); Assert.Equal(expected, decoded); diff --git a/Libplanet.Tests/Consensus/VoteTest.cs b/Libplanet.Tests/Consensus/VoteTest.cs index da9d846fa8c..092b3c2663d 100644 --- a/Libplanet.Tests/Consensus/VoteTest.cs +++ b/Libplanet.Tests/Consensus/VoteTest.cs @@ -1,5 +1,6 @@ using System; using System.Collections.Immutable; +using System.Numerics; using Libplanet.Crypto; using Libplanet.Types.Blocks; using Libplanet.Types.Consensus; @@ -22,6 +23,7 @@ public void Sign() hash, DateTimeOffset.UtcNow, privateKey.PublicKey, + BigInteger.One, VoteFlag.PreCommit); Vote vote = voteMetadata.Sign(privateKey); Assert.True( @@ -40,6 +42,7 @@ public void CannotSignWithWrongPrivateKey() blockHash: hash, timestamp: DateTimeOffset.UtcNow, validatorPublicKey: validatorPublicKey, + validatorPower: BigInteger.One, flag: VoteFlag.PreCommit); // Cannot sign with Sign method @@ -63,6 +66,7 @@ public void EmptySignatureNotAllowedForPreVoteAndPreCommit() blockHash: hash, timestamp: DateTimeOffset.UtcNow, validatorPublicKey: key.PublicKey, + validatorPower: BigInteger.One, flag: VoteFlag.PreVote); var preCommitMetadata = new VoteMetadata( height: 2, @@ -70,6 +74,7 @@ public void EmptySignatureNotAllowedForPreVoteAndPreCommit() blockHash: hash, timestamp: DateTimeOffset.UtcNow, validatorPublicKey: key.PublicKey, + validatorPower: BigInteger.One, flag: VoteFlag.PreCommit); // Works fine. @@ -95,6 +100,7 @@ public void NonEmptySignatureNotAllowedForNullAndUnknown() blockHash: hash, timestamp: DateTimeOffset.UtcNow, validatorPublicKey: key.PublicKey, + validatorPower: BigInteger.One, flag: VoteFlag.Null); var unknownMetadata = new VoteMetadata( height: 2, @@ -102,6 +108,7 @@ public void NonEmptySignatureNotAllowedForNullAndUnknown() blockHash: hash, timestamp: DateTimeOffset.UtcNow, validatorPublicKey: key.PublicKey, + validatorPower: BigInteger.One, flag: VoteFlag.Unknown); // Works fine. @@ -129,6 +136,7 @@ public void DefaultSignatureIsInvalid() default, DateTimeOffset.UtcNow, new PrivateKey().PublicKey, + BigInteger.One, VoteFlag.PreCommit); Assert.Throws(() => new Vote(voteMetadata, default)); } @@ -144,6 +152,7 @@ public void Bencoded() hash, DateTimeOffset.UtcNow, key.PublicKey, + BigInteger.One, VoteFlag.PreCommit).Sign(key); var decoded = new Vote(expected.Bencoded); Assert.Equal(expected, decoded); diff --git a/Libplanet.Tests/Store/StoreFixture.cs b/Libplanet.Tests/Store/StoreFixture.cs index 2dec496ce10..7a12a0471b2 100644 --- a/Libplanet.Tests/Store/StoreFixture.cs +++ b/Libplanet.Tests/Store/StoreFixture.cs @@ -1,6 +1,7 @@ using System; using System.Collections.Generic; using System.Collections.Immutable; +using System.Numerics; using System.Security.Cryptography; using Libplanet.Action; using Libplanet.Action.Loader; @@ -99,6 +100,7 @@ protected StoreFixture( var stateStore = new TrieStateStore(new MemoryKeyValueStore()); var stateRootHashes = new Dictionary>(); Proposer = TestUtils.GenesisProposer; + ProposerPower = TestUtils.ValidatorSet[0].Power; var preEval = TestUtils.ProposeGenesis( proposer: Proposer.PublicKey, validatorSet: TestUtils.ValidatorSet); @@ -171,6 +173,8 @@ protected StoreFixture( public PrivateKey Proposer { get; } + public BigInteger ProposerPower { get; } + public Block GenesisBlock { get; } public Block Block1 { get; } diff --git a/Libplanet.Tests/Store/StoreTest.cs b/Libplanet.Tests/Store/StoreTest.cs index 48be9570012..ae1f2e9cfa3 100644 --- a/Libplanet.Tests/Store/StoreTest.cs +++ b/Libplanet.Tests/Store/StoreTest.cs @@ -2,6 +2,7 @@ using System.Collections.Generic; using System.Collections.Immutable; using System.Linq; +using System.Numerics; using System.Security.Cryptography; using System.Threading.Tasks; using Bencodex.Types; @@ -1086,6 +1087,7 @@ public void GetBlockCommit() hash, DateTimeOffset.UtcNow, validator.PublicKey, + BigInteger.One, VoteFlag.PreCommit).Sign(validator)).ToImmutableArray(); BlockCommit commit = new BlockCommit(height, round, hash, votes); @@ -1109,6 +1111,7 @@ public void GetBlockCommitIndices() fx.Block1.Hash, DateTimeOffset.UtcNow, fx.Proposer.PublicKey, + fx.ProposerPower, VoteFlag.PreCommit).Sign(fx.Proposer)); var votesTwo = ImmutableArray.Empty .Add(new VoteMetadata( @@ -1117,6 +1120,7 @@ public void GetBlockCommitIndices() fx.Block2.Hash, DateTimeOffset.UtcNow, fx.Proposer.PublicKey, + fx.ProposerPower, VoteFlag.PreCommit).Sign(fx.Proposer)); BlockCommit[] blockCommits = @@ -1159,6 +1163,7 @@ public void DeleteLastCommit() Fx.GenesisBlock.Hash, DateTimeOffset.UtcNow, validatorPrivateKey.PublicKey, + BigInteger.One, VoteFlag.PreCommit).Sign(validatorPrivateKey))); fx.Store.PutBlockCommit(blockCommit); diff --git a/Libplanet.Tests/TestUtils.cs b/Libplanet.Tests/TestUtils.cs index 19531218a72..63e0dcb2ca1 100644 --- a/Libplanet.Tests/TestUtils.cs +++ b/Libplanet.Tests/TestUtils.cs @@ -40,13 +40,7 @@ namespace Libplanet.Tests { public static class TestUtils { - public static readonly PrivateKey GenesisProposer = PrivateKey.FromString( - "2a15e7deaac09ce631e1faa184efadb175b6b90989cf1faed9dfc321ad1db5ac"); - - public static readonly PrivateKey ChainPrivateKey = PrivateKey.FromString( - "cf36ecf9e47c879a0dbf46b2ecd83fd276182ade0265825e3b8c6ba214467b76"); - - public static readonly List ValidatorPrivateKeys = new List + public static readonly ImmutableList ValidatorPrivateKeys = new List { PrivateKey.FromString( "e5792a1518d9c7f7ecc35cd352899211a05164c9dde059c9811e0654860549ef"), @@ -56,7 +50,7 @@ public static class TestUtils "b17c919b07320edfb3e6da2f1cfed75910322de2e49377d6d4d226505afca550"), PrivateKey.FromString( "91602d7091c5c7837ac8e71a8d6b1ed1355cfe311914d9a76107899add0ad56a"), - }; // The ordering here should match the ordering by address. + }.ToImmutableList(); // The ordering here should match the ordering by address. public static readonly ValidatorSet ValidatorSet = new ValidatorSet( ValidatorPrivateKeys.Select( @@ -140,6 +134,8 @@ public static class TestUtils private static readonly Random _random = new Random(); + public static PrivateKey GenesisProposer => ValidatorPrivateKeys[0]; + public static void AssertBytesEqual(byte[] expected, byte[] actual) { if (expected is null) @@ -400,6 +396,7 @@ public static BlockCommit CreateBlockCommit( blockHash, deterministicTimestamp ? DateTimeOffset.UnixEpoch : DateTimeOffset.UtcNow, key.PublicKey, + ValidatorSet.GetValidator(key.PublicKey).Power, VoteFlag.PreCommit).Sign(key)).ToImmutableArray(); return new BlockCommit( @@ -407,7 +404,7 @@ public static BlockCommit CreateBlockCommit( } public static PreEvaluationBlock ProposeGenesis( - PublicKey proposer = null, + PublicKey proposer, IReadOnlyList transactions = null, ValidatorSet validatorSet = null, DateTimeOffset? timestamp = null, @@ -415,7 +412,7 @@ public static PreEvaluationBlock ProposeGenesis( ) { var txs = transactions?.ToList() ?? new List(); - long nonce = 0; + long nonce = txs.Count(tx => tx.Signer.Equals(GenesisProposer.Address)); validatorSet = validatorSet ?? ValidatorSet; txs.AddRange( validatorSet.Validators.Select( @@ -597,7 +594,7 @@ public static (BlockChain BlockChain, ActionEvaluator ActionEvaluator) ) { actions = actions ?? ImmutableArray.Empty; - privateKey = privateKey ?? ChainPrivateKey; + privateKey = privateKey ?? GenesisProposer; var txs = new[] { @@ -619,7 +616,7 @@ public static (BlockChain BlockChain, ActionEvaluator ActionEvaluator) if (genesisBlock is null) { var preEval = ProposeGenesis( - GenesisProposer.PublicKey, + privateKey.PublicKey, txs, validatorSet, timestamp, @@ -636,7 +633,7 @@ public static (BlockChain BlockChain, ActionEvaluator ActionEvaluator) null, preEval.Header.DeriveBlockHash(stateRootHash, null) )) - : preEval.Sign(GenesisProposer, stateRootHash); + : preEval.Sign(privateKey, stateRootHash); } ValidatingActionRenderer validator = null; diff --git a/Libplanet.Types/Blocks/PreEvaluationBlockHeader.cs b/Libplanet.Types/Blocks/PreEvaluationBlockHeader.cs index 4c725eab8c3..365e0dfd93a 100644 --- a/Libplanet.Types/Blocks/PreEvaluationBlockHeader.cs +++ b/Libplanet.Types/Blocks/PreEvaluationBlockHeader.cs @@ -156,7 +156,7 @@ public ImmutableArray MakeSignature( } else if (!privateKey.PublicKey.Equals(PublicKey)) { - string m = "The given private key does not match to the miner's public key." + + string m = "The given private key does not match to the proposer's public key." + $"Block's public key: {PublicKey}\n" + $"Derived public key: {privateKey.PublicKey}\n"; throw new ArgumentException(m, nameof(privateKey)); diff --git a/Libplanet.Types/Consensus/IVoteMetadata.cs b/Libplanet.Types/Consensus/IVoteMetadata.cs index 6e40855da88..6e9b4dfb895 100644 --- a/Libplanet.Types/Consensus/IVoteMetadata.cs +++ b/Libplanet.Types/Consensus/IVoteMetadata.cs @@ -1,4 +1,5 @@ using System; +using System.Numerics; using Libplanet.Crypto; using Libplanet.Types.Blocks; @@ -35,6 +36,11 @@ public interface IVoteMetadata /// PublicKey ValidatorPublicKey { get; } + /// + /// The voting power of the validator that voted. + /// + BigInteger ValidatorPower { get; } + /// /// The indicating the type of a . /// diff --git a/Libplanet.Types/Consensus/Vote.cs b/Libplanet.Types/Consensus/Vote.cs index e49b31c2f38..0b2b8deb139 100644 --- a/Libplanet.Types/Consensus/Vote.cs +++ b/Libplanet.Types/Consensus/Vote.cs @@ -4,6 +4,7 @@ using System.Diagnostics.Contracts; using System.Globalization; using System.Linq; +using System.Numerics; using System.Text.Json; using System.Text.Json.Serialization; using Bencodex; @@ -101,6 +102,9 @@ private Vote(Bencodex.Types.Dictionary encoded) /// public PublicKey ValidatorPublicKey => _metadata.ValidatorPublicKey; + /// + public BigInteger ValidatorPower => _metadata.ValidatorPower; + /// public VoteFlag Flag => _metadata.Flag; diff --git a/Libplanet.Types/Consensus/VoteMetadata.cs b/Libplanet.Types/Consensus/VoteMetadata.cs index fb22f9f00a1..6db9b6343c4 100644 --- a/Libplanet.Types/Consensus/VoteMetadata.cs +++ b/Libplanet.Types/Consensus/VoteMetadata.cs @@ -1,6 +1,7 @@ using System; using System.Collections.Immutable; using System.Globalization; +using System.Numerics; using System.Text.Json.Serialization; using Bencodex; using Bencodex.Types; @@ -30,6 +31,9 @@ public class VoteMetadata : IVoteMetadata, IEquatable, IBencodable private static readonly Binary ValidatorPublicKeyKey = new Binary(new byte[] { 0x50 }); // 'P' + private static readonly Binary ValidatorPowerKey = + new Binary(new byte[] { 0x70 }); // 'p' + private static readonly Binary FlagKey = new Binary(new byte[] { 0x46 }); // 'F' @@ -45,6 +49,7 @@ public class VoteMetadata : IVoteMetadata, IEquatable, IBencodable /// /// of the validator made the vote. /// + /// The voting power of the validator. /// for the vote's status. /// Thrown for any of the following reasons: /// @@ -64,6 +69,7 @@ public VoteMetadata( BlockHash blockHash, DateTimeOffset timestamp, PublicKey validatorPublicKey, + BigInteger validatorPower, VoteFlag flag) { if (height < 0) @@ -76,6 +82,12 @@ public VoteMetadata( throw new ArgumentException( $"Given {nameof(round)} cannot be negative: {round}"); } + else if (validatorPower <= 0) + { + var msg = $"Given {nameof(validatorPower)} cannot be negative " + + $"or equal to zero: {validatorPower}"; + throw new ArgumentException(msg); + } else if ( blockHash.Equals(default) && (flag == VoteFlag.Null || flag == VoteFlag.Unknown)) { @@ -89,6 +101,7 @@ public VoteMetadata( BlockHash = blockHash; Timestamp = timestamp; ValidatorPublicKey = validatorPublicKey; + ValidatorPower = validatorPower; Flag = flag; } @@ -114,6 +127,7 @@ private VoteMetadata(Bencodex.Types.Dictionary bencoded) CultureInfo.InvariantCulture), validatorPublicKey: new PublicKey( ((Binary)bencoded[ValidatorPublicKeyKey]).ByteArray), + validatorPower: (Integer)bencoded[ValidatorPowerKey], flag: (VoteFlag)(int)(Integer)bencoded[FlagKey]) { } @@ -134,6 +148,9 @@ private VoteMetadata(Bencodex.Types.Dictionary bencoded) /// public PublicKey ValidatorPublicKey { get; } + /// + public BigInteger ValidatorPower { get; } + /// public VoteFlag Flag { get; } @@ -150,6 +167,7 @@ public Bencodex.Types.IValue Bencoded TimestampKey, Timestamp.ToString(TimestampFormat, CultureInfo.InvariantCulture)) .Add(ValidatorPublicKeyKey, ValidatorPublicKey.Format(compress: true)) + .Add(ValidatorPowerKey, ValidatorPower) .Add(FlagKey, (long)Flag); if (BlockHash is { } blockHash) @@ -189,6 +207,7 @@ public bool Equals(VoteMetadata? other) TimestampFormat, CultureInfo.InvariantCulture)) && ValidatorPublicKey.Equals(metadata.ValidatorPublicKey) && + ValidatorPower == metadata.ValidatorPower && Flag == metadata.Flag; }