diff --git a/ledger/apply/heartbeat.go b/ledger/apply/heartbeat.go index 1c8a55f4b9..bce788cf68 100644 --- a/ledger/apply/heartbeat.go +++ b/ledger/apply/heartbeat.go @@ -28,10 +28,13 @@ import ( func Heartbeat(hb transactions.HeartbeatTxnFields, header transactions.Header, balances Balances, provider HdrProvider, round basics.Round) error { // Get the account's balance entry account, err := balances.Get(hb.HeartbeatAddress, false) + if err != nil { + return err + } sv := account.VoteID if sv.IsEmpty() { - return fmt.Errorf("HeartbeatAddress %s has has no voting keys\n", hb.HeartbeatAddress) + return fmt.Errorf("heartbeat address %s has no voting keys\n", hb.HeartbeatAddress) } id := basics.OneTimeIDForRound(header.LastValid, account.VoteKeyDilution) diff --git a/ledger/apply/mockBalances_test.go b/ledger/apply/mockBalances_test.go index dd77b66e7f..91f918cf80 100644 --- a/ledger/apply/mockBalances_test.go +++ b/ledger/apply/mockBalances_test.go @@ -291,5 +291,5 @@ func (m mockHeaders) BlockHdr(r basics.Round) (bookkeeping.BlockHeader, error) { if hdr, ok := m.b[r]; ok { return hdr, nil } - return bookkeeping.BlockHeader{}, fmt.Errorf("Round %v is not present\n", r) + return bookkeeping.BlockHeader{}, fmt.Errorf("round %v is not present\n", r) } diff --git a/ledger/eval/eval.go b/ledger/eval/eval.go index 419a960692..0014bc0044 100644 --- a/ledger/eval/eval.go +++ b/ledger/eval/eval.go @@ -1712,6 +1712,9 @@ type headerSource interface { BlockHdr(round basics.Round) (bookkeeping.BlockHeader, error) } +// ActiveChallenge returns details about the Challenge that was last issued if +// it is still in effect (that is, between one and two grace periods from +// issue). Otherwise it returns the zero value. func ActiveChallenge(rules config.ProposerPayoutRules, current basics.Round, headers headerSource) challenge { // are challenges active? interval := basics.Round(rules.ChallengeInterval) @@ -1736,6 +1739,8 @@ func ActiveChallenge(rules config.ProposerPayoutRules, current basics.Round, hea return challenge{lastChallenge, challengeHdr.Seed, rules.ChallengeBits} } +// FailsChallenge returns true iff ch is in effect, matches address, and +// lastSeen is before the challenge issue. func FailsChallenge(ch challenge, address basics.Address, lastSeen basics.Round) bool { return ch.round != 0 && bitsMatch(ch.seed[:], address[:], ch.bits) && lastSeen < ch.round }