Skip to content

Commit 3041530

Browse files
authored
Merge pull request ethereum#21 from quilt/aa-ethapi
Add AA Support to eth_sendTransaction
2 parents 810819a + 5fc0c1c commit 3041530

File tree

1 file changed

+83
-21
lines changed

1 file changed

+83
-21
lines changed

internal/ethapi/api.go

+83-21
Original file line numberDiff line numberDiff line change
@@ -1471,6 +1471,56 @@ func (args *SendTxArgs) setDefaults(ctx context.Context, b Backend) error {
14711471
return nil
14721472
}
14731473

1474+
// setDefaults is a helper function that fills in default values for unspecified AA tx fields.
1475+
func (args *SendTxArgs) setAADefaults(ctx context.Context, b Backend) error {
1476+
if args.GasPrice == nil {
1477+
args.GasPrice = new(hexutil.Big)
1478+
} else if args.GasPrice.ToInt().Sign() != 0 {
1479+
return errors.New(`"gasPrice" has to be 0 for account abstraction transactions`)
1480+
}
1481+
if args.Value == nil {
1482+
args.Value = new(hexutil.Big)
1483+
} else if args.Value.ToInt().Sign() != 0 {
1484+
return errors.New(`"value" has to be 0 for account abstraction transactions`)
1485+
}
1486+
if args.Nonce == nil {
1487+
args.Nonce = new(hexutil.Uint64)
1488+
} else if *args.Nonce != 0 {
1489+
return errors.New(`"nonce" has to be 0 for account abstraction transactions`)
1490+
}
1491+
1492+
if args.Data != nil && args.Input != nil && !bytes.Equal(*args.Data, *args.Input) {
1493+
return errors.New(`both "data" and "input" are set and not equal. Please use "input" to pass transaction call data`)
1494+
}
1495+
if args.To == nil {
1496+
return errors.New(`AA transactions require "to" address`)
1497+
}
1498+
// Estimate the gas usage if necessary.
1499+
if args.Gas == nil {
1500+
// For backwards-compatibility reason, we try both input and data
1501+
// but input is preferred.
1502+
input := args.Input
1503+
if input == nil {
1504+
input = args.Data
1505+
}
1506+
callArgs := CallArgs{
1507+
From: &args.From, // From shouldn't be nil
1508+
To: args.To,
1509+
GasPrice: args.GasPrice,
1510+
Value: args.Value,
1511+
Data: input,
1512+
}
1513+
pendingBlockNr := rpc.BlockNumberOrHashWithNumber(rpc.PendingBlockNumber)
1514+
estimated, err := DoEstimateGas(ctx, b, callArgs, pendingBlockNr, b.RPCGasCap())
1515+
if err != nil {
1516+
return err
1517+
}
1518+
args.Gas = &estimated
1519+
log.Trace("Estimate gas usage automatically", "gas", args.Gas)
1520+
}
1521+
return nil
1522+
}
1523+
14741524
func (args *SendTxArgs) toTransaction() *types.Transaction {
14751525
var input []byte
14761526
if args.Input != nil {
@@ -1506,32 +1556,44 @@ func SubmitTransaction(ctx context.Context, b Backend, tx *types.Transaction) (c
15061556
// SendTransaction creates a transaction for the given argument, sign it and submit it to the
15071557
// transaction pool.
15081558
func (s *PublicTransactionPoolAPI) SendTransaction(ctx context.Context, args SendTxArgs) (common.Hash, error) {
1509-
// Look up the wallet containing the requested signer
1510-
account := accounts.Account{Address: args.From}
1559+
var signed *types.Transaction
15111560

1512-
wallet, err := s.b.AccountManager().Find(account)
1513-
if err != nil {
1514-
return common.Hash{}, err
1515-
}
1561+
if args.From.IsEntryPoint() {
1562+
if err := args.setAADefaults(ctx, s.b); err != nil {
1563+
return common.Hash{}, err
1564+
}
1565+
// Assemble the transaction and add AA signature
1566+
tx := args.toTransaction()
1567+
signed = tx.WithAASignature()
1568+
} else {
1569+
// Look up the wallet containing the requested signer
1570+
account := accounts.Account{Address: args.From}
15161571

1517-
if args.Nonce == nil {
1518-
// Hold the addresse's mutex around signing to prevent concurrent assignment of
1519-
// the same nonce to multiple accounts.
1520-
s.nonceLock.LockAddr(args.From)
1521-
defer s.nonceLock.UnlockAddr(args.From)
1522-
}
1572+
wallet, err := s.b.AccountManager().Find(account)
1573+
if err != nil {
1574+
return common.Hash{}, err
1575+
}
15231576

1524-
// Set some sanity defaults and terminate on failure
1525-
if err := args.setDefaults(ctx, s.b); err != nil {
1526-
return common.Hash{}, err
1527-
}
1528-
// Assemble the transaction and sign with the wallet
1529-
tx := args.toTransaction()
1577+
if args.Nonce == nil {
1578+
// Hold the addresse's mutex around signing to prevent concurrent assignment of
1579+
// the same nonce to multiple accounts.
1580+
s.nonceLock.LockAddr(args.From)
1581+
defer s.nonceLock.UnlockAddr(args.From)
1582+
}
15301583

1531-
signed, err := wallet.SignTx(account, tx, s.b.ChainConfig().ChainID)
1532-
if err != nil {
1533-
return common.Hash{}, err
1584+
// Set some sanity defaults and terminate on failure
1585+
if err := args.setDefaults(ctx, s.b); err != nil {
1586+
return common.Hash{}, err
1587+
}
1588+
// Assemble the transaction and sign with the wallet
1589+
tx := args.toTransaction()
1590+
1591+
signed, err = wallet.SignTx(account, tx, s.b.ChainConfig().ChainID)
1592+
if err != nil {
1593+
return common.Hash{}, err
1594+
}
15341595
}
1596+
15351597
return SubmitTransaction(ctx, s.b, signed)
15361598
}
15371599

0 commit comments

Comments
 (0)