ManifestDisposition ManifestCache::applyManifest (Manifest m) { std::lock_guard<std::mutex> applyLock{apply_mutex_}; /* before we spend time checking the signature, make sure the sequence number is newer than any we have. */ auto const iter = map_.find(m.masterKey); if (iter != map_.end() && m.sequence <= iter->second.sequence) { /* A manifest was received for a validator we're tracking, but its sequence number is not higher than the one already stored. This will happen normally when a peer without the latest gossip connects. */ if (auto stream = j_.debug()) logMftAct(stream, "Stale", m.masterKey, m.sequence, iter->second.sequence); return ManifestDisposition::stale; // not a newer manifest, ignore } if (! m.verify()) { /* A manifest's signature is invalid. This shouldn't happen normally. */ if (auto stream = j_.warn()) logMftAct(stream, "Invalid", m.masterKey, m.sequence); return ManifestDisposition::invalid; } std::lock_guard<std::mutex> readLock{read_mutex_}; bool const revoked = m.revoked(); if (iter == map_.end ()) { /* This is the first received manifest for a trusted master key (possibly our own). This only happens once per validator per run. */ if (auto stream = j_.info()) logMftAct(stream, "AcceptedNew", m.masterKey, m.sequence); if (! revoked) signingToMasterKeys_[m.signingKey] = m.masterKey; map_.emplace (std::make_pair(m.masterKey, std::move (m))); } else { /* An ephemeral key was revoked and superseded by a new key. This is expected, but should happen infrequently. */ if (auto stream = j_.info()) logMftAct(stream, "AcceptedUpdate", m.masterKey, m.sequence, iter->second.sequence); signingToMasterKeys_.erase (iter->second.signingKey); if (! revoked) signingToMasterKeys_[m.signingKey] = m.masterKey; iter->second = std::move (m); } if (revoked) { /* A validator master key has been compromised, so its manifests are now untrustworthy. In order to prevent us from accepting a forged manifest signed by the compromised master key, store this manifest, which has the highest possible sequence number and therefore can't be superseded by a forged one. */ if (auto stream = j_.warn()) logMftAct(stream, "Revoked", m.masterKey, m.sequence); } return ManifestDisposition::accepted; }