Skip to content

Commit

Permalink
Merge pull request #1726 from cyrossignol/beacon-fixes
Browse files Browse the repository at this point in the history
Skip beacon advertisement when already pending
  • Loading branch information
jamescowens committed Jun 11, 2020
2 parents 679663d + 26fd7c3 commit 6e1961f
Show file tree
Hide file tree
Showing 5 changed files with 58 additions and 6 deletions.
15 changes: 14 additions & 1 deletion src/neuralnet/beacon.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@ uint256 HashBeaconPayload(const BeaconPayload& payload)
//! \return \c true if the supplied beacon contract matches an active beacon.
//! This updates the matched beacon with a new timestamp.
//!
bool TryRenewal(BeaconRegistry::BeaconMap beacons, const BeaconPayload& payload)
bool TryRenewal(BeaconRegistry::BeaconMap& beacons, const BeaconPayload& payload)
{
auto beacon_pair_iter = beacons.find(payload.m_cpid);

Expand Down Expand Up @@ -276,6 +276,19 @@ bool BeaconRegistry::ContainsActive(const Cpid& cpid) const
return ContainsActive(cpid, GetAdjustedTime());
}

std::vector<CKeyID> BeaconRegistry::FindPendingKeys(const Cpid& cpid) const
{
std::vector<CKeyID> found;

for (const auto& beacon_pair : m_pending) {
if (beacon_pair.second.m_cpid == cpid) {
found.emplace_back(beacon_pair.first);
}
}

return found;
}

void BeaconRegistry::Add(Contract contract)
{
BeaconPayload payload = contract.CopyPayloadAs<BeaconPayload>();
Expand Down
14 changes: 14 additions & 0 deletions src/neuralnet/beacon.h
Original file line number Diff line number Diff line change
Expand Up @@ -433,6 +433,20 @@ class BeaconRegistry : public IContractHandler
//!
bool ContainsActive(const Cpid& cpid) const;

//!
//! \brief Look up the key IDs of pending beacons for the specified CPID.
//!
//! The wallet matches key IDs returned by this method to determine whether
//! it contains private keys for pending beacons so that it can skip beacon
//! advertisement if it submitted one recently.
//!
//! \param cpid CPID of the beacons to find results for.
//!
//! \return The set of RIPEMD-160 hashes of the keys for the beacons that
//! match the supplied CPID.
//!
std::vector<CKeyID> FindPendingKeys(const Cpid& cpid) const;

//!
//! \brief Determine whether a beacon contract is valid.
//!
Expand Down
29 changes: 27 additions & 2 deletions src/neuralnet/researcher.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -323,6 +323,25 @@ bool CheckBeaconPrivateKey(const CWallet* const wallet, const CPubKey& public_ke
return true;
}

//!
//! \brief Determine whether the wallet contains a key for a pending beacon.
//!
//! \param beacons Fetches pending beacon keys IDs.
//! \param cpid CPID to look up pending beacons for.
//!
//! \return \c true if the a pending beacon exists for the supplied CPID.
//!
bool DetectPendingBeacon(const BeaconRegistry& beacons, const Cpid cpid)
{
for (const auto& key_id : beacons.FindPendingKeys(cpid)) {
if (pwalletMain->HaveKey(key_id)) {
return true;
}
}

return false;
}

//!
//! \brief Generate a new beacon key pair.
//!
Expand Down Expand Up @@ -883,14 +902,20 @@ AdvertiseBeaconResult Researcher::AdvertiseBeacon()
//
if (last_advertised_height >= (nBestHeight - 5)) {
LogPrintf("ERROR: %s: Beacon awaiting confirmation already", __func__);
return BeaconError::TOO_SOON;
return BeaconError::PENDING;
}

const BeaconOption current_beacon = GetBeaconRegistry().Try(*cpid);
const BeaconRegistry& beacons = GetBeaconRegistry();
const BeaconOption current_beacon = beacons.Try(*cpid);

AdvertiseBeaconResult result(BeaconError::NONE);

if (!current_beacon) {
if (DetectPendingBeacon(beacons, *cpid)) {
LogPrintf("%s: Beacon awaiting verification already", __func__);
return BeaconError::PENDING;
}

result = SendNewBeacon(*cpid);
} else {
result = RenewBeacon(*cpid, *current_beacon);
Expand Down
2 changes: 1 addition & 1 deletion src/neuralnet/researcher.h
Original file line number Diff line number Diff line change
Expand Up @@ -199,7 +199,7 @@ enum class BeaconError
MISSING_KEY, //!< Beacon private key missing or invalid.
NO_CPID, //!< No valid CPID detected (investor mode).
NOT_NEEDED, //!< Beacon exists for the CPID. No renewal needed.
TOO_SOON, //!< Not enough time elapsed for pending advertisement.
PENDING, //!< Not enough time elapsed for pending advertisement.
TX_FAILED, //!< Beacon contract transacton failed to send.
WALLET_LOCKED, //!< Wallet not fully unlocked.
};
Expand Down
4 changes: 2 additions & 2 deletions src/rpcblockchain.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -660,7 +660,7 @@ UniValue advertisebeacon(const UniValue& params, bool fHelp)
throw JSONRPCError(
RPC_INVALID_REQUEST,
"An active beacon already exists for this CPID");
case NN::BeaconError::TOO_SOON:
case NN::BeaconError::PENDING:
throw JSONRPCError(
RPC_INVALID_REQUEST,
"A beacon advertisement is already pending for this CPID");
Expand Down Expand Up @@ -729,7 +729,7 @@ UniValue revokebeacon(const UniValue& params, bool fHelp)
throw JSONRPCError(RPC_INVALID_REQUEST, "No active beacon for CPID");
case NN::BeaconError::NOT_NEEDED:
throw JSONRPCError(RPC_INTERNAL_ERROR, "Unexpected error occurred");
case NN::BeaconError::TOO_SOON:
case NN::BeaconError::PENDING:
throw JSONRPCError(RPC_INTERNAL_ERROR, "Unexpected error occurred");
case NN::BeaconError::TX_FAILED:
throw JSONRPCError(
Expand Down

0 comments on commit 6e1961f

Please sign in to comment.