Commit 65c1774d authored by Ralph Pichler's avatar Ralph Pichler Committed by GitHub

feat: gas price for deploy, deposit and withdraw (#1812)

parent 2e0c0396
...@@ -60,6 +60,7 @@ const ( ...@@ -60,6 +60,7 @@ const (
optionNameSwapInitialDeposit = "swap-initial-deposit" optionNameSwapInitialDeposit = "swap-initial-deposit"
optionNameSwapEnable = "swap-enable" optionNameSwapEnable = "swap-enable"
optionNameTransactionHash = "transaction" optionNameTransactionHash = "transaction"
optionNameSwapDeploymentGasPrice = "swap-deployment-gas-price"
optionNameFullNode = "full-node" optionNameFullNode = "full-node"
optionNamePostageContractAddress = "postage-stamp-address" optionNamePostageContractAddress = "postage-stamp-address"
optionNameBlockTime = "block-time" optionNameBlockTime = "block-time"
...@@ -234,6 +235,7 @@ func (c *command) setAllFlags(cmd *cobra.Command) { ...@@ -234,6 +235,7 @@ func (c *command) setAllFlags(cmd *cobra.Command) {
cmd.Flags().String(optionNamePostageContractAddress, "", "postage stamp contract address") cmd.Flags().String(optionNamePostageContractAddress, "", "postage stamp contract address")
cmd.Flags().String(optionNameTransactionHash, "", "proof-of-identity transaction hash") cmd.Flags().String(optionNameTransactionHash, "", "proof-of-identity transaction hash")
cmd.Flags().Uint64(optionNameBlockTime, 15, "chain block time") cmd.Flags().Uint64(optionNameBlockTime, 15, "chain block time")
cmd.Flags().String(optionNameSwapDeploymentGasPrice, "", "gas price in wei to use for deployment and funding")
} }
func newLogger(cmd *cobra.Command, verbosity string) (logging.Logger, error) { func newLogger(cmd *cobra.Command, verbosity string) (logging.Logger, error) {
......
...@@ -33,6 +33,7 @@ func (c *command) initDeployCmd() error { ...@@ -33,6 +33,7 @@ func (c *command) initDeployCmd() error {
factoryAddress := c.config.GetString(optionNameSwapFactoryAddress) factoryAddress := c.config.GetString(optionNameSwapFactoryAddress)
swapInitialDeposit := c.config.GetString(optionNameSwapInitialDeposit) swapInitialDeposit := c.config.GetString(optionNameSwapInitialDeposit)
swapEndpoint := c.config.GetString(optionNameSwapEndpoint) swapEndpoint := c.config.GetString(optionNameSwapEndpoint)
deployGasPrice := c.config.GetString(optionNameSwapDeploymentGasPrice)
stateStore, err := node.InitStateStore(logger, dataDir) stateStore, err := node.InitStateStore(logger, dataDir)
if err != nil { if err != nil {
...@@ -91,6 +92,7 @@ func (c *command) initDeployCmd() error { ...@@ -91,6 +92,7 @@ func (c *command) initDeployCmd() error {
transactionService, transactionService,
chequebookFactory, chequebookFactory,
swapInitialDeposit, swapInitialDeposit,
deployGasPrice,
) )
return err return err
......
...@@ -153,6 +153,7 @@ Welcome to the Swarm.... Bzzz Bzzzz Bzzzz ...@@ -153,6 +153,7 @@ Welcome to the Swarm.... Bzzz Bzzzz Bzzzz
Transaction: c.config.GetString(optionNameTransactionHash), Transaction: c.config.GetString(optionNameTransactionHash),
PostageContractAddress: c.config.GetString(optionNamePostageContractAddress), PostageContractAddress: c.config.GetString(optionNamePostageContractAddress),
BlockTime: c.config.GetUint64(optionNameBlockTime), BlockTime: c.config.GetUint64(optionNameBlockTime),
DeployGasPrice: c.config.GetString(optionNameSwapDeploymentGasPrice),
}) })
if err != nil { if err != nil {
return err return err
......
...@@ -598,6 +598,7 @@ paths: ...@@ -598,6 +598,7 @@ paths:
type: integer type: integer
required: true required: true
description: amount of tokens to deposit description: amount of tokens to deposit
- $ref: "SwarmCommon.yaml#/components/parameters/GasPriceParameter"
tags: tags:
- Chequebook - Chequebook
responses: responses:
...@@ -624,6 +625,7 @@ paths: ...@@ -624,6 +625,7 @@ paths:
type: integer type: integer
required: true required: true
description: amount of tokens to withdraw description: amount of tokens to withdraw
- $ref: "SwarmCommon.yaml#/components/parameters/GasPriceParameter"
tags: tags:
- Chequebook - Chequebook
responses: responses:
......
...@@ -74,6 +74,8 @@ password-file: /var/lib/bee/password ...@@ -74,6 +74,8 @@ password-file: /var/lib/bee/password
# swap-legacy-factory-addresses: "" # swap-legacy-factory-addresses: ""
## initial deposit if deploying a new chequebook (default 10000000000000000) ## initial deposit if deploying a new chequebook (default 10000000000000000)
# swap-initial-deposit: 10000000000000000 # swap-initial-deposit: 10000000000000000
## gas price in wei to use for deployment and funding (default "")
# swap-deployment-gas-price: ""
## enable tracing ## enable tracing
# tracing-enable: false # tracing-enable: false
## endpoint to send tracing data (default "127.0.0.1:6831") ## endpoint to send tracing data (default "127.0.0.1:6831")
......
...@@ -81,6 +81,8 @@ BEE_CLEF_SIGNER_ENABLE=true ...@@ -81,6 +81,8 @@ BEE_CLEF_SIGNER_ENABLE=true
# BEE_SWAP_LEGACY_FACTORY_ADDRESSES= # BEE_SWAP_LEGACY_FACTORY_ADDRESSES=
## initial deposit if deploying a new chequebook (default 10000000000000000) ## initial deposit if deploying a new chequebook (default 10000000000000000)
# BEE_SWAP_INITIAL_DEPOSIT=10000000000000000 # BEE_SWAP_INITIAL_DEPOSIT=10000000000000000
## gas price in wei to use for deployment and funding (default "")
# BEE_SWAP_DEPLOYMENT_GAS_PRICE=
## enable tracing ## enable tracing
# BEE_TRACING_ENABLE=false # BEE_TRACING_ENABLE=false
## endpoint to send tracing data (default 127.0.0.1:6831) ## endpoint to send tracing data (default 127.0.0.1:6831)
......
...@@ -74,6 +74,8 @@ password-file: /usr/local/var/lib/swarm-bee/password ...@@ -74,6 +74,8 @@ password-file: /usr/local/var/lib/swarm-bee/password
# swap-legacy-factory-addresses: "" # swap-legacy-factory-addresses: ""
## initial deposit if deploying a new chequebook (default 10000000000000000) ## initial deposit if deploying a new chequebook (default 10000000000000000)
# swap-initial-deposit: 10000000000000000 # swap-initial-deposit: 10000000000000000
## gas price in wei to use for deployment and funding (default "")
# swap-deployment-gas-price: ""
## enable tracing ## enable tracing
# tracing-enable: false # tracing-enable: false
## endpoint to send tracing data (default "127.0.0.1:6831") ## endpoint to send tracing data (default "127.0.0.1:6831")
......
...@@ -64,6 +64,8 @@ password-file: ./password ...@@ -64,6 +64,8 @@ password-file: ./password
# swap-legacy-factory-addresses: "" # swap-legacy-factory-addresses: ""
## initial deposit if deploying a new chequebook (default 10000000000000000) ## initial deposit if deploying a new chequebook (default 10000000000000000)
# swap-initial-deposit: 10000000000000000 # swap-initial-deposit: 10000000000000000
## gas price in wei to use for deployment and funding (default "")
# swap-deployment-gas-price: ""
## enable tracing ## enable tracing
# tracing-enable: false # tracing-enable: false
## endpoint to send tracing data (default "127.0.0.1:6831") ## endpoint to send tracing data (default "127.0.0.1:6831")
......
...@@ -335,7 +335,18 @@ func (s *Service) chequebookWithdrawHandler(w http.ResponseWriter, r *http.Reque ...@@ -335,7 +335,18 @@ func (s *Service) chequebookWithdrawHandler(w http.ResponseWriter, r *http.Reque
return return
} }
txHash, err := s.chequebook.Withdraw(r.Context(), amount) ctx := r.Context()
if price, ok := r.Header[gasPriceHeader]; ok {
p, ok := big.NewInt(0).SetString(price[0], 10)
if !ok {
s.logger.Error("debug api: withdraw: bad gas price")
jsonhttp.BadRequest(w, errBadGasPrice)
return
}
ctx = sctx.SetGasPrice(ctx, p)
}
txHash, err := s.chequebook.Withdraw(ctx, amount)
if errors.Is(err, chequebook.ErrInsufficientFunds) { if errors.Is(err, chequebook.ErrInsufficientFunds) {
jsonhttp.BadRequest(w, errChequebookInsufficientFunds) jsonhttp.BadRequest(w, errChequebookInsufficientFunds)
s.logger.Debugf("debug api: chequebook withdraw: %v", err) s.logger.Debugf("debug api: chequebook withdraw: %v", err)
...@@ -367,7 +378,18 @@ func (s *Service) chequebookDepositHandler(w http.ResponseWriter, r *http.Reques ...@@ -367,7 +378,18 @@ func (s *Service) chequebookDepositHandler(w http.ResponseWriter, r *http.Reques
return return
} }
txHash, err := s.chequebook.Deposit(r.Context(), amount) ctx := r.Context()
if price, ok := r.Header[gasPriceHeader]; ok {
p, ok := big.NewInt(0).SetString(price[0], 10)
if !ok {
s.logger.Error("debug api: deposit: bad gas price")
jsonhttp.BadRequest(w, errBadGasPrice)
return
}
ctx = sctx.SetGasPrice(ctx, p)
}
txHash, err := s.chequebook.Deposit(ctx, amount)
if errors.Is(err, chequebook.ErrInsufficientFunds) { if errors.Is(err, chequebook.ErrInsufficientFunds) {
jsonhttp.BadRequest(w, errChequebookInsufficientFunds) jsonhttp.BadRequest(w, errChequebookInsufficientFunds)
s.logger.Debugf("debug api: chequebook deposit: %v", err) s.logger.Debugf("debug api: chequebook deposit: %v", err)
......
...@@ -130,54 +130,115 @@ func TestChequebookWithdraw(t *testing.T) { ...@@ -130,54 +130,115 @@ func TestChequebookWithdraw(t *testing.T) {
txHash := common.HexToHash("0xfffff") txHash := common.HexToHash("0xfffff")
chequebookWithdrawFunc := func(ctx context.Context, amount *big.Int) (hash common.Hash, err error) { t.Run("ok", func(t *testing.T) {
if amount.Cmp(big.NewInt(500)) == 0 { chequebookWithdrawFunc := func(ctx context.Context, amount *big.Int) (hash common.Hash, err error) {
return txHash, nil if amount.Cmp(big.NewInt(500)) == 0 {
return txHash, nil
}
return common.Hash{}, nil
} }
return common.Hash{}, nil
}
testServer := newTestServer(t, testServerOptions{ testServer := newTestServer(t, testServerOptions{
ChequebookOpts: []mock.Option{mock.WithChequebookWithdrawFunc(chequebookWithdrawFunc)}, ChequebookOpts: []mock.Option{mock.WithChequebookWithdrawFunc(chequebookWithdrawFunc)},
})
expected := &debugapi.ChequebookTxResponse{TransactionHash: txHash}
var got *debugapi.ChequebookTxResponse
jsonhttptest.Request(t, testServer.Client, http.MethodPost, "/chequebook/withdraw?amount=500", http.StatusOK,
jsonhttptest.WithUnmarshalJSONResponse(&got),
)
if !reflect.DeepEqual(got, expected) {
t.Errorf("got address: %+v, expected: %+v", got, expected)
}
}) })
expected := &debugapi.ChequebookTxResponse{TransactionHash: txHash} t.Run("custom gas", func(t *testing.T) {
chequebookWithdrawFunc := func(ctx context.Context, amount *big.Int) (hash common.Hash, err error) {
if sctx.GetGasPrice(ctx).Cmp(big.NewInt(10)) != 0 {
return common.Hash{}, errors.New("wrong gas price")
}
if amount.Cmp(big.NewInt(500)) == 0 {
return txHash, nil
}
return common.Hash{}, nil
}
testServer := newTestServer(t, testServerOptions{
ChequebookOpts: []mock.Option{mock.WithChequebookWithdrawFunc(chequebookWithdrawFunc)},
})
var got *debugapi.ChequebookTxResponse expected := &debugapi.ChequebookTxResponse{TransactionHash: txHash}
jsonhttptest.Request(t, testServer.Client, http.MethodPost, "/chequebook/withdraw?amount=500", http.StatusOK,
jsonhttptest.WithUnmarshalJSONResponse(&got),
)
if !reflect.DeepEqual(got, expected) { var got *debugapi.ChequebookTxResponse
t.Errorf("got address: %+v, expected: %+v", got, expected) jsonhttptest.Request(t, testServer.Client, http.MethodPost, "/chequebook/withdraw?amount=500", http.StatusOK,
} jsonhttptest.WithRequestHeader("Gas-Price", "10"),
jsonhttptest.WithUnmarshalJSONResponse(&got),
)
if !reflect.DeepEqual(got, expected) {
t.Errorf("got address: %+v, expected: %+v", got, expected)
}
})
} }
func TestChequebookDeposit(t *testing.T) { func TestChequebookDeposit(t *testing.T) {
txHash := common.HexToHash("0xfffff") txHash := common.HexToHash("0xfffff")
chequebookDepositFunc := func(ctx context.Context, amount *big.Int) (hash common.Hash, err error) { t.Run("ok", func(t *testing.T) {
if amount.Cmp(big.NewInt(700)) == 0 { chequebookDepositFunc := func(ctx context.Context, amount *big.Int) (hash common.Hash, err error) {
return txHash, nil if amount.Cmp(big.NewInt(700)) == 0 {
return txHash, nil
}
return common.Hash{}, nil
} }
return common.Hash{}, nil
}
testServer := newTestServer(t, testServerOptions{ testServer := newTestServer(t, testServerOptions{
ChequebookOpts: []mock.Option{mock.WithChequebookDepositFunc(chequebookDepositFunc)}, ChequebookOpts: []mock.Option{mock.WithChequebookDepositFunc(chequebookDepositFunc)},
})
expected := &debugapi.ChequebookTxResponse{TransactionHash: txHash}
var got *debugapi.ChequebookTxResponse
jsonhttptest.Request(t, testServer.Client, http.MethodPost, "/chequebook/deposit?amount=700", http.StatusOK,
jsonhttptest.WithUnmarshalJSONResponse(&got),
)
if !reflect.DeepEqual(got, expected) {
t.Errorf("got address: %+v, expected: %+v", got, expected)
}
}) })
expected := &debugapi.ChequebookTxResponse{TransactionHash: txHash} t.Run("custom gas", func(t *testing.T) {
chequebookDepositFunc := func(ctx context.Context, amount *big.Int) (hash common.Hash, err error) {
if sctx.GetGasPrice(ctx).Cmp(big.NewInt(10)) != 0 {
return common.Hash{}, errors.New("wrong gas price")
}
var got *debugapi.ChequebookTxResponse if amount.Cmp(big.NewInt(700)) == 0 {
jsonhttptest.Request(t, testServer.Client, http.MethodPost, "/chequebook/deposit?amount=700", http.StatusOK, return txHash, nil
jsonhttptest.WithUnmarshalJSONResponse(&got), }
) return common.Hash{}, nil
}
if !reflect.DeepEqual(got, expected) { testServer := newTestServer(t, testServerOptions{
t.Errorf("got address: %+v, expected: %+v", got, expected) ChequebookOpts: []mock.Option{mock.WithChequebookDepositFunc(chequebookDepositFunc)},
} })
expected := &debugapi.ChequebookTxResponse{TransactionHash: txHash}
var got *debugapi.ChequebookTxResponse
jsonhttptest.Request(t, testServer.Client, http.MethodPost, "/chequebook/deposit?amount=700", http.StatusOK,
jsonhttptest.WithRequestHeader("Gas-Price", "10"),
jsonhttptest.WithUnmarshalJSONResponse(&got),
)
if !reflect.DeepEqual(got, expected) {
t.Errorf("got address: %+v, expected: %+v", got, expected)
}
})
} }
func TestChequebookLastCheques(t *testing.T) { func TestChequebookLastCheques(t *testing.T) {
......
...@@ -16,6 +16,7 @@ import ( ...@@ -16,6 +16,7 @@ import (
"github.com/ethersphere/bee/pkg/crypto" "github.com/ethersphere/bee/pkg/crypto"
"github.com/ethersphere/bee/pkg/logging" "github.com/ethersphere/bee/pkg/logging"
"github.com/ethersphere/bee/pkg/p2p/libp2p" "github.com/ethersphere/bee/pkg/p2p/libp2p"
"github.com/ethersphere/bee/pkg/sctx"
"github.com/ethersphere/bee/pkg/settlement" "github.com/ethersphere/bee/pkg/settlement"
"github.com/ethersphere/bee/pkg/settlement/swap" "github.com/ethersphere/bee/pkg/settlement/swap"
"github.com/ethersphere/bee/pkg/settlement/swap/chequebook" "github.com/ethersphere/bee/pkg/settlement/swap/chequebook"
...@@ -139,6 +140,7 @@ func InitChequebookService( ...@@ -139,6 +140,7 @@ func InitChequebookService(
transactionService transaction.Service, transactionService transaction.Service,
chequebookFactory chequebook.Factory, chequebookFactory chequebook.Factory,
initialDeposit string, initialDeposit string,
deployGasPrice string,
) (chequebook.Service, error) { ) (chequebook.Service, error) {
chequeSigner := chequebook.NewChequeSigner(signer, chainID) chequeSigner := chequebook.NewChequeSigner(signer, chainID)
...@@ -147,6 +149,14 @@ func InitChequebookService( ...@@ -147,6 +149,14 @@ func InitChequebookService(
return nil, fmt.Errorf("initial swap deposit \"%s\" cannot be parsed", initialDeposit) return nil, fmt.Errorf("initial swap deposit \"%s\" cannot be parsed", initialDeposit)
} }
if deployGasPrice != "" {
gasPrice, ok := new(big.Int).SetString(deployGasPrice, 10)
if !ok {
return nil, fmt.Errorf("deploy gas price \"%s\" cannot be parsed", deployGasPrice)
}
ctx = sctx.SetGasPrice(ctx, gasPrice)
}
chequebookService, err := chequebook.Init( chequebookService, err := chequebook.Init(
ctx, ctx,
chequebookFactory, chequebookFactory,
......
...@@ -137,6 +137,7 @@ type Options struct { ...@@ -137,6 +137,7 @@ type Options struct {
PostageContractAddress string PostageContractAddress string
PriceOracleAddress string PriceOracleAddress string
BlockTime uint64 BlockTime uint64
DeployGasPrice string
} }
const ( const (
...@@ -271,6 +272,7 @@ func NewBee(addr string, swarmAddress swarm.Address, publicKey ecdsa.PublicKey, ...@@ -271,6 +272,7 @@ func NewBee(addr string, swarmAddress swarm.Address, publicKey ecdsa.PublicKey,
transactionService, transactionService,
chequebookFactory, chequebookFactory,
o.SwapInitialDeposit, o.SwapInitialDeposit,
o.DeployGasPrice,
) )
if err != nil { if err != nil {
return nil, err return nil, err
......
...@@ -13,6 +13,7 @@ import ( ...@@ -13,6 +13,7 @@ import (
"sync" "sync"
"github.com/ethereum/go-ethereum/common" "github.com/ethereum/go-ethereum/common"
"github.com/ethersphere/bee/pkg/sctx"
"github.com/ethersphere/bee/pkg/settlement/swap/erc20" "github.com/ethersphere/bee/pkg/settlement/swap/erc20"
"github.com/ethersphere/bee/pkg/settlement/swap/transaction" "github.com/ethersphere/bee/pkg/settlement/swap/transaction"
"github.com/ethersphere/bee/pkg/storage" "github.com/ethersphere/bee/pkg/storage"
...@@ -324,7 +325,7 @@ func (s *service) Withdraw(ctx context.Context, amount *big.Int) (hash common.Ha ...@@ -324,7 +325,7 @@ func (s *service) Withdraw(ctx context.Context, amount *big.Int) (hash common.Ha
request := &transaction.TxRequest{ request := &transaction.TxRequest{
To: &s.address, To: &s.address,
Data: callData, Data: callData,
GasPrice: nil, GasPrice: sctx.GetGasPrice(ctx),
GasLimit: 0, GasLimit: 0,
Value: big.NewInt(0), Value: big.NewInt(0),
} }
......
...@@ -12,6 +12,7 @@ import ( ...@@ -12,6 +12,7 @@ import (
"github.com/ethereum/go-ethereum/accounts/abi" "github.com/ethereum/go-ethereum/accounts/abi"
"github.com/ethereum/go-ethereum/common" "github.com/ethereum/go-ethereum/common"
"github.com/ethersphere/bee/pkg/sctx"
"github.com/ethersphere/bee/pkg/settlement/swap/transaction" "github.com/ethersphere/bee/pkg/settlement/swap/transaction"
"github.com/ethersphere/go-sw3-abi/sw3abi" "github.com/ethersphere/go-sw3-abi/sw3abi"
"golang.org/x/net/context" "golang.org/x/net/context"
...@@ -80,7 +81,7 @@ func (c *factory) Deploy(ctx context.Context, issuer common.Address, defaultHard ...@@ -80,7 +81,7 @@ func (c *factory) Deploy(ctx context.Context, issuer common.Address, defaultHard
request := &transaction.TxRequest{ request := &transaction.TxRequest{
To: &c.address, To: &c.address,
Data: callData, Data: callData,
GasPrice: nil, GasPrice: sctx.GetGasPrice(ctx),
GasLimit: 0, GasLimit: 0,
Value: big.NewInt(0), Value: big.NewInt(0),
} }
......
...@@ -11,6 +11,7 @@ import ( ...@@ -11,6 +11,7 @@ import (
"github.com/ethereum/go-ethereum/accounts/abi" "github.com/ethereum/go-ethereum/accounts/abi"
"github.com/ethereum/go-ethereum/common" "github.com/ethereum/go-ethereum/common"
"github.com/ethersphere/bee/pkg/sctx"
"github.com/ethersphere/bee/pkg/settlement/swap/transaction" "github.com/ethersphere/bee/pkg/settlement/swap/transaction"
"github.com/ethersphere/go-sw3-abi/sw3abi" "github.com/ethersphere/go-sw3-abi/sw3abi"
) )
...@@ -78,7 +79,7 @@ func (c *erc20Service) Transfer(ctx context.Context, address common.Address, val ...@@ -78,7 +79,7 @@ func (c *erc20Service) Transfer(ctx context.Context, address common.Address, val
request := &transaction.TxRequest{ request := &transaction.TxRequest{
To: &c.address, To: &c.address,
Data: callData, Data: callData,
GasPrice: nil, GasPrice: sctx.GetGasPrice(ctx),
GasLimit: 0, GasLimit: 0,
Value: big.NewInt(0), Value: big.NewInt(0),
} }
......
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