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.
This commit is contained in:
@ -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
|
||||
}
|
||||
|
Reference in New Issue
Block a user