Skip to content

Commit

Permalink
feat: alternative withdrawal address (#4606)
Browse files Browse the repository at this point in the history
  • Loading branch information
notanatol authored Mar 15, 2024
1 parent 630b9b1 commit 4f32231
Show file tree
Hide file tree
Showing 13 changed files with 440 additions and 69 deletions.
3 changes: 3 additions & 0 deletions .github/workflows/beekeeper.yml
Original file line number Diff line number Diff line change
Expand Up @@ -162,6 +162,9 @@ jobs:
- name: Test staking
id: stake
run: timeout ${TIMEOUT} beekeeper check --cluster-name local-dns --checks ci-stake
- name: Test withdraw
id: withdraw
run: timeout ${TIMEOUT} bash -c 'until beekeeper check --cluster-name local-dns --checks ci-withdraw; do echo "waiting for withdraw..."; sleep .3; done'
- name: Test redundancy
id: redundancy
run: timeout ${TIMEOUT} beekeeper check --cluster-name local-dns --checks ci-redundancy
Expand Down
130 changes: 66 additions & 64 deletions cmd/bee/cmd/cmd.go
Original file line number Diff line number Diff line change
Expand Up @@ -22,70 +22,71 @@ import (
)

const (
optionNameDataDir = "data-dir"
optionNameCacheCapacity = "cache-capacity"
optionNameDBOpenFilesLimit = "db-open-files-limit"
optionNameDBBlockCacheCapacity = "db-block-cache-capacity"
optionNameDBWriteBufferSize = "db-write-buffer-size"
optionNameDBDisableSeeksCompaction = "db-disable-seeks-compaction"
optionNamePassword = "password"
optionNamePasswordFile = "password-file"
optionNameAPIAddr = "api-addr"
optionNameP2PAddr = "p2p-addr"
optionNameNATAddr = "nat-addr"
optionNameP2PWSEnable = "p2p-ws-enable"
optionNameDebugAPIEnable = "debug-api-enable"
optionNameDebugAPIAddr = "debug-api-addr"
optionNameBootnodes = "bootnode"
optionNameNetworkID = "network-id"
optionWelcomeMessage = "welcome-message"
optionCORSAllowedOrigins = "cors-allowed-origins"
optionNameTracingEnabled = "tracing-enable"
optionNameTracingEndpoint = "tracing-endpoint"
optionNameTracingHost = "tracing-host"
optionNameTracingPort = "tracing-port"
optionNameTracingServiceName = "tracing-service-name"
optionNameVerbosity = "verbosity"
optionNamePaymentThreshold = "payment-threshold"
optionNamePaymentTolerance = "payment-tolerance-percent"
optionNamePaymentEarly = "payment-early-percent"
optionNameResolverEndpoints = "resolver-options"
optionNameBootnodeMode = "bootnode-mode"
optionNameClefSignerEnable = "clef-signer-enable"
optionNameClefSignerEndpoint = "clef-signer-endpoint"
optionNameClefSignerEthereumAddress = "clef-signer-ethereum-address"
optionNameSwapEndpoint = "swap-endpoint" // deprecated: use rpc endpoint instead
optionNameBlockchainRpcEndpoint = "blockchain-rpc-endpoint"
optionNameSwapFactoryAddress = "swap-factory-address"
optionNameSwapInitialDeposit = "swap-initial-deposit"
optionNameSwapEnable = "swap-enable"
optionNameChequebookEnable = "chequebook-enable"
optionNameSwapDeploymentGasPrice = "swap-deployment-gas-price"
optionNameFullNode = "full-node"
optionNamePostageContractAddress = "postage-stamp-address"
optionNamePostageContractStartBlock = "postage-stamp-start-block"
optionNamePriceOracleAddress = "price-oracle-address"
optionNameRedistributionAddress = "redistribution-address"
optionNameStakingAddress = "staking-address"
optionNameBlockTime = "block-time"
optionWarmUpTime = "warmup-time"
optionNameMainNet = "mainnet"
optionNameRetrievalCaching = "cache-retrieval"
optionNameDevReserveCapacity = "dev-reserve-capacity"
optionNameResync = "resync"
optionNamePProfBlock = "pprof-profile"
optionNamePProfMutex = "pprof-mutex"
optionNameStaticNodes = "static-nodes"
optionNameAllowPrivateCIDRs = "allow-private-cidrs"
optionNameSleepAfter = "sleep-after"
optionNameRestrictedAPI = "restricted"
optionNameTokenEncryptionKey = "token-encryption-key"
optionNameAdminPasswordHash = "admin-password"
optionNameUsePostageSnapshot = "use-postage-snapshot"
optionNameStorageIncentivesEnable = "storage-incentives-enable"
optionNameStateStoreCacheCapacity = "statestore-cache-capacity"
optionNameTargetNeighborhood = "target-neighborhood"
optionNameNeighborhoodSuggester = "neighborhood-suggester"
optionNameDataDir = "data-dir"
optionNameCacheCapacity = "cache-capacity"
optionNameDBOpenFilesLimit = "db-open-files-limit"
optionNameDBBlockCacheCapacity = "db-block-cache-capacity"
optionNameDBWriteBufferSize = "db-write-buffer-size"
optionNameDBDisableSeeksCompaction = "db-disable-seeks-compaction"
optionNamePassword = "password"
optionNamePasswordFile = "password-file"
optionNameAPIAddr = "api-addr"
optionNameP2PAddr = "p2p-addr"
optionNameNATAddr = "nat-addr"
optionNameP2PWSEnable = "p2p-ws-enable"
optionNameDebugAPIEnable = "debug-api-enable"
optionNameDebugAPIAddr = "debug-api-addr"
optionNameBootnodes = "bootnode"
optionNameNetworkID = "network-id"
optionWelcomeMessage = "welcome-message"
optionCORSAllowedOrigins = "cors-allowed-origins"
optionNameTracingEnabled = "tracing-enable"
optionNameTracingEndpoint = "tracing-endpoint"
optionNameTracingHost = "tracing-host"
optionNameTracingPort = "tracing-port"
optionNameTracingServiceName = "tracing-service-name"
optionNameVerbosity = "verbosity"
optionNamePaymentThreshold = "payment-threshold"
optionNamePaymentTolerance = "payment-tolerance-percent"
optionNamePaymentEarly = "payment-early-percent"
optionNameResolverEndpoints = "resolver-options"
optionNameBootnodeMode = "bootnode-mode"
optionNameClefSignerEnable = "clef-signer-enable"
optionNameClefSignerEndpoint = "clef-signer-endpoint"
optionNameClefSignerEthereumAddress = "clef-signer-ethereum-address"
optionNameSwapEndpoint = "swap-endpoint" // deprecated: use rpc endpoint instead
optionNameBlockchainRpcEndpoint = "blockchain-rpc-endpoint"
optionNameSwapFactoryAddress = "swap-factory-address"
optionNameSwapInitialDeposit = "swap-initial-deposit"
optionNameSwapEnable = "swap-enable"
optionNameChequebookEnable = "chequebook-enable"
optionNameSwapDeploymentGasPrice = "swap-deployment-gas-price"
optionNameFullNode = "full-node"
optionNamePostageContractAddress = "postage-stamp-address"
optionNamePostageContractStartBlock = "postage-stamp-start-block"
optionNamePriceOracleAddress = "price-oracle-address"
optionNameRedistributionAddress = "redistribution-address"
optionNameStakingAddress = "staking-address"
optionNameBlockTime = "block-time"
optionWarmUpTime = "warmup-time"
optionNameMainNet = "mainnet"
optionNameRetrievalCaching = "cache-retrieval"
optionNameDevReserveCapacity = "dev-reserve-capacity"
optionNameResync = "resync"
optionNamePProfBlock = "pprof-profile"
optionNamePProfMutex = "pprof-mutex"
optionNameStaticNodes = "static-nodes"
optionNameAllowPrivateCIDRs = "allow-private-cidrs"
optionNameSleepAfter = "sleep-after"
optionNameRestrictedAPI = "restricted"
optionNameTokenEncryptionKey = "token-encryption-key"
optionNameAdminPasswordHash = "admin-password"
optionNameUsePostageSnapshot = "use-postage-snapshot"
optionNameStorageIncentivesEnable = "storage-incentives-enable"
optionNameStateStoreCacheCapacity = "statestore-cache-capacity"
optionNameTargetNeighborhood = "target-neighborhood"
optionNameNeighborhoodSuggester = "neighborhood-suggester"
optionNameWhitelistedWithdrawalAddress = "withdrawal-addresses-whitelist"
)

// nolint:gochecknoinits
Expand Down Expand Up @@ -304,6 +305,7 @@ func (c *command) setAllFlags(cmd *cobra.Command) {
cmd.Flags().Uint64(optionNameStateStoreCacheCapacity, 100_000, "lru memory caching capacity in number of statestore entries")
cmd.Flags().String(optionNameTargetNeighborhood, "", "neighborhood to target in binary format (ex: 111111001) for mining the initial overlay")
cmd.Flags().String(optionNameNeighborhoodSuggester, "https://api.swarmscan.io/v1/network/neighborhoods/suggestion", "suggester for target neighborhood")
cmd.Flags().StringSlice(optionNameWhitelistedWithdrawalAddress, []string{}, "withdrawal target addresses")
}

func newLogger(cmd *cobra.Command, verbosity string) (log.Logger, error) {
Expand Down
1 change: 1 addition & 0 deletions cmd/bee/cmd/start.go
Original file line number Diff line number Diff line change
Expand Up @@ -345,6 +345,7 @@ func buildBeeNode(ctx context.Context, c *command, cmd *cobra.Command, logger lo
StatestoreCacheCapacity: c.config.GetUint64(optionNameStateStoreCacheCapacity),
TargetNeighborhood: c.config.GetString(optionNameTargetNeighborhood),
NeighborhoodSuggester: neighborhoodSuggester,
WhitelistedWithdrawalAddress: c.config.GetStringSlice(optionNameWhitelistedWithdrawalAddress),
})

return b, err
Expand Down
43 changes: 43 additions & 0 deletions openapi/SwarmDebug.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -689,6 +689,41 @@ paths:
$ref: "SwarmCommon.yaml#/components/responses/500"
default:
description: Default response
"/wallet/withdraw/{coin}":
post:
summary: Allows withdrawals of BZZ or xDAI to provided (whitelisted) address
tags:
- Wallet
parameters:
- in: query
name: amount
required: true
schema:
$ref: "#/components/schemas/BigInt"
- in: query
name: address
required: true
schema:
$ref: "#/components/schemas/EthereumAddress"
- in: path
name: coin
required: true
schema:
$ref: "#/components/schemas/SwarmAddress"
responses:
"200":
content:
application/json:
schema:
$ref: '#/components/schemas/WalletTxResponse'
description: OK
"400":
$ref: "SwarmCommon.yaml#/components/responses/400"
description: Amount greater than ballance or coin is other than BZZ/xDAI
"500":
$ref: "SwarmCommon.yaml#/components/responses/500"
default:
description: Default response

"/transactions":
get:
Expand Down Expand Up @@ -1133,3 +1168,11 @@ paths:
$ref: "SwarmCommon.yaml#/components/responses/400"
default:
description: Default response.

components:
schemas:
WalletTxResponse:
type: object
properties:
transactionHash:
$ref: "#/components/schemas/TransactionHash"
7 changes: 7 additions & 0 deletions pkg/api/api.go
Original file line number Diff line number Diff line change
Expand Up @@ -197,6 +197,8 @@ type Service struct {
erc20Service erc20.Service
chainID int64

whitelistedWithdrawalAddress []common.Address

preMapHooks map[string]func(v string) (string, error)
validate *validator.Validate

Expand Down Expand Up @@ -254,6 +256,7 @@ type ExtraOptions struct {
func New(
publicKey, pssPublicKey ecdsa.PublicKey,
ethereumAddress common.Address,
whitelistedWithdrawalAddress []string,
logger log.Logger,
transaction transaction.Service,
batchStore postage.Storer,
Expand Down Expand Up @@ -303,6 +306,10 @@ func New(
})
s.stamperStore = stamperStore

for _, v := range whitelistedWithdrawalAddress {
s.whitelistedWithdrawalAddress = append(s.whitelistedWithdrawalAddress, common.HexToAddress(v))
}

return s
}

Expand Down
5 changes: 3 additions & 2 deletions pkg/api/api_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -132,6 +132,7 @@ type testServerOptions struct {
RedistributionAgent *storageincentives.Agent
NodeStatus *status.Service
PinIntegrity api.PinIntegrity
WhitelistedAddr string
}

func newTestServer(t *testing.T, o testServerOptions) (*http.Client, *websocket.Conn, string, *chanStorer) {
Expand Down Expand Up @@ -210,7 +211,7 @@ func newTestServer(t *testing.T, o testServerOptions) (*http.Client, *websocket.
o.BeeMode = api.FullMode
}

s := api.New(o.PublicKey, o.PSSPublicKey, o.EthereumAddress, o.Logger, transaction, o.BatchStore, o.BeeMode, true, true, backend, o.CORSAllowedOrigins, inmemstore.New())
s := api.New(o.PublicKey, o.PSSPublicKey, o.EthereumAddress, []string{o.WhitelistedAddr}, o.Logger, transaction, o.BatchStore, o.BeeMode, true, true, backend, o.CORSAllowedOrigins, inmemstore.New())
testutil.CleanupCloser(t, s)

s.SetP2P(o.P2P)
Expand Down Expand Up @@ -395,7 +396,7 @@ func TestParseName(t *testing.T) {
pk, _ := crypto.GenerateSecp256k1Key()
signer := crypto.NewDefaultSigner(pk)

s := api.New(pk.PublicKey, pk.PublicKey, common.Address{}, log, nil, nil, 1, false, false, nil, []string{"*"}, inmemstore.New())
s := api.New(pk.PublicKey, pk.PublicKey, common.Address{}, nil, log, nil, nil, 1, false, false, nil, []string{"*"}, inmemstore.New())
s.Configure(signer, nil, nil, api.Options{}, api.ExtraOptions{Resolver: tC.res}, 1, nil)
s.MountAPI()

Expand Down
1 change: 1 addition & 0 deletions pkg/api/export_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -95,6 +95,7 @@ type (
PostageStampBucketsResponse = postageStampBucketsResponse
BucketData = bucketData
WalletResponse = walletResponse
WalletTxResponse = walletTxResponse
GetStakeResponse = getStakeResponse
WithdrawAllStakeResponse = withdrawAllStakeResponse
StatusSnapshotResponse = statusSnapshotResponse
Expand Down
6 changes: 6 additions & 0 deletions pkg/api/router.go
Original file line number Diff line number Diff line change
Expand Up @@ -491,6 +491,12 @@ func (s *Service) mountBusinessDebug(restricted bool) {
handle("/wallet", jsonhttp.MethodHandler{
"GET": http.HandlerFunc(s.walletHandler),
})
handle("/wallet/withdraw/{coin}", jsonhttp.MethodHandler{
"POST": web.ChainHandlers(
s.gasConfigMiddleware("wallet withdraw"),
web.FinalHandlerFunc(s.walletWithdrawHandler),
),
})
}
}

Expand Down
Loading

0 comments on commit 4f32231

Please sign in to comment.