gitlab.com/SiaPrime/SiaPrime@v1.4.1/modules/negotiate_test.go (about)

     1  package modules
     2  
     3  import (
     4  	"bytes"
     5  	"testing"
     6  
     7  	"gitlab.com/SiaPrime/SiaPrime/crypto"
     8  	"gitlab.com/SiaPrime/SiaPrime/types"
     9  )
    10  
    11  // TestAnnouncementHandling checks that CreateAnnouncement and
    12  // DecodeAnnouncement work together correctly.
    13  func TestAnnouncementHandling(t *testing.T) {
    14  	t.Parallel()
    15  
    16  	// Create the keys that will be used to generate the announcement.
    17  	sk, pk := crypto.GenerateKeyPair()
    18  	spk := types.SiaPublicKey{
    19  		Algorithm: types.SignatureEd25519,
    20  		Key:       pk[:],
    21  	}
    22  	addr := NetAddress("f.o:1234")
    23  
    24  	// Generate the announcement.
    25  	annBytes, err := CreateAnnouncement(addr, spk, sk)
    26  	if err != nil {
    27  		t.Fatal(err)
    28  	}
    29  
    30  	// Decode the announcement
    31  	decAddr, decPubKey, err := DecodeAnnouncement(annBytes)
    32  	if err != nil {
    33  		t.Fatal(err)
    34  	}
    35  	if decPubKey.Algorithm != spk.Algorithm {
    36  		t.Error("decoded announcement has the wrong algorithm on the public key")
    37  	}
    38  	if decAddr != addr {
    39  		t.Error("decoded announcement has the wrong net address")
    40  	}
    41  	if !bytes.Equal(decPubKey.Key, spk.Key) {
    42  		t.Error("decoded announcement has the wrong public key")
    43  	}
    44  
    45  	// Corrupt the data, and see that decoding fails. Decoding should fail
    46  	// because the signature should not be valid anymore.
    47  	//
    48  	// First 16 bytes are the host announcement prefix, followed by 8 bytes
    49  	// describing the length of the net address, followed by the net address.
    50  	// Corrupt the net address.
    51  	annBytes[25]++
    52  	_, _, err = DecodeAnnouncement(annBytes)
    53  	if err != crypto.ErrInvalidSignature {
    54  		t.Error(err)
    55  	}
    56  	annBytes[25]--
    57  
    58  	// The final byte is going to be a part of the signature. Corrupt the final
    59  	// byte and verify that there's an error.
    60  	lastIndex := len(annBytes) - 1
    61  	annBytes[lastIndex]++
    62  	_, _, err = DecodeAnnouncement(annBytes)
    63  	if err != crypto.ErrInvalidSignature {
    64  		t.Error(err)
    65  	}
    66  	annBytes[lastIndex]--
    67  
    68  	// Pass in a bad specifier - change the host announcement type.
    69  	annBytes[0]++
    70  	_, _, err = DecodeAnnouncement(annBytes)
    71  	if err != ErrAnnNotAnnouncement {
    72  		t.Error(err)
    73  	}
    74  	annBytes[0]--
    75  
    76  	// Pass in a bad signature algorithm. 16 bytes to pass the specifier, 8+8 bytes to pass the net address.
    77  	annBytes[33]++
    78  	_, _, err = DecodeAnnouncement(annBytes)
    79  	if err != ErrAnnUnrecognizedSignature {
    80  		t.Error(err)
    81  	}
    82  	annBytes[33]--
    83  
    84  	// Cause the decoding to fail altogether.
    85  	_, _, err = DecodeAnnouncement(annBytes[:12])
    86  	if err == nil {
    87  		t.Error(err)
    88  	}
    89  }
    90  
    91  // TestNegotiationResponses tests the WriteNegotiationAcceptance,
    92  // WriteNegotiationRejection, and ReadNegotiationAcceptance functions.
    93  func TestNegotiationResponses(t *testing.T) {
    94  	// Write/Read acceptance
    95  	buf := new(bytes.Buffer)
    96  	err := WriteNegotiationAcceptance(buf)
    97  	if err != nil {
    98  		t.Fatal(err)
    99  	}
   100  	err = ReadNegotiationAcceptance(buf)
   101  	if err != nil {
   102  		t.Fatal(err)
   103  	}
   104  
   105  	// Write/Read rejection
   106  	buf.Reset()
   107  	err = WriteNegotiationRejection(buf, ErrLowBalance)
   108  	if err != ErrLowBalance {
   109  		t.Fatal(err)
   110  	}
   111  	err = ReadNegotiationAcceptance(buf)
   112  	// can't compare to ErrLowBalance directly; contents are the same, but pointer is different
   113  	if err == nil || err.Error() != ErrLowBalance.Error() {
   114  		t.Fatal(err)
   115  	}
   116  
   117  	// Write/Read StopResponse
   118  	buf.Reset()
   119  	err = WriteNegotiationStop(buf)
   120  	if err != nil {
   121  		t.Fatal(err)
   122  	}
   123  	err = ReadNegotiationAcceptance(buf)
   124  	if err != ErrStopResponse {
   125  		t.Fatal(err)
   126  	}
   127  }
   128  
   129  // TestRenterPayoutsPreTax probes the RenterPayoutsPreTax function
   130  func TestRenterPayoutsPreTax(t *testing.T) {
   131  	// Initialize inputs
   132  	var host HostDBEntry
   133  	var period types.BlockHeight
   134  	var baseCollateral types.Currency
   135  	var expectedStorage uint64
   136  
   137  	// Set currency values to trigger underflow check
   138  	funding := types.NewCurrency64(10)
   139  	txnFee := types.NewCurrency64(5)
   140  	basePrice := types.NewCurrency64(5)
   141  
   142  	// Check for underflow condition
   143  	_, _, _, err := RenterPayoutsPreTax(host, funding, txnFee, basePrice, baseCollateral, period, expectedStorage)
   144  	if err == nil {
   145  		t.Fatal("Expected underflow error but got nil")
   146  	}
   147  
   148  	// Confirm no underflow
   149  	funding = types.NewCurrency64(11)
   150  	renterPayout, hostPayout, hostCollateral, err := RenterPayoutsPreTax(host, funding, txnFee, basePrice, baseCollateral, period, expectedStorage)
   151  	if err != nil {
   152  		t.Fatal(err)
   153  	}
   154  	if renterPayout.Cmp(types.ZeroCurrency) < 0 {
   155  		t.Fatal("Negative currency returned for renter payout", renterPayout)
   156  	}
   157  	if hostPayout.Cmp(types.ZeroCurrency) < 0 {
   158  		t.Fatal("Negative currency returned for host payout", hostPayout)
   159  	}
   160  	if hostCollateral.Cmp(types.ZeroCurrency) < 0 {
   161  		t.Fatal("Negative currency returned for host collateral", hostCollateral)
   162  	}
   163  }