public bool CanSignBlock(UInt256 blockNumber, Keccak parentHash) { Snapshot snapshot = GetOrCreateSnapshot(blockNumber - 1, parentHash); if (!snapshot.Signers.ContainsKey(_key.Address)) { if (_logger.IsTrace) { _logger.Trace("Not on the signers list"); } return(false); } // If we're amongst the recent signers, wait for the next block if (snapshot.HasSignedRecently(blockNumber, _key.Address)) { if (_logger.IsTrace) { _logger.Trace("Signed recently"); } return(false); } return(true); }
public bool ValidateSeal(BlockHeader header) { UInt256 number = header.Number; // Retrieve the snapshot needed to validate this header and cache it Snapshot snapshot = GetOrCreateSnapshot(number - 1, header.ParentHash); // Resolve the authorization key and check against signers header.Author = header.Author ?? GetBlockSealer(header); Address signer = header.Author; if (!snapshot.Signers.ContainsKey(signer)) { if (_logger.IsWarn) { _logger.Warn($"Invalid block signer {signer} - not authorized to sign a block"); } return(false); } if (snapshot.HasSignedRecently(number, signer)) { if (_logger.IsWarn) { _logger.Warn($"Invalid block signer {signer} - the signer is among recents"); } return(false); } // Ensure that the difficulty corresponds to the turn-ness of the signer bool inTurn = snapshot.InTurn(header.Number, signer); if (inTurn && header.Difficulty != Clique.DifficultyInTurn) { if (_logger.IsWarn) { _logger.Warn($"Invalid block difficulty {header.Difficulty} - should be in-turn {Clique.DifficultyInTurn}"); } return(false); } if (!inTurn && header.Difficulty != Clique.DifficultyNoTurn) { if (_logger.IsWarn) { _logger.Warn($"Invalid block difficulty {header.Difficulty} - should be no-turn {Clique.DifficultyNoTurn}"); } return(false); } return(true); }