mirror of
https://gitlab.com/pulsechaincom/erigon-pulse.git
synced 2025-01-09 12:31:21 +00:00
c51573f333
Implemented polygon->eth flow
215 lines
5.7 KiB
Go
215 lines
5.7 KiB
Go
package accounts_steps
|
|
|
|
import (
|
|
"context"
|
|
"encoding/json"
|
|
"fmt"
|
|
"math/big"
|
|
|
|
libcommon "github.com/ledgerwatch/erigon-lib/common"
|
|
|
|
"github.com/ledgerwatch/erigon/accounts/abi/bind"
|
|
"github.com/ledgerwatch/erigon/cmd/devnet/accounts"
|
|
"github.com/ledgerwatch/erigon/cmd/devnet/devnet"
|
|
"github.com/ledgerwatch/erigon/cmd/devnet/requests"
|
|
"github.com/ledgerwatch/erigon/cmd/devnet/scenarios"
|
|
"github.com/ledgerwatch/erigon/cmd/devnet/services"
|
|
"github.com/ledgerwatch/erigon/cmd/devnet/transactions"
|
|
"github.com/ledgerwatch/erigon/rpc"
|
|
"github.com/ledgerwatch/erigon/turbo/adapter/ethapi"
|
|
)
|
|
|
|
func init() {
|
|
scenarios.MustRegisterStepHandlers(
|
|
scenarios.StepHandler(CreateAccount),
|
|
scenarios.StepHandler(CreateAccountWithFunds),
|
|
scenarios.StepHandler(SendFunds),
|
|
scenarios.StepHandler(GetBalance),
|
|
scenarios.StepHandler(GetNonce),
|
|
)
|
|
}
|
|
|
|
func CreateAccount(ctx context.Context, name string) (*accounts.Account, error) {
|
|
if account := accounts.GetAccount(name); account != nil {
|
|
return account, nil
|
|
}
|
|
|
|
return accounts.NewAccount(name), nil
|
|
}
|
|
|
|
func CreateAccountWithFunds(ctx context.Context, chainName string, name string, ethAmount float64) (*accounts.Account, error) {
|
|
account, err := CreateAccount(ctx, name)
|
|
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
if _, err = SendFunds(ctx, chainName, name, ethAmount); err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
return account, nil
|
|
}
|
|
|
|
func SendFunds(ctx context.Context, chainName string, name string, ethAmount float64) (uint64, error) {
|
|
chainCtx := devnet.WithCurrentNetwork(ctx, chainName)
|
|
faucet := services.Faucet(chainCtx)
|
|
|
|
account := accounts.GetAccount(name)
|
|
|
|
if account == nil {
|
|
return 0, fmt.Errorf("Unknown account: %s", name)
|
|
}
|
|
|
|
facuetStartingBalance, _ := faucet.Balance(chainCtx)
|
|
|
|
sent, hash, err := faucet.Send(chainCtx, account, ethAmount)
|
|
|
|
if err != nil {
|
|
return 0, err
|
|
}
|
|
|
|
blockMap, err := transactions.AwaitTransactions(chainCtx, hash)
|
|
|
|
if err != nil {
|
|
return 0, fmt.Errorf("Failed to get transfer tx: %w", err)
|
|
}
|
|
|
|
blockNum, _ := blockMap[hash]
|
|
|
|
logs, err := faucet.Contract().FilterSent(&bind.FilterOpts{
|
|
Start: blockNum,
|
|
End: &blockNum,
|
|
})
|
|
|
|
if err != nil {
|
|
return 0, fmt.Errorf("Failed to get post transfer logs: %w", err)
|
|
}
|
|
|
|
sendConfirmed := false
|
|
|
|
for logs.Next() {
|
|
if account.Address != logs.Event.Destination {
|
|
return 0, fmt.Errorf("Unexpected send destination: %s", logs.Event.Destination)
|
|
}
|
|
|
|
if sent.Cmp(logs.Event.Amount) != 0 {
|
|
return 0, fmt.Errorf("Unexpected send amount: %s", logs.Event.Amount)
|
|
}
|
|
|
|
sendConfirmed = true
|
|
}
|
|
|
|
node := devnet.SelectBlockProducer(chainCtx)
|
|
|
|
if !sendConfirmed {
|
|
logger := devnet.Logger(chainCtx)
|
|
|
|
traceResults, err := node.TraceTransaction(hash)
|
|
|
|
if err != nil {
|
|
return 0, fmt.Errorf("Send transaction failure: transaction trace failed: %w", err)
|
|
}
|
|
|
|
for _, traceResult := range traceResults {
|
|
accountResult, err := node.DebugAccountAt(traceResult.BlockHash, traceResult.TransactionPosition, faucet.Address())
|
|
|
|
if err != nil {
|
|
return 0, fmt.Errorf("Send transaction failure: account debug failed: %w", err)
|
|
}
|
|
|
|
logger.Info("Faucet account details", "address", faucet.Address(), "account", accountResult)
|
|
|
|
accountCode, err := node.GetCode(faucet.Address(), rpc.AsBlockReference(traceResult.BlockHash))
|
|
|
|
if err != nil {
|
|
return 0, fmt.Errorf("Send transaction failure: get account code failed: %w", err)
|
|
}
|
|
|
|
logger.Info("Faucet account code", "address", faucet.Address(), "code", accountCode)
|
|
|
|
callResults, err := node.TraceCall(rpc.AsBlockReference(blockNum), ethapi.CallArgs{
|
|
From: &traceResult.Action.From,
|
|
To: &traceResult.Action.To,
|
|
Data: &traceResult.Action.Input,
|
|
}, requests.TraceOpts.StateDiff, requests.TraceOpts.Trace, requests.TraceOpts.VmTrace)
|
|
|
|
if err != nil {
|
|
return 0, fmt.Errorf("Send transaction failure: trace call failed: %w", err)
|
|
}
|
|
|
|
results, _ := json.MarshalIndent(callResults, " ", " ")
|
|
logger.Debug("Send transaction call trace", "hash", hash, "trace", string(results))
|
|
}
|
|
}
|
|
|
|
balance, err := faucet.Balance(chainCtx)
|
|
|
|
if err != nil {
|
|
return 0, fmt.Errorf("Failed to get post transfer faucet balance: %w", err)
|
|
}
|
|
|
|
if balance.Cmp((&big.Int{}).Sub(facuetStartingBalance, sent)) != 0 {
|
|
return 0, fmt.Errorf("Unexpected post transfer faucet balance got: %s:, expected: %s", balance, (&big.Int{}).Sub(facuetStartingBalance, sent))
|
|
}
|
|
|
|
balance, err = node.GetBalance(account.Address, rpc.LatestBlock)
|
|
|
|
if err != nil {
|
|
return 0, fmt.Errorf("Failed to get post transfer balance: %w", err)
|
|
}
|
|
|
|
if balance.Cmp(sent) != 0 {
|
|
return 0, fmt.Errorf("Unexpected post transfer balance got: %s:, expected: %s", balance, sent)
|
|
}
|
|
|
|
return balance.Uint64(), nil
|
|
}
|
|
|
|
func GetBalance(ctx context.Context, accountName string, blockNum rpc.BlockNumber) (uint64, error) {
|
|
logger := devnet.Logger(ctx)
|
|
|
|
node := devnet.CurrentNode(ctx)
|
|
|
|
if node == nil {
|
|
node = devnet.SelectBlockProducer(ctx)
|
|
}
|
|
|
|
account := accounts.GetAccount(accountName)
|
|
|
|
if account == nil {
|
|
err := fmt.Errorf("Unknown account: %s", accountName)
|
|
logger.Error("FAILURE", "error", err)
|
|
return 0, err
|
|
}
|
|
|
|
logger.Info("Getting balance", "address", account.Address)
|
|
|
|
bal, err := node.GetBalance(account.Address, rpc.AsBlockReference(blockNum))
|
|
|
|
if err != nil {
|
|
logger.Error("FAILURE", "error", err)
|
|
return 0, err
|
|
}
|
|
|
|
logger.Info("SUCCESS", "balance", bal)
|
|
|
|
return bal.Uint64(), nil
|
|
}
|
|
|
|
func GetNonce(ctx context.Context, address libcommon.Address) (uint64, error) {
|
|
node := devnet.CurrentNode(ctx)
|
|
|
|
if node == nil {
|
|
node = devnet.SelectBlockProducer(ctx)
|
|
}
|
|
|
|
res, err := node.GetTransactionCount(address, rpc.LatestBlock)
|
|
|
|
if err != nil {
|
|
return 0, fmt.Errorf("failed to get transaction count for address 0x%x: %v", address, err)
|
|
}
|
|
|
|
return res.Uint64(), nil
|
|
}
|