Skip to content

Tests: enforce critical class instance attributes in functional tests, fix segwit test specificity#14305

Merged
maflcko merged 5 commits into
bitcoin:masterfrom
JustinTArthur:functional-test-attr-enforcement
Sep 27, 2018
Merged

Tests: enforce critical class instance attributes in functional tests, fix segwit test specificity#14305
maflcko merged 5 commits into
bitcoin:masterfrom
JustinTArthur:functional-test-attr-enforcement

Conversation

@JustinTArthur

@JustinTArthur JustinTArthur commented Sep 24, 2018

Copy link
Copy Markdown
Contributor

No extra attributes will be able to be added to instances of the C++ class ports or of other critical classes without causing an exception. Helps prevent adding or depending on attributes that aren't in the intended object structure. It may prevent issues such as the one fixed in #14300.

This request fixes the erroneous version attribute used in the p2p_segwit.py functional tests. This pull includes the commit from #14300.

@fanquake fanquake added the Tests label Sep 24, 2018
@JustinTArthur

JustinTArthur commented Sep 24, 2018

Copy link
Copy Markdown
Contributor Author

Travis tests should be re-run following the merge of #14300. Rebased this PR on #14300, so dependency isn't an issue.

@JustinTArthur JustinTArthur force-pushed the functional-test-attr-enforcement branch from bb803fe to 965c8ff Compare September 24, 2018 03:31
@DrahtBot

DrahtBot commented Sep 24, 2018

Copy link
Copy Markdown
Contributor
Reviewers, this pull request conflicts with the following ones:

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.

@JustinTArthur JustinTArthur changed the title Functional test attribute enforcement Tests: enforce critical class instance attributes in functional tests Sep 24, 2018
@practicalswift

practicalswift commented Sep 24, 2018

Copy link
Copy Markdown
Contributor

What an excellent first-time contribution! Thanks!

This is my favourite type of contribution: it not only fixes current code but also fixes future code by introducing a mechanism that helps us avoid introducing new instances of the same class of issue. Exactly the type of contribution that I was referring to in #14217 (comment):

Personally I'm much more excited to see a PR submitted which strengthens the long term security of the project in some form compared to when I see a PR submitted which implements some shiny new feature :-)

In addition to the above: __slots__ is also an unambiguous improvement from a memory usage perspective.

utACK 965c8ff9c7539719eb36bd46297358e33b571766

@jnewbery

Copy link
Copy Markdown
Contributor

Concept ACK.

There's some suggestion in this thread: https://stackoverflow.com/questions/472000/usage-of-slots that using __slots__ to constrain attribute creation is discouraged. However, I've searched for a few minutes and haven't been able to find a 'better' way to do it.

Comment thread test/functional/p2p_segwit.py Outdated

Copy link
Copy Markdown
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 demonstrate that this fails due to the correct reason: "non-mandatory-script-verify-flag (Witness program was passed an empty witness)"

You can achieve this with the assert_debug_log helper.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

I agree. Thanks for the tip on assert_debug_log. I'm more familiar with Python than I am of the test suite. Addressed in a new commit.

Comment thread test/functional/p2p_segwit.py Outdated

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Same here: The reject reason is just the same as above, whereas it now should be "mandatory-script-verify-flag-failed (Script evaluated without error but finished with a false/empty top stack element)"

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Addressed in a new commit.

@maflcko

maflcko commented Sep 24, 2018

Copy link
Copy Markdown
Member

Concept ACK. I guess this could also be implemented with a "frozen" decorator, which freezes the attributes after __init__.

It worries me that the tests just pass with or without this fix, which doesn't add much value to the fix. Would you mind changing the tests itself, such that they would fail without, but pass with the change. (See inline comments)

@gmaxwell

Copy link
Copy Markdown
Contributor

You are my hero of the day. I am python ignorant, and so I'm only concept ACKing because (1) I've run into this problem before and been frustrated, (2) I see people who know the tests better haven't opposed it, and (3) I asked for someone to fix this. :P

@JustinTArthur

Copy link
Copy Markdown
Contributor Author

Concept ACK. I guess this could also be implemented with a "frozen" decorator, which freezes the attributes after __init__.

I'm not opposed to moving to that at some point. Using __slots__ everywhere makes the code more verbose, where Python can otherwise excel at being concise. Unfortunately, these tests seem to do a bit of assignment after initialization so some refactoring would be necessary.

Added some checks for specific transaction acceptance failures in the debug log per @MarcoFalke's suggestion. Now at least the scriptSig typo would have caused a failure.

Thanks for the feedback, @MarcoFalke @gmaxwell and @practicalswift.

@JustinTArthur

JustinTArthur commented Sep 26, 2018

Copy link
Copy Markdown
Contributor Author

@MarcoFalke I've created an alternate implementation that uses a freezing decorator as you've suggested:
master...JustinTArthur:functional-test-attr-enforcement-decorator
Decorator implementation isn't great to look at, but makes the classes easier on the eyes. We'd lose the performance benefits of __slots__, if that matters. Unlike the freezing method used by attrs and Python 3.7 data classes, this will allow re-assignment of initialized attributes.

If the new implementation is preferred across the board, I can replace this PR's commits with the alternate ones. For what it's worth, I prefer __slots__. I don't think it's an aspect of the language at risk of breaking in the Python 3.x timeframe and while using double-underscore stuff never looks great, I don't see __slots__ as being much different from supplying an __init__. We're starting to see __slots__ mentioned in more of the higher level Python docs.

@JustinTArthur JustinTArthur changed the title Tests: enforce critical class instance attributes in functional tests Tests: enforce critical class instance attributes in functional tests, fix segwit test specificity Sep 26, 2018
@ken2812221

Copy link
Copy Markdown
Contributor

Concept ACK. Will try to learn how __slots__ work.

@promag

promag commented Sep 26, 2018

Copy link
Copy Markdown
Contributor

Concept ACK, +1 __slots__ for this case.

@maflcko maflcko left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

I slightly prefer the decorator for its brevity when used and thus easy reusability. We don't care about performance improvements if they are not significant or can not be measured.

Though, if slots are the commonly the preferred thing, I am fine with that.

Comment thread test/functional/p2p_segwit.py Outdated

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

nit: Could use the full error message here?

'was not accepted: mandatory-script-verify-flag-failed (Script evaluated without error but finished with a false/empty top stack element)'

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Reasonable, will adjust commit.

Comment thread test/functional/p2p_segwit.py Outdated

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

nit: Could use the full error message here?

'was not accepted: non-mandatory-script-verify-flag (Witness program was passed an empty witness)'

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Reasonable, will adjust commit.

@jnewbery

Copy link
Copy Markdown
Contributor

Concept ACK either approach. I slightly prefer the __slots__ approach, since it seems more explicit to me and doesn't require us to roll our own attribute-fixing code, but I'm happy with either.

@maflcko

maflcko commented Sep 26, 2018

Copy link
Copy Markdown
Member

Ok, let's keep the slots then.

@practicalswift

practicalswift commented Sep 26, 2018

Copy link
Copy Markdown
Contributor

Agree with @jnewbery – the explicitness of __slots__ is nice. Also: it is more idiomatic since it works out of the box without any extra code.

From the Zen of Python:

  • Explicit is better than implicit.
  • There should be one – and preferably only one – obvious way to do it.

:-)

@jimmysong jimmysong left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

ACK

Nice use of the slots feature! I would like to see something instructing new devs in the Python testing documentation (functional/README.md) so people don't trip over it.

Comment thread test/functional/test_framework/script.py Outdated
Per @jimmysong's suggestion in bitcoin#14305. Also corrects
module for network objects and wrappers.
@JustinTArthur JustinTArthur force-pushed the functional-test-attr-enforcement branch from 35c9a46 to e460232 Compare September 27, 2018 03:15
@JustinTArthur

Copy link
Copy Markdown
Contributor Author

Revised commits to incorporate code comment suggestions from @MarcoFalke and @jimmysong.

@jimmysong jimmysong left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Thanks for the changes!

ACK

@jnewbery

Copy link
Copy Markdown
Contributor

utACK e460232

@maflcko

maflcko commented Sep 27, 2018

Copy link
Copy Markdown
Member

utACK e460232

@maflcko maflcko merged commit e460232 into bitcoin:master Sep 27, 2018
maflcko pushed a commit that referenced this pull request Sep 27, 2018
…nctional tests, fix segwit test specificity

e460232 Document fixed attribute behavior in critical test framework classes. (Justin Turner Arthur)
17b42f4 Check for specific tx acceptance failures based on script signature (Justin Turner Arthur)
3a4449e Strictly enforce instance attrs in critical functional test classes. (Justin Turner Arthur)
1d0ce94 Fix for incorrect version attr set on functional test segwit block. (Justin Turner Arthur)
ba923e3 test: Fix broken segwit test (practicalswift)

Pull request description:

  No extra attributes will be able to be added to instances of the C++ class ports or of other critical classes without causing an exception. Helps prevent adding or depending on attributes that aren't in the intended object structure. It may prevent issues such as the one fixed in #14300.

  This request fixes the erroneous version attribute used in the p2p_segwit.py functional tests. This pull includes the commit from #14300.

Tree-SHA512: 1b8c58e7aa0f71075ed5ff3e5be0a5182599108d8cd9bce682feac3b1842508124288e9335432b16a43f40f159c9710899e6d84af1b5868f48c947bc6f3e07ec
@JustinTArthur JustinTArthur deleted the functional-test-attr-enforcement branch September 28, 2018 05:20
Bushstar pushed a commit to Bushstar/Feathercoin that referenced this pull request Oct 9, 2018
Per @jimmysong's suggestion in bitcoin/bitcoin#14305. Also corrects
module for network objects and wrappers.
jfhk pushed a commit to jfhk/bitcoin that referenced this pull request Nov 14, 2018
Per @jimmysong's suggestion in bitcoin#14305. Also corrects
module for network objects and wrappers.
SmarterHomes pushed a commit to SmarterHomes/chaincoin that referenced this pull request Nov 26, 2018
Per @jimmysong's suggestion in bitcoin#14305. Also corrects
module for network objects and wrappers.
pravblockc pushed a commit to pravblockc/dash that referenced this pull request Jul 28, 2021
…es in functional tests, fix segwit test specificity

e460232 Document fixed attribute behavior in critical test framework classes. (Justin Turner Arthur)
17b42f4 Check for specific tx acceptance failures based on script signature (Justin Turner Arthur)
3a4449e Strictly enforce instance attrs in critical functional test classes. (Justin Turner Arthur)
1d0ce94 Fix for incorrect version attr set on functional test segwit block. (Justin Turner Arthur)
ba923e3 test: Fix broken segwit test (practicalswift)

Pull request description:

  No extra attributes will be able to be added to instances of the C++ class ports or of other critical classes without causing an exception. Helps prevent adding or depending on attributes that aren't in the intended object structure. It may prevent issues such as the one fixed in bitcoin#14300.

  This request fixes the erroneous version attribute used in the p2p_segwit.py functional tests. This pull includes the commit from bitcoin#14300.

Tree-SHA512: 1b8c58e7aa0f71075ed5ff3e5be0a5182599108d8cd9bce682feac3b1842508124288e9335432b16a43f40f159c9710899e6d84af1b5868f48c947bc6f3e07ec
pravblockc pushed a commit to pravblockc/dash that referenced this pull request Jul 30, 2021
…es in functional tests, fix segwit test specificity

e460232 Document fixed attribute behavior in critical test framework classes. (Justin Turner Arthur)
17b42f4 Check for specific tx acceptance failures based on script signature (Justin Turner Arthur)
3a4449e Strictly enforce instance attrs in critical functional test classes. (Justin Turner Arthur)
1d0ce94 Fix for incorrect version attr set on functional test segwit block. (Justin Turner Arthur)
ba923e3 test: Fix broken segwit test (practicalswift)

Pull request description:

  No extra attributes will be able to be added to instances of the C++ class ports or of other critical classes without causing an exception. Helps prevent adding or depending on attributes that aren't in the intended object structure. It may prevent issues such as the one fixed in bitcoin#14300.

  This request fixes the erroneous version attribute used in the p2p_segwit.py functional tests. This pull includes the commit from bitcoin#14300.

Tree-SHA512: 1b8c58e7aa0f71075ed5ff3e5be0a5182599108d8cd9bce682feac3b1842508124288e9335432b16a43f40f159c9710899e6d84af1b5868f48c947bc6f3e07ec
pravblockc added a commit to pravblockc/dash that referenced this pull request Aug 2, 2021
pravblockc pushed a commit to pravblockc/dash that referenced this pull request Aug 4, 2021
…s in functional tests, fix segwit test specificity

e460232 Document fixed attribute behavior in critical test framework classes. (Justin Turner Arthur)
17b42f4 Check for specific tx acceptance failures based on script signature (Justin Turner Arthur)
3a4449e Strictly enforce instance attrs in critical functional test classes. (Justin Turner Arthur)
1d0ce94 Fix for incorrect version attr set on functional test segwit block. (Justin Turner Arthur)
ba923e3 test: Fix broken segwit test (practicalswift)

Pull request description:

  No extra attributes will be able to be added to instances of the C++ class ports or of other critical classes without causing an exception. Helps prevent adding or depending on attributes that aren't in the intended object structure. It may prevent issues such as the one fixed in bitcoin#14300.

  This request fixes the erroneous version attribute used in the p2p_segwit.py functional tests. This pull includes the commit from bitcoin#14300.

Tree-SHA512: 1b8c58e7aa0f71075ed5ff3e5be0a5182599108d8cd9bce682feac3b1842508124288e9335432b16a43f40f159c9710899e6d84af1b5868f48c947bc6f3e07ec
@bitcoin bitcoin locked as resolved and limited conversation to collaborators Sep 8, 2021
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.

10 participants