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  }