Skip to content

Commit

Permalink
Merge branch 'master' into 1.7.x
Browse files Browse the repository at this point in the history
  • Loading branch information
Bushstar authored Apr 22, 2021
2 parents 001c378 + e85a9b5 commit 9e56c69
Show file tree
Hide file tree
Showing 21 changed files with 626 additions and 41 deletions.
32 changes: 32 additions & 0 deletions src/httprpc.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -65,6 +65,8 @@ class HTTPRPCTimerInterface : public RPCTimerInterface
static std::string strRPCUserColonPass;
/* Stored RPC timer interface (for unregistration) */
static std::unique_ptr<HTTPRPCTimerInterface> httpRPCTimerInterface;
/* The host to be used for CORS header */
static std::string corsOriginHost;

static void JSONErrorReply(HTTPRequest* req, const UniValue& objError, const UniValue& id)
{
Expand Down Expand Up @@ -144,8 +146,35 @@ static bool RPCAuthorized(const std::string& strAuth, std::string& strAuthUserna
return multiUserAuthorized(strUserPass);
}

static bool CorsHandler(HTTPRequest *req) {
auto host = corsOriginHost;
// If if it's empty assume cors is disallowed. Do nothing and proceed,
// with request as usual.
if (host.empty())
return false;

req->WriteHeader("Access-Control-Allow-Origin", host);
req->WriteHeader("Access-Control-Allow-Credentials", "true");
req->WriteHeader("Access-Control-Allow-Methods", "POST, GET, OPTIONS");
req->WriteHeader("Access-Control-Allow-Headers", "Content-Type, Authorization");

// If it's a Cors preflight request, short-circuit and return. We have
// set what's needed already.
if (req->GetRequestMethod() == HTTPRequest::OPTIONS) {
req->WriteReply(HTTP_NO_CONTENT);
return true;
}

// Indicate to continue with the request as usual
return false;
}

static bool HTTPReq_JSONRPC(HTTPRequest* req, const std::string &)
{
// Handle CORS
if (CorsHandler(req))
return true;

// JSONRPC handles only POST
if (req->GetRequestMethod() != HTTPRequest::POST) {
req->WriteReply(HTTP_BAD_METHOD, "JSONRPC server handles only POST requests");
Expand Down Expand Up @@ -239,6 +268,9 @@ bool StartHTTPRPC()
if (!InitRPCAuthentication())
return false;

// Setup Cors origin host name from arg.
corsOriginHost = gArgs.GetArg("-rpcallowcors", "");

RegisterHTTPHandler("/", true, HTTPReq_JSONRPC);
if (g_wallet_init_interface.HasWalletSupport()) {
RegisterHTTPHandler("/wallet/", false, HTTPReq_JSONRPC);
Expand Down
11 changes: 11 additions & 0 deletions src/httpserver.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -205,6 +205,9 @@ static std::string RequestMethodString(HTTPRequest::RequestMethod m)
case HTTPRequest::PUT:
return "PUT";
break;
case HTTPRequest::OPTIONS:
return "OPTIONS";
break;
default:
return "unknown";
}
Expand Down Expand Up @@ -386,9 +389,14 @@ bool InitHTTPServer()
return false;
}

// Defaults + OPTIONS
auto allowed_methods = EVHTTP_REQ_GET | EVHTTP_REQ_HEAD | EVHTTP_REQ_POST;
allowed_methods |= EVHTTP_REQ_PUT | EVHTTP_REQ_DELETE | EVHTTP_REQ_OPTIONS;

evhttp_set_timeout(http, gArgs.GetArg("-rpcservertimeout", DEFAULT_HTTP_SERVER_TIMEOUT));
evhttp_set_max_headers_size(http, MAX_HEADERS_SIZE);
evhttp_set_max_body_size(http, MAX_DESER_SIZE);
evhttp_set_allowed_methods(http, allowed_methods);
evhttp_set_gencb(http, http_request_cb, nullptr);

if (!HTTPBindAddresses(http)) {
Expand Down Expand Up @@ -632,6 +640,9 @@ HTTPRequest::RequestMethod HTTPRequest::GetRequestMethod() const
case EVHTTP_REQ_PUT:
return PUT;
break;
case EVHTTP_REQ_OPTIONS:
return OPTIONS;
break;
default:
return UNKNOWN;
break;
Expand Down
3 changes: 2 additions & 1 deletion src/httpserver.h
Original file line number Diff line number Diff line change
Expand Up @@ -69,7 +69,8 @@ class HTTPRequest
GET,
POST,
HEAD,
PUT
PUT,
OPTIONS,
};

/** Get requested URI.
Expand Down
11 changes: 7 additions & 4 deletions src/init.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -387,6 +387,8 @@ void SetupServerArgs()
gArgs.AddArg("-blocksdir=<dir>", "Specify directory to hold blocks subdirectory for *.dat files (default: <datadir>)", ArgsManager::ALLOW_ANY, OptionsCategory::OPTIONS);
#if HAVE_SYSTEM
gArgs.AddArg("-blocknotify=<cmd>", "Execute command when the best block changes (%s in cmd is replaced by block hash)", ArgsManager::ALLOW_ANY, OptionsCategory::OPTIONS);
gArgs.AddArg("-spvblocknotify=<cmd>", "Execute command when the last Bitcoin block changes (%s in cmd is replaced by block hash)", ArgsManager::ALLOW_ANY, OptionsCategory::OPTIONS);
gArgs.AddArg("-spvwalletnotify=<cmd>", "Execute command when an SPV Bitcoin wallet transaction changes (%s in cmd is replaced by TxID)", ArgsManager::ALLOW_ANY, OptionsCategory::WALLET);
#endif
gArgs.AddArg("-blockreconstructionextratxn=<n>", strprintf("Extra transactions to keep in memory for compact block reconstructions (default: %u)", DEFAULT_BLOCK_RECONSTRUCTION_EXTRA_TXN), ArgsManager::ALLOW_ANY, OptionsCategory::OPTIONS);
gArgs.AddArg("-blocksonly", strprintf("Whether to reject transactions from network peers. Transactions from the wallet, RPC and relay whitelisted inbound peers are not affected. (default: %u)", DEFAULT_BLOCKSONLY), ArgsManager::ALLOW_ANY, OptionsCategory::OPTIONS);
Expand Down Expand Up @@ -458,7 +460,7 @@ void SetupServerArgs()
gArgs.AddArg("-dummypos", "Flag to skip PoS-related checks (regtest only)", ArgsManager::ALLOW_ANY, OptionsCategory::CHAINPARAMS);
gArgs.AddArg("-txnotokens", "Flag to force old tx serialization (regtest only)", ArgsManager::ALLOW_ANY, OptionsCategory::CHAINPARAMS);
gArgs.AddArg("-anchorquorum", "Min quorum size (regtest only)", ArgsManager::ALLOW_ANY, OptionsCategory::CHAINPARAMS);
gArgs.AddArg("-spv", "Enable SPV to bitcoin blockchain (default: 0, unless masternode)", ArgsManager::ALLOW_ANY, OptionsCategory::OPTIONS);
gArgs.AddArg("-spv", "Enable SPV to bitcoin blockchain (default: 1)", ArgsManager::ALLOW_ANY, OptionsCategory::OPTIONS);
gArgs.AddArg("-criminals", "punishment of criminal nodes (default: 0, regtest only)", ArgsManager::ALLOW_ANY, OptionsCategory::OPTIONS);
gArgs.AddArg("-spv_resync", "Flag to reset spv database and resync from zero block (default: 0)", ArgsManager::ALLOW_ANY, OptionsCategory::OPTIONS);
gArgs.AddArg("-spv_rescan", "Block height to rescan from (default: 0 = off)", ArgsManager::ALLOW_INT, OptionsCategory::OPTIONS);
Expand Down Expand Up @@ -581,6 +583,7 @@ void SetupServerArgs()
gArgs.AddArg("-rpcuser=<user>", "Username for JSON-RPC connections", ArgsManager::ALLOW_ANY, OptionsCategory::RPC);
gArgs.AddArg("-rpcworkqueue=<n>", strprintf("Set the depth of the work queue to service RPC calls (default: %d)", DEFAULT_HTTP_WORKQUEUE), ArgsManager::ALLOW_ANY | ArgsManager::DEBUG_ONLY, OptionsCategory::RPC);
gArgs.AddArg("-server", "Accept command line and JSON-RPC commands", ArgsManager::ALLOW_ANY, OptionsCategory::RPC);
gArgs.AddArg("-rpcallowcors=<host>", "Allow CORS requests from the given host origin. Include scheme and port (eg: -rpcallowcors=http://127.0.0.1:5000)", ArgsManager::ALLOW_ANY, OptionsCategory::RPC);

#if HAVE_DECL_DAEMON
gArgs.AddArg("-daemon", "Run in the background as a daemon and accept commands", ArgsManager::ALLOW_ANY, OptionsCategory::OPTIONS);
Expand Down Expand Up @@ -1748,16 +1751,16 @@ bool AppInitMain(InitInterfaces& interfaces)
panchorAwaitingConfirms = MakeUnique<CAnchorAwaitingConfirms>();
panchors.reset();

// If users set masternode_operator set SPV default to enabled
bool anchorsEnabled{!gArgs.GetArgs("-masternode_operator").empty()};
// Enable the anchors and spv by default
bool anchorsEnabled = true;
panchors = MakeUnique<CAnchorIndex>(nDefaultDbCache << 20, false, gArgs.GetBoolArg("-spv", anchorsEnabled) && gArgs.GetBoolArg("-spv_resync", false) /*fReset || fReindexChainState*/);

// load anchors after spv due to spv (and spv height) not set before (no last height yet)
if (gArgs.GetBoolArg("-spv", anchorsEnabled)) {
spv::pspv.reset();
if (Params().NetworkIDString() == "regtest") {
spv::pspv = MakeUnique<spv::CFakeSpvWrapper>();
} else if (Params().NetworkIDString() == "test") {
} else if (Params().NetworkIDString() == "test" || Params().NetworkIDString() == "devnet") {
spv::pspv = MakeUnique<spv::CSpvWrapper>(false, nMinDbCache << 20, false, gArgs.GetBoolArg("-spv_resync", false));
} else {
spv::pspv = MakeUnique<spv::CSpvWrapper>(true, nMinDbCache << 20, false, gArgs.GetBoolArg("-spv_resync", false));
Expand Down
9 changes: 9 additions & 0 deletions src/masternodes/anchors.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -789,6 +789,15 @@ bool CAnchorIndex::DbErase(uint256 const & hash)
return db->Erase(std::make_pair(DB_ANCHORS, hash));
}

const CAnchorIndex::AnchorRec* CAnchorIndex::GetLatestAnchorUpToDeFiHeight(THeight blockHeightDeFi) const
{
AssertLockHeld(cs_main);

auto & index = anchors.get<AnchorRec::ByDeFiHeight>();
auto it = index.lower_bound(blockHeightDeFi);
return (it != index.begin()) ? &(*(--it)) : nullptr;
}

/// Validates all except tx confirmations
bool ValidateAnchor(const CAnchor & anchor)
{
Expand Down
8 changes: 7 additions & 1 deletion src/masternodes/anchors.h
Original file line number Diff line number Diff line change
Expand Up @@ -212,12 +212,16 @@ class CAnchorIndex
// tags for multiindex
struct ByBtcTxHash{};
struct ByBtcHeight{};
struct ByDeFiHeight{};

THeight DeFiBlockHeight() const {return anchor.height;}
};

typedef boost::multi_index_container<AnchorRec,
indexed_by<
ordered_unique < tag<AnchorRec::ByBtcTxHash>, member<AnchorRec, uint256, &AnchorRec::txHash> >,
ordered_non_unique< tag<AnchorRec::ByBtcHeight>, member<AnchorRec, THeight, &AnchorRec::btcHeight> >
ordered_non_unique< tag<AnchorRec::ByBtcHeight>, member<AnchorRec, THeight, &AnchorRec::btcHeight> >,
ordered_non_unique< tag<AnchorRec::ByDeFiHeight>, const_mem_fun<AnchorRec, THeight, &AnchorRec::DeFiBlockHeight> >
>
> AnchorIndexImpl;

Expand Down Expand Up @@ -260,6 +264,8 @@ class CAnchorIndex
bool WriteBlock(const uint32_t height, const uint256& blockHash);
uint256 ReadBlockHash(const uint32_t& height);

AnchorRec const * GetLatestAnchorUpToDeFiHeight(THeight blockHeightDeFi) const;

private:
AnchorIndexImpl anchors;
AnchorRec const * top = nullptr;
Expand Down
4 changes: 2 additions & 2 deletions src/masternodes/masternodes.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -643,7 +643,7 @@ void CCustomCSView::CalcAnchoringTeams(const uint256 & stakeModifier, const CBlo
CKeyID minter;
if (pindex->GetBlockHeader().ExtractMinterKey(minter)) {
LOCK(cs_main);
auto id = pcustomcsview->GetMasternodeIdByOperator(minter);
auto id = GetMasternodeIdByOperator(minter);
if (id) {
masternodeIDs.insert(*id);
}
Expand Down Expand Up @@ -688,7 +688,7 @@ void CCustomCSView::CalcAnchoringTeams(const uint256 & stakeModifier, const CBlo

{
LOCK(cs_main);
pcustomcsview->SetAnchorTeams(authTeam, confirmTeam, pindexNew->height);
SetAnchorTeams(authTeam, confirmTeam, pindexNew->height);
}

// Debug logging
Expand Down
2 changes: 1 addition & 1 deletion src/masternodes/mn_checks.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1344,7 +1344,7 @@ ResVal<uint256> ApplyAnchorRewardTxPlus(CCustomCSView & mnview, CTransaction con
return Res::ErrDbg("bad-ar-sigs", "anchor signatures are incorrect");
}

auto team = pcustomcsview->GetConfirmTeam(height - 1);
auto team = mnview.GetConfirmTeam(height - 1);
if (!team) {
return Res::ErrDbg("bad-ar-team", "could not get confirm team for height: %d", height - 1);
}
Expand Down
1 change: 1 addition & 0 deletions src/rpc/client.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -227,6 +227,7 @@ static const CRPCConvertParam vRPCConvertParams[] =
{ "spv_listanchors", 3, "maxConfs" },
{ "spv_sendtoaddress", 1, "amount" },
{ "spv_sendtoaddress", 2, "feerate" },
{ "spv_listreceivedbyaddress", 0, "minconf" },

{ "createpoolpair", 0, "metadata" },
{ "createpoolpair", 1, "inputs" },
Expand Down
1 change: 1 addition & 0 deletions src/rpc/protocol.h
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
enum HTTPStatusCode
{
HTTP_OK = 200,
HTTP_NO_CONTENT = 204,
HTTP_BAD_REQUEST = 400,
HTTP_UNAUTHORIZED = 401,
HTTP_FORBIDDEN = 403,
Expand Down
14 changes: 13 additions & 1 deletion src/spv/bitcoin/BRPeerManager.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -202,6 +202,7 @@ struct BRPeerManagerStruct {
void (*syncStopped)(void *info, int error);
void (*txStatusUpdate)(void *info);
void (*saveBlocks)(void *info, int replace, BRMerkleBlock *blocks[], size_t blocksCount);
void (*blockNotify)(void *info, const UInt256& blockHash);
void (*savePeers)(void *info, int replace, const BRPeer peers[], size_t peersCount);
int (*networkIsReachable)(void *info);
void (*threadCleanup)(void *info);
Expand Down Expand Up @@ -1226,7 +1227,7 @@ static void _peerRelayedBlock(void *info, BRMerkleBlock *block)
txTime = block->timestamp/2 + prev->timestamp/2;
block->height = prev->height + 1;
}

// track the observed bloom filter false positive rate using a low pass filter to smooth out variance
if (peer == manager->downloadPeer && block->totalTx > 0) {
for (i = 0; i < txCount; i++) { // wallet tx are not false-positives
Expand All @@ -1253,6 +1254,8 @@ static void _peerRelayedBlock(void *info, BRMerkleBlock *block)
}
}

const auto lastBlockHash = manager->lastBlock->blockHash;

// ignore block headers that are newer than one week before earliestKeyTime (it's a header if it has 0 totalTx)
if (block->totalTx == 0 && block->timestamp + 7*24*60*60 > manager->earliestKeyTime + 2*60*60) {
BRMerkleBlockFree(block);
Expand Down Expand Up @@ -1403,6 +1406,12 @@ static void _peerRelayedBlock(void *info, BRMerkleBlock *block)
}
}
}

// Has last block changed?
if (!UInt256Eq(lastBlockHash, manager->lastBlock->blockHash))
{
manager->blockNotify(manager->info, manager->lastBlock->blockHash);
}

if (txHashes != _txHashes) free(txHashes);

Expand Down Expand Up @@ -1607,6 +1616,7 @@ BRPeerManager *BRPeerManagerNew(const BRChainParams *params, BRWallet *wallet, u
// void syncStopped(void *, int) - called when blockchain syncing stops, error is an errno.h code
// void txStatusUpdate(void *) - called when transaction status may have changed such as when a new block arrives
// void saveBlocks(void *, int, BRMerkleBlock *[], size_t) - called when blocks should be saved to the persistent store
// void blockNotify(void *info, const UInt256& blockHash) - Called when chain tip changes
// - if replace is true, remove any previously saved blocks first
// void savePeers(void *, int, const BRPeer[], size_t) - called when peers should be saved to the persistent store
// - if replace is true, remove any previously saved peers first
Expand All @@ -1617,6 +1627,7 @@ void BRPeerManagerSetCallbacks(BRPeerManager *manager, void *info,
void (*syncStopped)(void *info, int error),
void (*txStatusUpdate)(void *info),
void (*saveBlocks)(void *info, int replace, BRMerkleBlock *blocks[], size_t blocksCount),
void (*blockNotify)(void *info, const UInt256& blockHash),
void (*savePeers)(void *info, int replace, const BRPeer peers[], size_t peersCount),
int (*networkIsReachable)(void *info),
void (*threadCleanup)(void *info))
Expand All @@ -1627,6 +1638,7 @@ void BRPeerManagerSetCallbacks(BRPeerManager *manager, void *info,
manager->syncStopped = syncStopped;
manager->txStatusUpdate = txStatusUpdate;
manager->saveBlocks = saveBlocks;
manager->blockNotify = blockNotify;
manager->savePeers = savePeers;
manager->networkIsReachable = networkIsReachable;
manager->threadCleanup = (threadCleanup) ? threadCleanup : _dummyThreadCleanup;
Expand Down
2 changes: 2 additions & 0 deletions src/spv/bitcoin/BRPeerManager.h
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,7 @@ BRPeerManager *BRPeerManagerNew(const BRChainParams *params, BRWallet *wallet, u
// void syncStopped(void *, int) - called when blockchain syncing stops, error is an errno.h code
// void txStatusUpdate(void *) - called when transaction status may have changed such as when a new block arrives
// void saveBlocks(void *, int, BRMerkleBlock *[], size_t) - called when blocks should be saved to the persistent store
// void blockNotify(void *info, const UInt256& blockHash) - Called when chain tip changes
// - if replace is true, remove any previously saved blocks first
// void savePeers(void *, int, const BRPeer[], size_t) - called when peers should be saved to the persistent store
// - if replace is true, remove any previously saved peers first
Expand All @@ -61,6 +62,7 @@ void BRPeerManagerSetCallbacks(BRPeerManager *manager, void *info,
void (*syncStopped)(void *info, int error),
void (*txStatusUpdate)(void *info),
void (*saveBlocks)(void *info, int replace, BRMerkleBlock *blocks[], size_t blocksCount),
void (*blockNotify)(void *info, const UInt256& blockHash),
void (*savePeers)(void *info, int replace, const BRPeer peers[], size_t peersCount),
int (*networkIsReachable)(void *info),
void (*threadCleanup)(void *info));
Expand Down
Loading

0 comments on commit 9e56c69

Please sign in to comment.