mirror of
https://github.com/ElementsProject/elements.git
synced 2026-08-16 13:01:19 +02:00
Use RPC calls to check bitcoin blocks are valid and confirmed
This commit is contained in:
parent
6dc16a139c
commit
eca4077baa
7 changed files with 62 additions and 5 deletions
|
|
@ -10,7 +10,7 @@ using namespace json_spirit;
|
|||
|
||||
#define _(x) std::string(x) /* Keep the _() around in case gettext or such will be used later to translate non-UI */
|
||||
|
||||
Object CallRPC(const string& strMethod, const Array& params)
|
||||
Object CallRPC(const string& strMethod, const Array& params, string port)
|
||||
{
|
||||
if (mapArgs["-rpcuser"] == "" && mapArgs["-rpcpassword"] == "")
|
||||
throw runtime_error(strprintf(
|
||||
|
|
@ -27,7 +27,9 @@ Object CallRPC(const string& strMethod, const Array& params)
|
|||
SSLIOStreamDevice<asio::ip::tcp> d(sslStream, fUseSSL);
|
||||
iostreams::stream< SSLIOStreamDevice<asio::ip::tcp> > stream(d);
|
||||
|
||||
const bool fConnected = d.connect(GetArg("-rpcconnect", "127.0.0.1"), GetArg("-rpcport", itostr(BaseParams().RPCPort())));
|
||||
if (port == "")
|
||||
port = GetArg("-rpcport", itostr(BaseParams().RPCPort()));
|
||||
const bool fConnected = d.connect(GetArg("-rpcconnect", "127.0.0.1"), port);
|
||||
if (!fConnected)
|
||||
throw CConnectionFailed("couldn't connect to server");
|
||||
|
||||
|
|
@ -67,3 +69,26 @@ Object CallRPC(const string& strMethod, const Array& params)
|
|||
|
||||
return reply;
|
||||
}
|
||||
|
||||
bool IsConfirmedBitcoinBlock(const uint256& hash, int nMinConfirmationDepth)
|
||||
{
|
||||
try {
|
||||
Array params;
|
||||
params.push_back(hash.GetHex());
|
||||
Object reply = CallRPC("getblock", params, GetArg("-rpcconnectport", "18332"));
|
||||
if (find_value(reply, "error").type() != null_type)
|
||||
return false;
|
||||
Value result = find_value(reply, "result");
|
||||
if (result.type() != obj_type)
|
||||
return false;
|
||||
result = find_value(result.get_obj(), "confirmations");
|
||||
return result.type() == int_type && result.get_int64() >= nMinConfirmationDepth;
|
||||
} catch (CConnectionFailed& e) {
|
||||
LogPrintf("ERROR: Lost connection to bitcoind RPC, you will want to restart after fixing this!\n");
|
||||
return false;
|
||||
} catch (...) {
|
||||
LogPrintf("ERROR: Failure connecting to bitcoind RPC, you will want to restart after fixing this!\n");
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -8,6 +8,7 @@
|
|||
|
||||
#include "rpcclient.h"
|
||||
#include "rpcprotocol.h"
|
||||
#include "uint256.h"
|
||||
|
||||
#include <string>
|
||||
|
||||
|
|
@ -25,6 +26,7 @@ public:
|
|||
|
||||
};
|
||||
|
||||
json_spirit::Object CallRPC(const std::string& strMethod, const json_spirit::Array& params);
|
||||
json_spirit::Object CallRPC(const std::string& strMethod, const json_spirit::Array& params, std::string port="");
|
||||
bool IsConfirmedBitcoinBlock(const uint256& hash, int nMinConfirmationDepth);
|
||||
|
||||
#endif // BITCOIN_CALLRPC_H
|
||||
|
|
|
|||
|
|
@ -8,6 +8,9 @@
|
|||
#include <secp256k1.h>
|
||||
|
||||
#define FEDERATED_PEG_SIDECHAIN_ONLY
|
||||
#ifdef FEDERATED_PEG_SIDECHAIN_ONLY
|
||||
#include "callrpc.h"
|
||||
#endif
|
||||
|
||||
#include "primitives/transaction.h"
|
||||
#include "crypto/ripemd160.h"
|
||||
|
|
@ -23,6 +26,7 @@
|
|||
#include "streams.h"
|
||||
#include "uint256.h"
|
||||
#include "utilstrencodings.h"
|
||||
#include "util.h"
|
||||
|
||||
using namespace std;
|
||||
|
||||
|
|
@ -1285,7 +1289,8 @@ bool EvalScript(vector<vector<unsigned char> >& stack, const CScript& script, un
|
|||
return set_error(serror, SCRIPT_ERR_WITHDRAW_VERIFY_SECONDSCRIPT);
|
||||
|
||||
#ifdef FEDERATED_PEG_SIDECHAIN_ONLY
|
||||
//TODO: Check that we're spending from a valid, buried bitcoin block
|
||||
if (!GetBoolArg("-blindtrust", true) && !checker.IsConfirmedBitcoinBlock(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
|
||||
|
|
@ -1712,6 +1717,13 @@ CAmount TransactionSignatureChecker::GetValueInPrevIn() const
|
|||
return nInMinusOneValue;
|
||||
}
|
||||
|
||||
#ifdef FEDERATED_PEG_SIDECHAIN_ONLY
|
||||
bool TransactionSignatureChecker::IsConfirmedBitcoinBlock(const uint256& hash, bool fConservativeConfirmationRequirements) const
|
||||
{
|
||||
return ::IsConfirmedBitcoinBlock(hash, fConservativeConfirmationRequirements ? 10 : 8);
|
||||
}
|
||||
#endif
|
||||
|
||||
bool VerifyScript(const CScript& scriptSig, const CScript& scriptPubKey, unsigned int flags, const BaseSignatureChecker& checker, ScriptError* serror)
|
||||
{
|
||||
set_error(serror, SCRIPT_ERR_UNKNOWN_ERROR);
|
||||
|
|
|
|||
|
|
@ -82,6 +82,9 @@ enum
|
|||
|
||||
// Execute sidechain-related opcodes instead of treating them as NOPs
|
||||
SCRIPT_VERIFY_WITHDRAW = (1U << 11),
|
||||
|
||||
// Dirty hack to require a higher bar of bitcoin block confirmation in mempool
|
||||
SCRIPT_VERIFY_INCREASE_CONFIRMATIONS_REQUIRED = (1U << 12)
|
||||
};
|
||||
|
||||
uint256 SignatureHash(const CScript &scriptCode, const CTransaction& txTo, unsigned int nIn, int nHashType);
|
||||
|
|
@ -117,6 +120,14 @@ public:
|
|||
return -1;
|
||||
}
|
||||
|
||||
#define FEDERATED_PEG_SIDECHAIN_ONLY
|
||||
#ifdef FEDERATED_PEG_SIDECHAIN_ONLY
|
||||
virtual bool IsConfirmedBitcoinBlock(const uint256& hash, bool fConservativeConfirmationRequirements) const
|
||||
{
|
||||
return false;
|
||||
}
|
||||
#endif
|
||||
|
||||
virtual ~BaseSignatureChecker() {}
|
||||
};
|
||||
|
||||
|
|
@ -157,6 +168,9 @@ public:
|
|||
CAmount GetValueIn() const;
|
||||
CAmount GetValueInPrevIn() const;
|
||||
CAmount GetTransactionFee() const;
|
||||
#ifdef FEDERATED_PEG_SIDECHAIN_ONLY
|
||||
bool IsConfirmedBitcoinBlock(const uint256& hash, bool fConservativeConfirmationRequirements) const;
|
||||
#endif
|
||||
};
|
||||
|
||||
bool EvalScript(std::vector<std::vector<unsigned char> >& stack, const CScript& script, unsigned int flags, const BaseSignatureChecker& checker, ScriptError* error = NULL);
|
||||
|
|
|
|||
|
|
@ -79,6 +79,8 @@ const char* ScriptErrorString(const ScriptError serror)
|
|||
return "Withdraw proof validation failed - locktime was not set correctly";
|
||||
case SCRIPT_ERR_WITHDRAW_VERIFY_SECONDSCRIPT:
|
||||
return "Withdraw proof validation failed - second script validation failed";
|
||||
case SCRIPT_ERR_WITHDRAW_VERIFY_BLOCKCONFIRMED:
|
||||
return "Withdraw proof validation failed - lock block was not sufficiently confirmed on sending chain";
|
||||
case SCRIPT_ERR_REORG_VERIFY_FORMAT:
|
||||
return "Reorg/Fraud proof validation failed - invalid proof format";
|
||||
case SCRIPT_ERR_REORG_VERIFY_FRAUD_BLOCK:
|
||||
|
|
|
|||
|
|
@ -58,6 +58,7 @@ typedef enum ScriptError_t
|
|||
SCRIPT_ERR_WITHDRAW_VERIFY_OUTPUT,
|
||||
SCRIPT_ERR_WITHDRAW_VERIFY_LOCKTIME,
|
||||
SCRIPT_ERR_WITHDRAW_VERIFY_SECONDSCRIPT,
|
||||
SCRIPT_ERR_WITHDRAW_VERIFY_BLOCKCONFIRMED,
|
||||
SCRIPT_ERR_REORG_VERIFY_FORMAT,
|
||||
SCRIPT_ERR_REORG_VERIFY_FRAUD_BLOCK,
|
||||
SCRIPT_ERR_REORG_VERIFY_FRAUD_ORIG_BLOCK,
|
||||
|
|
|
|||
|
|
@ -51,7 +51,8 @@ static const unsigned int STANDARD_SCRIPT_VERIFY_FLAGS = MANDATORY_SCRIPT_VERIFY
|
|||
SCRIPT_VERIFY_NULLDUMMY |
|
||||
SCRIPT_VERIFY_DISCOURAGE_UPGRADABLE_NOPS |
|
||||
SCRIPT_VERIFY_CHECKLOCKTIMEVERIFY |
|
||||
SCRIPT_VERIFY_CHECKSEQUENCEVERIFY;
|
||||
SCRIPT_VERIFY_CHECKSEQUENCEVERIFY |
|
||||
SCRIPT_VERIFY_INCREASE_CONFIRMATIONS_REQUIRED;
|
||||
|
||||
/** For convenience, standard but not mandatory verify flags. */
|
||||
static const unsigned int STANDARD_NOT_MANDATORY_VERIFY_FLAGS = STANDARD_SCRIPT_VERIFY_FLAGS & ~MANDATORY_SCRIPT_VERIFY_FLAGS;
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue