github.com/number571/tendermint@v0.34.11-gost/test/fuzz/p2p/secret_connection/read_write.go (about) 1 package secretconnection 2 3 import ( 4 "bytes" 5 "fmt" 6 "io" 7 "log" 8 9 "github.com/number571/tendermint/crypto/gost512" 10 sc "github.com/number571/tendermint/internal/p2p/conn" 11 "github.com/number571/tendermint/libs/async" 12 ) 13 14 func Fuzz(data []byte) int { 15 if len(data) == 0 { 16 return -1 17 } 18 19 fooConn, barConn := makeSecretConnPair() 20 21 // Run Write in a separate goroutine because if data is greater than 1024 22 // bytes, each Write must be followed by Read (see io.Pipe documentation). 23 go func() { 24 // Copy data because Write modifies the slice. 25 dataToWrite := make([]byte, len(data)) 26 copy(dataToWrite, data) 27 28 n, err := fooConn.Write(dataToWrite) 29 if err != nil { 30 panic(err) 31 } 32 if n < len(data) { 33 panic(fmt.Sprintf("wanted to write %d bytes, but %d was written", len(data), n)) 34 } 35 }() 36 37 dataRead := make([]byte, len(data)) 38 totalRead := 0 39 for totalRead < len(data) { 40 buf := make([]byte, len(data)-totalRead) 41 m, err := barConn.Read(buf) 42 if err != nil { 43 panic(err) 44 } 45 copy(dataRead[totalRead:], buf[:m]) 46 totalRead += m 47 log.Printf("total read: %d", totalRead) 48 } 49 50 if !bytes.Equal(data, dataRead) { 51 panic("bytes written != read") 52 } 53 54 return 1 55 } 56 57 type kvstoreConn struct { 58 *io.PipeReader 59 *io.PipeWriter 60 } 61 62 func (drw kvstoreConn) Close() (err error) { 63 err2 := drw.PipeWriter.CloseWithError(io.EOF) 64 err1 := drw.PipeReader.Close() 65 if err2 != nil { 66 return err 67 } 68 return err1 69 } 70 71 // Each returned ReadWriteCloser is akin to a net.Connection 72 func makeKVStoreConnPair() (fooConn, barConn kvstoreConn) { 73 barReader, fooWriter := io.Pipe() 74 fooReader, barWriter := io.Pipe() 75 return kvstoreConn{fooReader, fooWriter}, kvstoreConn{barReader, barWriter} 76 } 77 78 func makeSecretConnPair() (fooSecConn, barSecConn *sc.SecretConnection) { 79 var ( 80 fooConn, barConn = makeKVStoreConnPair() 81 fooPrvKey = gost512.GenPrivKey() 82 fooPubKey = fooPrvKey.PubKey() 83 barPrvKey = gost512.GenPrivKey() 84 barPubKey = barPrvKey.PubKey() 85 ) 86 87 // Make connections from both sides in parallel. 88 var trs, ok = async.Parallel( 89 func(_ int) (val interface{}, abort bool, err error) { 90 fooSecConn, err = sc.MakeSecretConnection(fooConn, fooPrvKey) 91 if err != nil { 92 log.Printf("failed to establish SecretConnection for foo: %v", err) 93 return nil, true, err 94 } 95 remotePubBytes := fooSecConn.RemotePubKey() 96 if !remotePubBytes.Equals(barPubKey) { 97 err = fmt.Errorf("unexpected fooSecConn.RemotePubKey. Expected %v, got %v", 98 barPubKey, fooSecConn.RemotePubKey()) 99 log.Print(err) 100 return nil, true, err 101 } 102 return nil, false, nil 103 }, 104 func(_ int) (val interface{}, abort bool, err error) { 105 barSecConn, err = sc.MakeSecretConnection(barConn, barPrvKey) 106 if barSecConn == nil { 107 log.Printf("failed to establish SecretConnection for bar: %v", err) 108 return nil, true, err 109 } 110 remotePubBytes := barSecConn.RemotePubKey() 111 if !remotePubBytes.Equals(fooPubKey) { 112 err = fmt.Errorf("unexpected barSecConn.RemotePubKey. Expected %v, got %v", 113 fooPubKey, barSecConn.RemotePubKey()) 114 log.Print(err) 115 return nil, true, err 116 } 117 return nil, false, nil 118 }, 119 ) 120 121 if trs.FirstError() != nil { 122 log.Fatalf("unexpected error: %v", trs.FirstError()) 123 } 124 if !ok { 125 log.Fatal("Unexpected task abortion") 126 } 127 128 return fooSecConn, barSecConn 129 }