aboutsummaryrefslogtreecommitdiffstats
path: root/ethclient
diff options
context:
space:
mode:
authorFelix Lange <fjl@twurst.com>2016-11-29 22:54:06 +0800
committerFelix Lange <fjl@twurst.com>2016-12-05 17:57:11 +0800
commit3bc0fe1ee3183311efe851aca8fd10d5a5433929 (patch)
treeed6e33c3af93115e02e508f86b993a6bf64f5328 /ethclient
parentfa0cc274009670209fd71b1462dcdde3b431d64f (diff)
downloaddexon-3bc0fe1ee3183311efe851aca8fd10d5a5433929.tar
dexon-3bc0fe1ee3183311efe851aca8fd10d5a5433929.tar.gz
dexon-3bc0fe1ee3183311efe851aca8fd10d5a5433929.tar.bz2
dexon-3bc0fe1ee3183311efe851aca8fd10d5a5433929.tar.lz
dexon-3bc0fe1ee3183311efe851aca8fd10d5a5433929.tar.xz
dexon-3bc0fe1ee3183311efe851aca8fd10d5a5433929.tar.zst
dexon-3bc0fe1ee3183311efe851aca8fd10d5a5433929.zip
ethclient, ethereum: add NotFound, split transactions out of ChainReader
ethclient now returns ethereum.NotFound if the server returns null and no error while accessing blockchain data. The light client cannot provide arbitrary transactions. The change to split transaction access into its own interface emphasizes that transactions should not be relied on and recommends use of logs.
Diffstat (limited to 'ethclient')
-rw-r--r--ethclient/ethclient.go49
-rw-r--r--ethclient/ethclient_test.go2
2 files changed, 35 insertions, 16 deletions
diff --git a/ethclient/ethclient.go b/ethclient/ethclient.go
index b23e9baa3..4daebda92 100644
--- a/ethclient/ethclient.go
+++ b/ethclient/ethclient.go
@@ -81,6 +81,8 @@ func (ec *Client) getBlock(ctx context.Context, method string, args ...interface
err := ec.c.CallContext(ctx, &raw, method, args...)
if err != nil {
return nil, err
+ } else if len(raw) == 0 {
+ return nil, ethereum.NotFound
}
// Decode header and transactions.
var head *types.Header
@@ -135,6 +137,9 @@ func (ec *Client) getBlock(ctx context.Context, method string, args ...interface
func (ec *Client) HeaderByHash(ctx context.Context, hash common.Hash) (*types.Header, error) {
var head *types.Header
err := ec.c.CallContext(ctx, &head, "eth_getBlockByHash", hash, false)
+ if err == nil && head == nil {
+ err = ethereum.NotFound
+ }
return head, err
}
@@ -143,19 +148,31 @@ func (ec *Client) HeaderByHash(ctx context.Context, hash common.Hash) (*types.He
func (ec *Client) HeaderByNumber(ctx context.Context, number *big.Int) (*types.Header, error) {
var head *types.Header
err := ec.c.CallContext(ctx, &head, "eth_getBlockByNumber", toBlockNumArg(number), false)
+ if err == nil && head == nil {
+ err = ethereum.NotFound
+ }
return head, err
}
// TransactionByHash returns the transaction with the given hash.
-func (ec *Client) TransactionByHash(ctx context.Context, hash common.Hash) (*types.Transaction, error) {
- var tx *types.Transaction
- err := ec.c.CallContext(ctx, &tx, "eth_getTransactionByHash", hash)
- if err == nil {
- if _, r, _ := tx.RawSignatureValues(); r == nil {
- return nil, fmt.Errorf("server returned transaction without signature")
- }
+func (ec *Client) TransactionByHash(ctx context.Context, hash common.Hash) (tx *types.Transaction, isPending bool, err error) {
+ var raw json.RawMessage
+ err = ec.c.CallContext(ctx, &raw, "eth_getTransactionByHash", hash)
+ if err != nil {
+ return nil, false, err
+ } else if len(raw) == 0 {
+ return nil, false, ethereum.NotFound
}
- return tx, err
+ if err := json.Unmarshal(raw, tx); err != nil {
+ return nil, false, err
+ } else if _, r, _ := tx.RawSignatureValues(); r == nil {
+ return nil, false, fmt.Errorf("server returned transaction without signature")
+ }
+ var block struct{ BlockHash *common.Hash }
+ if err := json.Unmarshal(raw, &block); err != nil {
+ return nil, false, err
+ }
+ return tx, block.BlockHash == nil, nil
}
// TransactionCount returns the total number of transactions in the given block.
@@ -170,11 +187,9 @@ func (ec *Client) TransactionInBlock(ctx context.Context, blockHash common.Hash,
var tx *types.Transaction
err := ec.c.CallContext(ctx, &tx, "eth_getTransactionByBlockHashAndIndex", blockHash, index)
if err == nil {
- var signer types.Signer = types.HomesteadSigner{}
- if tx.Protected() {
- signer = types.NewEIP155Signer(tx.ChainId())
- }
- if _, r, _ := types.SignatureValues(signer, tx); r == nil {
+ if tx == nil {
+ return nil, ethereum.NotFound
+ } else if _, r, _ := tx.RawSignatureValues(); r == nil {
return nil, fmt.Errorf("server returned transaction without signature")
}
}
@@ -186,8 +201,12 @@ func (ec *Client) TransactionInBlock(ctx context.Context, blockHash common.Hash,
func (ec *Client) TransactionReceipt(ctx context.Context, txHash common.Hash) (*types.Receipt, error) {
var r *types.Receipt
err := ec.c.CallContext(ctx, &r, "eth_getTransactionReceipt", txHash)
- if err == nil && r != nil && len(r.PostState) == 0 {
- return nil, fmt.Errorf("server returned receipt without post state")
+ if err == nil {
+ if r == nil {
+ return nil, ethereum.NotFound
+ } else if len(r.PostState) == 0 {
+ return nil, fmt.Errorf("server returned receipt without post state")
+ }
}
return r, err
}
diff --git a/ethclient/ethclient_test.go b/ethclient/ethclient_test.go
index 102c0d3b2..178eb2be9 100644
--- a/ethclient/ethclient_test.go
+++ b/ethclient/ethclient_test.go
@@ -21,9 +21,9 @@ import "github.com/ethereum/go-ethereum"
// Verify that Client implements the ethereum interfaces.
var (
_ = ethereum.ChainReader(&Client{})
+ _ = ethereum.TransactionReader(&Client{})
_ = ethereum.ChainStateReader(&Client{})
_ = ethereum.ChainSyncReader(&Client{})
- _ = ethereum.ChainHeadEventer(&Client{})
_ = ethereum.ContractCaller(&Client{})
_ = ethereum.GasEstimator(&Client{})
_ = ethereum.GasPricer(&Client{})