-
Notifications
You must be signed in to change notification settings - Fork 514
/
Copy pathIBlockTree.cs
207 lines (165 loc) · 9.05 KB
/
IBlockTree.cs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
// SPDX-FileCopyrightText: 2022 Demerzel Solutions Limited
// SPDX-License-Identifier: LGPL-3.0-only
using System;
using System.Collections.Generic;
using System.Threading;
using System.Threading.Tasks;
using Nethermind.Blockchain.Find;
using Nethermind.Blockchain.Visitors;
using Nethermind.Core;
using Nethermind.Core.Collections;
using Nethermind.Core.Crypto;
namespace Nethermind.Blockchain
{
public interface IBlockTree : IBlockFinder
{
/// <summary>
/// Network ID that identifies the chain among the public and private chains (different IDs for mainnet, ETH classic, etc.)
/// </summary>
ulong NetworkId { get; }
/// <summary>
/// Additional identifier of the chain to mitigate risks described in 155
/// </summary>
ulong ChainId { get; }
/// <summary>
/// Genesis block or <value>null</value> if genesis has not been processed yet
/// </summary>
BlockHeader? Genesis { get; }
/// <summary>
/// Best header that has been suggested for processing
/// </summary>
BlockHeader? BestSuggestedHeader { get; }
/// <summary>
/// Best block that has been suggested for processing
/// </summary>
Block? BestSuggestedBody { get; }
BlockHeader? BestSuggestedBeaconHeader { get; }
/// <summary>
/// Lowest header added in reverse fast sync insert
/// </summary>
BlockHeader? LowestInsertedHeader { get; set; }
/// <summary>
/// Lowest header number added in reverse beacon sync insert. Used to determine if BeaconHeaderSync is completed.
/// </summary>
BlockHeader? LowestInsertedBeaconHeader { get; set; }
/// <summary>
/// Best downloaded block number (highest number of chain level on the chain)
/// </summary>
long BestKnownNumber { get; }
long BestKnownBeaconNumber { get; }
/// <summary>
/// Inserts a disconnected block header (without body)
/// </summary>
/// <param name="header">Header to add</param>
/// <param name="headerOptions"></param>
/// <returns>Result of the operation, eg. Added, AlreadyKnown, etc.</returns>
AddBlockResult Insert(BlockHeader header, BlockTreeInsertHeaderOptions headerOptions = BlockTreeInsertHeaderOptions.None);
/// <summary>
/// Inserts a disconnected batched block header (without body)
/// </summary>
/// <param name="headers">Header batch to add</param>
/// <param name="headerOptions"></param>
/// <returns>Result of the operation, eg. Added, AlreadyKnown, etc.</returns>
void BulkInsertHeader(IReadOnlyList<BlockHeader> headers, BlockTreeInsertHeaderOptions headerOptions = BlockTreeInsertHeaderOptions.None);
/// <summary>
/// Inserts a disconnected block body (not for processing).
/// </summary>
/// <param name="block">Block to add</param>
/// <returns>Result of the operation, eg. Added, AlreadyKnown, etc.</returns>
AddBlockResult Insert(Block block, BlockTreeInsertBlockOptions insertBlockOptions = BlockTreeInsertBlockOptions.None,
BlockTreeInsertHeaderOptions insertHeaderOptions = BlockTreeInsertHeaderOptions.None, WriteFlags bodiesWriteFlags = WriteFlags.None);
void UpdateHeadBlock(Hash256 blockHash);
/// <summary>
/// Suggests block for inclusion in the block tree.
/// </summary>
/// <param name="block">Block to be included</param>
/// <param name="options">Options for suggesting block, whether a block should be processed or just added to the store.</param>
/// <returns>Result of the operation, eg. Added, AlreadyKnown, etc.</returns>
AddBlockResult SuggestBlock(Block block, BlockTreeSuggestOptions options = BlockTreeSuggestOptions.ShouldProcess);
/// <summary>
/// Suggests block for inclusion in the block tree. Wait for DB unlock if needed.
/// </summary>
/// <param name="block">Block to be included</param>
/// <param name="options">Options for suggesting block, whether a block should be processed or just added to the store.</param>
/// <returns>Result of the operation, eg. Added, AlreadyKnown, etc.</returns>
ValueTask<AddBlockResult> SuggestBlockAsync(Block block, BlockTreeSuggestOptions options = BlockTreeSuggestOptions.ShouldProcess);
/// <summary>
/// Suggests a block header (without body)
/// </summary>
/// <param name="header">Header to add</param>
/// <returns>Result of the operation, eg. Added, AlreadyKnown, etc.</returns>
AddBlockResult SuggestHeader(BlockHeader header);
/// <summary>
/// Checks if the block was downloaded and the block RLP is in the DB
/// </summary>
/// <param name="number">Number of the block to check (needed for faster lookup)</param>
/// <param name="blockHash">Hash of the block to check</param>
/// <returns><value>True</value> if known, otherwise <value>False</value></returns>
bool IsKnownBlock(long number, Hash256 blockHash);
/// <summary>
/// Checks if beacon block was inserted and the block RLP is in the DB
/// </summary>
/// <param name="number">Number of the block to check (needed for faster lookup)</param>
/// <param name="blockHash">Hash of the block to check</param>
/// <returns><value>True</value> if known, otherwise <value>False</value></returns>
bool IsKnownBeaconBlock(long number, Hash256 blockHash);
/// <summary>
/// Checks if the state changes of the block can be found in the state tree.
/// </summary>
/// <param name="number">Number of the block to check (needed for faster lookup)</param>
/// <param name="blockHash">Hash of the block to check</param>
/// <returns><value>True</value> if processed, otherwise <value>False</value></returns>
bool WasProcessed(long number, Hash256 blockHash);
/// <summary>
/// Marks all <paramref name="blocks"/> as processed, changes chain head to the last of them and updates all the chain levels./>
/// </summary>
/// <param name="blocks">Blocks that will now be at the top of the chain</param>
/// <param name="wereProcessed"></param>
/// <param name="forceHeadBlock">Force updating <seealso cref="IBlockFinder.Head"/> block regardless of <see cref="Block.TotalDifficulty"/></param>
void UpdateMainChain(IReadOnlyList<Block> blocks, bool wereProcessed, bool forceHeadBlock = false);
void MarkChainAsProcessed(IReadOnlyList<Block> blocks);
bool CanAcceptNewBlocks { get; }
Task Accept(IBlockTreeVisitor blockTreeVisitor, CancellationToken cancellationToken);
(BlockInfo? Info, ChainLevelInfo? Level) GetInfo(long number, Hash256 blockHash);
ChainLevelInfo? FindLevel(long number);
BlockInfo FindCanonicalBlockInfo(long blockNumber);
Hash256 FindHash(long blockNumber);
IOwnedReadOnlyList<BlockHeader> FindHeaders(Hash256 hash, int numberOfBlocks, int skip, bool reverse);
void DeleteInvalidBlock(Block invalidBlock);
void ForkChoiceUpdated(Hash256? finalizedBlockHash, Hash256? safeBlockBlockHash);
event EventHandler<BlockEventArgs> NewBestSuggestedBlock;
event EventHandler<BlockEventArgs> NewSuggestedBlock;
/// <summary>
/// A block is marked as canon
/// </summary>
event EventHandler<BlockReplacementEventArgs> BlockAddedToMain;
/// <summary>
/// A block is now set as head
/// </summary>
event EventHandler<BlockEventArgs> NewHeadBlock;
/// <summary>
/// A branch is now set as canon. This is different from `BlockAddedToMain` as it is fired only once for the
/// the whole branch.
/// </summary>
event EventHandler<OnUpdateMainChainArgs> OnUpdateMainChain;
event EventHandler<ForkChoice> OnForkChoiceUpdated;
int DeleteChainSlice(in long startNumber, long? endNumber = null, bool force = false);
bool IsBetterThanHead(BlockHeader? header);
void UpdateBeaconMainChain(BlockInfo[]? blockInfos, long clearBeaconMainChainStartPoint);
void RecalculateTreeLevels();
/// <summary>
/// Sync pivot is mainly concerned with old blocks and receipts.
/// After sync pivot, blocks and headers should be continuous.
/// Sync pivot should be guaranteed to be a finalized block, code should not need to be concerned of consensus
/// for blocks before sync pivot.
/// Before sync pivot, there is no guarantee that blocks and receipts are available or continuous.
/// </summary>
(long BlockNumber, Hash256 BlockHash) SyncPivot { get; set; }
public readonly struct ForkChoice(Block? head, long safe, long finalized)
{
public readonly Block? Head => head;
public readonly long Safe => safe;
public readonly long Finalized => finalized;
}
}
}