Skip to content

Commit

Permalink
Merge branch 'master' of https://github.com/bitcoin/bitcoin
Browse files Browse the repository at this point in the history
  • Loading branch information
actions-user committed Jun 15, 2024
2 parents 489c487 + 2c79abc commit 95406e4
Show file tree
Hide file tree
Showing 10 changed files with 167 additions and 16 deletions.
114 changes: 114 additions & 0 deletions doc/release-notes/release-notes-27.1.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,114 @@
27.1 Release Notes
=====================

Bitcoin Core version 27.1 is now available from:

<https://bitcoincore.org/bin/bitcoin-core-27.1/>

This release includes various bug fixes and performance
improvements, as well as updated translations.

Please report bugs using the issue tracker at GitHub:

<https://github.com/bitcoin/bitcoin/issues>

To receive security and update notifications, please subscribe to:

<https://bitcoincore.org/en/list/announcements/join/>

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 macOS)
or `bitcoind`/`bitcoin-qt` (on Linux).

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.

Compatibility
==============

Bitcoin Core is supported and extensively tested on operating systems
using the Linux Kernel 3.17+, macOS 11.0+, 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.

Notable changes
===============

### Miniscript

- #29853 sign: don't assume we are parsing a sane TapMiniscript

### RPC

- #29869 rpc, bugfix: Enforce maximum value for setmocktime
- #29870 rpc: Reword SighashFromStr error message
- #30094 rpc: move UniValue in blockToJSON

### Index

- #29776 Fix #29767, set m_synced = true after Commit()

### Gui

- #gui812 Fix create unsigned transaction fee bump
- #gui813 Don't permit port in proxy IP option

### Test

- #29892 test: Fix failing univalue float test

### P2P

- #30085 p2p: detect addnode cjdns peers in GetAddedNodeInfo()

### Build

- #29747 depends: fix mingw-w64 Qt DEBUG=1 build
- #29859 build: Fix false positive CHECK_ATOMIC test
- #29985 depends: Fix build of Qt for 32-bit platforms with recent glibc
- #30097 crypto: disable asan for sha256_sse4 with clang and -O0
- #30151 depends: Fetch miniupnpc sources from an alternative website
- #30216 build: Fix building fuzz binary on on SunOS / illumos
- #30217 depends: Update Boost download link

### Doc

- #29934 doc: add LLVM instruction for macOS < 13

### CI

- #29856 ci: Bump s390x to ubuntu:24.04

### Misc

- #29691 Change Luke Dashjr seed to dashjr-list-of-p2p-nodes.us
- #30149 contrib: Renew Windows code signing certificate

Credits
=======

Thanks to everyone who directly contributed to this release:

- Antoine Poinsot
- Ava Chow
- Cory Fields
- dergoegge
- fanquake
- furszy
- Hennadii Stepanov
- Jon Atack
- laanwj
- Luke Dashjr
- MarcoFalke
- nanlour
- Sjors Provoost
- willcl-ark

As well as to everyone that helped with translations on
[Transifex](https://www.transifex.com/bitcoin/bitcoin/).
2 changes: 1 addition & 1 deletion src/coins.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -361,7 +361,7 @@ static bool ExecuteBackedWrapper(Func func, const std::vector<std::function<void
for (const auto& f : err_callbacks) {
f();
}
LogPrintf("Error reading from database: %s\n", e.what());
LogError("Error reading from database: %s\n", e.what());
// Starting the shutdown sequence and returning false to the caller would be
// interpreted as 'entry not found' (as opposed to unable to read data), and
// could lead to invalid interpretation. Just exit immediately, as we can't
Expand Down
16 changes: 8 additions & 8 deletions src/init.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -409,7 +409,7 @@ static void HandleSIGHUP(int)
static BOOL WINAPI consoleCtrlHandler(DWORD dwCtrlType)
{
if (!(*Assert(g_shutdown))()) {
LogPrintf("Error: failed to send shutdown signal on Ctrl-C\n");
LogError("Failed to send shutdown signal on Ctrl-C\n");
return false;
}
Sleep(INFINITE);
Expand Down Expand Up @@ -840,7 +840,7 @@ std::set<BlockFilterType> g_enabled_filter_types;
// Since LogPrintf may itself allocate memory, set the handler directly
// to terminate first.
std::set_new_handler(std::terminate);
LogPrintf("Error: Out of memory. Terminating.\n");
LogError("Out of memory. Terminating.\n");

// The log was successful, terminate now.
std::terminate();
Expand Down Expand Up @@ -1175,9 +1175,9 @@ bool AppInitMain(NodeContext& node, interfaces::BlockAndHeaderTipInfo* tip_info)
scheduler.scheduleEvery([&args, &node]{
constexpr uint64_t min_disk_space = 50 << 20; // 50 MB
if (!CheckDiskSpace(args.GetBlocksDirPath(), min_disk_space)) {
LogPrintf("Shutting down due to lack of disk space!\n");
LogError("Shutting down due to lack of disk space!\n");
if (!(*Assert(node.shutdown))()) {
LogPrintf("Error: failed to send shutdown signal after disk space check\n");
LogError("Failed to send shutdown signal after disk space check\n");
}
}
}, std::chrono::minutes{5});
Expand Down Expand Up @@ -1582,7 +1582,7 @@ bool AppInitMain(NodeContext& node, interfaces::BlockAndHeaderTipInfo* tip_info)
try {
return f();
} catch (const std::exception& e) {
LogPrintf("%s\n", e.what());
LogError("%s\n", e.what());
return std::make_tuple(node::ChainstateLoadStatus::FAILURE, _("Error opening block database"));
}
};
Expand Down Expand Up @@ -1614,10 +1614,10 @@ bool AppInitMain(NodeContext& node, interfaces::BlockAndHeaderTipInfo* tip_info)
if (fRet) {
do_reindex = true;
if (!Assert(node.shutdown)->reset()) {
LogPrintf("Internal error: failed to reset shutdown signal.\n");
LogError("Internal error: failed to reset shutdown signal.\n");
}
} else {
LogPrintf("Aborted block database rebuild. Exiting.\n");
LogError("Aborted block database rebuild. Exiting.\n");
return false;
}
} else {
Expand Down Expand Up @@ -1752,7 +1752,7 @@ bool AppInitMain(NodeContext& node, interfaces::BlockAndHeaderTipInfo* tip_info)
if (args.GetBoolArg("-stopafterblockimport", DEFAULT_STOPAFTERBLOCKIMPORT)) {
LogPrintf("Stopping after block import\n");
if (!(*Assert(node.shutdown))()) {
LogPrintf("Error: failed to send shutdown signal after finishing block import\n");
LogError("Failed to send shutdown signal after finishing block import\n");
}
return;
}
Expand Down
4 changes: 4 additions & 0 deletions src/leveldb/include/leveldb/status.h
Original file line number Diff line number Diff line change
Expand Up @@ -103,6 +103,8 @@ class LEVELDB_EXPORT Status {
inline Status::Status(const Status& rhs) {
state_ = (rhs.state_ == nullptr) ? nullptr : CopyState(rhs.state_);
}

// NOLINTBEGIN(bugprone-unhandled-self-assignment)
inline Status& Status::operator=(const Status& rhs) {
// The following condition catches both aliasing (when this == &rhs),
// and the common case where both rhs and *this are ok.
Expand All @@ -112,6 +114,8 @@ inline Status& Status::operator=(const Status& rhs) {
}
return *this;
}
// NOLINTEND(bugprone-unhandled-self-assignment)

inline Status& Status::operator=(Status&& rhs) noexcept {
std::swap(state_, rhs.state_);
return *this;
Expand Down
2 changes: 1 addition & 1 deletion src/node/interfaces.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -125,7 +125,7 @@ class NodeImpl : public Node
void startShutdown() override
{
if (!(*Assert(Assert(m_context)->shutdown))()) {
LogPrintf("Error: failed to send shutdown signal\n");
LogError("Failed to send shutdown signal\n");
}
// Stop RPC for clean shutdown if any of waitfor* commands is executed.
if (args().GetBoolArg("-server", false)) {
Expand Down
2 changes: 1 addition & 1 deletion src/node/kernel_notifications.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -63,7 +63,7 @@ kernel::InterruptResult KernelNotifications::blockTip(SynchronizationState state
uiInterface.NotifyBlockTip(state, &index);
if (m_stop_at_height && index.nHeight >= m_stop_at_height) {
if (!m_shutdown()) {
LogPrintf("Error: failed to send shutdown signal after reaching stop height\n");
LogError("Failed to send shutdown signal after reaching stop height\n");
}
return kernel::Interrupted{};
}
Expand Down
6 changes: 3 additions & 3 deletions src/validation.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -5967,8 +5967,8 @@ SnapshotCompletionResult ChainstateManager::MaybeCompleteSnapshotValidation()
PACKAGE_NAME, snapshot_tip_height, snapshot_base_height, snapshot_base_height, PACKAGE_BUGREPORT
);

LogPrintf("[snapshot] !!! %s\n", user_error.original);
LogPrintf("[snapshot] deleting snapshot, reverting to validated chain, and stopping node\n");
LogError("[snapshot] !!! %s\n", user_error.original);
LogError("[snapshot] deleting snapshot, reverting to validated chain, and stopping node\n");

m_active_chainstate = m_ibd_chainstate.get();
m_snapshot_chainstate->m_disabled = true;
Expand Down Expand Up @@ -6320,7 +6320,7 @@ bool ChainstateManager::ValidatedSnapshotCleanup()
fs::path p_old,
fs::path p_new,
const fs::filesystem_error& err) {
LogPrintf("Error renaming path (%s) -> (%s): %s\n",
LogError("[snapshot] Error renaming path (%s) -> (%s): %s\n",
fs::PathToString(p_old), fs::PathToString(p_new), err.what());
GetNotifications().fatalError(strprintf(_(
"Rename of '%s' -> '%s' failed. "
Expand Down
2 changes: 1 addition & 1 deletion src/wallet/feebumper.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -93,7 +93,7 @@ static feebumper::Result CheckFeeRate(const CWallet& wallet, const CMutableTrans
}
CAmount new_total_fee = newFeerate.GetFee(maxTxSize) + combined_bump_fee.value();

CFeeRate incrementalRelayFee = std::max(wallet.chain().relayIncrementalFee(), CFeeRate(WALLET_INCREMENTAL_RELAY_FEE));
CFeeRate incrementalRelayFee = wallet.chain().relayIncrementalFee();

// Min total fee is old fee + relay fee
CAmount minTotalFee = old_fee + incrementalRelayFee.GetFee(maxTxSize);
Expand Down
10 changes: 10 additions & 0 deletions test/functional/rpc_signrawtransactionwithkey.py
Original file line number Diff line number Diff line change
Expand Up @@ -126,10 +126,20 @@ def invalid_sighashtype_test(self):
privkeys = [self.nodes[0].get_deterministic_priv_key().key]
assert_raises_rpc_error(-8, "'all' is not a valid sighash parameter.", self.nodes[0].signrawtransactionwithkey, tx, privkeys, sighashtype="all")

def invalid_private_key_and_tx(self):
self.log.info("Test signing transaction with an invalid private key")
tx = self.nodes[0].createrawtransaction(INPUTS, OUTPUTS)
privkeys = ["123"]
assert_raises_rpc_error(-5, "Invalid private key", self.nodes[0].signrawtransactionwithkey, tx, privkeys)
self.log.info("Test signing transaction with an invalid tx hex")
privkeys = [self.nodes[0].get_deterministic_priv_key().key]
assert_raises_rpc_error(-22, "TX decode failed. Make sure the tx has at least one input.", self.nodes[0].signrawtransactionwithkey, tx + "00", privkeys)

def run_test(self):
self.successful_signing_test()
self.witness_script_test()
self.invalid_sighashtype_test()
self.invalid_private_key_and_tx()


if __name__ == '__main__':
Expand Down
25 changes: 24 additions & 1 deletion test/functional/wallet_bumpfee.py
Original file line number Diff line number Diff line change
Expand Up @@ -117,6 +117,7 @@ def run_test(self):

# Context independent tests
test_feerate_checks_replaced_outputs(self, rbf_node, peer_node)
test_bumpfee_with_feerate_ignores_walletincrementalrelayfee(self, rbf_node, peer_node)

def test_invalid_parameters(self, rbf_node, peer_node, dest_address):
self.log.info('Test invalid parameters')
Expand Down Expand Up @@ -816,7 +817,7 @@ def test_feerate_checks_replaced_outputs(self, rbf_node, peer_node):
# Since the bumped tx will replace all of the outputs with a single output, we can estimate that its size will 31 * (len(outputs) - 1) bytes smaller
tx_size = tx_details["decoded"]["vsize"]
est_bumped_size = tx_size - (len(tx_details["decoded"]["vout"]) - 1) * 31
inc_fee_rate = max(rbf_node.getmempoolinfo()["incrementalrelayfee"], Decimal(0.00005000)) # Wallet has a fixed incremental relay fee of 5 sat/vb
inc_fee_rate = rbf_node.getmempoolinfo()["incrementalrelayfee"]
# RPC gives us fee as negative
min_fee = (-tx_details["fee"] + get_fee(est_bumped_size, inc_fee_rate)) * Decimal(1e8)
min_fee_rate = (min_fee / est_bumped_size).quantize(Decimal("1.000"))
Expand All @@ -830,5 +831,27 @@ def test_feerate_checks_replaced_outputs(self, rbf_node, peer_node):
self.clear_mempool()


def test_bumpfee_with_feerate_ignores_walletincrementalrelayfee(self, rbf_node, peer_node):
self.log.info('Test that bumpfee with fee_rate ignores walletincrementalrelayfee')
# Make sure there is enough balance
peer_node.sendtoaddress(rbf_node.getnewaddress(), 2)
self.generate(peer_node, 1)

dest_address = peer_node.getnewaddress(address_type="bech32")
tx = rbf_node.send(outputs=[{dest_address: 1}], fee_rate=2)

# Ensure you can not fee bump with a fee_rate below or equal to the original fee_rate
assert_raises_rpc_error(-8, "Insufficient total fee", rbf_node.bumpfee, tx["txid"], {"fee_rate": 1})
assert_raises_rpc_error(-8, "Insufficient total fee", rbf_node.bumpfee, tx["txid"], {"fee_rate": 2})

# Ensure you can not fee bump if the fee_rate is more than original fee_rate but the total fee from new fee_rate is
# less than (original fee + incrementalrelayfee)
assert_raises_rpc_error(-8, "Insufficient total fee", rbf_node.bumpfee, tx["txid"], {"fee_rate": 2.8})

# You can fee bump as long as the new fee set from fee_rate is atleast (original fee + incrementalrelayfee)
rbf_node.bumpfee(tx["txid"], {"fee_rate": 3})
self.clear_mempool()


if __name__ == "__main__":
BumpFeeTest().main()

0 comments on commit 95406e4

Please sign in to comment.