예제 #1
0
        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);
        }
예제 #2
0
        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);
        }