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