public void nonconsecutive_non_producing_preProcess_loads_pending_validators_from_receipts(int lastLevelFinalized, int initialValidatorsIndex, int?expectedBlockValidators) { IEnumerable <Block> GetAllBlocks(BlockTree bt) { var block = bt.FindBlock(bt.Head.Hash, BlockTreeLookupOptions.None); while (block != null) { yield return(block); block = bt.FindBlock(block.ParentHash, BlockTreeLookupOptions.None); } } var validators = TestItem.Addresses[initialValidatorsIndex * 10]; var inMemoryReceiptStorage = new InMemoryReceiptStorage(); var blockTreeBuilder = Build.A.BlockTree().WithTransactions(inMemoryReceiptStorage, RopstenSpecProvider.Instance, delegate(Block block, Transaction transaction) { byte i = 0; return(new[] { Build.A.LogEntry.WithAddress(_contractAddress) .WithData(new[] { (byte)(block.Number * 10 + i++) }) .WithTopics(ValidatorContract.Definition.initiateChangeEventHash, block.ParentHash) .TestObject }); }) .OfChainLength(9, 0, 0, validators); var blockTree = blockTreeBuilder.TestObject; SetupInitialValidators(blockTree.Head, validators); IAuRaValidatorProcessor validator = new ContractValidator(_validator, _db, _stateProvider, _abiEncoder, _transactionProcessor, blockTree, inMemoryReceiptStorage, _logManager, 1); validator.SetFinalizationManager(_blockFinalizationManager); _abiEncoder.Decode(ValidatorContract.Definition.addressArrayResult, Arg.Any <byte[]>()) .Returns(c => { var addressIndex = c.Arg <byte[]>()[0]; return(new object[] { new Address[] { TestItem.Addresses[addressIndex] } }); }); _blockFinalizationManager.GetLastLevelFinalizedBy(blockTree.Head.ParentHash).Returns(lastLevelFinalized); validator.PreProcess(blockTree.FindBlock(blockTree.Head.Hash, BlockTreeLookupOptions.None)); byte[] expectedPendingValidatorsBytes = Rlp.OfEmptySequence.Bytes; if (expectedBlockValidators.HasValue) { var block = GetAllBlocks(blockTree).First(b => b.Number == expectedBlockValidators.Value); var pendingValidators = new ContractValidator.PendingValidators(block.Number, block.Hash, new [] { TestItem.Addresses[block.Number * 10] }); expectedPendingValidatorsBytes = Rlp.Encode(pendingValidators).Bytes; } _db.Received()[ContractValidator.PendingValidatorsKey.Bytes] = Arg.Is <byte[]>(r => r.SequenceEqual(expectedPendingValidatorsBytes)); }
public void consecutive_initiate_change_gets_finalized_and_switch_validators(ConsecutiveInitiateChangeTestParameters test) { var currentValidators = GenerateValidators(1); SetupInitialValidators(currentValidators); IAuRaValidatorProcessor validator = new ContractValidator(_validator, new MemDb(), _stateProvider, _abiEncoder, _transactionProcessor, _blockTree, _receiptsStorage, _logManager, test.StartBlockNumber); validator.SetFinalizationManager(_blockFinalizationManager); test.TryDoReorganisations(test.StartBlockNumber, out _); for (int i = 0; i < test.Current.NumberOfSteps; i++) { var blockNumber = test.Current.BlockNumber + i; if (test.TryDoReorganisations(blockNumber, out var lastChain)) { ValidateFinalizationForChain(lastChain); i = 0; blockNumber = test.Current.BlockNumber + i; } _block.Number = blockNumber; _block.Beneficiary = currentValidators[blockNumber % currentValidators.Length]; _block.Header.AuRaStep = blockNumber; _block.Hash = Keccak.Compute(blockNumber.ToString()); var txReceipts = test.GetReceipts(_block, _contractAddress, _abiEncoder, SetupAbiAddresses); _block.Bloom = new Bloom(txReceipts.SelectMany(r => r.Logs).ToArray()); Action preProcess = () => validator.PreProcess(_block); preProcess.Should().NotThrow <InvalidOperationException>(test.TestName); validator.PostProcess(_block, txReceipts); var finalizedNumber = blockNumber - validator.MinSealersForFinalization + 1; _blockFinalizationManager.BlocksFinalized += Raise.EventWith( new FinalizeEventArgs(_block.Header, Build.A.BlockHeader.WithNumber(finalizedNumber) .WithHash(Keccak.Compute(finalizedNumber.ToString())).TestObject)); currentValidators = test.GetCurrentValidators(blockNumber); var nextValidators = test.GetNextValidators(blockNumber); currentValidators.Select((a, index) => validator.IsValidSealer(a, index)).Should().AllBeEquivalentTo(true, $"Validator address is not recognized in block {blockNumber}"); nextValidators?.Except(currentValidators).Select((a, index) => validator.IsValidSealer(a, index)).Should().AllBeEquivalentTo(false); } ValidateFinalizationForChain(test.Current); }
public void initializes_pendingValidators_from_db() { var blockNumber = 10; var validators = TestItem.Addresses.Take(10).ToArray(); var blockHash = Keccak.Compute("Test"); var pendingValidators = new ContractValidator.PendingValidators(blockNumber, blockHash, validators); var rlp = Rlp.Encode(pendingValidators); _db[ContractValidator.PendingValidatorsKey.Bytes].Returns(rlp.Bytes); IAuRaValidatorProcessor validator = new ContractValidator(_validator, _db, _stateProvider, _abiEncoder, _transactionProcessor, _blockTree, _receiptsStorage, _logManager, 1); validator.SetFinalizationManager(_blockFinalizationManager); _blockFinalizationManager.BlocksFinalized += Raise.EventWith(new FinalizeEventArgs(_block.Header, Build.A.BlockHeader.WithNumber(blockNumber).WithHash(blockHash).TestObject)); validators.Select((v, i) => validator.IsValidSealer(v, i)).Should().AllBeEquivalentTo(true); }