ethapi: refactor to minimize duplicate code

This commit is contained in:
Martin Holst Swende 2018-01-26 13:07:48 +01:00
parent b540bf6a0e
commit a2ccf4f526
No known key found for this signature in database
GPG key ID: 683B438C05A5DDF0

View file

@ -333,28 +333,19 @@ func (s *PrivateAccountAPI) LockAccount(addr common.Address) bool {
return fetchKeystore(s.am).Lock(addr) == nil return fetchKeystore(s.am).Lock(addr) == nil
} }
// SendTransaction will create a transaction from the given arguments and // signTransactions sets defaults and signs the given transation
// tries to sign it with the key associated with args.To. If the given passwd isn't // NOTE: the caller needs to ensure that the nonceLock is held, if applicable,
// able to decrypt the key it fails. // and release it after the transaction has been submitted to the tx pool
func (s *PrivateAccountAPI) SendTransaction(ctx context.Context, args SendTxArgs, passwd string) (common.Hash, error) { func (s *PrivateAccountAPI) signTransaction(ctx context.Context, args SendTxArgs, passwd string) (*types.Transaction, error) {
// Look up the wallet containing the requested signer // Look up the wallet containing the requested signer
account := accounts.Account{Address: args.From} account := accounts.Account{Address: args.From}
wallet, err := s.am.Find(account) wallet, err := s.am.Find(account)
if err != nil { if err != nil {
return common.Hash{}, err return nil, err
} }
if args.Nonce == nil {
// Hold the addresse's mutex around signing to prevent concurrent assignment of
// the same nonce to multiple accounts.
s.nonceLock.LockAddr(args.From)
defer s.nonceLock.UnlockAddr(args.From)
}
// Set some sanity defaults and terminate on failure // Set some sanity defaults and terminate on failure
if err := args.setDefaults(ctx, s.b); err != nil { if err := args.setDefaults(ctx, s.b); err != nil {
return common.Hash{}, err return nil, err
} }
// Assemble the transaction and sign with the wallet // Assemble the transaction and sign with the wallet
tx := args.toTransaction() tx := args.toTransaction()
@ -363,7 +354,20 @@ func (s *PrivateAccountAPI) SendTransaction(ctx context.Context, args SendTxArgs
if config := s.b.ChainConfig(); config.IsEIP155(s.b.CurrentBlock().Number()) { if config := s.b.ChainConfig(); config.IsEIP155(s.b.CurrentBlock().Number()) {
chainID = config.ChainId chainID = config.ChainId
} }
signed, err := wallet.SignTxWithPassphrase(account, passwd, tx, chainID) return wallet.SignTxWithPassphrase(account, passwd, tx, chainID)
}
// SendTransaction will create a transaction from the given arguments and
// tries to sign it with the key associated with args.To. If the given passwd isn't
// able to decrypt the key it fails.
func (s *PrivateAccountAPI) SendTransaction(ctx context.Context, args SendTxArgs, passwd string) (common.Hash, error) {
if args.Nonce == nil {
// Hold the addresse's mutex around signing to prevent concurrent assignment of
// the same nonce to multiple accounts.
s.nonceLock.LockAddr(args.From)
defer s.nonceLock.UnlockAddr(args.From)
}
signed, err := s.signTransaction(ctx, args, passwd)
if err != nil { if err != nil {
return common.Hash{}, err return common.Hash{}, err
} }
@ -375,39 +379,17 @@ func (s *PrivateAccountAPI) SendTransaction(ctx context.Context, args SendTxArgs
// able to decrypt the key it fails. The transaction is returned in RLP-form, not broadcast // able to decrypt the key it fails. The transaction is returned in RLP-form, not broadcast
// to other nodes // to other nodes
func (s *PrivateAccountAPI) SignTransaction(ctx context.Context, args SendTxArgs, passwd string) (*SignTransactionResult, error) { func (s *PrivateAccountAPI) SignTransaction(ctx context.Context, args SendTxArgs, passwd string) (*SignTransactionResult, error) {
// Look up the wallet containing the requested signer // No need to obtain the noncelock mutex, since we won't be sending this
account := accounts.Account{Address: args.From} // tx into the transaction pool, but right back to the user
signed, err := s.signTransaction(ctx, args, passwd)
wallet, err := s.am.Find(account)
if err != nil { if err != nil {
return nil, err return nil, err
} }
if args.Nonce == nil { data, err := rlp.EncodeToBytes(signed)
// Hold the addresse's mutex around signing to prevent concurrent assignment of
// the same nonce to multiple accounts.
s.nonceLock.LockAddr(args.From)
defer s.nonceLock.UnlockAddr(args.From)
}
// Set some sanity defaults and terminate on failure
if err := args.setDefaults(ctx, s.b); err != nil {
return nil, err
}
// Assemble the transaction and sign with the wallet
tx := args.toTransaction()
var chainID *big.Int
if config := s.b.ChainConfig(); config.IsEIP155(s.b.CurrentBlock().Number()) {
chainID = config.ChainId
}
tx, err = wallet.SignTxWithPassphrase(account, passwd, tx, chainID)
if err != nil { if err != nil {
return nil, err return nil, err
} }
data, err := rlp.EncodeToBytes(tx) return &SignTransactionResult{data, signed}, nil
if err != nil {
return nil, err
}
return &SignTransactionResult{data, tx}, nil
} }
// signHash is a helper function that calculates a hash for the given message that can be // signHash is a helper function that calculates a hash for the given message that can be