This commit is contained in:
David Burkett 2022-05-04 13:38:03 -04:00 committed by Loshan T
parent 2944bf24af
commit eef63f7034
34 changed files with 327 additions and 274 deletions

View File

@ -3,7 +3,7 @@ define(_CLIENT_VERSION_MAJOR, 0)
define(_CLIENT_VERSION_MINOR, 21)
define(_CLIENT_VERSION_REVISION, 2)
define(_CLIENT_VERSION_BUILD, 0)
define(_CLIENT_VERSION_RC, 7)
define(_CLIENT_VERSION_RC, 0)
define(_CLIENT_VERSION_IS_RELEASE, true)
define(_COPYRIGHT_YEAR, 2022)
define(_COPYRIGHT_HOLDERS,[The %s developers])

View File

@ -0,0 +1,120 @@
Litecoin Core version 0.21.2 is now available from:
<https://download.litecoin.org/litecoin-0.21.2/>.
This is the largest update ever, providing full node, wallet, and mining support for MWEB.
Please report bugs using the issue tracker at GitHub:
<https://github.com/litecoin-project/litecoin/issues>
To receive security and update notifications, please subscribe to:
<https://groups.google.com/forum/#!forum/litecoin-dev>
How to upgrade:
==============
Firstly, thank you for running Litecoin Core and helping secure the network!
As youre running an older version of Litecoin Core, shut it down. Wait until its completely shut down - which might take a few minutes for older versions - then follow these simple steps:
For Windows: simply run the installer
For Mac: copy over to `/Applications/Litecoin-Qt`
For Linux: copy cover `litecoind`/`litecoin-qt`.
NB: upgrading directly from an end of life version of Litecoin Core is possible, but it might take a while if the data directory needs to be migrated. Old wallet versions of Litecoin Core are generally supported.
Compatibility:
==============
Litecoin Core is supported and extensively tested on operating systems using the Linux kernel, macOS 10.10+, Windows 7 and newer. Its not recommended to use Litecoin Core on unsupported systems.
Litecoin Core should also work on most other Unix-like systems, but is not as frequently tested on them.
MWEB fields added to BlockIndex, and block serialization format has changed. Downgrading to older versions is unsafe.
If upgrading to 0.21.2 *after* MWEB has activated, you must resync to download MWEB blocks.
Notable changes
===============
Consensus changes
-----------------
- This release implements the proposed MWEB consensus rules
([LIP002](https://github.com/litecoin-project/lips/blob/master/lip-0002.mediawiki),
[LIP003](https://github.com/litecoin-project/lips/blob/master/lip-0003.mediawiki), and
[LIP004](https://github.com/litecoin-project/lips/blob/master/lip-0004.mediawiki))
P2P and network changes
-----------------------
- A new service flag, NODE_MWEB (1 << 24), was added to signal to peers that the node supports MWEB.
When connected peers both advertise this capability, they are expected to provide all MWEB data when
sharing transactions, blocks, and compact blocks with each other.
- Nodes now announce compact block version 3 support, informing peers that they can provide MWEB data
in compact blocks.
Updated RPCs
------------
- `getblockheader` now returns an additional `mweb_header` field containing
all of the MWEB header data, and an `mweb_amount` field containing the total
number of coins pegged-in to the MWEB after applying the block.
- `getblock` now returns an additional `mweb` field containing MWEB header info,
and all of the inputs, outputs, and kernels in the MWEB block.
- Added `mwebweight`, `descendantmwebweight`, `ancestormwebweight`, and `mweb`
fields to `getrawmempool`, `getmempoolancestors`, `getmempooldescendants`,
and `getmempoolentry`.
- Added new fields to describe MWEB transaction inputs, outputs, and kernels
for `getrawtransaction`.
Changes to Wallet or GUI related RPCs can be found in the GUI or Wallet section below.
New settings
------------
- Added "fMWEBFeatures" option for enabling the new "Advanced MWEB Features"
control.
Wallet Database
---------------
- Added "mweb_coin" type which stores MWEB coins and their derived keys.
- Added CHDChain version 4 which includes an MWEB key index counter and
the stealth address scan key.
- Added CKeyMetadata version 14 which includes the MWEB key index.
- Added FEATURE_MWEB = 210000 minimum database version.
Wallet RPC changes
------------------
- Added 'listwallettransactions' which matches the transaction list display values.
GUI changes
-----------
- Added an "Advanced MWEB Features" control for testing. Its only available
when the "-debug" argument is supplied, and the option is turned on in the
settings dialog.
Credits
=======
Thanks to everyone who directly contributed to this release:
- [The Bitcoin Core Developers]
- DavidBurkett
- hectorchu
- losh11

View File

@ -1,203 +1,120 @@
0.21.1 Release Notes
====================
Litecoin Core version 0.21.2 is now available from:
Bitcoin Core version 0.21.1 is now available from:
<https://download.litecoin.org/litecoin-0.21.2/>.
<https://bitcoincore.org/bin/bitcoin-core-0.21.1/>
This minor release includes various bug fixes and performance
improvements, as well as updated translations.
This is the largest update ever, providing full node, wallet, and mining support for MWEB.
Please report bugs using the issue tracker at GitHub:
<https://github.com/bitcoin/bitcoin/issues>
<https://github.com/litecoin-project/litecoin/issues>
To receive security and update notifications, please subscribe to:
<https://bitcoincore.org/en/list/announcements/join/>
<https://groups.google.com/forum/#!forum/litecoin-dev>
How to Upgrade
How to upgrade:
==============
If you are running an older version, shut it down. Wait until it has completely
shut down (which might take a few minutes in some cases), then run the
installer (on Windows) or just copy over `/Applications/Bitcoin-Qt` (on Mac)
or `bitcoind`/`bitcoin-qt` (on Linux).
Firstly, thank you for running Litecoin Core and helping secure the network!
Upgrading directly from a version of Bitcoin Core that has reached its EOL is
possible, but it might take some time if the data directory needs to be migrated. Old
wallet versions of Bitcoin Core are generally supported.
As youre running an older version of Litecoin Core, shut it down. Wait until its completely shut down - which might take a few minutes for older versions - then follow these simple steps:
For Windows: simply run the installer
For Mac: copy over to `/Applications/Litecoin-Qt`
For Linux: copy cover `litecoind`/`litecoin-qt`.
Compatibility
NB: upgrading directly from an end of life version of Litecoin Core is possible, but it might take a while if the data directory needs to be migrated. Old wallet versions of Litecoin Core are generally supported.
Compatibility:
==============
Bitcoin Core is supported and extensively tested on operating systems
using the Linux kernel, macOS 10.14+, and Windows 7 and newer. Bitcoin
Core should also work on most other Unix-like systems but is not as
frequently tested on them. It is not recommended to use Bitcoin Core on
unsupported systems.
Litecoin Core is supported and extensively tested on operating systems using the Linux kernel, macOS 10.10+, Windows 7 and newer. Its not recommended to use Litecoin Core on unsupported systems.
From Bitcoin Core 0.22.0 onwards, macOS versions earlier than 10.14 are no
longer supported. Additionally, Bitcoin Core does not yet change appearance
when macOS "dark mode" is activated.
Litecoin Core should also work on most other Unix-like systems, but is not as frequently tested on them.
MWEB fields added to BlockIndex, and block serialization format has changed. Downgrading to older versions is unsafe.
If upgrading to 0.21.2 *after* MWEB has activated, you must resync to download MWEB blocks.
Notable changes
===============
## Taproot Soft Fork
Consensus changes
-----------------
Included in this release are the mainnet and testnet activation
parameters for the taproot soft fork (BIP341) which also adds support
for schnorr signatures (BIP340) and tapscript (BIP342).
- This release implements the proposed MWEB consensus rules
([LIP002](https://github.com/litecoin-project/lips/blob/master/lip-0002.mediawiki),
[LIP003](https://github.com/litecoin-project/lips/blob/master/lip-0003.mediawiki), and
[LIP004](https://github.com/litecoin-project/lips/blob/master/lip-0004.mediawiki))
If activated, these improvements will allow users of single-signature
scripts, multisignature scripts, and complex contracts to all use
identical-appearing commitments that enhance their privacy and the
fungibility of all bitcoins. Spenders will enjoy lower fees and the
ability to resolve many multisig scripts and complex contracts with the
same efficiency, low fees, and large anonymity set as single-sig users.
Taproot and schnorr also include efficiency improvements for full nodes
such as the ability to batch signature verification. Together, the
improvements lay the groundwork for future potential
upgrades that may improve efficiency, privacy, and fungibility further.
P2P and network changes
-----------------------
Activation for taproot is being managed using a variation of BIP9
versionbits called Speedy Trial (described in BIP341). Taproot's
versionbit is bit 2, and nodes will begin tracking which blocks signal
support for taproot at the beginning of the first retarget period after
taproots start date of 24 April 2021. If 90% of blocks within a
2,016-block retarget period (about two weeks) signal support for taproot
prior to the first retarget period beginning after the time of 11 August
2021, the soft fork will be locked in, and taproot will then be active
as of block 709632 (expected in early or mid November).
- A new service flag, NODE_MWEB (1 << 24), was added to signal to peers that the node supports MWEB.
When connected peers both advertise this capability, they are expected to provide all MWEB data when
sharing transactions, blocks, and compact blocks with each other.
Should taproot not be locked in via Speedy Trial activation, it is
expected that a follow-up activation mechanism will be deployed, with
changes to address the reasons the Speedy Trial method failed.
- Nodes now announce compact block version 3 support, informing peers that they can provide MWEB data
in compact blocks.
This release includes the ability to pay taproot addresses, although
payments to such addresses are not secure until taproot activates.
It also includes the ability to relay and mine taproot transactions
after activation. Beyond those two basic capabilities, this release
does not include any code that allows anyone to directly use taproot.
The addition of taproot-related features to Bitcoin Core's wallet is
expected in later releases once taproot activation is assured.
All users, businesses, and miners are encouraged to upgrade to this
release (or a subsequent compatible release) unless they object to
activation of taproot. If taproot is locked in, then upgrading before
block 709632 is highly recommended to help enforce taproot's new rules
and to avoid the unlikely case of seeing falsely confirmed transactions.
Miners who want to activate Taproot should preferably use this release
to control their signaling. The `getblocktemplate` RPC results will
automatically be updated to signal once the appropriate start has been
reached and continue signaling until the timeout occurs or taproot
activates. Alternatively, miners may manually start signaling on bit 2
at any time; if taproot activates, they will need to ensure they update
their nodes before block 709632 or non-upgraded nodes could cause them to mine on
an invalid chain. See the [versionbits
FAQ](https://bitcoincore.org/en/2016/06/08/version-bits-miners-faq/) for
details.
For more information about taproot, please see the following resources:
- Technical specifications
- [BIP340 Schnorr signatures for secp256k1](https://github.com/bitcoin/bips/blob/master/bip-0340.mediawiki)
- [BIP341 Taproot: SegWit version 1 spending rules](https://github.com/bitcoin/bips/blob/master/bip-0341.mediawiki)
- [BIP342 Validation of Taproot scripts](https://github.com/bitcoin/bips/blob/master/bip-0342.mediawiki)
- Popular articles;
- [Taproot Is Coming: What It Is, and How It Will Benefit Bitcoin](https://bitcoinmagazine.com/technical/taproot-coming-what-it-and-how-it-will-benefit-bitcoin)
- [What do Schnorr Signatures Mean for Bitcoin?](https://academy.binance.com/en/articles/what-do-schnorr-signatures-mean-for-bitcoin)
- [The Schnorr Signature & Taproot Softfork Proposal](https://blog.bitmex.com/the-schnorr-signature-taproot-softfork-proposal/)
- Development history overview
- [Taproot](https://bitcoinops.org/en/topics/taproot/)
- [Schnorr signatures](https://bitcoinops.org/en/topics/schnorr-signatures/)
- [Tapscript](https://bitcoinops.org/en/topics/tapscript/)
- [Soft fork activation](https://bitcoinops.org/en/topics/soft-fork-activation/)
- Other
- [Questions and answers related to taproot](https://bitcoin.stackexchange.com/questions/tagged/taproot)
- [Taproot review](https://github.com/ajtowns/taproot-review)
Updated RPCs
------------
- Due to [BIP 350](https://github.com/bitcoin/bips/blob/master/bip-0350.mediawiki)
being implemented, behavior for all RPCs that accept addresses is changed when
a native witness version 1 (or higher) is passed. These now require a Bech32m
encoding instead of a Bech32 one, and Bech32m encoding will be used for such
addresses in RPC output as well. No version 1 addresses should be created
for mainnet until consensus rules are adopted that give them meaning
(e.g. through [BIP 341](https://github.com/bitcoin/bips/blob/master/bip-0341.mediawiki)).
Once that happens, Bech32m is expected to be used for them, so this shouldn't
affect any production systems, but may be observed on other networks where such
addresses already have meaning (like signet).
- `getblockheader` now returns an additional `mweb_header` field containing
all of the MWEB header data, and an `mweb_amount` field containing the total
number of coins pegged-in to the MWEB after applying the block.
0.21.1 change log
=================
- `getblock` now returns an additional `mweb` field containing MWEB header info,
and all of the inputs, outputs, and kernels in the MWEB block.
### Consensus
- #21377 Speedy trial support for versionbits (ajtowns)
- #21686 Speedy trial activation parameters for Taproot (achow101)
- Added `mwebweight`, `descendantmwebweight`, `ancestormwebweight`, and `mweb`
fields to `getrawmempool`, `getmempoolancestors`, `getmempooldescendants`,
and `getmempoolentry`.
### P2P protocol and network code
- #20852 allow CSubNet of non-IP networks (vasild)
- #21043 Avoid UBSan warning in ProcessMessage(…) (practicalswift)
- Added new fields to describe MWEB transaction inputs, outputs, and kernels
for `getrawtransaction`.
### Wallet
- #21166 Introduce DeferredSignatureChecker and have SignatureExtractorClass subclass it (achow101)
- #21083 Avoid requesting fee rates multiple times during coin selection (achow101)
Changes to Wallet or GUI related RPCs can be found in the GUI or Wallet section below.
### RPC and other APIs
- #21201 Disallow sendtoaddress and sendmany when private keys disabled (achow101)
New settings
------------
### Build system
- #21486 link against -lsocket if required for `*ifaddrs` (fanquake)
- #20983 Fix MSVC build after gui#176 (hebasto)
- Added "fMWEBFeatures" option for enabling the new "Advanced MWEB Features"
control.
### Tests and QA
- #21380 Add fuzzing harness for versionbits (ajtowns)
- #20812 fuzz: Bump FuzzedDataProvider.h (MarcoFalke)
- #20740 fuzz: Update FuzzedDataProvider.h from upstream (LLVM) (practicalswift)
- #21446 Update vcpkg checkout commit (sipsorcery)
- #21397 fuzz: Bump FuzzedDataProvider.h (MarcoFalke)
- #21081 Fix the unreachable code at `feature_taproot` (brunoerg)
- #20562 Test that a fully signed tx given to signrawtx is unchanged (achow101)
- #21571 Make sure non-IP peers get discouraged and disconnected (vasild, MarcoFalke)
- #21489 fuzz: cleanups for versionbits fuzzer (ajtowns)
Wallet Database
---------------
### Miscellaneous
- #20861 BIP 350: Implement Bech32m and use it for v1+ segwit addresses (sipa)
- Added "mweb_coin" type which stores MWEB coins and their derived keys.
- Added CHDChain version 4 which includes an MWEB key index counter and
the stealth address scan key.
- Added CKeyMetadata version 14 which includes the MWEB key index.
- Added FEATURE_MWEB = 210000 minimum database version.
Wallet RPC changes
------------------
- Added 'listwallettransactions' which matches the transaction list display values.
GUI changes
-----------
- Added an "Advanced MWEB Features" control for testing. Its only available
when the "-debug" argument is supplied, and the option is turned on in the
settings dialog.
### Documentation
- #21384 add signet to bitcoin.conf documentation (jonatack)
- #21342 Remove outdated comment (hebasto)
Credits
=======
Thanks to everyone who directly contributed to this release:
- Aaron Clauson
- Andrew Chow
- Anthony Towns
- Bruno Garcia
- Fabian Jahr
- fanquake
- Hennadii Stepanov
- Jon Atack
- Luke Dashjr
- MarcoFalke
- Pieter Wuille
- practicalswift
- randymcmillan
- Sjors Provoost
- Vasil Dimov
- W. J. van der Laan
As well as to everyone that helped with translations on
[Transifex](https://www.transifex.com/bitcoin/bitcoin/).
- [The Bitcoin Core Developers]
- DavidBurkett
- hectorchu
- losh11

View File

@ -8,11 +8,12 @@
#include <stdlib.h>
#include <stdint.h>
#include <mw/consensus/Params.h>
/** The maximum allowed size for a serialized block, in bytes (only for buffer size limits) */
static const unsigned int MAX_BLOCK_SERIALIZED_SIZE = 4000000;
/** MWEB: The maximum size of an MWEB block is just over 11 MB, plus 4 MB for a full segwit block. Add a ~1 MB buffer just to be safe. */
static const unsigned int MAX_BLOCK_SERIALIZED_SIZE_WITH_MWEB = 16'000'000;
static const unsigned int MAX_BLOCK_SERIALIZED_SIZE_WITH_MWEB = MAX_BLOCK_SERIALIZED_SIZE + mw::MAX_BLOCK_BYTES;
/** The maximum allowed weight for a block, see BIP 141 (network rule) */
static const unsigned int MAX_BLOCK_WEIGHT = 4000000;
/** The maximum allowed number of signature check operations in a block (network rule) */

View File

@ -195,7 +195,7 @@ public:
auto output_type = OutputType::BECH32;
auto reserve_dest = std::make_shared<ReserveDestination>(m_wallet.get(), output_type);
if (reserve_dest->GetReservedDestination(dest, true)) {
if (reserve_dest->GetReservedDestination(dest, false)) {
return reserve_dest;
}

View File

@ -10,6 +10,23 @@ MW_NAMESPACE
/// Consensus parameters
/// Any change to these will cause a hardfork!
/// </summary>
static constexpr std::size_t MAX_BLOCK_WEIGHT = 21'000;
static constexpr size_t BYTES_PER_WEIGHT = 42;
static constexpr size_t BASE_KERNEL_WEIGHT = 2;
static constexpr size_t STEALTH_EXCESS_WEIGHT = 1;
static constexpr size_t KERNEL_WITH_STEALTH_WEIGHT = BASE_KERNEL_WEIGHT + STEALTH_EXCESS_WEIGHT;
static constexpr size_t BASE_OUTPUT_WEIGHT = 17;
static constexpr size_t STANDARD_OUTPUT_FIELDS_WEIGHT = 1;
static constexpr size_t STANDARD_OUTPUT_WEIGHT = BASE_OUTPUT_WEIGHT + STANDARD_OUTPUT_FIELDS_WEIGHT;
static constexpr size_t MAX_NUM_INPUTS = 50'000;
static constexpr size_t INPUT_BYTES = 196;
static constexpr std::size_t MAX_BLOCK_WEIGHT = 200'000; // Nodes won't accept blocks over this weight
static constexpr std::size_t MAX_MINE_WEIGHT = 20'000; // Miners won't create blocks over this weight. Non-consensus
static constexpr size_t MAX_BLOCK_BYTES = 180 + (3 * 5) + // 180 bytes per header and 5 bytes each for input, output, and kernel vec size
(MAX_NUM_INPUTS * INPUT_BYTES) + // 50k inputs at 196 bytes each (ignoring extradata)
(MAX_BLOCK_WEIGHT * 60); // Ignoring inputs, no tx component is ever more than 60 bytes per unit of weight
END_NAMESPACE

View File

@ -8,22 +8,6 @@
class Weight
{
public:
static constexpr size_t BYTES_PER_WEIGHT = 42;
static constexpr size_t BASE_KERNEL_WEIGHT = 2;
static constexpr size_t STEALTH_EXCESS_WEIGHT = 1;
static constexpr size_t KERNEL_WITH_STEALTH_WEIGHT = BASE_KERNEL_WEIGHT + STEALTH_EXCESS_WEIGHT;
static constexpr size_t BASE_OUTPUT_WEIGHT = 17;
static constexpr size_t STANDARD_OUTPUT_FIELDS_WEIGHT = 1;
static constexpr size_t STANDARD_OUTPUT_WEIGHT = BASE_OUTPUT_WEIGHT + STANDARD_OUTPUT_FIELDS_WEIGHT;
static constexpr size_t MAX_NUM_INPUTS = 50'000;
static constexpr size_t INPUT_BYTES = 196;
static constexpr size_t MAX_MWEB_BYTES = 180 + (3 * 5) + // 180 bytes per header and 5 bytes each for input, output, and kernel vec size
(MAX_NUM_INPUTS * INPUT_BYTES) + // 50k inputs at 196 bytes each (ignoring extradata)
(mw::MAX_BLOCK_WEIGHT * 60); // Ignoring inputs, no tx component is ever more than 60 bytes per unit of weight
static size_t Calculate(const TxBody& tx_body)
{
size_t input_weight = std::accumulate(
@ -57,7 +41,7 @@ public:
static bool ExceedsMaximum(const TxBody& tx_body)
{
return tx_body.GetInputs().size() > MAX_NUM_INPUTS || Calculate(tx_body) > mw::MAX_BLOCK_WEIGHT;
return tx_body.GetInputs().size() > mw::MAX_NUM_INPUTS || Calculate(tx_body) > mw::MAX_BLOCK_WEIGHT;
}
static size_t CalcInputWeight(const std::vector<uint8_t>& extra_data)
@ -71,7 +55,7 @@ public:
const std::vector<uint8_t>& extra_data = {})
{
// Kernels with a stealth excess cost extra.
size_t base_weight = has_stealth_excess ? KERNEL_WITH_STEALTH_WEIGHT : BASE_KERNEL_WEIGHT;
size_t base_weight = has_stealth_excess ? mw::KERNEL_WITH_STEALTH_WEIGHT : mw::BASE_KERNEL_WEIGHT;
return base_weight + ExtraBytesToWeight(pegout_script.size()) + ExtraBytesToWeight(extra_data.size());
}
@ -82,7 +66,7 @@ public:
const std::vector<uint8_t>& extra_data = {})
{
// Kernels with a stealth excess cost extra.
size_t base_weight = has_stealth_excess ? KERNEL_WITH_STEALTH_WEIGHT : BASE_KERNEL_WEIGHT;
size_t base_weight = has_stealth_excess ? mw::KERNEL_WITH_STEALTH_WEIGHT : mw::BASE_KERNEL_WEIGHT;
size_t pegout_weight = std::accumulate(
pegouts.begin(), pegouts.end(), (size_t)0,
@ -97,13 +81,13 @@ public:
// Outputs have a weight of 'BASE_OUTPUT_WEIGHT' plus 2 weight for standard fields, and 1 weight for every 'BYTES_PER_WEIGHT' extra_data bytes
static size_t CalcOutputWeight(const bool standard_fields, const std::vector<uint8_t>& extra_data = {})
{
size_t base_weight = standard_fields ? STANDARD_OUTPUT_WEIGHT : BASE_OUTPUT_WEIGHT;
size_t base_weight = standard_fields ? mw::STANDARD_OUTPUT_WEIGHT : mw::BASE_OUTPUT_WEIGHT;
return base_weight + ExtraBytesToWeight(extra_data.size());
}
private:
static size_t ExtraBytesToWeight(const size_t extra_bytes)
{
return (extra_bytes + (BYTES_PER_WEIGHT - 1)) / BYTES_PER_WEIGHT;
return (extra_bytes + (mw::BYTES_PER_WEIGHT - 1)) / mw::BYTES_PER_WEIGHT;
}
};

View File

@ -52,7 +52,7 @@ mw::Transaction::CPtr TxBuilder::BuildTx(
.Sub(kernel_offset)
.Total();
// MW: TODO - This is only needed for peg-ins or when no change
// MW: FUTURE - This is only needed for peg-ins or when no change
SecretKey stealth_blind = SecretKey::Random();
// Create the kernel

View File

@ -60,50 +60,50 @@ static std::vector<Kernel> CreateKernels(const size_t plain_kernels, const size_
BOOST_AUTO_TEST_CASE(ExceedsMaximum)
{
BOOST_CHECK(Weight::MAX_NUM_INPUTS == 50'000);
BOOST_CHECK(Weight::BASE_KERNEL_WEIGHT == 2);
BOOST_CHECK(Weight::KERNEL_WITH_STEALTH_WEIGHT == 3);
BOOST_CHECK(Weight::BASE_OUTPUT_WEIGHT == 17);
BOOST_CHECK(Weight::STANDARD_OUTPUT_WEIGHT == 18);
BOOST_CHECK(Weight::BYTES_PER_WEIGHT == 42);
BOOST_CHECK(mw::MAX_BLOCK_WEIGHT == 21'000);
BOOST_CHECK(mw::MAX_NUM_INPUTS == 50'000);
BOOST_CHECK(mw::BASE_KERNEL_WEIGHT == 2);
BOOST_CHECK(mw::KERNEL_WITH_STEALTH_WEIGHT == 3);
BOOST_CHECK(mw::BASE_OUTPUT_WEIGHT == 17);
BOOST_CHECK(mw::STANDARD_OUTPUT_WEIGHT == 18);
BOOST_CHECK(mw::BYTES_PER_WEIGHT == 42);
BOOST_CHECK(mw::MAX_BLOCK_WEIGHT == 200'000);
// 1,000 outputs + 1,000 stealth kernels = 21,000 Weight
// 10,000 outputs + 10,000 plain kernels = 200,000 Weight
{
std::vector<Input> inputs(Weight::MAX_NUM_INPUTS);
std::vector<Output> outputs = CreateStandardOutputs(1000);
std::vector<Kernel> kernels = CreateKernels(0, 1000);
std::vector<Input> inputs(mw::MAX_NUM_INPUTS);
std::vector<Output> outputs = CreateStandardOutputs(10'000);
std::vector<Kernel> kernels = CreateKernels(10'000, 0);
TxBody tx(inputs, outputs, kernels);
BOOST_CHECK(Weight::Calculate(tx) == 21'000);
BOOST_CHECK(Weight::Calculate(tx) == 200'000);
BOOST_CHECK(!Weight::ExceedsMaximum(tx));
}
// 50,000 inputs max, so 50,001 should exceed maximum
{
std::vector<Input> inputs(Weight::MAX_NUM_INPUTS + 1);
std::vector<Output> outputs = CreateStandardOutputs(1000);
std::vector<Kernel> kernels = CreateKernels(0, 1000);
std::vector<Input> inputs(mw::MAX_NUM_INPUTS + 1);
std::vector<Output> outputs = CreateStandardOutputs(10'000);
std::vector<Kernel> kernels = CreateKernels(10'000, 0);
BOOST_CHECK(inputs.size() == 50'001);
TxBody tx(inputs, outputs, kernels);
BOOST_CHECK(Weight::Calculate(tx) == 21'000);
BOOST_CHECK(Weight::Calculate(tx) == 200'000);
BOOST_CHECK(Weight::ExceedsMaximum(tx));
}
// 1,000 outputs + 1,000 stealth kernels and 1 plain kernel = 21,002 Weight
// 10,000 outputs + 10,000 plain kernels and 1 stealth kernel = 200,003 Weight
{
std::vector<Input> inputs(Weight::MAX_NUM_INPUTS);
std::vector<Output> outputs = CreateStandardOutputs(1000);
std::vector<Kernel> kernels = CreateKernels(1, 1000);
std::vector<Input> inputs(mw::MAX_NUM_INPUTS);
std::vector<Output> outputs = CreateStandardOutputs(10'000);
std::vector<Kernel> kernels = CreateKernels(10'000, 1);
BOOST_CHECK(inputs.size() == 50'000);
TxBody tx(inputs, outputs, kernels);
BOOST_CHECK(Weight::Calculate(tx) == 21'002);
BOOST_CHECK(Weight::Calculate(tx) == 200'003);
BOOST_CHECK(Weight::ExceedsMaximum(tx));
}

View File

@ -220,7 +220,7 @@ bool BlockAssembler::TestPackage(uint64_t packageSize, int64_t packageSigOpsCost
return false;
if (nBlockSigOpsCost + packageSigOpsCost >= MAX_BLOCK_SIGOPS_COST)
return false;
if (nBlockMWEBWeight + packageMWEBWeight >= mw::MAX_BLOCK_WEIGHT)
if (nBlockMWEBWeight + packageMWEBWeight >= mw::MAX_MINE_WEIGHT)
return false;
return true;
}

View File

@ -68,11 +68,11 @@ uint64_t MWEB::CalcMWEBWeight(const MWEB::TxType& mweb_type, const bool change_o
uint64_t mweb_weight = 0;
if (mweb_type == MWEB::TxType::PEGIN || mweb_type == MWEB::TxType::MWEB_TO_MWEB) {
mweb_weight += Weight::STANDARD_OUTPUT_WEIGHT; // MW: FUTURE - Look at actual recipients list, but for now we only support 1 MWEB recipient.
mweb_weight += mw::STANDARD_OUTPUT_WEIGHT; // MW: FUTURE - Look at actual recipients list, but for now we only support 1 MWEB recipient.
}
if (change_on_mweb) {
mweb_weight += Weight::STANDARD_OUTPUT_WEIGHT;
mweb_weight += mw::STANDARD_OUTPUT_WEIGHT;
}
if (mweb_type != MWEB::TxType::LTC_TO_LTC) {
@ -134,8 +134,8 @@ void Transact::AddMWEBTx(InProcessTx& new_tx)
[](CAmount amt, const CInputCoin& input) { return amt + (input.IsMWEB() ? 0 : input.GetAmount()); }
);
if (ltc_input_amount > 0) {
assert(new_tx.total_fee < ltc_input_amount);
const CAmount ltc_fee = new_tx.total_fee - new_tx.mweb_fee;
assert(ltc_fee <= ltc_input_amount);
pegin_amount = (ltc_input_amount - (ltc_fee + ltc_change));
}

View File

@ -7,7 +7,7 @@
#include <tinyformat.h>
static const CAmount BASE_MWEB_FEE = 1'000;
static const CAmount BASE_MWEB_FEE = 100;
CFeeRate::CFeeRate(const CAmount& nFeePaid, size_t nBytes_, uint64_t mweb_weight)
: m_nFeePaid(nFeePaid), m_nBytes(nBytes_), m_weight(mweb_weight)

View File

@ -49,7 +49,7 @@ static const unsigned int MAX_STANDARD_P2WSH_SCRIPT_SIZE = 3600;
* standard and should be done with care and ideally rarely. It makes sense to
* only increase the dust limit after prior releases were already not creating
* outputs below the new threshold */
static const unsigned int DUST_RELAY_TX_FEE = 3000;
static const unsigned int DUST_RELAY_TX_FEE = 30'000;
/**
* Standard script verification flags that standard transactions will comply
* with. However scripts violating these flags may still be present in valid

View File

@ -136,6 +136,10 @@ OptionsDialog::OptionsDialog(QWidget *parent, bool enableWallet) :
ui->minimizeToTray->setEnabled(false);
}
if (!gArgs.IsArgSet("-debug")) {
ui->mwebFeatures->setVisible(false);
}
GUIUtil::handleCloseWindowShortcut(this);
}

View File

@ -82,7 +82,7 @@ void OptionsModel::Init(bool resetSettings)
if (!settings.contains("fMWEBFeatures"))
settings.setValue("fMWEBFeatures", false);
fMWEBFeatures = settings.value("fMWEBFeatures", false).toBool();
fMWEBFeatures = settings.value("fMWEBFeatures", false).toBool() && gArgs.IsArgSet("-debug");
// These are shared with the core or have a command-line parameter
// and we want command-line parameters to overwrite the GUI settings.

View File

@ -267,7 +267,6 @@ QString TransactionDesc::toHTML_Amounts(interfaces::Wallet& wallet, const interf
strHTML += "<br>";
}
}
// MW: TODO - Pegouts?
strHTML += "<b>" + tr("Debit") + ":</b> " + BitcoinUnits::formatHtmlWithUnit(unit, -txout.nValue) + "<br>";
if (toSelf)
@ -304,6 +303,8 @@ QString TransactionDesc::toHTML_Amounts(interfaces::Wallet& wallet, const interf
if (fAllToMe) {
// Payment to self
CAmount nValue = wtx.credit - wtx.change;
strHTML += "<b>" + tr("Credit") + ":</b> " + BitcoinUnits::formatHtmlWithUnit(unit, wtx.credit) + "<br>";
strHTML += "<b>" + tr("Change") + ":</b> " + BitcoinUnits::formatHtmlWithUnit(unit, wtx.change) + "<br>";
strHTML += "<b>" + tr("Total debit") + ":</b> " + BitcoinUnits::formatHtmlWithUnit(unit, -nValue) + "<br>";
strHTML += "<b>" + tr("Total credit") + ":</b> " + BitcoinUnits::formatHtmlWithUnit(unit, nValue) + "<br>";
}

View File

@ -651,7 +651,7 @@ public:
};
/** A parsed mweb descriptor. */
class MWEBDescriptor final : public DescriptorImpl // MW: TODO - Finish this
class MWEBDescriptor final : public DescriptorImpl
{
SecretKey m_scanSecret;
@ -894,7 +894,7 @@ std::unique_ptr<DescriptorImpl> ParseScript(uint32_t key_exp_index, Span<const c
if (Func("mweb", expr)) {
auto pubkey = ParsePubkey(key_exp_index, expr, false, out, error);
if (!pubkey) return nullptr;
return MakeUnique<MWEBDescriptor>(std::move(pubkey), SecretKey::Null()); // MW: TODO - Lookup scan_secret
return MakeUnique<MWEBDescriptor>(std::move(pubkey), SecretKey::Null());
}
if (ctx == ParseScriptContext::TOP && Func("combo", expr)) {
auto pubkey = ParsePubkey(key_exp_index, expr, true, out, error);
@ -1135,7 +1135,6 @@ std::string GetDescriptorChecksum(const std::string& descriptor)
std::unique_ptr<Descriptor> InferDescriptor(const DestinationAddr& script, const SigningProvider& provider)
{
if (script.IsMWEB()) {
// MW: TODO - Lookup scan_secret
CPubKey pubkey(script.GetMWEBAddress().GetSpendPubKey().vec());
return MakeUnique<MWEBDescriptor>(InferPubkey(pubkey, ParseScriptContext::TOP, provider), SecretKey::Null());
}

View File

@ -674,7 +674,7 @@ BOOST_AUTO_TEST_CASE(test_IsStandard)
// Check dust with default relay fee:
CAmount nDustThreshold = 182 * dustRelayFee.GetFeePerK()/1000;
BOOST_CHECK_EQUAL(nDustThreshold, 546);
BOOST_CHECK_EQUAL(nDustThreshold, 5460);
// dust:
t.vout[0].nValue = nDustThreshold - 1;
reason.clear();

View File

@ -1728,6 +1728,8 @@ void LegacyScriptPubKeyMan::LoadMWEBKeychain()
return;
}
m_storage.SetMinVersion(FEATURE_MWEB);
// try to get the seed
CKey seed;
if (!GetKey(m_hd_chain.seed_id, seed)) {

View File

@ -35,6 +35,10 @@ AssembledTx TxAssembler::CreateTransaction(
{
VerifyRecipients(recipients);
if (boost::get<StealthAddress>(&coin_control.destChange)) {
throw CreateTxError(_("Custom MWEB change addresses not yet supported"));
}
InProcessTx new_tx;
new_tx.recipients = recipients;
new_tx.recipient_amount = std::accumulate(
@ -398,8 +402,8 @@ bool TxAssembler::AttemptCoinSelection(InProcessTx& new_tx, const CAmount& nTarg
// First try to construct an MWEB-to-MWEB transaction
CoinSelectionParams mweb_to_mweb = new_tx.coin_selection_params;
mweb_to_mweb.input_preference = InputPreference::MWEB_ONLY;
mweb_to_mweb.mweb_change_output_weight = Weight::STANDARD_OUTPUT_WEIGHT;
mweb_to_mweb.mweb_nochange_weight = Weight::KERNEL_WITH_STEALTH_WEIGHT + (new_tx.recipients.size() * Weight::STANDARD_OUTPUT_WEIGHT);
mweb_to_mweb.mweb_change_output_weight = mw::STANDARD_OUTPUT_WEIGHT;
mweb_to_mweb.mweb_nochange_weight = mw::KERNEL_WITH_STEALTH_WEIGHT + (new_tx.recipients.size() * mw::STANDARD_OUTPUT_WEIGHT);
mweb_to_mweb.change_output_size = 0;
mweb_to_mweb.change_spend_size = 0;
mweb_to_mweb.tx_noinputs_size = 0;
@ -412,8 +416,8 @@ bool TxAssembler::AttemptCoinSelection(InProcessTx& new_tx, const CAmount& nTarg
const bool change_on_mweb = MWEB::IsChangeOnMWEB(m_wallet, MWEB::TxType::PEGIN, new_tx.recipients, new_tx.coin_control.destChange);
CoinSelectionParams params_pegin = new_tx.coin_selection_params;
params_pegin.input_preference = InputPreference::ANY;
params_pegin.mweb_change_output_weight = change_on_mweb ? Weight::STANDARD_OUTPUT_WEIGHT : 0;
params_pegin.mweb_nochange_weight = Weight::KERNEL_WITH_STEALTH_WEIGHT + (new_tx.recipients.size() * Weight::STANDARD_OUTPUT_WEIGHT);
params_pegin.mweb_change_output_weight = change_on_mweb ? mw::STANDARD_OUTPUT_WEIGHT : 0;
params_pegin.mweb_nochange_weight = mw::KERNEL_WITH_STEALTH_WEIGHT + (new_tx.recipients.size() * mw::STANDARD_OUTPUT_WEIGHT);
params_pegin.change_output_size = change_on_mweb ? 0 : new_tx.coin_selection_params.change_output_size;
params_pegin.change_spend_size = change_on_mweb ? 0 : new_tx.coin_selection_params.change_spend_size;
@ -439,7 +443,7 @@ bool TxAssembler::AttemptCoinSelection(InProcessTx& new_tx, const CAmount& nTarg
// If LTC-to-LTC fails, create a peg-out transaction
CoinSelectionParams params_pegout = new_tx.coin_selection_params;
params_pegout.input_preference = InputPreference::ANY;
params_pegout.mweb_change_output_weight = Weight::STANDARD_OUTPUT_WEIGHT;
params_pegout.mweb_change_output_weight = mw::STANDARD_OUTPUT_WEIGHT;
params_pegout.mweb_nochange_weight = Weight::CalcKernelWeight(true, new_tx.recipients.front().GetScript());
params_pegout.change_output_size = 0;
params_pegout.change_spend_size = 0;

View File

@ -2236,7 +2236,7 @@ void CWallet::ReacceptWalletTransactions()
int nDepth = wtx.GetDepthInMainChain();
if (!wtx.IsCoinBase() && (nDepth == 0 && !wtx.isAbandoned())) {
if (!wtx.IsCoinBase() && !wtx.IsHogEx() && (nDepth == 0 && !wtx.isAbandoned())) {
mapSorted.insert(std::make_pair(wtx.nOrderPos, &wtx));
}
}
@ -4631,7 +4631,7 @@ const CWalletTx* CWallet::FindWalletTxByKernelId(const mw::Hash& kernel_id) cons
{
LOCK(cs_wallet);
auto kernel_iter = mapKernelsMWEB.find(kernel_id);
if (kernel_iter != mapOutputsMWEB.end()) {
if (kernel_iter != mapKernelsMWEB.end()) {
auto tx_iter = mapWallet.find(kernel_iter->second);
if (tx_iter != mapWallet.end()) {
return &tx_iter->second;

View File

@ -63,11 +63,11 @@ std::unique_ptr<WalletDatabase> MakeWalletDatabase(const std::string& name, cons
//! -paytxfee default
constexpr CAmount DEFAULT_PAY_TX_FEE = 0;
//! -fallbackfee default
static const CAmount DEFAULT_FALLBACK_FEE = 0;
static const CAmount DEFAULT_FALLBACK_FEE = 200'000;
//! -discardfee default
static const CAmount DEFAULT_DISCARD_FEE = 10000;
static const CAmount DEFAULT_DISCARD_FEE = 10'000;
//! -mintxfee default
static const CAmount DEFAULT_TRANSACTION_MINFEE = 1000;
static const CAmount DEFAULT_TRANSACTION_MINFEE = 10'000;
/**
* maximum fee increase allowed to do partial spend avoidance, even for nodes with this feature disabled by default
*

View File

@ -26,7 +26,9 @@ enum WalletFeature
FEATURE_PRE_SPLIT_KEYPOOL = 169900, // Upgraded to HD SPLIT and can have a pre-split keypool
FEATURE_LATEST = FEATURE_PRE_SPLIT_KEYPOOL
FEATURE_MWEB = 210000, // Wallet with MWEB keys and coins
FEATURE_LATEST = FEATURE_MWEB
};
bool IsFeatureSupported(int wallet_version, int feature_version);

View File

@ -36,7 +36,7 @@ class MaxUploadTest(BitcoinTestFramework):
self.setup_clean_chain = True
self.num_nodes = 1
self.extra_args = [[
"-maxuploadtarget=3200",
"-maxuploadtarget=6400",
"-acceptnonstdtxn=1",
"-peertimeout=9999", # bump because mocktime might cause a disconnect otherwise
]]
@ -90,8 +90,8 @@ class MaxUploadTest(BitcoinTestFramework):
getdata_request = msg_getdata()
getdata_request.inv.append(CInv(MSG_BLOCK, big_old_block))
max_bytes_per_day = 3200*1024*1024
daily_buffer = 144 * 4000000 * 4 # MWEB uses a buffer 4x the max serialized segwit block
max_bytes_per_day = 6400*1024*1024
daily_buffer = 144 * 25800195 # MWEB uses a buffer 4x the max serialized segwit block
max_bytes_available = max_bytes_per_day - daily_buffer
success_count = max_bytes_available // old_block_size

View File

@ -1199,7 +1199,7 @@ class TaprootTest(BitcoinTestFramework):
self.num_nodes = 2
self.setup_clean_chain = True
# Node 0 has Taproot inactive, Node 1 active.
self.extra_args = [["-par=1", "-vbparams=taproot:1:1"], ["-par=1"]]
self.extra_args = [["-par=1", "-dustrelayfee=0.00003", "-mintxfee=0.00001", "-vbparams=taproot:1:1"], ["-par=1", "-dustrelayfee=0.00003", "-mintxfee=0.00001"]]
def block_submit(self, node, txs, msg, err_msg, cb_pubkey=None, fees=0, sigops_weight=0, witness=False, accept=False):

View File

@ -16,6 +16,7 @@ class MempoolLimitTest(BitcoinTestFramework):
self.extra_args = [[
"-acceptnonstdtxn=1",
"-maxmempool=5",
"-mintxfee=0.00001",
"-spendzeroconfchange=0",
]]
self.supports_cli = False

View File

@ -19,6 +19,7 @@ MAX_INITIAL_BROADCAST_DELAY = 15 * 60 # 15 minutes in seconds
class MempoolUnbroadcastTest(BitcoinTestFramework):
def set_test_params(self):
self.num_nodes = 2
self.extra_args = [["-mintxfee=0.00001"]] * self.num_nodes
def skip_test_if_missing_module(self):
self.skip_if_no_wallet()

View File

@ -98,8 +98,8 @@ class MWEBBasicTest(BitcoinTestFramework):
assert_equal(len(utxos), 1)
assert sum(x['amount'] for x in utxos) < 1
self.log.info("Mine 5 blocks. Peg-out maturity is 6 blocks, so coins shouldn't be available yet.")
self.nodes[1].generate(5)
self.log.info("Mine 4 more blocks. Peg-out maturity is 6 blocks, so coins shouldn't be available yet.")
self.nodes[1].generate(4)
self.sync_all()
self.log.info("Check for UTXO on node 1")

View File

@ -81,7 +81,7 @@ class MWEBWalletBasicTest(BitcoinTestFramework):
assert n1_tx2['fee'] < 0 and n1_tx2['fee'] > -0.1
self.log.info("Verify node2's wallet receives the first pegout transaction")
n2_tx2 = node2.gettransaction(txid=tx2_id)
n2_tx2 = node2.listwallettransactions(txid=tx2_id)[0]
assert_equal(n2_tx2['amount'], 15)
assert_equal(n2_tx2['confirmations'], 0)
assert tx2_id in node1.getrawmempool()

View File

@ -31,7 +31,7 @@ class RawTransactionsTest(BitcoinTestFramework):
self.setup_clean_chain = True
# This test isn't testing tx relay. Set whitelist on the peers for
# instant tx relay.
self.extra_args = [['-whitelist=noban@127.0.0.1', '-vbparams=mweb:-2:0']] * self.num_nodes
self.extra_args = [['-whitelist=noban@127.0.0.1', "-mintxfee=0.00001", '-vbparams=mweb:-2:0']] * self.num_nodes
def skip_test_if_missing_module(self):
self.skip_if_no_wallet()

View File

@ -231,7 +231,7 @@ class WalletTest(BitcoinTestFramework):
node_0_bal = self.check_fee_amount(self.nodes[0].getbalance(), node_0_bal + Decimal('10'), fee_per_byte, self.get_vsize(self.nodes[2].gettransaction(txid)['hex']))
self.log.info("Test sendmany with fee_rate param (explicit fee rate in sat/vB)")
fee_rate_sat_vb = 2
fee_rate_sat_vb = 20
fee_rate_btc_kvb = fee_rate_sat_vb * 1e3 / 1e8
explicit_fee_rate_btc_kvb = Decimal(fee_rate_btc_kvb) / 1000
@ -260,12 +260,12 @@ class WalletTest(BitcoinTestFramework):
assert_raises_rpc_error(-8, "Unknown named parameter key", self.nodes[2].sendtoaddress, address=address, amount=1, fee_rate=1, key=1)
# Test setting explicit fee rate just below the minimum.
self.log.info("Test sendmany raises 'fee rate too low' if fee_rate of 0.99999999 is passed")
assert_raises_rpc_error(-6, "Fee rate (0.999 sat/vB) is lower than the minimum fee rate setting (1.000 sat/vB)",
self.nodes[2].sendmany, amounts={address: 10}, fee_rate=0.99999999)
self.log.info("Test sendmany raises 'fee rate too low' if fee_rate of 9.99999999 is passed")
assert_raises_rpc_error(-6, "Fee rate (9.999 sat/vB) is lower than the minimum fee rate setting (10.000 sat/vB)",
self.nodes[2].sendmany, amounts={address: 10}, fee_rate=9.99999999)
self.log.info("Test sendmany raises if fee_rate of 0 or -1 is passed")
assert_raises_rpc_error(-6, "Fee rate (0.000 sat/vB) is lower than the minimum fee rate setting (1.000 sat/vB)",
assert_raises_rpc_error(-6, "Fee rate (0.000 sat/vB) is lower than the minimum fee rate setting (10.000 sat/vB)",
self.nodes[2].sendmany, amounts={address: 10}, fee_rate=0)
assert_raises_rpc_error(-3, OUT_OF_RANGE, self.nodes[2].sendmany, amounts={address: 10}, fee_rate=-1)
@ -415,7 +415,7 @@ class WalletTest(BitcoinTestFramework):
assert prebalance > 2
address = self.nodes[1].getnewaddress()
amount = 3
fee_rate_sat_vb = 2
fee_rate_sat_vb = 20
fee_rate_btc_kvb = fee_rate_sat_vb * 1e3 / 1e8
# Test passing fee_rate as an integer
txid = self.nodes[2].sendtoaddress(address=address, amount=amount, fee_rate=fee_rate_sat_vb)
@ -428,7 +428,7 @@ class WalletTest(BitcoinTestFramework):
prebalance = self.nodes[2].getbalance()
amount = Decimal("0.001")
fee_rate_sat_vb = 1.23
fee_rate_sat_vb = 10.23
fee_rate_btc_kvb = fee_rate_sat_vb * 1e3 / 1e8
# Test passing fee_rate as a string
txid = self.nodes[2].sendtoaddress(address=address, amount=amount, fee_rate=str(fee_rate_sat_vb))
@ -443,12 +443,12 @@ class WalletTest(BitcoinTestFramework):
assert_raises_rpc_error(-8, "Unknown named parameter key", self.nodes[2].sendtoaddress, address=address, amount=1, fee_rate=1, key=1)
# Test setting explicit fee rate just below the minimum.
self.log.info("Test sendtoaddress raises 'fee rate too low' if fee_rate of 0.99999999 is passed")
assert_raises_rpc_error(-6, "Fee rate (0.999 sat/vB) is lower than the minimum fee rate setting (1.000 sat/vB)",
self.nodes[2].sendtoaddress, address=address, amount=1, fee_rate=0.99999999)
self.log.info("Test sendtoaddress raises 'fee rate too low' if fee_rate of 9.99999999 is passed")
assert_raises_rpc_error(-6, "Fee rate (9.999 sat/vB) is lower than the minimum fee rate setting (10.000 sat/vB)",
self.nodes[2].sendtoaddress, address=address, amount=1, fee_rate=9.99999999)
self.log.info("Test sendtoaddress raises if fee_rate of 0 or -1 is passed")
assert_raises_rpc_error(-6, "Fee rate (0.000 sat/vB) is lower than the minimum fee rate setting (1.000 sat/vB)",
assert_raises_rpc_error(-6, "Fee rate (0.000 sat/vB) is lower than the minimum fee rate setting (10.000 sat/vB)",
self.nodes[2].sendtoaddress, address=address, amount=10, fee_rate=0)
assert_raises_rpc_error(-3, OUT_OF_RANGE, self.nodes[2].sendtoaddress, address=address, amount=1.0, fee_rate=-1)

View File

@ -45,7 +45,7 @@ class CreateTxWalletTest(BitcoinTestFramework):
def test_tx_size_too_large(self):
# More than 10kB of outputs, so that we hit -maxtxfee with a high feerate
outputs = {self.nodes[0].getnewaddress(address_type='bech32'): 0.000025 for _ in range(400)}
outputs = {self.nodes[0].getnewaddress(address_type='bech32'): 0.00025 for _ in range(400)}
raw_tx = self.nodes[0].createrawtransaction(inputs=[], outputs=outputs)
for fee_setting in ['-minrelaytxfee=0.01', '-mintxfee=0.01', '-paytxfee=0.01']:

View File

@ -163,7 +163,7 @@ class KeyPoolTest(BitcoinTestFramework):
assert_equal(res[0]['success'], True)
w1.walletpassphrase('test', 100)
res = w1.sendtoaddress(address=address, amount=0.00010000)
res = w1.sendtoaddress(address=address, amount=0.00020000)
nodes[0].generate(1)
destination = addr.pop()
@ -172,24 +172,24 @@ class KeyPoolTest(BitcoinTestFramework):
assert_raises_rpc_error(-4, "Transaction needs a change address, but we can't generate it. Please call keypoolrefill first.", w2.walletcreatefundedpsbt, inputs=[], outputs=[{addr.pop(): 0.00005000}], options={"subtractFeeFromOutputs": [0], "feeRate": 0.00010})
# creating a 10,000 sat transaction without change, with a manual input, should still be possible
res = w2.walletcreatefundedpsbt(inputs=w2.listunspent(), outputs=[{destination: 0.00010000}], options={"subtractFeeFromOutputs": [0], "feeRate": 0.00010})
res = w2.walletcreatefundedpsbt(inputs=w2.listunspent(), outputs=[{destination: 0.00020000}], options={"subtractFeeFromOutputs": [0], "feeRate": 0.00010})
assert_equal("psbt" in res, True)
# creating a 10,000 sat transaction without change should still be possible
res = w2.walletcreatefundedpsbt(inputs=[], outputs=[{destination: 0.00010000}], options={"subtractFeeFromOutputs": [0], "feeRate": 0.00010})
res = w2.walletcreatefundedpsbt(inputs=[], outputs=[{destination: 0.00020000}], options={"subtractFeeFromOutputs": [0], "feeRate": 0.00010})
assert_equal("psbt" in res, True)
# should work without subtractFeeFromOutputs if the exact fee is subtracted from the amount
res = w2.walletcreatefundedpsbt(inputs=[], outputs=[{destination: 0.00008900}], options={"feeRate": 0.00010})
res = w2.walletcreatefundedpsbt(inputs=[], outputs=[{destination: 0.00018900}], options={"feeRate": 0.00010})
assert_equal("psbt" in res, True)
# dust change should be removed
res = w2.walletcreatefundedpsbt(inputs=[], outputs=[{destination: 0.00008800}], options={"feeRate": 0.00010})
res = w2.walletcreatefundedpsbt(inputs=[], outputs=[{destination: 0.00018800}], options={"feeRate": 0.00010})
assert_equal("psbt" in res, True)
# create a transaction without change at the maximum fee rate, such that the output is still spendable:
res = w2.walletcreatefundedpsbt(inputs=[], outputs=[{destination: 0.00010000}], options={"subtractFeeFromOutputs": [0], "feeRate": 0.0008824})
res = w2.walletcreatefundedpsbt(inputs=[], outputs=[{destination: 0.00020000}], options={"subtractFeeFromOutputs": [0], "feeRate": 0.00155099})
assert_equal("psbt" in res, True)
assert_equal(res["fee"], Decimal("0.00009706"))
assert_equal(res["fee"], Decimal("0.00017060"))
# creating a 10,000 sat transaction with a manual change address should be possible
res = w2.walletcreatefundedpsbt(inputs=[], outputs=[{destination: 0.00010000}], options={"subtractFeeFromOutputs": [0], "feeRate": 0.00010, "changeAddress": addr.pop()})

View File

@ -256,29 +256,29 @@ class WalletSendTest(BitcoinTestFramework):
assert res["complete"]
self.log.info("Test setting explicit fee rate")
res1 = self.test_send(from_wallet=w0, to_wallet=w1, amount=1, arg_fee_rate="1", add_to_wallet=False)
res2 = self.test_send(from_wallet=w0, to_wallet=w1, amount=1, fee_rate="1", add_to_wallet=False)
res1 = self.test_send(from_wallet=w0, to_wallet=w1, amount=1, arg_fee_rate="10", add_to_wallet=False)
res2 = self.test_send(from_wallet=w0, to_wallet=w1, amount=1, fee_rate="10", add_to_wallet=False)
assert_equal(self.nodes[1].decodepsbt(res1["psbt"])["fee"], self.nodes[1].decodepsbt(res2["psbt"])["fee"])
res = self.test_send(from_wallet=w0, to_wallet=w1, amount=1, fee_rate=7, add_to_wallet=False)
res = self.test_send(from_wallet=w0, to_wallet=w1, amount=1, fee_rate=10, add_to_wallet=False)
fee = self.nodes[1].decodepsbt(res["psbt"])["fee"]
assert_fee_amount(fee, Decimal(len(res["hex"]) / 2), Decimal("0.00007"))
assert_fee_amount(fee, Decimal(len(res["hex"]) / 2), Decimal("0.0001"))
# "unset" and None are treated the same for estimate_mode
res = self.test_send(from_wallet=w0, to_wallet=w1, amount=1, fee_rate=2, estimate_mode="unset", add_to_wallet=False)
res = self.test_send(from_wallet=w0, to_wallet=w1, amount=1, fee_rate=20, estimate_mode="unset", add_to_wallet=False)
fee = self.nodes[1].decodepsbt(res["psbt"])["fee"]
assert_fee_amount(fee, Decimal(len(res["hex"]) / 2), Decimal("0.00002"))
assert_fee_amount(fee, Decimal(len(res["hex"]) / 2), Decimal("0.0002"))
res = self.test_send(from_wallet=w0, to_wallet=w1, amount=1, arg_fee_rate=4.531, add_to_wallet=False)
res = self.test_send(from_wallet=w0, to_wallet=w1, amount=1, arg_fee_rate=14.531, add_to_wallet=False)
fee = self.nodes[1].decodepsbt(res["psbt"])["fee"]
assert_fee_amount(fee, Decimal(len(res["hex"]) / 2), Decimal("0.00004531"))
assert_fee_amount(fee, Decimal(len(res["hex"]) / 2), Decimal("0.00014531"))
res = self.test_send(from_wallet=w0, to_wallet=w1, amount=1, arg_fee_rate=3, add_to_wallet=False)
res = self.test_send(from_wallet=w0, to_wallet=w1, amount=1, arg_fee_rate=30, add_to_wallet=False)
fee = self.nodes[1].decodepsbt(res["psbt"])["fee"]
assert_fee_amount(fee, Decimal(len(res["hex"]) / 2), Decimal("0.00003"))
assert_fee_amount(fee, Decimal(len(res["hex"]) / 2), Decimal("0.0003"))
# Test that passing fee_rate as both an argument and an option raises.
self.test_send(from_wallet=w0, to_wallet=w1, amount=1, arg_fee_rate=1, fee_rate=1, add_to_wallet=False,
self.test_send(from_wallet=w0, to_wallet=w1, amount=1, arg_fee_rate=10, fee_rate=10, add_to_wallet=False,
expect_error=(-8, "Pass the fee_rate either as an argument, or in the options object, but not both"))
assert_raises_rpc_error(-8, "Use fee_rate (sat/vB) instead of feeRate", w0.send, {w1.getnewaddress(): 1}, 6, "conservative", 1, {"feeRate": 0.01})
@ -303,15 +303,15 @@ class WalletSendTest(BitcoinTestFramework):
expect_error=(-3, "Expected type number for conf_target, got {}".format(k)))
# Test setting explicit fee rate just below the minimum and at zero.
self.log.info("Explicit fee rate raises RPC error 'fee rate too low' if fee_rate of 0.99999999 is passed")
self.test_send(from_wallet=w0, to_wallet=w1, amount=1, fee_rate=0.99999999,
expect_error=(-4, "Fee rate (0.999 sat/vB) is lower than the minimum fee rate setting (1.000 sat/vB)"))
self.test_send(from_wallet=w0, to_wallet=w1, amount=1, arg_fee_rate=0.99999999,
expect_error=(-4, "Fee rate (0.999 sat/vB) is lower than the minimum fee rate setting (1.000 sat/vB)"))
self.log.info("Explicit fee rate raises RPC error 'fee rate too low' if fee_rate of 9.99999999 is passed")
self.test_send(from_wallet=w0, to_wallet=w1, amount=1, fee_rate=9.99999999,
expect_error=(-4, "Fee rate (9.999 sat/vB) is lower than the minimum fee rate setting (10.000 sat/vB)"))
self.test_send(from_wallet=w0, to_wallet=w1, amount=1, arg_fee_rate=9.99999999,
expect_error=(-4, "Fee rate (9.999 sat/vB) is lower than the minimum fee rate setting (10.000 sat/vB)"))
self.test_send(from_wallet=w0, to_wallet=w1, amount=1, fee_rate=0,
expect_error=(-4, "Fee rate (0.000 sat/vB) is lower than the minimum fee rate setting (1.000 sat/vB)"))
expect_error=(-4, "Fee rate (0.000 sat/vB) is lower than the minimum fee rate setting (10.000 sat/vB)"))
self.test_send(from_wallet=w0, to_wallet=w1, amount=1, arg_fee_rate=0,
expect_error=(-4, "Fee rate (0.000 sat/vB) is lower than the minimum fee rate setting (1.000 sat/vB)"))
expect_error=(-4, "Fee rate (0.000 sat/vB) is lower than the minimum fee rate setting (10.000 sat/vB)"))
# TODO: Return hex if fee rate is below -maxmempool
# res = self.test_send(from_wallet=w0, to_wallet=w1, amount=1, conf_target=0.1, estimate_mode="sat/b", add_to_wallet=False)