Skip to content

Conversation

@w0xlt
Copy link
Contributor

@w0xlt w0xlt commented Aug 6, 2022

As suggested in #25787, this PR adds tests for datacarrier and datacarriersize initialization options.

Close #25787.

Copy link
Contributor

@theStack theStack left a comment

Choose a reason for hiding this comment

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

Concept ACK

Thanks for improving test coverage! Seems like the implementation can be simplified in many ways, I'd suggest to:

  • using MiniWallet's default mode (ADDRESS_OP_TRUE), since we are only concerned with modifying outputs here; there is no need to use the P2PK mode
  • use the UTXOs from the pre-mined test chain instead of generating new ones; they can be imported via self.wallet.rescan_utxos() (see many other tests, e.g. p2p_filter.py)
  • shorten the create_null_data_transaction helper by creating a zero-fee template tx with MiniWallet's create_self_transfer (we are not interested in setting the inputs manually), append the datacarrier output and then deduct the fee manually, e.g. something like this should be sufficient (admittedly, still a bit hacky though):
tx = self.wallet.create_self_transfer(fee_rate=0)["tx"]
tx.vout.append(CTxOut(nValue=0, scriptPubKey=script))
tx.vout[0].nValue -= tx.get_vsize()  # simply pay 1sat/vbyte fee
return tx

@w0xlt w0xlt force-pushed the test_data_carrier branch 4 times, most recently from 65b11c8 to 8677781 Compare August 7, 2022 05:46
@w0xlt
Copy link
Contributor Author

w0xlt commented Aug 7, 2022

@theStack thanks for detailed review and suggestions.
They really simplified the code. I added you as co-author.

Copy link
Member

@glozow glozow left a comment

Choose a reason for hiding this comment

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

Concept ACK, thanks for working on this.

To test differences between a default and a configured node, I'd recommend you create 2 nodes with different policies and submit transactions to both, instead of restarting.

@brunoerg
Copy link
Contributor

brunoerg commented Aug 8, 2022

Concept ACK

Copy link
Contributor

@stickies-v stickies-v left a comment

Choose a reason for hiding this comment

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

Approach ACK 8677781f4

Just left a few style nits

Comment on lines 7 to 19
Copy link
Contributor

Choose a reason for hiding this comment

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

nit: I think one-line alphabetically sorted is a bit easier to read

Suggested change
from test_framework.script import (
CScript,
OP_RETURN,
)
from test_framework.wallet import (
MiniWallet
)
from test_framework.messages import (
CTxOut,
)
from test_framework.util import (
assert_raises_rpc_error,
)
from test_framework.messages import CTxOut
from test_framework.script import CScript, OP_RETURN
from test_framework.test_framework import BitcoinTestFramework
from test_framework.util import assert_raises_rpc_error
from test_framework.wallet import MiniWallet

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Done in 10bfe12.

Copy link
Contributor

Choose a reason for hiding this comment

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

AFAIK, we usually prefer multi-line over single-line imports in order to avoid potential merge conflicts. I opened a PR to hopefully get some consensus on how strict this (so far unwritten) rule should be followed: #25811

Copy link
Contributor

Choose a reason for hiding this comment

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

nit: PEP8 requires 2 blank lines before class definition

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Done in 10bfe12

Copy link
Contributor

Choose a reason for hiding this comment

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

adding a short message can help debugging:

Suggested change
assert(tx.rehash() in self.nodes[0].getrawmempool(True))
assert(tx.rehash() in self.nodes[0].getrawmempool(True), f"{tx_hex} not in mempool")

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Done in 10bfe12

Copy link
Contributor

Choose a reason for hiding this comment

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

nit: missing whiteline

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Done in 10bfe12

Copy link
Contributor

Choose a reason for hiding this comment

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

nit: the style guidelines suggest adding type hints

Suggested change
def create_null_data_transaction(self, script):
def create_null_data_transaction(self, script: CScript) -> CTransaction:

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Done in 10bfe12

Copy link
Contributor

Choose a reason for hiding this comment

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

nit: I think this variable name could be a bit more descriptive (and script could be renamed to short_script)

Suggested change
script2 = CScript([OP_RETURN, data])
too_long_script = CScript([OP_RETURN, data])

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Done in 10bfe12. Thanks for the review.

Copy link
Contributor

@theStack theStack left a comment

Choose a reason for hiding this comment

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

LGTM. Some more suggestions (feel free to ignore, or do in a follow-up):

  • The interface for the create_null_data_transaction method would be IMHO more logical if only the null-data payload (type bytes) is passed; the scriptPubKey with prepended OP_RETURN could then be created in there instead of the need to do that repeatedly at the caller's side
  • The same approach of testing the exact boundaries (as suggested by glozow) could also be applied to the custom set datacarriersize limit
  • It's usually preferred to name policy- or consensus-relevant constants in the functional test framework the same as in the C++ codebase (see e.g. #25596), i.e. in this case this would be MAX_OP_RETURN_RELAY (which is 83 and not 80 though, as it denotes the serialized size of the whole scriptPubKey; "+1 for OP_RETURN, 2 for the pushdata opcodes")

Copy link
Contributor

Choose a reason for hiding this comment

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

Would suggest to use the deterministic random_bytes helper instead (to be found in test_framework.util). (Background: also used the urandom approach for generating random data recently in a PR and got a review with good counter-arguments: #25625 (comment))

Copy link
Contributor Author

@w0xlt w0xlt Aug 9, 2022

Choose a reason for hiding this comment

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

Great suggestions! All have been addressed in 1650f9457bc1c3cfecde554522f3c38ca18ef04c.

@DrahtBot
Copy link
Contributor

DrahtBot commented Aug 9, 2022

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

Conflicts

No conflicts as of last run.

Copy link
Contributor

@stickies-v stickies-v left a comment

Choose a reason for hiding this comment

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

ACK 1650f9457bc1c3cfecde554522f3c38ca18ef04c

edit: modulo MarcoFalke's comment regarding -datacarrier=true

Copy link
Member

@maflcko maflcko Aug 10, 2022

Choose a reason for hiding this comment

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

This parses as =0 (The test fails regardless of the second option)

Probably a good time to make this an init error finally.

Copy link
Contributor

@stickies-v stickies-v Aug 10, 2022

Choose a reason for hiding this comment

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

FYI for anyone else confused about this, see the docs of InterpretBool():

non-numeric string values like "foo", return 0

so -datacarrier=false and -datacarrier=true all resolve to -datacarrier=0.

As such, should be:

            ["-datacarrier=0"],
            ["-datacarrier=1", f"-datacarriersize={MAX_OP_RETURN_RELAY - 1}"]

Good catch MarcoFalke!

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Interesting! I applied the requested change and added a new test that checks that "-datacarrier=1" works.

Copy link
Member

Choose a reason for hiding this comment

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

See also #16545

@w0xlt w0xlt force-pushed the test_data_carrier branch from 1650f94 to 02bcfe2 Compare August 10, 2022 15:42
maflcko pushed a commit to bitcoin-core/gui that referenced this pull request Aug 10, 2022
… functional test style guide

4edc689 doc: test: suggest multi-line imports in functional test style guide (Sebastian Falbesoner)

Pull request description:

  As long as I remember contributing to functional tests (~2-3 years), it was always kind of an unwritten rule that multi-line imports are preferred over single-line imports in order to reduce the possibility of potential merge conflicts -- at least if more than one symbol from a module is imported. This PR adds this rule to the style guide and adapts the example test accordingly. (Inspired by bitcoin/bitcoin#25792 (comment)).

ACKs for top commit:
  kouloumos:
    ACK 4edc689
  1440000bytes:
    ACK bitcoin/bitcoin@4edc689
  w0xlt:
    ACK bitcoin/bitcoin@4edc689
  fanquake:
    ACK 4edc689

Tree-SHA512: c7b6ff62f601f4e57cc8334d291662987d6737ebca8d81c063280409f4412302172f1404ec16afc9a13007bcdba55bdab66b9b80363287e287888929cb386584
@w0xlt w0xlt force-pushed the test_data_carrier branch from 02bcfe2 to 4bebb81 Compare August 10, 2022 19:10
@w0xlt
Copy link
Contributor Author

w0xlt commented Aug 10, 2022

Rebased.

sidhujag pushed a commit to syscoin/syscoin that referenced this pull request Aug 11, 2022
…nal test style guide

4edc689 doc: test: suggest multi-line imports in functional test style guide (Sebastian Falbesoner)

Pull request description:

  As long as I remember contributing to functional tests (~2-3 years), it was always kind of an unwritten rule that multi-line imports are preferred over single-line imports in order to reduce the possibility of potential merge conflicts -- at least if more than one symbol from a module is imported. This PR adds this rule to the style guide and adapts the example test accordingly. (Inspired by bitcoin#25792 (comment)).

ACKs for top commit:
  kouloumos:
    ACK 4edc689
  1440000bytes:
    ACK bitcoin@4edc689
  w0xlt:
    ACK bitcoin@4edc689
  fanquake:
    ACK 4edc689

Tree-SHA512: c7b6ff62f601f4e57cc8334d291662987d6737ebca8d81c063280409f4412302172f1404ec16afc9a13007bcdba55bdab66b9b80363287e287888929cb386584
Copy link
Contributor

@theStack theStack left a comment

Choose a reason for hiding this comment

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

ACK 4bebb81622eb71a83db1d46ca84c09f7e1ab7f9a

I think the methods test_transaction and create_null_data_transaction could be merged into one (e.g. something like test_null_data_transaction with node, data and success parameters) to reduce it to even less code at the callers side, since we don't reuse any of the transactions anyway, but no hard feelings.

Comment on lines 7 to 8
Copy link
Contributor

Choose a reason for hiding this comment

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

yocto-nit: sorted order

Suggested change
CTxOut,
CTransaction,
CTransaction,
CTxOut,

Copy link
Contributor

@stickies-v stickies-v left a comment

Choose a reason for hiding this comment

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

re-ACK 4bebb81 - verified changes are limited to fixing the startup arguments and adding a new test to check the happy path with a lower-than-default datacarriersize

git range-diff 93999a5 1650f94 4bebb81
1:  1650f9457 ! 1:  4bebb8162 test: add tests for `datacarrier` and `datacarriersize` options
    @@ test/functional/mempool_datacarrier.py (new)
     +        self.num_nodes = 3
     +        self.extra_args = [
     +            [],
    -+            ["-datacarrier=false"],
    -+            ["-datacarrier=true", f"-datacarriersize={MAX_OP_RETURN_RELAY - 1}"]
    ++            ["-datacarrier=0"],
    ++            ["-datacarrier=1", f"-datacarriersize={MAX_OP_RETURN_RELAY - 1}"]
     +        ]
     +
     +    def test_transaction(self, node: TestNode, tx: CTransaction, success: bool):
    @@ test/functional/mempool_datacarrier.py (new)
     +        # By default, only 80 bytes are used for data (+1 for OP_RETURN, +2 for the pushdata opcodes).
     +        default_size_data = random_bytes(MAX_OP_RETURN_RELAY - 3)
     +        too_long_data = random_bytes(MAX_OP_RETURN_RELAY - 2)
    ++        small_data = random_bytes(MAX_OP_RETURN_RELAY - 4)
     +
     +        self.log.info("Testing null data transaction with default -datacarrier and -datacarriersize values.")
     +        tx = self.create_null_data_transaction(default_size_data)
    @@ test/functional/mempool_datacarrier.py (new)
     +        tx3 = self.create_null_data_transaction(default_size_data)
     +        self.test_transaction(self.nodes[1], tx3, success=False)
     +
    -+        self.log.info("Testing a null data transaction with a small -datacarriersize value.")
    ++        self.log.info("Testing a null data transaction with a size larger than accepted by -datacarriersize.")
     +        tx4 = self.create_null_data_transaction(default_size_data)
     +        self.test_transaction(self.nodes[2], tx4, success=False)
     +
    ++        self.log.info("Testing a null data transaction with a size smaller than accepted by -datacarriersize.")
    ++        tx5 = self.create_null_data_transaction(small_data)
    ++        self.test_transaction(self.nodes[2], tx5, success=True)
    ++
     +
     +if __name__ == '__main__':
     +    DataCarrierTest().main()
     
      ## test/functional/test_framework/messages.py ##
    -@@ test/functional/test_framework/messages.py: FILTER_TYPE_BASIC = 0
    - 
    - WITNESS_SCALE_FACTOR = 4
    +@@ test/functional/test_framework/messages.py: WITNESS_SCALE_FACTOR = 4
    + DEFAULT_ANCESTOR_LIMIT = 25    # default max number of in-mempool ancestors
    + DEFAULT_DESCENDANT_LIMIT = 25  # default max number of in-mempool descendants
      
     +# Default setting for -datacarriersize. 80 bytes of data, +1 for OP_RETURN, +2 for the pushdata opcodes.
     +MAX_OP_RETURN_RELAY = 83

@w0xlt w0xlt force-pushed the test_data_carrier branch 2 times, most recently from 1d64dc4 to ea77b73 Compare August 11, 2022 14:57
@w0xlt
Copy link
Contributor Author

w0xlt commented Aug 11, 2022

#25792 (review) addressed in 8b3d2bb

@w0xlt w0xlt force-pushed the test_data_carrier branch from ea77b73 to 8b3d2bb Compare August 11, 2022 15:06
Copy link
Contributor

@theStack theStack left a comment

Choose a reason for hiding this comment

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

re-ACK 8b3d2bb

Copy link
Contributor

@stickies-v stickies-v left a comment

Choose a reason for hiding this comment

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

re-ACK 8b3d2bb

@maflcko maflcko merged commit 29c195c into bitcoin:master Aug 11, 2022
DEFAULT_DESCENDANT_LIMIT = 25 # default max number of in-mempool descendants

# Default setting for -datacarriersize. 80 bytes of data, +1 for OP_RETURN, +2 for the pushdata opcodes.
MAX_OP_RETURN_RELAY = 83
Copy link
Member

Choose a reason for hiding this comment

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

Not sure if we want to use messages.py for default values of settings. Maybe leave them in the only test that needs them for now (if there is only one), or create a new default_settings.py module (or a mempool.py one?)

@w0xlt w0xlt deleted the test_data_carrier branch August 11, 2022 16:42
sidhujag pushed a commit to syscoin/syscoin that referenced this pull request Aug 11, 2022
…ersize` options

8b3d2bb test: add tests for `datacarrier` and `datacarriersize` options (w0xlt)

Pull request description:

  As suggested in bitcoin#25787, this PR adds tests for `datacarrier` and `datacarriersize` initialization options.

  Close bitcoin#25787.

ACKs for top commit:
  theStack:
    re-ACK 8b3d2bb
  stickies-v:
    re-ACK bitcoin@8b3d2bb

Tree-SHA512: 962638ac9659f9d641bc5d1eff0571a08085dc7d4981b534b7ede03e4c702abd7048d543c199a588e2f94567b6d2393280e686629b19d7f4b24d365662be5e40
@bitcoin bitcoin locked and limited conversation to collaborators Aug 11, 2023
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

no test coverage for -datacarrier and -datacarriersize

7 participants