added helper method for timelock, enabled signing of timelock #320
3 changed files with 82 additions and 1 deletions
|
@ -80,6 +80,7 @@ static const CRPCConvertParam vRPCConvertParams[] =
|
|||
{ "scantxoutset", 1, "scanobjects" },
|
||||
{ "addmultisigaddress", 0, "nrequired" },
|
||||
{ "addmultisigaddress", 1, "keys" },
|
||||
{ "addtimelockedaddress", 0, "timelock" },
|
||||
{ "createmultisig", 0, "nrequired" },
|
||||
{ "createmultisig", 1, "keys" },
|
||||
{ "listunspent", 0, "minconf" },
|
||||
|
|
|
@ -87,6 +87,21 @@ static bool CreateSig(const BaseSignatureCreator& creator, SignatureData& sigdat
|
|||
return false;
|
||||
}
|
||||
|
||||
static CScript StripTimelockPrefix(const CScript& script) {
|
||||
auto it = script.begin();
|
||||
opcodetype op;
|
||||
if (!script.GetOp(it, op))
|
||||
return script;
|
||||
|
||||
if (!script.GetOp(it, op) || (op != OP_CHECKLOCKTIMEVERIFY && op != OP_CHECKSEQUENCEVERIFY))
|
||||
CSV is enabled. getblockchaininfo shows that it is active. CSV is enabled. getblockchaininfo shows that it is active.
You're right i made assumption by bit value https://github.com/lbryio/lbrycrd/blob/master/src/chainparams.cpp#L159 You're right i made assumption by bit value https://github.com/lbryio/lbrycrd/blob/master/src/chainparams.cpp#L159
|
||||
return script;
|
||||
|
||||
if (!script.GetOp(it, op) || op != OP_DROP)
|
||||
return script;
|
||||
|
||||
return CScript(it, script.end());
|
||||
}
|
||||
|
||||
/**
|
||||
* Sign scriptPubKey using signature made with creator.
|
||||
* Signatures are returned in scriptSigRet (or returns false if scriptPubKey can't be signed),
|
||||
|
@ -102,7 +117,9 @@ static bool SignStep(const SigningProvider& provider, const BaseSignatureCreator
|
|||
std::vector<unsigned char> sig;
|
||||
|
||||
std::vector<valtype> vSolutions;
|
||||
if (!Solver(StripClaimScriptPrefix(scriptPubKey), whichTypeRet, vSolutions))
|
||||
auto stripped = StripClaimScriptPrefix(scriptPubKey);
|
||||
stripped = StripTimelockPrefix(stripped);
|
||||
if (!Solver(stripped, whichTypeRet, vSolutions))
|
||||
return false;
|
||||
|
||||
switch (whichTypeRet)
|
||||
|
|
|
@ -1914,6 +1914,68 @@ static UniValue addmultisigaddress(const JSONRPCRequest& request)
|
|||
return result;
|
||||
}
|
||||
|
||||
static UniValue addtimelockedaddress(const JSONRPCRequest& request)
|
||||
{
|
||||
std::shared_ptr<CWallet> const wallet = GetWalletForJSONRPCRequest(request);
|
||||
CWallet* const pwallet = wallet.get();
|
||||
|
||||
if (!EnsureWalletIsAvailable(pwallet, request.fHelp)) {
|
||||
return NullUniValue;
|
||||
}
|
||||
|
||||
if (request.fHelp || request.params.size() < 2 || request.params.size() > 4) {
|
||||
std::string msg = "addtimelockedaddress timelock address ( \"label\" \"address_type\" )\n"
|
||||
"\nAdd an address that can't be redeemed until timelock. Requires a new wallet backup.\n"
|
||||
"See `importaddress` for watchonly p2sh address support.\n"
|
||||
"If 'label' is specified, assign address to that label.\n"
|
||||
|
||||
"\nArguments:\n"
|
||||
"1. timelock (numeric, required) Block height if < 500 million or unix timestamp if greater.\n"
|
||||
"1. \"address\" (string, required) The destination wallet address.\n"
|
||||
"2. \"label\" (string, optional) A label to assign the addresses to.\n"
|
||||
"3. \"address_type\" (string, optional) The address type to use. Options are \"legacy\", \"p2sh-segwit\", and \"bech32\". Default is set by -addresstype.\n"
|
||||
|
||||
"\nResult:\n"
|
||||
"{\n"
|
||||
" \"address\":\"address\", (string) The value of the new P2SH address.\n"
|
||||
" \"redeemScript\":\"script\" (string) The string value of the hex-encoded redemption script.\n"
|
||||
"}\n"
|
||||
;
|
||||
throw std::runtime_error(msg);
|
||||
}
|
||||
|
||||
auto timelock = request.params[0].get_int();
|
||||
std::string label;
|
||||
if (!request.params[2].isNull())
|
||||
label = LabelFromValue(request.params[2]);
|
||||
|
||||
LOCK2(cs_main, pwallet->cs_wallet);
|
||||
|
||||
auto address = request.params[1].get_str();
|
||||
CTxDestination destination = DecodeDestination(address);
|
||||
if (!IsValidDestination(destination)) {
|
||||
throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, std::string("Invalid LBRY address: ") + address);
|
||||
}
|
||||
auto destinationScript = GetScriptForDestination(destination);
|
||||
|
||||
OutputType output_type = pwallet->m_default_address_type;
|
||||
if (!request.params[3].isNull()) {
|
||||
if (!ParseOutputType(request.params[3].get_str(), output_type)) {
|
||||
throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, strprintf("Unknown address type '%s'", request.params[3].get_str()));
|
||||
}
|
||||
}
|
||||
|
||||
// Construct using pay-to-script-hash:
|
||||
CScript inner = (CScript() << CScriptNum(timelock) << OP_CHECKLOCKTIMEVERIFY << OP_DROP) + destinationScript;
|
||||
CTxDestination dest = AddAndGetDestinationForScript(*pwallet, inner, output_type);
|
||||
pwallet->SetAddressBook(dest, label, "timelock");
|
||||
|
||||
UniValue result(UniValue::VOBJ);
|
||||
result.pushKV("address", EncodeDestination(dest));
|
||||
result.pushKV("redeemScript", HexStr(inner.begin(), inner.end()));
|
||||
return result;
|
||||
}
|
||||
|
||||
class Witnessifier : public boost::static_visitor<bool>
|
||||
{
|
||||
public:
|
||||
|
@ -5305,6 +5367,7 @@ static const CRPCCommand commands[] =
|
|||
{ "wallet", "abandontransaction", &abandontransaction, {"txid"} },
|
||||
{ "wallet", "abortrescan", &abortrescan, {} },
|
||||
{ "wallet", "addmultisigaddress", &addmultisigaddress, {"nrequired","keys","label|account","address_type"} },
|
||||
{ "wallet", "addtimelockedaddress", &addtimelockedaddress, {"timelock", "address", "label|account","address_type"} },
|
||||
{ "hidden", "addwitnessaddress", &addwitnessaddress, {"address","p2sh"} },
|
||||
{ "wallet", "backupwallet", &backupwallet, {"destination"} },
|
||||
{ "wallet", "bumpfee", &bumpfee, {"txid", "options"} },
|
||||
|
|
Loading…
Reference in a new issue
Can we expect OP_CHECKSEQUENCEVERIFY since BIP112 is not enabled? I mean it should be filtered by interpreter and it shouldn't go here, no?