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 }