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