Skip to content

perf(p2p/conn): Use a read buffer on the secret connection#3419

Merged
melekes merged 3 commits intomainfrom
dev/secret_conn_readbuffer
Jul 5, 2024
Merged

perf(p2p/conn): Use a read buffer on the secret connection#3419
melekes merged 3 commits intomainfrom
dev/secret_conn_readbuffer

Conversation

@ValarDragon
Copy link
Contributor

@ValarDragon ValarDragon commented Jul 3, 2024

Closes #3198

Similar to #3346 , buffers the secret connection reads. This is a notable savings to CPU time. (25% of recvRoutine time, on Osmosis' version)


PR checklist

  • Tests written/updated
  • Changelog entry added in .changelog (we use unclog to manage our changelog)
  • Updated relevant documentation (docs/ or spec/) and code comments
  • Title follows the Conventional Commits spec

@ValarDragon ValarDragon requested a review from a team as a code owner July 3, 2024 22:48
@ValarDragon ValarDragon requested a review from a team July 3, 2024 22:48
{"share bad ethimeral key", newEvilConn(true, true, false, false), func(err error) bool { return assert.Contains(t, err.Error(), "wrong wireType") }},
{"refuse to share auth signature", newEvilConn(true, false, false, false), func(err error) bool { return errors.Is(err, io.EOF) }},
{"share bad auth signature", newEvilConn(true, false, true, true), func(err error) bool { return errors.As(err, &ErrDecryptFrame{}) }},
{"all good", newEvilConn(true, false, true, false), func(err error) bool { return err == nil }},
Copy link
Contributor Author

Choose a reason for hiding this comment

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

I have spent over 12 hours attempting to fix this test, and it is incredibly complicated to do so. (The hardest test change out of everything I've done in comment) I do not think its worth investing in fixing the test.

And this is because this is mocking an invalid secret connection, and then a "final check" that we mocked the whole evil secret connection correctly. Which involves simulating all reads/writes to something internal.

After talking with @zmanian we both think this test is unneeded. This test is basically testing an evil secret connection peer, who sent bad signatures /deviated from protocol could not authenticate. We check the exact error at every step, so we are still matching every error case. So it seems fine to delete the test that the evil secret connection mocking, would work for the full connection.

We test that good handshakes complete in many ways (All E2E tests, other secret connection tests, many switch tests, etc) I have also tested this on mainnet on multiple occasions.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

cc @melekes if this sounds good to you. Your the one who wrote this set of tests!

Copy link

Choose a reason for hiding this comment

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

The produced error, which should be nil is:

SecretConnection: failed to decrypt the frame: chacha20poly1305: message authentication failed

Copy link

Choose a reason for hiding this comment

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

It is produced here:

_, err = protoio.NewDelimitedReader(sc, 1024*1024).ReadMsg(&pba)

Copy link

Choose a reason for hiding this comment

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

Anyway, do you mind commenting this line out instead of removing it? And put a comment "fails with the introduction of changes PR #3419"?

Copy link
Collaborator

Choose a reason for hiding this comment

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

It's okay to comment out the test.

@ValarDragon
Copy link
Contributor Author

This is an improvement, but not nearly as good as the write buffer.

Encryption open time vs IO.Read time
OLD: 5.6 to 14.5
NEW: 5 to 12.6

So an ~8% speedup?

Copy link

@cason cason left a comment

Choose a reason for hiding this comment

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

Ok with the changes, buffering is good in general.

{"share bad ethimeral key", newEvilConn(true, true, false, false), func(err error) bool { return assert.Contains(t, err.Error(), "wrong wireType") }},
{"refuse to share auth signature", newEvilConn(true, false, false, false), func(err error) bool { return errors.Is(err, io.EOF) }},
{"share bad auth signature", newEvilConn(true, false, true, true), func(err error) bool { return errors.As(err, &ErrDecryptFrame{}) }},
{"all good", newEvilConn(true, false, true, false), func(err error) bool { return err == nil }},
Copy link

Choose a reason for hiding this comment

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

The produced error, which should be nil is:

SecretConnection: failed to decrypt the frame: chacha20poly1305: message authentication failed

{"share bad ethimeral key", newEvilConn(true, true, false, false), func(err error) bool { return assert.Contains(t, err.Error(), "wrong wireType") }},
{"refuse to share auth signature", newEvilConn(true, false, false, false), func(err error) bool { return errors.Is(err, io.EOF) }},
{"share bad auth signature", newEvilConn(true, false, true, true), func(err error) bool { return errors.As(err, &ErrDecryptFrame{}) }},
{"all good", newEvilConn(true, false, true, false), func(err error) bool { return err == nil }},
Copy link

Choose a reason for hiding this comment

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

It is produced here:

_, err = protoio.NewDelimitedReader(sc, 1024*1024).ReadMsg(&pba)

{"share bad ethimeral key", newEvilConn(true, true, false, false), func(err error) bool { return assert.Contains(t, err.Error(), "wrong wireType") }},
{"refuse to share auth signature", newEvilConn(true, false, false, false), func(err error) bool { return errors.Is(err, io.EOF) }},
{"share bad auth signature", newEvilConn(true, false, true, true), func(err error) bool { return errors.As(err, &ErrDecryptFrame{}) }},
{"all good", newEvilConn(true, false, true, false), func(err error) bool { return err == nil }},
Copy link

Choose a reason for hiding this comment

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

Anyway, do you mind commenting this line out instead of removing it? And put a comment "fails with the introduction of changes PR #3419"?

Copy link
Collaborator

@melekes melekes left a comment

Choose a reason for hiding this comment

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

Thanks @ValarDragon ❤️

and comment it out
@melekes melekes enabled auto-merge July 5, 2024 06:31
@melekes melekes added this pull request to the merge queue Jul 5, 2024
Merged via the queue into main with commit e1eabe0 Jul 5, 2024
@melekes melekes deleted the dev/secret_conn_readbuffer branch July 5, 2024 06:41
@melekes
Copy link
Collaborator

melekes commented Jul 10, 2024

@mergify backport v1.x

@mergify
Copy link
Contributor

mergify bot commented Jul 10, 2024

backport v1.x

✅ Backports have been created

Details

mergify bot pushed a commit that referenced this pull request Jul 10, 2024
Closes #3198

Similar to #3346 , buffers the secret connection reads. This is a
notable savings to CPU time. (25% of recvRoutine time, on Osmosis'
version)

---

#### PR checklist

- [ ] Tests written/updated
- [ ] Changelog entry added in `.changelog` (we use
[unclog](https://github.com/informalsystems/unclog) to manage our
changelog)
- [ ] Updated relevant documentation (`docs/` or `spec/`) and code
comments
- [x] Title follows the [Conventional
Commits](https://www.conventionalcommits.org/en/v1.0.0/) spec

---------

Co-authored-by: Anton Kaliaev <anton.kalyaev@gmail.com>
(cherry picked from commit e1eabe0)

# Conflicts:
#	p2p/conn/evil_secret_connection_test.go
melekes added a commit that referenced this pull request Jul 10, 2024
…3419) (#3489)

Closes #3198 

Similar to #3346 , buffers the secret connection reads. This is a
notable savings to CPU time. (25% of recvRoutine time, on Osmosis'
version)

---

#### PR checklist

- [ ] Tests written/updated
- [ ] Changelog entry added in `.changelog` (we use
[unclog](https://github.com/informalsystems/unclog) to manage our
changelog)
- [ ] Updated relevant documentation (`docs/` or `spec/`) and code
comments
- [x] Title follows the [Conventional
Commits](https://www.conventionalcommits.org/en/v1.0.0/) spec
<hr>This is an automatic backport of pull request #3419 done by
[Mergify](https://mergify.com).

---------

Co-authored-by: Dev Ojha <ValarDragon@users.noreply.github.com>
Co-authored-by: Anton Kaliaev <anton.kalyaev@gmail.com>
mattac21 pushed a commit that referenced this pull request Sep 9, 2025
Closes #3198

Similar to #3346 , buffers the secret connection reads. This is a
notable savings to CPU time. (25% of recvRoutine time, on Osmosis'
version)

---

- [ ] Tests written/updated
- [ ] Changelog entry added in `.changelog` (we use
[unclog](https://github.com/informalsystems/unclog) to manage our
changelog)
- [ ] Updated relevant documentation (`docs/` or `spec/`) and code
comments
- [x] Title follows the [Conventional
Commits](https://www.conventionalcommits.org/en/v1.0.0/) spec

---------

Co-authored-by: Anton Kaliaev <anton.kalyaev@gmail.com>
mattac21 pushed a commit that referenced this pull request Sep 10, 2025
Closes #3198

Similar to #3346 , buffers the secret connection reads. This is a
notable savings to CPU time. (25% of recvRoutine time, on Osmosis'
version)

---

- [ ] Tests written/updated
- [ ] Changelog entry added in `.changelog` (we use
[unclog](https://github.com/informalsystems/unclog) to manage our
changelog)
- [ ] Updated relevant documentation (`docs/` or `spec/`) and code
comments
- [x] Title follows the [Conventional
Commits](https://www.conventionalcommits.org/en/v1.0.0/) spec

---------

Co-authored-by: Anton Kaliaev <anton.kalyaev@gmail.com>
@mattac21 mattac21 mentioned this pull request Sep 12, 2025
3 tasks
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Secret Connection: Buffer the underlying connection

3 participants