github.com/sberex/go-sberex@v1.8.2-0.20181113200658-ed96ac38f7d7/contracts/chequebook/cheque_test.go (about) 1 // This file is part of the go-sberex library. The go-sberex library is 2 // free software: you can redistribute it and/or modify it under the terms 3 // of the GNU Lesser General Public License as published by the Free 4 // Software Foundation, either version 3 of the License, or (at your option) 5 // any later version. 6 // 7 // The go-sberex library is distributed in the hope that it will be useful, 8 // but WITHOUT ANY WARRANTY; without even the implied warranty of 9 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser 10 // General Public License <http://www.gnu.org/licenses/> for more details. 11 12 package chequebook 13 14 import ( 15 "crypto/ecdsa" 16 "math/big" 17 "os" 18 "path/filepath" 19 "testing" 20 "time" 21 22 "github.com/Sberex/go-sberex/accounts/abi/bind" 23 "github.com/Sberex/go-sberex/accounts/abi/bind/backends" 24 "github.com/Sberex/go-sberex/common" 25 "github.com/Sberex/go-sberex/contracts/chequebook/contract" 26 "github.com/Sberex/go-sberex/core" 27 "github.com/Sberex/go-sberex/crypto" 28 ) 29 30 var ( 31 key0, _ = crypto.HexToECDSA("b71c71a67e1177ad4e901695e1b4b9ee17ae16c6668d313eac2f96dbcda3f291") 32 key1, _ = crypto.HexToECDSA("8a1f9a8f95be41cd7ccb6168179afb4504aefe388d1e14474d32c45c72ce7b7a") 33 key2, _ = crypto.HexToECDSA("49a7b37aa6f6645917e7b807e9d1c00d4fa71f18343b0d4122a4d2df64dd6fee") 34 addr0 = crypto.PubkeyToAddress(key0.PublicKey) 35 addr1 = crypto.PubkeyToAddress(key1.PublicKey) 36 addr2 = crypto.PubkeyToAddress(key2.PublicKey) 37 ) 38 39 func newTestBackend() *backends.SimulatedBackend { 40 return backends.NewSimulatedBackend(core.GenesisAlloc{ 41 addr0: {Balance: big.NewInt(1000000000)}, 42 addr1: {Balance: big.NewInt(1000000000)}, 43 addr2: {Balance: big.NewInt(1000000000)}, 44 }) 45 } 46 47 func deploy(prvKey *ecdsa.PrivateKey, amount *big.Int, backend *backends.SimulatedBackend) (common.Address, error) { 48 deployTransactor := bind.NewKeyedTransactor(prvKey) 49 deployTransactor.Value = amount 50 addr, _, _, err := contract.DeployChequebook(deployTransactor, backend) 51 if err != nil { 52 return common.Address{}, err 53 } 54 backend.Commit() 55 return addr, nil 56 } 57 58 func TestIssueAndReceive(t *testing.T) { 59 path := filepath.Join(os.TempDir(), "chequebook-test.json") 60 backend := newTestBackend() 61 addr0, err := deploy(key0, big.NewInt(0), backend) 62 if err != nil { 63 t.Fatalf("deploy contract: expected no error, got %v", err) 64 } 65 chbook, err := NewChequebook(path, addr0, key0, backend) 66 if err != nil { 67 t.Fatalf("expected no error, got %v", err) 68 } 69 chbook.sent[addr1] = new(big.Int).SetUint64(42) 70 amount := common.Big1 71 72 if _, err = chbook.Issue(addr1, amount); err == nil { 73 t.Fatalf("expected insufficient funds error, got none") 74 } 75 76 chbook.balance = new(big.Int).Set(common.Big1) 77 if chbook.Balance().Cmp(common.Big1) != 0 { 78 t.Fatalf("expected: %v, got %v", "0", chbook.Balance()) 79 } 80 81 ch, err := chbook.Issue(addr1, amount) 82 if err != nil { 83 t.Fatalf("expected no error, got %v", err) 84 } 85 86 if chbook.Balance().Sign() != 0 { 87 t.Errorf("expected: %v, got %v", "0", chbook.Balance()) 88 } 89 90 chbox, err := NewInbox(key1, addr0, addr1, &key0.PublicKey, backend) 91 if err != nil { 92 t.Fatalf("expected no error, got %v", err) 93 } 94 95 received, err := chbox.Receive(ch) 96 if err != nil { 97 t.Fatalf("expected no error, got %v", err) 98 } 99 100 if received.Cmp(big.NewInt(43)) != 0 { 101 t.Errorf("expected: %v, got %v", "43", received) 102 } 103 104 } 105 106 func TestCheckbookFile(t *testing.T) { 107 path := filepath.Join(os.TempDir(), "chequebook-test.json") 108 backend := newTestBackend() 109 chbook, err := NewChequebook(path, addr0, key0, backend) 110 if err != nil { 111 t.Fatalf("expected no error, got %v", err) 112 } 113 chbook.sent[addr1] = new(big.Int).SetUint64(42) 114 chbook.balance = new(big.Int).Set(common.Big1) 115 116 chbook.Save() 117 118 chbook, err = LoadChequebook(path, key0, backend, false) 119 if err != nil { 120 t.Fatalf("expected no error, got %v", err) 121 } 122 if chbook.Balance().Cmp(common.Big1) != 0 { 123 t.Errorf("expected: %v, got %v", "0", chbook.Balance()) 124 } 125 126 var ch *Cheque 127 if ch, err = chbook.Issue(addr1, common.Big1); err != nil { 128 t.Fatalf("expected no error, got %v", err) 129 } 130 if ch.Amount.Cmp(new(big.Int).SetUint64(43)) != 0 { 131 t.Errorf("expected: %v, got %v", "0", ch.Amount) 132 } 133 134 err = chbook.Save() 135 if err != nil { 136 t.Fatalf("expected no error, got %v", err) 137 } 138 } 139 140 func TestVerifyErrors(t *testing.T) { 141 path0 := filepath.Join(os.TempDir(), "chequebook-test-0.json") 142 backend := newTestBackend() 143 contr0, err := deploy(key0, common.Big2, backend) 144 if err != nil { 145 t.Errorf("expected no error, got %v", err) 146 } 147 chbook0, err := NewChequebook(path0, contr0, key0, backend) 148 if err != nil { 149 t.Errorf("expected no error, got %v", err) 150 } 151 152 path1 := filepath.Join(os.TempDir(), "chequebook-test-1.json") 153 contr1, _ := deploy(key1, common.Big2, backend) 154 chbook1, err := NewChequebook(path1, contr1, key1, backend) 155 if err != nil { 156 t.Errorf("expected no error, got %v", err) 157 } 158 159 chbook0.sent[addr1] = new(big.Int).SetUint64(42) 160 chbook0.balance = new(big.Int).Set(common.Big2) 161 chbook1.balance = new(big.Int).Set(common.Big1) 162 amount := common.Big1 163 ch0, err := chbook0.Issue(addr1, amount) 164 if err != nil { 165 t.Fatalf("expected no error, got %v", err) 166 } 167 168 chbox, err := NewInbox(key1, contr0, addr1, &key0.PublicKey, backend) 169 if err != nil { 170 t.Fatalf("expected no error, got %v", err) 171 } 172 173 received, err := chbox.Receive(ch0) 174 if err != nil { 175 t.Fatalf("expected no error, got %v", err) 176 } 177 178 if received.Cmp(big.NewInt(43)) != 0 { 179 t.Errorf("expected: %v, got %v", "43", received) 180 } 181 182 ch1, err := chbook0.Issue(addr2, amount) 183 if err != nil { 184 t.Fatalf("expected no error, got %v", err) 185 } 186 187 received, err = chbox.Receive(ch1) 188 t.Logf("correct error: %v", err) 189 if err == nil { 190 t.Fatalf("expected receiver error, got none and value %v", received) 191 } 192 193 ch2, err := chbook1.Issue(addr1, amount) 194 if err != nil { 195 t.Fatalf("expected no error, got %v", err) 196 } 197 received, err = chbox.Receive(ch2) 198 t.Logf("correct error: %v", err) 199 if err == nil { 200 t.Fatalf("expected sender error, got none and value %v", received) 201 } 202 203 _, err = chbook1.Issue(addr1, new(big.Int).SetInt64(-1)) 204 t.Logf("correct error: %v", err) 205 if err == nil { 206 t.Fatalf("expected incorrect amount error, got none") 207 } 208 209 received, err = chbox.Receive(ch0) 210 t.Logf("correct error: %v", err) 211 if err == nil { 212 t.Fatalf("expected incorrect amount error, got none and value %v", received) 213 } 214 215 } 216 217 func TestDeposit(t *testing.T) { 218 path0 := filepath.Join(os.TempDir(), "chequebook-test-0.json") 219 backend := newTestBackend() 220 contr0, _ := deploy(key0, new(big.Int), backend) 221 222 chbook, err := NewChequebook(path0, contr0, key0, backend) 223 if err != nil { 224 t.Errorf("expected no error, got %v", err) 225 } 226 227 balance := new(big.Int).SetUint64(42) 228 chbook.Deposit(balance) 229 backend.Commit() 230 if chbook.Balance().Cmp(balance) != 0 { 231 t.Fatalf("expected balance %v, got %v", balance, chbook.Balance()) 232 } 233 234 amount := common.Big1 235 _, err = chbook.Issue(addr1, amount) 236 if err != nil { 237 t.Fatalf("expected no error, got %v", err) 238 } 239 backend.Commit() 240 exp := new(big.Int).SetUint64(41) 241 if chbook.Balance().Cmp(exp) != 0 { 242 t.Fatalf("expected balance %v, got %v", exp, chbook.Balance()) 243 } 244 245 // autodeposit on each issue 246 chbook.AutoDeposit(0, balance, balance) 247 _, err = chbook.Issue(addr1, amount) 248 if err != nil { 249 t.Fatalf("expected no error, got %v", err) 250 } 251 backend.Commit() 252 _, err = chbook.Issue(addr1, amount) 253 if err != nil { 254 t.Fatalf("expected no error, got %v", err) 255 } 256 backend.Commit() 257 if chbook.Balance().Cmp(balance) != 0 { 258 t.Fatalf("expected balance %v, got %v", balance, chbook.Balance()) 259 } 260 261 // autodeposit off 262 chbook.AutoDeposit(0, common.Big0, balance) 263 _, err = chbook.Issue(addr1, amount) 264 if err != nil { 265 t.Fatalf("expected no error, got %v", err) 266 } 267 backend.Commit() 268 _, err = chbook.Issue(addr1, amount) 269 if err != nil { 270 t.Fatalf("expected no error, got %v", err) 271 } 272 backend.Commit() 273 274 exp = new(big.Int).SetUint64(40) 275 if chbook.Balance().Cmp(exp) != 0 { 276 t.Fatalf("expected balance %v, got %v", exp, chbook.Balance()) 277 } 278 279 // autodeposit every 200ms if new cheque issued 280 interval := 200 * time.Millisecond 281 chbook.AutoDeposit(interval, common.Big1, balance) 282 _, err = chbook.Issue(addr1, amount) 283 if err != nil { 284 t.Fatalf("expected no error, got %v", err) 285 } 286 backend.Commit() 287 _, err = chbook.Issue(addr1, amount) 288 if err != nil { 289 t.Fatalf("expected no error, got %v", err) 290 } 291 backend.Commit() 292 293 exp = new(big.Int).SetUint64(38) 294 if chbook.Balance().Cmp(exp) != 0 { 295 t.Fatalf("expected balance %v, got %v", exp, chbook.Balance()) 296 } 297 298 time.Sleep(3 * interval) 299 backend.Commit() 300 if chbook.Balance().Cmp(balance) != 0 { 301 t.Fatalf("expected balance %v, got %v", balance, chbook.Balance()) 302 } 303 304 exp = new(big.Int).SetUint64(40) 305 chbook.AutoDeposit(4*interval, exp, balance) 306 _, err = chbook.Issue(addr1, amount) 307 if err != nil { 308 t.Fatalf("expected no error, got %v", err) 309 } 310 backend.Commit() 311 _, err = chbook.Issue(addr1, amount) 312 if err != nil { 313 t.Fatalf("expected no error, got %v", err) 314 } 315 time.Sleep(3 * interval) 316 backend.Commit() 317 if chbook.Balance().Cmp(exp) != 0 { 318 t.Fatalf("expected balance %v, got %v", exp, chbook.Balance()) 319 } 320 321 _, err = chbook.Issue(addr1, amount) 322 if err != nil { 323 t.Fatalf("expected no error, got %v", err) 324 } 325 time.Sleep(1 * interval) 326 backend.Commit() 327 328 if chbook.Balance().Cmp(balance) != 0 { 329 t.Fatalf("expected balance %v, got %v", balance, chbook.Balance()) 330 } 331 332 chbook.AutoDeposit(1*interval, common.Big0, balance) 333 chbook.Stop() 334 335 _, err = chbook.Issue(addr1, common.Big1) 336 if err != nil { 337 t.Fatalf("expected no error, got %v", err) 338 } 339 backend.Commit() 340 341 _, err = chbook.Issue(addr1, common.Big2) 342 if err != nil { 343 t.Fatalf("expected no error, got %v", err) 344 } 345 346 time.Sleep(1 * interval) 347 backend.Commit() 348 349 exp = new(big.Int).SetUint64(39) 350 if chbook.Balance().Cmp(exp) != 0 { 351 t.Fatalf("expected balance %v, got %v", exp, chbook.Balance()) 352 } 353 354 } 355 356 func TestCash(t *testing.T) { 357 path := filepath.Join(os.TempDir(), "chequebook-test.json") 358 backend := newTestBackend() 359 contr0, _ := deploy(key0, common.Big2, backend) 360 361 chbook, err := NewChequebook(path, contr0, key0, backend) 362 if err != nil { 363 t.Errorf("expected no error, got %v", err) 364 } 365 chbook.sent[addr1] = new(big.Int).SetUint64(42) 366 amount := common.Big1 367 chbook.balance = new(big.Int).Set(common.Big1) 368 ch, err := chbook.Issue(addr1, amount) 369 if err != nil { 370 t.Fatalf("expected no error, got %v", err) 371 } 372 backend.Commit() 373 chbox, err := NewInbox(key1, contr0, addr1, &key0.PublicKey, backend) 374 if err != nil { 375 t.Fatalf("expected no error, got %v", err) 376 } 377 378 // cashing latest cheque 379 if _, err = chbox.Receive(ch); err != nil { 380 t.Fatalf("expected no error, got %v", err) 381 } 382 if _, err = ch.Cash(chbook.session); err != nil { 383 t.Fatal("Cash failed:", err) 384 } 385 backend.Commit() 386 387 chbook.balance = new(big.Int).Set(common.Big3) 388 ch0, err := chbook.Issue(addr1, amount) 389 if err != nil { 390 t.Fatalf("expected no error, got %v", err) 391 } 392 backend.Commit() 393 ch1, err := chbook.Issue(addr1, amount) 394 if err != nil { 395 t.Fatalf("expected no error, got %v", err) 396 } 397 backend.Commit() 398 399 interval := 10 * time.Millisecond 400 // setting autocash with interval of 10ms 401 chbox.AutoCash(interval, nil) 402 _, err = chbox.Receive(ch0) 403 if err != nil { 404 t.Fatalf("expected no error, got %v", err) 405 } 406 _, err = chbox.Receive(ch1) 407 if err != nil { 408 t.Fatalf("expected no error, got %v", err) 409 } 410 backend.Commit() 411 // after 3x interval time and 2 cheques received, exactly one cashing tx is sent 412 time.Sleep(4 * interval) 413 backend.Commit() 414 415 // after stopping autocash no more tx are sent 416 ch2, err := chbook.Issue(addr1, amount) 417 if err != nil { 418 t.Fatalf("expected no error, got %v", err) 419 } 420 chbox.Stop() 421 _, err = chbox.Receive(ch2) 422 if err != nil { 423 t.Fatalf("expected no error, got %v", err) 424 } 425 time.Sleep(2 * interval) 426 backend.Commit() 427 428 // autocash below 1 429 chbook.balance = big.NewInt(2) 430 chbox.AutoCash(0, common.Big1) 431 432 ch3, err := chbook.Issue(addr1, amount) 433 if err != nil { 434 t.Fatalf("expected no error, got %v", err) 435 } 436 backend.Commit() 437 438 ch4, err := chbook.Issue(addr1, amount) 439 if err != nil { 440 t.Fatalf("expected no error, got %v", err) 441 } 442 backend.Commit() 443 444 _, err = chbox.Receive(ch3) 445 if err != nil { 446 t.Fatalf("expected no error, got %v", err) 447 } 448 backend.Commit() 449 _, err = chbox.Receive(ch4) 450 if err != nil { 451 t.Fatalf("expected no error, got %v", err) 452 } 453 backend.Commit() 454 455 // autochash on receipt when maxUncashed is 0 456 chbook.balance = new(big.Int).Set(common.Big2) 457 chbox.AutoCash(0, common.Big0) 458 459 ch5, err := chbook.Issue(addr1, amount) 460 if err != nil { 461 t.Fatalf("expected no error, got %v", err) 462 } 463 backend.Commit() 464 465 ch6, err := chbook.Issue(addr1, amount) 466 if err != nil { 467 t.Fatalf("expected no error, got %v", err) 468 } 469 470 _, err = chbox.Receive(ch5) 471 if err != nil { 472 t.Fatalf("expected no error, got %v", err) 473 } 474 backend.Commit() 475 476 _, err = chbox.Receive(ch6) 477 if err != nil { 478 t.Fatalf("expected no error, got %v", err) 479 } 480 backend.Commit() 481 482 }