Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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