github.com/klaytn/klaytn@v1.10.2/node/sc/bridge_manager_test.go (about) 1 // Copyright 2019 The klaytn Authors 2 // This file is part of the klaytn library. 3 // 4 // The klaytn 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 klaytn 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 klaytn library. If not, see <http://www.gnu.org/licenses/>. 16 17 package sc 18 19 import ( 20 "context" 21 "encoding/hex" 22 "io/ioutil" 23 "log" 24 "math/big" 25 "math/rand" 26 "os" 27 "path" 28 "strconv" 29 "sync" 30 "testing" 31 "time" 32 33 "github.com/golang/mock/gomock" 34 "github.com/klaytn/klaytn/accounts" 35 "github.com/klaytn/klaytn/accounts/abi/bind" 36 "github.com/klaytn/klaytn/accounts/abi/bind/backends" 37 "github.com/klaytn/klaytn/accounts/keystore" 38 "github.com/klaytn/klaytn/blockchain" 39 "github.com/klaytn/klaytn/blockchain/types" 40 "github.com/klaytn/klaytn/blockchain/vm" 41 "github.com/klaytn/klaytn/common" 42 "github.com/klaytn/klaytn/contracts/bridge" 43 sctoken "github.com/klaytn/klaytn/contracts/sc_erc20" 44 scnft "github.com/klaytn/klaytn/contracts/sc_erc721" 45 scnft_no_uri "github.com/klaytn/klaytn/contracts/sc_erc721_no_uri" 46 "github.com/klaytn/klaytn/crypto" 47 "github.com/klaytn/klaytn/node/sc/bridgepool" 48 "github.com/klaytn/klaytn/params" 49 "github.com/klaytn/klaytn/rlp" 50 "github.com/klaytn/klaytn/storage/database" 51 "github.com/stretchr/testify/assert" 52 ) 53 54 // WaitGroupWithTimeOut waits the given wait group until the timout duration. 55 func WaitGroupWithTimeOut(wg *sync.WaitGroup, duration time.Duration, t *testing.T) { 56 c := make(chan struct{}) 57 go func() { 58 wg.Wait() 59 c <- struct{}{} 60 }() 61 t.Log("start to wait group") 62 select { 63 case <-c: 64 t.Log("waiting group is done") 65 case <-time.After(duration): 66 t.Fatal("timed out waiting group") 67 } 68 } 69 70 // CheckReceipt can check if the tx receipt has expected status. 71 func CheckReceipt(b bind.DeployBackend, tx *types.Transaction, duration time.Duration, expectedStatus uint, t *testing.T) { 72 timeoutContext, cancelTimeout := context.WithTimeout(context.Background(), duration) 73 defer cancelTimeout() 74 75 receipt, err := bind.WaitMined(timeoutContext, b, tx) 76 assert.Equal(t, nil, err) 77 assert.Equal(t, expectedStatus, receipt.Status) 78 } 79 80 func handleValueTransfer(t *testing.T, ev IRequestValueTransferEvent, bridgeInfo *BridgeInfo, wg *sync.WaitGroup, backend *backends.SimulatedBackend) { 81 var ( 82 tokenType = ev.GetTokenType() 83 valueOrTokenId = ev.GetValueOrTokenId() 84 from = ev.GetFrom() 85 to = ev.GetTo() 86 contractAddr = ev.GetRaw().Address 87 tokenAddr = ev.GetTokenAddress() 88 requestNonce = ev.GetRequestNonce() 89 txHash = ev.GetRaw().TxHash 90 ) 91 t.Log("Request Event", 92 "type", tokenType, 93 "amount", valueOrTokenId, 94 "from", from.String(), 95 "to", to.String(), 96 "contract", contractAddr.String(), 97 "token", tokenAddr.String(), 98 "requestNonce", requestNonce) 99 100 bridge := bridgeInfo.bridge 101 done, err := bridge.HandledRequestTx(nil, txHash) 102 assert.NoError(t, err) 103 assert.Equal(t, false, done) 104 105 // insert the value transfer request event to the bridge info's event list. 106 bridgeInfo.AddRequestValueTransferEvents([]IRequestValueTransferEvent{ev}) 107 108 // handle the value transfer request event in the event list. 109 bridgeInfo.processingPendingRequestEvents() 110 111 backend.Commit() // block 112 wg.Done() 113 done, err = bridge.HandledRequestTx(nil, txHash) 114 assert.NoError(t, err) 115 assert.Equal(t, true, done) 116 } 117 118 // TestBridgeManager tests the event/method of Token/NFT/Bridge contracts. 119 // TODO-Klaytn-Servicechain needs to refine this test. 120 // - consider parent/child chain simulated backend. 121 // - separate each test 122 func TestBridgeManager(t *testing.T) { 123 tempDir, err := ioutil.TempDir(os.TempDir(), "sc") 124 assert.NoError(t, err) 125 defer func() { 126 if err := os.RemoveAll(tempDir); err != nil { 127 t.Fatalf("fail to delete file %v", err) 128 } 129 }() 130 131 wg := sync.WaitGroup{} 132 wg.Add(10) 133 134 // Config Bridge Account Manager 135 config := &SCConfig{} 136 config.DataDir = tempDir 137 bacc, _ := NewBridgeAccounts(nil, config.DataDir, database.NewDBManager(&database.DBConfig{DBType: database.MemoryDB}), DefaultBridgeTxGasLimit, DefaultBridgeTxGasLimit) 138 bacc.pAccount.chainID = big.NewInt(0) 139 bacc.cAccount.chainID = big.NewInt(0) 140 141 pAuth := bacc.cAccount.GenerateTransactOpts() 142 cAuth := bacc.pAccount.GenerateTransactOpts() 143 144 // Generate a new random account and a funded simulator 145 aliceKey, _ := crypto.GenerateKey() 146 alice := bind.NewKeyedTransactor(aliceKey) 147 148 bobKey, _ := crypto.GenerateKey() 149 bob := bind.NewKeyedTransactor(bobKey) 150 151 // Create Simulated backend 152 alloc := blockchain.GenesisAlloc{ 153 alice.From: {Balance: big.NewInt(params.KLAY)}, 154 bacc.pAccount.address: {Balance: big.NewInt(params.KLAY)}, 155 bacc.cAccount.address: {Balance: big.NewInt(params.KLAY)}, 156 } 157 sim := backends.NewSimulatedBackend(alloc) 158 defer sim.Close() 159 160 sc := &SubBridge{ 161 chainDB: database.NewDBManager(&database.DBConfig{DBType: database.MemoryDB}), 162 config: config, 163 peers: newBridgePeerSet(), 164 bridgeAccounts: bacc, 165 localBackend: sim, 166 remoteBackend: sim, 167 } 168 sc.handler, err = NewSubBridgeHandler(sc) 169 if err != nil { 170 log.Fatalf("Failed to initialize bridgeHandler : %v", err) 171 return 172 } 173 174 bridgeManager, err := NewBridgeManager(sc) 175 assert.NoError(t, err) 176 177 testToken := big.NewInt(123) 178 testKLAY := big.NewInt(321) 179 180 // 1. Deploy Bridge Contract 181 addr, err := bridgeManager.DeployBridgeTest(sim, 10000, false) 182 if err != nil { 183 log.Fatalf("Failed to deploy new bridge contract: %v", err) 184 } 185 bridgeInfo, _ := bridgeManager.GetBridgeInfo(addr) 186 bridge := bridgeInfo.bridge 187 t.Log("===== BridgeContract Addr ", addr.Hex()) 188 sim.Commit() // block 189 190 // 2. Deploy Token Contract 191 tokenAddr, tx, token, err := sctoken.DeployServiceChainToken(alice, sim, addr) 192 if err != nil { 193 log.Fatalf("Failed to DeployGXToken: %v", err) 194 } 195 sim.Commit() // block 196 197 // 3. Deploy NFT Contract 198 nftAddr, tx, nft, err := scnft.DeployServiceChainNFT(alice, sim, addr) 199 if err != nil { 200 log.Fatalf("Failed to DeployServiceChainNFT: %v", err) 201 } 202 sim.Commit() // block 203 204 // Register the owner as a signer 205 _, err = bridge.RegisterOperator(&bind.TransactOpts{From: cAuth.From, Signer: cAuth.Signer, GasLimit: testGasLimit}, cAuth.From) 206 assert.NoError(t, err) 207 sim.Commit() // block 208 209 // Register tokens on the bridgeInfo 210 bridgeInfo.RegisterToken(tokenAddr, tokenAddr) 211 bridgeInfo.RegisterToken(nftAddr, nftAddr) 212 213 // Register tokens on the bridge 214 bridge.RegisterToken(&bind.TransactOpts{From: cAuth.From, Signer: cAuth.Signer, GasLimit: testGasLimit}, tokenAddr, tokenAddr) 215 bridge.RegisterToken(&bind.TransactOpts{From: cAuth.From, Signer: cAuth.Signer, GasLimit: testGasLimit}, nftAddr, nftAddr) 216 sim.Commit() // block 217 218 cTokenAddr, err := bridge.RegisteredTokens(nil, tokenAddr) 219 assert.Equal(t, err, nil) 220 assert.Equal(t, cTokenAddr, tokenAddr) 221 cNftAddr, err := bridge.RegisteredTokens(nil, nftAddr) 222 assert.Equal(t, err, nil) 223 assert.Equal(t, cNftAddr, nftAddr) 224 225 balance, _ := sim.BalanceAt(context.Background(), pAuth.From, nil) 226 t.Logf("auth(%v) KLAY balance : %v\n", pAuth.From.String(), balance) 227 228 balance, _ = sim.BalanceAt(context.Background(), cAuth.From, nil) 229 t.Logf("auth2(%v) KLAY balance : %v\n", cAuth.From.String(), balance) 230 231 balance, _ = sim.BalanceAt(context.Background(), alice.From, nil) 232 t.Logf("auth3(%v) KLAY balance : %v\n", alice.From.String(), balance) 233 234 balance, _ = sim.BalanceAt(context.Background(), bob.From, nil) 235 t.Logf("auth4(%v) KLAY balance : %v\n", bob.From.String(), balance) 236 237 // 4. Subscribe Bridge Contract 238 bridgeManager.SubscribeEvent(addr) 239 240 reqVTevCh := make(chan RequestValueTransferEvent) 241 reqVTencodedEvCh := make(chan RequestValueTransferEncodedEvent) 242 handleValueTransferEventCh := make(chan *HandleValueTransferEvent) 243 bridgeManager.SubscribeReqVTev(reqVTevCh) 244 bridgeManager.SubscribeReqVTencodedEv(reqVTencodedEvCh) 245 bridgeManager.SubscribeHandleVTev(handleValueTransferEventCh) 246 247 go func() { 248 for { 249 select { 250 case ev := <-reqVTevCh: 251 handleValueTransfer(t, ev, bridgeInfo, &wg, sim) 252 case ev := <-reqVTencodedEvCh: 253 handleValueTransfer(t, ev, bridgeInfo, &wg, sim) 254 case ev := <-handleValueTransferEventCh: 255 t.Log("Handle value transfer event", 256 "bridgeAddr", ev.Raw.Address.Hex(), 257 "type", ev.TokenType, 258 "amount", ev.ValueOrTokenId, 259 "owner", ev.To.String(), 260 "contract", ev.Raw.Address.String(), 261 "token", ev.TokenAddress.String(), 262 "handleNonce", ev.HandleNonce) 263 wg.Done() 264 } 265 } 266 }() 267 268 nftTokenIDs := []uint64{4437, 4438, 4439} 269 testURIs := []string{"", "testURI", "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"} 270 // 6. Register (Mint) an NFT to Alice 271 { 272 for i := 0; i < len(nftTokenIDs); i++ { 273 tx, err = nft.MintWithTokenURI(&bind.TransactOpts{From: alice.From, Signer: alice.Signer, GasLimit: testGasLimit}, alice.From, big.NewInt(int64(nftTokenIDs[i])), testURIs[i]) 274 assert.NoError(t, err) 275 t.Log("Register NFT Transaction", tx.Hash().Hex()) 276 sim.Commit() // block 277 CheckReceipt(sim, tx, 1*time.Second, types.ReceiptStatusSuccessful, t) 278 279 owner, err := nft.OwnerOf(nil, big.NewInt(int64(nftTokenIDs[i]))) 280 assert.Equal(t, nil, err) 281 assert.Equal(t, alice.From, owner) 282 } 283 } 284 285 // 7. Request ERC20 Transfer from Alice to Bob 286 { 287 tx, err = token.RequestValueTransfer(&bind.TransactOpts{From: alice.From, Signer: alice.Signer, GasLimit: testGasLimit}, testToken, bob.From, big.NewInt(0), nil) 288 assert.NoError(t, err) 289 t.Log("RequestValueTransfer Transaction", tx.Hash().Hex()) 290 sim.Commit() // block 291 292 CheckReceipt(sim, tx, 1*time.Second, types.ReceiptStatusSuccessful, t) 293 } 294 295 // 8. RequestKLAYTransfer from Alice to Bob 296 { 297 tx, err = bridge.RequestKLAYTransfer(&bind.TransactOpts{From: alice.From, Signer: alice.Signer, Value: testKLAY, GasLimit: testGasLimit}, bob.From, testKLAY, nil) 298 assert.NoError(t, err) 299 t.Log("DepositKLAY Transaction", tx.Hash().Hex()) 300 301 sim.Commit() // block 302 303 CheckReceipt(sim, tx, 1*time.Second, types.ReceiptStatusSuccessful, t) 304 } 305 306 // 9. Request NFT transfer from Alice to Bob 307 { 308 for i := 0; i < len(nftTokenIDs); i++ { 309 tx, err = nft.RequestValueTransfer(&bind.TransactOpts{From: alice.From, Signer: alice.Signer, GasLimit: testGasLimit}, big.NewInt(int64(nftTokenIDs[i])), bob.From, nil) 310 assert.NoError(t, err) 311 t.Log("nft.RequestValueTransfer Transaction", tx.Hash().Hex()) 312 sim.Commit() // block 313 CheckReceipt(sim, tx, 1*time.Second, types.ReceiptStatusSuccessful, t) 314 315 uri, err := nft.TokenURI(nil, big.NewInt(int64(nftTokenIDs[i]))) 316 assert.NoError(t, err) 317 assert.Equal(t, testURIs[i], uri) 318 t.Log("URI length: ", len(testURIs[i]), len(uri)) 319 } 320 } 321 322 // Wait a few second for wait group 323 WaitGroupWithTimeOut(&wg, 3*time.Second, t) 324 325 // 10. Check Token balance 326 { 327 balance, err = token.BalanceOf(nil, bob.From) 328 assert.Equal(t, nil, err) 329 assert.Equal(t, testToken.String(), balance.String()) 330 } 331 332 // 11. Check KLAY balance 333 { 334 balance, err = sim.BalanceAt(context.Background(), bob.From, nil) 335 assert.Equal(t, nil, err) 336 assert.Equal(t, testKLAY.String(), balance.String()) 337 } 338 339 // 12. Check NFT owner sent by RequestValueTransfer() 340 { 341 for i := 0; i < len(nftTokenIDs); i++ { 342 owner, err := nft.OwnerOf(nil, big.NewInt(int64(nftTokenIDs[i]))) 343 assert.Equal(t, nil, err) 344 assert.Equal(t, bob.From, owner) 345 } 346 } 347 bridgeManager.Stop() 348 } 349 350 // TestBridgeManagerERC721_notSupportURI tests if bridge can handle an ERC721 which does not support URI. 351 func TestBridgeManagerERC721_notSupportURI(t *testing.T) { 352 tempDir, err := ioutil.TempDir(os.TempDir(), "sc") 353 assert.NoError(t, err) 354 defer func() { 355 if err := os.RemoveAll(tempDir); err != nil { 356 t.Fatalf("fail to delete file %v", err) 357 } 358 }() 359 360 wg := sync.WaitGroup{} 361 wg.Add(2) 362 363 // Config Bridge Account Manager 364 config := &SCConfig{} 365 config.DataDir = tempDir 366 bacc, _ := NewBridgeAccounts(nil, config.DataDir, database.NewDBManager(&database.DBConfig{DBType: database.MemoryDB}), DefaultBridgeTxGasLimit, DefaultBridgeTxGasLimit) 367 bacc.pAccount.chainID = big.NewInt(0) 368 bacc.cAccount.chainID = big.NewInt(0) 369 370 // pAuth := bacc.cAccount.GenerateTransactOpts() 371 cAuth := bacc.pAccount.GenerateTransactOpts() 372 373 // Generate a new random account and a funded simulator 374 aliceKey, _ := crypto.GenerateKey() 375 alice := bind.NewKeyedTransactor(aliceKey) 376 377 bobKey, _ := crypto.GenerateKey() 378 bob := bind.NewKeyedTransactor(bobKey) 379 380 // Create Simulated backend 381 alloc := blockchain.GenesisAlloc{ 382 alice.From: {Balance: big.NewInt(params.KLAY)}, 383 bacc.pAccount.address: {Balance: big.NewInt(params.KLAY)}, 384 bacc.cAccount.address: {Balance: big.NewInt(params.KLAY)}, 385 } 386 sim := backends.NewSimulatedBackend(alloc) 387 defer sim.Close() 388 389 sc := &SubBridge{ 390 chainDB: database.NewDBManager(&database.DBConfig{DBType: database.MemoryDB}), 391 config: config, 392 peers: newBridgePeerSet(), 393 bridgeAccounts: bacc, 394 localBackend: sim, 395 remoteBackend: sim, 396 } 397 398 sc.handler, err = NewSubBridgeHandler(sc) 399 if err != nil { 400 log.Fatalf("Failed to initialize bridgeHandler : %v", err) 401 return 402 } 403 404 bridgeManager, err := NewBridgeManager(sc) 405 assert.NoError(t, err) 406 407 // Deploy Bridge Contract 408 addr, err := bridgeManager.DeployBridgeTest(sim, 10000, false) 409 if err != nil { 410 log.Fatalf("Failed to deploy new bridge contract: %v", err) 411 } 412 bridgeInfo, _ := bridgeManager.GetBridgeInfo(addr) 413 bridge := bridgeInfo.bridge 414 t.Log("===== BridgeContract Addr ", addr.Hex()) 415 sim.Commit() // block 416 417 // Deploy NFT Contract 418 nftTokenID := uint64(4438) 419 nftAddr, tx, nft, err := scnft_no_uri.DeployServiceChainNFTNoURI(alice, sim, addr) 420 if err != nil { 421 log.Fatalf("Failed to DeployServiceChainNFT: %v", err) 422 } 423 424 nft_uri, err := scnft.NewServiceChainNFT(nftAddr, sim) 425 if err != nil { 426 log.Fatalf("Failed to get NFT object: %v", err) 427 } 428 429 sim.Commit() // block 430 431 // Register the owner as a signer 432 _, err = bridge.RegisterOperator(&bind.TransactOpts{From: cAuth.From, Signer: cAuth.Signer, GasLimit: testGasLimit}, cAuth.From) 433 assert.NoError(t, err) 434 sim.Commit() // block 435 436 // Register tokens on the bridgeInfo 437 bridgeInfo.RegisterToken(nftAddr, nftAddr) 438 439 // Register tokens on the bridge 440 bridge.RegisterToken(&bind.TransactOpts{From: cAuth.From, Signer: cAuth.Signer, GasLimit: testGasLimit}, nftAddr, nftAddr) 441 sim.Commit() // block 442 443 cNftAddr, err := bridge.RegisteredTokens(nil, nftAddr) 444 assert.Equal(t, err, nil) 445 assert.Equal(t, cNftAddr, nftAddr) 446 447 // Subscribe Bridge Contract 448 bridgeManager.SubscribeEvent(addr) 449 450 reqVTevCh := make(chan RequestValueTransferEvent) 451 reqVTencodedEvCh := make(chan RequestValueTransferEncodedEvent) 452 handleValueTransferEventCh := make(chan *HandleValueTransferEvent) 453 bridgeManager.SubscribeReqVTev(reqVTevCh) 454 bridgeManager.SubscribeReqVTencodedEv(reqVTencodedEvCh) 455 bridgeManager.SubscribeHandleVTev(handleValueTransferEventCh) 456 457 go func() { 458 for { 459 select { 460 case ev := <-reqVTevCh: 461 handleValueTransfer(t, ev, bridgeInfo, &wg, sim) 462 case ev := <-reqVTencodedEvCh: 463 handleValueTransfer(t, ev, bridgeInfo, &wg, sim) 464 case ev := <-handleValueTransferEventCh: 465 t.Log("Handle value transfer event", 466 "bridgeAddr", ev.Raw.Address.Hex(), 467 "type", ev.TokenType, 468 "amount", ev.ValueOrTokenId, 469 "owner", ev.To.String(), 470 "contract", ev.Raw.Address.String(), 471 "token", ev.TokenAddress.String(), 472 "handleNonce", ev.HandleNonce) 473 wg.Done() 474 } 475 } 476 }() 477 478 // Register (Mint) an NFT to Alice 479 { 480 tx, err = nft.Mint(&bind.TransactOpts{From: alice.From, Signer: alice.Signer, GasLimit: testGasLimit}, alice.From, big.NewInt(int64(nftTokenID))) 481 assert.NoError(t, err) 482 t.Log("Register NFT Transaction", tx.Hash().Hex()) 483 sim.Commit() // block 484 485 CheckReceipt(sim, tx, 1*time.Second, types.ReceiptStatusSuccessful, t) 486 487 owner, err := nft.OwnerOf(nil, big.NewInt(int64(nftTokenID))) 488 assert.Equal(t, nil, err) 489 assert.Equal(t, alice.From, owner) 490 } 491 492 // Request NFT transfer from Alice to Bob 493 { 494 tx, err = nft.RequestValueTransfer(&bind.TransactOpts{From: alice.From, Signer: alice.Signer, GasLimit: testGasLimit}, big.NewInt(int64(nftTokenID)), bob.From, nil) 495 assert.NoError(t, err) 496 t.Log("nft.RequestValueTransfer Transaction", tx.Hash().Hex()) 497 498 sim.Commit() // block 499 500 CheckReceipt(sim, tx, 1*time.Second, types.ReceiptStatusSuccessful, t) 501 uri, err := nft_uri.TokenURI(nil, big.NewInt(int64(nftTokenID))) 502 assert.Equal(t, vm.ErrExecutionReverted, err) 503 assert.Equal(t, "", uri) 504 } 505 506 // Wait a few second for wait group 507 WaitGroupWithTimeOut(&wg, 3*time.Second, t) 508 509 // Check NFT owner 510 { 511 owner, err := nft.OwnerOf(nil, big.NewInt(int64(nftTokenID))) 512 assert.Equal(t, nil, err) 513 assert.Equal(t, bob.From, owner) 514 } 515 516 bridgeManager.Stop() 517 } 518 519 // TestBridgeManagerWithFee tests the KLAY/ERC20 transfer with fee. 520 func TestBridgeManagerWithFee(t *testing.T) { 521 tempDir, err := ioutil.TempDir(os.TempDir(), "sc") 522 assert.NoError(t, err) 523 defer func() { 524 if err := os.RemoveAll(tempDir); err != nil { 525 t.Fatalf("fail to delete file %v", err) 526 } 527 }() 528 529 wg := sync.WaitGroup{} 530 wg.Add(7 * 2) 531 532 // Generate a new random account and a funded simulator 533 AliceKey, _ := crypto.GenerateKey() 534 Alice := bind.NewKeyedTransactor(AliceKey) 535 536 BobKey, _ := crypto.GenerateKey() 537 Bob := bind.NewKeyedTransactor(BobKey) 538 539 receiverKey, _ := crypto.GenerateKey() 540 receiver := bind.NewKeyedTransactor(receiverKey) 541 542 // Config Bridge Account Manager 543 config := &SCConfig{} 544 config.DataDir = tempDir 545 bacc, _ := NewBridgeAccounts(nil, config.DataDir, database.NewDBManager(&database.DBConfig{DBType: database.MemoryDB}), DefaultBridgeTxGasLimit, DefaultBridgeTxGasLimit) 546 bacc.pAccount.chainID = big.NewInt(0) 547 bacc.cAccount.chainID = big.NewInt(0) 548 549 pAuth := bacc.cAccount.GenerateTransactOpts() 550 cAuth := bacc.pAccount.GenerateTransactOpts() 551 552 // Create Simulated backend 553 initialValue := int64(10000000000) 554 alloc := blockchain.GenesisAlloc{ 555 Alice.From: {Balance: big.NewInt(initialValue)}, 556 bacc.cAccount.address: {Balance: big.NewInt(initialValue)}, 557 bacc.pAccount.address: {Balance: big.NewInt(initialValue)}, 558 } 559 sim := backends.NewSimulatedBackend(alloc) 560 defer sim.Close() 561 562 sc := &SubBridge{ 563 chainDB: database.NewDBManager(&database.DBConfig{DBType: database.MemoryDB}), 564 config: config, 565 peers: newBridgePeerSet(), 566 bridgeAccounts: bacc, 567 } 568 sc.handler, err = NewSubBridgeHandler(sc) 569 if err != nil { 570 log.Fatalf("Failed to initialize bridgeHandler : %v", err) 571 return 572 } 573 574 bridgeManager, err := NewBridgeManager(sc) 575 576 testToken := int64(100000) 577 testKLAY := int64(100000) 578 KLAYFee := int64(500) 579 ERC20Fee := int64(500) 580 581 // 1. Deploy Bridge Contract 582 pBridgeAddr, err := bridgeManager.DeployBridgeTest(sim, 10000, false) 583 assert.NoError(t, err) 584 pBridgeInfo, _ := bridgeManager.GetBridgeInfo(pBridgeAddr) 585 pBridge := pBridgeInfo.bridge 586 t.Log("===== BridgeContract Addr ", pBridgeAddr.Hex()) 587 sim.Commit() // block 588 589 // 2. Deploy Token Contract 590 tokenAddr, tx, token, err := sctoken.DeployServiceChainToken(pAuth, sim, pBridgeAddr) 591 assert.NoError(t, err) 592 sim.Commit() // block 593 594 // Set value transfer fee 595 { 596 nilReceiver, err := pBridge.FeeReceiver(nil) 597 assert.Equal(t, nil, err) 598 assert.Equal(t, common.Address{}, nilReceiver) 599 } 600 601 pBridge.SetFeeReceiver(&bind.TransactOpts{From: cAuth.From, Signer: cAuth.Signer, GasLimit: testGasLimit}, receiver.From) 602 sim.Commit() // block 603 604 { 605 recv, err := pBridge.FeeReceiver(nil) 606 assert.Equal(t, nil, err) 607 assert.Equal(t, receiver.From, recv) 608 } 609 610 { 611 fee, err := pBridge.FeeOfKLAY(nil) 612 assert.Equal(t, nil, err) 613 assert.Equal(t, big.NewInt(0).String(), fee.String()) 614 } 615 616 { 617 fee, err := pBridge.FeeOfERC20(nil, tokenAddr) 618 assert.Equal(t, nil, err) 619 assert.Equal(t, big.NewInt(0).String(), fee.String()) 620 } 621 622 cn, err := pBridge.ConfigurationNonce(nil) 623 assert.NoError(t, err) 624 _, err = pBridge.RegisterOperator(&bind.TransactOpts{From: cAuth.From, Signer: cAuth.Signer, GasLimit: testGasLimit}, cAuth.From) 625 assert.NoError(t, err) 626 pBridge.SetKLAYFee(&bind.TransactOpts{From: cAuth.From, Signer: cAuth.Signer, GasLimit: testGasLimit}, big.NewInt(KLAYFee), cn) 627 pBridge.SetERC20Fee(&bind.TransactOpts{From: cAuth.From, Signer: cAuth.Signer, GasLimit: testGasLimit}, tokenAddr, big.NewInt(ERC20Fee), cn+1) 628 sim.Commit() // block 629 630 { 631 fee, err := pBridge.FeeOfKLAY(nil) 632 assert.Equal(t, nil, err) 633 assert.Equal(t, KLAYFee, fee.Int64()) 634 } 635 636 { 637 fee, err := pBridge.FeeOfERC20(nil, tokenAddr) 638 assert.Equal(t, nil, err) 639 assert.Equal(t, ERC20Fee, fee.Int64()) 640 } 641 642 // Register tokens on the bridgeInfo 643 pBridgeInfo.RegisterToken(tokenAddr, tokenAddr) 644 645 // Register tokens on the bridge 646 pBridge.RegisterToken(&bind.TransactOpts{From: cAuth.From, Signer: cAuth.Signer, GasLimit: testGasLimit}, tokenAddr, tokenAddr) 647 sim.Commit() // block 648 649 cTokenAddr, err := pBridge.RegisteredTokens(nil, tokenAddr) 650 assert.Equal(t, err, nil) 651 assert.Equal(t, cTokenAddr, tokenAddr) 652 653 balance, _ := sim.BalanceAt(context.Background(), Alice.From, nil) 654 t.Logf("Alice(%v) KLAY balance : %v\n", Alice.From.String(), balance) 655 656 balance, _ = sim.BalanceAt(context.Background(), Bob.From, nil) 657 t.Logf("Bob(%v) KLAY balance : %v\n", Bob.From.String(), balance) 658 659 // 4. Subscribe Bridge Contract 660 bridgeManager.SubscribeEvent(pBridgeAddr) 661 662 reqVTevCh := make(chan RequestValueTransferEvent) 663 handleValueTransferEventCh := make(chan *HandleValueTransferEvent) 664 bridgeManager.SubscribeReqVTev(reqVTevCh) 665 bridgeManager.SubscribeHandleVTev(handleValueTransferEventCh) 666 667 go func() { 668 for { 669 select { 670 case ev := <-reqVTevCh: 671 t.Log("Request value transfer event", 672 "type", ev.GetTokenType(), 673 "amount", ev.GetValueOrTokenId(), 674 "from", ev.GetFrom().String(), 675 "to", ev.GetTo().String(), 676 "contract", ev.GetRaw().Address.String(), 677 "token", ev.GetTokenAddress().String(), 678 "requestNonce", ev.GetRequestNonce(), 679 "fee", ev.GetFee().String()) 680 681 // insert the value transfer request event to the bridge info's event list. 682 pBridgeInfo.AddRequestValueTransferEvents([]IRequestValueTransferEvent{ev}) 683 684 // handle the value transfer request event in the event list. 685 pBridgeInfo.processingPendingRequestEvents() 686 687 sim.Commit() // block 688 wg.Done() 689 690 case ev := <-handleValueTransferEventCh: 691 t.Log("Handle value transfer event", 692 "bridgeAddr", ev.Raw.Address.Hex(), 693 "type", ev.TokenType, 694 "amount", ev.ValueOrTokenId, 695 "owner", ev.To.String(), 696 "contract", ev.Raw.Address.String(), 697 "token", ev.TokenAddress.String(), 698 "handleNonce", ev.HandleNonce) 699 wg.Done() 700 } 701 } 702 }() 703 704 // 5. transfer from parentAcc to Alice for charging and check balances 705 { 706 tx, err = token.Transfer(&bind.TransactOpts{From: pAuth.From, Signer: pAuth.Signer, GasLimit: testGasLimit}, Alice.From, big.NewInt(initialValue)) 707 if err != nil { 708 log.Fatalf("Failed to Transfer for charging: %v", err) 709 } 710 t.Log("Transfer Transaction", tx.Hash().Hex()) 711 sim.Commit() // block 712 713 CheckReceipt(sim, tx, 1*time.Second, types.ReceiptStatusSuccessful, t) 714 715 balance, err = token.BalanceOf(nil, pAuth.From) 716 assert.Equal(t, nil, err) 717 t.Log("parentAcc token balance", balance.String()) 718 719 balance, err = token.BalanceOf(nil, Alice.From) 720 assert.Equal(t, nil, err) 721 t.Log("Alice token balance", balance.String()) 722 723 balance, err = token.BalanceOf(nil, Bob.From) 724 assert.Equal(t, nil, err) 725 t.Log("Bob token balance", balance.String()) 726 } 727 728 // 7-1. Request ERC20 Transfer from Alice to Bob with same feeLimit with fee 729 { 730 tx, err = token.RequestValueTransfer(&bind.TransactOpts{From: Alice.From, Signer: Alice.Signer, GasLimit: testGasLimit}, big.NewInt(testToken), Bob.From, big.NewInt(ERC20Fee), nil) 731 assert.NoError(t, err) 732 t.Log("RequestValueTransfer Transaction", tx.Hash().Hex()) 733 sim.Commit() // block 734 735 CheckReceipt(sim, tx, 1*time.Second, types.ReceiptStatusSuccessful, t) 736 } 737 738 // 7-2. Request ERC20 Transfer from Alice to Bob with insufficient zero feeLimit 739 { 740 tx, err = token.RequestValueTransfer(&bind.TransactOpts{From: Alice.From, Signer: Alice.Signer, GasLimit: testGasLimit}, big.NewInt(testToken), Bob.From, big.NewInt(0), nil) 741 assert.Equal(t, nil, err) 742 743 sim.Commit() // block 744 745 CheckReceipt(sim, tx, 1*time.Second, types.ReceiptStatusErrExecutionReverted, t) 746 } 747 748 // 7-3. Request ERC20 Transfer from Alice to Bob with insufficient feeLimit 749 { 750 tx, err = token.RequestValueTransfer(&bind.TransactOpts{From: Alice.From, Signer: Alice.Signer, GasLimit: testGasLimit}, big.NewInt(testToken), Bob.From, big.NewInt(ERC20Fee-1), nil) 751 assert.Equal(t, nil, err) 752 753 sim.Commit() // block 754 755 CheckReceipt(sim, tx, 1*time.Second, types.ReceiptStatusErrExecutionReverted, t) 756 } 757 758 // 7-4. Request ERC20 Transfer from Alice to Bob with enough feeLimit 759 { 760 tx, err = token.RequestValueTransfer(&bind.TransactOpts{From: Alice.From, Signer: Alice.Signer, GasLimit: testGasLimit}, big.NewInt(testToken), Bob.From, big.NewInt(ERC20Fee+1), nil) 761 assert.Equal(t, nil, err) 762 763 sim.Commit() // block 764 765 CheckReceipt(sim, tx, 1*time.Second, types.ReceiptStatusSuccessful, t) 766 } 767 768 // 8-1. Approve/Request ERC20 Transfer from Alice to Bob with same feeLimit with fee 769 { 770 tx, err = token.Approve(&bind.TransactOpts{From: Alice.From, Signer: Alice.Signer, GasLimit: testGasLimit}, pBridgeAddr, big.NewInt(testToken+ERC20Fee)) 771 assert.Equal(t, nil, err) 772 773 tx, err = pBridge.RequestERC20Transfer(&bind.TransactOpts{From: Alice.From, Signer: Alice.Signer, GasLimit: testGasLimit}, tokenAddr, Bob.From, big.NewInt(testToken), big.NewInt(ERC20Fee), nil) 774 assert.Equal(t, nil, err) 775 776 t.Log("RequestValueTransfer Transaction", tx.Hash().Hex()) 777 sim.Commit() // block 778 779 CheckReceipt(sim, tx, 1*time.Second, types.ReceiptStatusSuccessful, t) 780 } 781 782 // 8-2. Approve/Request ERC20 Transfer from Alice to Bob with insufficient zero feeLimit 783 { 784 tx, err = token.Approve(&bind.TransactOpts{From: Alice.From, Signer: Alice.Signer, GasLimit: testGasLimit}, pBridgeAddr, big.NewInt(testToken)) 785 assert.Equal(t, nil, err) 786 787 tx, err = pBridge.RequestERC20Transfer(&bind.TransactOpts{From: Alice.From, Signer: Alice.Signer, GasLimit: testGasLimit}, tokenAddr, Bob.From, big.NewInt(testToken), big.NewInt(0), nil) 788 assert.Equal(t, nil, err) 789 790 t.Log("RequestValueTransfer Transaction", tx.Hash().Hex()) 791 sim.Commit() // block 792 793 CheckReceipt(sim, tx, 1*time.Second, types.ReceiptStatusErrExecutionReverted, t) 794 } 795 796 // 8-3. Approve/Request ERC20 Transfer from Alice to Bob with insufficient feeLimit 797 { 798 tx, err = token.Approve(&bind.TransactOpts{From: Alice.From, Signer: Alice.Signer, GasLimit: testGasLimit}, pBridgeAddr, big.NewInt(testToken+ERC20Fee-1)) 799 assert.Equal(t, nil, err) 800 801 tx, err = pBridge.RequestERC20Transfer(&bind.TransactOpts{From: Alice.From, Signer: Alice.Signer, GasLimit: testGasLimit}, tokenAddr, Bob.From, big.NewInt(testToken), big.NewInt(ERC20Fee-1), nil) 802 assert.Equal(t, nil, err) 803 804 t.Log("RequestValueTransfer Transaction", tx.Hash().Hex()) 805 sim.Commit() // block 806 807 CheckReceipt(sim, tx, 1*time.Second, types.ReceiptStatusErrExecutionReverted, t) 808 } 809 810 // 8-4. Approve/Request ERC20 Transfer from Alice to Bob with enough feeLimit 811 { 812 tx, err = token.Approve(&bind.TransactOpts{From: Alice.From, Signer: Alice.Signer, GasLimit: testGasLimit}, pBridgeAddr, big.NewInt(testToken+ERC20Fee+1)) 813 assert.Equal(t, nil, err) 814 815 tx, err = pBridge.RequestERC20Transfer(&bind.TransactOpts{From: Alice.From, Signer: Alice.Signer, GasLimit: testGasLimit}, tokenAddr, Bob.From, big.NewInt(testToken), big.NewInt(ERC20Fee+1), nil) 816 assert.Equal(t, nil, err) 817 818 t.Log("RequestValueTransfer Transaction", tx.Hash().Hex()) 819 sim.Commit() // block 820 821 CheckReceipt(sim, tx, 1*time.Second, types.ReceiptStatusSuccessful, t) 822 } 823 824 // 9-1. Request KLAY transfer from Alice to Bob with same feeLimit with fee 825 { 826 tx, err = pBridge.RequestKLAYTransfer(&bind.TransactOpts{From: Alice.From, Signer: Alice.Signer, Value: big.NewInt(testKLAY + KLAYFee), GasLimit: testGasLimit}, Bob.From, big.NewInt(testKLAY), nil) 827 if err != nil { 828 log.Fatalf("Failed to RequestKLAYTransfer: %v", err) 829 } 830 t.Log("RequestKLAYTransfer Transaction", tx.Hash().Hex()) 831 832 sim.Commit() // block 833 834 CheckReceipt(sim, tx, 1*time.Second, types.ReceiptStatusSuccessful, t) 835 } 836 837 // 9-2. Request KLAY transfer from Alice to Bob with zero feeLimit 838 { 839 tx, err = pBridge.RequestKLAYTransfer(&bind.TransactOpts{From: Alice.From, Signer: Alice.Signer, Value: big.NewInt(testKLAY), GasLimit: testGasLimit}, Bob.From, big.NewInt(testKLAY), nil) 840 assert.Equal(t, nil, err) 841 842 sim.Commit() // block 843 844 CheckReceipt(sim, tx, 1*time.Second, types.ReceiptStatusErrExecutionReverted, t) 845 } 846 847 // 9-3. Request KLAY transfer from Alice to Bob with insufficient feeLimit 848 { 849 tx, err = pBridge.RequestKLAYTransfer(&bind.TransactOpts{From: Alice.From, Signer: Alice.Signer, Value: big.NewInt(testKLAY + (KLAYFee - 1)), GasLimit: testGasLimit}, Bob.From, big.NewInt(testKLAY), nil) 850 assert.Equal(t, nil, err) 851 852 sim.Commit() // block 853 854 CheckReceipt(sim, tx, 1*time.Second, types.ReceiptStatusErrExecutionReverted, t) 855 } 856 857 // 9-4. Request KLAY transfer from Alice to Bob with enough feeLimit 858 { 859 tx, err = pBridge.RequestKLAYTransfer(&bind.TransactOpts{From: Alice.From, Signer: Alice.Signer, Value: big.NewInt(testKLAY + (KLAYFee + 1)), GasLimit: testGasLimit}, Bob.From, big.NewInt(testKLAY), nil) 860 assert.Equal(t, nil, err) 861 862 sim.Commit() // block 863 864 CheckReceipt(sim, tx, 1*time.Second, types.ReceiptStatusSuccessful, t) 865 } 866 867 // 9-4. Request KLAY transfer from Alice to Alice through () payable method 868 { 869 nonce, _ := sim.PendingNonceAt(context.Background(), Alice.From) 870 gasPrice, _ := sim.SuggestGasPrice(context.Background()) 871 unsignedTx := types.NewTransaction(nonce, pBridgeAddr, big.NewInt(testKLAY+KLAYFee), testGasLimit, gasPrice, []byte{}) 872 873 chainID, _ := sim.ChainID(context.Background()) 874 tx, err = types.SignTx(unsignedTx, types.LatestSignerForChainID(chainID), AliceKey) 875 sim.SendTransaction(context.Background(), tx) 876 assert.Equal(t, nil, err) 877 878 sim.Commit() // block 879 880 CheckReceipt(sim, tx, 1*time.Second, types.ReceiptStatusSuccessful, t) 881 } 882 883 // Wait a few second for wait group 884 WaitGroupWithTimeOut(&wg, 3*time.Second, t) 885 886 // 10. Check Token balance 887 { 888 balance, err = token.BalanceOf(nil, Alice.From) 889 assert.Equal(t, nil, err) 890 t.Log("Alice token balance", balance.String()) 891 assert.Equal(t, initialValue-(testToken+ERC20Fee)*4, balance.Int64()) 892 893 balance, err = token.BalanceOf(nil, Bob.From) 894 assert.Equal(t, nil, err) 895 t.Log("Bob token balance", balance.String()) 896 assert.Equal(t, testToken*4, balance.Int64()) 897 898 balance, err = token.BalanceOf(nil, receiver.From) 899 assert.Equal(t, nil, err) 900 t.Log("Fee receiver token balance", balance.String()) 901 assert.Equal(t, ERC20Fee*4, balance.Int64()) 902 } 903 904 // 11. Check KLAY balance 905 { 906 balance, _ = sim.BalanceAt(context.Background(), Alice.From, nil) 907 t.Log("Alice KLAY balance :", balance) 908 assert.Equal(t, initialValue-(testKLAY+KLAYFee)*2-KLAYFee, balance.Int64()) 909 910 balance, _ = sim.BalanceAt(context.Background(), Bob.From, nil) 911 t.Log("Bob KLAY balance :", balance) 912 assert.Equal(t, big.NewInt(testKLAY*2).String(), balance.String()) 913 914 balance, _ = sim.BalanceAt(context.Background(), receiver.From, nil) 915 t.Log("receiver KLAY balance :", balance) 916 assert.Equal(t, KLAYFee*3, balance.Int64()) 917 } 918 919 bridgeManager.Stop() 920 } 921 922 // TestBasicJournal tests basic journal functionality. 923 func TestBasicJournal(t *testing.T) { 924 tempDir, err := ioutil.TempDir(os.TempDir(), "sc") 925 assert.NoError(t, err) 926 defer func() { 927 if err := os.RemoveAll(tempDir); err != nil { 928 t.Fatalf("fail to delete file %v", err) 929 } 930 }() 931 932 wg := sync.WaitGroup{} 933 wg.Add(2) 934 935 // Generate a new random account and a funded simulator 936 key, _ := crypto.GenerateKey() 937 auth := bind.NewKeyedTransactor(key) 938 939 key2, _ := crypto.GenerateKey() 940 auth2 := bind.NewKeyedTransactor(key2) 941 942 key4, _ := crypto.GenerateKey() 943 auth4 := bind.NewKeyedTransactor(key4) 944 945 config := &SCConfig{} 946 config.DataDir = tempDir 947 config.VTRecovery = true 948 949 bacc, _ := NewBridgeAccounts(nil, tempDir, database.NewDBManager(&database.DBConfig{DBType: database.MemoryDB}), DefaultBridgeTxGasLimit, DefaultBridgeTxGasLimit) 950 bacc.pAccount.chainID = big.NewInt(0) 951 bacc.cAccount.chainID = big.NewInt(0) 952 953 alloc := blockchain.GenesisAlloc{ 954 auth.From: {Balance: big.NewInt(params.KLAY)}, 955 auth2.From: {Balance: big.NewInt(params.KLAY)}, 956 auth4.From: {Balance: big.NewInt(params.KLAY)}, 957 bacc.pAccount.address: {Balance: big.NewInt(params.KLAY)}, 958 bacc.cAccount.address: {Balance: big.NewInt(params.KLAY)}, 959 } 960 sim := backends.NewSimulatedBackend(alloc) 961 defer sim.Close() 962 963 sc := &SubBridge{ 964 config: config, 965 peers: newBridgePeerSet(), 966 localBackend: sim, 967 remoteBackend: sim, 968 bridgeAccounts: bacc, 969 } 970 sc.handler, err = NewSubBridgeHandler(sc) 971 if err != nil { 972 log.Fatalf("Failed to initialize bridgeHandler : %v", err) 973 return 974 } 975 976 // Prepare manager and deploy bridge contract. 977 bm, err := NewBridgeManager(sc) 978 assert.NoError(t, err) 979 980 localAddr, err := bm.DeployBridgeTest(sim, 10000, true) 981 assert.NoError(t, err) 982 remoteAddr, err := bm.DeployBridgeTest(sim, 10000, false) 983 assert.NoError(t, err) 984 985 bm.SetJournal("", localAddr, remoteAddr) 986 987 ps := sc.BridgePeerSet() 988 ps.peers["test"] = nil 989 990 if err := bm.RestoreBridges(); err != nil { 991 t.Fatal("bm restoring bridges failed") 992 } 993 994 localInfo, ok := bm.GetBridgeInfo(localAddr) 995 assert.Equal(t, true, ok) 996 assert.Equal(t, false, localInfo.subscribed) 997 998 remoteInfo, ok := bm.GetBridgeInfo(remoteAddr) 999 assert.Equal(t, true, ok) 1000 assert.Equal(t, false, remoteInfo.subscribed) 1001 } 1002 1003 // TestMethodRestoreBridges tests restoring bridges from the journal. 1004 func TestMethodRestoreBridges(t *testing.T) { 1005 tempDir, err := ioutil.TempDir(os.TempDir(), "sc") 1006 assert.NoError(t, err) 1007 defer func() { 1008 if err := os.RemoveAll(tempDir); err != nil { 1009 t.Fatalf("fail to delete file %v", err) 1010 } 1011 }() 1012 1013 wg := sync.WaitGroup{} 1014 wg.Add(2) 1015 1016 // Generate a new random account and a funded simulator 1017 key, _ := crypto.GenerateKey() 1018 auth := bind.NewKeyedTransactor(key) 1019 1020 key2, _ := crypto.GenerateKey() 1021 auth2 := bind.NewKeyedTransactor(key2) 1022 1023 key4, _ := crypto.GenerateKey() 1024 auth4 := bind.NewKeyedTransactor(key4) 1025 config := &SCConfig{} 1026 config.DataDir = tempDir 1027 config.VTRecovery = true 1028 config.VTRecoveryInterval = 60 1029 1030 bacc, _ := NewBridgeAccounts(nil, tempDir, database.NewDBManager(&database.DBConfig{DBType: database.MemoryDB}), DefaultBridgeTxGasLimit, DefaultBridgeTxGasLimit) 1031 bacc.pAccount.chainID = big.NewInt(0) 1032 bacc.cAccount.chainID = big.NewInt(0) 1033 1034 alloc := blockchain.GenesisAlloc{ 1035 auth.From: {Balance: big.NewInt(params.KLAY)}, 1036 auth2.From: {Balance: big.NewInt(params.KLAY)}, 1037 auth4.From: {Balance: big.NewInt(params.KLAY)}, 1038 bacc.pAccount.address: {Balance: big.NewInt(params.KLAY)}, 1039 bacc.cAccount.address: {Balance: big.NewInt(params.KLAY)}, 1040 } 1041 sim := backends.NewSimulatedBackend(alloc) 1042 defer sim.Close() 1043 1044 sc := &SubBridge{ 1045 config: config, 1046 peers: newBridgePeerSet(), 1047 localBackend: sim, 1048 remoteBackend: sim, 1049 bridgeAccounts: bacc, 1050 } 1051 1052 sc.handler, err = NewSubBridgeHandler(sc) 1053 if err != nil { 1054 log.Fatalf("Failed to initialize bridgeHandler : %v", err) 1055 return 1056 } 1057 1058 // Prepare manager and deploy bridge contract. 1059 bm, err := NewBridgeManager(sc) 1060 assert.NoError(t, err) 1061 1062 var bridgeAddrs [4]common.Address 1063 for i := 0; i < 4; i++ { 1064 if i%2 == 0 { 1065 bridgeAddrs[i], err = bm.DeployBridgeTest(sim, 10000, true) 1066 } else { 1067 bridgeAddrs[i], err = bm.DeployBridgeTest(sim, 10000, false) 1068 } 1069 if err != nil { 1070 t.Fatal("deploy bridge test failed", bridgeAddrs[i]) 1071 } 1072 bm.DeleteBridgeInfo(bridgeAddrs[i]) 1073 } 1074 sim.Commit() 1075 1076 // Set journal 1077 bm.SetJournal("", bridgeAddrs[0], bridgeAddrs[1]) 1078 bm.journal.cache[bridgeAddrs[0]].Subscribed = true 1079 bm.SetJournal("", bridgeAddrs[2], bridgeAddrs[3]) 1080 bm.journal.cache[bridgeAddrs[2]].Subscribed = true 1081 1082 ps := sc.BridgePeerSet() 1083 ps.peers["test"] = nil 1084 1085 // Call RestoreBridges 1086 if err := bm.RestoreBridges(); err != nil { 1087 t.Fatal("bm restoring bridges failed") 1088 } 1089 1090 // Duplicated RestoreBridges 1091 if err := bm.RestoreBridges(); err != nil { 1092 t.Fatal("bm restoring bridges failed") 1093 } 1094 1095 // Case 1: check bridge contract creation. 1096 for i := 0; i < 4; i++ { 1097 info, _ := bm.GetBridgeInfo(bridgeAddrs[i]) 1098 assert.NotEqual(t, nil, info.bridge) 1099 } 1100 1101 // Case 2: check subscription 1102 for i := 0; i < 4; i++ { 1103 info, _ := bm.GetBridgeInfo(bridgeAddrs[i]) 1104 assert.Equal(t, true, info.subscribed) 1105 } 1106 1107 // Case 3: check recovery 1108 recovery1 := bm.recoveries[bridgeAddrs[0]] 1109 assert.NotEqual(t, nil, recovery1) 1110 recovery1.Start() 1111 assert.Equal(t, nil, recovery1.WaitRunningStatus(true, 5*time.Second)) 1112 recovery2 := bm.recoveries[bridgeAddrs[2]] 1113 assert.NotEqual(t, nil, recovery2) 1114 recovery2.Start() 1115 assert.Equal(t, nil, recovery2.WaitRunningStatus(true, 5*time.Second)) 1116 1117 bm.stopAllRecoveries() 1118 bm.Stop() 1119 } 1120 1121 // TestMethodGetAllBridge tests a method GetAllBridge. 1122 func TestMethodGetAllBridge(t *testing.T) { 1123 tempDir, err := ioutil.TempDir(os.TempDir(), "sc") 1124 assert.NoError(t, err) 1125 defer func() { 1126 if err := os.RemoveAll(tempDir); err != nil { 1127 t.Fatalf("fail to delete file %v", err) 1128 } 1129 }() 1130 1131 sc := &SubBridge{ 1132 config: &SCConfig{DataDir: tempDir, VTRecovery: true}, 1133 peers: newBridgePeerSet(), 1134 } 1135 bm, err := NewBridgeManager(sc) 1136 if err != nil { 1137 t.Fatalf("fail to create bridge manager %v", err) 1138 } 1139 1140 testBridge1 := common.BytesToAddress([]byte("test1")) 1141 testBridge2 := common.BytesToAddress([]byte("test2")) 1142 1143 bm.journal.insert("", testBridge1, testBridge2) 1144 bm.journal.insert("", testBridge2, testBridge1) 1145 1146 bridges := bm.GetAllBridge() 1147 assert.Equal(t, 2, len(bridges)) 1148 1149 bm.Stop() 1150 } 1151 1152 // TestErrorDuplication tests if duplication of journal insertion is ignored or not. 1153 func TestErrorDuplication(t *testing.T) { 1154 tempDir, err := ioutil.TempDir(os.TempDir(), "sc") 1155 assert.NoError(t, err) 1156 defer func() { 1157 if err := os.RemoveAll(tempDir); err != nil { 1158 t.Fatalf("fail to delete file %v", err) 1159 } 1160 }() 1161 1162 sc := &SubBridge{ 1163 config: &SCConfig{DataDir: tempDir, VTRecovery: true}, 1164 peers: newBridgePeerSet(), 1165 } 1166 bm, err := NewBridgeManager(sc) 1167 if err != nil { 1168 t.Fatalf("fail to create bridge manager %v", err) 1169 } 1170 1171 localAddr := common.BytesToAddress([]byte("test1")) 1172 remoteAddr := common.BytesToAddress([]byte("test2")) 1173 1174 err = bm.journal.insert("", localAddr, remoteAddr) 1175 assert.Equal(t, nil, err) 1176 err = bm.journal.insert("", remoteAddr, localAddr) 1177 assert.Equal(t, nil, err) 1178 1179 // try duplicated insert. 1180 err = bm.journal.insert("", localAddr, remoteAddr) 1181 assert.NotEqual(t, nil, err) 1182 err = bm.journal.insert("", remoteAddr, localAddr) 1183 assert.NotEqual(t, nil, err) 1184 1185 // check cache size for checking duplication 1186 bridges := bm.GetAllBridge() 1187 assert.Equal(t, 2, len(bridges)) 1188 1189 bm.Stop() 1190 } 1191 1192 // TestMethodSetJournal tests if duplication of journal insertion is ignored or not. 1193 func TestMethodSetJournal(t *testing.T) { 1194 tempDir, err := ioutil.TempDir(os.TempDir(), "sc") 1195 assert.NoError(t, err) 1196 defer func() { 1197 if err := os.RemoveAll(tempDir); err != nil { 1198 t.Fatalf("fail to delete file %v", err) 1199 } 1200 }() 1201 1202 sc := &SubBridge{ 1203 config: &SCConfig{DataDir: tempDir, VTRecovery: true}, 1204 peers: newBridgePeerSet(), 1205 } 1206 bm, err := NewBridgeManager(sc) 1207 if err != nil { 1208 t.Fatalf("fail to create bridge manager %v", err) 1209 } 1210 1211 localAddr := common.BytesToAddress([]byte("test1")) 1212 remoteAddr := common.BytesToAddress([]byte("test2")) 1213 1214 // Simple insert case 1215 err = bm.SetJournal("", localAddr, remoteAddr) 1216 assert.Equal(t, nil, err) 1217 1218 // Error case 1219 err = bm.SetJournal("", localAddr, remoteAddr) 1220 assert.NotEqual(t, nil, err) 1221 1222 // Check the number of bridge elements for checking duplication 1223 bridges := bm.GetAllBridge() 1224 assert.Equal(t, 1, len(bridges)) 1225 1226 bm.Stop() 1227 } 1228 1229 // TestErrorDuplicatedSetBridgeInfo tests if duplication of bridge info insertion. 1230 func TestErrorDuplicatedSetBridgeInfo(t *testing.T) { 1231 tempDir, err := ioutil.TempDir(os.TempDir(), "sc") 1232 assert.NoError(t, err) 1233 defer func() { 1234 if err := os.RemoveAll(tempDir); err != nil { 1235 t.Fatalf("fail to delete file %v", err) 1236 } 1237 }() 1238 1239 wg := sync.WaitGroup{} 1240 wg.Add(2) 1241 1242 // Generate a new random account and a funded simulator 1243 key, _ := crypto.GenerateKey() 1244 auth := bind.NewKeyedTransactor(key) 1245 1246 key2, _ := crypto.GenerateKey() 1247 auth2 := bind.NewKeyedTransactor(key2) 1248 1249 key4, _ := crypto.GenerateKey() 1250 auth4 := bind.NewKeyedTransactor(key4) 1251 config := &SCConfig{} 1252 config.DataDir = tempDir 1253 config.VTRecovery = true 1254 1255 bacc, _ := NewBridgeAccounts(nil, tempDir, database.NewDBManager(&database.DBConfig{DBType: database.MemoryDB}), DefaultBridgeTxGasLimit, DefaultBridgeTxGasLimit) 1256 bacc.pAccount.chainID = big.NewInt(0) 1257 bacc.cAccount.chainID = big.NewInt(0) 1258 1259 alloc := blockchain.GenesisAlloc{ 1260 auth.From: {Balance: big.NewInt(params.KLAY)}, 1261 auth2.From: {Balance: big.NewInt(params.KLAY)}, 1262 auth4.From: {Balance: big.NewInt(params.KLAY)}, 1263 bacc.pAccount.address: {Balance: big.NewInt(params.KLAY)}, 1264 bacc.cAccount.address: {Balance: big.NewInt(params.KLAY)}, 1265 } 1266 sim := backends.NewSimulatedBackend(alloc) 1267 defer sim.Close() 1268 1269 sc := &SubBridge{ 1270 config: config, 1271 peers: newBridgePeerSet(), 1272 localBackend: sim, 1273 remoteBackend: sim, 1274 bridgeAccounts: bacc, 1275 } 1276 1277 sc.handler, err = NewSubBridgeHandler(sc) 1278 if err != nil { 1279 log.Fatalf("Failed to initialize bridgeHandler : %v", err) 1280 return 1281 } 1282 1283 // Prepare manager 1284 bm, err := NewBridgeManager(sc) 1285 assert.NoError(t, err) 1286 addr, err := bm.DeployBridgeTest(sim, 10000, false) 1287 assert.NoError(t, err) 1288 bridgeInfo, _ := bm.GetBridgeInfo(addr) 1289 1290 // Try to call duplicated SetBridgeInfo 1291 err = bm.SetBridgeInfo(addr, bridgeInfo.bridge, common.Address{}, nil, sc.bridgeAccounts.pAccount, false, false) 1292 assert.NotEqual(t, nil, err) 1293 bm.Stop() 1294 } 1295 1296 // TestScenarioSubUnsub tests subscription and unsubscription scenario. 1297 func TestScenarioSubUnsub(t *testing.T) { 1298 tempDir, err := ioutil.TempDir(os.TempDir(), "sc") 1299 assert.NoError(t, err) 1300 defer func() { 1301 if err := os.RemoveAll(tempDir); err != nil { 1302 t.Fatalf("fail to delete file %v", err) 1303 } 1304 }() 1305 1306 wg := sync.WaitGroup{} 1307 wg.Add(2) 1308 1309 // Generate a new random account and a funded simulator 1310 key, _ := crypto.GenerateKey() 1311 auth := bind.NewKeyedTransactor(key) 1312 1313 key2, _ := crypto.GenerateKey() 1314 auth2 := bind.NewKeyedTransactor(key2) 1315 1316 key4, _ := crypto.GenerateKey() 1317 auth4 := bind.NewKeyedTransactor(key4) 1318 config := &SCConfig{} 1319 config.DataDir = tempDir 1320 config.VTRecovery = true 1321 1322 bacc, _ := NewBridgeAccounts(nil, tempDir, database.NewDBManager(&database.DBConfig{DBType: database.MemoryDB}), DefaultBridgeTxGasLimit, DefaultBridgeTxGasLimit) 1323 bacc.pAccount.chainID = big.NewInt(0) 1324 bacc.cAccount.chainID = big.NewInt(0) 1325 1326 alloc := blockchain.GenesisAlloc{ 1327 auth.From: {Balance: big.NewInt(params.KLAY)}, 1328 auth2.From: {Balance: big.NewInt(params.KLAY)}, 1329 auth4.From: {Balance: big.NewInt(params.KLAY)}, 1330 bacc.pAccount.address: {Balance: big.NewInt(params.KLAY)}, 1331 bacc.cAccount.address: {Balance: big.NewInt(params.KLAY)}, 1332 } 1333 sim := backends.NewSimulatedBackend(alloc) 1334 defer sim.Close() 1335 1336 sc := &SubBridge{ 1337 config: config, 1338 peers: newBridgePeerSet(), 1339 localBackend: sim, 1340 remoteBackend: sim, 1341 bridgeAccounts: bacc, 1342 } 1343 1344 sc.handler, err = NewSubBridgeHandler(sc) 1345 if err != nil { 1346 log.Fatalf("Failed to initialize bridgeHandler : %v", err) 1347 return 1348 } 1349 1350 // Prepare manager and deploy bridge contract. 1351 bm, err := NewBridgeManager(sc) 1352 assert.NoError(t, err) 1353 1354 localAddr, err := bm.DeployBridgeTest(sim, 10000, true) 1355 if err != nil { 1356 t.Fatal("deploy bridge test failed", localAddr) 1357 } 1358 1359 bm.SubscribeEvent(localAddr) 1360 bridgeInfo, ok := bm.GetBridgeInfo(localAddr) 1361 assert.Equal(t, true, ok) 1362 assert.Equal(t, true, bridgeInfo.subscribed) 1363 bm.UnsubscribeEvent(localAddr) 1364 assert.Equal(t, false, bridgeInfo.subscribed) 1365 1366 // Journal is irrelevant to the bridge unsubscription. 1367 journal := bm.journal.cache[localAddr] 1368 assert.NotEqual(t, nil, journal) 1369 } 1370 1371 // TestErrorEmptyAccount tests empty account error in case of journal insertion. 1372 func TestErrorEmptyAccount(t *testing.T) { 1373 tempDir, err := ioutil.TempDir(os.TempDir(), "sc") 1374 assert.NoError(t, err) 1375 defer func() { 1376 if err := os.RemoveAll(tempDir); err != nil { 1377 t.Fatalf("fail to delete file %v", err) 1378 } 1379 }() 1380 1381 sc := &SubBridge{ 1382 config: &SCConfig{DataDir: tempDir, VTRecovery: true}, 1383 peers: newBridgePeerSet(), 1384 } 1385 bm, err := NewBridgeManager(sc) 1386 if err != nil { 1387 t.Fatalf("fail to create bridge manager %v", err) 1388 } 1389 1390 localAddr := common.BytesToAddress([]byte("test1")) 1391 remoteAddr := common.BytesToAddress([]byte("test2")) 1392 1393 err = bm.journal.insert("", localAddr, common.Address{}) 1394 assert.NotEqual(t, nil, err) 1395 1396 err = bm.journal.insert("", common.Address{}, remoteAddr) 1397 assert.NotEqual(t, nil, err) 1398 1399 bm.Stop() 1400 } 1401 1402 // TestErrorDupSubscription tests duplicated subscription error. 1403 func TestErrorDupSubscription(t *testing.T) { 1404 tempDir, err := ioutil.TempDir(os.TempDir(), "sc") 1405 assert.NoError(t, err) 1406 defer func() { 1407 if err := os.RemoveAll(tempDir); err != nil { 1408 t.Fatalf("fail to delete file %v", err) 1409 } 1410 }() 1411 1412 wg := sync.WaitGroup{} 1413 wg.Add(2) 1414 1415 // Generate a new random account and a funded simulator 1416 key, _ := crypto.GenerateKey() 1417 auth := bind.NewKeyedTransactor(key) 1418 1419 key2, _ := crypto.GenerateKey() 1420 auth2 := bind.NewKeyedTransactor(key2) 1421 1422 key4, _ := crypto.GenerateKey() 1423 auth4 := bind.NewKeyedTransactor(key4) 1424 config := &SCConfig{} 1425 config.DataDir = tempDir 1426 config.VTRecovery = true 1427 1428 bacc, _ := NewBridgeAccounts(nil, tempDir, database.NewDBManager(&database.DBConfig{DBType: database.MemoryDB}), DefaultBridgeTxGasLimit, DefaultBridgeTxGasLimit) 1429 bacc.pAccount.chainID = big.NewInt(0) 1430 bacc.cAccount.chainID = big.NewInt(0) 1431 1432 alloc := blockchain.GenesisAlloc{ 1433 auth.From: {Balance: big.NewInt(params.KLAY)}, 1434 auth2.From: {Balance: big.NewInt(params.KLAY)}, 1435 auth4.From: {Balance: big.NewInt(params.KLAY)}, 1436 bacc.pAccount.address: {Balance: big.NewInt(params.KLAY)}, 1437 bacc.cAccount.address: {Balance: big.NewInt(params.KLAY)}, 1438 } 1439 sim := backends.NewSimulatedBackend(alloc) 1440 defer sim.Close() 1441 1442 sc := &SubBridge{ 1443 config: config, 1444 peers: newBridgePeerSet(), 1445 localBackend: sim, 1446 remoteBackend: sim, 1447 bridgeAccounts: bacc, 1448 } 1449 1450 sc.handler, err = NewSubBridgeHandler(sc) 1451 if err != nil { 1452 log.Fatalf("Failed to initialize bridgeHandler : %v", err) 1453 return 1454 } 1455 1456 // 1. Prepare manager and subscribe event 1457 bm, err := NewBridgeManager(sc) 1458 assert.NoError(t, err) 1459 1460 addr, err := bm.DeployBridgeTest(sim, 10000, false) 1461 bridgeInfo, _ := bm.GetBridgeInfo(addr) 1462 bridge := bridgeInfo.bridge 1463 t.Log("===== BridgeContract Addr ", addr.Hex()) 1464 sim.Commit() // block 1465 1466 bm.bridges[addr], err = NewBridgeInfo(sc, addr, bridge, common.Address{}, nil, bacc.cAccount, true, true, sim) 1467 1468 bm.journal.cache[addr] = &BridgeJournal{"", addr, addr, true, false} 1469 1470 bm.SubscribeEvent(addr) 1471 err = bm.SubscribeEvent(addr) 1472 assert.NotEqual(t, nil, err) 1473 1474 bm.Stop() 1475 } 1476 1477 // TestAnchoringBasic tests the following: 1478 // 1. generate anchoring tx 1479 // 2. decode anchoring tx 1480 // 3. start anchoring from the current block 1481 // 4. accumulated tx counts 1482 func TestAnchoringBasic(t *testing.T) { 1483 tempDir, err := ioutil.TempDir(os.TempDir(), "anchoring") 1484 assert.NoError(t, err) 1485 defer func() { 1486 if err := os.RemoveAll(tempDir); err != nil { 1487 t.Fatalf("fail to delete file %v", err) 1488 } 1489 }() 1490 1491 sim, sc, bAcc, _, _, _ := generateAnchoringEnv(t, tempDir) 1492 defer sim.Close() 1493 1494 assert.Equal(t, uint64(0), sc.handler.txCountStartingBlockNumber) 1495 assert.Equal(t, uint64(0), sc.handler.latestTxCountAddedBlockNumber) 1496 assert.Equal(t, uint64(1), sc.handler.chainTxPeriod) 1497 1498 auth := bAcc.pAccount.GenerateTransactOpts() 1499 _, _, _, err = bridge.DeployBridge(auth, sim, true) // dummy tx 1500 sim.Commit() 1501 curBlk := sim.BlockChain().CurrentBlock() 1502 1503 // nil block 1504 { 1505 err := sc.handler.blockAnchoringManager(nil) 1506 assert.Error(t, ErrInvalidBlock, err) 1507 } 1508 1509 { 1510 err := sc.handler.generateAndAddAnchoringTxIntoTxPool(nil) 1511 assert.Error(t, ErrInvalidBlock, err) 1512 } 1513 // Generate anchoring tx again for the curBlk. 1514 err = sc.handler.blockAnchoringManager(curBlk) 1515 assert.NoError(t, err) 1516 1517 pending := sc.GetBridgeTxPool().Pending() 1518 assert.Equal(t, 1, len(pending)) 1519 var tx *types.Transaction 1520 for _, v := range pending { 1521 assert.Equal(t, 1, len(v)) 1522 tx = v[0] 1523 } 1524 assert.Equal(t, uint64(0), sc.handler.txCount) 1525 1526 assert.Equal(t, curBlk.NumberU64(), sc.handler.latestTxCountAddedBlockNumber) 1527 compareBlockAndAnchoringTx(t, curBlk, tx) 1528 } 1529 1530 // TestAnchoringBasicWithFeePayer tests the following with feePayer: 1531 // 1. generate anchoring tx 1532 // 2. decode anchoring tx 1533 // 3. start anchoring from the current block 1534 // 4. accumulated tx counts 1535 func TestAnchoringBasicWithFeePayer(t *testing.T) { 1536 tempDir, err := ioutil.TempDir(os.TempDir(), "anchoring") 1537 assert.NoError(t, err) 1538 defer func() { 1539 if err := os.RemoveAll(tempDir); err != nil { 1540 t.Fatalf("fail to delete file %v", err) 1541 } 1542 }() 1543 1544 sim, sc, bAcc, parentOperator, feePayer, tester := generateAnchoringEnv(t, tempDir) 1545 defer sim.Close() 1546 1547 invalidAccount := common.HexToAddress("0x1") 1548 bAcc.SetParentOperatorFeePayer(feePayer.Address) 1549 1550 assert.Equal(t, uint64(0), sc.handler.txCountStartingBlockNumber) 1551 assert.Equal(t, uint64(0), sc.handler.latestTxCountAddedBlockNumber) 1552 assert.Equal(t, uint64(1), sc.handler.chainTxPeriod) 1553 1554 // fail to generate anchoring tx with invalid parent operator 1555 { 1556 pAccBackup := bAcc.pAccount.address 1557 bAcc.pAccount.address = invalidAccount 1558 1559 curBlk := sim.BlockChain().CurrentBlock() 1560 err = sc.handler.generateAndAddAnchoringTxIntoTxPool(curBlk) 1561 assert.Error(t, err, accounts.ErrUnknownAccount) 1562 1563 bAcc.pAccount.address = pAccBackup 1564 } 1565 1566 // fail to generate anchoring tx with invalid feePayer 1567 { 1568 bAcc.SetParentOperatorFeePayer(invalidAccount) 1569 1570 curBlk := sim.BlockChain().CurrentBlock() 1571 err = sc.handler.generateAndAddAnchoringTxIntoTxPool(curBlk) 1572 assert.Error(t, err, accounts.ErrUnknownAccount) 1573 1574 bAcc.SetParentOperatorFeePayer(feePayer.Address) 1575 } 1576 1577 _, _, _, err = bridge.DeployBridge(tester, sim, true) // dummy tx 1578 sim.Commit() 1579 curBlk := sim.BlockChain().CurrentBlock() 1580 1581 // Generate anchoring tx again for the curBlk. 1582 sc.handler.blockAnchoringManager(curBlk) 1583 pending := sc.GetBridgeTxPool().Pending() 1584 assert.Equal(t, 1, len(pending)) 1585 var tx *types.Transaction 1586 for _, v := range pending { 1587 assert.Equal(t, 1, len(v)) 1588 tx = v[0] 1589 1590 // Check Balance 1591 feePayerBalanceBefore, err := sim.BalanceAt(context.Background(), feePayer.Address, nil) 1592 assert.NoError(t, err) 1593 parentOperatorBalanceBefore, err := sim.BalanceAt(context.Background(), parentOperator.address, nil) 1594 assert.NoError(t, err) 1595 1596 sim.SendTransaction(context.Background(), tx) 1597 sim.Commit() 1598 1599 // Check Balance 1600 feePayerBalanceAfter, err := sim.BalanceAt(context.Background(), feePayer.Address, nil) 1601 assert.NoError(t, err) 1602 parentOperatorBalanceAfter, err := sim.BalanceAt(context.Background(), parentOperator.address, nil) 1603 assert.NoError(t, err) 1604 1605 receipt, err := sim.TransactionReceipt(context.Background(), tx.Hash()) 1606 assert.NoError(t, err) 1607 1608 fee := new(big.Int).SetUint64(receipt.GasUsed * params.DefaultUnitPrice) 1609 1610 assert.Equal(t, new(big.Int).Sub(feePayerBalanceBefore, fee).String(), feePayerBalanceAfter.String()) 1611 t.Log("feePayer paid ", fee) 1612 assert.Equal(t, parentOperatorBalanceBefore, parentOperatorBalanceAfter) 1613 } 1614 1615 assert.Equal(t, uint64(0), sc.handler.txCount) 1616 assert.Equal(t, curBlk.NumberU64(), sc.handler.latestTxCountAddedBlockNumber) 1617 compareBlockAndAnchoringTx(t, curBlk, tx) 1618 } 1619 1620 // TestAnchoringBasicWithBridgeTxPoolMock tests the following : 1621 // - BridgeTxPool addLocal() fail case. 1622 func TestAnchoringBasicWithBridgeTxPoolMock(t *testing.T) { 1623 tempDir, err := ioutil.TempDir(os.TempDir(), "anchoring") 1624 assert.NoError(t, err) 1625 defer func() { 1626 if err := os.RemoveAll(tempDir); err != nil { 1627 t.Fatalf("fail to delete file %v", err) 1628 } 1629 }() 1630 1631 sim, sc, bAcc, _, feePayer, _ := generateAnchoringEnv(t, tempDir) 1632 defer sim.Close() 1633 1634 // mock BridgeTxPool 1635 { 1636 mockCtrl := gomock.NewController(t) 1637 defer mockCtrl.Finish() 1638 mockBridgeTxPool := NewMockBridgeTxPool(mockCtrl) 1639 sc.bridgeTxPool = mockBridgeTxPool 1640 mockBridgeTxPool.EXPECT().AddLocal(gomock.Any()).Return(bridgepool.ErrKnownTx) 1641 } 1642 1643 bAcc.SetParentOperatorFeePayer(feePayer.Address) 1644 1645 assert.Equal(t, uint64(0), sc.handler.txCountStartingBlockNumber) 1646 assert.Equal(t, uint64(0), sc.handler.latestTxCountAddedBlockNumber) 1647 assert.Equal(t, uint64(1), sc.handler.chainTxPeriod) 1648 1649 curBlk := sim.BlockChain().CurrentBlock() 1650 1651 // Generate anchoring tx with mocked BridgeTxPool returns a error 1652 err = sc.handler.blockAnchoringManager(curBlk) 1653 assert.Equal(t, bridgepool.ErrKnownTx, err) 1654 } 1655 1656 func generateAnchoringEnv(t *testing.T, tempDir string) (*backends.SimulatedBackend, *SubBridge, *BridgeAccounts, *accountInfo, accounts.Account, *bind.TransactOpts) { 1657 config := &SCConfig{AnchoringPeriod: 1} 1658 config.DataDir = tempDir 1659 config.VTRecovery = true 1660 1661 ks := keystore.NewKeyStore(tempDir, keystore.StandardScryptN, keystore.StandardScryptP) 1662 back := []accounts.Backend{ 1663 ks, 1664 } 1665 am := accounts.NewManager(back...) 1666 bAcc, _ := NewBridgeAccounts(am, tempDir, database.NewDBManager(&database.DBConfig{DBType: database.MemoryDB}), DefaultBridgeTxGasLimit, DefaultBridgeTxGasLimit) 1667 bAcc.pAccount.chainID = big.NewInt(0) 1668 bAcc.cAccount.chainID = big.NewInt(0) 1669 parentOperator := bAcc.pAccount 1670 1671 aliceKey, _ := crypto.GenerateKey() 1672 alice := bind.NewKeyedTransactor(aliceKey) 1673 1674 initBal := new(big.Int).Exp(big.NewInt(10), big.NewInt(50), nil) 1675 1676 feePayer, err := ks.NewAccount("pwd") 1677 assert.NoError(t, err) 1678 ks.TimedUnlock(feePayer, "pwd", 0) 1679 1680 alloc := blockchain.GenesisAlloc{ 1681 alice.From: {Balance: initBal}, 1682 feePayer.Address: {Balance: initBal}, 1683 parentOperator.address: {Balance: initBal}, 1684 } 1685 sim := backends.NewSimulatedBackendWithGasPrice(alloc, params.DefaultUnitPrice) 1686 1687 sc := &SubBridge{ 1688 config: config, 1689 peers: newBridgePeerSet(), 1690 localBackend: sim, 1691 remoteBackend: sim, 1692 bridgeAccounts: bAcc, 1693 } 1694 sc.blockchain = sim.BlockChain() 1695 1696 sc.handler, err = NewSubBridgeHandler(sc) 1697 if err != nil { 1698 log.Fatalf("Failed to initialize bridgeHandler : %v", err) 1699 } 1700 1701 sc.handler.setRemoteGasPrice(params.DefaultUnitPrice) 1702 1703 sc.bridgeTxPool = bridgepool.NewBridgeTxPool(bridgepool.BridgeTxPoolConfig{ 1704 Journal: path.Join(tempDir, "bridge_transactions.rlp"), 1705 GlobalQueue: 1024, 1706 }) 1707 1708 return sim, sc, bAcc, parentOperator, feePayer, alice 1709 } 1710 1711 func compareBlockAndAnchoringTx(t *testing.T, block *types.Block, tx *types.Transaction) { 1712 // Decoding the anchoring tx. 1713 assert.Equal(t, true, tx.Type().IsChainDataAnchoring()) 1714 anchoringData := new(types.AnchoringData) 1715 data, err := tx.AnchoredData() 1716 assert.NoError(t, err) 1717 1718 err = rlp.DecodeBytes(data, anchoringData) 1719 assert.NoError(t, err) 1720 assert.Equal(t, types.AnchoringDataType0, anchoringData.Type) 1721 anchoringDataInternal := new(types.AnchoringDataInternalType0) 1722 if err := rlp.DecodeBytes(anchoringData.Data, anchoringDataInternal); err != nil { 1723 logger.Error("writeChildChainTxHashFromBlock : failed to decode anchoring data") 1724 } 1725 1726 // Check the current block is anchored. 1727 assert.Equal(t, new(big.Int).SetUint64(block.NumberU64()).String(), anchoringDataInternal.BlockNumber.String()) 1728 assert.Equal(t, block.Hash(), anchoringDataInternal.BlockHash) 1729 assert.Equal(t, big.NewInt(1).String(), anchoringDataInternal.BlockCount.String()) 1730 assert.Equal(t, big.NewInt(1).String(), anchoringDataInternal.TxCount.String()) 1731 } 1732 1733 // TestAnchoringStart tests the following: 1734 // 1. set anchoring period 4 1735 // 2. check if tx counting started immediately and accumulated correctly 1736 func TestAnchoringStart(t *testing.T) { 1737 tempDir, err := ioutil.TempDir(os.TempDir(), "anchoringPeriod") 1738 assert.NoError(t, err) 1739 defer func() { 1740 if err := os.RemoveAll(tempDir); err != nil { 1741 t.Fatalf("fail to delete file %v", err) 1742 } 1743 }() 1744 1745 config := &SCConfig{AnchoringPeriod: 4} 1746 config.DataDir = tempDir 1747 config.VTRecovery = true 1748 1749 bAcc, _ := NewBridgeAccounts(nil, tempDir, database.NewDBManager(&database.DBConfig{DBType: database.MemoryDB}), DefaultBridgeTxGasLimit, DefaultBridgeTxGasLimit) 1750 bAcc.pAccount.chainID = big.NewInt(0) 1751 bAcc.cAccount.chainID = big.NewInt(0) 1752 1753 alloc := blockchain.GenesisAlloc{} 1754 sim := backends.NewSimulatedBackend(alloc) 1755 defer sim.Close() 1756 1757 sc := &SubBridge{ 1758 config: config, 1759 peers: newBridgePeerSet(), 1760 localBackend: sim, 1761 remoteBackend: sim, 1762 bridgeAccounts: bAcc, 1763 } 1764 sc.blockchain = sim.BlockChain() 1765 1766 sc.handler, err = NewSubBridgeHandler(sc) 1767 if err != nil { 1768 log.Fatalf("Failed to initialize bridgeHandler : %v", err) 1769 return 1770 } 1771 sc.bridgeTxPool = bridgepool.NewBridgeTxPool(bridgepool.BridgeTxPoolConfig{ 1772 Journal: path.Join(tempDir, "bridge_transactions.rlp"), 1773 GlobalQueue: 1024, 1774 }) 1775 1776 assert.Equal(t, uint64(0), sc.handler.txCountStartingBlockNumber) 1777 assert.Equal(t, uint64(4), sc.handler.chainTxPeriod) 1778 1779 sim.Commit() // start with arbitrary block number. 1780 1781 // 1. Fresh start with dummy tx and check tx count 1782 auth := bAcc.pAccount.GenerateTransactOpts() 1783 _, _, _, err = bridge.DeployBridge(auth, sim, true) // dummy tx 1784 sim.Commit() 1785 curBlk := sim.BlockChain().CurrentBlock() 1786 sc.handler.blockAnchoringManager(curBlk) 1787 assert.Equal(t, uint64(1), sc.handler.txCount) 1788 pending := sc.GetBridgeTxPool().Pending() 1789 assert.Equal(t, 0, len(pending)) // the anchoring period has not yet been reached. 1790 1791 // 2. Generate dummy txs and check tx count 1792 _, _, _, err = bridge.DeployBridge(auth, sim, true) // dummy tx 1793 _, _, _, err = bridge.DeployBridge(auth, sim, true) // dummy tx 1794 sim.Commit() 1795 curBlk = sim.BlockChain().CurrentBlock() 1796 sc.handler.blockAnchoringManager(curBlk) 1797 assert.Equal(t, uint64(3), sc.handler.txCount) 1798 assert.Equal(t, 0, len(pending)) // the anchoring period has not yet been reached. 1799 1800 // 3. Generate dummy blocks and check anchoring tx 1801 sim.Commit() // block number 4 1802 curBlk = sim.BlockChain().CurrentBlock() 1803 sc.handler.blockAnchoringManager(curBlk) 1804 assert.Equal(t, uint64(0), sc.handler.txCount) 1805 pending = sc.GetBridgeTxPool().Pending() 1806 assert.Equal(t, 1, len(pending)) 1807 for _, v := range pending { 1808 decodeAndCheckAnchoringTx(t, v[0], curBlk, 3, 3) 1809 break 1810 } 1811 } 1812 1813 // TestAnchoringPeriod tests the following: 1814 // 1. set anchoring period 4 1815 // 2. accumulate tx counts 1816 func TestAnchoringPeriod(t *testing.T) { 1817 const ( 1818 startTxCount = 100 1819 ) 1820 tempDir, err := ioutil.TempDir(os.TempDir(), "anchoringPeriod") 1821 assert.NoError(t, err) 1822 defer func() { 1823 if err := os.RemoveAll(tempDir); err != nil { 1824 t.Fatalf("fail to delete file %v", err) 1825 } 1826 }() 1827 1828 config := &SCConfig{AnchoringPeriod: 4} 1829 config.DataDir = tempDir 1830 config.VTRecovery = true 1831 1832 bAcc, _ := NewBridgeAccounts(nil, tempDir, database.NewDBManager(&database.DBConfig{DBType: database.MemoryDB}), DefaultBridgeTxGasLimit, DefaultBridgeTxGasLimit) 1833 bAcc.pAccount.chainID = big.NewInt(0) 1834 bAcc.cAccount.chainID = big.NewInt(0) 1835 1836 alloc := blockchain.GenesisAlloc{} 1837 sim := backends.NewSimulatedBackend(alloc) 1838 defer sim.Close() 1839 1840 sc := &SubBridge{ 1841 config: config, 1842 peers: newBridgePeerSet(), 1843 localBackend: sim, 1844 remoteBackend: sim, 1845 bridgeAccounts: bAcc, 1846 } 1847 sc.blockchain = sim.BlockChain() 1848 1849 sc.handler, err = NewSubBridgeHandler(sc) 1850 if err != nil { 1851 log.Fatalf("Failed to initialize bridgeHandler : %v", err) 1852 return 1853 } 1854 sc.bridgeTxPool = bridgepool.NewBridgeTxPool(bridgepool.BridgeTxPoolConfig{ 1855 Journal: path.Join(tempDir, "bridge_transactions.rlp"), 1856 GlobalQueue: 1024, 1857 }) 1858 1859 assert.Equal(t, uint64(0), sc.handler.txCountStartingBlockNumber) 1860 assert.Equal(t, uint64(4), sc.handler.chainTxPeriod) 1861 1862 // Period 1 1863 sim.Commit() 1864 auth := bAcc.pAccount.GenerateTransactOpts() 1865 _, _, _, err = bridge.DeployBridge(auth, sim, true) // dummy tx 1866 sim.Commit() 1867 curBlk := sim.BlockChain().CurrentBlock() 1868 1869 sc.handler.txCountStartingBlockNumber = curBlk.NumberU64() - 1 1870 sc.handler.txCount = startTxCount 1871 sc.handler.blockAnchoringManager(curBlk) 1872 assert.Equal(t, uint64(startTxCount+1), sc.handler.txCount) 1873 pending := sc.GetBridgeTxPool().Pending() 1874 assert.Equal(t, 0, len(pending)) // the anchoring period has not yet been reached. 1875 1876 // Generate anchoring tx for the curBlk. 1877 _, _, _, err = bridge.DeployBridge(auth, sim, true) // dummy tx 1878 sim.Commit() 1879 _, _, _, err = bridge.DeployBridge(auth, sim, true) // dummy tx 1880 _, _, _, err = bridge.DeployBridge(auth, sim, true) // dummy tx 1881 sim.Commit() 1882 curBlk = sim.BlockChain().CurrentBlock() 1883 sc.handler.blockAnchoringManager(curBlk) 1884 pending = sc.GetBridgeTxPool().Pending() 1885 assert.Equal(t, 1, len(pending)) 1886 1887 for _, v := range pending { 1888 decodeAndCheckAnchoringTx(t, v[0], curBlk, 4, startTxCount+4) 1889 break 1890 } 1891 1892 // Period 2: 1893 assert.Equal(t, uint64(0), sc.handler.txCount) 1894 assert.Equal(t, uint64(5), sc.handler.txCountStartingBlockNumber) 1895 1896 // Generate anchoring tx. 1897 _, _, _, err = bridge.DeployBridge(auth, sim, true) // dummy tx 1898 _, _, _, err = bridge.DeployBridge(auth, sim, true) // dummy tx 1899 sim.Commit() 1900 _, _, _, err = bridge.DeployBridge(auth, sim, true) // dummy tx 1901 sim.Commit() 1902 sim.Commit() 1903 sim.Commit() 1904 1905 curBlk = sim.BlockChain().CurrentBlock() 1906 sc.handler.blockAnchoringManager(curBlk) 1907 pending = sc.GetBridgeTxPool().Pending() 1908 for _, v := range pending { 1909 decodeAndCheckAnchoringTx(t, v[1], curBlk, 4, 3) 1910 break 1911 } 1912 } 1913 1914 // decodeAndCheckAnchoringTx decodes anchoring tx and check with a block. 1915 func decodeAndCheckAnchoringTx(t *testing.T, tx *types.Transaction, blk *types.Block, blockCount, txCounts int64) { 1916 assert.Equal(t, types.TxTypeChainDataAnchoring, tx.Type()) 1917 anchoringData := new(types.AnchoringData) 1918 data, err := tx.AnchoredData() 1919 assert.NoError(t, err) 1920 1921 err = rlp.DecodeBytes(data, anchoringData) 1922 assert.NoError(t, err) 1923 assert.Equal(t, types.AnchoringDataType0, anchoringData.Type) 1924 anchoringDataInternal := new(types.AnchoringDataInternalType0) 1925 if err := rlp.DecodeBytes(anchoringData.Data, anchoringDataInternal); err != nil { 1926 logger.Error("writeChildChainTxHashFromBlock : failed to decode anchoring data") 1927 } 1928 1929 // Check the current block is anchored. 1930 assert.Equal(t, new(big.Int).SetUint64(blk.NumberU64()).String(), anchoringDataInternal.BlockNumber.String()) 1931 assert.Equal(t, blk.Hash(), anchoringDataInternal.BlockHash) 1932 assert.Equal(t, big.NewInt(blockCount).String(), anchoringDataInternal.BlockCount.String()) 1933 assert.Equal(t, big.NewInt(txCounts).String(), anchoringDataInternal.TxCount.String()) 1934 } 1935 1936 // TestDecodingLegacyAnchoringTx tests the following: 1937 // 1. generate AnchoringDataLegacy anchoring tx 1938 // 2. decode AnchoringDataLegacy with a decoding method of a sub-bridge handler. 1939 func TestDecodingLegacyAnchoringTx(t *testing.T) { 1940 const ( 1941 startBlkNum = 10 1942 startTxCount = 100 1943 ) 1944 tempDir, err := ioutil.TempDir(os.TempDir(), "anchoring") 1945 assert.NoError(t, err) 1946 defer func() { 1947 if err := os.RemoveAll(tempDir); err != nil { 1948 t.Fatalf("fail to delete file %v", err) 1949 } 1950 }() 1951 1952 config := &SCConfig{AnchoringPeriod: 1} 1953 config.DataDir = tempDir 1954 config.VTRecovery = true 1955 1956 bAcc, _ := NewBridgeAccounts(nil, tempDir, database.NewDBManager(&database.DBConfig{DBType: database.MemoryDB}), DefaultBridgeTxGasLimit, DefaultBridgeTxGasLimit) 1957 bAcc.pAccount.chainID = big.NewInt(0) 1958 bAcc.cAccount.chainID = big.NewInt(0) 1959 1960 alloc := blockchain.GenesisAlloc{} 1961 sim := backends.NewSimulatedBackend(alloc) 1962 defer sim.Close() 1963 1964 sc := &SubBridge{ 1965 config: config, 1966 peers: newBridgePeerSet(), 1967 localBackend: sim, 1968 remoteBackend: sim, 1969 bridgeAccounts: bAcc, 1970 } 1971 sc.blockchain = sim.BlockChain() 1972 1973 sc.handler, err = NewSubBridgeHandler(sc) 1974 if err != nil { 1975 log.Fatalf("Failed to initialize bridgeHandler : %v", err) 1976 return 1977 } 1978 1979 // Encoding anchoring tx. 1980 auth := bAcc.pAccount.GenerateTransactOpts() 1981 _, _, _, err = bridge.DeployBridge(auth, sim, true) // dummy tx 1982 sim.Commit() 1983 curBlk := sim.BlockChain().CurrentBlock() 1984 1985 anchoringData := &types.AnchoringDataLegacy{ 1986 BlockHash: curBlk.Hash(), 1987 TxHash: curBlk.Header().TxHash, 1988 ParentHash: curBlk.Header().ParentHash, 1989 ReceiptHash: curBlk.Header().ReceiptHash, 1990 StateRootHash: curBlk.Header().Root, 1991 BlockNumber: curBlk.Header().Number, 1992 } 1993 data, err := rlp.EncodeToBytes(anchoringData) 1994 assert.NoError(t, err) 1995 1996 // Decoding the anchoring tx. 1997 decodedData, err := types.DecodeAnchoringData(data) 1998 assert.Equal(t, curBlk.Hash(), decodedData.GetBlockHash()) 1999 assert.Equal(t, curBlk.Header().Number.String(), decodedData.GetBlockNumber().String()) 2000 } 2001 2002 func TestBridgeAliasAPIs(t *testing.T) { 2003 tempDir, err := ioutil.TempDir(os.TempDir(), "sc") 2004 assert.NoError(t, err) 2005 defer func() { 2006 if err := os.RemoveAll(tempDir); err != nil { 2007 t.Fatalf("fail to delete file %v", err) 2008 } 2009 }() 2010 2011 // Generate a new random account and a funded simulator 2012 aliceKey, _ := crypto.GenerateKey() 2013 alice := bind.NewKeyedTransactor(aliceKey) 2014 bobKey, _ := crypto.GenerateKey() 2015 bob := bind.NewKeyedTransactor(bobKey) 2016 2017 config := &SCConfig{} 2018 config.DataDir = tempDir 2019 2020 bacc, _ := NewBridgeAccounts(nil, tempDir, database.NewDBManager(&database.DBConfig{DBType: database.MemoryDB}), DefaultBridgeTxGasLimit, DefaultBridgeTxGasLimit) 2021 bacc.pAccount.chainID = big.NewInt(0) 2022 bacc.cAccount.chainID = big.NewInt(0) 2023 2024 alloc := blockchain.GenesisAlloc{ 2025 alice.From: {Balance: big.NewInt(params.KLAY)}, 2026 bob.From: {Balance: big.NewInt(params.KLAY)}, 2027 bacc.pAccount.address: {Balance: big.NewInt(params.KLAY)}, 2028 bacc.cAccount.address: {Balance: big.NewInt(params.KLAY)}, 2029 } 2030 sim := backends.NewSimulatedBackend(alloc) 2031 defer sim.Close() 2032 2033 sc := &SubBridge{ 2034 config: config, 2035 peers: newBridgePeerSet(), 2036 localBackend: sim, 2037 remoteBackend: sim, 2038 bridgeAccounts: bacc, 2039 } 2040 2041 sc.APIBackend = &SubBridgeAPI{sc} 2042 sc.handler, err = NewSubBridgeHandler(sc) 2043 assert.NoError(t, err) 2044 2045 // Prepare manager and deploy bridge contract. 2046 bm, err := NewBridgeManager(sc) 2047 assert.NoError(t, err) 2048 sc.handler.subbridge.bridgeManager = bm 2049 2050 // 1. Deploy bridge contracts and register them 2051 cBridgeAddr := deployBridge(t, bm, sim, true) 2052 pBridgeAddr := deployBridge(t, bm, sim, false) 2053 2054 // 2. Deploy token Contracts 2055 cTokenAddr, _, _, err := sctoken.DeployServiceChainToken(alice, sim, cBridgeAddr) 2056 assert.NoError(t, err) 2057 pTokenAddr, _, _, err := sctoken.DeployServiceChainToken(alice, sim, pBridgeAddr) 2058 assert.NoError(t, err) 2059 sim.Commit() // block 2060 2061 cBridgeAddrStr := cBridgeAddr.String() 2062 pBridgeAddrStr := pBridgeAddr.String() 2063 cTokenAddrStr := cTokenAddr.String() 2064 pTokenAddrStr := pTokenAddr.String() 2065 // -------------------------- Done prepration -------------------------- 2066 2067 // -------------------------- API test with the raw addresss format -------------------------- 2068 { 2069 // TEST 1-1 - Success (Register bridge, tokens and subscribe registered bridges) 2070 bridgePairs := bm.subBridge.APIBackend.ListBridge() 2071 assert.Equal(t, len(bridgePairs), 0) 2072 2073 testBridgeAPIBasic(t, bm, cBridgeAddr, pBridgeAddr, nil, cTokenAddr, pTokenAddr) 2074 2075 bridgePairs = bm.subBridge.APIBackend.ListBridge() 2076 assert.Equal(t, len(bridgePairs), 1) 2077 assert.Equal(t, bridgePairs[0].Subscribed, true) 2078 } 2079 2080 { 2081 // TEST 1-2 - Failure 2082 // Duplicated journal 2083 testDuplicatedJournal(t, bm, cBridgeAddr, pBridgeAddr, nil) 2084 2085 // Duplicated token 2086 testDuplicatedToken(t, bm, &cBridgeAddrStr, &pBridgeAddrStr, &cTokenAddrStr, &pTokenAddrStr) 2087 2088 // Already subscribed 2089 testAlreadySubscribed(t, bm, &cBridgeAddrStr, &pBridgeAddrStr) 2090 } 2091 2092 { 2093 // TEST 1-3 - Success (Unsubscribe bridge, deregister bridges and tokens) 2094 testUnsubscribeAndDeRegister(t, bm, &cBridgeAddrStr, &pBridgeAddrStr, &cTokenAddrStr, &pTokenAddrStr) 2095 } 2096 2097 // -------------------------- API test with the bridge format -------------------------- 2098 alias := "MYBRIDGE" 2099 changedAlias := "MYBRIDGE_v2" 2100 invalidBridgeAlias := "0xMYBRIDGE" 2101 { 2102 // TEST 2-1 - Success (Register bridge, tokens and subscribe registered bridges) 2103 bridgePairs := bm.subBridge.APIBackend.ListBridge() 2104 assert.Equal(t, len(bridgePairs), 0) 2105 2106 testBridgeAPIBasic(t, bm, cBridgeAddr, pBridgeAddr, &alias, cTokenAddr, pTokenAddr) 2107 2108 bridgePairs = bm.subBridge.APIBackend.ListBridge() 2109 assert.Equal(t, len(bridgePairs), 1) 2110 assert.Equal(t, bridgePairs[0].Subscribed, true) 2111 bridgePair := bm.subBridge.APIBackend.GetBridgePairByAlias(alias) 2112 assert.Equal(t, bridgePair.BridgeAlias, alias) 2113 } 2114 2115 { 2116 // TEST 2-2 - Failure 2117 // Duplicated bridge alias 2118 testDuplicatedJournal(t, bm, cBridgeAddr, pBridgeAddr, &alias) 2119 2120 // Duplicated token 2121 testDuplicatedToken(t, bm, &alias, &cTokenAddrStr, &pTokenAddrStr, nil) 2122 2123 // Already subscribed 2124 testAlreadySubscribed(t, bm, &alias, nil) 2125 } 2126 2127 { 2128 // TEST 2-3 - Success (change bridge alias) 2129 err = bm.subBridge.APIBackend.ChangeBridgeAlias(alias, changedAlias) 2130 assert.NoError(t, err) 2131 2132 // Try to deregister with empty bridge alias 2133 err = bm.subBridge.APIBackend.DeregisterBridge(&alias, nil) 2134 assert.Equal(t, err, ErrEmptyBridgeAlias) 2135 2136 bridgePair := bm.subBridge.APIBackend.GetBridgePairByAlias(alias) 2137 assert.Nil(t, bridgePair) 2138 2139 bridgePair = bm.subBridge.APIBackend.GetBridgePairByAlias(changedAlias) 2140 assert.Equal(t, bridgePair.BridgeAlias, changedAlias) 2141 } 2142 2143 { 2144 // TEST 2-4 - Success (Unsubscribe bridge, deregister bridges and tokens) 2145 testUnsubscribeAndDeRegister(t, bm, &changedAlias, &cTokenAddrStr, &pTokenAddrStr, nil) 2146 2147 // TEST 2-5 - Failure (Unsubscribe register bridge already unsubscribed) 2148 err := bm.subBridge.APIBackend.UnsubscribeBridge(&changedAlias, nil) 2149 assert.Equal(t, err, ErrEmptyBridgeAlias) 2150 } 2151 2152 { 2153 // TEST 2-6 - Failure (Try to create a bridge alias with invalid bridge alias name) 2154 err = bm.subBridge.APIBackend.RegisterBridge(cBridgeAddr, pBridgeAddr, &invalidBridgeAlias) 2155 assert.Equal(t, err, ErrNotAllowedAliasFormat) 2156 } 2157 2158 { 2159 // TEST 3 - Concurrent API Call 2160 contractPairLen := 10 2161 bridgeAddrs := make([]common.Address, contractPairLen) 2162 tokenAddrs := make([]common.Address, contractPairLen) 2163 t.Logf("Prepare %d contracts\n", contractPairLen) 2164 // Preparation: Deploy bridge and token contracts 2165 for i := 0; i < contractPairLen/2; i++ { 2166 cBridgeAddr, pBridgeAddr = deployBridge(t, bm, sim, true), deployBridge(t, bm, sim, false) 2167 cIdx, pIdx := i*2, i*2+1 2168 bridgeAddrs[cIdx], bridgeAddrs[pIdx] = cBridgeAddr, pBridgeAddr 2169 2170 cTokenAddr, _, _, err := sctoken.DeployServiceChainToken(alice, sim, cBridgeAddr) 2171 assert.NoError(t, err) 2172 pTokenAddr, _, _, err := sctoken.DeployServiceChainToken(alice, sim, pBridgeAddr) 2173 assert.NoError(t, err) 2174 tokenAddrs[cIdx], tokenAddrs[pIdx] = cTokenAddr, pTokenAddr 2175 2176 t.Logf("Deployed bridge contracts %d, %d\n", cIdx, pIdx) 2177 } 2178 2179 // Declare another bridge and token contracts that did not initialize 2180 fixedChildBridgeAddr, fixedParentBridgeAddr := deployBridge(t, bm, sim, true), deployBridge(t, bm, sim, false) 2181 2182 const ( 2183 BRIDGE_SETUP = iota 2184 FAILURE 2185 CLEANUP_BRIDGE 2186 ALIAS_BRIDGE_SETUP 2187 ALIAS_FAILURE 2188 ALIAS_CLEANUP_BRIDGE 2189 REGISTER_MULTIPLE_TOKEN_WITH_SINGLE_BRIDGE 2190 ) 2191 // DO NOT CHANGE THE TEST ORDER 2192 testCases := map[uint8]string{ 2193 BRIDGE_SETUP: "BRIDGE_SETUP", 2194 FAILURE: "FAILURE", 2195 CLEANUP_BRIDGE: "CLEANUP_BRIDGE", 2196 ALIAS_BRIDGE_SETUP: "ALIAS_BRIDGE_SETUP", 2197 ALIAS_FAILURE: "ALIAS_FAILURE", 2198 ALIAS_CLEANUP_BRIDGE: "ALIAS_CLEANUP_BRIDGE", 2199 REGISTER_MULTIPLE_TOKEN_WITH_SINGLE_BRIDGE: "REGISTER_MULTIPLE_TOKEN_WITH_SINGLE_BRIDGE", 2200 } 2201 2202 for testNum := 0; testNum < len(testCases); testNum++ { 2203 wg := sync.WaitGroup{} 2204 wg.Add(contractPairLen / 2) 2205 for i := 0; i < len(bridgeAddrs); i += 2 { 2206 cIdx, pIdx := i, i+1 2207 go func(cIdx, pIdx int) { 2208 cBridgeAddr, pBridgeAddr := bridgeAddrs[cIdx], bridgeAddrs[pIdx] 2209 cBridgeAddrStr, pBridgeAddrStr := cBridgeAddr.String(), pBridgeAddr.String() 2210 cTokenAddr, pTokenAddr := tokenAddrs[cIdx], tokenAddrs[pIdx] 2211 cTokenAddrStr, pTokenAddrStr := cTokenAddr.String(), pTokenAddr.String() 2212 alias := "MYBRIDGE_v3" + strconv.Itoa(cIdx) 2213 2214 switch testNum { 2215 case BRIDGE_SETUP: 2216 // TEST 3-1. `testBridgeAPIBasic` again with concurrent calls using raw-address-format APIS 2217 testBridgeAPIBasic(t, bm, cBridgeAddr, pBridgeAddr, nil, cTokenAddr, pTokenAddr) 2218 t.Log("passed:", testCases[uint8(testNum)], cIdx, pIdx) 2219 case FAILURE: 2220 // TEST 3-2 - Failure 2221 testDuplicatedJournal(t, bm, cBridgeAddr, pBridgeAddr, nil) 2222 testDuplicatedToken(t, bm, &cBridgeAddrStr, &pBridgeAddrStr, &cTokenAddrStr, &pTokenAddrStr) 2223 testAlreadySubscribed(t, bm, &cBridgeAddrStr, &pBridgeAddrStr) 2224 t.Log("passed:", testCases[uint8(testNum)], cIdx, pIdx) 2225 case ALIAS_BRIDGE_SETUP: 2226 // TEST 3-3. `testBridgeAPIBasic` again with concurrent calls using alias APIS 2227 testBridgeAPIBasic(t, bm, cBridgeAddr, pBridgeAddr, &alias, cTokenAddr, pTokenAddr) 2228 t.Log("passed:", testCases[uint8(testNum)], cIdx, pIdx) 2229 case ALIAS_FAILURE: 2230 // TEST 3-4 - Failure 2231 testDuplicatedJournal(t, bm, cBridgeAddr, pBridgeAddr, &alias) 2232 testDuplicatedToken(t, bm, &alias, &cTokenAddrStr, &pTokenAddrStr, nil) 2233 testAlreadySubscribed(t, bm, &alias, nil) 2234 t.Log("passed:", testCases[uint8(testNum)], cIdx, pIdx) 2235 case CLEANUP_BRIDGE: 2236 // TEST 3-5 - Success (Unsubscribe bridge, deregister bridges and tokens) 2237 testUnsubscribeAndDeRegister(t, bm, &cBridgeAddrStr, &pBridgeAddrStr, &cTokenAddrStr, &pTokenAddrStr) 2238 t.Log("passed:", testCases[uint8(testNum)], cIdx, pIdx) 2239 case ALIAS_CLEANUP_BRIDGE: 2240 // TEST 3-6 - Success (Unsubscribe bridge, deregister bridges and tokens) 2241 testUnsubscribeAndDeRegister(t, bm, &alias, &cTokenAddrStr, &pTokenAddrStr, nil) 2242 t.Log("passed:", testCases[uint8(testNum)], cIdx, pIdx) 2243 case REGISTER_MULTIPLE_TOKEN_WITH_SINGLE_BRIDGE: 2244 // TEST 3-7 - Use the fresh bridge that did not register any token contracts 2245 cbAddr, pbAddr := fixedChildBridgeAddr.String(), fixedParentBridgeAddr.String() 2246 testRegisterToken(t, bm, &cbAddr, &pbAddr, &cTokenAddrStr, &pTokenAddrStr) 2247 t.Log("passed:", testCases[uint8(testNum)], cIdx, pIdx) 2248 } 2249 wg.Done() 2250 }(cIdx, pIdx) 2251 } 2252 wg.Wait() 2253 t.Log("Test Done: ", testCases[uint8(testNum)]) 2254 // Check the status of conccurent calls with a signle thread 2255 switch testNum { 2256 case BRIDGE_SETUP: 2257 checkBridgeSetup(t, bm, true, 1, contractPairLen/2) 2258 case CLEANUP_BRIDGE: 2259 checkBridgeSetup(t, bm, false, 0, 0) 2260 case ALIAS_BRIDGE_SETUP: 2261 checkBridgeSetup(t, bm, true, 1, contractPairLen/2) 2262 case ALIAS_CLEANUP_BRIDGE: 2263 checkBridgeSetup(t, bm, false, 0, 0) 2264 // Initiailize another two bridge contracts for the test `REGISTER_MULTIPLE_TOKEN_WITH_SINGLE_BRIDGE` 2265 err = bm.subBridge.APIBackend.RegisterBridge(fixedChildBridgeAddr, fixedParentBridgeAddr, nil) 2266 assert.NoError(t, err) 2267 case REGISTER_MULTIPLE_TOKEN_WITH_SINGLE_BRIDGE: 2268 checkRegisterMultipleToken(t, bm, fixedChildBridgeAddr, fixedParentBridgeAddr, contractPairLen/2) 2269 } 2270 } 2271 t.Log("All Done") 2272 } 2273 } 2274 2275 func testBridgeAPIBasic(t *testing.T, bm *BridgeManager, 2276 cBridgeAddr, pBridgeAddr common.Address, 2277 alias *string, 2278 cTokenAddr, pTokenAddr common.Address, 2279 ) { 2280 // TEST 1 - Success (Register bridge, tokens and subscribe registered bridges) 2281 cBridgeAddrStr := cBridgeAddr.String() 2282 pBridgeAddrStr := pBridgeAddr.String() 2283 cTokenAddrStr := cTokenAddr.String() 2284 pTokenAddrStr := pTokenAddr.String() 2285 2286 // Register Bridge 2287 err := bm.subBridge.APIBackend.RegisterBridge(cBridgeAddr, pBridgeAddr, alias) 2288 assert.NoError(t, err) 2289 2290 // Register tokens 2291 if alias != nil { 2292 err = bm.subBridge.APIBackend.RegisterToken(alias, &cTokenAddrStr, &pTokenAddrStr, nil) 2293 } else { 2294 err = bm.subBridge.APIBackend.RegisterToken(&cBridgeAddrStr, &pBridgeAddrStr, &cTokenAddrStr, &pTokenAddrStr) 2295 } 2296 assert.NoError(t, err) 2297 2298 // Subscribe bridges 2299 if alias != nil { 2300 err = bm.subBridge.APIBackend.SubscribeBridge(alias, nil) 2301 } else { 2302 err = bm.subBridge.APIBackend.SubscribeBridge(&cBridgeAddrStr, &pBridgeAddrStr) 2303 } 2304 assert.NoError(t, err) 2305 } 2306 2307 func testDuplicatedJournal(t *testing.T, bm *BridgeManager, cBridgeAddr, pBridgeAddr common.Address, alias *string) { 2308 err := bm.subBridge.APIBackend.RegisterBridge(cBridgeAddr, pBridgeAddr, alias) 2309 if err != ErrDuplicatedJournal && err != ErrDuplicatedAlias { 2310 t.Fatal("Unexpected error", err) 2311 } 2312 } 2313 2314 func testDuplicatedToken(t *testing.T, bm *BridgeManager, cBridgeAddrStr, pBridgeAddrStr, cTokenAddrStr, pTokenAddrStr *string) { 2315 err := bm.subBridge.APIBackend.RegisterToken(cBridgeAddrStr, pBridgeAddrStr, cTokenAddrStr, pTokenAddrStr) 2316 assert.Equal(t, err, ErrDuplicatedToken) 2317 } 2318 2319 func testAlreadySubscribed(t *testing.T, bm *BridgeManager, cBridgeAddrStr, pBridgeAddrStr *string) { 2320 err := bm.subBridge.APIBackend.SubscribeBridge(cBridgeAddrStr, pBridgeAddrStr) 2321 assert.Equal(t, err, ErrAlreadySubscribed) 2322 } 2323 2324 func testRegisterToken(t *testing.T, bm *BridgeManager, cBridgeAddrStr, pBridgeAddrStr, cTokenAddrStr, pTokenAddrStr *string) { 2325 err := bm.subBridge.APIBackend.RegisterToken(cBridgeAddrStr, pBridgeAddrStr, cTokenAddrStr, pTokenAddrStr) 2326 assert.NoError(t, err) 2327 } 2328 2329 func testUnsubscribeAndDeRegister(t *testing.T, bm *BridgeManager, 2330 cBridgeAddrStr, pBridgeAddrStr, cTokenAddrStr, pTokenAddrStr *string, 2331 ) { 2332 findBridgePair := func(addrStr string) *BridgeJournal { 2333 bridgePairs := bm.subBridge.APIBackend.ListBridge() 2334 for _, bridgePair := range bridgePairs { 2335 if bridgePair.ChildAddress.String() == addrStr || bridgePair.BridgeAlias == addrStr { 2336 return bridgePair 2337 } 2338 } 2339 return nil 2340 } 2341 bridgePairLen := len(bm.subBridge.APIBackend.ListBridge()) 2342 defer func() { 2343 err := bm.subBridge.APIBackend.DeregisterBridge(cBridgeAddrStr, pBridgeAddrStr) 2344 assert.NoError(t, err) 2345 assert.Equal(t, len(bm.subBridge.APIBackend.ListBridge()) < bridgePairLen, true) 2346 }() 2347 2348 bridgePair := findBridgePair(*cBridgeAddrStr) 2349 assert.NotNil(t, bridgePair) 2350 assert.Equal(t, bridgePair.Subscribed, true) 2351 err := bm.subBridge.APIBackend.UnsubscribeBridge(cBridgeAddrStr, pBridgeAddrStr) 2352 assert.NoError(t, err) 2353 assert.Equal(t, bridgePair.Subscribed, false) 2354 2355 cBi, ok := bm.GetBridgeInfo(bridgePair.ChildAddress) 2356 assert.Equal(t, ok, true) 2357 assert.Equal(t, len(cBi.counterpartToken), 1) 2358 pBi, ok := bm.GetBridgeInfo(bridgePair.ParentAddress) 2359 assert.Equal(t, ok, true) 2360 assert.Equal(t, len(pBi.counterpartToken), 1) 2361 2362 err = bm.subBridge.APIBackend.DeregisterToken(cBridgeAddrStr, pBridgeAddrStr, cTokenAddrStr, pTokenAddrStr) 2363 assert.NoError(t, err) 2364 assert.Equal(t, len(cBi.counterpartToken), 0) 2365 assert.Equal(t, len(pBi.counterpartToken), 0) 2366 } 2367 2368 func TestLegacyBridgeJournalDecode(t *testing.T) { 2369 // `encodedJournalHexStr` is an encoded legacy bridge journals. The code below generate the following hex. 2370 encodedJournalHexStr := "eb9485564429cce278d4399436f1af2f91e1be6f0bd494c12701e0cb09d6600f774be1dbb585ddc749f9da80eb9485564429cce278d4399436f1af2f91e1be6f0bd594c12701e0cb09d6600f774be1dbb585ddc749f9db01eb9485564429cce278d4399436f1af2f91e1be6f0bd694c12701e0cb09d6600f774be1dbb585ddc749f9dc01" 2371 /* 2372 legacyJournals := []BridgeJournal{ 2373 { 2374 ChildAddress: common.HexToAddress("0x85564429cce278d4399436f1af2f91e1be6f0bd4"), 2375 ParentAddress: common.HexToAddress("0xc12701e0cb09d6600f774be1dbb585ddc749f9da"), 2376 Subscribed: false, 2377 }, 2378 { 2379 ChildAddress: common.HexToAddress("0x85564429cce278d4399436f1af2f91e1be6f0bd5"), 2380 ParentAddress: common.HexToAddress("0xc12701e0cb09d6600f774be1dbb585ddc749f9db"), 2381 Subscribed: true, 2382 }, 2383 { 2384 ChildAddress: common.HexToAddress("0x85564429cce278d4399436f1af2f91e1be6f0bd6"), 2385 ParentAddress: common.HexToAddress("0xc12701e0cb09d6600f774be1dbb585ddc749f9dc"), 2386 Subscribed: true, 2387 }, 2388 } 2389 encodedBuf := new(bytes.Buffer) 2390 for i := 0; i < len(journals); i++ { 2391 err := rlp.Encode(encodedBuf, &journals[i]) 2392 assert.NoError(t, err) 2393 } 2394 encodedString := hex.EncodeToString(encodedBuf.Bytes()) 2395 fmt.Println(encodedString) 2396 */ 2397 2398 legacyJournals := []BridgeJournal{ 2399 { 2400 ChildAddress: common.HexToAddress("0x85564429cce278d4399436f1af2f91e1be6f0bd4"), 2401 ParentAddress: common.HexToAddress("0xc12701e0cb09d6600f774be1dbb585ddc749f9da"), 2402 Subscribed: false, 2403 }, 2404 { 2405 ChildAddress: common.HexToAddress("0x85564429cce278d4399436f1af2f91e1be6f0bd5"), 2406 ParentAddress: common.HexToAddress("0xc12701e0cb09d6600f774be1dbb585ddc749f9db"), 2407 Subscribed: true, 2408 }, 2409 { 2410 ChildAddress: common.HexToAddress("0x85564429cce278d4399436f1af2f91e1be6f0bd6"), 2411 ParentAddress: common.HexToAddress("0xc12701e0cb09d6600f774be1dbb585ddc749f9dc"), 2412 Subscribed: true, 2413 }, 2414 } 2415 2416 tempJournalPath := "legacy-journal-decoding-test" 2417 tempFile, err := ioutil.TempFile(".", tempJournalPath) 2418 assert.NoError(t, err) 2419 2420 encodedHex, err := hex.DecodeString(encodedJournalHexStr) 2421 assert.NoError(t, err) 2422 2423 _, err = tempFile.Write(encodedHex) 2424 assert.NoError(t, err) 2425 defer os.Remove(tempFile.Name()) 2426 2427 readJournalIdx := 0 2428 load := func(gwjournal BridgeJournal) error { 2429 assert.Equal(t, len(gwjournal.BridgeAlias), 0) 2430 assert.Equal(t, gwjournal.ChildAddress.String(), legacyJournals[readJournalIdx].ChildAddress.String()) 2431 assert.Equal(t, gwjournal.ParentAddress.String(), legacyJournals[readJournalIdx].ParentAddress.String()) 2432 assert.Equal(t, gwjournal.Subscribed, legacyJournals[readJournalIdx].Subscribed) 2433 readJournalIdx++ 2434 return nil 2435 } 2436 journalAddr := newBridgeAddrJournal(tempFile.Name()) 2437 err = journalAddr.load(load) 2438 assert.NoError(t, err) 2439 } 2440 2441 func checkBridgeSetup(t *testing.T, bm *BridgeManager, expectedSubscribed bool, expectedNumberOfToken, expectedBridgeLen int) { 2442 bridgePairs := bm.subBridge.APIBackend.ListBridge() 2443 assert.Equal(t, len(bridgePairs), expectedBridgeLen) 2444 for _, bridgePair := range bridgePairs { 2445 assert.Equal(t, bridgePair.Subscribed, expectedSubscribed) 2446 cbi, ok := bm.GetBridgeInfo(bridgePair.ChildAddress) 2447 assert.Equal(t, ok, true) 2448 pbi, ok := bm.GetBridgeInfo(bridgePair.ChildAddress) 2449 assert.Equal(t, ok, true) 2450 assert.Equal(t, len(cbi.counterpartToken), expectedNumberOfToken) 2451 assert.Equal(t, len(pbi.counterpartToken), expectedNumberOfToken) 2452 } 2453 } 2454 2455 func checkRegisterMultipleToken(t *testing.T, bm *BridgeManager, cBridgeAddr, pBridgeAddr common.Address, expectedLen int) { 2456 cbi, ok := bm.GetBridgeInfo(cBridgeAddr) 2457 assert.Equal(t, ok, true) 2458 pbi, ok := bm.GetBridgeInfo(pBridgeAddr) 2459 assert.Equal(t, ok, true) 2460 assert.Equal(t, len(cbi.counterpartToken), expectedLen) 2461 assert.Equal(t, len(pbi.counterpartToken), expectedLen) 2462 } 2463 2464 func randomHex(n int) (string, error) { 2465 bytes := make([]byte, n) 2466 if _, err := rand.Read(bytes); err != nil { 2467 return "", err 2468 } 2469 return hex.EncodeToString(bytes), nil 2470 } 2471 2472 func TestBridgeAddressType(t *testing.T) { 2473 tempDir, err := ioutil.TempDir(os.TempDir(), "sc") 2474 assert.NoError(t, err) 2475 defer func() { 2476 if err := os.RemoveAll(tempDir); err != nil { 2477 t.Fatalf("fail to delete file %v", err) 2478 } 2479 }() 2480 2481 // Config Bridge Account Manager 2482 config := &SCConfig{} 2483 config.DataDir = tempDir 2484 bacc, _ := NewBridgeAccounts(nil, config.DataDir, database.NewDBManager(&database.DBConfig{DBType: database.MemoryDB}), DefaultBridgeTxGasLimit, DefaultBridgeTxGasLimit) 2485 bacc.pAccount.chainID = big.NewInt(0) 2486 bacc.cAccount.chainID = big.NewInt(0) 2487 2488 // Create Simulated backend 2489 alloc := blockchain.GenesisAlloc{ 2490 bacc.pAccount.address: {Balance: big.NewInt(params.KLAY)}, 2491 bacc.cAccount.address: {Balance: big.NewInt(params.KLAY)}, 2492 } 2493 sim := backends.NewSimulatedBackend(alloc) 2494 defer sim.Close() 2495 2496 sc := &SubBridge{ 2497 chainDB: database.NewDBManager(&database.DBConfig{DBType: database.MemoryDB}), 2498 config: config, 2499 peers: newBridgePeerSet(), 2500 bridgeAccounts: bacc, 2501 localBackend: sim, 2502 remoteBackend: sim, 2503 } 2504 sc.handler, err = NewSubBridgeHandler(sc) 2505 assert.NoError(t, err) 2506 bm, err := NewBridgeManager(sc) 2507 assert.NoError(t, err) 2508 2509 auth := bacc.cAccount.GenerateTransactOpts() 2510 2511 // Deploy Bridge Contract 2512 bridgeAddr, err := bm.DeployBridgeTest(sim, 10000, false) 2513 assert.NoError(t, err) 2514 sim.Commit() // block 2515 2516 anotherBridgeAddr, err := bm.DeployBridgeTest(sim, 10000, false) 2517 assert.NoError(t, err) 2518 sim.Commit() // block 2519 2520 // Case 1 - Success (The bridge address type is contract address) 2521 { 2522 // 1. Deploy Token Contract 2523 _, tx, token, err := sctoken.DeployServiceChainToken(auth, sim, bridgeAddr) 2524 assert.NoError(t, err) 2525 sim.Commit() // block 2526 CheckReceipt(sim, tx, time.Second, types.ReceiptStatusSuccessful, t) 2527 2528 // 2. Deploy NFT Contract 2529 _, tx, nft, err := scnft.DeployServiceChainNFT(auth, sim, bridgeAddr) 2530 assert.NoError(t, err) 2531 sim.Commit() // block 2532 CheckReceipt(sim, tx, time.Second, types.ReceiptStatusSuccessful, t) 2533 2534 tx, err = token.SetBridge(auth, anotherBridgeAddr) 2535 assert.NoError(t, err) 2536 sim.Commit() // block 2537 CheckReceipt(sim, tx, time.Second, types.ReceiptStatusSuccessful, t) 2538 tx, err = nft.SetBridge(auth, anotherBridgeAddr) 2539 assert.NoError(t, err) 2540 sim.Commit() // block 2541 CheckReceipt(sim, tx, time.Second, types.ReceiptStatusSuccessful, t) 2542 } 2543 2544 // Case 2 - Failure (The bridge address type is not a contract address) 2545 { 2546 _, tx, _, err := sctoken.DeployServiceChainToken(auth, sim, auth.From) 2547 assert.NoError(t, err) 2548 sim.Commit() // block 2549 CheckReceipt(sim, tx, time.Second, types.ReceiptStatusErrExecutionReverted, t) 2550 2551 _, tx, _, err = scnft.DeployServiceChainNFT(auth, sim, auth.From) 2552 assert.NoError(t, err) 2553 sim.Commit() // block 2554 CheckReceipt(sim, tx, time.Second, types.ReceiptStatusErrExecutionReverted, t) 2555 } 2556 2557 // Case 3 - Failure (The bridge address type is not a contract address) 2558 { 2559 _, tx, token, err := sctoken.DeployServiceChainToken(auth, sim, bridgeAddr) 2560 assert.NoError(t, err) 2561 sim.Commit() // block 2562 CheckReceipt(sim, tx, time.Second, types.ReceiptStatusSuccessful, t) 2563 2564 _, tx, nft, err := scnft.DeployServiceChainNFT(auth, sim, bridgeAddr) 2565 assert.NoError(t, err) 2566 sim.Commit() // block 2567 CheckReceipt(sim, tx, time.Second, types.ReceiptStatusSuccessful, t) 2568 2569 tx, err = token.SetBridge(auth, auth.From) 2570 assert.NoError(t, err) 2571 sim.Commit() // block 2572 CheckReceipt(sim, tx, time.Second, types.ReceiptStatusErrExecutionReverted, t) 2573 tx, err = nft.SetBridge(auth, auth.From) 2574 assert.NoError(t, err) 2575 sim.Commit() // block 2576 CheckReceipt(sim, tx, time.Second, types.ReceiptStatusErrExecutionReverted, t) 2577 } 2578 } 2579 2580 // DeployBridgeTest is a test-only function which deploys a bridge contract with some amount of KLAY. 2581 func (bm *BridgeManager) DeployBridgeTest(backend *backends.SimulatedBackend, amountOfDeposit int64, local bool) (common.Address, error) { 2582 var acc *accountInfo 2583 2584 // When the pending block of backend is updated, commit it 2585 // bm.DeployBridge will be waiting until the block is committed 2586 pendingBlock := backend.PendingBlock() 2587 go func() { 2588 for pendingBlock == backend.PendingBlock() { 2589 time.Sleep(100 * time.Millisecond) 2590 } 2591 backend.Commit() 2592 return 2593 }() 2594 2595 // Set transfer value of the bridge account 2596 if local { 2597 acc = bm.subBridge.bridgeAccounts.cAccount 2598 } else { 2599 acc = bm.subBridge.bridgeAccounts.pAccount 2600 } 2601 2602 auth := acc.GenerateTransactOpts() 2603 auth.Value = big.NewInt(amountOfDeposit) 2604 2605 // Deploy a bridge contract 2606 deployedBridge, addr, err := bm.DeployBridge(auth, backend, local) 2607 if err != nil { 2608 return common.Address{}, err 2609 } 2610 2611 // Set the bridge contract information to the BridgeManager 2612 err = bm.SetBridgeInfo(addr, deployedBridge, common.Address{}, nil, acc, local, false) 2613 if err != nil { 2614 return common.Address{}, err 2615 } 2616 return addr, err 2617 } 2618 2619 // deployBridge deploys bridge contract and returns its address 2620 func deployBridge(t *testing.T, bm *BridgeManager, backend *backends.SimulatedBackend, local bool) common.Address { 2621 var acc *accountInfo 2622 2623 // When the pending block of backend is updated, commit it 2624 // bm.DeployBridge will be waiting until the block is committed 2625 pendingBlock := backend.PendingBlock() 2626 go func() { 2627 for pendingBlock == backend.PendingBlock() { 2628 time.Sleep(100 * time.Millisecond) 2629 } 2630 backend.Commit() 2631 return 2632 }() 2633 2634 // Set transfer value of the bridge account 2635 if local { 2636 acc = bm.subBridge.bridgeAccounts.cAccount 2637 } else { 2638 acc = bm.subBridge.bridgeAccounts.pAccount 2639 } 2640 2641 auth := acc.GenerateTransactOpts() 2642 auth.Value = big.NewInt(10000) 2643 2644 // Deploy a bridge contract 2645 _, addr, err := bm.DeployBridge(auth, backend, local) 2646 assert.NoError(t, err) 2647 return addr 2648 } 2649 2650 func isExpectedBalance(t *testing.T, bridgeManager *BridgeManager, 2651 pBridgeAddr, cBridgeAddr common.Address, 2652 expectedParentBridgeBalance, expectedChildBridgeBalance int64, 2653 ) { 2654 pBridgeBalance, err := bridgeManager.subBridge.APIBackend.GetParentBridgeContractBalance(pBridgeAddr) 2655 assert.NoError(t, err) 2656 cBridgeBalance, err := bridgeManager.subBridge.APIBackend.GetChildBridgeContractBalance(cBridgeAddr) 2657 assert.NoError(t, err) 2658 assert.Equal(t, pBridgeBalance.Int64(), expectedParentBridgeBalance) 2659 assert.Equal(t, cBridgeBalance.Int64(), expectedChildBridgeBalance) 2660 } 2661 2662 func TestGetBridgeContractBalance(t *testing.T) { 2663 tempDir, err := ioutil.TempDir(os.TempDir(), "sc") 2664 assert.NoError(t, err) 2665 defer func() { 2666 if err := os.RemoveAll(tempDir); err != nil { 2667 t.Fatalf("fail to delete file %v", err) 2668 } 2669 }() 2670 2671 // Config Bridge Account Manager 2672 config := &SCConfig{} 2673 config.DataDir = tempDir 2674 bacc, _ := NewBridgeAccounts(nil, config.DataDir, database.NewDBManager(&database.DBConfig{DBType: database.MemoryDB}), DefaultBridgeTxGasLimit, DefaultBridgeTxGasLimit) 2675 bacc.pAccount.chainID = big.NewInt(0) 2676 bacc.cAccount.chainID = big.NewInt(0) 2677 2678 // Create Simulated backend 2679 alloc := blockchain.GenesisAlloc{ 2680 bacc.pAccount.address: {Balance: big.NewInt(params.KLAY)}, 2681 bacc.cAccount.address: {Balance: big.NewInt(params.KLAY)}, 2682 } 2683 sim := backends.NewSimulatedBackend(alloc) 2684 defer sim.Close() 2685 2686 sc := &SubBridge{ 2687 chainDB: database.NewDBManager(&database.DBConfig{DBType: database.MemoryDB}), 2688 config: config, 2689 peers: newBridgePeerSet(), 2690 bridgeAccounts: bacc, 2691 localBackend: sim, 2692 remoteBackend: sim, 2693 } 2694 sc.APIBackend = &SubBridgeAPI{sc} 2695 sc.handler, err = NewSubBridgeHandler(sc) 2696 if err != nil { 2697 log.Fatalf("Failed to initialize bridgeHandler : %v", err) 2698 return 2699 } 2700 2701 bm, err := NewBridgeManager(sc) 2702 assert.NoError(t, err) 2703 sc.handler.subbridge.bridgeManager = bm 2704 2705 // Case 1 - Success 2706 { 2707 initialChildbridgeBalance, initialParentbridgeBalance := int64(100), int64(100) 2708 cBridgeAddr, err := bm.DeployBridgeTest(sim, initialChildbridgeBalance, true) 2709 assert.NoError(t, err) 2710 pBridgeAddr, err := bm.DeployBridgeTest(sim, initialParentbridgeBalance, false) 2711 assert.NoError(t, err) 2712 bm.SetJournal("", cBridgeAddr, pBridgeAddr) 2713 assert.NoError(t, err) 2714 sim.Commit() 2715 isExpectedBalance(t, bm, pBridgeAddr, cBridgeAddr, initialParentbridgeBalance, initialChildbridgeBalance) 2716 } 2717 2718 // Case 2 - ? (Random) 2719 { 2720 rand.Seed(time.Now().UnixNano()) 2721 for i := 0; i < 10; i++ { 2722 initialChildbridgeBalance, initialParentbridgeBalance := rand.Int63n(10000), rand.Int63n(10000) 2723 cBridgeAddr, err := bm.DeployBridgeTest(sim, initialChildbridgeBalance, true) 2724 assert.NoError(t, err) 2725 pBridgeAddr, err := bm.DeployBridgeTest(sim, initialParentbridgeBalance, false) 2726 assert.NoError(t, err) 2727 bm.SetJournal("", cBridgeAddr, pBridgeAddr) 2728 assert.NoError(t, err) 2729 sim.Commit() 2730 isExpectedBalance(t, bm, pBridgeAddr, cBridgeAddr, initialParentbridgeBalance, initialChildbridgeBalance) 2731 } 2732 } 2733 }