From 0f911d504136869180216a5848838258e819e1f4 Mon Sep 17 00:00:00 2001 From: Umer Date: Tue, 22 Nov 2022 20:03:33 +0500 Subject: [PATCH] feat(staking): add tx hash --- openapi/SwarmCommon.yaml | 22 +++++++++------ openapi/SwarmDebug.yaml | 2 +- pkg/api/staking.go | 9 ++++-- pkg/api/staking_test.go | 22 ++++++++------- pkg/node/devnode.go | 4 +-- pkg/storageincentives/staking/contract.go | 28 +++++++++++-------- .../staking/contract_test.go | 22 +++++++-------- .../staking/mock/contract.go | 7 +++-- 8 files changed, 68 insertions(+), 48 deletions(-) diff --git a/openapi/SwarmCommon.yaml b/openapi/SwarmCommon.yaml index 6ff31cb4637..77f23b9cb76 100644 --- a/openapi/SwarmCommon.yaml +++ b/openapi/SwarmCommon.yaml @@ -9,7 +9,7 @@ externalDocs: description: Browse the documentation @ the Swarm Docs url: "https://docs.swarm.eth" -paths: {} +paths: { } components: schemas: Address: @@ -407,7 +407,7 @@ components: properties: beeMode: type: string - enum: [light, full, dev] + enum: [ light, full, dev ] description: > Gives back in what mode the Bee client has been started. The modes are mutually exclusive * `light` - light node; does not participate in forwarding or storing chunks @@ -423,7 +423,7 @@ components: properties: status: type: string - enum: [ok, nok] + enum: [ ok, nok ] description: > Indicates health state of node * `ok` - node is healthy @@ -584,7 +584,13 @@ components: type: object properties: stakedAmount: - $ref: "#/components/schemas/BigInt" + $ref: "#/components/schemas/BigInt" + + StakeDepositResponse: + type: object + properties: + stakedAmount: + $ref: "#/components/schemas/TransactionHash" SwarmOnlyReference: oneOf: @@ -680,9 +686,9 @@ components: xDai: $ref: "#/components/schemas/BigInt" chainID: - type: integer + type: integer contractAddress: - $ref: "#/components/schemas/EthereumAddress" + $ref: "#/components/schemas/EthereumAddress" PendingTransactionsResponse: type: object @@ -752,7 +758,7 @@ components: LoggerTreeNode: type: object additionalProperties: - $ref: "#/components/schemas/LoggerTreeData" + $ref: "#/components/schemas/LoggerTreeData" Logger: type: object @@ -770,7 +776,7 @@ components: type: object properties: tree: - $ref: "#/components/schemas/LoggerTreeNode" + $ref: "#/components/schemas/LoggerTreeNode" loggers: type: array items: 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/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/storageincentives/staking/contract.go b/pkg/storageincentives/staking/contract.go index b22fc8d6f3f..862fcf1f16b 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,43 @@ 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) + receipt, err := s.sendApproveTransaction(ctx, stakedAmount) if err != nil { - return err + if receipt != nil { + txHash = receipt.TxHash + } + return } - _, err = s.sendDepositStakeTransaction(ctx, s.owner, stakedAmount, s.overlayNonce) + receipt, err = s.sendDepositStakeTransaction(ctx, s.owner, stakedAmount, s.overlayNonce) + txHash = receipt.TxHash if err != nil { - return err + return } - 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 }