diff --git a/openapi/SwarmDebug.yaml b/openapi/SwarmDebug.yaml index e363114d123..85e2d057d83 100644 --- a/openapi/SwarmDebug.yaml +++ b/openapi/SwarmDebug.yaml @@ -1035,7 +1035,7 @@ paths: - $ref: "SwarmCommon.yaml#/components/parameters/GasLimitParameter" responses: "200": - description: Amount successfully staked + $ref: "SwarmCommon.yaml#/components/schemas/StakeDepositResponse" "400": $ref: "SwarmCommon.yaml#/components/responses/400" "500": diff --git a/pkg/api/postage.go b/pkg/api/postage.go index 20644723262..15a784f33a8 100644 --- a/pkg/api/postage.go +++ b/pkg/api/postage.go @@ -100,24 +100,24 @@ func (s *Service) postageCreateHandler(w http.ResponseWriter, r *http.Request) { ) if err != nil { if errors.Is(err, postagecontract.ErrChainDisabled) { - logger.Debug("create batch: no chain backend", "error", err, "txHash", txHash) + logger.Debug("create batch: no chain backend", "error", err) logger.Error(nil, "create batch: no chain backend") jsonhttp.MethodNotAllowed(w, "no chain backend") return } if errors.Is(err, postagecontract.ErrInsufficientFunds) { - logger.Debug("create batch: out of funds", "error", err, "txHash", txHash) + logger.Debug("create batch: out of funds", "error", err) logger.Error(nil, "create batch: out of funds") jsonhttp.BadRequest(w, "out of funds") return } if errors.Is(err, postagecontract.ErrInvalidDepth) { - logger.Debug("create batch: invalid depth", "error", err, "txHash", txHash) + logger.Debug("create batch: invalid depth", "error", err) logger.Error(nil, "create batch: invalid depth") jsonhttp.BadRequest(w, "invalid depth") return } - logger.Debug("create batch: create failed", "error", err, "txHash", txHash) + logger.Debug("create batch: create failed", "error", err) logger.Error(nil, "create batch: create failed") jsonhttp.InternalServerError(w, "cannot create batch") return @@ -466,18 +466,18 @@ func (s *Service) postageTopUpHandler(w http.ResponseWriter, r *http.Request) { txHash, err := s.postageContract.TopUpBatch(r.Context(), paths.BatchID, paths.Amount) if err != nil { if errors.Is(err, postagecontract.ErrInsufficientFunds) { - logger.Debug("topup batch: out of funds", "batch_id", hexBatchID, "amount", paths.Amount, "error", err, "tx_hash", txHash) + logger.Debug("topup batch: out of funds", "batch_id", hexBatchID, "amount", paths.Amount, "error", err) logger.Error(nil, "topup batch: out of funds") jsonhttp.PaymentRequired(w, "out of funds") return } if errors.Is(err, postagecontract.ErrNotImplemented) { - logger.Debug("topup batch: not implemented", "error", err, "tx_hash", txHash) + logger.Debug("topup batch: not implemented", "error", err) logger.Error(nil, "topup batch: not implemented") jsonhttp.NotImplemented(w, nil) return } - logger.Debug("topup batch: topup failed", "batch_id", hexBatchID, "amount", paths.Amount, "error", err, "tx_hash", txHash) + logger.Debug("topup batch: topup failed", "batch_id", hexBatchID, "amount", paths.Amount, "error", err) logger.Error(nil, "topup batch: topup failed") jsonhttp.InternalServerError(w, "cannot topup batch") return @@ -505,18 +505,18 @@ func (s *Service) postageDiluteHandler(w http.ResponseWriter, r *http.Request) { txHash, err := s.postageContract.DiluteBatch(r.Context(), paths.BatchID, paths.Depth) if err != nil { if errors.Is(err, postagecontract.ErrInvalidDepth) { - logger.Debug("dilute batch: invalid depth", "error", err, "tx_hash", txHash) + logger.Debug("dilute batch: invalid depth", "error", err) logger.Error(nil, "dilute batch: invalid depth") jsonhttp.BadRequest(w, "invalid depth") return } if errors.Is(err, postagecontract.ErrNotImplemented) { - logger.Debug("dilute batch: not implemented", "error", "tx_hash", txHash) + logger.Debug("dilute batch: not implemented", "error") logger.Error(nil, "dilute batch: not implemented") jsonhttp.NotImplemented(w, nil) return } - logger.Debug("dilute batch: dilute failed", "batch_id", hexBatchID, "depth", paths.Depth, "error", err, "tx_hash", txHash) + logger.Debug("dilute batch: dilute failed", "batch_id", hexBatchID, "depth", paths.Depth, "error", err) logger.Error(nil, "dilute batch: dilute failed") jsonhttp.InternalServerError(w, "cannot dilute batch") return diff --git a/pkg/api/staking.go b/pkg/api/staking.go index 41d7be2ee5b..1e50f0baff1 100644 --- a/pkg/api/staking.go +++ b/pkg/api/staking.go @@ -32,6 +32,9 @@ func (s *Service) stakingAccessHandler(h http.Handler) http.Handler { type getStakeResponse struct { StakedAmount *bigint.BigInt `json:"stakedAmount"` } +type stakeDepositResponse struct { + TxHash string `json:"txhash"` +} func (s *Service) stakingDepositHandler(w http.ResponseWriter, r *http.Request) { logger := s.logger.WithName("post_stake_deposit").Build() @@ -44,7 +47,7 @@ func (s *Service) stakingDepositHandler(w http.ResponseWriter, r *http.Request) return } - err := s.stakingContract.DepositStake(r.Context(), paths.Amount) + txHash, err := s.stakingContract.DepositStake(r.Context(), paths.Amount) if err != nil { if errors.Is(err, staking.ErrInsufficientStakeAmount) { logger.Debug("insufficient stake amount", "minimum_stake", staking.MinimumStakeAmount, "error", err) @@ -69,7 +72,9 @@ func (s *Service) stakingDepositHandler(w http.ResponseWriter, r *http.Request) jsonhttp.InternalServerError(w, "cannot stake") return } - jsonhttp.OK(w, nil) + jsonhttp.OK(w, stakeDepositResponse{ + TxHash: txHash.String(), + }) } func (s *Service) getStakedAmountHandler(w http.ResponseWriter, r *http.Request) { diff --git a/pkg/api/staking_test.go b/pkg/api/staking_test.go index cb51cef4839..51477c94b81 100644 --- a/pkg/api/staking_test.go +++ b/pkg/api/staking_test.go @@ -7,6 +7,7 @@ package api_test import ( "context" "fmt" + "github.com/ethereum/go-ethereum/common" "github.com/ethersphere/bee/pkg/bigint" "math/big" "net/http" @@ -23,6 +24,7 @@ import ( func TestDepositStake(t *testing.T) { t.Parallel() + txHash := common.HexToHash("0x1234") minStake := big.NewInt(100000000000000000).String() depositStake := func(amount string) string { return fmt.Sprintf("/stake/%s", amount) @@ -32,8 +34,8 @@ func TestDepositStake(t *testing.T) { t.Parallel() contract := stakingContractMock.New( - stakingContractMock.WithDepositStake(func(ctx context.Context, stakedAmount *big.Int) error { - return nil + stakingContractMock.WithDepositStake(func(ctx context.Context, stakedAmount *big.Int) (common.Hash, error) { + return txHash, nil }), ) ts, _, _, _ := newTestServer(t, testServerOptions{DebugAPI: true, StakingContract: contract}) @@ -45,8 +47,8 @@ func TestDepositStake(t *testing.T) { invalidMinStake := big.NewInt(0).String() contract := stakingContractMock.New( - stakingContractMock.WithDepositStake(func(ctx context.Context, stakedAmount *big.Int) error { - return staking.ErrInsufficientStakeAmount + stakingContractMock.WithDepositStake(func(ctx context.Context, stakedAmount *big.Int) (common.Hash, error) { + return common.Hash{}, staking.ErrInsufficientStakeAmount }), ) ts, _, _, _ := newTestServer(t, testServerOptions{DebugAPI: true, StakingContract: contract}) @@ -58,8 +60,8 @@ func TestDepositStake(t *testing.T) { t.Parallel() contract := stakingContractMock.New( - stakingContractMock.WithDepositStake(func(ctx context.Context, stakedAmount *big.Int) error { - return staking.ErrInsufficientFunds + stakingContractMock.WithDepositStake(func(ctx context.Context, stakedAmount *big.Int) (common.Hash, error) { + return common.Hash{}, staking.ErrInsufficientFunds }), ) ts, _, _, _ := newTestServer(t, testServerOptions{DebugAPI: true, StakingContract: contract}) @@ -71,8 +73,8 @@ func TestDepositStake(t *testing.T) { t.Parallel() contract := stakingContractMock.New( - stakingContractMock.WithDepositStake(func(ctx context.Context, stakedAmount *big.Int) error { - return fmt.Errorf("some error") + stakingContractMock.WithDepositStake(func(ctx context.Context, stakedAmount *big.Int) (common.Hash, error) { + return common.Hash{}, fmt.Errorf("some error") }), ) ts, _, _, _ := newTestServer(t, testServerOptions{DebugAPI: true, StakingContract: contract}) @@ -84,12 +86,12 @@ func TestDepositStake(t *testing.T) { t.Parallel() contract := stakingContractMock.New( - stakingContractMock.WithDepositStake(func(ctx context.Context, stakedAmount *big.Int) error { + stakingContractMock.WithDepositStake(func(ctx context.Context, stakedAmount *big.Int) (common.Hash, error) { gasLimit := sctx.GetGasLimit(ctx) if gasLimit != 2000000 { t.Fatalf("want 2000000, got %d", gasLimit) } - return nil + return txHash, nil }), ) ts, _, _, _ := newTestServer(t, testServerOptions{ diff --git a/pkg/node/devnode.go b/pkg/node/devnode.go index 4959bf38d7a..d8b164103f2 100644 --- a/pkg/node/devnode.go +++ b/pkg/node/devnode.go @@ -370,8 +370,8 @@ func NewDevBee(logger log.Logger, o *DevOptions) (b *DevBee, err error) { mockSteward := new(mockSteward.Steward) mockStaking := stakingContractMock.New( - stakingContractMock.WithDepositStake(func(ctx context.Context, stakedAmount *big.Int) error { - return staking.ErrNotImplemented + stakingContractMock.WithDepositStake(func(ctx context.Context, stakedAmount *big.Int) (common.Hash, error) { + return common.Hash{}, staking.ErrNotImplemented })) debugOpts := api.ExtraOptions{ diff --git a/pkg/postage/postagecontract/contract.go b/pkg/postage/postagecontract/contract.go index 74c44d91e78..4ee4172a7e6 100644 --- a/pkg/postage/postagecontract/contract.go +++ b/pkg/postage/postagecontract/contract.go @@ -286,9 +286,8 @@ func (c *postageContract) CreateBatch(ctx context.Context, initialBalance *big.I return } - receipt, err := c.sendApproveTransaction(ctx, totalAmount) + _, err = c.sendApproveTransaction(ctx, totalAmount) if err != nil { - txHash = receipt.TxHash return } @@ -298,7 +297,7 @@ func (c *postageContract) CreateBatch(ctx context.Context, initialBalance *big.I return } - receipt, err = c.sendCreateBatchTransaction(ctx, c.owner, initialBalance, depth, common.BytesToHash(nonce), immutable) + receipt, err := c.sendCreateBatchTransaction(ctx, c.owner, initialBalance, depth, common.BytesToHash(nonce), immutable) if err != nil { return } @@ -352,13 +351,12 @@ func (c *postageContract) TopUpBatch(ctx context.Context, batchID []byte, topupB return } - receipt, err := c.sendApproveTransaction(ctx, totalAmount) + _, err = c.sendApproveTransaction(ctx, totalAmount) if err != nil { - txHash = receipt.TxHash return } - receipt, err = c.sendTopUpBatchTransaction(ctx, batch.ID, topupBalance) + receipt, err := c.sendTopUpBatchTransaction(ctx, batch.ID, topupBalance) if err != nil { txHash = receipt.TxHash return diff --git a/pkg/storageincentives/staking/contract.go b/pkg/storageincentives/staking/contract.go index b22fc8d6f3f..e821137b0da 100644 --- a/pkg/storageincentives/staking/contract.go +++ b/pkg/storageincentives/staking/contract.go @@ -35,7 +35,7 @@ var ( ) type Contract interface { - DepositStake(ctx context.Context, stakedAmount *big.Int) error + DepositStake(ctx context.Context, stakedAmount *big.Int) (common.Hash, error) GetStake(ctx context.Context) (*big.Int, error) } @@ -159,37 +159,39 @@ func (s *contract) getStake(ctx context.Context, overlay swarm.Address) (*big.In return abi.ConvertType(results[0], new(big.Int)).(*big.Int), nil } -func (s *contract) DepositStake(ctx context.Context, stakedAmount *big.Int) error { +func (s *contract) DepositStake(ctx context.Context, stakedAmount *big.Int) (txHash common.Hash, err error) { prevStakedAmount, err := s.GetStake(ctx) if err != nil { - return err + return } if len(prevStakedAmount.Bits()) == 0 { if stakedAmount.Cmp(MinimumStakeAmount) == -1 { - return ErrInsufficientStakeAmount + err = ErrInsufficientStakeAmount + return } } balance, err := s.getBalance(ctx) if err != nil { - return err + return } if balance.Cmp(stakedAmount) < 0 { - return ErrInsufficientFunds + err = ErrInsufficientFunds + return } _, err = s.sendApproveTransaction(ctx, stakedAmount) if err != nil { - return err + return } - _, err = s.sendDepositStakeTransaction(ctx, s.owner, stakedAmount, s.overlayNonce) - if err != nil { - return err + receipt, err := s.sendDepositStakeTransaction(ctx, s.owner, stakedAmount, s.overlayNonce) + if receipt != nil { + txHash = receipt.TxHash } - return nil + return } func (s *contract) GetStake(ctx context.Context) (*big.Int, error) { diff --git a/pkg/storageincentives/staking/contract_test.go b/pkg/storageincentives/staking/contract_test.go index 9e5f73bb409..2f7c1de2bea 100644 --- a/pkg/storageincentives/staking/contract_test.go +++ b/pkg/storageincentives/staking/contract_test.go @@ -81,7 +81,7 @@ func TestDepositStake(t *testing.T) { })), nonce) - err = contract.DepositStake(ctx, stakedAmount) + _, err = contract.DepositStake(ctx, stakedAmount) if err != nil { t.Fatal(err) } @@ -135,7 +135,7 @@ func TestDepositStake(t *testing.T) { })), nonce) - err = contract.DepositStake(ctx, stakedAmount) + _, err = contract.DepositStake(ctx, stakedAmount) if err != nil { t.Fatal(err) } @@ -167,7 +167,7 @@ func TestDepositStake(t *testing.T) { })), nonce) - err := contract.DepositStake(ctx, big.NewInt(0)) + _, err := contract.DepositStake(ctx, big.NewInt(0)) if !errors.Is(err, staking2.ErrInsufficientStakeAmount) { t.Fatal(fmt.Errorf("wanted %w, got %v", staking2.ErrInsufficientStakeAmount, err)) } @@ -192,7 +192,7 @@ func TestDepositStake(t *testing.T) { })), nonce) - err := contract.DepositStake(ctx, big.NewInt(100000000000000000)) + _, err := contract.DepositStake(ctx, big.NewInt(100000000000000000)) if !errors.Is(err, staking2.ErrInsufficientFunds) { t.Fatal(fmt.Errorf("wanted %w, got %v", staking2.ErrInsufficientFunds, err)) } @@ -217,7 +217,7 @@ func TestDepositStake(t *testing.T) { })), nonce) - err := contract.DepositStake(ctx, big.NewInt(100000000000000000)) + _, err := contract.DepositStake(ctx, big.NewInt(100000000000000000)) if !errors.Is(err, staking2.ErrInsufficientFunds) { t.Fatal(fmt.Errorf("wanted %w, got %v", staking2.ErrInsufficientStakeAmount, err)) } @@ -248,7 +248,7 @@ func TestDepositStake(t *testing.T) { })), nonce) - err := contract.DepositStake(ctx, stakedAmount) + _, err := contract.DepositStake(ctx, stakedAmount) if err == nil { t.Fatal("expected error") } @@ -290,7 +290,7 @@ func TestDepositStake(t *testing.T) { })), nonce) - err = contract.DepositStake(ctx, stakedAmount) + _, err = contract.DepositStake(ctx, stakedAmount) if err == nil { t.Fatal("expected error") } @@ -318,7 +318,7 @@ func TestDepositStake(t *testing.T) { } return txHashDeposited, nil } - return common.Hash{}, errors.New("sent to wrong contract") + return txHashDeposited, errors.New("sent to wrong contract") }), transactionMock.WithWaitForReceiptFunc(func(ctx context.Context, txHash common.Hash) (receipt *types.Receipt, err error) { if txHash == txHashDeposited { @@ -344,7 +344,7 @@ func TestDepositStake(t *testing.T) { })), nonce) - err = contract.DepositStake(ctx, stakedAmount) + _, err = contract.DepositStake(ctx, stakedAmount) if !errors.Is(err, transaction.ErrTransactionReverted) { t.Fatalf("expeted %v, got %v", transaction.ErrTransactionReverted, err) } @@ -396,7 +396,7 @@ func TestDepositStake(t *testing.T) { })), nonce) - err = contract.DepositStake(ctx, stakedAmount) + _, err = contract.DepositStake(ctx, stakedAmount) if err == nil { t.Fatalf("expected error") } @@ -415,7 +415,7 @@ func TestDepositStake(t *testing.T) { })), nonce) - err := contract.DepositStake(ctx, stakedAmount) + _, err := contract.DepositStake(ctx, stakedAmount) if err == nil { t.Fatalf("expected error") } diff --git a/pkg/storageincentives/staking/mock/contract.go b/pkg/storageincentives/staking/mock/contract.go index d2c3c4a769b..eaf8730930a 100644 --- a/pkg/storageincentives/staking/mock/contract.go +++ b/pkg/storageincentives/staking/mock/contract.go @@ -6,17 +6,18 @@ package mock import ( "context" + "github.com/ethereum/go-ethereum/common" "math/big" "github.com/ethersphere/bee/pkg/storageincentives/staking" ) type stakingContractMock struct { - depositStake func(ctx context.Context, stakedAmount *big.Int) error + depositStake func(ctx context.Context, stakedAmount *big.Int) (common.Hash, error) getStake func(ctx context.Context) (*big.Int, error) } -func (s *stakingContractMock) DepositStake(ctx context.Context, stakedAmount *big.Int) error { +func (s *stakingContractMock) DepositStake(ctx context.Context, stakedAmount *big.Int) (common.Hash, error) { return s.depositStake(ctx, stakedAmount) } @@ -38,7 +39,7 @@ func New(opts ...Option) staking.Contract { return bs } -func WithDepositStake(f func(ctx context.Context, stakedAmount *big.Int) error) Option { +func WithDepositStake(f func(ctx context.Context, stakedAmount *big.Int) (common.Hash, error)) Option { return func(mock *stakingContractMock) { mock.depositStake = f }