github.com/keybase/client/go@v0.0.0-20240309051027-028f7c731f8b/engine/cryptocurrency_test.go (about)

     1  // Copyright 2015 Keybase, Inc. All rights reserved. Use of
     2  // this source code is governed by the included BSD license.
     3  
     4  package engine
     5  
     6  import (
     7  	"testing"
     8  
     9  	"github.com/keybase/client/go/libkb"
    10  	keybase1 "github.com/keybase/client/go/protocol/keybase1"
    11  )
    12  
    13  func getCurrentCryptocurrencyAddr(tc libkb.TestContext, username string, family libkb.CryptocurrencyFamily) string {
    14  	u, err := libkb.LoadUser(libkb.NewLoadUserByNameArg(tc.G, username))
    15  	if err != nil {
    16  		tc.T.Fatal(err)
    17  	}
    18  	cryptoLink := u.IDTable().ActiveCryptocurrency(family)
    19  	if cryptoLink == nil {
    20  		return ""
    21  	}
    22  	return cryptoLink.ToDisplayString()
    23  }
    24  
    25  const (
    26  	firstAddress  = "17JyYCvn37BodyLbZdKQrW3WNbW7JcsvAJ"
    27  	secondAddress = "1kwg3FnLysQAi8Wqu37KqBwTUaUGiL7t1"
    28  	zcash1        = "zcCk6rKzynC4tT1Rmg325A5Xw81Ck3S6nD6mtPWCXaMtyFczkyU4kYjEhrcz2QKfF5T2siWGyJNxWo43XWT3qk5YpPhFGj2"
    29  	zcash2        = "t1c3Ebc6FBbWuirNrjJ6HbS4KHLb6Dbh5xL"
    30  )
    31  
    32  func TestCryptocurrency(t *testing.T) {
    33  	doWithSigChainVersions(func(sigVersion libkb.SigVersion) {
    34  		_testCryptocurrency(t, sigVersion)
    35  	})
    36  }
    37  
    38  func _testCryptocurrency(t *testing.T, sigVersion libkb.SigVersion) {
    39  	tc := SetupEngineTest(t, "Cryptocurrency")
    40  	defer tc.Cleanup()
    41  
    42  	u := CreateAndSignupFakeUser(tc, "btc")
    43  
    44  	uis := libkb.UIs{
    45  		LogUI:    tc.G.UI.GetLogUI(),
    46  		SecretUI: u.NewSecretUI(),
    47  	}
    48  
    49  	// First test setting a bad address; this should fail.
    50  	sv := keybase1.SigVersion(sigVersion)
    51  	e := NewCryptocurrencyEngine(tc.G, keybase1.RegisterAddressArg{Address: "somejunk", SigVersion: &sv})
    52  	m := NewMetaContextForTest(tc).WithUIs(uis)
    53  	err := RunEngine2(m, e)
    54  	if err == nil {
    55  		t.Fatalf("Bad address should have failed.")
    56  	}
    57  	current := getCurrentCryptocurrencyAddr(tc, u.Username, libkb.CryptocurrencyFamilyBitcoin)
    58  	if current != "" {
    59  		t.Fatalf("No address should be set")
    60  	}
    61  
    62  	// Now set a real address, but with the wrong family. This should fail
    63  	e = NewCryptocurrencyEngine(tc.G, keybase1.RegisterAddressArg{Address: firstAddress, WantedFamily: "zcash", SigVersion: &sv})
    64  	err = RunEngine2(m, e)
    65  	if err == nil {
    66  		t.Fatal("Wanted an error for wrong address type")
    67  	}
    68  	if current != "" {
    69  		t.Fatalf("No address should be set")
    70  	}
    71  
    72  	// Now set a real address; this should succeed.
    73  	e = NewCryptocurrencyEngine(tc.G, keybase1.RegisterAddressArg{Address: firstAddress, WantedFamily: "bitcoin", SigVersion: &sv})
    74  	err = RunEngine2(m, e)
    75  	if err != nil {
    76  		t.Fatal(err)
    77  	}
    78  	current = getCurrentCryptocurrencyAddr(tc, u.Username, libkb.CryptocurrencyFamilyBitcoin)
    79  	if current != firstAddress {
    80  		t.Fatalf("Expected Cryptocurrency address '%s'. Found '%s'.", firstAddress, current)
    81  	}
    82  
    83  	// Test overwriting it without --force; should fail.
    84  	e = NewCryptocurrencyEngine(tc.G, keybase1.RegisterAddressArg{Address: secondAddress, SigVersion: &sv})
    85  	err = RunEngine2(m, e)
    86  	if err == nil {
    87  		t.Fatal("Overwriting a Cryptocurrency address should fail without --force.")
    88  	} else if _, ok := err.(libkb.ExistsError); !ok {
    89  		t.Fatal("Error should by typed 'libkb.ExistsError'")
    90  	}
    91  	current = getCurrentCryptocurrencyAddr(tc, u.Username, libkb.CryptocurrencyFamilyBitcoin)
    92  	if current != firstAddress {
    93  		t.Fatalf("Address should not have changed.")
    94  	}
    95  
    96  	// Now test the overwrite with the --force flag; should succeed.
    97  	e = NewCryptocurrencyEngine(tc.G, keybase1.RegisterAddressArg{Address: secondAddress, Force: true, SigVersion: &sv})
    98  	err = RunEngine2(m, e)
    99  	if err != nil {
   100  		t.Fatal(err)
   101  	}
   102  	current = getCurrentCryptocurrencyAddr(tc, u.Username, libkb.CryptocurrencyFamilyBitcoin)
   103  	if current != secondAddress {
   104  		t.Fatalf("Expected Cryptocurrency address '%s'. Found '%s'.", secondAddress, current)
   105  	}
   106  
   107  	// Make sure the previous link was revoked.
   108  	loadedUser, err := libkb.LoadUser(libkb.NewLoadUserByNameArg(tc.G, u.Username))
   109  	if err != nil {
   110  		t.Fatalf("Failed to load user.")
   111  	}
   112  	revoked := loadedUser.IDTable().GetRevokedCryptocurrencyForTesting()
   113  	if len(revoked) != 1 {
   114  		t.Fatal("Expected 1 revoked link.")
   115  	} else if revoked[0].ToDisplayString() != firstAddress {
   116  		t.Fatal("Revoked link should correspond to the first address.")
   117  	}
   118  
   119  	// Check that we can also add a Zcash address
   120  	e = NewCryptocurrencyEngine(tc.G, keybase1.RegisterAddressArg{Address: zcash1, SigVersion: &sv})
   121  	err = RunEngine2(m, e)
   122  	if err != nil {
   123  		t.Fatal("We should be able to add a Zcash in addition to a BTC address")
   124  	}
   125  	current = getCurrentCryptocurrencyAddr(tc, u.Username, libkb.CryptocurrencyFamilyBitcoin)
   126  	if current != secondAddress {
   127  		t.Fatalf("BTC Address should not have changed.")
   128  	}
   129  	current = getCurrentCryptocurrencyAddr(tc, u.Username, libkb.CryptocurrencyFamilyZCash)
   130  	if current != zcash1 {
   131  		t.Fatalf("Zcash address didn't take")
   132  	}
   133  
   134  	// Check that we can't also add a second Zcash address
   135  	e = NewCryptocurrencyEngine(tc.G, keybase1.RegisterAddressArg{Address: zcash2, SigVersion: &sv})
   136  	err = RunEngine2(m, e)
   137  	if err == nil {
   138  		t.Fatal("Overwriting a second Zcash address should fail without --force.")
   139  	} else if _, ok := err.(libkb.ExistsError); !ok {
   140  		t.Fatal("Error should by typed 'libkb.ExistsError'")
   141  	}
   142  	current = getCurrentCryptocurrencyAddr(tc, u.Username, libkb.CryptocurrencyFamilyBitcoin)
   143  	if current != secondAddress {
   144  		t.Fatalf("BTC Address should not have changed.")
   145  	}
   146  	current = getCurrentCryptocurrencyAddr(tc, u.Username, libkb.CryptocurrencyFamilyZCash)
   147  	if current != zcash1 {
   148  		t.Fatalf("Zcash address didn't take")
   149  	}
   150  
   151  	// Check that we can't also add a second Zcash address
   152  	e = NewCryptocurrencyEngine(tc.G, keybase1.RegisterAddressArg{Address: zcash2, Force: true, SigVersion: &sv})
   153  	err = RunEngine2(m, e)
   154  	if err != nil {
   155  		t.Fatal("Forcing Zcash overwrite should have worked")
   156  	}
   157  	current = getCurrentCryptocurrencyAddr(tc, u.Username, libkb.CryptocurrencyFamilyBitcoin)
   158  	if current != secondAddress {
   159  		t.Fatalf("BTC Address should not have changed.")
   160  	}
   161  	current = getCurrentCryptocurrencyAddr(tc, u.Username, libkb.CryptocurrencyFamilyZCash)
   162  	if current != zcash2 {
   163  		t.Fatalf("Zcash address force didn't take")
   164  	}
   165  
   166  	// Make sure the previous link was revoked.
   167  	loadedUser, err = libkb.LoadUser(libkb.NewLoadUserByNameArg(tc.G, u.Username))
   168  	if err != nil {
   169  		t.Fatalf("Failed to load user.")
   170  	}
   171  	revoked = loadedUser.IDTable().GetRevokedCryptocurrencyForTesting()
   172  	if len(revoked) != 2 {
   173  		t.Fatalf("Expected 2 revoked links; got %d", len(revoked))
   174  	} else if revoked[0].ToDisplayString() != firstAddress {
   175  		t.Fatal("Revoked link should correspond to the first address.")
   176  	} else if revoked[1].ToDisplayString() != zcash1 {
   177  		t.Fatal("Revoked link should correspond to the first Zcash address.")
   178  	}
   179  }
   180  
   181  func TestCryptocurrencyWithSecretStore(t *testing.T) {
   182  	doWithSigChainVersions(func(sigVersion libkb.SigVersion) {
   183  		_testCryptocurrencyWithSecretStore(t, sigVersion)
   184  	})
   185  }
   186  
   187  // Make sure the Cryptocurrency engine uses the secret store.
   188  func _testCryptocurrencyWithSecretStore(t *testing.T, sigVersion libkb.SigVersion) {
   189  	testEngineWithSecretStore(t, func(
   190  		tc libkb.TestContext, fu *FakeUser, secretUI libkb.SecretUI) {
   191  		sv := keybase1.SigVersion(sigVersion)
   192  		e := NewCryptocurrencyEngine(tc.G, keybase1.RegisterAddressArg{Address: firstAddress, Force: true, SigVersion: &sv})
   193  		uis := libkb.UIs{
   194  			LogUI:    tc.G.UI.GetLogUI(),
   195  			SecretUI: secretUI,
   196  		}
   197  		m := NewMetaContextForTest(tc).WithUIs(uis)
   198  		err := RunEngine2(m, e)
   199  		if err != nil {
   200  			t.Fatal(err)
   201  		}
   202  	})
   203  }