diff --git a/components/restapi/core/accounts.go b/components/restapi/core/accounts.go index 9b0eaffee..0efcdbb59 100644 --- a/components/restapi/core/accounts.go +++ b/components/restapi/core/accounts.go @@ -16,12 +16,7 @@ import ( "github.com/iotaledger/iota.go/v4/nodeclient/apimodels" ) -func congestionForAccountID(c echo.Context) (*apimodels.CongestionResponse, error) { - accountID, err := httpserver.ParseAccountIDParam(c, restapipkg.ParameterAccountID) - if err != nil { - return nil, err - } - +func congestionByAccountAddress(c echo.Context) (*apimodels.CongestionResponse, error) { commitmentID, err := httpserver.ParseCommitmentIDQueryParam(c, restapipkg.ParameterCommitmentID) if err != nil { return nil, err @@ -36,6 +31,18 @@ func congestionForAccountID(c echo.Context) (*apimodels.CongestionResponse, erro } } + hrp := deps.Protocol.CommittedAPI().ProtocolParameters().Bech32HRP() + address, err := httpserver.ParseBech32AddressParam(c, hrp, restapipkg.ParameterBech32Address) + if err != nil { + return nil, err + } + + accountAddress, ok := address.(*iotago.AccountAddress) + if !ok { + return nil, ierrors.Wrapf(httpserver.ErrInvalidParameter, "address %s is not an account address", c.Param(restapipkg.ParameterBech32Address)) + } + + accountID := accountAddress.AccountID() acc, exists, err := deps.Protocol.MainEngineInstance().Ledger.Account(accountID, commitment.Slot()) if err != nil { return nil, ierrors.Wrapf(echo.ErrInternalServerError, "failed to get account %s from the Ledger: %s", accountID.ToHex(), err) @@ -107,13 +114,21 @@ func validators(c echo.Context) (*apimodels.ValidatorsResponse, error) { return resp, nil } -func validatorByAccountID(c echo.Context) (*apimodels.ValidatorResponse, error) { - accountID, err := httpserver.ParseAccountIDParam(c, restapipkg.ParameterAccountID) +func validatorByAccountAddress(c echo.Context) (*apimodels.ValidatorResponse, error) { + hrp := deps.Protocol.CommittedAPI().ProtocolParameters().Bech32HRP() + address, err := httpserver.ParseBech32AddressParam(c, hrp, restapipkg.ParameterBech32Address) if err != nil { - return nil, ierrors.Wrapf(err, "failed to parse account ID %s", c.Param(restapipkg.ParameterAccountID)) + return nil, err } + + accountAddress, ok := address.(*iotago.AccountAddress) + if !ok { + return nil, ierrors.Wrapf(httpserver.ErrInvalidParameter, "address %s is not an account address", c.Param(restapipkg.ParameterBech32Address)) + } + latestCommittedSlot := deps.Protocol.MainEngineInstance().SyncManager.LatestCommitment().Slot() + accountID := accountAddress.AccountID() accountData, exists, err := deps.Protocol.MainEngineInstance().Ledger.Account(accountID, latestCommittedSlot) if err != nil { return nil, ierrors.Wrapf(echo.ErrInternalServerError, "failed to get account %s from the Ledger: %s", accountID.ToHex(), err) @@ -121,6 +136,7 @@ func validatorByAccountID(c echo.Context) (*apimodels.ValidatorResponse, error) if !exists { return nil, ierrors.Wrapf(echo.ErrNotFound, "account %s not found for latest committedSlot %d", accountID.ToHex(), latestCommittedSlot) } + nextEpoch := deps.Protocol.APIForSlot(latestCommittedSlot).TimeProvider().EpochFromSlot(latestCommittedSlot) + 1 active, err := deps.Protocol.MainEngineInstance().SybilProtection.IsCandidateActive(accountID, nextEpoch) diff --git a/components/restapi/core/component.go b/components/restapi/core/component.go index 806f8e37d..a36c8bd30 100644 --- a/components/restapi/core/component.go +++ b/components/restapi/core/component.go @@ -112,10 +112,10 @@ const ( RouteCommitmentByIndexUTXOChanges = "/commitments/by-index/:" + restapipkg.ParameterSlotIndex + "/utxo-changes" // RouteCongestion is the route for getting the current congestion state and all account related useful details as block issuance credits. - // GET returns the congestion state related to the specified account. (optional query parameters: "commitmentID" to specify the used commitment) + // GET returns the congestion state related to the specified account address. (optional query parameters: "commitmentID" to specify the used commitment) // MIMEApplicationJSON => json. // MIMEApplicationVendorIOTASerializerV2 => bytes. - RouteCongestion = "/accounts/:" + restapipkg.ParameterAccountID + "/congestion" + RouteCongestion = "/accounts/:" + restapipkg.ParameterBech32Address + "/congestion" // RouteValidators is the route for getting informations about the current validators. // GET returns the paginated response with the list of validators. @@ -123,11 +123,11 @@ const ( // MIMEApplicationVendorIOTASerializerV2 => bytes. RouteValidators = "/validators" - // RouteValidatorsAccount is the route for getting details about the validator by its accountID. + // RouteValidatorsAccount is the route for getting details about the validator by its account address. // GET returns the validator details. // MIMEApplicationJSON => json. // MIMEApplicationVendorIOTASerializerV2 => bytes. - RouteValidatorsAccount = "/validators/:" + restapipkg.ParameterAccountID + RouteValidatorsAccount = "/validators/:" + restapipkg.ParameterBech32Address // RouteRewards is the route for getting the rewards for staking or delegation based on staking account or delegation output. // Rewards are decayed up to returned epochEnd index. @@ -345,7 +345,7 @@ func configure() error { }, checkNodeSynced()) routeGroup.GET(RouteCongestion, func(c echo.Context) error { - resp, err := congestionForAccountID(c) + resp, err := congestionByAccountAddress(c) if err != nil { return err } @@ -363,7 +363,7 @@ func configure() error { }, checkNodeSynced()) routeGroup.GET(RouteValidatorsAccount, func(c echo.Context) error { - resp, err := validatorByAccountID(c) + resp, err := validatorByAccountAddress(c) if err != nil { return err } diff --git a/pkg/restapi/restapi.go b/pkg/restapi/restapi.go index b1aab4cdb..4c7f3de96 100644 --- a/pkg/restapi/restapi.go +++ b/pkg/restapi/restapi.go @@ -27,8 +27,8 @@ const ( // ParameterCommitmentID is used to identify a slot commitment by its ID. ParameterCommitmentID = "commitmentID" - // ParameterAccountID is used to identify an account by its ID. - ParameterAccountID = "accountID" + // ParameterBech32Address is used to to represent bech32 address. + ParameterBech32Address = "bech32Address" // ParameterPeerID is used to identify a peer. ParameterPeerID = "peerID"