Skip to content

Commit 11a0b25

Browse files
committed
Refactor polls repo initialize method
2 parents 08fdf3b + 8a6f3f4 commit 11a0b25

File tree

2 files changed

+71
-46
lines changed

2 files changed

+71
-46
lines changed

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

Lines changed: 70 additions & 46 deletions
Original file line numberDiff line numberDiff line change
@@ -81,77 +81,101 @@ public void Initialize()
8181
return;
8282
}
8383

84-
this.highestPollId = (polls.Length > 0) ? polls.Max(p => p.Id) : -1;
85-
8684
Row<byte[], byte[]> rowTip = transaction.Select<byte[], byte[]>(DataTable, RepositoryTipKey);
85+
if (!rowTip.Exists)
86+
{
87+
this.logger.LogInformation("The polls repository tip is unknown. Will re-build the repo.");
88+
this.ResetLocked(transaction);
89+
transaction.Commit();
90+
return;
91+
}
8792

88-
if (rowTip.Exists)
93+
this.CurrentTip = this.dBreezeSerializer.Deserialize<HashHeightPair>(rowTip.Value);
94+
if (this.chainIndexer == null || this.chainIndexer.GetHeader(this.CurrentTip.Hash) != null)
8995
{
90-
this.CurrentTip = this.dBreezeSerializer.Deserialize<HashHeightPair>(rowTip.Value);
91-
if (this.chainIndexer != null && this.chainIndexer.GetHeader(this.CurrentTip.Hash) == null)
92-
this.CurrentTip = null;
96+
this.highestPollId = (polls.Length > 0) ? polls.Max(p => p.Id) : -1;
97+
return;
9398
}
9499

95-
if (this.CurrentTip == null)
100+
this.logger.LogInformation("The polls repository tip {0} was not found in the consensus chain. Determining fork.", this.CurrentTip);
101+
102+
// == Find fork.
103+
// The polls repository tip could not be found in the consenus chain.
104+
// Look at all other known hash/height pairs to find something in common with the consensus chain.
105+
// We will take that as the last known valid height.
106+
107+
int maxGoodHeight = -1;
108+
109+
foreach (Poll poll in polls)
96110
{
111+
if (poll.PollStartBlockData.Height > maxGoodHeight && this.chainIndexer.GetHeader(poll.PollStartBlockData.Hash) != null)
112+
maxGoodHeight = poll.PollStartBlockData.Height;
113+
if (poll.PollExecutedBlockData?.Height > maxGoodHeight && this.chainIndexer.GetHeader(poll.PollExecutedBlockData.Hash) != null)
114+
maxGoodHeight = poll.PollStartBlockData.Height;
115+
if (poll.PollVotedInFavorBlockData?.Height > maxGoodHeight && this.chainIndexer.GetHeader(poll.PollExecutedBlockData.Hash) != null)
116+
maxGoodHeight = poll.PollStartBlockData.Height;
117+
}
118+
119+
if (maxGoodHeight == -1)
120+
{
121+
this.logger.LogInformation("No common blocks found. Will rebuild the repo from scratch.");
97122
this.ResetLocked(transaction);
98123
transaction.Commit();
124+
return;
99125
}
100-
else if (this.chainIndexer != null)
126+
127+
this.CurrentTip = new HashHeightPair(this.chainIndexer.GetHeader(maxGoodHeight));
128+
129+
this.logger.LogInformation("Common block found at height {0}. Will re-build the repo from there.", this.CurrentTip.Height);
130+
131+
// Trim polls to tip.
132+
HashSet<Poll> pollsToDelete = new HashSet<Poll>();
133+
foreach (Poll poll in polls)
101134
{
102-
// Trim poll information to chain indexer tip.
103-
ChainedHeader newTip = this.chainIndexer.Tip;
135+
if (poll.PollStartBlockData.Height > this.CurrentTip.Height)
136+
{
137+
pollsToDelete.Add(poll);
138+
continue;
139+
}
104140

105-
HashSet<Poll> pollsToDelete = new HashSet<Poll>();
106-
foreach (Poll poll in polls)
141+
bool modified = false;
142+
143+
if (poll.PubKeysHexVotedInFavor.Any(v => v.Height > this.CurrentTip.Height))
107144
{
108-
if (poll.PollStartBlockData.Height > newTip.Height)
109-
{
110-
pollsToDelete.Add(poll);
111-
continue;
112-
}
113-
114-
bool modified = false;
115-
116-
if (poll.PubKeysHexVotedInFavor.Any(v => v.Height > newTip.Height))
117-
{
118-
poll.PubKeysHexVotedInFavor = poll.PubKeysHexVotedInFavor.Where(v => v.Height <= newTip.Height).ToList();
119-
modified = true;
120-
}
121-
122-
if (poll.PollExecutedBlockData?.Height > newTip.Height)
123-
{
124-
poll.PollExecutedBlockData = null;
125-
modified = true;
126-
}
127-
128-
if (poll.PollVotedInFavorBlockData?.Height > newTip.Height)
129-
{
130-
poll.PollVotedInFavorBlockData = null;
131-
modified = true;
132-
}
133-
134-
if (modified)
135-
UpdatePoll(transaction, poll);
145+
poll.PubKeysHexVotedInFavor = poll.PubKeysHexVotedInFavor.Where(v => v.Height <= this.CurrentTip.Height).ToList();
146+
modified = true;
136147
}
137148

138-
DeletePollsAndSetHighestPollId(transaction, pollsToDelete.Select(p => p.Id).ToArray());
149+
if (poll.PollExecutedBlockData?.Height > this.CurrentTip.Height)
150+
{
151+
poll.PollExecutedBlockData = null;
152+
modified = true;
153+
}
139154

140-
SaveCurrentTip(transaction, newTip);
155+
if (poll.PollVotedInFavorBlockData?.Height > this.CurrentTip.Height)
156+
{
157+
poll.PollVotedInFavorBlockData = null;
158+
modified = true;
159+
}
141160

142-
transaction.Commit();
161+
if (modified)
162+
UpdatePoll(transaction, poll);
143163
}
164+
165+
DeletePollsAndSetHighestPollId(transaction, pollsToDelete.Select(p => p.Id).ToArray());
166+
167+
transaction.Commit();
168+
169+
this.logger.LogDebug("Polls repo initialized with highest id: {0}.", this.highestPollId);
144170
}
145171
catch (Exception err) when (err.Message == "No more byte to read")
146172
{
147-
// The polls repository requires an upgrade.
173+
this.logger.LogWarning("There was an error reading the polls repository. Will rebuild it.");
148174
this.ResetLocked(transaction);
149175
transaction.Commit();
150176
}
151177
}
152178
}
153-
154-
this.logger.LogDebug("Polls repo initialized with highest id: {0}.", this.highestPollId);
155179
}
156180

157181
private void ResetLocked(DBreeze.Transactions.Transaction transaction)

src/Stratis.Sidechains.Networks/CirrusMain.cs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -270,6 +270,7 @@ public CirrusMain()
270270
{ 1_850_000, new CheckpointInfo(new uint256("0x6e2590bd9a8eaab25b236c0c9ac314abec70b18aa053b96c9257f2356dec8314")) },
271271
{ 2_150_000, new CheckpointInfo(new uint256("0x4c65f29b5098479cab275afd77d302ebe5ed8d8ef33e02ae54bf185865763f18")) },
272272
{ 2_500_000, new CheckpointInfo(new uint256("0x2853be7b7224840d3d4b60427ea832e9bd67d8fc6bfcd4956b8c6b2414cf8fc2")) },
273+
{ 2_827_550, new CheckpointInfo(new uint256("0xcf0ebdd99ec04ef260d22befe70ef7b948e50b5fcc18d9d37376d49e872372a0")) }
273274
};
274275

275276
this.DNSSeeds = new List<DNSSeedData>

0 commit comments

Comments
 (0)