Skip to content

Conversation

glozow
Copy link
Member

@glozow glozow commented Oct 20, 2021

We use the same type for txids and wtxids, uint256. In places where we want the ability to pass either one, we distinguish them using GenTxid.

The (overloaded) CTxMemPool::exists() function is defined as follows:

bool exists(const uint256& txid) const { return exists(GenTxid{false, txid}); }

It always assumes that a uint256 is a txid, which is a footgunny interface.
Querying by wtxid returns a false negative if the transaction has a witness. 🐛

Another approach would be to try both:

bool exists(const uint256& txid) const { return exists(GenTxid{false, txid}) || exists(GenTxid{false, txid}); }

But that's slower and wrongfully placing the burden on the callee; the caller always knows whether the hash is a txid or a wtxid.

@JeremyRubin
Copy link
Contributor

JeremyRubin commented Oct 20, 2021

Why not do a 'newtype' wrapper and then multiple dispatch?

struct Wtxid {
    uint256 h;
   explicit Wtxid(uint256 i): h(i);
}

struct Txid {
    uint256 h;
   explicit Txid(uint256 i): h(i);
}

class CTxMempool{
    bool exists(Txid t);
    bool exists(Wtxid t);
}

(for a more thorough treatment of newtypes, see https://www.boost.org/doc/libs/1_46_1/boost/strong_typedef.hpp)

@DrahtBot
Copy link
Contributor

The following sections might be updated with supplementary metadata relevant to reviewers and maintainers.

Conflicts

Reviewers, this pull request conflicts with the following ones:

  • #23121 ([policy] check ancestor feerate in RBF, remove BIP125 Rule2 by glozow)
  • #19880 (fix CTxMemPool::TrimToSize to put only confirmed coins in pvNoSpendsRemaining by markblundeberg)

If you consider this pull request important, please also help to review the conflicting pull requests. Ideally, start with the one that should be merged first.

@glozow
Copy link
Member Author

glozow commented Oct 21, 2021

Right, ideally we have different types for txid and wtxid. I also think we should make GenTxid a std::variant<Txid, Wtxid> instead of overloading everything.

@MarcoFalke @JeremyRubin would you prefer I change this PR to add new types, or open a new one? Either way we'd delete this function.

@maflcko
Copy link
Member

maflcko commented Oct 21, 2021

I am not sure if it is possible to make Wtxid and Txid different types. Wouldn't that require a major rewrite of txrequest?

@glozow
Copy link
Member Author

glozow commented Oct 21, 2021

True, we'd need to change the Announcement struct to store a GenTxid instead of uint256 and bool, which would probably increase the size...

@naumenkogs
Copy link
Member

Concept ACK. I think the confusion is worth addressing.
No idea what's the best way to achieve it though, but I'd avoid a lot of code changes for this matter.

@jnewbery
Copy link
Contributor

jnewbery commented Oct 21, 2021

Concept ACK. Mixing up txids and wtxids has been a source of several bugs. Anything that we can do to stop just passing uint256s around and instead being explicit about what is expected in function interfaces is an improvement in my opinion.

I agree that ideally we'd have separate types for Txid and Wtxid (and BlockHash) so the compiler can catch bugs for us, but that seems like a much wider scope than this PR is proposing to improve, so could be left for later.

I initially thought that this change carried a tiny performance penalty, since exists(const uint256& txid) used to be able to take a reference, and now we're making a copy of the uint256. However, that exists(const uint256& txid) function was actually making a copy internally anyway, so there's no change in behaviour here.

Allowing callers to pass in a uint256 (which could be txid or wtxid)
but then always assuming that it's a txid is a footgunny interface.
@glozow glozow force-pushed the 2021-10-exists-txid branch from d767a93 to 4307849 Compare October 21, 2021 15:29
@glozow
Copy link
Member Author

glozow commented Oct 21, 2021

Thanks for the reviews! I've added the explicit ctors.

@JeremyRubin
Copy link
Contributor

i think the newtype stuff is obviously better, but that can be handled as a separate PR if desired.

Given the named CTor approach, it's also possible to change those into static functions returning the newtype wrappers with minimal diff.

@@ -393,6 +393,8 @@ class GenTxid
uint256 m_hash;
public:
GenTxid(bool is_wtxid, const uint256& hash) : m_is_wtxid(is_wtxid), m_hash(hash) {}
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Would be nice to make this constructor private / protected at some point (not here though)

@laanwj
Copy link
Member

laanwj commented Oct 21, 2021

Code review ACK 4307849

@jnewbery
Copy link
Contributor

Tested and code review ACK 4307849

The static ctors seem like a strictly superior way to construct the GenTxid objects. What do you think about a follow-up that removes the default ctor?

@maflcko
Copy link
Member

maflcko commented Oct 22, 2021

review ACK 4307849 👘

Show signature and timestamp

Signature:

-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA512

review ACK 4307849256761fe2440d82bbec892d0e8e6b4dd4 👘
-----BEGIN PGP SIGNATURE-----

iQGzBAEBCgAdFiEE+rVPoUahrI9sLGYTzit1aX5ppUgFAlwqrYAACgkQzit1aX5p
pUgDtAwApnU2595pO10vRTuqKZCscCE0DH2Qi/P7/v3ebPKBO+luHWXU0V+4PtaM
VdMCfmRJOmrKY9AKEVodNcA6a6kuCdO2cLvunHiWdvAzomYvGd2n7AxWEda3p+wh
u7raNPMhF57YSVyKKpaF4MxO46KR6MvJLsNZ3304yMTcAl4gT4ZujnVG4HZOurcW
xTIIvYrYlGTssVLJmuOBoUSyJHg4DdcDa8rZfncfDbunkVWT4BzB4PZNB4jGfccG
9vgUd34kSYajNNeThDa+cJ4TROiigSFhVMMyua8gqd0l8Pm9Kkzjs3YezL5islNQ
9OH7I+dB/X04xkAIba+Ifs+UjVFRK6tWWZRQ342MvVxs/V1R5S8vW4wKZwpU4TEV
D8RST1gLp7REB4KQUADnft9EEyYK8c8yDr+LsxLQd/UKdKgkEQMLVxOeTrhemVx6
7dov5TofVCI2XJT0azFbZWNSvhHVTbulUE3GrRKBEQLus9XnsMDIrKjoiBINcFRp
euiR0wMg
=dZ5k
-----END PGP SIGNATURE-----

@maflcko maflcko merged commit c001da3 into bitcoin:master Oct 22, 2021
sidhujag pushed a commit to syscoin/syscoin that referenced this pull request Oct 22, 2021
@bitcoin bitcoin locked and limited conversation to collaborators Oct 30, 2022
@glozow glozow deleted the 2021-10-exists-txid branch July 20, 2023 12:12
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

7 participants