mirror of
https://github.com/ethereum/go-ethereum.git
synced 2026-08-19 18:32:23 +00:00
ethclient/lightclient: implemented PendingNonceAt and PendingTransactionCount
This commit is contained in:
parent
ab8ca04b54
commit
5b05bb625d
2 changed files with 49 additions and 10 deletions
|
|
@ -223,7 +223,7 @@ func (c *Client) TransactionReceipt(ctx context.Context, txHash common.Hash) (*t
|
|||
return c.txAndReceipts.getReceiptByTxHash(ctx, txHash)
|
||||
}
|
||||
|
||||
// ChainStateReader interface {
|
||||
// ChainStateReader interface
|
||||
|
||||
func (c *Client) BalanceAt(ctx context.Context, account common.Address, blockNumber *big.Int) (*big.Int, error) {
|
||||
proof, _, err := c.state.getProof(ctx, blockNumber, account, nil, false)
|
||||
|
|
@ -234,7 +234,7 @@ func (c *Client) BalanceAt(ctx context.Context, account common.Address, blockNum
|
|||
}
|
||||
|
||||
func (c *Client) StorageAt(ctx context.Context, account common.Address, key common.Hash, blockNumber *big.Int) ([]byte, error) {
|
||||
proof, _, err := c.state.getProof(ctx, blockNumber, account, []string{key.Hex()}, false) //TODO hashed key?
|
||||
proof, _, err := c.state.getProof(ctx, blockNumber, account, []string{key.Hex()}, false)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
|
@ -265,13 +265,14 @@ func (c *Client) BlockReceipts(ctx context.Context, blockNrOrHash rpc.BlockNumbe
|
|||
return c.txAndReceipts.getBlockReceipts(ctx, hash)
|
||||
}
|
||||
|
||||
// TransactionSender interface {
|
||||
// TransactionSender interface
|
||||
|
||||
func (c *Client) SendTransaction(ctx context.Context, tx *types.Transaction) error {
|
||||
return c.txAndReceipts.sendTransaction(ctx, tx)
|
||||
//TODO
|
||||
}
|
||||
|
||||
// PendingStateReader interface {
|
||||
// PendingStateReader interface
|
||||
|
||||
func (c *Client) PendingBalanceAt(ctx context.Context, account common.Address) (*big.Int, error) {
|
||||
return c.BalanceAt(ctx, account, big.NewInt(int64(rpc.LatestBlockNumber)))
|
||||
//TODO subtract upper estimate for pending tx costs?
|
||||
|
|
@ -286,19 +287,47 @@ func (c *Client) PendingCodeAt(ctx context.Context, account common.Address) ([]b
|
|||
}
|
||||
|
||||
func (c *Client) PendingNonceAt(ctx context.Context, account common.Address) (uint64, error) {
|
||||
nonce, err := c.NonceAt(ctx, account, big.NewInt(int64(rpc.LatestBlockNumber)))
|
||||
head := c.canonicalChain.getHead()
|
||||
if head == nil {
|
||||
return 0, errors.New("chain head unknown")
|
||||
}
|
||||
headNonce, pendingTxs, err := c.txAndReceipts.nonceAndPendingTxs(ctx, head, account)
|
||||
if err != nil {
|
||||
return 0, err
|
||||
}
|
||||
//TODO
|
||||
return nonce, err
|
||||
if len(pendingTxs) == 0 {
|
||||
return headNonce, nil
|
||||
}
|
||||
return pendingTxs[len(pendingTxs)-1].Nonce(), nil
|
||||
}
|
||||
|
||||
func (c *Client) PendingTransactionCount(ctx context.Context) (uint, error) {
|
||||
return 0, nil //TODO
|
||||
head := c.canonicalChain.getHead()
|
||||
if head == nil {
|
||||
return 0, errors.New("chain head unknown")
|
||||
}
|
||||
allSenders := c.txAndReceipts.allSenders()
|
||||
countCh := make(chan uint, len(allSenders))
|
||||
errCh := make(chan error, len(allSenders))
|
||||
for _, sender := range allSenders {
|
||||
go func() {
|
||||
_, pendingTxs, err := c.txAndReceipts.nonceAndPendingTxs(ctx, head, sender)
|
||||
errCh <- err
|
||||
countCh <- uint(len(pendingTxs))
|
||||
}()
|
||||
}
|
||||
var count uint
|
||||
for range allSenders {
|
||||
if err := <-errCh; err != nil {
|
||||
return 0, err
|
||||
}
|
||||
count += <-countCh
|
||||
}
|
||||
return count, nil
|
||||
}
|
||||
|
||||
// BlockNumberReader interface {
|
||||
// BlockNumberReader interface
|
||||
|
||||
func (c *Client) BlockNumber(ctx context.Context) (uint64, error) {
|
||||
if head := c.canonicalChain.getHead(); head != nil {
|
||||
return head.BlockNumber(), nil
|
||||
|
|
|
|||
|
|
@ -333,6 +333,16 @@ func (t *txAndReceipts) discardOldTxs() {
|
|||
}
|
||||
}
|
||||
|
||||
func (t *txAndReceipts) allSenders() []common.Address {
|
||||
t.sentTxLock.Lock()
|
||||
allSenders := make([]common.Address, 0, len(t.sentTxs))
|
||||
for sender := range t.sentTxs {
|
||||
allSenders = append(allSenders, sender)
|
||||
}
|
||||
t.sentTxLock.Unlock()
|
||||
return allSenders
|
||||
}
|
||||
|
||||
func (t *txAndReceipts) nonceAndPendingTxs(ctx context.Context, head *btypes.ExecutionHeader, sender common.Address) (uint64, types.Transactions, error) {
|
||||
proof, err := t.lightState.fetchProof(ctx, proofRequest{blockNumber: head.BlockNumber(), address: sender, storageKeys: ""})
|
||||
if err != nil {
|
||||
|
|
|
|||
Loading…
Reference in a new issue