Skip to content

Commit

Permalink
Potentially better handling of reorgs
Browse files Browse the repository at this point in the history
  • Loading branch information
jmederosalvarado committed Oct 26, 2022
1 parent 35f5574 commit 60dee2a
Show file tree
Hide file tree
Showing 2 changed files with 22 additions and 20 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -514,13 +514,22 @@ public void consecutive_initiate_change_gets_finalized_and_switch_validators(Con
_block.Header.Beneficiary = currentValidators[blockNumber % currentValidators.Length];
_block.Header.AuRaStep = blockNumber;
_block.Header.Hash = Keccak.Compute((blockNumber + hashSeeds[blockNumber]).ToString());
_block.Header.ParentHash = blockNumber == test.StartBlockNumber ? Keccak.Zero : Keccak.Compute((blockNumber - 1 + hashSeeds[blockNumber - 1]).ToString());

TxReceipt[] txReceipts = test.GetReceipts(_validatorContract, _block, _contractAddress, _abiEncoder, SetupAbiAddresses);

Keccak? blockHashForClosure = _block.Hash;
_receiptsStorage.Get(Arg.Is<Block>(b => b.Hash == blockHashForClosure)).Returns(txReceipts);

_block.Header.Bloom = new Bloom(txReceipts.SelectMany(r => r.Logs).ToArray());

_blockTree.FindBlock(_block.Header.Hash, Arg.Any<BlockTreeLookupOptions>()).Returns(new Block(_block.Header.Clone(), BlockBody.Empty));

Action preProcess = () => validator.OnBlockProcessingStart(_block);
preProcess.Should().NotThrow<InvalidOperationException>(test.TestName);
validator.OnBlockProcessingEnd(_block, txReceipts);
int finalizedNumber = blockNumber - validator.Validators.MinSealersForFinalization() + 1;
_blockFinalizationManager.GetLastLevelFinalizedBy(_block.Header.Hash).Returns(finalizedNumber);
_blockFinalizationManager.BlocksFinalized += Raise.EventWith(
new FinalizeEventArgs(_block.Header, Build.A.BlockHeader.WithNumber(finalizedNumber)
.WithHash(Keccak.Compute((finalizedNumber + hashSeeds[finalizedNumber]).ToString())).TestObject));
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,8 @@ public partial class ContractBasedValidator : AuRaValidatorBase, IDisposable
private readonly ILogger _logger;

private PendingValidators _currentPendingValidators;
private long _lastProcessedBlockNumber = 0;
private long? _lastProcessedBlockNumber = null;
private Keccak? _lastProcessedBlockHash = null;
private IAuRaBlockFinalizationManager _blockFinalizationManager;
internal IBlockTree BlockTree { get; }
private readonly IReceiptFinder _receiptFinder;
Expand Down Expand Up @@ -94,13 +95,12 @@ public override void OnBlockProcessingStart(Block block, ProcessingOptions optio
bool isInitBlock = InitBlockNumber == block.Number;
bool isProducingBlock = options.ContainsFlag(ProcessingOptions.ProducingBlock);
bool isMainChainProcessing = !ForSealing && !isProducingBlock;
// TODO: check this and everywhere it is used
bool isConsecutiveBlock = block.Number - 1 <= _lastProcessedBlockNumber && _lastProcessedBlockNumber != 0;
bool isInProcessedRange = _lastProcessedBlockNumber is not null && block.Number - 1 <= _lastProcessedBlockNumber;

if (Validators == null || !isConsecutiveBlock || isProducingBlock)
if (Validators == null || !isInProcessedRange || isProducingBlock)
{
var parentHeader = BlockTree.FindParentHeader(block.Header, BlockTreeLookupOptions.None);
Validators = isInitBlock || !isConsecutiveBlock ? LoadValidatorsFromContract(parentHeader) : ValidatorStore.GetValidators(block.Number);
Validators = isInitBlock || !isInProcessedRange ? LoadValidatorsFromContract(parentHeader) : ValidatorStore.GetValidators(block.Number);

if (isMainChainProcessing)
{
Expand All @@ -118,20 +118,12 @@ public override void OnBlockProcessingStart(Block block, ProcessingOptions optio
}
else
{
if (!isConsecutiveBlock)// either reorg or blocks skipped (like fast sync)
if (isMainChainProcessing && !isInProcessedRange)
{
if (isMainChainProcessing)
bool loadedValidatorsAreSameInStore = (ValidatorStore.GetValidators()?.SequenceEqual(Validators) == true);
if (!loadedValidatorsAreSameInStore)
{
bool loadedValidatorsAreSameInStore = (ValidatorStore.GetValidators()?.SequenceEqual(Validators) == true);
if (!loadedValidatorsAreSameInStore)
{
ValidatorStore.SetValidators(_blockFinalizationManager.GetLastLevelFinalizedBy(block.ParentHash), Validators);
}
}

if (!isProducingBlock)
{
_currentPendingValidators = ValidatorStore.PendingValidators = TryGetInitChangeFromPastBlocks(block.ParentHash);
ValidatorStore.SetValidators(_blockFinalizationManager.GetLastLevelFinalizedBy(block.ParentHash), Validators);
}
}

Expand All @@ -141,17 +133,18 @@ public override void OnBlockProcessingStart(Block block, ProcessingOptions optio
// We need to initialize pending validators from db on each block being produced.
_currentPendingValidators = ValidatorStore.PendingValidators;
}
else if (_lastProcessedBlockHash is null || block.ParentHash != _lastProcessedBlockHash) // either reorg or blocks skipped (like fast sync)
_currentPendingValidators = ValidatorStore.PendingValidators = TryGetInitChangeFromPastBlocks(block.ParentHash);
}


base.OnBlockProcessingStart(block, options);

FinalizePendingValidatorsIfNeeded(block.Header, isProducingBlock);

_lastProcessedBlockNumber = block.Number;
(_lastProcessedBlockNumber, _lastProcessedBlockHash) = (block.Number, block.Hash);
}

// FIXME
private PendingValidators TryGetInitChangeFromPastBlocks(Keccak blockHash)
{
PendingValidators pendingValidators = null;
Expand All @@ -165,7 +158,7 @@ private PendingValidators TryGetInitChangeFromPastBlocks(Keccak blockHash)
{
if (Validators.SequenceEqual(potentialValidators))
{
break;
break; // TODO: why this?
}

pendingValidators = new PendingValidators(block.Number, block.Hash, potentialValidators);
Expand Down

0 comments on commit 60dee2a

Please sign in to comment.