Commit 80bcf665 authored by Ralph Pichler's avatar Ralph Pichler Committed by GitHub

transaction: add support for deployments (#1265)

parent f28ff0db
......@@ -107,7 +107,7 @@ func (s *cashoutService) CashCheque(ctx context.Context, chequebook, recipient c
}
request := &transaction.TxRequest{
To: chequebook,
To: &chequebook,
Data: callData,
GasPrice: nil,
GasLimit: 0,
......
......@@ -83,7 +83,7 @@ func TestCashout(t *testing.T) {
),
transactionmock.New(
transactionmock.WithSendFunc(func(c context.Context, request *transaction.TxRequest) (common.Hash, error) {
if request.To != chequebookAddress {
if request.To != nil && *request.To != chequebookAddress {
t.Fatalf("sending to wrong contract. wanted %x, got %x", chequebookAddress, request.To)
}
if request.Value.Cmp(big.NewInt(0)) != 0 {
......@@ -222,7 +222,7 @@ func TestCashoutBounced(t *testing.T) {
),
transactionmock.New(
transactionmock.WithSendFunc(func(c context.Context, request *transaction.TxRequest) (common.Hash, error) {
if request.To != chequebookAddress {
if request.To != nil && *request.To != chequebookAddress {
t.Fatalf("sending to wrong contract. wanted %x, got %x", chequebookAddress, request.To)
}
if request.Value.Cmp(big.NewInt(0)) != 0 {
......
......@@ -139,7 +139,7 @@ func (s *service) Deposit(ctx context.Context, amount *big.Int) (hash common.Has
}
request := &transaction.TxRequest{
To: s.erc20Address,
To: &s.erc20Address,
Data: callData,
GasPrice: nil,
GasLimit: 0,
......@@ -371,7 +371,7 @@ func (s *service) Withdraw(ctx context.Context, amount *big.Int) (hash common.Ha
}
request := &transaction.TxRequest{
To: s.address,
To: &s.address,
Data: callData,
GasPrice: nil,
GasLimit: 0,
......
......@@ -131,7 +131,7 @@ func TestChequebookDeposit(t *testing.T) {
backendmock.New(),
transactionmock.New(
transactionmock.WithSendFunc(func(c context.Context, request *transaction.TxRequest) (common.Hash, error) {
if request.To != erc20address {
if request.To != nil && *request.To != erc20address {
t.Fatalf("sending to wrong contract. wanted %x, got %x", erc20address, request.To)
}
if request.Value.Cmp(big.NewInt(0)) != 0 {
......@@ -502,7 +502,7 @@ func TestChequebookWithdraw(t *testing.T) {
backendmock.New(),
transactionmock.New(
transactionmock.WithSendFunc(func(c context.Context, request *transaction.TxRequest) (common.Hash, error) {
if request.To != address {
if request.To != nil && *request.To != address {
t.Fatalf("sending to wrong contract. wanted %x, got %x", address, request.To)
}
if request.Value.Cmp(big.NewInt(0)) != 0 {
......@@ -559,7 +559,7 @@ func TestChequebookWithdrawInsufficientFunds(t *testing.T) {
backendmock.New(),
transactionmock.New(
transactionmock.WithSendFunc(func(c context.Context, request *transaction.TxRequest) (common.Hash, error) {
if request.To != address {
if request.To != nil && *request.To != address {
t.Fatalf("sending to wrong contract. wanted %x, got %x", address, request.To)
}
if request.Value.Cmp(big.NewInt(0)) != 0 {
......
......@@ -76,7 +76,7 @@ func (c *factory) Deploy(ctx context.Context, issuer common.Address, defaultHard
}
request := &transaction.TxRequest{
To: c.address,
To: &c.address,
Data: callData,
GasPrice: nil,
GasLimit: 0,
......
......@@ -188,7 +188,7 @@ func TestFactoryDeploy(t *testing.T) {
backendmock.New(),
transactionmock.New(
transactionmock.WithSendFunc(func(ctx context.Context, request *transaction.TxRequest) (txHash common.Hash, err error) {
if request.To != factoryAddress {
if request.To != nil && *request.To != factoryAddress {
t.Fatalf("sending to wrong address. wanted %x, got %x", factoryAddress, request.To)
}
if request.Value.Cmp(big.NewInt(0)) != 0 {
......
......@@ -23,11 +23,11 @@ var (
// TxRequest describes a request for a transaction that can be executed.
type TxRequest struct {
To common.Address // recipient of the transaction
Data []byte // transaction data
GasPrice *big.Int // gas price or nil if suggested gas price should be used
GasLimit uint64 // gas limit or 0 if it should be estimated
Value *big.Int // amount of wei to send
To *common.Address // recipient of the transaction
Data []byte // transaction data
GasPrice *big.Int // gas price or nil if suggested gas price should be used
GasLimit uint64 // gas limit or 0 if it should be estimated
Value *big.Int // amount of wei to send
}
// Service is the service to send transactions. It takes care of gas price, gas limit and nonce management.
......@@ -107,7 +107,7 @@ func prepareTransaction(ctx context.Context, request *TxRequest, from common.Add
if request.GasLimit == 0 {
gasLimit, err = backend.EstimateGas(ctx, ethereum.CallMsg{
From: from,
To: &request.To,
To: request.To,
Data: request.Data,
})
if err != nil {
......@@ -132,12 +132,22 @@ func prepareTransaction(ctx context.Context, request *TxRequest, from common.Add
return nil, err
}
return types.NewTransaction(
nonce,
request.To,
request.Value,
gasLimit,
gasPrice,
request.Data,
), nil
if request.To != nil {
return types.NewTransaction(
nonce,
*request.To,
request.Value,
gasLimit,
gasPrice,
request.Data,
), nil
} else {
return types.NewContractCreation(
nonce,
request.Value,
gasLimit,
gasPrice,
request.Data,
), nil
}
}
......@@ -31,7 +31,7 @@ func TestTransactionSend(t *testing.T) {
nonce := uint64(2)
request := &transaction.TxRequest{
To: recipient,
To: &recipient,
Data: txData,
Value: value,
}
......@@ -100,6 +100,84 @@ func TestTransactionSend(t *testing.T) {
}
}
func TestTransactionDeploy(t *testing.T) {
logger := logging.New(ioutil.Discard, 0)
signedTx := types.NewContractCreation(0, big.NewInt(0), 0, nil, nil)
txData := common.Hex2Bytes("0xabcdee")
value := big.NewInt(1)
suggestedGasPrice := big.NewInt(2)
estimatedGasLimit := uint64(3)
nonce := uint64(2)
request := &transaction.TxRequest{
To: nil,
Data: txData,
Value: value,
}
transactionService, err := transaction.NewService(logger,
backendmock.New(
backendmock.WithSendTransactionFunc(func(ctx context.Context, tx *types.Transaction) error {
if tx != signedTx {
t.Fatal("not sending signed transaction")
}
return nil
}),
backendmock.WithEstimateGasFunc(func(ctx context.Context, call ethereum.CallMsg) (gas uint64, err error) {
if call.To != nil {
t.Fatalf("estimating with recipient. wanted nil, got %x", call.To)
}
if !bytes.Equal(call.Data, txData) {
t.Fatal("estimating with wrong data")
}
return estimatedGasLimit, nil
}),
backendmock.WithSuggestGasPriceFunc(func(ctx context.Context) (*big.Int, error) {
return suggestedGasPrice, nil
}),
backendmock.WithPendingNonceAtFunc(func(ctx context.Context, account common.Address) (uint64, error) {
return nonce, nil
}),
),
signermock.New(
signermock.WithSignTxFunc(func(transaction *types.Transaction) (*types.Transaction, error) {
if transaction.To() != nil {
t.Fatalf("signing transaction with recipient. wanted nil, got %x", transaction.To())
}
if !bytes.Equal(transaction.Data(), txData) {
t.Fatalf("signing transaction with wrong data. wanted %x, got %x", txData, transaction.Data())
}
if transaction.Value().Cmp(value) != 0 {
t.Fatalf("signing transaction with wrong value. wanted %d, got %d", value, transaction.Value())
}
if transaction.Gas() != estimatedGasLimit {
t.Fatalf("signing transaction with wrong gas. wanted %d, got %d", estimatedGasLimit, transaction.Gas())
}
if transaction.GasPrice().Cmp(suggestedGasPrice) != 0 {
t.Fatalf("signing transaction with wrong gasprice. wanted %d, got %d", suggestedGasPrice, transaction.GasPrice())
}
if transaction.Nonce() != nonce {
t.Fatalf("signing transaction with wrong nonce. wanted %d, got %d", nonce, transaction.Nonce())
}
return signedTx, nil
}),
),
)
if err != nil {
t.Fatal(err)
}
txHash, err := transactionService.Send(context.Background(), request)
if err != nil {
t.Fatal(err)
}
if !bytes.Equal(txHash.Bytes(), signedTx.Hash().Bytes()) {
t.Fatal("returning wrong transaction hash")
}
}
func TestTransactionWaitForReceipt(t *testing.T) {
logger := logging.New(ioutil.Discard, 0)
txHash := common.HexToHash("0xabcdee")
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment