Skip to content
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

Fix height serialization inside script of coinbase input #14633

Conversation

kostyantyn
Copy link
Contributor

According to the specification https://github.com/bitcoin/bips/blob/master/bip-0034.mediawiki,
height is serialized as: "first byte is number of bytes in the number, ...
following bytes are little-endian representation of the number"

However, CScript() << nHeight invokes push_int64 function which has
different serialization strategy for numbers smaller than 17.

The current implementation doesn't cause any issues as BIP34 is enabled from height 227931.
But, if in regtest set consensus.BIP34Height=1 (which can be convenient to test BIP34),
most of the tests will fail as they follow the specification.

@DrahtBot
Copy link
Contributor

DrahtBot commented Nov 1, 2018

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

Conflicts

No conflicts as of last run.

@kostyantyn kostyantyn force-pushed the fix_height_serialization_in_coinbase branch from cc12945 to 65b8c8c Compare November 1, 2018 22:45
According to the specification https://github.com/bitcoin/bips/blob/master/bip-0034.mediawiki,
height is serialized as: "first byte is number of bytes in the number, ...
following bytes are little-endian representation of the number"

However, `CScript() << nHeight` invokes `push_int64` function which has
different serialization strategy for numbers smaller than 17.

The current implementation doesn't cause any issues as BIP34 is enabled from height 227931.
But, if in regtest set `consensus.BIP34Height=1` (which can be convenient to test BIP34),
most of the tests will fail as they follow the specification.
@Gnappuraz
Copy link
Contributor

utACK f151162

@gmaxwell
Copy link
Contributor

gmaxwell commented Nov 3, 2018

It's not clear to me that moving further away from canonical encoding would be a good idea.

@scravy
Copy link
Contributor

scravy commented Nov 5, 2018

ACK f151162

I very much appreciate this change. In the end it does not change anything in bitcoin (height above 16 is serialized the same way), but it adheres to the specification in BIP34 which explicitly states:

The format of the height is "serialized CScript" -- first byte is number of bytes in the number (will be 0x03 on main net for the next 150 or so years with 223-1 blocks), following bytes are little-endian representation of the number (including a sign bit).

That clearly says the serialization is: first byte is the number of bytes in the number.

If I, say, wanted to start a testnet and start from scratch, and have a blockchain explorer for this which parses the height form the coinbase, then this would be one strange issue less I'd have to combat.

scravy pushed a commit to dtr-org/unit-e that referenced this pull request Nov 5, 2018
Ported from bitcoin/bitcoin#14633

For bitcoin it's a minor fix as it doesn't cause any problems
but as we want to enable height verification from the beginning
we need to either fix cpp code or adjust BIP34 and fix tests.
@laanwj
Copy link
Member

laanwj commented Nov 6, 2018

It's not clear to me that moving further away from canonical encoding would be a good idea.

This has been in the implementation so long, and for bitcoin the implementation is the final 'spec'. Might be better to update the BIP at this point.

@sdaftuar
Copy link
Member

sdaftuar commented Nov 7, 2018

I tend to agree with @laanwj -- seems to me there is more benefit in updating the BIP (and/or adding a comment to the code, highlighting the issue) than in changing the behavior.

@kostyantyn
Copy link
Contributor Author

It doesn't change the behavior of the bitcoin as existing implementation also invokes CScriptNum::serialize for numbers larger than 16, I don't see how it can affect the network.

The good thing is that it allows testing BIP34 starting from the first block after the genesis. This can be convenient once it's decided to enable BIP34 from the height=1 in regtest. And it seems there is an intention of doing this as create_coinbase(height, pubkey=None) accepts the height and its value is correctly incremented in tests. Otherwise, we would need to pre-mine 16 blocks with BIP34 off in all functional tests. It looks like a weird workaround that can be avoided.

However, I see it's a minor change, and there are ways to work around it if needed. Let me know if there is anything I can help here.

@luke-jr
Copy link
Member

luke-jr commented Dec 20, 2018

@laanwj The implementation does not enforce BIP34 code for the affected blocks, so the "code trumps the spec" logic does not apply.

  • Eloipool implements this according to BIP34.
  • ckpool implements this according to BIP34.
  • libblkmaker implements this according to BIP34.
  • cgminer implements this according to BIP34.

In other words, the only violation of this is in a hypothetical (dead code) path in Bitcoin Core.

Additionally, using the "canonical" encoding would significantly complicate implementation.

For the reasons above, I think fixing this in Core is the correct solution. (Or at least documenting it as a known limitation tolerated because BIP34 isn't active at such heights.)

utACK

@sdaftuar
Copy link
Member

sdaftuar commented Jan 7, 2019

(Or at least documenting it as a known limitation tolerated because BIP34 isn't active at such heights.)

I think documentation (in the form of a code comment) is exactly what is called for if we want to improve things, rather than a code change. There is no benefit to users of our software from changing this consensus-critical code as proposed, but there is a higher review burden -- I think we should avoid making these kind of changes.

@laanwj
Copy link
Member

laanwj commented Jul 3, 2019

Closing this, the change is controversial and (at best) wouldn't make any difference, at worst it'd introduce a consensus bug. Pros/cons just don't weight up.

I think documentation (in the form of a code comment) is exactly what is called for if we want to improve things

Yes.

@laanwj laanwj closed this Jul 3, 2019
maflcko pushed a commit to maflcko/bitcoin-core that referenced this pull request Aug 5, 2019
fa8489a test: Add test for BIP30 duplicate tx (MarcoFalke)
77770d9 test: Properly serialize BIP34 coinbase height (MarcoFalke)

Pull request description:

  This adds a test for BIP30 to check that duplicate txs can exist in the blockchain given the first one was completely spent when the second one is added. (Requested by ajtowns in bitcoin#16333 (comment))

  We can not add a test that a later duplicate tx overwrites a previous one, because BIP30 is always enforced on regtest. If someone feels strongly about such a test, some Bitcoin Core code would have to be modified, which can be done in a follow up pull request.

  Also, add a commit to fix the BIP34 test failures reported in bitcoin#14633 (comment)

ACKs for top commit:
  laanwj:
    Code review ACK fa8489a

Tree-SHA512: c707d0bdc93937263876b603425b53322a2a9f9ec3f50716ae2fa9de8ddc644beb22b26c1bfde7f4aab102633e096b354ef380db919176bd2cb44a2828f884aa
sidhujag pushed a commit to syscoin/syscoin that referenced this pull request Aug 10, 2019
fa8489a test: Add test for BIP30 duplicate tx (MarcoFalke)
77770d9 test: Properly serialize BIP34 coinbase height (MarcoFalke)

Pull request description:

  This adds a test for BIP30 to check that duplicate txs can exist in the blockchain given the first one was completely spent when the second one is added. (Requested by ajtowns in bitcoin#16333 (comment))

  We can not add a test that a later duplicate tx overwrites a previous one, because BIP30 is always enforced on regtest. If someone feels strongly about such a test, some Bitcoin Core code would have to be modified, which can be done in a follow up pull request.

  Also, add a commit to fix the BIP34 test failures reported in bitcoin#14633 (comment)

ACKs for top commit:
  laanwj:
    Code review ACK fa8489a

Tree-SHA512: c707d0bdc93937263876b603425b53322a2a9f9ec3f50716ae2fa9de8ddc644beb22b26c1bfde7f4aab102633e096b354ef380db919176bd2cb44a2828f884aa
ShengguangXiao pushed a commit to DeFiCh/ain that referenced this pull request Aug 28, 2020
5bf58be test: Add test for BIP30 duplicate tx (MarcoFalke)
8725c48 test: Properly serialize BIP34 coinbase height (MarcoFalke)

Pull request description:

  This adds a test for BIP30 to check that duplicate txs can exist in the blockchain given the first one was completely spent when the second one is added. (Requested by ajtowns in bitcoin/bitcoin#16333 (comment))

  We can not add a test that a later duplicate tx overwrites a previous one, because BIP30 is always enforced on regtest. If someone feels strongly about such a test, some Bitcoin Core code would have to be modified, which can be done in a follow up pull request.

  Also, add a commit to fix the BIP34 test failures reported in bitcoin/bitcoin#14633 (comment)

ACKs for top commit:
  laanwj:
    Code review ACK 5bf58be

Tree-SHA512: c707d0bdc93937263876b603425b53322a2a9f9ec3f50716ae2fa9de8ddc644beb22b26c1bfde7f4aab102633e096b354ef380db919176bd2cb44a2828f884aa
Munkybooty pushed a commit to Munkybooty/dash that referenced this pull request Nov 25, 2021
fa8489a test: Add test for BIP30 duplicate tx (MarcoFalke)
77770d9 test: Properly serialize BIP34 coinbase height (MarcoFalke)

Pull request description:

  This adds a test for BIP30 to check that duplicate txs can exist in the blockchain given the first one was completely spent when the second one is added. (Requested by ajtowns in bitcoin#16333 (comment))

  We can not add a test that a later duplicate tx overwrites a previous one, because BIP30 is always enforced on regtest. If someone feels strongly about such a test, some Bitcoin Core code would have to be modified, which can be done in a follow up pull request.

  Also, add a commit to fix the BIP34 test failures reported in bitcoin#14633 (comment)

ACKs for top commit:
  laanwj:
    Code review ACK fa8489a

Tree-SHA512: c707d0bdc93937263876b603425b53322a2a9f9ec3f50716ae2fa9de8ddc644beb22b26c1bfde7f4aab102633e096b354ef380db919176bd2cb44a2828f884aa
Munkybooty pushed a commit to Munkybooty/dash that referenced this pull request Nov 25, 2021
fa8489a test: Add test for BIP30 duplicate tx (MarcoFalke)
77770d9 test: Properly serialize BIP34 coinbase height (MarcoFalke)

Pull request description:

  This adds a test for BIP30 to check that duplicate txs can exist in the blockchain given the first one was completely spent when the second one is added. (Requested by ajtowns in bitcoin#16333 (comment))

  We can not add a test that a later duplicate tx overwrites a previous one, because BIP30 is always enforced on regtest. If someone feels strongly about such a test, some Bitcoin Core code would have to be modified, which can be done in a follow up pull request.

  Also, add a commit to fix the BIP34 test failures reported in bitcoin#14633 (comment)

ACKs for top commit:
  laanwj:
    Code review ACK fa8489a

Tree-SHA512: c707d0bdc93937263876b603425b53322a2a9f9ec3f50716ae2fa9de8ddc644beb22b26c1bfde7f4aab102633e096b354ef380db919176bd2cb44a2828f884aa
Munkybooty pushed a commit to Munkybooty/dash that referenced this pull request Nov 30, 2021
fa8489a test: Add test for BIP30 duplicate tx (MarcoFalke)
77770d9 test: Properly serialize BIP34 coinbase height (MarcoFalke)

Pull request description:

  This adds a test for BIP30 to check that duplicate txs can exist in the blockchain given the first one was completely spent when the second one is added. (Requested by ajtowns in bitcoin#16333 (comment))

  We can not add a test that a later duplicate tx overwrites a previous one, because BIP30 is always enforced on regtest. If someone feels strongly about such a test, some Bitcoin Core code would have to be modified, which can be done in a follow up pull request.

  Also, add a commit to fix the BIP34 test failures reported in bitcoin#14633 (comment)

ACKs for top commit:
  laanwj:
    Code review ACK fa8489a

Tree-SHA512: c707d0bdc93937263876b603425b53322a2a9f9ec3f50716ae2fa9de8ddc644beb22b26c1bfde7f4aab102633e096b354ef380db919176bd2cb44a2828f884aa
@bitcoin bitcoin locked as resolved and limited conversation to collaborators Dec 16, 2021
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.

9 participants