sign blob tx test case

This commit is contained in:
Sina Mahmoodi 2024-01-10 14:21:09 +03:30
parent 28516b0314
commit 838c78d018
2 changed files with 90 additions and 4 deletions

View file

@ -17,6 +17,7 @@
package ethapi package ethapi
import ( import (
"bytes"
"context" "context"
"crypto/ecdsa" "crypto/ecdsa"
"encoding/json" "encoding/json"
@ -31,6 +32,7 @@ import (
"github.com/ethereum/go-ethereum" "github.com/ethereum/go-ethereum"
"github.com/ethereum/go-ethereum/accounts" "github.com/ethereum/go-ethereum/accounts"
"github.com/ethereum/go-ethereum/accounts/keystore"
"github.com/ethereum/go-ethereum/common" "github.com/ethereum/go-ethereum/common"
"github.com/ethereum/go-ethereum/common/hexutil" "github.com/ethereum/go-ethereum/common/hexutil"
"github.com/ethereum/go-ethereum/consensus" "github.com/ethereum/go-ethereum/consensus"
@ -403,10 +405,30 @@ func allBlobTxs(addr common.Address, config *params.ChainConfig) []txData {
} }
} }
func newTestAccountManager(t *testing.T) (*accounts.Manager, accounts.Account) {
var (
dir = t.TempDir()
am = accounts.NewManager(&accounts.Config{InsecureUnlockAllowed: true})
b = keystore.NewKeyStore(dir, 2, 1)
testKey, _ = crypto.HexToECDSA("b71c71a67e1177ad4e901695e1b4b9ee17ae16c6668d313eac2f96dbcda3f291")
)
acc, err := b.ImportECDSA(testKey, "")
if err != nil {
t.Fatalf("failed to create test account: %v", err)
}
if err := b.Unlock(acc, ""); err != nil {
t.Fatalf("failed to unlock account: %v\n", err)
}
am.AddBackend(b)
return am, acc
}
type testBackend struct { type testBackend struct {
db ethdb.Database db ethdb.Database
chain *core.BlockChain chain *core.BlockChain
pending *types.Block pending *types.Block
accman *accounts.Manager
acc accounts.Account
} }
func newTestBackend(t *testing.T, n int, gspec *core.Genesis, engine consensus.Engine, generator func(i int, b *core.BlockGen)) *testBackend { func newTestBackend(t *testing.T, n int, gspec *core.Genesis, engine consensus.Engine, generator func(i int, b *core.BlockGen)) *testBackend {
@ -419,6 +441,8 @@ func newTestBackend(t *testing.T, n int, gspec *core.Genesis, engine consensus.E
TrieDirtyDisabled: true, // Archive mode TrieDirtyDisabled: true, // Archive mode
} }
) )
accman, acc := newTestAccountManager(t)
gspec.Alloc[acc.Address] = core.GenesisAccount{Balance: big.NewInt(params.Ether)}
// Generate blocks for testing // Generate blocks for testing
db, blocks, _ := core.GenerateChainWithGenesis(gspec, engine, n, generator) db, blocks, _ := core.GenerateChainWithGenesis(gspec, engine, n, generator)
txlookupLimit := uint64(0) txlookupLimit := uint64(0)
@ -430,7 +454,7 @@ func newTestBackend(t *testing.T, n int, gspec *core.Genesis, engine consensus.E
t.Fatalf("block %d: failed to insert into chain: %v", n, err) t.Fatalf("block %d: failed to insert into chain: %v", n, err)
} }
backend := &testBackend{db: db, chain: chain} backend := &testBackend{db: db, chain: chain, accman: accman, acc: acc}
return backend return backend
} }
@ -446,7 +470,7 @@ func (b testBackend) FeeHistory(ctx context.Context, blockCount uint64, lastBloc
return nil, nil, nil, nil, nil return nil, nil, nil, nil, nil
} }
func (b testBackend) ChainDb() ethdb.Database { return b.db } func (b testBackend) ChainDb() ethdb.Database { return b.db }
func (b testBackend) AccountManager() *accounts.Manager { return nil } func (b testBackend) AccountManager() *accounts.Manager { return b.accman }
func (b testBackend) ExtRPCEnabled() bool { return false } func (b testBackend) ExtRPCEnabled() bool { return false }
func (b testBackend) RPCGasCap() uint64 { return 10000000 } func (b testBackend) RPCGasCap() uint64 { return 10000000 }
func (b testBackend) RPCEVMTimeout() time.Duration { return time.Second } func (b testBackend) RPCEVMTimeout() time.Duration { return time.Second }
@ -566,7 +590,7 @@ func (b testBackend) GetTransaction(ctx context.Context, txHash common.Hash) (*t
func (b testBackend) GetPoolTransactions() (types.Transactions, error) { panic("implement me") } func (b testBackend) GetPoolTransactions() (types.Transactions, error) { panic("implement me") }
func (b testBackend) GetPoolTransaction(txHash common.Hash) *types.Transaction { panic("implement me") } func (b testBackend) GetPoolTransaction(txHash common.Hash) *types.Transaction { panic("implement me") }
func (b testBackend) GetPoolNonce(ctx context.Context, addr common.Address) (uint64, error) { func (b testBackend) GetPoolNonce(ctx context.Context, addr common.Address) (uint64, error) {
panic("implement me") return 0, nil
} }
func (b testBackend) Stats() (pending int, queued int) { panic("implement me") } func (b testBackend) Stats() (pending int, queued int) { panic("implement me") }
func (b testBackend) TxPoolContent() (map[common.Address][]*types.Transaction, map[common.Address][]*types.Transaction) { func (b testBackend) TxPoolContent() (map[common.Address][]*types.Transaction, map[common.Address][]*types.Transaction) {
@ -937,6 +961,68 @@ func TestCall(t *testing.T) {
} }
} }
func TestSignBlobTransaction(t *testing.T) {
t.Parallel()
// Initialize test accounts
var (
key, _ = crypto.HexToECDSA("8a1f9a8f95be41cd7ccb6168179afb4504aefe388d1e14474d32c45c72ce7b7a")
to = crypto.PubkeyToAddress(key.PublicKey)
genesis = &core.Genesis{
Config: params.MergedTestChainConfig,
Alloc: core.GenesisAlloc{},
}
)
b := newTestBackend(t, 1, genesis, beacon.New(ethash.NewFaker()), func(i int, b *core.BlockGen) {
b.SetPoS()
})
api := NewTransactionAPI(b, nil)
res, err := api.FillTransaction(context.Background(), TransactionArgs{
From: &b.acc.Address,
To: &to,
Value: (*hexutil.Big)(big.NewInt(1)),
BlobVersionedHashes: []common.Hash{common.Hash{0x01, 0x22}},
})
if err != nil {
t.Fatalf("failed to fill tx defaults: %v\n", err)
}
res, err = api.SignTransaction(context.Background(), argsFromTransaction(res.Tx, b.acc.Address))
if err != nil {
t.Fatalf("failed to sign tx: %v\n", err)
}
tx, err := json.Marshal(res.Tx)
if err != nil {
t.Fatal(err)
}
expect := `{"type":"0x3","chainId":"0x1","nonce":"0x0","to":"0x703c4b2bd70c169f5717101caee543299fc946c7","gas":"0x5208","gasPrice":null,"maxPriorityFeePerGas":"0x0","maxFeePerGas":"0x684ee180","maxFeePerBlobGas":"0x2","value":"0x1","input":"0x","accessList":[],"blobVersionedHashes":["0x0122000000000000000000000000000000000000000000000000000000000000"],"v":"0x1","r":"0x94e52c0d77144ec96d0e52c65195b3b574d3184b788d44b80c1cac9c43495924","s":"0x17ee5cdc420360a221df4ac805030ecf4a2f0bb292ced555267f54a76e0400b6","yParity":"0x1","hash":"0xe4c90a797ceae5e2cd7f32ca27134e72d3a2db5eac755333c8fa20da537f4f25"}`
if !bytes.Equal(tx, []byte(expect)) {
t.Errorf("result mismatch. Have:\n%s\nWant:\n%s\n", tx, expect)
}
}
func argsFromTransaction(tx *types.Transaction, from common.Address) TransactionArgs {
var (
gas = tx.Gas()
nonce = tx.Nonce()
input = tx.Data()
)
return TransactionArgs{
From: &from,
To: tx.To(),
Gas: (*hexutil.Uint64)(&gas),
MaxFeePerGas: (*hexutil.Big)(tx.GasFeeCap()),
MaxPriorityFeePerGas: (*hexutil.Big)(tx.GasTipCap()),
Value: (*hexutil.Big)(tx.Value()),
Nonce: (*hexutil.Uint64)(&nonce),
Input: (*hexutil.Bytes)(&input),
ChainID: (*hexutil.Big)(tx.ChainId()),
// TODO: impl accessList conversion
//AccessList: tx.AccessList(),
MaxFeePerBlobGas: (*hexutil.Big)(tx.BlobGasFeeCap()),
BlobVersionedHashes: tx.BlobHashes(),
}
}
type account struct { type account struct {
key *ecdsa.PrivateKey key *ecdsa.PrivateKey
addr common.Address addr common.Address

View file

@ -122,7 +122,7 @@ func (args *TransactionArgs) setDefaults(ctx context.Context, b Backend) error {
Data: (*hexutil.Bytes)(&data), Data: (*hexutil.Bytes)(&data),
AccessList: args.AccessList, AccessList: args.AccessList,
} }
pendingBlockNr := rpc.BlockNumberOrHashWithNumber(rpc.PendingBlockNumber) pendingBlockNr := rpc.BlockNumberOrHashWithNumber(rpc.LatestBlockNumber)
estimated, err := DoEstimateGas(ctx, b, callArgs, pendingBlockNr, nil, b.RPCGasCap()) estimated, err := DoEstimateGas(ctx, b, callArgs, pendingBlockNr, nil, b.RPCGasCap())
if err != nil { if err != nil {
return err return err