diff --git a/bchain/coins/avalanche/contract_batch_integration_test.go b/bchain/coins/avalanche/contract_batch_integration_test.go index 5fa3dfc4..4f8d167b 100644 --- a/bchain/coins/avalanche/contract_batch_integration_test.go +++ b/bchain/coins/avalanche/contract_batch_integration_test.go @@ -9,12 +9,10 @@ import ( "github.com/trezor/blockbook/bchain/coins" ) -const defaultAvaxRpcURL = "http://localhost:8098/ext/bc/C/rpc" - func TestAvalancheErc20ContractBalancesIntegration(t *testing.T) { coins.RunERC20BatchBalanceTest(t, coins.ERC20BatchCase{ Name: "avalanche", - RPCURL: defaultAvaxRpcURL, + RPCURL: coins.RPCURLFromConfig(t, "avalanche"), // Token-rich address on Avalanche C-Chain (balanceOf works for any address). Addr: common.HexToAddress("0x60aE616a2155Ee3d9A68541Ba4544862310933d4"), Contracts: []common.Address{ diff --git a/bchain/coins/base/contract_batch_integration_test.go b/bchain/coins/base/contract_batch_integration_test.go index e3a90c81..333897c2 100644 --- a/bchain/coins/base/contract_batch_integration_test.go +++ b/bchain/coins/base/contract_batch_integration_test.go @@ -9,12 +9,10 @@ import ( "github.com/trezor/blockbook/bchain/coins" ) -const defaultBaseRpcURL = "ws://localhost:8309" - func TestBaseErc20ContractBalancesIntegration(t *testing.T) { coins.RunERC20BatchBalanceTest(t, coins.ERC20BatchCase{ Name: "base", - RPCURL: defaultBaseRpcURL, + RPCURL: coins.RPCURLFromConfig(t, "base"), Addr: common.HexToAddress("0x242E2d70d3AdC00a9eF23CeD6E88811fCefCA788"), Contracts: []common.Address{ common.HexToAddress("0x4200000000000000000000000000000000000006"), // WETH diff --git a/bchain/coins/bsc/contract_batch_integration_test.go b/bchain/coins/bsc/contract_batch_integration_test.go index 5c628bd1..9e3e6c9d 100644 --- a/bchain/coins/bsc/contract_batch_integration_test.go +++ b/bchain/coins/bsc/contract_batch_integration_test.go @@ -9,12 +9,10 @@ import ( "github.com/trezor/blockbook/bchain/coins" ) -const defaultBscRpcURL = "ws://localhost:8064" - func TestBNBSmartChainErc20ContractBalancesIntegration(t *testing.T) { coins.RunERC20BatchBalanceTest(t, coins.ERC20BatchCase{ Name: "bsc", - RPCURL: defaultBscRpcURL, + RPCURL: coins.RPCURLFromConfig(t, "bsc"), Addr: common.HexToAddress("0x21d45650db732cE5dF77685d6021d7D5d1da807f"), Contracts: []common.Address{ common.HexToAddress("0xBB4CdB9CBd36B01bD1cBaEBF2De08d9173bc095c"), // WBNB diff --git a/bchain/coins/erc20_batch_integration.go b/bchain/coins/erc20_batch_integration.go index f08b15a0..b4d8240b 100644 --- a/bchain/coins/erc20_batch_integration.go +++ b/bchain/coins/erc20_batch_integration.go @@ -3,10 +3,14 @@ package coins import ( + "bytes" "context" "errors" "fmt" "net" + "os" + "path/filepath" + "runtime" "strings" "testing" "time" @@ -14,6 +18,7 @@ import ( "github.com/ethereum/go-ethereum/common" "github.com/trezor/blockbook/bchain" "github.com/trezor/blockbook/bchain/coins/eth" + buildcfg "github.com/trezor/blockbook/build/tools" ) const defaultBatchSize = 200 @@ -55,6 +60,50 @@ func RunERC20BatchBalanceTest(t *testing.T, tc ERC20BatchCase) { } } +func RPCURLFromConfig(t *testing.T, coinAlias string) string { + t.Helper() + configsDir, err := repoConfigsDir() + if err != nil { + t.Fatalf("integration config path error: %v", err) + } + cfg, err := buildcfg.LoadConfig(configsDir, coinAlias) + if err != nil { + t.Fatalf("load config for %s: %v", coinAlias, err) + } + templ := cfg.ParseTemplate() + var out bytes.Buffer + if err := templ.ExecuteTemplate(&out, "IPC.RPCURLTemplate", cfg); err != nil { + t.Fatalf("render rpc_url_template for %s: %v", coinAlias, err) + } + rpcURL := strings.TrimSpace(out.String()) + if rpcURL == "" { + t.Fatalf("empty rpc url from config for %s", coinAlias) + } + return rpcURL +} + +func repoConfigsDir() (string, error) { + _, file, _, ok := runtime.Caller(0) + if !ok { + return "", errors.New("unable to resolve caller path") + } + dir := filepath.Dir(file) + for i := 0; i < 6; i++ { + configsDir := filepath.Join(dir, "configs") + if _, err := os.Stat(filepath.Join(configsDir, "coins")); err == nil { + return configsDir, nil + } else if !os.IsNotExist(err) { + return "", err + } + parent := filepath.Dir(dir) + if parent == dir { + break + } + dir = parent + } + return "", errors.New("configs/coins not found from caller path") +} + func handleRPCError(t *testing.T, tc ERC20BatchCase, err error) { t.Helper() if tc.SkipUnavailable && isRPCUnavailable(err) { diff --git a/bchain/coins/eth/contract_batch_integration_test.go b/bchain/coins/eth/contract_batch_integration_test.go index f41809f5..5c4dc3ec 100644 --- a/bchain/coins/eth/contract_batch_integration_test.go +++ b/bchain/coins/eth/contract_batch_integration_test.go @@ -9,12 +9,10 @@ import ( "github.com/trezor/blockbook/bchain/coins" ) -const defaultEthRpcURL = "http://localhost:8545" - func TestEthereumTypeGetErc20ContractBalancesIntegration(t *testing.T) { coins.RunERC20BatchBalanceTest(t, coins.ERC20BatchCase{ Name: "ethereum", - RPCURL: defaultEthRpcURL, + RPCURL: coins.RPCURLFromConfig(t, "ethereum"), // Token-rich EOA (CEX hot wallet) used as a stable address reference. Addr: common.HexToAddress("0x28C6c06298d514Db089934071355E5743bf21d60"), Contracts: []common.Address{ diff --git a/bchain/coins/optimism/contract_batch_integration_test.go b/bchain/coins/optimism/contract_batch_integration_test.go index 5b9c64cb..fe0b94ca 100644 --- a/bchain/coins/optimism/contract_batch_integration_test.go +++ b/bchain/coins/optimism/contract_batch_integration_test.go @@ -9,12 +9,10 @@ import ( "github.com/trezor/blockbook/bchain/coins" ) -const defaultOptimismRpcURL = "ws://localhost:8200" - func TestOptimismErc20ContractBalancesIntegration(t *testing.T) { coins.RunERC20BatchBalanceTest(t, coins.ERC20BatchCase{ Name: "optimism", - RPCURL: defaultOptimismRpcURL, + RPCURL: coins.RPCURLFromConfig(t, "optimism"), Addr: common.HexToAddress("0xDF90C9B995a3b10A5b8570a47101e6c6a29eb945"), Contracts: []common.Address{ common.HexToAddress("0x4200000000000000000000000000000000000006"), // WETH