### Question:
IbftCommitSealsValidationRule implements AttachedBlockHeaderValidationRule { @Override public boolean validate( final BlockHeader header, final BlockHeader parent, final ProtocolContext protocolContext) { final ValidatorProvider validatorProvider = protocolContext .getConsensusState(IbftContext.class) .getVoteTallyCache() .getVoteTallyAfterBlock(parent); final IbftExtraData ibftExtraData = IbftExtraData.decode(header); final List<Address> committers = IbftBlockHashing.recoverCommitterAddresses(header, ibftExtraData); final List<Address> committersWithoutDuplicates = new ArrayList<>(new HashSet<>(committers)); if (committers.size() != committersWithoutDuplicates.size()) { LOGGER.trace("Duplicated seals found in header."); return false; } return validateCommitters(committersWithoutDuplicates, validatorProvider.getValidators()); }  @Override boolean validate(
      final BlockHeader header, final BlockHeader parent, final ProtocolContext protocolContext); @Override boolean includeInLightValidation();  }### Answer:
@Test public void correctlyConstructedHeaderPassesValidation() { final List<NodeKey> committerNodeKeys = IntStream.range(0, 2).mapToObj(i -> NodeKeyUtils.generate()).collect(Collectors.toList()); final List<Address> committerAddresses = committerNodeKeys.stream() .map(nodeKey -> Util.publicKeyToAddress(nodeKey.getPublicKey())) .sorted() .collect(Collectors.toList()); final ProtocolContext context = new ProtocolContext(null, null, setupContextWithValidators(committerAddresses)); BlockHeader header = createProposedBlockHeader(committerAddresses, committerNodeKeys, false); assertThat(commitSealsValidationRule.validate(header, null, context)).isTrue(); }
@Test public void insufficientCommitSealsFailsValidation() { final NodeKey committerNodeKey = NodeKeyUtils.generate(); final Address committerAddress = Address.extract(Hash.hash(committerNodeKey.getPublicKey().getEncodedBytes())); final List<Address> validators = singletonList(committerAddress); final ProtocolContext context = new ProtocolContext(null, null, setupContextWithValidators(validators)); final BlockHeader header = createProposedBlockHeader(validators, emptyList(), false); final IbftExtraData headerExtraData = IbftExtraData.decode(header); assertThat(headerExtraData.getSeals().size()).isEqualTo(0); assertThat(commitSealsValidationRule.validate(header, null, context)).isFalse(); }
@Test public void committerNotInValidatorListFailsValidation() { final NodeKey committerNodeKey = NodeKeyUtils.generate(); final Address committerAddress = Util.publicKeyToAddress(committerNodeKey.getPublicKey()); final List<Address> validators = singletonList(committerAddress); final NodeKey nonValidatorNodeKey = NodeKeyUtils.generate(); final BlockHeader header = createProposedBlockHeader(validators, singletonList(nonValidatorNodeKey), false); final ProtocolContext context = new ProtocolContext(null, null, setupContextWithValidators(validators)); assertThat(commitSealsValidationRule.validate(header, null, context)).isFalse(); }
@Test public void headerContainsDuplicateSealsFailsValidation() { final NodeKey committerNodeKey = NodeKeyUtils.generate(); final List<Address> validators = singletonList(Util.publicKeyToAddress(committerNodeKey.getPublicKey())); final BlockHeader header = createProposedBlockHeader( validators, Lists.newArrayList(committerNodeKey, committerNodeKey), false); final ProtocolContext context = new ProtocolContext(null, null, setupContextWithValidators(validators)); assertThat(commitSealsValidationRule.validate(header, null, context)).isFalse(); }