Skip to content

feat: add EIP-7702 #1112

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 41 commits into from
Feb 25, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
41 commits
Select commit Hold shift + click to select a range
8c459ec
feat: add EIP-7702
colinlyguo Feb 6, 2025
85a8482
fix goimport
colinlyguo Feb 10, 2025
f3dfc7a
add unit tests
colinlyguo Feb 11, 2025
74b01b2
add api test
colinlyguo Feb 11, 2025
e8cff42
sync txpool update
colinlyguo Feb 12, 2025
0d0511b
update generated code
colinlyguo Feb 12, 2025
49ce6e2
make code readable
colinlyguo Feb 12, 2025
9dddd1d
fix goimport
colinlyguo Feb 12, 2025
197739d
fix TestAsyncChecker unit test
colinlyguo Feb 12, 2025
40ef7c7
add AuthorizationList in fuzz tests for completeness sake
colinlyguo Feb 12, 2025
1eac54c
add EuclidV2 test, EIP-7702 transaction in TestT8n
colinlyguo Feb 12, 2025
cdc301f
clean up logs
colinlyguo Feb 12, 2025
70419dd
bump version
colinlyguo Feb 12, 2025
5257971
Merge branch 'develop' into add-eip-7702
colinlyguo Feb 13, 2025
9a7229d
fix TestAsyncChecker
colinlyguo Feb 13, 2025
08cc2f9
Revert "fix TestAsyncChecker"
colinlyguo Feb 13, 2025
f0e54b8
accept eip-7702 txns only after enabling eip-7702
colinlyguo Feb 13, 2025
233a56f
revert IntrinsicGas param name from setCodeAuthorizations to authList
colinlyguo Feb 13, 2025
7c2d9f4
fix a bug
colinlyguo Feb 13, 2025
9e70b14
align upstream implementation in Encoding Receipts
colinlyguo Feb 13, 2025
2dc0756
fix one test case
colinlyguo Feb 13, 2025
15e71c9
Merge branch 'develop' into add-eip-7702
colinlyguo Feb 14, 2025
3611717
fix tracer
colinlyguo Feb 16, 2025
51d6ec8
return precode copy
colinlyguo Feb 17, 2025
028347e
support setcode tx in EstimateGas and add unit tests
colinlyguo Feb 17, 2025
6d29693
add TestValidateAuthorizations
colinlyguo Feb 18, 2025
2273e77
poseidon hash fix
colinlyguo Feb 19, 2025
23bd703
migrate a fix before the fix pr is merged
colinlyguo Feb 20, 2025
2dde0c7
support setcode type transactions in TransactionData
colinlyguo Feb 20, 2025
431adc1
Merge branch 'develop' into add-eip-7702
colinlyguo Feb 21, 2025
65d164e
chore: auto version bump [bot]
colinlyguo Feb 21, 2025
3af3735
add a nonce-gapped-auth-does-not-block-pending-tx unit test
colinlyguo Feb 24, 2025
482194f
make the auth invalid
colinlyguo Feb 24, 2025
2340de4
Apply suggestions from code review
Thegaram Feb 25, 2025
6665460
change usedAndLeftSlots and knownConflicts to util functions
colinlyguo Feb 25, 2025
06e22a1
add comments about different return of applyAuthorization
colinlyguo Feb 25, 2025
1fa9c8c
remove gencodec:required in transaction signatures
colinlyguo Feb 25, 2025
8648d68
fix goimport
colinlyguo Feb 25, 2025
eeafee4
update StructLogger and AccessListTracer
colinlyguo Feb 25, 2025
4c3385d
fix a bug
colinlyguo Feb 25, 2025
1a3942d
fix flaky test
Thegaram Feb 25, 2025
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,11 @@ test: all
$(GORUN) build/ci.go test ./consensus ./core ./eth ./miner ./node ./trie ./rollup/...
# RIP-7212 (secp256r1) precompiled contract test
cd ${PWD}/core/vm; go test -v -run=^TestPrecompiledP256 -bench=^BenchmarkPrecompiledP256
# EIP-7702 test
cd ${PWD}/core/vm/runtime; go test -v -run=^TestDelegatedAccountAccessCost
cd ${PWD}/core/types; go test -v -run=^TestParseDelegation
cd ${PWD}/internal/ethapi; go test -v -run=^TestEstimateGas
cd ${PWD}/cmd/evm; go test -v -run=^TestT8n

lint: ## Run linters.
$(GORUN) build/ci.go lint
Expand Down
31 changes: 16 additions & 15 deletions accounts/abi/bind/backends/simulated.go
Original file line number Diff line number Diff line change
Expand Up @@ -639,7 +639,7 @@ func (b *SimulatedBackend) callContract(ctx context.Context, call ethereum.CallM
// about the transaction and calling mechanisms.
vmEnv := vm.NewEVM(evmContext, txContext, stateDB, b.config, vm.Config{NoBaseFee: true})
gasPool := new(core.GasPool).AddGas(math.MaxUint64)
signer := types.MakeSigner(b.blockchain.Config(), head.Number)
signer := types.MakeSigner(b.blockchain.Config(), head.Number, head.Time)
l1DataFee, err := fees.EstimateL1DataFeeForMessage(msg, head.BaseFee, b.blockchain.Config(), signer, stateDB, head.Number)
if err != nil {
return nil, err
Expand All @@ -660,7 +660,7 @@ func (b *SimulatedBackend) SendTransaction(ctx context.Context, tx *types.Transa
panic("could not fetch parent")
}
// Check transaction validity
signer := types.MakeSigner(b.blockchain.Config(), block.Number())
signer := types.MakeSigner(b.blockchain.Config(), block.Number(), block.Time())
sender, err := types.Sender(signer, tx)
if err != nil {
panic(fmt.Errorf("invalid transaction: %v", err))
Expand Down Expand Up @@ -809,19 +809,20 @@ type callMsg struct {
ethereum.CallMsg
}

func (m callMsg) From() common.Address { return m.CallMsg.From }
func (m callMsg) Nonce() uint64 { return 0 }
func (m callMsg) IsFake() bool { return true }
func (m callMsg) To() *common.Address { return m.CallMsg.To }
func (m callMsg) GasPrice() *big.Int { return m.CallMsg.GasPrice }
func (m callMsg) GasFeeCap() *big.Int { return m.CallMsg.GasFeeCap }
func (m callMsg) GasTipCap() *big.Int { return m.CallMsg.GasTipCap }
func (m callMsg) Gas() uint64 { return m.CallMsg.Gas }
func (m callMsg) Value() *big.Int { return m.CallMsg.Value }
func (m callMsg) Data() []byte { return m.CallMsg.Data }
func (m callMsg) AccessList() types.AccessList { return m.CallMsg.AccessList }
func (m callMsg) IsL1MessageTx() bool { return false }
func (m callMsg) TxSize() common.StorageSize { return 0 }
func (m callMsg) From() common.Address { return m.CallMsg.From }
func (m callMsg) Nonce() uint64 { return 0 }
func (m callMsg) IsFake() bool { return true }
func (m callMsg) To() *common.Address { return m.CallMsg.To }
func (m callMsg) GasPrice() *big.Int { return m.CallMsg.GasPrice }
func (m callMsg) GasFeeCap() *big.Int { return m.CallMsg.GasFeeCap }
func (m callMsg) GasTipCap() *big.Int { return m.CallMsg.GasTipCap }
func (m callMsg) Gas() uint64 { return m.CallMsg.Gas }
func (m callMsg) Value() *big.Int { return m.CallMsg.Value }
func (m callMsg) Data() []byte { return m.CallMsg.Data }
func (m callMsg) AccessList() types.AccessList { return m.CallMsg.AccessList }
func (m callMsg) IsL1MessageTx() bool { return false }
func (m callMsg) TxSize() common.StorageSize { return 0 }
func (m callMsg) SetCodeAuthorizations() []types.SetCodeAuthorization { return nil }

// filterBackend implements filters.Backend to support filtering for logs without
// taking bloom-bits acceleration structures into account.
Expand Down
2 changes: 1 addition & 1 deletion accounts/external/backend.go
Original file line number Diff line number Diff line change
Expand Up @@ -218,7 +218,7 @@ func (api *ExternalSigner) SignTx(account accounts.Account, tx *types.Transactio
switch tx.Type() {
case types.LegacyTxType, types.AccessListTxType:
args.GasPrice = (*hexutil.Big)(tx.GasPrice())
case types.DynamicFeeTxType:
case types.DynamicFeeTxType, types.SetCodeTxType:
args.MaxFeePerGas = (*hexutil.Big)(tx.GasFeeCap())
args.MaxPriorityFeePerGas = (*hexutil.Big)(tx.GasTipCap())
default:
Expand Down
2 changes: 1 addition & 1 deletion cmd/evm/internal/t8ntool/execution.go
Original file line number Diff line number Diff line change
Expand Up @@ -117,7 +117,7 @@ func (pre *Prestate) Apply(vmConfig vm.Config, chainConfig *params.ChainConfig,
}
var (
statedb = MakePreState(rawdb.NewMemoryDatabase(), pre.Pre)
signer = types.MakeSigner(chainConfig, new(big.Int).SetUint64(pre.Env.Number))
signer = types.MakeSigner(chainConfig, new(big.Int).SetUint64(pre.Env.Number), pre.Env.Timestamp)
gaspool = new(core.GasPool)
blockHash = common.Hash{0x13, 0x37}
rejectedTxs []*rejectedTx
Expand Down
4 changes: 2 additions & 2 deletions cmd/evm/internal/t8ntool/transaction.go
Original file line number Diff line number Diff line change
Expand Up @@ -113,7 +113,7 @@ func Transaction(ctx *cli.Context) error {
return NewError(ErrorIO, errors.New("only rlp supported"))
}
}
signer := types.MakeSigner(chainConfig, new(big.Int))
signer := types.MakeSigner(chainConfig, new(big.Int), 0)
// We now have the transactions in 'body', which is supposed to be an
// rlp list of transactions
it, err := rlp.NewListIterator([]byte(body))
Expand All @@ -140,7 +140,7 @@ func Transaction(ctx *cli.Context) error {
r.Address = sender
}
// Check intrinsic gas
if gas, err := core.IntrinsicGas(tx.Data(), tx.AccessList(), tx.To() == nil,
if gas, err := core.IntrinsicGas(tx.Data(), tx.AccessList(), tx.SetCodeAuthorizations(), tx.To() == nil,
chainConfig.IsHomestead(new(big.Int)), chainConfig.IsIstanbul(new(big.Int)), chainConfig.IsShanghai(new(big.Int))); err != nil {
r.Error = err
results = append(results, r)
Expand Down
2 changes: 1 addition & 1 deletion cmd/evm/internal/t8ntool/transition.go
Original file line number Diff line number Diff line change
Expand Up @@ -241,7 +241,7 @@ func Transition(ctx *cli.Context) error {
}
}
// We may have to sign the transactions.
signer := types.MakeSigner(chainConfig, big.NewInt(int64(prestate.Env.Number)))
signer := types.MakeSigner(chainConfig, big.NewInt(int64(prestate.Env.Number)), prestate.Env.Timestamp)

if txs, err = signUnsignedTransactions(txsWithKeys, signer); err != nil {
return NewError(ErrorJson, fmt.Errorf("failed signing transactions: %v", err))
Expand Down
24 changes: 16 additions & 8 deletions cmd/evm/t8n_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -124,14 +124,14 @@ func TestT8n(t *testing.T) {
output: t8nOutput{alloc: true, result: true},
expOut: "exp.json",
},
{ // missing blockhash test
base: "./testdata/4",
input: t8nInput{
"alloc.json", "txs.json", "env.json", "Berlin", "",
},
output: t8nOutput{alloc: true, result: true},
expExitCode: 4,
},
//{ // missing blockhash test
// base: "./testdata/4",
// input: t8nInput{
// "alloc.json", "txs.json", "env.json", "Berlin", "",
// },
// output: t8nOutput{alloc: true, result: true},
// expExitCode: 4,
//},
{ // Uncle test
base: "./testdata/5",
input: t8nInput{
Expand Down Expand Up @@ -204,6 +204,14 @@ func TestT8n(t *testing.T) {
output: t8nOutput{result: true},
expOut: "exp.json",
},
{ // EuclidV2 test, EIP-7702 transaction
base: "./testdata/33",
input: t8nInput{
"alloc.json", "txs.json", "env.json", "EuclidV2", "",
},
output: t8nOutput{alloc: true, result: true},
expOut: "exp.json",
},
} {

args := []string{"t8n"}
Expand Down
1 change: 1 addition & 0 deletions cmd/evm/testdata/33/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
This test sets some EIP-7702 delegations and calls them.
30 changes: 30 additions & 0 deletions cmd/evm/testdata/33/alloc.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
{
"0x8a0a19589531694250d570040a0c4b74576919b8": {
"nonce": "0x00",
"balance": "0x0de0b6b3a7640000",
"code": "0x600060006000600060007310000000000000000000000000000000000000015af1600155600060006000600060007310000000000000000000000000000000000000025af16002553d600060003e600051600355",
"storage": {
"0x01": "0x0100",
"0x02": "0x0100",
"0x03": "0x0100"
}
},
"0x000000000000000000000000000000000000aaaa": {
"nonce": "0x00",
"balance": "0x4563918244f40000",
"code": "0x58808080600173703c4b2bd70c169f5717101caee543299fc946c75af100",
"storage": {}
},
"0x000000000000000000000000000000000000bbbb": {
"nonce": "0x00",
"balance": "0x29a2241af62c0000",
"code": "0x6042805500",
"storage": {}
},
"0x71562b71999873DB5b286dF957af199Ec94617F7": {
"nonce": "0x00",
"balance": "0x6124fee993bc0000",
"code": "0x",
"storage": {}
}
}
14 changes: 14 additions & 0 deletions cmd/evm/testdata/33/env.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
{
"currentCoinbase": "0x2adc25665018aa1fe0e6bc666dac8fc2697ff9ba",
"currentGasLimit": "71794957647893862",
"currentNumber": "1",
"currentTimestamp": "1000",
"currentRandom": "0",
"currentDifficulty": "0",
"blockHashes": {},
"ommers": [],
"currentBaseFee": "7",
"parentUncleHash": "0x0000000000000000000000000000000000000000000000000000000000000000",
"withdrawals": [],
"parentBeaconBlockRoot": "0x0000000000000000000000000000000000000000000000000000000000000000"
}
57 changes: 57 additions & 0 deletions cmd/evm/testdata/33/exp.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
{
"alloc": {
"0x000000000000000000000000000000000000aaaa": {
"code": "0x58808080600173703c4b2bd70c169f5717101caee543299fc946c75af100",
"balance": "0x4563918244f40000"
},
"0x000000000000000000000000000000000000bbbb": {
"code": "0x6042805500",
"balance": "0x29a2241af62c0000"
},
"0x2adc25665018aa1fe0e6bc666dac8fc2697ff9ba": {
"balance": "0x2bf52"
},
"0x703c4b2bd70c169f5717101caee543299fc946c7": {
"code": "0xef0100000000000000000000000000000000000000bbbb",
"storage": {
"0x0000000000000000000000000000000000000000000000000000000000000042": "0x0000000000000000000000000000000000000000000000000000000000000042"
},
"balance": "0x1",
"nonce": "0x1"
},
"0x71562b71999873db5b286df957af199ec94617f7": {
"code": "0xef0100000000000000000000000000000000000000aaaa",
"balance": "0x6124fee993afa30e",
"nonce": "0x2"
},
"0x8a0a19589531694250d570040a0c4b74576919b8": {
"code": "0x600060006000600060007310000000000000000000000000000000000000015af1600155600060006000600060007310000000000000000000000000000000000000025af16002553d600060003e600051600355",
"storage": {
"0x0000000000000000000000000000000000000000000000000000000000000001": "0x0000000000000000000000000000000000000000000000000000000000000100",
"0x0000000000000000000000000000000000000000000000000000000000000002": "0x0000000000000000000000000000000000000000000000000000000000000100",
"0x0000000000000000000000000000000000000000000000000000000000000003": "0x0000000000000000000000000000000000000000000000000000000000000100"
},
"balance": "0xde0b6b3a7640000"
}
},
"result": {
"stateRoot": "0x9fdcacd4510e93c4488e537dc51578b5c6d505771db64a2610036eeb4be7b26f",
"txRoot": "0x5d13a0b074e80388dc754da92b22922313a63417b3e25a10f324935e09697a53",
"receiptsRoot": "0x504c5d86c34391f70d210e6c482615b391db4bdb9f43479366399d9c5599850a",
"logsHash": "0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347",
"logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000","receipts": [{
"type": "0x4",
"root": "0x",
"status": "0x1",
"cumulativeGasUsed": "0x15fa9",
"logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000","logs": null,"transactionHash": "0x0417aab7c1d8a3989190c3167c132876ce9b8afd99262c5a0f9d06802de3d7ef",
"contractAddress": "0x0000000000000000000000000000000000000000",
"gasUsed": "0x15fa9",
"blockHash": "0x0000000000000000000000000000000000000000000000000000000000000000",
"transactionIndex": "0x0"
}
],
"currentDifficulty": "0x0",
"gasUsed": "0x15fa9"
}
}
37 changes: 37 additions & 0 deletions cmd/evm/testdata/33/txs.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
[
{
"type": "0x4",
"chainId": "0x1",
"nonce": "0x0",
"to": "0x71562b71999873db5b286df957af199ec94617f7",
"gas": "0x7a120",
"gasPrice": null,
"maxPriorityFeePerGas": "0x2",
"maxFeePerGas": "0x12a05f200",
"value": "0x0",
"input": "0x",
"accessList": [],
"authorizationList": [
{
"chainId": "0x1",
"address": "0x000000000000000000000000000000000000aaaa",
"nonce": "0x1",
"yParity": "0x1",
"r": "0xf7e3e597fc097e71ed6c26b14b25e5395bc8510d58b9136af439e12715f2d721",
"s": "0x6cf7c3d7939bfdb784373effc0ebb0bd7549691a513f395e3cdabf8602724987"
},
{
"chainId": "0x0",
"address": "0x000000000000000000000000000000000000bbbb",
"nonce": "0x0",
"yParity": "0x1",
"r": "0x5011890f198f0356a887b0779bde5afa1ed04e6acb1e3f37f8f18c7b6f521b98",
"s": "0x56c3fa3456b103f3ef4a0acb4b647b9cab9ec4bc68fbcdf1e10b49fb2bcbcf61"
}
],
"secretKey": "0xb71c71a67e1177ad4e901695e1b4b9ee17ae16c6668d313eac2f96dbcda3f291",
"v": "0x0",
"r": "0x0",
"s": "0x0"
}
]
45 changes: 45 additions & 0 deletions common/hexutil/json.go
Original file line number Diff line number Diff line change
Expand Up @@ -23,13 +23,16 @@ import (
"math/big"
"reflect"
"strconv"

"github.com/holiman/uint256"
)

var (
bytesT = reflect.TypeOf(Bytes(nil))
bigT = reflect.TypeOf((*Big)(nil))
uintT = reflect.TypeOf(Uint(0))
uint64T = reflect.TypeOf(Uint64(0))
u256T = reflect.TypeOf((*uint256.Int)(nil))
)

// Bytes marshals/unmarshals as a JSON string with 0x prefix.
Expand Down Expand Up @@ -225,6 +228,48 @@ func (b *Big) UnmarshalGraphQL(input interface{}) error {
return err
}

// U256 marshals/unmarshals as a JSON string with 0x prefix.
// The zero value marshals as "0x0".
type U256 uint256.Int

// MarshalText implements encoding.TextMarshaler
func (b U256) MarshalText() ([]byte, error) {
u256 := (*uint256.Int)(&b)
return []byte(u256.Hex()), nil
}

// UnmarshalJSON implements json.Unmarshaler.
func (b *U256) UnmarshalJSON(input []byte) error {
// The uint256.Int.UnmarshalJSON method accepts "dec", "0xhex"; we must be
// more strict, hence we check string and invoke SetFromHex directly.
if !isString(input) {
return errNonString(u256T)
}
// The hex decoder needs to accept empty string ("") as '0', which uint256.Int
// would reject.
if len(input) == 2 {
(*uint256.Int)(b).Clear()
return nil
}
err := (*uint256.Int)(b).SetFromHex(string(input[1 : len(input)-1]))
if err != nil {
return &json.UnmarshalTypeError{Value: err.Error(), Type: u256T}
}
return nil
}

// UnmarshalText implements encoding.TextUnmarshaler
func (b *U256) UnmarshalText(input []byte) error {
// The uint256.Int.UnmarshalText method accepts "dec", "0xhex"; we must be
// more strict, hence we check string and invoke SetFromHex directly.
return (*uint256.Int)(b).SetFromHex(string(input))
}

// String returns the hex encoding of b.
func (b *U256) String() string {
return (*uint256.Int)(b).Hex()
}

// Uint64 marshals/unmarshals as a JSON string with 0x prefix.
// The zero value marshals as "0x0".
type Uint64 uint64
Expand Down
6 changes: 3 additions & 3 deletions core/bench_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -85,8 +85,8 @@ func genValueTx(nbytes int) func(int, *BlockGen) {
return func(i int, gen *BlockGen) {
toaddr := common.Address{}
data := make([]byte, nbytes)
gas, _ := IntrinsicGas(data, nil, false, false, false, false)
signer := types.MakeSigner(gen.config, big.NewInt(int64(i)))
gas, _ := IntrinsicGas(data, nil, nil, false, false, false, false)
signer := types.MakeSigner(gen.config, big.NewInt(int64(i)), 0 /* block time */)
gasPrice := big.NewInt(0)
if gen.header.BaseFee != nil {
gasPrice = gen.header.BaseFee
Expand Down Expand Up @@ -130,7 +130,7 @@ func genTxRing(naccounts int) func(int, *BlockGen) {
if gen.header.BaseFee != nil {
gasPrice = gen.header.BaseFee
}
signer := types.MakeSigner(gen.config, big.NewInt(int64(i)))
signer := types.MakeSigner(gen.config, big.NewInt(int64(i)), 0 /* block time */)
for {
gas -= params.TxGas
if gas < params.TxGas {
Expand Down
2 changes: 1 addition & 1 deletion core/blockchain.go
Original file line number Diff line number Diff line change
Expand Up @@ -1507,7 +1507,7 @@ func (bc *BlockChain) insertChain(chain types.Blocks, verifySeals bool) (int, er
}

// Start a parallel signature recovery (signer will fluke on fork transition, minimal perf loss)
senderCacher.recoverFromBlocks(types.MakeSigner(bc.chainConfig, chain[0].Number()), chain)
senderCacher.recoverFromBlocks(types.MakeSigner(bc.chainConfig, chain[0].Number(), chain[0].Time()), chain)

var (
stats = insertStats{startTime: mclock.Now()}
Expand Down
Loading
Loading