Merge pull request #5106

1bea2bb Rename ProcessBlock to ProcessNewBlock to indicate change of behaviour, and document it (Luke Dashjr)
d29a291 Rename RPC_TRANSACTION_* errors to RPC_VERIFY_* and use RPC_VERIFY_ERROR for submitblock (Luke Dashjr)
f877aaa Bugfix: submitblock: Use a temporary CValidationState to determine accurately the outcome of ProcessBlock, now that it no longer does the full block validity check (Luke Dashjr)
24e8896 Add CValidationInterface::BlockChecked notification (Luke Dashjr)
This commit is contained in:
Wladimir J. van der Laan
2014-11-03 12:16:12 +01:00
6 changed files with 71 additions and 18 deletions

View File

@@ -152,6 +152,8 @@ struct CMainSignals {
boost::signals2::signal<void (const uint256 &)> Inventory;
// Tells listeners to broadcast their data.
boost::signals2::signal<void ()> Broadcast;
// Notifies listeners of a block validation result
boost::signals2::signal<void (const CBlock&, const CValidationState&)> BlockChecked;
} g_signals;
} // anon namespace
@@ -163,9 +165,11 @@ void RegisterValidationInterface(CValidationInterface* pwalletIn) {
g_signals.SetBestChain.connect(boost::bind(&CValidationInterface::SetBestChain, pwalletIn, _1));
g_signals.Inventory.connect(boost::bind(&CValidationInterface::Inventory, pwalletIn, _1));
g_signals.Broadcast.connect(boost::bind(&CValidationInterface::ResendWalletTransactions, pwalletIn));
g_signals.BlockChecked.connect(boost::bind(&CValidationInterface::BlockChecked, pwalletIn, _1, _2));
}
void UnregisterValidationInterface(CValidationInterface* pwalletIn) {
g_signals.BlockChecked.disconnect(boost::bind(&CValidationInterface::BlockChecked, pwalletIn, _1, _2));
g_signals.Broadcast.disconnect(boost::bind(&CValidationInterface::ResendWalletTransactions, pwalletIn));
g_signals.Inventory.disconnect(boost::bind(&CValidationInterface::Inventory, pwalletIn, _1));
g_signals.SetBestChain.disconnect(boost::bind(&CValidationInterface::SetBestChain, pwalletIn, _1));
@@ -175,6 +179,7 @@ void UnregisterValidationInterface(CValidationInterface* pwalletIn) {
}
void UnregisterAllValidationInterfaces() {
g_signals.BlockChecked.disconnect_all_slots();
g_signals.Broadcast.disconnect_all_slots();
g_signals.Inventory.disconnect_all_slots();
g_signals.SetBestChain.disconnect_all_slots();
@@ -1864,7 +1869,9 @@ bool static ConnectTip(CValidationState &state, CBlockIndex *pindexNew, CBlock *
{
CCoinsViewCache view(pcoinsTip);
CInv inv(MSG_BLOCK, pindexNew->GetBlockHash());
if (!ConnectBlock(*pblock, state, pindexNew, view)) {
bool rv = ConnectBlock(*pblock, state, pindexNew, view);
g_signals.BlockChecked(*pblock, state);
if (!rv) {
if (state.IsInvalid())
InvalidBlockFound(pindexNew, state);
return error("ConnectTip() : ConnectBlock %s failed", pindexNew->GetBlockHash().ToString());
@@ -2504,7 +2511,7 @@ void CBlockIndex::BuildSkip()
pskip = pprev->GetAncestor(GetSkipHeight(nHeight));
}
bool ProcessBlock(CValidationState &state, CNode* pfrom, CBlock* pblock, CDiskBlockPos *dbp)
bool ProcessNewBlock(CValidationState &state, CNode* pfrom, CBlock* pblock, CDiskBlockPos *dbp)
{
// Preliminary checks
bool checked = CheckBlock(*pblock, state);
@@ -2513,7 +2520,7 @@ bool ProcessBlock(CValidationState &state, CNode* pfrom, CBlock* pblock, CDiskBl
LOCK(cs_main);
MarkBlockAsReceived(pblock->GetHash());
if (!checked) {
return error("ProcessBlock() : CheckBlock FAILED");
return error("%s : CheckBlock FAILED", __func__);
}
// Store to disk
@@ -2523,11 +2530,11 @@ bool ProcessBlock(CValidationState &state, CNode* pfrom, CBlock* pblock, CDiskBl
mapBlockSource[pindex->GetBlockHash()] = pfrom->GetId();
}
if (!ret)
return error("ProcessBlock() : AcceptBlock FAILED");
return error("%s : AcceptBlock FAILED", __func__);
}
if (!ActivateBestChain(state, pblock))
return error("ProcessBlock() : ActivateBestChain failed");
return error("%s : ActivateBestChain failed", __func__);
return true;
}
@@ -3136,7 +3143,7 @@ bool LoadExternalBlockFile(FILE* fileIn, CDiskBlockPos *dbp)
// process in case the block isn't known yet
if (mapBlockIndex.count(hash) == 0) {
CValidationState state;
if (ProcessBlock(state, NULL, &block, dbp))
if (ProcessNewBlock(state, NULL, &block, dbp))
nLoaded++;
if (state.IsError())
break;
@@ -3156,7 +3163,7 @@ bool LoadExternalBlockFile(FILE* fileIn, CDiskBlockPos *dbp)
LogPrintf("%s: Processing out of order child %s of %s\n", __func__, block.GetHash().ToString(),
head.ToString());
CValidationState dummy;
if (ProcessBlock(dummy, NULL, &block, &it->second))
if (ProcessNewBlock(dummy, NULL, &block, &it->second))
{
nLoaded++;
queue.push_back(block.GetHash());
@@ -3934,7 +3941,7 @@ bool static ProcessMessage(CNode* pfrom, string strCommand, CDataStream& vRecv,
pfrom->AddInventoryKnown(inv);
CValidationState state;
ProcessBlock(state, pfrom, &block);
ProcessNewBlock(state, pfrom, &block);
int nDoS;
if (state.IsInvalid(nDoS)) {
pfrom->PushMessage("reject", strCommand, state.GetRejectCode(),