10000 chore: export p2p package errors by akaladarshi · Pull Request #1901 · cometbft/cometbft · GitHub
[go: up one dir, main page]
More Web Proxy on the site http://driver.im/
Skip to content

chore: export p2p package errors #1901

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

Merged
merged 32 commits into from
Mar 18, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
32 commits
Select commit Hold shift + click to select a range
67bc6ef
refactor: export p2p package errors
akaladarshi Dec 28, 2023
8ff3f03
address comments
akaladarshi Jan 4, 2024
5baaca3
Merge branch 'cometbft:main' into tikaryan/export-p2p-errors
akaladarshi Jan 4, 2024
4a75eee
fix: linter issue
akaladarshi Jan 4, 2024
ae1f33a
Merge branch 'main' into tikaryan/export-p2p-errors
akaladarshi Jan 9, 2024
4a2beb1
Merge branch 'main' into tikaryan/export-p2p-errors
akaladarshi Jan 16, 2024
52c06e5
Merge branch 'main' into tikaryan/export-p2p-errors
akaladarshi Jan 23, 2024
0347276
address comments
akaladarshi Jan 23, 2024
b6e723e
fix: ci test
akaladarshi Jan 30, 2024
e689291
Merge branch 'main' into tikaryan/export-p2p-errors
akaladarshi Jan 30, 2024
4386d22
test: use custom type for comparing errors
akaladarshi Jan 30, 2024
dee0632
Merge branch 'main' into tikaryan/export-p2p-errors
akaladarshi Feb 2, 2024
c472d3e
Merge branch 'main' into tikaryan/export-p2p-errors
akaladarshi Feb 13, 2024
d31c97a
Merge branch 'main' into tikaryan/export-p2p-errors
akaladarshi Feb 25, 2024
21b0575
Merge branch 'main' into tikaryan/export-p2p-errors
akaladarshi Feb 29, 2024
ddd475e
Merge branch 'main' into tikaryan/export-p2p-errors
akaladarshi Mar 11, 2024
1c0f1f9
Merge branch 'main' into tikaryan/export-p2p-errors
andynog Mar 12, 2024
4a424aa
Merge branch 'main' into tikaryan/export-p2p-errors
andynog Mar 14, 2024
8825dbc
Merge branch 'main' into tikaryan/export-p2p-errors
andynog Mar 15, 2024
aab6c46
Merge branch 'main' into tikaryan/export-p2p-errors
andynog Mar 15, 2024
b7d42f0
exported errors (#1901)
andynog Mar 15, 2024
2cf0728
refactor err returned (#1901)
andynog Mar 15, 2024
cf99854
added exported error to unit test (#1901)
andynog Mar 15, 2024
638c874
avoid prematurely returning, wrapping source error (#1901)
andynog Mar 18, 2024
6a602c5
reverting some error messages changes (#1901)
andynog Mar 18, 2024
7dce992
don't use any if no need to (#1901)
andynog Mar 18, 2024
5e896d0
exporting errors and minor refactorings (#1901)
andynog Mar 18, 2024
6356537
add changelog entry (#1901)
andynog Mar 18, 2024
defbbed
export errors (#1901)
andynog Mar 18, 2024
aed15a8
exporting errors and adding Unwrap (#1901)
andynog Mar 18, 2024
6b9989b
minor refactoring in error.As check (#1901)
andynog Mar 18, 2024
76e9342
merge main and fix conflicts, fix error (#1901)
andynog Mar 18, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
- `[p2p]` Export p2p package errors ([\#1901](https://github.com/cometbft/cometbft/pull/1901)) (contributes to [\#1140](https://github.com/cometbft/cometbft/issues/1140))
7 changes: 6 additions & 1 deletion p2p/conn/connection.go
Original file line number Diff line number Diff line change
Expand Up @@ -852,6 +852,10 @@ func (ch *Channel) nextPacketMsg() tmp2p.PacketMsg {
func (ch *Channel) writePacketMsgTo(w io.Writer) (n int, err error) {
packet := ch.nextPacketMsg()
n, err = protoio.NewDelimitedWriter(w).WriteMsg(mustWrapPacket(&packet))
if err != nil {
err = ErrPacketWrite{Source: err}
}

atomic.AddInt64(&ch.recentlySent, int64(n))
return n, err
}
Expand All @@ -863,8 +867,9 @@ func (ch *Channel) recvPacketMsg(packet tmp2p.PacketMsg) ([]byte, error) {
ch.Logger.Debug("Read PacketMsg", "conn", ch.conn, "packet", packet)
recvCap, recvReceived := ch.desc.RecvMessageCapacity, len(ch.recving)+len(packet.Data)
if recvCap < recvReceived {
return nil, fmt.Errorf("received message exceeds available capacity: %v < %v", recvCap, recvReceived)
return nil, ErrPacketTooBig{Max: recvCap, Received: recvReceived}
}

ch.recving = append(ch.recving, packet.Data...)
if packet.EOF {
msgBytes := ch.recving
Expand Down
64 changes: 64 additions & 0 deletions p2p/conn/errors.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
package conn

import (
"errors"
"fmt"
)

var (
ErrInvalidSecretConnKeySend = errors.New("send invalid secret connection key")
ErrInvalidSecretConnKeyRecv = errors.New("invalid receive SecretConnection Key")
ErrChallengeVerification = errors.New("challenge verification failed")
)

// ErrPacketWrite Packet error when writing.
type ErrPacketWrite struct {
Source error
}

func (e ErrPacketWrite) Error() string {
return fmt.Sprintf("failed to write packet message: %v", e.Source)
}

func (e ErrPacketWrite) Unwrap() error {
return e.Source
}

type ErrUnexpectedPubKeyType struct {
Expected string
Got string
}

func (e ErrUnexpectedPubKeyType) Error() string {
return fmt.Sprintf("expected pubkey type %s, got %s", e.Expected, e.Got)
}

type ErrDecryptFrame struct {
Source error
}

func (e ErrDecryptFrame) Error() string {
return fmt.Sprintf("SecretConnection: failed to decrypt the frame: %v", e.Source)
}

func (e ErrDecryptFrame) Unwrap() error {
return e.Source
}

type ErrPacketTooBig struct {
Received int
Max int
}

func (e ErrPacketTooBig) Error() string {
return fmt.Sprintf("received message exceeds available capacity (max: %d, got: %d)", e.Max, e.Received)
}

type ErrChunkTooBig struct {
Received int
Max int
}

func (e ErrChunkTooBig) Error() string {
return fmt.Sprintf("chunk too big (max: %d, got %d)", e.Max, e.Received)
}
22 changes: 10 additions & 12 deletions p2p/conn/evil_secret_connection_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -244,26 +244,24 @@ func (c *evilConn) signChallenge() []byte {
// MakeSecretConnection errors at different stages.
func TestMakeSecretConnection(t *testing.T) {
testCases := []struct {
name string
conn *evilConn
errMsg string
name string
conn *evilConn
checkError func(error) bool // Function to check if the error matches the expectation
}{
{"refuse to share ethimeral key", newEvilConn(false, false, false, false), "EOF"},
{"share bad ethimeral key", newEvilConn(true, true, false, false), "wrong wireType"},
{"refuse to share auth signature", newEvilConn(true, false, false, false), "EOF"},
{"share bad auth signature", newEvilConn(true, false, true, true), "failed to decrypt SecretConnection"},
{"all good", newEvilConn(true, false, true, false), ""},
{"refuse to share ethimeral key", newEvilConn(false, false, false, false), func(err error) bool { return err == io.EOF }},
{"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 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 }},
}

for _, tc := range testCases {
tc := tc
t.Run(tc.name, func(t *testing.T) {
privKey := ed25519.GenPrivKey()
_, err := MakeSecretConnection(tc.conn, privKey)
if tc.errMsg != "" {
if assert.Error(t, err) { //nolint:testifylint // require.Error doesn't work with the conditional here
assert.Contains(t, err.Error(), tc.errMsg)
}
if tc.checkError != nil {
assert.True(t, tc.checkError(err))
} else {
require.NoError(t, err)
}
Expand Down
30 changes: 20 additions & 10 deletions p2p/conn/secret_connection.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,6 @@ import (
"crypto/sha256"
"encoding/binary"
"errors"
"fmt"
"io"
"math"
"net"
Expand Down Expand Up @@ -46,8 +45,7 @@ const (
)

var (
ErrSmallOrderRemotePubKey = errors.New("detected low order point from remote peer")

ErrSmallOrderRemotePubKey = errors.New("detected low order point from remote peer")
secretConnKeyAndChallengeGen = []byte("TENDERMINT_SECRET_CONNECTION_KEY_AND_CHALLENGE_GEN")
)

Expand Down Expand Up @@ -133,11 +131,12 @@ func MakeSecretConnection(conn io.ReadWriteCloser, locPrivKey crypto.PrivKey) (*

sendAead, err := chacha20poly1305.New(sendSecret[:])
if err != nil {
return nil, errors.New("invalid send SecretConnection Key")
return nil, ErrInvalidSecretConnKeySend
}

recvAead, err := chacha20poly1305.New(recvSecret[:])
if err != nil {
return nil, errors.New("invalid receive SecretConnection Key")
return nil, ErrInvalidSecretConnKeyRecv
}

sc := &SecretConnection{
Expand All @@ -162,11 +161,16 @@ func MakeSecretConnection(conn io.ReadWriteCloser, locPrivKey crypto.PrivKey) (*
}

remPubKey, remSignature := authSigMsg.Key, authSigMsg.Sig
// Usage in your function
if _, ok := remPubKey.(ed25519.PubKey); !ok {
return nil, fmt.Errorf("expected ed25519 pubkey, got %T", remPubKey)
return nil, ErrUnexpectedPubKeyType{
Expected: ed25519.KeyType,
Got: remPubKey.Type(),
}
}

if !remPubKey.VerifySignature(challenge[:], remSignature) {
return nil, errors.New("challenge verification failed")
return nil, ErrChallengeVerification
}

// We've authorized.
Expand Down Expand Up @@ -214,6 +218,7 @@ func (sc *SecretConnection) Write(data []byte) (n int, err error) {
if err != nil {
return err
}

n += len(chunk)
return nil
}(); err != nil {
Expand Down Expand Up @@ -249,17 +254,22 @@ func (sc *SecretConnection) Read(data []byte) (n int, err error) {
defer pool.Put(frame)
_, err = sc.recvAead.Open(frame[:0], sc.recvNonce[:], sealedFrame, nil)
if err != nil {
return n, fmt.Errorf("failed to decrypt SecretConnection: %w", err)
return n, ErrDecryptFrame{Source: err}
}

incrNonce(sc.recvNonce)
// end decryption

// copy checkLength worth into data,
// set recvBuffer to the rest.
chunkLength := binary.LittleEndian.Uint32(frame) // read the first four bytes
if chunkLength > dataMaxSize {
return 0, errors.New("chunkLength is greater than dataMaxSize")
return 0, ErrChunkTooBig{
Received: int(chunkLength),
Max: dataMaxSize,
}
}

chunk := frame[dataLenSize : dataLenSize+chunkLength]
n = copy(data, chunk)
if n < len(chunk) {
Expand Down Expand Up @@ -289,7 +299,7 @@ func genEphKeys() (ephPub, ephPriv *[32]byte) {
// see: https://github.com/dalek-cryptography/x25519-dalek/blob/34676d336049df2bba763cc076a75e47ae1f170f/src/x25519.rs#L56-L74
ephPub, ephPriv, err = box.GenerateKey(crand.Reader)
if err != nil {
panic("Could not generate ephemeral key-pair")
panic("failed to generate ephemeral key-pair")
}
return ephPub, ephPriv
}
Expand Down
3 changes: 2 additions & 1 deletion p2p/conn/secret_connection_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ package conn
import (
"bufio"
"encoding/hex"
"errors"
"flag"
"fmt"
"io"
Expand Down Expand Up @@ -155,7 +156,7 @@ func TestSecretConnectionReadWrite(t *testing.T) {
readBuffer := make([]byte, dataMaxSize)
for {
n, err := nodeSecretConn.Read(readBuffer)
if err == io.EOF {
if errors.Is(err, io.EOF) {
if err := nodeConn.PipeReader.Close(); err != nil {
t.Error(err)
return nil, true, err
Expand Down
Loading
0