Merge d052f5e6b7 into merged_master (Bitcoin PR #16841)

This commit is contained in:
Andrew Poelstra 2020-11-27 21:29:55 +00:00
commit 3ca887d480
12 changed files with 46 additions and 128 deletions

View file

@ -337,8 +337,8 @@ static void MutateTxAddOutPubKey(CMutableTransaction& tx, const std::string& str
if (!pubkey.IsCompressed()) {
throw std::runtime_error("Uncompressed pubkeys are not useable for SegWit outputs");
}
// Call GetScriptForWitness() to build a P2WSH scriptPubKey
scriptPubKey = GetScriptForWitness(scriptPubKey);
// Build a P2WPKH script
scriptPubKey = GetScriptForDestination(WitnessV0KeyHash(pubkey));
}
if (bScriptHash) {
// Get the ID for the script, and then construct a P2SH destination for it.
@ -407,8 +407,8 @@ static void MutateTxAddOutMultiSig(CMutableTransaction& tx, const std::string& s
throw std::runtime_error("Uncompressed pubkeys are not useable for SegWit outputs");
}
}
// Call GetScriptForWitness() to build a P2WSH scriptPubKey
scriptPubKey = GetScriptForWitness(scriptPubKey);
// Build a P2WSH with the multisig script
scriptPubKey = GetScriptForDestination(WitnessV0ScriptHash(scriptPubKey));
}
if (bScriptHash) {
if (scriptPubKey.size() > MAX_SCRIPT_ELEMENT_SIZE) {
@ -501,7 +501,7 @@ static void MutateTxAddOutScript(CMutableTransaction& tx, const std::string& str
}
if (bSegWit) {
scriptPubKey = GetScriptForWitness(scriptPubKey);
scriptPubKey = GetScriptForDestination(WitnessV0ScriptHash(scriptPubKey));
}
if (bScriptHash) {
if (scriptPubKey.size() > MAX_SCRIPT_ELEMENT_SIZE) {

View file

@ -185,7 +185,7 @@ static bool CheckPeginTx(const std::vector<unsigned char>& tx_data, T& pegtx, co
}
CScript tweaked_fedpegscript = calculate_contract(scripts.second, claim_script);
// TODO: Remove script/standard.h dep for GetScriptFor*
CScript expected_script(GetScriptForWitness(tweaked_fedpegscript));
CScript expected_script(GetScriptForDestination(WitnessV0ScriptHash(tweaked_fedpegscript)));
if (scripts.first.IsPayToScriptHash()) {
expected_script = GetScriptForDestination(ScriptHash(expected_script));
}

View file

@ -708,7 +708,8 @@ UniValue tweakfedpegscript(const JSONRPCRequest& request)
CScript claim_script = CScript(scriptData.begin(), scriptData.end());
CScript tweaked_script = calculate_contract(fedpegscript, claim_script);
CTxDestination parent_addr(ScriptHash(GetScriptForWitness(tweaked_script)));
CScript redeem_script = GetScriptForDestination(WitnessV0ScriptHash(tweaked_script));
CTxDestination parent_addr{ScriptHash(redeem_script)};
UniValue ret(UniValue::VOBJ);
ret.pushKV("script", HexStr(tweaked_script));

View file

@ -28,7 +28,7 @@ template<typename T_tx>
unsigned int GetPeginTxnOutputIndex(const T_tx& txn, const CScript& witnessProgram, const std::vector<std::pair<CScript, CScript>>& fedpegscripts)
{
for (const auto & scripts : fedpegscripts) {
CScript mainchain_script = GetScriptForWitness(calculate_contract(scripts.second, witnessProgram));
CScript mainchain_script = GetScriptForDestination(WitnessV0ScriptHash(calculate_contract(scripts.second, witnessProgram)));
if (scripts.first.IsPayToScriptHash()) {
mainchain_script = GetScriptForDestination(ScriptHash(mainchain_script));
}

View file

@ -350,18 +350,6 @@ CScript GetScriptForMultisig(int nRequired, const std::vector<CPubKey>& keys)
return script;
}
CScript GetScriptForWitness(const CScript& redeemscript)
{
std::vector<std::vector<unsigned char> > vSolutions;
TxoutType typ = Solver(redeemscript, vSolutions);
if (typ == TxoutType::PUBKEY) {
return GetScriptForDestination(WitnessV0KeyHash(Hash160(vSolutions[0])));
} else if (typ == TxoutType::PUBKEYHASH) {
return GetScriptForDestination(WitnessV0KeyHash(uint160{vSolutions[0]}));
}
return GetScriptForDestination(WitnessV0ScriptHash(redeemscript));
}
bool IsValidDestination(const CTxDestination& dest) {
return dest.which() != 0;
}

View file

@ -324,14 +324,4 @@ CScript GetScriptForRawPubKey(const CPubKey& pubkey);
/** Generate a multisig script. */
CScript GetScriptForMultisig(int nRequired, const std::vector<CPubKey>& keys);
/**
* Generate a pay-to-witness script for the given redeem script. If the redeem
* script is P2PK or P2PKH, this returns a P2WPKH script, otherwise it returns a
* P2WSH script.
*
* TODO: replace calls to GetScriptForWitness with GetScriptForDestination using
* the various witness-specific CTxDestination subtypes.
*/
CScript GetScriptForWitness(const CScript& redeemscript);
#endif // BITCOIN_SCRIPT_STANDARD_H

View file

@ -63,8 +63,6 @@ void test_one_input(const std::vector<uint8_t>& buffer)
int required_ret;
(void)ExtractDestinations(script, type_ret, addresses, required_ret);
(void)GetScriptForWitness(script);
const FlatSigningProvider signing_provider;
(void)InferDescriptor(script, signing_provider);

View file

@ -349,21 +349,16 @@ BOOST_AUTO_TEST_CASE(script_standard_GetScriptFor_)
result = GetScriptForMultisig(2, std::vector<CPubKey>(pubkeys, pubkeys + 3));
BOOST_CHECK(result == expected);
// GetScriptForWitness
CScript witnessScript;
witnessScript << ToByteVector(pubkeys[0]) << OP_CHECKSIG;
// WitnessV0KeyHash
expected.clear();
expected << OP_0 << ToByteVector(pubkeys[0].GetID());
result = GetScriptForWitness(witnessScript);
result = GetScriptForDestination(WitnessV0KeyHash(Hash160(ToByteVector(pubkeys[0]))));
BOOST_CHECK(result == expected);
result = GetScriptForDestination(WitnessV0KeyHash(pubkeys[0].GetID()));
BOOST_CHECK(result == expected);
witnessScript.clear();
witnessScript << OP_DUP << OP_HASH160 << ToByteVector(pubkeys[0].GetID()) << OP_EQUALVERIFY << OP_CHECKSIG;
result = GetScriptForWitness(witnessScript);
BOOST_CHECK(result == expected);
witnessScript.clear();
// WitnessV0ScriptHash (multisig)
CScript witnessScript;
witnessScript << OP_1 << ToByteVector(pubkeys[0]) << OP_1 << OP_CHECKMULTISIG;
uint256 scriptHash;
@ -372,7 +367,7 @@ BOOST_AUTO_TEST_CASE(script_standard_GetScriptFor_)
expected.clear();
expected << OP_0 << ToByteVector(scriptHash);
result = GetScriptForWitness(witnessScript);
result = GetScriptForDestination(WitnessV0ScriptHash(witnessScript));
BOOST_CHECK(result == expected);
}

View file

@ -162,8 +162,7 @@ BOOST_AUTO_TEST_CASE(GetTxSigOpCost)
// P2WPKH witness program
{
CScript p2pk = CScript() << ToByteVector(pubkey) << OP_CHECKSIG;
CScript scriptPubKey = GetScriptForWitness(p2pk);
CScript scriptPubKey = GetScriptForDestination(WitnessV0KeyHash(pubkey));
CScript scriptSig = CScript();
CScriptWitness scriptWitness;
scriptWitness.stack.push_back(std::vector<unsigned char>(0));
@ -191,8 +190,7 @@ BOOST_AUTO_TEST_CASE(GetTxSigOpCost)
// P2WPKH nested in P2SH
{
CScript p2pk = CScript() << ToByteVector(pubkey) << OP_CHECKSIG;
CScript scriptSig = GetScriptForWitness(p2pk);
CScript scriptSig = GetScriptForDestination(WitnessV0KeyHash(pubkey));
CScript scriptPubKey = GetScriptForDestination(ScriptHash(scriptSig));
scriptSig = CScript() << ToByteVector(scriptSig);
CScriptWitness scriptWitness;
@ -207,7 +205,7 @@ BOOST_AUTO_TEST_CASE(GetTxSigOpCost)
// P2WSH witness program
{
CScript witnessScript = CScript() << 1 << ToByteVector(pubkey) << ToByteVector(pubkey) << 2 << OP_CHECKMULTISIGVERIFY;
CScript scriptPubKey = GetScriptForWitness(witnessScript);
CScript scriptPubKey = GetScriptForDestination(WitnessV0ScriptHash(witnessScript));
CScript scriptSig = CScript();
CScriptWitness scriptWitness;
scriptWitness.stack.push_back(std::vector<unsigned char>(0));
@ -223,7 +221,7 @@ BOOST_AUTO_TEST_CASE(GetTxSigOpCost)
// P2WSH nested in P2SH
{
CScript witnessScript = CScript() << 1 << ToByteVector(pubkey) << ToByteVector(pubkey) << 2 << OP_CHECKMULTISIGVERIFY;
CScript redeemScript = GetScriptForWitness(witnessScript);
CScript redeemScript = GetScriptForDestination(WitnessV0ScriptHash(witnessScript));
CScript scriptPubKey = GetScriptForDestination(ScriptHash(redeemScript));
CScript scriptSig = CScript() << ToByteVector(redeemScript);
CScriptWitness scriptWitness;

View file

@ -512,13 +512,19 @@ BOOST_AUTO_TEST_CASE(test_witness)
BOOST_CHECK(keystore.AddCScript(scriptPubkey1L));
BOOST_CHECK(keystore.AddCScript(scriptPubkey2L));
BOOST_CHECK(keystore.AddCScript(scriptMulti));
BOOST_CHECK(keystore.AddCScript(GetScriptForWitness(scriptPubkey1)));
BOOST_CHECK(keystore.AddCScript(GetScriptForWitness(scriptPubkey2)));
BOOST_CHECK(keystore.AddCScript(GetScriptForWitness(scriptPubkey1L)));
BOOST_CHECK(keystore.AddCScript(GetScriptForWitness(scriptPubkey2L)));
BOOST_CHECK(keystore.AddCScript(GetScriptForWitness(scriptMulti)));
CScript destination_script_1, destination_script_2, destination_script_1L, destination_script_2L, destination_script_multi;
destination_script_1 = GetScriptForDestination(WitnessV0KeyHash(pubkey1));
destination_script_2 = GetScriptForDestination(WitnessV0KeyHash(pubkey2));
destination_script_1L = GetScriptForDestination(WitnessV0KeyHash(pubkey1L));
destination_script_2L = GetScriptForDestination(WitnessV0KeyHash(pubkey2L));
destination_script_multi = GetScriptForDestination(WitnessV0ScriptHash(scriptMulti));
BOOST_CHECK(keystore.AddCScript(destination_script_1));
BOOST_CHECK(keystore.AddCScript(destination_script_2));
BOOST_CHECK(keystore.AddCScript(destination_script_1L));
BOOST_CHECK(keystore.AddCScript(destination_script_2L));
BOOST_CHECK(keystore.AddCScript(destination_script_multi));
BOOST_CHECK(keystore2.AddCScript(scriptMulti));
BOOST_CHECK(keystore2.AddCScript(GetScriptForWitness(scriptMulti)));
BOOST_CHECK(keystore2.AddCScript(destination_script_multi));
BOOST_CHECK(keystore2.AddKeyPubKey(key3, pubkey3));
CTransactionRef output1, output2;
@ -550,8 +556,8 @@ BOOST_AUTO_TEST_CASE(test_witness)
CheckWithFlag(output1, input2, STANDARD_SCRIPT_VERIFY_FLAGS, false);
// Witness pay-to-compressed-pubkey (v0).
CreateCreditAndSpend(keystore, GetScriptForWitness(scriptPubkey1), output1, input1);
CreateCreditAndSpend(keystore, GetScriptForWitness(scriptPubkey2), output2, input2);
CreateCreditAndSpend(keystore, destination_script_1, output1, input1);
CreateCreditAndSpend(keystore, destination_script_2, output2, input2);
CheckWithFlag(output1, input1, 0, true);
CheckWithFlag(output1, input1, SCRIPT_VERIFY_P2SH, true);
CheckWithFlag(output1, input1, SCRIPT_VERIFY_WITNESS | SCRIPT_VERIFY_P2SH, true);
@ -562,9 +568,9 @@ BOOST_AUTO_TEST_CASE(test_witness)
CheckWithFlag(output1, input2, STANDARD_SCRIPT_VERIFY_FLAGS, false);
// P2SH witness pay-to-compressed-pubkey (v0).
CreateCreditAndSpend(keystore, GetScriptForDestination(ScriptHash(GetScriptForWitness(scriptPubkey1))), output1, input1);
CreateCreditAndSpend(keystore, GetScriptForDestination(ScriptHash(GetScriptForWitness(scriptPubkey2))), output2, input2);
ReplaceRedeemScript(input2.vin[0].scriptSig, GetScriptForWitness(scriptPubkey1));
CreateCreditAndSpend(keystore, GetScriptForDestination(ScriptHash(destination_script_1)), output1, input1);
CreateCreditAndSpend(keystore, GetScriptForDestination(ScriptHash(destination_script_2)), output2, input2);
ReplaceRedeemScript(input2.vin[0].scriptSig, destination_script_1);
CheckWithFlag(output1, input1, 0, true);
CheckWithFlag(output1, input1, SCRIPT_VERIFY_P2SH, true);
CheckWithFlag(output1, input1, SCRIPT_VERIFY_WITNESS | SCRIPT_VERIFY_P2SH, true);
@ -600,12 +606,12 @@ BOOST_AUTO_TEST_CASE(test_witness)
CheckWithFlag(output1, input2, STANDARD_SCRIPT_VERIFY_FLAGS, false);
// Signing disabled for witness pay-to-uncompressed-pubkey (v1).
CreateCreditAndSpend(keystore, GetScriptForWitness(scriptPubkey1L), output1, input1, false);
CreateCreditAndSpend(keystore, GetScriptForWitness(scriptPubkey2L), output2, input2, false);
CreateCreditAndSpend(keystore, destination_script_1L, output1, input1, false);
CreateCreditAndSpend(keystore, destination_script_2L, output2, input2, false);
// Signing disabled for P2SH witness pay-to-uncompressed-pubkey (v1).
CreateCreditAndSpend(keystore, GetScriptForDestination(ScriptHash(GetScriptForWitness(scriptPubkey1L))), output1, input1, false);
CreateCreditAndSpend(keystore, GetScriptForDestination(ScriptHash(GetScriptForWitness(scriptPubkey2L))), output2, input2, false);
CreateCreditAndSpend(keystore, GetScriptForDestination(ScriptHash(destination_script_1L)), output1, input1, false);
CreateCreditAndSpend(keystore, GetScriptForDestination(ScriptHash(destination_script_2L)), output2, input2, false);
// Normal 2-of-2 multisig
CreateCreditAndSpend(keystore, scriptMulti, output1, input1, false);
@ -630,10 +636,10 @@ BOOST_AUTO_TEST_CASE(test_witness)
CheckWithFlag(output1, input1, STANDARD_SCRIPT_VERIFY_FLAGS, true);
// Witness 2-of-2 multisig
CreateCreditAndSpend(keystore, GetScriptForWitness(scriptMulti), output1, input1, false);
CreateCreditAndSpend(keystore, destination_script_multi, output1, input1, false);
CheckWithFlag(output1, input1, 0, true);
CheckWithFlag(output1, input1, SCRIPT_VERIFY_P2SH | SCRIPT_VERIFY_WITNESS, false);
CreateCreditAndSpend(keystore2, GetScriptForWitness(scriptMulti), output2, input2, false);
CreateCreditAndSpend(keystore2, destination_script_multi, output2, input2, false);
CheckWithFlag(output2, input2, 0, true);
CheckWithFlag(output2, input2, SCRIPT_VERIFY_P2SH | SCRIPT_VERIFY_WITNESS, false);
BOOST_CHECK(*output1 == *output2);
@ -642,10 +648,10 @@ BOOST_AUTO_TEST_CASE(test_witness)
CheckWithFlag(output1, input1, STANDARD_SCRIPT_VERIFY_FLAGS, true);
// P2SH witness 2-of-2 multisig
CreateCreditAndSpend(keystore, GetScriptForDestination(ScriptHash(GetScriptForWitness(scriptMulti))), output1, input1, false);
CreateCreditAndSpend(keystore, GetScriptForDestination(ScriptHash(destination_script_multi)), output1, input1, false);
CheckWithFlag(output1, input1, SCRIPT_VERIFY_P2SH, true);
CheckWithFlag(output1, input1, SCRIPT_VERIFY_P2SH | SCRIPT_VERIFY_WITNESS, false);
CreateCreditAndSpend(keystore2, GetScriptForDestination(ScriptHash(GetScriptForWitness(scriptMulti))), output2, input2, false);
CreateCreditAndSpend(keystore2, GetScriptForDestination(ScriptHash(destination_script_multi)), output2, input2, false);
CheckWithFlag(output2, input2, SCRIPT_VERIFY_P2SH, true);
CheckWithFlag(output2, input2, SCRIPT_VERIFY_P2SH | SCRIPT_VERIFY_WITNESS, false);
BOOST_CHECK(*output1 == *output2);

View file

@ -158,7 +158,7 @@ BOOST_FIXTURE_TEST_CASE(checkinputs_test, TestChain100Setup)
CScript p2pk_scriptPubKey = CScript() << ToByteVector(coinbaseKey.GetPubKey()) << OP_CHECKSIG;
CScript p2sh_scriptPubKey = GetScriptForDestination(ScriptHash(p2pk_scriptPubKey));
CScript p2pkh_scriptPubKey = GetScriptForDestination(PKHash(coinbaseKey.GetPubKey()));
CScript p2wpkh_scriptPubKey = GetScriptForWitness(p2pkh_scriptPubKey);
CScript p2wpkh_scriptPubKey = GetScriptForDestination(WitnessV0KeyHash(coinbaseKey.GetPubKey()));
FillableSigningProvider keystore;
BOOST_CHECK(keystore.AddKey(coinbaseKey));

View file

@ -1095,64 +1095,6 @@ static UniValue addmultisigaddress(const JSONRPCRequest& request)
return result;
}
class Witnessifier : public boost::static_visitor<bool>
{
public:
const SigningProvider * const provider;
CTxDestination result;
bool already_witness;
explicit Witnessifier(const SigningProvider *_provider) : provider(_provider), already_witness(false) {}
bool operator()(const PKHash &keyID) {
if (provider) {
CScript basescript = GetScriptForDestination(keyID);
CScript witscript = GetScriptForWitness(basescript);
if (!IsSolvable(*provider, witscript)) {
return false;
}
return ExtractDestination(witscript, result);
}
return false;
}
bool operator()(const ScriptHash &scripthash) {
CScript subscript;
if (provider && provider->GetCScript(CScriptID(scripthash), subscript)) {
int witnessversion;
std::vector<unsigned char> witprog;
if (subscript.IsWitnessProgram(witnessversion, witprog)) {
ExtractDestination(subscript, result);
already_witness = true;
return true;
}
CScript witscript = GetScriptForWitness(subscript);
if (!IsSolvable(*provider, witscript)) {
return false;
}
return ExtractDestination(witscript, result);
}
return false;
}
bool operator()(const WitnessV0KeyHash& id)
{
already_witness = true;
result = id;
return true;
}
bool operator()(const WitnessV0ScriptHash& id)
{
already_witness = true;
result = id;
return true;
}
template<typename T>
bool operator()(const T& dest) { return false; }
};
struct tallyitem
{
CAmountMap mapAmount;