Use RPC calls to check bitcoin blocks are valid and confirmed

This commit is contained in:
Matt Corallo 2014-12-06 14:38:47 -08:00 committed by Gregory Sanders
parent 7c9a06de5a
commit c94ee2b4e0
12 changed files with 122 additions and 13 deletions

View file

@ -20,6 +20,11 @@
#include "streams.h"
#include "uint256.h"
#include "utilstrencodings.h"
#include "util.h"
#ifndef BITCOIN_SCRIPT_NO_CALLRPC
#include "callrpc.h"
#endif
using namespace std;
@ -1211,7 +1216,10 @@ bool EvalScript(vector<vector<unsigned char> >& stack, const CScript& script, un
if (withdrawOutput.scriptPubKey != expectedWithdrawScriptPubKey)
return set_error(serror, SCRIPT_ERR_WITHDRAW_VERIFY_OUTPUT);
//TODO: Check that we're spending from a valid, buried bitcoin block
#ifndef BITCOIN_SCRIPT_NO_CALLRPC
if (!GetBoolArg("-blindtrust", true) && !checker.IsConfirmedBitcoinBlock(genesishash, merkleBlock.header.GetHash(), flags & SCRIPT_VERIFY_INCREASE_CONFIRMATIONS_REQUIRED))
return set_error(serror, SCRIPT_ERR_WITHDRAW_VERIFY_BLOCKCONFIRMED);
#endif
} catch (std::exception& e) {
// Probably invalid encoding of something which was deserialized
return set_error(serror, SCRIPT_ERR_WITHDRAW_VERIFY_FORMAT);
@ -1582,6 +1590,15 @@ CAmount TransactionSignatureChecker::GetValueInPrevIn() const
return amountPreviousInput;
}
bool TransactionSignatureChecker::IsConfirmedBitcoinBlock(const uint256& genesishash, const uint256& hash, bool fConservativeConfirmationRequirements) const
{
#ifndef BITCOIN_SCRIPT_NO_CALLRPC
return ::IsConfirmedBitcoinBlock(genesishash, hash, fConservativeConfirmationRequirements ? 10 : 8);
#else
return true;
#endif
}
static bool VerifyWitnessProgram(const CScriptWitness& witness, int witversion, const std::vector<unsigned char>& program, unsigned int flags, const BaseSignatureChecker& checker, ScriptError* serror)
{
vector<vector<unsigned char> > stack;

View file

@ -111,6 +111,10 @@ enum
// Execute sidechain-related opcodes instead of treating them as NOPs
//
SCRIPT_VERIFY_WITHDRAW = (1U << 16),
// Dirty hack to require a higher bar of bitcoin block confirmation in mempool
//
SCRIPT_VERIFY_INCREASE_CONFIRMATIONS_REQUIRED = (1U << 17)
};
bool CheckSignatureEncoding(const std::vector<unsigned char> &vchSig, unsigned int flags, ScriptError* serror);
@ -161,6 +165,11 @@ public:
return -1;
}
virtual bool IsConfirmedBitcoinBlock(const uint256& genesishash, const uint256& hash, bool fConservativeConfirmationRequirements) const
{
return false;
}
virtual ~BaseSignatureChecker() {}
};
@ -203,6 +212,7 @@ public:
COutPoint GetPrevOut() const;
CAmount GetValueIn() const;
CAmount GetValueInPrevIn() const;
bool IsConfirmedBitcoinBlock(const uint256& genesishash, const uint256& hash, bool fConservativeConfirmationRequirements) const;
};
bool EvalScript(std::vector<std::vector<unsigned char> >& stack, const CScript& script, unsigned int flags, const BaseSignatureChecker& checker, SigVersion sigversion, ScriptError* error = NULL);

View file

@ -95,6 +95,8 @@ const char* ScriptErrorString(const ScriptError serror)
return "Withdraw proof validation failed - locking transaction misformatted";
case SCRIPT_ERR_WITHDRAW_VERIFY_OUTPUT:
return "Withdraw proof validation failed - output does not match expected";
case SCRIPT_ERR_WITHDRAW_VERIFY_BLOCKCONFIRMED:
return "Withdraw proof validation failed - lock block was not sufficiently confirmed on sending chain";
case SCRIPT_ERR_UNKNOWN_ERROR:
case SCRIPT_ERR_ERROR_COUNT:
default: break;

View file

@ -69,6 +69,7 @@ typedef enum ScriptError_t
SCRIPT_ERR_WITHDRAW_VERIFY_BLOCK,
SCRIPT_ERR_WITHDRAW_VERIFY_LOCKTX,
SCRIPT_ERR_WITHDRAW_VERIFY_OUTPUT,
SCRIPT_ERR_WITHDRAW_VERIFY_BLOCKCONFIRMED,
SCRIPT_ERR_ERROR_COUNT
} ScriptError;