Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

module: double indirection #178

Merged
merged 10 commits into from
Aug 22, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 0 additions & 4 deletions .github/dependabot.yml
Original file line number Diff line number Diff line change
Expand Up @@ -4,10 +4,6 @@ updates:
directory: "/"
schedule:
interval: "daily"
- package-ecosystem: "gomod"
directory: "/examples"
schedule:
interval: "daily"
- package-ecosystem: "npm"
directory: "/docs"
schedule:
Expand Down
38 changes: 19 additions & 19 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@ defer client.Close()

// 2. Make a batch request
var (
balance big.Int
balance *big.Int
nonce uint64
)
if err := client.Call(
Expand Down Expand Up @@ -168,47 +168,47 @@ List of supported RPC methods for [`w3.Client`](https://pkg.go.dev/github.com/lm

| Method | Go Code
| :---------------------------------------- | :-------
| `eth_blockNumber` | `eth.BlockNumber().Returns(blockNumber *big.Int)`
| `eth_blockNumber` | `eth.BlockNumber().Returns(blockNumber **big.Int)`
| `eth_call` | `eth.Call(msg *w3types.Message, blockNumber *big.Int, overrides w3types.State).Returns(output *[]byte)`<br>`eth.CallFunc(contract common.Address, f w3types.Func, args ...any).Returns(returns ...any)`
| `eth_chainId` | `eth.ChainID().Returns(chainID *uint64)`
| `eth_createAccessList` | `eth.AccessList(msg *w3types.Message, blockNumber *big.Int).Returns(resp *eth.AccessListResponse)`
| `eth_createAccessList` | `eth.AccessList(msg *w3types.Message, blockNumber *big.Int).Returns(resp **eth.AccessListResponse)`
| `eth_estimateGas` | `eth.EstimateGas(msg *w3types.Message, blockNumber *big.Int).Returns(gas *uint64)`
| `eth_gasPrice` | `eth.GasPrice().Returns(gasPrice *big.Int)`
| `eth_maxPriorityFeePerGas` | `eth.GasTipCap().Returns(gasTipCap *big.Int)`
| `eth_getBalance` | `eth.Balance(addr common.Address, blockNumber *big.Int).Returns(balance *big.Int)`
| `eth_getBlockByHash` | `eth.BlockByHash(hash common.Hash).Returns(block *types.Block)`<br>`eth.HeaderByHash(hash common.Hash).Returns(header *types.Header)`
| `eth_getBlockByNumber` | `eth.BlockByNumber(number *big.Int).Returns(block *types.Block)`<br>`eth.HeaderByNumber(number *big.Int).Returns(header *types.Header)`
| `eth_gasPrice` | `eth.GasPrice().Returns(gasPrice **big.Int)`
| `eth_maxPriorityFeePerGas` | `eth.GasTipCap().Returns(gasTipCap **big.Int)`
| `eth_getBalance` | `eth.Balance(addr common.Address, blockNumber *big.Int).Returns(balance **big.Int)`
| `eth_getBlockByHash` | `eth.BlockByHash(hash common.Hash).Returns(block *types.Block)`<br>`eth.HeaderByHash(hash common.Hash).Returns(header **types.Header)`
| `eth_getBlockByNumber` | `eth.BlockByNumber(number *big.Int).Returns(block *types.Block)`<br>`eth.HeaderByNumber(number *big.Int).Returns(header **types.Header)`
| `eth_getBlockReceipts` | `eth.BlockReceipts(blockNumber *big.Int).Returns(receipts *types.Receipts)`
| `eth_getBlockTransactionCountByHash` | `eth.BlockTxCountByHash(hash common.Hash).Returns(count *uint)`
| `eth_getBlockTransactionCountByNumber` | `eth.BlockTxCountByNumber(number *big.Int).Returns(count *uint)`
| `eth_getCode` | `eth.Code(addr common.Address, blockNumber *big.Int).Returns(code *[]byte)`
| `eth_getLogs` | `eth.Logs(q ethereum.FilterQuery).Returns(logs *[]types.Log)`
| `eth_getStorageAt` | `eth.StorageAt(addr common.Address, slot common.Hash, blockNumber *big.Int).Returns(storage *common.Hash)`
| `eth_getTransactionByHash` | `eth.Tx(hash common.Hash).Returns(tx *types.Transaction)`
| `eth_getTransactionByBlockHashAndIndex` | `eth.TxByBlockHashAndIndex(blockHash common.Hash, index uint).Returns(tx *types.Transaction)`
| `eth_getTransactionByBlockNumberAndIndex` | `eth.TxByBlockNumberAndIndex(blockNumber *big.Int, index uint).Returns(tx *types.Transaction)`
| `eth_getTransactionByHash` | `eth.Tx(hash common.Hash).Returns(tx **types.Transaction)`
| `eth_getTransactionByBlockHashAndIndex` | `eth.TxByBlockHashAndIndex(blockHash common.Hash, index uint).Returns(tx **types.Transaction)`
| `eth_getTransactionByBlockNumberAndIndex` | `eth.TxByBlockNumberAndIndex(blockNumber *big.Int, index uint).Returns(tx **types.Transaction)`
| `eth_getTransactionCount` | `eth.Nonce(addr common.Address, blockNumber *big.Int).Returns(nonce *uint)`
| `eth_getTransactionReceipt` | `eth.TxReceipt(txHash common.Hash).Returns(receipt *types.Receipt)`
| `eth_getTransactionReceipt` | `eth.TxReceipt(txHash common.Hash).Returns(receipt **types.Receipt)`
| `eth_sendRawTransaction` | `eth.SendRawTx(rawTx []byte).Returns(hash *common.Hash)`<br>`eth.SendTx(tx *types.Transaction).Returns(hash *common.Hash)`
| `eth_getUncleByBlockHashAndIndex` | `eth.UncleByBlockHashAndIndex(hash common.Hash, index uint).Returns(uncle *types.Header)`
| `eth_getUncleByBlockNumberAndIndex` | `eth.UncleByBlockNumberAndIndex(number *big.Int, index uint).Returns(uncle *types.Header)`
| `eth_getUncleByBlockHashAndIndex` | `eth.UncleByBlockHashAndIndex(hash common.Hash, index uint).Returns(uncle **types.Header)`
| `eth_getUncleByBlockNumberAndIndex` | `eth.UncleByBlockNumberAndIndex(number *big.Int, index uint).Returns(uncle **types.Header)`
| `eth_getUncleCountByBlockHash` | `eth.UncleCountByBlockHash(hash common.Hash).Returns(count *uint)`
| `eth_getUncleCountByBlockNumber` | `eth.UncleCountByBlockNumber(number *big.Int).Returns(count *uint)`

### [`debug`](https://pkg.go.dev/github.com/lmittmann/w3/module/debug)

| Method | Go Code
| :----------------------- | :-------
| `debug_traceCall` | `debug.TraceCall(msg *w3types.Message, blockNumber *big.Int, config *debug.TraceConfig).Returns(trace *debug.Trace)`<br>`debug.CallTraceCall(msg *w3types.Message, blockNumber *big.Int, overrides w3types.State).Returns(trace *debug.CallTrace)`
| `debug_traceTransaction` | `debug.TraceTx(txHash common.Hash, config *debug.TraceConfig).Returns(trace *debug.Trace)`<br>`debug.CallTraceTx(txHash common.Hash, overrides w3types.State).Returns(trace *debug.CallTrace)`
| `debug_traceCall` | `debug.TraceCall(msg *w3types.Message, blockNumber *big.Int, config *debug.TraceConfig).Returns(trace **debug.Trace)`<br>`debug.CallTraceCall(msg *w3types.Message, blockNumber *big.Int, overrides w3types.State).Returns(trace **debug.CallTrace)`
| `debug_traceTransaction` | `debug.TraceTx(txHash common.Hash, config *debug.TraceConfig).Returns(trace **debug.Trace)`<br>`debug.CallTraceTx(txHash common.Hash, overrides w3types.State).Returns(trace **debug.CallTrace)`

### [`txpool`](https://pkg.go.dev/github.com/lmittmann/w3/module/txpool)

| Method | Go Code
| :--------------------| :-------
| `txpool_content` | `txpool.Content().Returns(resp *txpool.ContentResponse)`
| `txpool_contentFrom` | `txpool.ContentFrom(addr common.Address).Returns(resp *txpool.ContentFromResponse)`
| `txpool_status` | `txpool.Status().Returns(resp *txpool.StatusResponse)`
| `txpool_content` | `txpool.Content().Returns(resp **txpool.ContentResponse)`
| `txpool_contentFrom` | `txpool.ContentFrom(addr common.Address).Returns(resp **txpool.ContentFromResponse)`
| `txpool_status` | `txpool.Status().Returns(resp **txpool.StatusResponse)`

### [`web3`](https://pkg.go.dev/github.com/lmittmann/w3/module/web3)

Expand Down
35 changes: 10 additions & 25 deletions client_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,7 @@ func ExampleClient() {

// 2. Make a batch request
var (
balance big.Int
balance *big.Int
nonce uint64
)
if err := client.Call(
Expand All @@ -58,7 +58,7 @@ func ExampleClient() {
// handle error
}

fmt.Printf("balance: %s\nnonce: %d\n", w3.FromWei(&balance, 18), nonce)
fmt.Printf("balance: %s\nnonce: %d\n", w3.FromWei(balance, 18), nonce)
}

func ExampleClient_Call_balanceOf() {
Expand All @@ -76,8 +76,8 @@ func ExampleClient_Call_balanceOf() {
balanceOf = w3.MustNewFunc("balanceOf(address)", "uint256")

// Declare variables for the RPC responses.
ethBalance big.Int
weth9Balance big.Int
ethBalance *big.Int
weth9Balance *big.Int
)

// Do batch request (both RPC requests are send in the same
Expand All @@ -91,7 +91,7 @@ func ExampleClient_Call_balanceOf() {
}

fmt.Printf("Combined balance: %v wei",
new(big.Int).Add(&ethBalance, &weth9Balance),
new(big.Int).Add(ethBalance, weth9Balance),
)
}

Expand All @@ -103,7 +103,7 @@ func ExampleClient_Call_nonceAndBalance() {
addr = w3.A("0x000000000000000000000000000000000000c0Fe")

nonce uint64
balance big.Int
balance *big.Int
)

if err := client.Call(
Expand All @@ -114,7 +114,7 @@ func ExampleClient_Call_nonceAndBalance() {
return
}

fmt.Printf("%s: Nonce: %d, Balance: ♦%s\n", addr, nonce, w3.FromWei(&balance, 18))
fmt.Printf("%s: Nonce: %d, Balance: ♦%s\n", addr, nonce, w3.FromWei(balance, 18))
}

func ExampleClient_Call_sendERC20transferTx() {
Expand Down Expand Up @@ -329,21 +329,6 @@ func (c *testCaller) HandleResponse(elem rpc.BatchElem) (err error) {
return c.ReturnErr
}

func TestClientCall_NilReference(t *testing.T) {
client := w3.MustDial("https://rpc.ankr.com/eth")
defer client.Close()

var block *types.Block
err := client.Call(
eth.BlockByNumber(nil).Returns(block),
)

want := "w3: cannot return Go value of type *types.Block: value must be passed as a non-nil pointer reference"
if diff := cmp.Diff(want, err.Error()); diff != "" {
t.Fatalf("(-want, +got)\n%s", diff)
}
}

func BenchmarkCall_BalanceNonce(b *testing.B) {
if *benchRPC == "" {
b.Skipf("Missing -benchRPC")
Expand All @@ -360,7 +345,7 @@ func BenchmarkCall_BalanceNonce(b *testing.B) {
b.Run("Batch", func(b *testing.B) {
var (
nonce uint64
balance big.Int
balance *big.Int
)
for range b.N {
w3Client.Call(
Expand Down Expand Up @@ -395,7 +380,7 @@ func BenchmarkCall_Balance100(b *testing.B) {
}

b.Run("Batch", func(b *testing.B) {
var balance big.Int
var balance *big.Int
for range b.N {
requests := make([]w3types.RPCCaller, len(addr100))
for j := range len(requests) {
Expand Down Expand Up @@ -477,7 +462,7 @@ func BenchmarkCall_Block100(b *testing.B) {
}

b.Run("Batch", func(b *testing.B) {
var block types.Block
var block *types.Block
for range b.N {
requests := make([]w3types.RPCCaller, len(block100))
for j := range len(requests) {
Expand Down
38 changes: 19 additions & 19 deletions docs/pages/index.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -58,7 +58,7 @@ defer client.Close()

// 2. Make a batch request
var (
balance big.Int
balance *big.Int
nonce uint64
)
if err := client.Call(
Expand Down Expand Up @@ -188,47 +188,47 @@ List of supported RPC methods for [`w3.Client`](https://pkg.go.dev/github.com/lm

| Method | Go Code
| :---------------------------------------- | :-------
| `eth_blockNumber` | `eth.BlockNumber().Returns(blockNumber *big.Int)`
| `eth_blockNumber` | `eth.BlockNumber().Returns(blockNumber **big.Int)`
| `eth_call` | `eth.Call(msg *w3types.Message, blockNumber *big.Int, overrides w3types.State).Returns(output *[]byte)`<br/>`eth.CallFunc(contract common.Address, f w3types.Func, args ...any).Returns(returns ...any)`
| `eth_chainId` | `eth.ChainID().Returns(chainID *uint64)`
| `eth_createAccessList` | `eth.AccessList(msg *w3types.Message, blockNumber *big.Int).Returns(resp *eth.AccessListResponse)`
| `eth_createAccessList` | `eth.AccessList(msg *w3types.Message, blockNumber *big.Int).Returns(resp **eth.AccessListResponse)`
| `eth_estimateGas` | `eth.EstimateGas(msg *w3types.Message, blockNumber *big.Int).Returns(gas *uint64)`
| `eth_gasPrice` | `eth.GasPrice().Returns(gasPrice *big.Int)`
| `eth_maxPriorityFeePerGas` | `eth.GasTipCap().Returns(gasTipCap *big.Int)`
| `eth_getBalance` | `eth.Balance(addr common.Address, blockNumber *big.Int).Returns(balance *big.Int)`
| `eth_getBlockByHash` | `eth.BlockByHash(hash common.Hash).Returns(block *types.Block)`<br/>`eth.HeaderByHash(hash common.Hash).Returns(header *types.Header)`
| `eth_getBlockByNumber` | `eth.BlockByNumber(number *big.Int).Returns(block *types.Block)`<br/>`eth.HeaderByNumber(number *big.Int).Returns(header *types.Header)`
| `eth_gasPrice` | `eth.GasPrice().Returns(gasPrice **big.Int)`
| `eth_maxPriorityFeePerGas` | `eth.GasTipCap().Returns(gasTipCap **big.Int)`
| `eth_getBalance` | `eth.Balance(addr common.Address, blockNumber *big.Int).Returns(balance **big.Int)`
| `eth_getBlockByHash` | `eth.BlockByHash(hash common.Hash).Returns(block *types.Block)`<br/>`eth.HeaderByHash(hash common.Hash).Returns(header **types.Header)`
| `eth_getBlockByNumber` | `eth.BlockByNumber(number *big.Int).Returns(block *types.Block)`<br/>`eth.HeaderByNumber(number *big.Int).Returns(header **types.Header)`
| `eth_getBlockReceipts` | `eth.BlockReceipts(blockNumber *big.Int).Returns(receipts *types.Receipts)`
| `eth_getBlockTransactionCountByHash` | `eth.BlockTxCountByHash(hash common.Hash).Returns(count *uint)`
| `eth_getBlockTransactionCountByNumber` | `eth.BlockTxCountByNumber(number *big.Int).Returns(count *uint)`
| `eth_getCode` | `eth.Code(addr common.Address, blockNumber *big.Int).Returns(code *[]byte)`
| `eth_getLogs` | `eth.Logs(q ethereum.FilterQuery).Returns(logs *[]types.Log)`
| `eth_getStorageAt` | `eth.StorageAt(addr common.Address, slot common.Hash, blockNumber *big.Int).Returns(storage *common.Hash)`
| `eth_getTransactionByHash` | `eth.Tx(hash common.Hash).Returns(tx *types.Transaction)`
| `eth_getTransactionByBlockHashAndIndex` | `eth.TxByBlockHashAndIndex(blockHash common.Hash, index uint).Returns(tx *types.Transaction)`
| `eth_getTransactionByBlockNumberAndIndex` | `eth.TxByBlockNumberAndIndex(blockNumber *big.Int, index uint).Returns(tx *types.Transaction)`
| `eth_getTransactionByHash` | `eth.Tx(hash common.Hash).Returns(tx **types.Transaction)`
| `eth_getTransactionByBlockHashAndIndex` | `eth.TxByBlockHashAndIndex(blockHash common.Hash, index uint).Returns(tx **types.Transaction)`
| `eth_getTransactionByBlockNumberAndIndex` | `eth.TxByBlockNumberAndIndex(blockNumber *big.Int, index uint).Returns(tx **types.Transaction)`
| `eth_getTransactionCount` | `eth.Nonce(addr common.Address, blockNumber *big.Int).Returns(nonce *uint)`
| `eth_getTransactionReceipt` | `eth.TxReceipt(txHash common.Hash).Returns(receipt *types.Receipt)`
| `eth_getTransactionReceipt` | `eth.TxReceipt(txHash common.Hash).Returns(receipt **types.Receipt)`
| `eth_sendRawTransaction` | `eth.SendRawTx(rawTx []byte).Returns(hash *common.Hash)`<br/>`eth.SendTx(tx *types.Transaction).Returns(hash *common.Hash)`
| `eth_getUncleByBlockHashAndIndex` | `eth.UncleByBlockHashAndIndex(hash common.Hash, index uint).Returns(uncle *types.Header)`
| `eth_getUncleByBlockNumberAndIndex` | `eth.UncleByBlockNumberAndIndex(number *big.Int, index uint).Returns(uncle *types.Header)`
| `eth_getUncleByBlockHashAndIndex` | `eth.UncleByBlockHashAndIndex(hash common.Hash, index uint).Returns(uncle **types.Header)`
| `eth_getUncleByBlockNumberAndIndex` | `eth.UncleByBlockNumberAndIndex(number *big.Int, index uint).Returns(uncle **types.Header)`
| `eth_getUncleCountByBlockHash` | `eth.UncleCountByBlockHash(hash common.Hash).Returns(count *uint)`
| `eth_getUncleCountByBlockNumber` | `eth.UncleCountByBlockNumber(number *big.Int).Returns(count *uint)`

### [`debug`](https://pkg.go.dev/github.com/lmittmann/w3/module/debug)

| Method | Go Code
| :----------------------- | :-------
| `debug_traceCall` | `debug.TraceCall(msg *w3types.Message, blockNumber *big.Int, config *debug.TraceConfig).Returns(trace *debug.Trace)`<br/>`debug.CallTraceCall(msg *w3types.Message, blockNumber *big.Int, overrides w3types.State).Returns(trace *debug.CallTrace)`
| `debug_traceTransaction` | `debug.TraceTx(txHash common.Hash, config *debug.TraceConfig).Returns(trace *debug.Trace)`<br/>`debug.CallTraceTx(txHash common.Hash, overrides w3types.State).Returns(trace *debug.CallTrace)`
| `debug_traceCall` | `debug.TraceCall(msg *w3types.Message, blockNumber *big.Int, config *debug.TraceConfig).Returns(trace **debug.Trace)`<br/>`debug.CallTraceCall(msg *w3types.Message, blockNumber *big.Int, overrides w3types.State).Returns(trace **debug.CallTrace)`
| `debug_traceTransaction` | `debug.TraceTx(txHash common.Hash, config *debug.TraceConfig).Returns(trace **debug.Trace)`<br/>`debug.CallTraceTx(txHash common.Hash, overrides w3types.State).Returns(trace **debug.CallTrace)`

### [`txpool`](https://pkg.go.dev/github.com/lmittmann/w3/module/txpool)

| Method | Go Code
| :--------------------| :-------
| `txpool_content` | `txpool.Content().Returns(resp *txpool.ContentResponse)`
| `txpool_contentFrom` | `txpool.ContentFrom(addr common.Address).Returns(resp *txpool.ContentFromResponse)`
| `txpool_status` | `txpool.Status().Returns(resp *txpool.StatusResponse)`
| `txpool_content` | `txpool.Content().Returns(resp **txpool.ContentResponse)`
| `txpool_contentFrom` | `txpool.ContentFrom(addr common.Address).Returns(resp **txpool.ContentFromResponse)`
| `txpool_status` | `txpool.Status().Returns(resp **txpool.StatusResponse)`

### [`web3`](https://pkg.go.dev/github.com/lmittmann/w3/module/web3)

Expand Down
8 changes: 4 additions & 4 deletions examples/scan_blocks/main.go
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
scan_blocks interates over blocks with their transactions from a given start block.
scan_blocks iterates over blocks with their transactions from a given start block.

Usage:

Expand Down Expand Up @@ -37,7 +37,7 @@ func main() {
// parse flags
flag.Uint64Var(&startBlock, "start", 10_000_000, "Start block")
flag.Usage = func() {
fmt.Println("scan_blocks interates over blocks with their transactions from a given start block.")
fmt.Println("scan_blocks iterates over blocks with their transactions from a given start block.")
flag.PrintDefaults()
}
flag.Parse()
Expand All @@ -48,7 +48,7 @@ func main() {

// fetch blocks in bulk
calls := make([]w3types.RPCCaller, bulkSize)
blocks := make([]types.Block, bulkSize)
blocks := make([]*types.Block, bulkSize)

for i, txCount := 0, 0; ; i++ {
j := i % bulkSize
Expand All @@ -62,7 +62,7 @@ func main() {

for _, block := range blocks {
txCount += len(block.Transactions())
processBlock(&block)
processBlock(block)
}
fmt.Printf("\rFetched %d blocks with a total of %d transactions", i+1, txCount)
}
Expand Down
13 changes: 7 additions & 6 deletions internal/module/factory.go
Original file line number Diff line number Diff line change
Expand Up @@ -91,9 +91,10 @@ func WithRetWrapper[T any](fn RetWrapperFunc[T]) Option[T] {
}
}

var (
HexBigRetWrapper RetWrapperFunc[big.Int] = func(ret *big.Int) any { return (*hexutil.Big)(ret) }
HexUintRetWrapper RetWrapperFunc[uint] = func(ret *uint) any { return (*hexutil.Uint)(ret) }
HexUint64RetWrapper RetWrapperFunc[uint64] = func(ret *uint64) any { return (*hexutil.Uint64)(ret) }
HexBytesRetWrapper RetWrapperFunc[[]byte] = func(ret *[]byte) any { return (*hexutil.Bytes)(ret) }
)
func HexBigRetWrapper(ret **big.Int) any {
*ret = new(big.Int)
return (*hexutil.Big)(*ret)
}
func HexUintRetWrapper(ret *uint) any { return (*hexutil.Uint)(ret) }
func HexUint64RetWrapper(ret *uint64) any { return (*hexutil.Uint64)(ret) }
func HexBytesRetWrapper(ret *[]byte) any { return (*hexutil.Bytes)(ret) }
Loading