mirror of
https://github.com/Retropex/bitcoin.git
synced 2025-05-13 03:30:42 +02:00
Merge bitcoin/bitcoin#26749: refactor: Use move semantics instead of custom swap functions
95ad70ab65
test: Default initialize `should_freeze` to `true` (Hennadii Stepanov)cea50521fe
refactor: Drop no longer used `swap` member functions (Hennadii Stepanov)a87fb6bee5
clang-tidy: Fix modernize-use-default-member-init in `CScriptCheck` (Hennadii Stepanov)b4bed5c1f9
refactor: Drop no longer used `CScriptCheck()` default constructor (Hennadii Stepanov)d8427cc28e
refactor: Use move semantics in `CCheckQueue::Loop` (Hennadii Stepanov)9a0b524139
clang-tidy, test: Fix bugprone-use-after-move in `Correct_Queue_range()` (Hennadii Stepanov)04831fee6d
refactor: Make move semantics explicit for callers (Hennadii Stepanov)6c2d5972f3
refactor: Use move semantics in `CCheckQueue::Add` (Hennadii Stepanov)0682003214
test, refactor: Avoid `CScriptCheck::swap` in `transaction_tests` (Hennadii Stepanov)15209d97c6
consensus, refactor: Avoid `CScriptCheck::swap` in `CheckInputScripts` (Hennadii Stepanov) Pull request description: This PR makes code more succinct and readable by using move semantics. ACKs for top commit: martinus: re-ACK95ad70ab65
achow101: ACK95ad70ab65
TheCharlatan: re-ACK95ad70ab65
MarcoFalke: re-ACK95ad70ab65
🚥 Tree-SHA512: adda760891b12d252dc9b823fe7c41eed660364b6fb1a69f17607d7a31eb0bbb82a80d154a7acfaa241b5de37d42a293c2b6e059f26a8e92d88d3a87c99768fb
This commit is contained in:
commit
a70911492f
@ -29,7 +29,6 @@ static void CCheckQueueSpeedPrevectorJob(benchmark::Bench& bench)
|
|||||||
|
|
||||||
struct PrevectorJob {
|
struct PrevectorJob {
|
||||||
prevector<PREVECTOR_SIZE, uint8_t> p;
|
prevector<PREVECTOR_SIZE, uint8_t> p;
|
||||||
PrevectorJob() = default;
|
|
||||||
explicit PrevectorJob(FastRandomContext& insecure_rand){
|
explicit PrevectorJob(FastRandomContext& insecure_rand){
|
||||||
p.resize(insecure_rand.randrange(PREVECTOR_SIZE*2));
|
p.resize(insecure_rand.randrange(PREVECTOR_SIZE*2));
|
||||||
}
|
}
|
||||||
@ -37,10 +36,6 @@ static void CCheckQueueSpeedPrevectorJob(benchmark::Bench& bench)
|
|||||||
{
|
{
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
void swap(PrevectorJob& x) noexcept
|
|
||||||
{
|
|
||||||
p.swap(x.p);
|
|
||||||
};
|
|
||||||
};
|
};
|
||||||
CCheckQueue<PrevectorJob> queue {QUEUE_BATCH_SIZE};
|
CCheckQueue<PrevectorJob> queue {QUEUE_BATCH_SIZE};
|
||||||
// The main thread should be counted to prevent thread oversubscription, and
|
// The main thread should be counted to prevent thread oversubscription, and
|
||||||
@ -60,7 +55,7 @@ static void CCheckQueueSpeedPrevectorJob(benchmark::Bench& bench)
|
|||||||
// Make insecure_rand here so that each iteration is identical.
|
// Make insecure_rand here so that each iteration is identical.
|
||||||
CCheckQueueControl<PrevectorJob> control(&queue);
|
CCheckQueueControl<PrevectorJob> control(&queue);
|
||||||
for (auto vChecks : vBatches) {
|
for (auto vChecks : vBatches) {
|
||||||
control.Add(vChecks);
|
control.Add(std::move(vChecks));
|
||||||
}
|
}
|
||||||
// control waits for completion by RAII, but
|
// control waits for completion by RAII, but
|
||||||
// it is done explicitly here for clarity
|
// it is done explicitly here for clarity
|
||||||
|
@ -11,6 +11,7 @@
|
|||||||
#include <util/threadnames.h>
|
#include <util/threadnames.h>
|
||||||
|
|
||||||
#include <algorithm>
|
#include <algorithm>
|
||||||
|
#include <iterator>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
|
||||||
template <typename T>
|
template <typename T>
|
||||||
@ -111,13 +112,9 @@ private:
|
|||||||
// * Try to account for idle jobs which will instantly start helping.
|
// * Try to account for idle jobs which will instantly start helping.
|
||||||
// * Don't do batches smaller than 1 (duh), or larger than nBatchSize.
|
// * Don't do batches smaller than 1 (duh), or larger than nBatchSize.
|
||||||
nNow = std::max(1U, std::min(nBatchSize, (unsigned int)queue.size() / (nTotal + nIdle + 1)));
|
nNow = std::max(1U, std::min(nBatchSize, (unsigned int)queue.size() / (nTotal + nIdle + 1)));
|
||||||
vChecks.resize(nNow);
|
auto start_it = queue.end() - nNow;
|
||||||
for (unsigned int i = 0; i < nNow; i++) {
|
vChecks.assign(std::make_move_iterator(start_it), std::make_move_iterator(queue.end()));
|
||||||
// We want the lock on the m_mutex to be as short as possible, so swap jobs from the global
|
queue.erase(start_it, queue.end());
|
||||||
// queue to the local batch vector instead of copying.
|
|
||||||
vChecks[i].swap(queue.back());
|
|
||||||
queue.pop_back();
|
|
||||||
}
|
|
||||||
// Check whether we need to do work at all
|
// Check whether we need to do work at all
|
||||||
fOk = fAllOk;
|
fOk = fAllOk;
|
||||||
}
|
}
|
||||||
@ -165,7 +162,7 @@ public:
|
|||||||
}
|
}
|
||||||
|
|
||||||
//! Add a batch of checks to the queue
|
//! Add a batch of checks to the queue
|
||||||
void Add(std::vector<T>& vChecks) EXCLUSIVE_LOCKS_REQUIRED(!m_mutex)
|
void Add(std::vector<T>&& vChecks) EXCLUSIVE_LOCKS_REQUIRED(!m_mutex)
|
||||||
{
|
{
|
||||||
if (vChecks.empty()) {
|
if (vChecks.empty()) {
|
||||||
return;
|
return;
|
||||||
@ -173,10 +170,7 @@ public:
|
|||||||
|
|
||||||
{
|
{
|
||||||
LOCK(m_mutex);
|
LOCK(m_mutex);
|
||||||
for (T& check : vChecks) {
|
queue.insert(queue.end(), std::make_move_iterator(vChecks.begin()), std::make_move_iterator(vChecks.end()));
|
||||||
queue.emplace_back();
|
|
||||||
check.swap(queue.back());
|
|
||||||
}
|
|
||||||
nTodo += vChecks.size();
|
nTodo += vChecks.size();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -239,10 +233,11 @@ public:
|
|||||||
return fRet;
|
return fRet;
|
||||||
}
|
}
|
||||||
|
|
||||||
void Add(std::vector<T>& vChecks)
|
void Add(std::vector<T>&& vChecks)
|
||||||
{
|
{
|
||||||
if (pqueue != nullptr)
|
if (pqueue != nullptr) {
|
||||||
pqueue->Add(vChecks);
|
pqueue->Add(std::move(vChecks));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
~CCheckQueueControl()
|
~CCheckQueueControl()
|
||||||
|
@ -43,7 +43,6 @@ struct FakeCheck {
|
|||||||
{
|
{
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
void swap(FakeCheck& x) noexcept {};
|
|
||||||
};
|
};
|
||||||
|
|
||||||
struct FakeCheckCheckCompletion {
|
struct FakeCheckCheckCompletion {
|
||||||
@ -53,7 +52,6 @@ struct FakeCheckCheckCompletion {
|
|||||||
n_calls.fetch_add(1, std::memory_order_relaxed);
|
n_calls.fetch_add(1, std::memory_order_relaxed);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
void swap(FakeCheckCheckCompletion& x) noexcept {};
|
|
||||||
};
|
};
|
||||||
|
|
||||||
struct FailingCheck {
|
struct FailingCheck {
|
||||||
@ -64,10 +62,6 @@ struct FailingCheck {
|
|||||||
{
|
{
|
||||||
return !fails;
|
return !fails;
|
||||||
}
|
}
|
||||||
void swap(FailingCheck& x) noexcept
|
|
||||||
{
|
|
||||||
std::swap(fails, x.fails);
|
|
||||||
};
|
|
||||||
};
|
};
|
||||||
|
|
||||||
struct UniqueCheck {
|
struct UniqueCheck {
|
||||||
@ -82,10 +76,6 @@ struct UniqueCheck {
|
|||||||
results.insert(check_id);
|
results.insert(check_id);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
void swap(UniqueCheck& x) noexcept
|
|
||||||
{
|
|
||||||
std::swap(x.check_id, check_id);
|
|
||||||
};
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
@ -113,19 +103,13 @@ struct MemoryCheck {
|
|||||||
{
|
{
|
||||||
fake_allocated_memory.fetch_sub(b, std::memory_order_relaxed);
|
fake_allocated_memory.fetch_sub(b, std::memory_order_relaxed);
|
||||||
};
|
};
|
||||||
void swap(MemoryCheck& x) noexcept
|
|
||||||
{
|
|
||||||
std::swap(b, x.b);
|
|
||||||
};
|
|
||||||
};
|
};
|
||||||
|
|
||||||
struct FrozenCleanupCheck {
|
struct FrozenCleanupCheck {
|
||||||
static std::atomic<uint64_t> nFrozen;
|
static std::atomic<uint64_t> nFrozen;
|
||||||
static std::condition_variable cv;
|
static std::condition_variable cv;
|
||||||
static std::mutex m;
|
static std::mutex m;
|
||||||
// Freezing can't be the default initialized behavior given how the queue
|
bool should_freeze{true};
|
||||||
// swaps in default initialized Checks.
|
|
||||||
bool should_freeze {false};
|
|
||||||
bool operator()() const
|
bool operator()() const
|
||||||
{
|
{
|
||||||
return true;
|
return true;
|
||||||
@ -140,10 +124,17 @@ struct FrozenCleanupCheck {
|
|||||||
cv.wait(l, []{ return nFrozen.load(std::memory_order_relaxed) == 0;});
|
cv.wait(l, []{ return nFrozen.load(std::memory_order_relaxed) == 0;});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
void swap(FrozenCleanupCheck& x) noexcept
|
FrozenCleanupCheck(FrozenCleanupCheck&& other) noexcept
|
||||||
{
|
{
|
||||||
std::swap(should_freeze, x.should_freeze);
|
should_freeze = other.should_freeze;
|
||||||
};
|
other.should_freeze = false;
|
||||||
|
}
|
||||||
|
FrozenCleanupCheck& operator=(FrozenCleanupCheck&& other) noexcept
|
||||||
|
{
|
||||||
|
should_freeze = other.should_freeze;
|
||||||
|
other.should_freeze = false;
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
// Static Allocations
|
// Static Allocations
|
||||||
@ -173,14 +164,16 @@ static void Correct_Queue_range(std::vector<size_t> range)
|
|||||||
small_queue->StartWorkerThreads(SCRIPT_CHECK_THREADS);
|
small_queue->StartWorkerThreads(SCRIPT_CHECK_THREADS);
|
||||||
// Make vChecks here to save on malloc (this test can be slow...)
|
// Make vChecks here to save on malloc (this test can be slow...)
|
||||||
std::vector<FakeCheckCheckCompletion> vChecks;
|
std::vector<FakeCheckCheckCompletion> vChecks;
|
||||||
|
vChecks.reserve(9);
|
||||||
for (const size_t i : range) {
|
for (const size_t i : range) {
|
||||||
size_t total = i;
|
size_t total = i;
|
||||||
FakeCheckCheckCompletion::n_calls = 0;
|
FakeCheckCheckCompletion::n_calls = 0;
|
||||||
CCheckQueueControl<FakeCheckCheckCompletion> control(small_queue.get());
|
CCheckQueueControl<FakeCheckCheckCompletion> control(small_queue.get());
|
||||||
while (total) {
|
while (total) {
|
||||||
vChecks.resize(std::min(total, (size_t) InsecureRandRange(10)));
|
vChecks.clear();
|
||||||
|
vChecks.resize(std::min<size_t>(total, InsecureRandRange(10)));
|
||||||
total -= vChecks.size();
|
total -= vChecks.size();
|
||||||
control.Add(vChecks);
|
control.Add(std::move(vChecks));
|
||||||
}
|
}
|
||||||
BOOST_REQUIRE(control.Wait());
|
BOOST_REQUIRE(control.Wait());
|
||||||
if (FakeCheckCheckCompletion::n_calls != i) {
|
if (FakeCheckCheckCompletion::n_calls != i) {
|
||||||
@ -242,7 +235,7 @@ BOOST_AUTO_TEST_CASE(test_CheckQueue_Catches_Failure)
|
|||||||
vChecks.reserve(r);
|
vChecks.reserve(r);
|
||||||
for (size_t k = 0; k < r && remaining; k++, remaining--)
|
for (size_t k = 0; k < r && remaining; k++, remaining--)
|
||||||
vChecks.emplace_back(remaining == 1);
|
vChecks.emplace_back(remaining == 1);
|
||||||
control.Add(vChecks);
|
control.Add(std::move(vChecks));
|
||||||
}
|
}
|
||||||
bool success = control.Wait();
|
bool success = control.Wait();
|
||||||
if (i > 0) {
|
if (i > 0) {
|
||||||
@ -267,7 +260,7 @@ BOOST_AUTO_TEST_CASE(test_CheckQueue_Recovers_From_Failure)
|
|||||||
std::vector<FailingCheck> vChecks;
|
std::vector<FailingCheck> vChecks;
|
||||||
vChecks.resize(100, false);
|
vChecks.resize(100, false);
|
||||||
vChecks[99] = end_fails;
|
vChecks[99] = end_fails;
|
||||||
control.Add(vChecks);
|
control.Add(std::move(vChecks));
|
||||||
}
|
}
|
||||||
bool r =control.Wait();
|
bool r =control.Wait();
|
||||||
BOOST_REQUIRE(r != end_fails);
|
BOOST_REQUIRE(r != end_fails);
|
||||||
@ -293,7 +286,7 @@ BOOST_AUTO_TEST_CASE(test_CheckQueue_UniqueCheck)
|
|||||||
std::vector<UniqueCheck> vChecks;
|
std::vector<UniqueCheck> vChecks;
|
||||||
for (size_t k = 0; k < r && total; k++)
|
for (size_t k = 0; k < r && total; k++)
|
||||||
vChecks.emplace_back(--total);
|
vChecks.emplace_back(--total);
|
||||||
control.Add(vChecks);
|
control.Add(std::move(vChecks));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
{
|
{
|
||||||
@ -331,7 +324,7 @@ BOOST_AUTO_TEST_CASE(test_CheckQueue_Memory)
|
|||||||
// to catch any sort of deallocation failure
|
// to catch any sort of deallocation failure
|
||||||
vChecks.emplace_back(total == 0 || total == i || total == i/2);
|
vChecks.emplace_back(total == 0 || total == i || total == i/2);
|
||||||
}
|
}
|
||||||
control.Add(vChecks);
|
control.Add(std::move(vChecks));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
BOOST_REQUIRE_EQUAL(MemoryCheck::fake_allocated_memory, 0U);
|
BOOST_REQUIRE_EQUAL(MemoryCheck::fake_allocated_memory, 0U);
|
||||||
@ -349,11 +342,7 @@ BOOST_AUTO_TEST_CASE(test_CheckQueue_FrozenCleanup)
|
|||||||
std::thread t0([&]() {
|
std::thread t0([&]() {
|
||||||
CCheckQueueControl<FrozenCleanupCheck> control(queue.get());
|
CCheckQueueControl<FrozenCleanupCheck> control(queue.get());
|
||||||
std::vector<FrozenCleanupCheck> vChecks(1);
|
std::vector<FrozenCleanupCheck> vChecks(1);
|
||||||
// Freezing can't be the default initialized behavior given how the queue
|
control.Add(std::move(vChecks));
|
||||||
// swaps in default initialized Checks (otherwise freezing destructor
|
|
||||||
// would get called twice).
|
|
||||||
vChecks[0].should_freeze = true;
|
|
||||||
control.Add(vChecks);
|
|
||||||
bool waitResult = control.Wait(); // Hangs here
|
bool waitResult = control.Wait(); // Hangs here
|
||||||
assert(waitResult);
|
assert(waitResult);
|
||||||
});
|
});
|
||||||
|
@ -13,9 +13,7 @@
|
|||||||
|
|
||||||
namespace {
|
namespace {
|
||||||
struct DumbCheck {
|
struct DumbCheck {
|
||||||
const bool result = false;
|
bool result = false;
|
||||||
|
|
||||||
DumbCheck() = default;
|
|
||||||
|
|
||||||
explicit DumbCheck(const bool _result) : result(_result)
|
explicit DumbCheck(const bool _result) : result(_result)
|
||||||
{
|
{
|
||||||
@ -25,10 +23,6 @@ struct DumbCheck {
|
|||||||
{
|
{
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
void swap(DumbCheck& x) noexcept
|
|
||||||
{
|
|
||||||
}
|
|
||||||
};
|
};
|
||||||
} // namespace
|
} // namespace
|
||||||
|
|
||||||
@ -48,7 +42,7 @@ FUZZ_TARGET(checkqueue)
|
|||||||
checks_2.emplace_back(result);
|
checks_2.emplace_back(result);
|
||||||
}
|
}
|
||||||
if (fuzzed_data_provider.ConsumeBool()) {
|
if (fuzzed_data_provider.ConsumeBool()) {
|
||||||
check_queue_1.Add(checks_1);
|
check_queue_1.Add(std::move(checks_1));
|
||||||
}
|
}
|
||||||
if (fuzzed_data_provider.ConsumeBool()) {
|
if (fuzzed_data_provider.ConsumeBool()) {
|
||||||
(void)check_queue_1.Wait();
|
(void)check_queue_1.Wait();
|
||||||
@ -56,7 +50,7 @@ FUZZ_TARGET(checkqueue)
|
|||||||
|
|
||||||
CCheckQueueControl<DumbCheck> check_queue_control{&check_queue_2};
|
CCheckQueueControl<DumbCheck> check_queue_control{&check_queue_2};
|
||||||
if (fuzzed_data_provider.ConsumeBool()) {
|
if (fuzzed_data_provider.ConsumeBool()) {
|
||||||
check_queue_control.Add(checks_2);
|
check_queue_control.Add(std::move(checks_2));
|
||||||
}
|
}
|
||||||
if (fuzzed_data_provider.ConsumeBool()) {
|
if (fuzzed_data_provider.ConsumeBool()) {
|
||||||
(void)check_queue_control.Wait();
|
(void)check_queue_control.Wait();
|
||||||
|
@ -547,10 +547,8 @@ BOOST_AUTO_TEST_CASE(test_big_witness_transaction)
|
|||||||
|
|
||||||
for(uint32_t i = 0; i < mtx.vin.size(); i++) {
|
for(uint32_t i = 0; i < mtx.vin.size(); i++) {
|
||||||
std::vector<CScriptCheck> vChecks;
|
std::vector<CScriptCheck> vChecks;
|
||||||
CScriptCheck check(coins[tx.vin[i].prevout.n].out, tx, i, SCRIPT_VERIFY_P2SH | SCRIPT_VERIFY_WITNESS, false, &txdata);
|
vChecks.emplace_back(coins[tx.vin[i].prevout.n].out, tx, i, SCRIPT_VERIFY_P2SH | SCRIPT_VERIFY_WITNESS, false, &txdata);
|
||||||
vChecks.push_back(CScriptCheck());
|
control.Add(std::move(vChecks));
|
||||||
check.swap(vChecks.back());
|
|
||||||
control.Add(vChecks);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
bool controlCheck = control.Wait();
|
bool controlCheck = control.Wait();
|
||||||
|
@ -1815,8 +1815,7 @@ bool CheckInputScripts(const CTransaction& tx, TxValidationState& state,
|
|||||||
// Verify signature
|
// Verify signature
|
||||||
CScriptCheck check(txdata.m_spent_outputs[i], tx, i, flags, cacheSigStore, &txdata);
|
CScriptCheck check(txdata.m_spent_outputs[i], tx, i, flags, cacheSigStore, &txdata);
|
||||||
if (pvChecks) {
|
if (pvChecks) {
|
||||||
pvChecks->push_back(CScriptCheck());
|
pvChecks->emplace_back(std::move(check));
|
||||||
check.swap(pvChecks->back());
|
|
||||||
} else if (!check()) {
|
} else if (!check()) {
|
||||||
if (flags & STANDARD_NOT_MANDATORY_VERIFY_FLAGS) {
|
if (flags & STANDARD_NOT_MANDATORY_VERIFY_FLAGS) {
|
||||||
// Check whether the failure was caused by a
|
// Check whether the failure was caused by a
|
||||||
@ -2325,7 +2324,7 @@ bool Chainstate::ConnectBlock(const CBlock& block, BlockValidationState& state,
|
|||||||
return error("ConnectBlock(): CheckInputScripts on %s failed with %s",
|
return error("ConnectBlock(): CheckInputScripts on %s failed with %s",
|
||||||
tx.GetHash().ToString(), state.ToString());
|
tx.GetHash().ToString(), state.ToString());
|
||||||
}
|
}
|
||||||
control.Add(vChecks);
|
control.Add(std::move(vChecks));
|
||||||
}
|
}
|
||||||
|
|
||||||
CTxUndo undoDummy;
|
CTxUndo undoDummy;
|
||||||
|
@ -314,27 +314,20 @@ private:
|
|||||||
unsigned int nIn;
|
unsigned int nIn;
|
||||||
unsigned int nFlags;
|
unsigned int nFlags;
|
||||||
bool cacheStore;
|
bool cacheStore;
|
||||||
ScriptError error;
|
ScriptError error{SCRIPT_ERR_UNKNOWN_ERROR};
|
||||||
PrecomputedTransactionData *txdata;
|
PrecomputedTransactionData *txdata;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
CScriptCheck(): ptxTo(nullptr), nIn(0), nFlags(0), cacheStore(false), error(SCRIPT_ERR_UNKNOWN_ERROR) {}
|
|
||||||
CScriptCheck(const CTxOut& outIn, const CTransaction& txToIn, unsigned int nInIn, unsigned int nFlagsIn, bool cacheIn, PrecomputedTransactionData* txdataIn) :
|
CScriptCheck(const CTxOut& outIn, const CTransaction& txToIn, unsigned int nInIn, unsigned int nFlagsIn, bool cacheIn, PrecomputedTransactionData* txdataIn) :
|
||||||
m_tx_out(outIn), ptxTo(&txToIn), nIn(nInIn), nFlags(nFlagsIn), cacheStore(cacheIn), error(SCRIPT_ERR_UNKNOWN_ERROR), txdata(txdataIn) { }
|
m_tx_out(outIn), ptxTo(&txToIn), nIn(nInIn), nFlags(nFlagsIn), cacheStore(cacheIn), txdata(txdataIn) { }
|
||||||
|
|
||||||
|
CScriptCheck(const CScriptCheck&) = delete;
|
||||||
|
CScriptCheck& operator=(const CScriptCheck&) = delete;
|
||||||
|
CScriptCheck(CScriptCheck&&) = default;
|
||||||
|
CScriptCheck& operator=(CScriptCheck&&) = default;
|
||||||
|
|
||||||
bool operator()();
|
bool operator()();
|
||||||
|
|
||||||
void swap(CScriptCheck& check) noexcept
|
|
||||||
{
|
|
||||||
std::swap(ptxTo, check.ptxTo);
|
|
||||||
std::swap(m_tx_out, check.m_tx_out);
|
|
||||||
std::swap(nIn, check.nIn);
|
|
||||||
std::swap(nFlags, check.nFlags);
|
|
||||||
std::swap(cacheStore, check.cacheStore);
|
|
||||||
std::swap(error, check.error);
|
|
||||||
std::swap(txdata, check.txdata);
|
|
||||||
}
|
|
||||||
|
|
||||||
ScriptError GetScriptError() const { return error; }
|
ScriptError GetScriptError() const { return error; }
|
||||||
};
|
};
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user