-
Notifications
You must be signed in to change notification settings - Fork 2.1k
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 Benchmark Test (BenchmarkReadMessage/Funding_Locked) in the lnwire package #7356
Fix Benchmark Test (BenchmarkReadMessage/Funding_Locked) in the lnwire package #7356
Conversation
d46da4c
to
b38fb2d
Compare
Don't we do something similar for
Yes, I think this is the best way to avoid bit rot. Then when a new TLV is introduced, the test will fail and alert us that we need to update the benchmarks. |
Thanks for your review, appreciate it :) Good point, thats because the upfrontscript needs to be in the tlv-data, thats a hard requirement according to the bolts:
https://github.com/lightning/bolts/blob/master/02-peer-protocol.md therefore the compelete random string of The swapping happens here |
Because its a benchmark test, maybe its better to write a function which fills the Otherwise just passing almost empty |
3d816d5
to
fdea26a
Compare
fdea26a
to
41dc347
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks for the fix!
One suggestion below on simplifying the new code.
lnwire/message_test.go
Outdated
msg := lnwire.NewFundingLocked(lnwire.ChannelID(c), pubKey) | ||
msg.ExtraData = createExtraData(t, r) | ||
|
||
// When testing the WriteMessage function we need to populate | ||
// the alias to test the encoding of the tlv_stream in the | ||
// funding_locked message (now called channel_ready in the bolt spec). | ||
_, err = r.Read(c[:8]) | ||
require.NoError(t, err, "unable to generate channel alias") | ||
aliasScid := lnwire.NewShortChanIDFromInt( | ||
binary.BigEndian.Uint64(c[:8]), | ||
) | ||
|
||
msg.AliasScid = &aliasScid |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think we could simplify this code a bit. Something like:
msg := lnwire.FundingLocked{
ChanID: lnwire.ChannelID(c),
NextPerCommitmentPoint: pubkey,
AliasScid: lnwire.NewShortChanIDFromInt(r.Int63()),
ExtraData: make([]byte, 0),
}
The RecordProducer
stuff below to populate ExtraData
could stay the same.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Done, Though I had to keep the aliasScid separate because the AliasScid
is a pointer but the NewShortChanIDFromInt
returns a value type
41dc347
to
3025541
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM
lnwire/message_test.go
Outdated
err = lnwire.EncodeMessageExtraData(&msg.ExtraData, recordProducers...) | ||
require.NoError(t, err, "unable to encode channel alias into "+ | ||
"tlv stream") |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
IIUC, we don't need to call EncodeMessageExtraData
here, since it will also be done inside Encode
.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks you are right, its now part because we write it before 👍
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Though I think also including it in the extradata is the correct way of doing it, because normally when calling newMsgFundingLocked
I would expect a correctly filled message of this type without having to know that I need to encode
it first so the TLV data is included in the right place ?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
but I am good with both ways, I deleted it but added a remark why we do not write the TLV data in the ExtraData in the method. I think that's the best way.
make/testing_flags.mk
Outdated
@@ -101,12 +101,14 @@ ifeq ($(UNIT_TARGETED), yes) | |||
UNIT := $(GOTEST) -tags="$(DEV_TAGS) $(LOG_TAGS)" $(TEST_FLAGS) $(UNITPKG) | |||
UNIT_DEBUG := $(GOTEST) -v -tags="$(DEV_TAGS) $(LOG_TAGS)" $(TEST_FLAGS) $(UNITPKG) | |||
UNIT_RACE := $(GOTEST) -tags="$(DEV_TAGS) $(LOG_TAGS) lowscrypt" $(TEST_FLAGS) -race $(UNITPKG) | |||
UNIT_BENCH := $(GOTEST) -tags="$(DEV_TAGS) $(LOG_TAGS)" -test.bench=. -test.run=XXX $(UNITPKG) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
What's the test.run=XXX
here? Is the intent to only run very short benchmark tests to make sure they work in general but finish quickly?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
My intention with the XXX
regex was to only run the bench-mark tests without any other tests, because otherwise it would run the normal unit-tests too. And this make commd should only handle the Benchmark Tests ?
I will add a comment clarifying it, and also changed the regex to something better with NONE
which is a special value in golang and matches no tests
Hmm I understand your points regarding adding it to the CI tests, so the initial issue of this PR was, because it was not on anyone's radar that the Benchmark tests were failing. But adding them to the CI is also maybe not the right approach. Maybe only execute them for specific releases so that we make sure they do not fail and pass at least ? |
3025541
to
f95cac7
Compare
Perhaps we can just run the benchmark tests on |
I like your idea so I changed the CI workflow for Benchmark tests. |
f95cac7
to
663c90b
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks for the PR! I like that we are considering putting benchmarks into our CI, but the current approach may not add many benefits.
At the moment, for a particular PR, we run benchmarks twice, one before and one after, to assess the performance improvement brought by the PR. Running benchmarks alone, however, doesn't provide us with any useful info.
I thought about adding a new workflow here to run benchmarks periodically. Or run them per release to see the performance change between releases, or run them for particular PRs, with the help of a github bot to report the results.
So I'd say we should remove it from CI because it doesn't give us useful info. And similar bugs can get fixed whenever the benchmarks are run. Not ideal, until we can properly figure out how to run them automatically.
What do you mean by "run twice" here, are the benchmarks already included in some kind of test-script or "should" a developer run the benchmark tests twice? Anyways I agree maybe just put them out of the CI for now as you said and look in a separate PR how we can integrate the benchmarks properly. |
663c90b
to
ad1bc03
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM👍
What do you mean by "run twice" here, are the benchmarks already included in some kind of test-script or "should" a developer run the benchmark tests twice?
I meant the developer should run it twice to understand the performance change. An example would be #4884, which used the bench results to guide the code change.
ad1bc03
to
d3ced08
Compare
@ziggie1984, remember to re-request review from reviewers when ready |
Maybe this can be rebased and merged🧐 |
The addition of AliasScid in the tlv_stream field of the funding_locked msg made the requirement for testdata of the ExtraOpaqueData part for the funding_locked msg type more strict. Now the input testdata for the funding_locked test is more specific and includes the new added AliasScid tlv record.
Add benchmark tests as a separate test run besides the current unit tests.
d3ced08
to
0c31eb7
Compare
Rebased and ready to be merged I think. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM 🎉
Change Description
This PR fixes #7152
The benchmark tests failed as described in the issue. Currently the tests produce random data for the
ExtraOpaqueData
field of most of the message types. This can be dangerous as soon as new data is added to a msg type via a tlv record. In this case other tests will fail too, if they use the random data generator for the tlv part.The benchmark tests failed now, because the
funding_locked
msg type is the first message in the code base which has an tlv record nested in the overall message type therefore this behaviour was not observed before. Except theOpen_channel
msg but this is a special kind of message because theupfront_script
has to be always in the tlv_data therefore the tests swap theExtraOpaqueData
and encode the relevantupfront_script
record in the tlv streamMy approach was to narrow down the funding_locked message, discarding the random part of the
ExtraOpaqueData
data and including the newAliasScid
tlv record, this way the tests will test the encode and decode method of thefunding_locked
msg more throughly.Though as soon as another msg type introduces a new nested tlv field the tests will fail again. So maybe we should get rid of the random message generation part for the
ExtraOpaqueData
field for all msg types, or restrict its size to 0, and add additional tests which really try to push the max size of the whole message to its boundaries to actually test the size limits of the payload etc.Moreover I added the Benchmark tests to the CI which which only runs the benchmark tests, explicitly avoiding all the other unit tests with the
test.run=NONE
option.Steps to Test
In the lnwire directory run:
go test -v -bench=BenchmarkReadMessage
or more general:
make unit-bench
which runs all benchmark tests of all packagesPull Request Checklist
Testing
Code Style and Documentation
[skip ci]
in the commit message for small changes.📝 Please see our Contribution Guidelines for further guidance.