Skip to content

Commit 1acde4b

Browse files
quantumagifassadlr
authored andcommitted
Improve LastRemovalEventId determinism by adding ordering (#826)
* Improve LastRemovalEventId determinism by adding ordering * Cleanup * Changes based on feedback
1 parent c5210d0 commit 1acde4b

File tree

2 files changed

+21
-16
lines changed

2 files changed

+21
-16
lines changed

src/Stratis.Bitcoin.Features.PoA/Voting/JoinFederationRequestService.cs

Lines changed: 18 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -49,6 +49,23 @@ public JoinFederationRequestService(ICounterChainSettings counterChainSettings,
4949
this.votingManager = votingManager;
5050
}
5151

52+
public static byte[] GetFederationMemberBytes(JoinFederationRequest joinRequest, Network network, Network counterChainNetwork)
53+
{
54+
Script collateralScript = PayToPubkeyHashTemplate.Instance.GenerateScriptPubKey(joinRequest.CollateralMainchainAddress);
55+
BitcoinAddress bitcoinAddress = collateralScript.GetDestinationAddress(counterChainNetwork);
56+
var collateralFederationMember = new CollateralFederationMember(joinRequest.PubKey, false, joinRequest.CollateralAmount, bitcoinAddress.ToString());
57+
58+
return (network.Consensus.ConsensusFactory as CollateralPoAConsensusFactory).SerializeFederationMember(collateralFederationMember);
59+
}
60+
61+
public static void SetLastRemovalEventId(JoinFederationRequest joinRequest, byte[] federationMemberBytes, VotingManager votingManager)
62+
{
63+
Poll poll = votingManager.GetExecutedPolls().OrderByDescending(p => p.PollExecutedBlockData.Height).FirstOrDefault(x =>
64+
x.VotingData.Key == VoteKey.KickFederationMember && x.VotingData.Data.SequenceEqual(federationMemberBytes));
65+
66+
joinRequest.RemovalEventId = (poll == null) ? Guid.Empty : new Guid(poll.PollExecutedBlockData.Hash.ToBytes().TakeLast(16).ToArray());
67+
}
68+
5269
public async Task<PubKey> JoinFederationAsync(JoinFederationRequestModel request, CancellationToken cancellationToken)
5370
{
5471
// Wait until the node is synced before joining.
@@ -74,13 +91,7 @@ public async Task<PubKey> JoinFederationAsync(JoinFederationRequestModel request
7491
var joinRequest = new JoinFederationRequest(minerKey.PubKey, new Money(expectedCollateralAmount, MoneyUnit.BTC), addressKey);
7592

7693
// Populate the RemovalEventId.
77-
var collateralFederationMember = new CollateralFederationMember(minerKey.PubKey, false, joinRequest.CollateralAmount, request.CollateralAddress);
78-
79-
byte[] federationMemberBytes = (this.network.Consensus.ConsensusFactory as CollateralPoAConsensusFactory).SerializeFederationMember(collateralFederationMember);
80-
Poll poll = this.votingManager.GetApprovedPolls().FirstOrDefault(x => x.IsExecuted &&
81-
x.VotingData.Key == VoteKey.KickFederationMember && x.VotingData.Data.SequenceEqual(federationMemberBytes));
82-
83-
joinRequest.RemovalEventId = (poll == null) ? Guid.Empty : new Guid(poll.PollExecutedBlockData.Hash.ToBytes().TakeLast(16).ToArray());
94+
SetLastRemovalEventId(joinRequest, GetFederationMemberBytes(joinRequest, this.network, this.counterChainSettings.CounterChainNetwork), this.votingManager);
8495

8596
// Get the signature by calling the counter-chain "signmessage" API.
8697
var signMessageRequest = new SignMessageRequest()

src/Stratis.Features.Collateral/JoinFederationRequestMonitor.cs

Lines changed: 3 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@
1010
using Stratis.Bitcoin.PoA.Features.Voting;
1111
using Stratis.Bitcoin.Signals;
1212
using Stratis.Features.Collateral.CounterChain;
13+
using Stratis.Features.PoA.Voting;
1314

1415
namespace Stratis.Features.Collateral
1516
{
@@ -88,11 +89,7 @@ public void OnBlockConnected(BlockConnected blockConnectedData)
8889
}
8990

9091
// Fill in the request.removalEventId (if any).
91-
Script collateralScript = PayToPubkeyHashTemplate.Instance.GenerateScriptPubKey(request.CollateralMainchainAddress);
92-
93-
var collateralFederationMember = new CollateralFederationMember(request.PubKey, false, request.CollateralAmount, collateralScript.GetDestinationAddress(this.counterChainNetwork).ToString());
94-
95-
byte[] federationMemberBytes = consensusFactory.SerializeFederationMember(collateralFederationMember);
92+
byte[] federationMemberBytes = JoinFederationRequestService.GetFederationMemberBytes(request, this.network, this.counterChainNetwork);
9693

9794
// Nothing to do if already voted.
9895
if (this.votingManager.AlreadyVotingFor(VoteKey.AddFederationMember, federationMemberBytes))
@@ -102,10 +99,7 @@ public void OnBlockConnected(BlockConnected blockConnectedData)
10299
}
103100

104101
// Populate the RemovalEventId.
105-
Poll poll = this.votingManager.GetApprovedPolls().FirstOrDefault(x => x.IsExecuted &&
106-
x.VotingData.Key == VoteKey.KickFederationMember && x.VotingData.Data.SequenceEqual(federationMemberBytes));
107-
108-
request.RemovalEventId = (poll == null) ? Guid.Empty : new Guid(poll.PollExecutedBlockData.Hash.ToBytes().TakeLast(16).ToArray());
102+
JoinFederationRequestService.SetLastRemovalEventId(request, federationMemberBytes, this.votingManager);
109103

110104
// Check the signature.
111105
PubKey key = PubKey.RecoverFromMessage(request.SignatureMessage, request.Signature);

0 commit comments

Comments
 (0)