15 #include <boost/algorithm/string.hpp>
41 std::vector<unsigned char> CheckedParseHex(
const std::string& str)
43 if (str.size() && !
IsHex(str))
throw std::runtime_error(
"Non-hex input '" + str +
"'");
49 std::vector<unsigned char> data = CheckedParseHex(str);
50 return CScript(data.begin(), data.end());
58 }
catch (
const std::ios_base::failure&) {
59 throw std::runtime_error(
"Tx deserialization failure");
66 if (!univalue.
isArray())
throw std::runtime_error(
"Prevouts must be array");
67 std::vector<CTxOut> prevouts;
68 for (
size_t i = 0; i < univalue.
size(); ++i) {
72 }
catch (
const std::ios_base::failure&) {
73 throw std::runtime_error(
"Prevout invalid format");
75 prevouts.push_back(std::move(txout));
82 if (!univalue.
isArray())
throw std::runtime_error(
"Script witness is not array");
84 for (
size_t i = 0; i < univalue.
size(); ++i) {
85 auto bytes = CheckedParseHex(univalue[i].get_str());
86 scriptwitness.
stack.push_back(std::move(bytes));
91 const std::map<std::string, unsigned int> FLAG_NAMES = {
101 std::vector<unsigned int> AllFlags()
103 std::vector<unsigned int> ret;
105 for (
unsigned int i = 0; i < 128; ++i) {
106 unsigned int flag = 0;
126 const std::vector<unsigned int> ALL_FLAGS = AllFlags();
130 if (str.empty())
return 0;
132 unsigned int flags = 0;
133 std::vector<std::string> words;
134 boost::algorithm::split(words, str, boost::algorithm::is_any_of(
","));
136 for (
const std::string& word : words) {
137 auto it = FLAG_NAMES.find(word);
138 if (it == FLAG_NAMES.end())
throw std::runtime_error(
"Unknown verification flag " + word);
145 void Test(
const std::string& str)
148 if (!test.
read(str) || !test.
isObject())
throw std::runtime_error(
"Non-object test input");
151 const std::vector<CTxOut> prevouts =
TxOutsFromJSON(test[
"prevouts"]);
152 if (prevouts.size() != tx.
vin.size())
throw std::runtime_error(
"Incorrect number of prevouts");
154 if (idx >= tx.
vin.size())
throw std::runtime_error(
"Invalid index");
158 if (test.
exists(
"success")) {
159 tx.
vin[idx].scriptSig =
ScriptFromHex(test[
"success"][
"scriptSig"].get_str());
162 txdata.
Init(tx, std::vector<CTxOut>(prevouts));
164 for (
const auto flags : ALL_FLAGS) {
167 if (
final || ((
flags & test_flags) ==
flags)) {
168 (void)
VerifyScript(tx.
vin[idx].scriptSig, prevouts[idx].scriptPubKey, &tx.
vin[idx].scriptWitness,
flags, txcheck,
nullptr);
173 if (test.
exists(
"failure")) {
174 tx.
vin[idx].scriptSig =
ScriptFromHex(test[
"failure"][
"scriptSig"].get_str());
177 txdata.
Init(tx, std::vector<CTxOut>(prevouts));
179 for (
const auto flags : ALL_FLAGS) {
181 if ((
flags & test_flags) == test_flags) {
182 (void)
VerifyScript(tx.
vin[idx].scriptSig, prevouts[idx].scriptPubKey, &tx.
vin[idx].scriptWitness,
flags, txcheck,
nullptr);
195 if (buffer.size() < 2 || buffer.back() !=
'\n' || buffer[buffer.size() - 2] !=
',')
return;
196 const std::string str((
const char*)buffer.data(), buffer.size() - 2);
199 }
catch (
const std::runtime_error&) {