Skip to content

Prepare 23.3.0rc5 #1431

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 19 commits into from
Mar 5, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
19 commits
Select commit Hold shift + click to select a range
37adf7d
Squashed 'src/simplicity/' changes from 4858b89526..b549192109
roconnor-blockstream Feb 18, 2025
c211d1a
Merge commit '37adf7d72df079b97e622f5d9a61dd029c71afa1' into simplicity
roconnor-blockstream Feb 18, 2025
1ded388
Merge pull request #1420 from ElementsProject/simplicity
delta1 Feb 19, 2025
cd67236
feature_discount_ct: some txs can return 2 different weights, adapt t…
psgreco Feb 20, 2025
305de6d
feature_confidential_transactions: Use system temp dir instead of har…
psgreco Feb 22, 2025
258d9d3
feature_fedpeg: Use os.join instead of hardcoded separator
psgreco Feb 22, 2025
fe04483
Avoid concatenating default path when mainchainrpccookiefile is an ab…
psgreco Feb 23, 2025
73c542e
Fix error reading cookie file on windows when path contains UTF-8
psgreco Feb 23, 2025
d973e36
Win64 Native: Fix PACKAGE_NAME and bug report url
psgreco Feb 21, 2025
38065e1
Fix warning about mixing enum and int
psgreco Feb 18, 2025
b92a3ce
TSAN: Avoid unlocked access to pindexBestHeader
psgreco Feb 20, 2025
7ed2768
Merge pull request #1421 from psgreco/master-fixlock
delta1 Feb 24, 2025
4058bd1
Remove extra ; in confidential.h
psgreco Feb 25, 2025
59c30c0
Blinding: update change_position after calling fillBlindDetails
psgreco Feb 25, 2025
df4e99d
Merge pull request #1423 from psgreco/master-win64-fixassert
delta1 Feb 26, 2025
3a80782
Avoid double free in simplicity pointer when copying PrecomputedTrans…
roconnor-blockstream Mar 3, 2025
0eb2ea5
Merge pull request #1425 from ElementsProject/simplicity
delta1 Mar 4, 2025
54fa255
Merge branch 'master' into elem-23.3.0rc5
psgreco Mar 4, 2025
30eeffd
Bump version to 23.3.0-rc5
psgreco Mar 4, 2025
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions build_msvc/bitcoind/bitcoind.vcxproj
Original file line number Diff line number Diff line change
Expand Up @@ -57,9 +57,9 @@
<Target Name="AfterBuild">
<Copy SourceFiles="$(ConfigIniIn)" DestinationFiles="$(ConfigIniOut)" ></Copy>
<ReplaceInFile FilePath="$(ConfigIniOut)"
Replace="@PACKAGE_NAME@" By="Bitcoin Core"></ReplaceInFile>
Replace="@PACKAGE_NAME@" By="Elements Core"></ReplaceInFile>
<ReplaceInFile FilePath="$(ConfigIniOut)"
Replace="@PACKAGE_BUGREPORT@" By="https://github.com/bitcoin/bitcoin/issues"></ReplaceInFile>
Replace="@PACKAGE_BUGREPORT@" By="https://github.com/ElementsProject/elements/issues"></ReplaceInFile>
<ReplaceInFile FilePath="$(ConfigIniOut)"
Replace="@abs_top_srcdir@" By="..\.." ToFullPath="true"></ReplaceInFile>
<ReplaceInFile FilePath="$(ConfigIniOut)"
Expand Down
2 changes: 1 addition & 1 deletion configure.ac
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ AC_PREREQ([2.69])
define(_CLIENT_VERSION_MAJOR, 23)
define(_CLIENT_VERSION_MINOR, 3)
define(_CLIENT_VERSION_BUILD, 0)
define(_CLIENT_VERSION_RC, 4)
define(_CLIENT_VERSION_RC, 5)
define(_CLIENT_VERSION_IS_RELEASE, true)
define(_COPYRIGHT_YEAR, 2024)
define(_COPYRIGHT_HOLDERS,[The %s developers])
Expand Down
2 changes: 1 addition & 1 deletion src/block_proof.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,7 @@ static bool CheckProofGeneric(const CBlockHeader& block, const uint32_t max_bloc
| SCRIPT_VERIFY_SIGPUSHONLY // Witness is push-only
| SCRIPT_VERIFY_LOW_S // Stop easiest signature fiddling
| SCRIPT_VERIFY_WITNESS // Witness and to enforce cleanstack
| (is_dyna ? 0 : SCRIPT_NO_SIGHASH_BYTE); // Non-dynafed blocks do not have sighash byte
| (is_dyna ? SCRIPT_VERIFY_NONE : SCRIPT_NO_SIGHASH_BYTE); // Non-dynafed blocks do not have sighash byte
return GenericVerifyScript(scriptSig, witness, challenge, proof_flags, block);
}

Expand Down
43 changes: 22 additions & 21 deletions src/net_processing.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2131,29 +2131,30 @@ void PeerManagerImpl::ProcessHeadersMessage(CNode& pfrom, const Peer& peer,
// If we are already too far ahead of where we want to be on headers, discard
// the received headers. We can still get ahead by up to a single maximum-sized
// headers message here, but never further, so that's fine.
if (pindexBestHeader) {
int64_t headers_ahead = pindexBestHeader->nHeight - m_chainman.ActiveHeight();
bool too_far_ahead = node::fTrimHeaders && (headers_ahead >= node::nHeaderDownloadBuffer);
if (too_far_ahead) {
LOCK(cs_main);
CNodeState *nodestate = State(pfrom.GetId());
if ((nodestate->pindexBestKnownBlock == nullptr) ||
if (node::fTrimHeaders) {
LOCK(cs_main);
if (pindexBestHeader) {
int64_t headers_ahead = pindexBestHeader->nHeight - m_chainman.ActiveHeight();
if (headers_ahead >= node::nHeaderDownloadBuffer) {
CNodeState *nodestate = State(pfrom.GetId());
if ((nodestate->pindexBestKnownBlock == nullptr) ||
(nodestate->pindexBestKnownBlock->nHeight < m_chainman.ActiveHeight())) {
// Our notion of what blocks a peer has available is based on its pindexBestKnownBlock,
// which is based on headers received from it. If we don't have one, or it's too old,
// then we can never get blocks from this peer until we accept headers from it first.
LogPrint(BCLog::NET, "NOT discarding headers from peer=%d, to update its block availability. (current best header %d, active chain height %d)\n", pfrom.GetId(), pindexBestHeader->nHeight, m_chainman.ActiveHeight());
} else {
LogPrint(BCLog::NET, "Discarding received headers and pausing header sync from peer=%d, because we are too far ahead of block sync. (%d > %d)\n", pfrom.GetId(), pindexBestHeader->nHeight, m_chainman.ActiveHeight());
if (nodestate->fSyncStarted) {
// Cancel sync from this node, so we don't penalize it later.
// This will cause us to automatically start syncing from a different node (or restart syncing from the same node) later,
// if we still need to sync headers.
nSyncStarted--;
nodestate->fSyncStarted = false;
nodestate->m_headers_sync_timeout = 0us;
// Our notion of what blocks a peer has available is based on its pindexBestKnownBlock,
// which is based on headers received from it. If we don't have one, or it's too old,
// then we can never get blocks from this peer until we accept headers from it first.
LogPrint(BCLog::NET, "NOT discarding headers from peer=%d, to update its block availability. (current best header %d, active chain height %d)\n", pfrom.GetId(), pindexBestHeader->nHeight, m_chainman.ActiveHeight());
} else {
LogPrint(BCLog::NET, "Discarding received headers and pausing header sync from peer=%d, because we are too far ahead of block sync. (%d > %d)\n", pfrom.GetId(), pindexBestHeader->nHeight, m_chainman.ActiveHeight());
if (nodestate->fSyncStarted) {
// Cancel sync from this node, so we don't penalize it later.
// This will cause us to automatically start syncing from a different node (or restart syncing from the same node) later,
// if we still need to sync headers.
nSyncStarted--;
nodestate->fSyncStarted = false;
nodestate->m_headers_sync_timeout = 0us;
}
return;
}
return;
}
}
}
Expand Down
2 changes: 1 addition & 1 deletion src/primitives/confidential.h
Original file line number Diff line number Diff line change
Expand Up @@ -149,7 +149,7 @@ class CConfidentialValue : public CConfidentialCommitment<9, 8, 9>
return -1;
}

assert(IsExplicit());;
assert(IsExplicit());
return ReadBE64(&vchCommitment[1]);
}
void SetToAmount(CAmount nAmount);
Expand Down
7 changes: 5 additions & 2 deletions src/rpc/request.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -139,7 +139,10 @@ static fs::path GetMainchainAuthCookieFile()
if (gArgs.GetChainName() == "liquidv1") {
cookie_file = ".cookie";
}
return fsbridge::AbsPathJoin(GetMainchainDefaultDataDir(), fs::PathFromString(gArgs.GetArg("-mainchainrpccookiefile", cookie_file)));
fs::path cookie_path = fs::PathFromString(gArgs.GetArg("-mainchainrpccookiefile", cookie_file));
if (cookie_path.is_absolute())
return cookie_path;
return fsbridge::AbsPathJoin(GetMainchainDefaultDataDir(), cookie_path);
}

bool GetMainchainAuthCookie(std::string *cookie_out)
Expand All @@ -148,7 +151,7 @@ bool GetMainchainAuthCookie(std::string *cookie_out)
std::string cookie;

std::filesystem::path filepath = GetMainchainAuthCookieFile();
file.open(filepath.string().c_str());
file.open(filepath);
if (!file.is_open())
return false;
std::getline(file, cookie);
Expand Down
4 changes: 2 additions & 2 deletions src/script/interpreter.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2669,7 +2669,7 @@ void PrecomputedTransactionData::Init(const T& txTo, std::vector<CTxOut>&& spent
simplicityRawTx.version = txTo.nVersion;
simplicityRawTx.lockTime = txTo.nLockTime;

m_simplicity_tx_data = simplicity_elements_mallocTransaction(&simplicityRawTx);
m_simplicity_tx_data = SimplicityTransactionUniquePtr(simplicity_elements_mallocTransaction(&simplicityRawTx));

m_bip341_taproot_ready = true;
}
Expand Down Expand Up @@ -3121,7 +3121,7 @@ bool GenericTransactionSignatureChecker<T>::CheckSimplicity(const valtype& progr

assert(txdata->m_simplicity_tx_data);
assert(simplicityTapEnv);
if (!simplicity_elements_execSimplicity(&error, 0, txdata->m_simplicity_tx_data, nIn, simplicityTapEnv, txdata->m_hash_genesis_block.data(), budget, 0, program.data(), program.size(), witness.data(), witness.size())) {
if (!simplicity_elements_execSimplicity(&error, 0, txdata->m_simplicity_tx_data.get(), nIn, simplicityTapEnv, txdata->m_hash_genesis_block.data(), budget, 0, program.data(), program.size(), witness.data(), witness.size())) {
assert(!"simplicity_elements_execSimplicity internal error");
}
simplicity_elements_freeTapEnv(simplicityTapEnv);
Expand Down
14 changes: 10 additions & 4 deletions src/script/interpreter.h
Original file line number Diff line number Diff line change
Expand Up @@ -169,9 +169,18 @@ enum : uint32_t {

bool CheckSignatureEncoding(const std::vector<unsigned char> &vchSig, unsigned int flags, ScriptError* serror);

struct SimplicityTransactionDeleter
{
void operator()(transaction* ptr)
{
simplicity_elements_freeTransaction(ptr);
}
};
using SimplicityTransactionUniquePtr = std::unique_ptr<transaction, SimplicityTransactionDeleter>;

struct PrecomputedTransactionData
{
transaction* m_simplicity_tx_data = nullptr;
SimplicityTransactionUniquePtr m_simplicity_tx_data;
// BIP341 precomputed data.
// These are single-SHA256, see https://github.com/bitcoin/bips/blob/master/bip-0341.mediawiki#cite_note-15.
uint256 m_prevouts_single_hash;
Expand Down Expand Up @@ -221,9 +230,6 @@ struct PrecomputedTransactionData

template <class T>
explicit PrecomputedTransactionData(const T& tx);
~PrecomputedTransactionData() {
simplicity_elements_freeTransaction(m_simplicity_tx_data);
}
};

enum class SigVersion
Expand Down
4 changes: 2 additions & 2 deletions src/simplicity/dag.c
Original file line number Diff line number Diff line change
Expand Up @@ -367,7 +367,7 @@ void simplicity_computeAnnotatedMerkleRoot(analyses* analysis, const dag_node* d
}

/* Verifies that the 'dag' is in canonical order, meaning that nodes under the left branches have lower indices than nodes under
* right branches, with the exception that nodes under right braches may (cross-)reference identical nodes that already occur under
* right branches, with the exception that nodes under right branches may (cross-)reference identical nodes that already occur under
* left branches.
*
* Returns 'SIMPLICITY_NO_ERROR' if the 'dag' is in canonical order, and returns 'SIMPLICITY_ERR_DATA_OUT_OF_ORDER' if it is not.
Expand All @@ -389,7 +389,7 @@ simplicity_err simplicity_verifyCanonicalOrder(dag_node* dag, const uint_fast32_
/* We use dag[i].aux as a "stack" to manage the traversal of the DAG. */
dag[top].aux = len; /* We will set top to 'len' to indicate we are finished. */

/* Each time any particular 'top' value is revisted in this loop, bottom has increased to be strictly larger than the last 'child'
/* Each time any particular 'top' value is revisited in this loop, bottom has increased to be strictly larger than the last 'child'
value examined. Therefore we will make further progress in the loop the next time around.
By this reasoning any given 'top' value will be visited no more than numChildren(dag[top].tag) + 1 <= 3 times.
Thus this loop iterates at most O('len') times.
Expand Down
2 changes: 1 addition & 1 deletion src/simplicity/dag.h
Original file line number Diff line number Diff line change
Expand Up @@ -350,7 +350,7 @@ void simplicity_computeCommitmentMerkleRoot(dag_node* dag, uint_fast32_t i);
void simplicity_computeAnnotatedMerkleRoot(analyses* analysis, const dag_node* dag, const type* type_dag, uint_fast32_t len);

/* Verifies that the 'dag' is in canonical order, meaning that nodes under the left branches have lower indices than nodes under
* right branches, with the exception that nodes under right braches may (cross-)reference identical nodes that already occur under
* right branches, with the exception that nodes under right branches may (cross-)reference identical nodes that already occur under
* left branches.
*
* Returns 'SIMPLICITY_NO_ERROR' if the 'dag' is in canonical order, and returns 'SIMPLICITY_ERR_DATA_OUT_OF_ORDER' if it is not.
Expand Down
2 changes: 1 addition & 1 deletion src/simplicity/jets-secp256k1.c
Original file line number Diff line number Diff line change
Expand Up @@ -714,7 +714,7 @@ bool simplicity_hash_to_curve(frameItem* dst, frameItem src, const txEnv* env) {
return true;
}

/* THIS IS NOT A JET. It doesn't have the type signatue of a jet
/* THIS IS NOT A JET. It doesn't have the type signature of a jet
* This is a generic taptweak jet implementation parameterized by the tag used in the hash.
* It is designed to be specialized to implement slightly different taptweak operations for Bitcoin and Elements.
*
Expand Down
20 changes: 10 additions & 10 deletions src/simplicity/jets.c
Original file line number Diff line number Diff line change
Expand Up @@ -591,7 +591,7 @@ RIGHT_EXTEND_(32,64)

#define LEFT_SHIFT_(log, bits) \
static inline void left_shift_helper_##bits(bool with, frameItem* dst, frameItem *src) { \
static_assert(log <= 8, "Only log parameter upto 8 is supported."); \
static_assert(log <= 8, "Only log parameter up to 8 is supported."); \
uint_fast8_t amt = simplicity_read##log(src); \
uint_fast##bits##_t output = simplicity_read##bits(src); \
if (with) output = UINT##bits##_MAX ^ output; \
Expand Down Expand Up @@ -625,7 +625,7 @@ LEFT_SHIFT_(8,64)

#define RIGHT_SHIFT_(log, bits) \
static inline void right_shift_helper_##bits(bool with, frameItem* dst, frameItem *src) { \
static_assert(log <= 8, "Only log parameter upto 8 is supported."); \
static_assert(log <= 8, "Only log parameter up to 8 is supported."); \
uint_fast8_t amt = simplicity_read##log(src); \
uint_fast##bits##_t output = simplicity_read##bits(src); \
if (with) output = UINT##bits##_MAX ^ output; \
Expand Down Expand Up @@ -1046,7 +1046,7 @@ DIVIDES_(64)
/* Implements the 3n/2n division algorithm for n=32 bits.
* For more details see "Fast Recursive Division" by Christoph Burnikel and Joachim Ziegler, MPI-I-98-1-022, Oct. 1998.
*
* Given a 96 bit (unsigned) value A and a 64 bit value B, set *q and *r to the quotent and remainder of A divided by B.
* Given a 96 bit (unsigned) value A and a 64 bit value B, set *q and *r to the quotient and remainder of A divided by B.
*
* ah is passed the high 64 bits of A, and al is passed the low 32 bits of A.
* We say that A = [ah;al] where [ah;al] denotes ah * 2^32 + al.
Expand All @@ -1067,7 +1067,7 @@ DIVIDES_(64)
*
* Preconditon 2 ensures that this estimate is close to the true value of Q. In fact Q <= estQ <= Q + 2 (see proof below)
*
* There is a corresponding estR value satifying the equation estR = A - estQ * B.
* There is a corresponding estR value satisfying the equation estR = A - estQ * B.
* This estR is one of {R, R - B, R - 2B}.
* Therefore if estR is non-negative, then estR is equal to the true R value, and hence estQ is equal to the true Q value.
*
Expand All @@ -1085,7 +1085,7 @@ DIVIDES_(64)
*
* Lemma 2: estQ < [1;2] (== 2^32 + 2).
* First note that ah - [bh;0] < [1;0] because
* ah < B (by precondtion 1)
* ah < B (by precondition 1)
* < [bh+1;0]
* == [bh;0] + [1;0]
*
Expand Down Expand Up @@ -1116,7 +1116,7 @@ static void div_mod_96_64(uint_fast32_t *q, uint_fast64_t *r,
/* B == b == [bh;bl] */
uint_fast64_t estQ = ah / bh;

/* Precondition 1 guarentees Q is 32-bits, if estQ is greater than UINT32_MAX, then reduce our initial estimated quotient to UINT32_MAX. */
/* Precondition 1 guarantees Q is 32-bits, if estQ is greater than UINT32_MAX, then reduce our initial estimated quotient to UINT32_MAX. */
*q = estQ <= UINT32_MAX ? (uint_fast32_t)estQ : UINT32_MAX;

/* *q * bh <= estQ * bh <= ah */
Expand All @@ -1131,7 +1131,7 @@ static void div_mod_96_64(uint_fast32_t *q, uint_fast64_t *r,
* This value is negative when [rh;al] < d.
* Note that d is 64 bit and thus if rh is greater than UINT32_MAX, then this value cannot be negative.
*/
/* This loop is exectued at most twice. */
/* This loop is executed at most twice. */
while (rh <= UINT32_MAX && 0x100000000u*rh + al < d) {
/* Our estimated remainder, A - *q * B is negative. */
/* 0 < d == *q * bl and hence 0 < *q, so this decrement does not underflow. */
Expand Down Expand Up @@ -1173,7 +1173,7 @@ bool simplicity_div_mod_128_64(frameItem* dst, frameItem src, const txEnv* env)
* RR
*
* First divide the high 3 "digit"s (96-bits) of A by the two "digit"s (64-bits) of B,
* returning the first "digit" (high 32-bits) of the quotient, and an intermediate remainer consisiting of 2 "digit"s (64-bits).
* returning the first "digit" (high 32-bits) of the quotient, and an intermediate remainder consisiting of 2 "digit"s (64-bits).
*/
div_mod_96_64(&qh, &r, ah, am, b);
simplicity_debug_assert(r < b);
Expand All @@ -1187,8 +1187,8 @@ bool simplicity_div_mod_128_64(frameItem* dst, frameItem src, const txEnv* env)
* ---
* RR
*
* Then append the last "digit" of A to the intermidiate remainder and divide that value (96_bits) by the two "digit"s (64-bits) of B,
* returning the second "digit" (low 32-bits) of the quotient, and the final remainer consisiting of 2 "digit"s (64-bits).
* Then append the last "digit" of A to the intermediate remainder and divide that value (96_bits) by the two "digit"s (64-bits) of B,
* returning the second "digit" (low 32-bits) of the quotient, and the final remainder consisiting of 2 "digit"s (64-bits).
*/
div_mod_96_64(&ql, &r, r, al, b);
simplicity_write32(dst, qh);
Expand Down
12 changes: 6 additions & 6 deletions src/simplicity/primitive/elements/env.c
Original file line number Diff line number Diff line change
Expand Up @@ -260,11 +260,11 @@ static void copyOutput(sigOutput* result, opcode** allocation, size_t* allocatio

/* Tally a sorted list of feeOutputs
*
* Given a sorted array of feeOutput pointers, tally all the (explict) amounts of the entries with the same asset id,
* Given a sorted array of feeOutput pointers, tally all the (explicit) amounts of the entries with the same asset id,
* which are all necessarily next to each other, into the assetFee field of the first entry of the bunch.
*
* Discard all entries other than the first one of each bunch.
* Return 'ret_value', the number of remaning entries in the array after these discards.
* Return 'ret_value', the number of remaining entries in the array after these discards.
*
* Note: the array is not re-allocated, so there will be "junk" values in the array past the end of 'ret_value'.
*
Expand Down Expand Up @@ -497,7 +497,7 @@ extern transaction* simplicity_elements_mallocTransaction(const rawTransaction*
uint_fast32_t ix_fee = 0;

/* perm is a temporary array the same length (numFees) and size as feeOutputs.
* perm is used to initalize feeOutputs and is not used afterward.
* perm is used to initialize feeOutputs and is not used afterward.
* This makes it safe for perm to use the same memory allocation as feeOutputs.
*/
static_assert(sizeof(const sha256_midstate*) == sizeof(sigOutput*), "Pointers (to structures) ought to have the same size.");
Expand Down Expand Up @@ -528,8 +528,8 @@ extern transaction* simplicity_elements_mallocTransaction(const rawTransaction*
/* Initialize the feeOutputs array from the perm array.
* Because the perm array entries are the same size as the feeOutputs array entries, it is safe to initialize one by one.
*
* In practical C implementations, the feeOutputs array entires are initalized to the same value as the perm array entries.
* In practical C implementations, this is a no-op, and generally compiliers are able to see this fact and eliminate this loop.
* In practical C implementations, the feeOutputs array entries are initialized to the same value as the perm array entries.
* In practical C implementations, this is a no-op, and generally compilers are able to see this fact and eliminate this loop.
*
* We keep the loop in the code just to be pedantic.
*/
Expand Down Expand Up @@ -652,7 +652,7 @@ extern void simplicity_elements_freeTapEnv(tapEnv* env) {
simplicity_free(env);
}

/* Contstruct a txEnv structure from its components.
/* Construct a txEnv structure from its components.
* This function will precompute any cached values.
*
* Precondition: NULL != tx
Expand Down
4 changes: 2 additions & 2 deletions src/simplicity/primitive/elements/primitive.h
Original file line number Diff line number Diff line change
Expand Up @@ -248,7 +248,7 @@ typedef struct tapEnv {
unsigned char leafVersion;
} tapEnv;

/* The 'txEnv' structure used by the Elements application of Simplcity.
/* The 'txEnv' structure used by the Elements application of Simplicity.
*
* It includes
* + the transaction data, which may be shared when Simplicity expressions are used for multiple inputs in the same transaction),
Expand All @@ -263,7 +263,7 @@ typedef struct txEnv {
uint_fast32_t ix;
} txEnv;

/* Contstruct a txEnv structure from its components.
/* Construct a txEnv structure from its components.
* This function will precompute any cached values.
*
* Precondition: NULL != tx
Expand Down
Loading