diff options
author | aaronbuchwald <[email protected]> | 2020-11-20 10:06:46 -0500 |
---|---|---|
committer | GitHub <[email protected]> | 2020-11-20 10:06:46 -0500 |
commit | ef19d4da57f99c0c4d93b1ad7dbcbd0b3892bff7 (patch) | |
tree | 2dccd3942cdea2f00ae67c95ba2d26d0479f12d3 /examples/client/main.go | |
parent | 59453f4676ae1d778a32fd9a4edcc94d74747e14 (diff) | |
parent | 9feab9d470278e4eecffa059b476dbf3c9417d8d (diff) |
Merge pull request #58 from ava-labs/ethclient
Ethclient
Diffstat (limited to 'examples/client/main.go')
-rw-r--r-- | examples/client/main.go | 220 |
1 files changed, 220 insertions, 0 deletions
diff --git a/examples/client/main.go b/examples/client/main.go new file mode 100644 index 0000000..5f61e6a --- /dev/null +++ b/examples/client/main.go @@ -0,0 +1,220 @@ +package main + +import ( + "context" + "fmt" + "time" + + "math/big" + + "github.com/ava-labs/avalanchego/utils/crypto" + "github.com/ava-labs/avalanchego/utils/formatting" + "github.com/ava-labs/coreth/ethclient" + "github.com/ava-labs/coreth/plugin/evm" + + "github.com/ava-labs/coreth" + "github.com/ava-labs/coreth/core/types" + "github.com/ethereum/go-ethereum/common" +) + +var ( + key = "ewoqjP7PxY4yr3iLTpLisriqt94hdyDFNgchSxGGztUrTXtNN" + prefixedPrivateKey = fmt.Sprintf("PrivateKey-%s", key) + ipAddr = "127.0.0.1" + port = 9650 +) + +type ethWSAPITestExecutor struct { + uri string + requestTimeout time.Duration +} + +// ExecuteTest ... +func (e *ethWSAPITestExecutor) ExecuteTest() error { + client, err := ethclient.Dial(e.uri) + if err != nil { + return fmt.Errorf("Failed to create ethclient: %w", err) + } + fmt.Printf("Created ethclient\n") + + ctx := context.Background() + + cb58 := formatting.CB58{} + factory := crypto.FactorySECP256K1R{} + _ = cb58.FromString(key) + pk, _ := factory.ToPrivateKey(cb58.Bytes) + secpKey := pk.(*crypto.PrivateKeySECP256K1R) + ethAddr := evm.GetEthAddress(secpKey) + + if err := testSubscription(ctx, client); err != nil { + return fmt.Errorf("Subscription Test failed: %w", err) + } + + if err := testHeaderAndBlockCalls(ctx, client, ethAddr); err != nil { + return fmt.Errorf("HeaderAndBlockCalls Test failed: %w", err) + } + + return nil +} + +type ethRPCAPITestExecutor struct { + uri string + requestTimeout time.Duration +} + +// ExecuteTest ... +func (e *ethRPCAPITestExecutor) ExecuteTest() error { + client, err := ethclient.Dial(e.uri) + if err != nil { + return fmt.Errorf("Failed to create ethclient: %w", err) + } + fmt.Printf("Created ethclient\n") + + ctx := context.Background() + + cb58 := formatting.CB58{} + factory := crypto.FactorySECP256K1R{} + _ = cb58.FromString(key) + pk, _ := factory.ToPrivateKey(cb58.Bytes) + secpKey := pk.(*crypto.PrivateKeySECP256K1R) + ethAddr := evm.GetEthAddress(secpKey) + + if err := testHeaderAndBlockCalls(ctx, client, ethAddr); err != nil { + return fmt.Errorf("HeaderAndBlockCalls Test failed: %w", err) + } + + return nil +} + +func testSubscription(ctx context.Context, client *ethclient.Client) error { + headerChan := make(chan *types.Header) + subscription, err := client.SubscribeNewHead(ctx, headerChan) + if err != nil { + return fmt.Errorf("Failed to create subscription: %s", err) + } + fmt.Printf("Created subscription: %s\n", subscription) + + suggestedGasPrice, err := client.SuggestGasPrice(ctx) + if err != nil { + return fmt.Errorf("Failed to get suggested gas price: %s", err) + } + fmt.Printf("Suggested gas price: %d\n", suggestedGasPrice.Uint64()) + + logChan := make(chan types.Log) + query := coreth.FilterQuery{ + BlockHash: nil, + FromBlock: nil, + ToBlock: nil, + Addresses: []common.Address{}, + Topics: [][]common.Hash{}, + } + subscription, err = client.SubscribeFilterLogs(ctx, query, logChan) + if err != nil { + return fmt.Errorf("Failed to create subscription: %s", err) + } + fmt.Printf("Created subscription: %s\n", subscription) + + return nil +} + +func testHeaderAndBlockCalls(ctx context.Context, client *ethclient.Client, ethAddr common.Address) error { + // Test Header and Block ByNumber work for special cases + for i := 0; i > -3; i-- { + if err := checkHeaderAndBlocks(ctx, client, i, ethAddr); err != nil { + return err + } + } + + return nil +} + +func checkHeaderAndBlocks(ctx context.Context, client *ethclient.Client, i int, ethAddr common.Address) error { + fmt.Printf("Checking HeaderAndBlocks for i = %d\n", i) + + header1, err := client.HeaderByNumber(ctx, big.NewInt(int64(i))) + if err != nil { + return fmt.Errorf("Failed to retrieve HeaderByNumber: %w", err) + } + fmt.Printf("HeaderByNumber (Block Number: %d, Block Hash: %s)\n", header1.Number, header1.Hash().Hex()) + + originalHash := header1.Hash() + originalBlockNumber := header1.Number + if i >= 0 && int(originalBlockNumber.Int64()) != i { + return fmt.Errorf("Requested block number %d, but found block number %d", i, originalBlockNumber) + } + + header2, err := client.HeaderByHash(ctx, header1.Hash()) + if err != nil { + return fmt.Errorf("Failed to retrieve HeaderByHash: %w", err) + } + fmt.Printf("HeaderByNumber (Block Number: %d, Block Hash: %s)\n", header2.Number, header2.Hash().Hex()) + + if originalHash.Hex() != header2.Hash().Hex() { + return fmt.Errorf("Expected HeaderByHash with Hash: %s, but found: %s", originalHash.Hex(), header2.Hash().Hex()) + } + + if originalBlockNumber.Cmp(header2.Number) != 0 { + return fmt.Errorf("Expected HeaderByHash with Number: %d, but found %d", originalBlockNumber, header2.Number) + } + + block1, err := client.BlockByNumber(ctx, big.NewInt(int64(i))) + if err != nil { + return fmt.Errorf("Failed to retrieve BlockByNumber: %w", err) + } + header3 := block1.Header() + fmt.Printf("BlockByNumber (Block Number: %d, Block Hash: %s)\n", header3.Number, header3.Hash().Hex()) + + if originalHash.Hex() != header3.Hash().Hex() { + return fmt.Errorf("Expected HeaderByHash with Hash: %s, but found: %s", originalHash.Hex(), header3.Hash().Hex()) + } + + if originalBlockNumber.Cmp(header3.Number) != 0 { + return fmt.Errorf("Expected HeaderByHash with Number: %d, but found %d", originalBlockNumber, header3.Number) + } + + block2, err := client.BlockByHash(ctx, header1.Hash()) + if err != nil { + return fmt.Errorf("Failed to retrieve BlockByHash: %w", err) + } + header4 := block2.Header() + fmt.Printf("BlockByHash (Block Number: %d, Block Hash: %s)\n", header4.Number, header4.Hash().Hex()) + if originalHash.Hex() != header4.Hash().Hex() { + return fmt.Errorf("Expected HeaderByHash with Hash: %s, but found: %s", originalHash.Hex(), header4.Hash().Hex()) + } + + if originalBlockNumber.Cmp(header4.Number) != 0 { + return fmt.Errorf("Expected HeaderByHash with Number: %d, but found %d", originalBlockNumber, header4.Number) + } + + balance, err := client.BalanceAt(ctx, ethAddr, big.NewInt(int64(i))) + if err != nil { + return fmt.Errorf("Failed to get balance: %s", err) + } + fmt.Printf("Balance: %d for address: %s\n", balance, ethAddr.Hex()) + + return nil +} + +func main() { + wsURI := fmt.Sprintf("ws://%s:%d/ext/bc/C/ws", ipAddr, port) + wsTest := ðWSAPITestExecutor{ + uri: wsURI, + requestTimeout: 3 * time.Second, + } + if err := wsTest.ExecuteTest(); err != nil { + fmt.Printf("WebSocket Test failed due to %s\n", err) + } else { + fmt.Printf("WebSocket Test succeeded!\n") + } + + rpcURI := fmt.Sprintf("http://%s:%d/ext/bc/C/rpc", ipAddr, port) + rpcTest := ðRPCAPITestExecutor{ + uri: rpcURI, + requestTimeout: 3 * time.Second, + } + if err := rpcTest.ExecuteTest(); err != nil { + fmt.Printf("RPC Test failed due to %s\n", err) + } else { + fmt.Printf("RPC Test succeeded!\n") + } +} |