From 2f797c2da2e1333f5dc4d5072a4f1f3a2c4f33bd Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Daria=20Dziuba=C5=82towska?= Date: Tue, 21 Nov 2023 15:19:02 +0100 Subject: [PATCH 1/4] Update getCongestion endpoint to use AccountAddress --- components/restapi/core/accounts.go | 17 ++++++++++++----- components/restapi/core/component.go | 2 +- pkg/restapi/restapi.go | 3 +++ 3 files changed, 16 insertions(+), 6 deletions(-) diff --git a/components/restapi/core/accounts.go b/components/restapi/core/accounts.go index 9b0eaffee..db4348173 100644 --- a/components/restapi/core/accounts.go +++ b/components/restapi/core/accounts.go @@ -17,11 +17,6 @@ import ( ) func congestionForAccountID(c echo.Context) (*apimodels.CongestionResponse, error) { - accountID, err := httpserver.ParseAccountIDParam(c, restapipkg.ParameterAccountID) - if err != nil { - return nil, err - } - 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, ierrors.Wrapf(err, "failed to parse bech32 address %s", c.Param(restapipkg.ParameterBech32Address)) + } + + accountAddress, ok := address.Clone().(*iotago.AccountAddress) + if !ok { + return nil, ierrors.Wrapf(echo.ErrInternalServerError, "failed to parse bech32 address %s", 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) diff --git a/components/restapi/core/component.go b/components/restapi/core/component.go index 806f8e37d..53f2755c5 100644 --- a/components/restapi/core/component.go +++ b/components/restapi/core/component.go @@ -115,7 +115,7 @@ const ( // GET returns the congestion state related to the specified account. (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. diff --git a/pkg/restapi/restapi.go b/pkg/restapi/restapi.go index b1aab4cdb..ad954eff9 100644 --- a/pkg/restapi/restapi.go +++ b/pkg/restapi/restapi.go @@ -30,6 +30,9 @@ const ( // ParameterAccountID is used to identify an account by its ID. ParameterAccountID = "accountID" + // ParameterBech32Address is used to identify an account address by its bech32 address. + ParameterBech32Address = "bech32Address" + // ParameterPeerID is used to identify a peer. ParameterPeerID = "peerID" From 19fb585361c08ad1419072db1aee0f4c5222cc84 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Daria=20Dziuba=C5=82towska?= Date: Tue, 21 Nov 2023 15:29:16 +0100 Subject: [PATCH 2/4] Replace paramAccountID, address review suggestion --- components/restapi/core/accounts.go | 8 ++++---- components/restapi/core/component.go | 2 +- pkg/restapi/restapi.go | 3 --- 3 files changed, 5 insertions(+), 8 deletions(-) diff --git a/components/restapi/core/accounts.go b/components/restapi/core/accounts.go index db4348173..0eb820879 100644 --- a/components/restapi/core/accounts.go +++ b/components/restapi/core/accounts.go @@ -34,10 +34,10 @@ 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, ierrors.Wrapf(err, "failed to parse bech32 address %s", c.Param(restapipkg.ParameterBech32Address)) + return nil, err } - accountAddress, ok := address.Clone().(*iotago.AccountAddress) + accountAddress, ok := address.(*iotago.AccountAddress) if !ok { return nil, ierrors.Wrapf(echo.ErrInternalServerError, "failed to parse bech32 address %s", c.Param(restapipkg.ParameterBech32Address)) } @@ -115,9 +115,9 @@ func validators(c echo.Context) (*apimodels.ValidatorsResponse, error) { } func validatorByAccountID(c echo.Context) (*apimodels.ValidatorResponse, error) { - accountID, err := httpserver.ParseAccountIDParam(c, restapipkg.ParameterAccountID) + accountID, err := httpserver.ParseAccountIDParam(c, restapipkg.ParameterBech32Address) if err != nil { - return nil, ierrors.Wrapf(err, "failed to parse account ID %s", c.Param(restapipkg.ParameterAccountID)) + return nil, ierrors.Wrapf(err, "failed to parse account ID %s", c.Param(restapipkg.ParameterBech32Address)) } latestCommittedSlot := deps.Protocol.MainEngineInstance().SyncManager.LatestCommitment().Slot() diff --git a/components/restapi/core/component.go b/components/restapi/core/component.go index 53f2755c5..3e8ada8a9 100644 --- a/components/restapi/core/component.go +++ b/components/restapi/core/component.go @@ -127,7 +127,7 @@ const ( // 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. diff --git a/pkg/restapi/restapi.go b/pkg/restapi/restapi.go index ad954eff9..5436b4745 100644 --- a/pkg/restapi/restapi.go +++ b/pkg/restapi/restapi.go @@ -27,9 +27,6 @@ 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 identify an account address by its bech32 address. ParameterBech32Address = "bech32Address" From 5628ef40f254102532e3105be032056cf4710ede Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Daria=20Dziuba=C5=82towska?= Date: Tue, 21 Nov 2023 15:40:08 +0100 Subject: [PATCH 3/4] Update validator endpoint, further renames --- components/restapi/core/accounts.go | 21 +++++++++++++++------ components/restapi/core/component.go | 10 +++++----- pkg/restapi/restapi.go | 4 ++-- 3 files changed, 22 insertions(+), 13 deletions(-) diff --git a/components/restapi/core/accounts.go b/components/restapi/core/accounts.go index 0eb820879..6a4bff320 100644 --- a/components/restapi/core/accounts.go +++ b/components/restapi/core/accounts.go @@ -16,7 +16,7 @@ import ( "github.com/iotaledger/iota.go/v4/nodeclient/apimodels" ) -func congestionForAccountID(c echo.Context) (*apimodels.CongestionResponse, error) { +func congestionByAccountAddress(c echo.Context) (*apimodels.CongestionResponse, error) { commitmentID, err := httpserver.ParseCommitmentIDQueryParam(c, restapipkg.ParameterCommitmentID) if err != nil { return nil, err @@ -32,14 +32,14 @@ func congestionForAccountID(c echo.Context) (*apimodels.CongestionResponse, erro } hrp := deps.Protocol.CommittedAPI().ProtocolParameters().Bech32HRP() - address, err := httpserver.ParseBech32AddressParam(c, hrp, restapipkg.ParameterBech32Address) + address, err := httpserver.ParseBech32AddressParam(c, hrp, restapipkg.ParameterAddress) if err != nil { return nil, err } accountAddress, ok := address.(*iotago.AccountAddress) if !ok { - return nil, ierrors.Wrapf(echo.ErrInternalServerError, "failed to parse bech32 address %s", c.Param(restapipkg.ParameterBech32Address)) + return nil, ierrors.Wrapf(echo.ErrInternalServerError, "failed to assert account address %s", c.Param(restapipkg.ParameterAddress)) } accountID := accountAddress.AccountID() @@ -114,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.ParameterBech32Address) +func validatorByAccountAddress(c echo.Context) (*apimodels.ValidatorResponse, error) { + hrp := deps.Protocol.CommittedAPI().ProtocolParameters().Bech32HRP() + address, err := httpserver.ParseBech32AddressQueryParam(c, hrp, restapipkg.ParameterAddress) if err != nil { - return nil, ierrors.Wrapf(err, "failed to parse account ID %s", c.Param(restapipkg.ParameterBech32Address)) + return nil, ierrors.Wrapf(err, "failed to parse account address %s", c.Param(restapipkg.ParameterAddress)) + } + + accountAddress, ok := address.(*iotago.AccountAddress) + if !ok { + return nil, ierrors.Wrapf(echo.ErrInternalServerError, "failed to assert account address %s", c.Param(restapipkg.ParameterAddress)) } + 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) @@ -128,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 3e8ada8a9..92c69fe39 100644 --- a/components/restapi/core/component.go +++ b/components/restapi/core/component.go @@ -115,7 +115,7 @@ const ( // GET returns the congestion state related to the specified account. (optional query parameters: "commitmentID" to specify the used commitment) // MIMEApplicationJSON => json. // MIMEApplicationVendorIOTASerializerV2 => bytes. - RouteCongestion = "/accounts/:" + restapipkg.ParameterBech32Address + "/congestion" + RouteCongestion = "/accounts/:" + restapipkg.ParameterAddress + "/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.ParameterBech32Address + RouteValidatorsAccount = "/validators/:" + restapipkg.ParameterAddress // 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 5436b4745..cd094afa4 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" - // ParameterBech32Address is used to identify an account address by its bech32 address. - ParameterBech32Address = "bech32Address" + // ParameterAddress is used to identify an account by its address. + ParameterAddress = "address" // ParameterPeerID is used to identify a peer. ParameterPeerID = "peerID" From f4c0817131e45091b2421876bd6c15f45789899a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Daria=20Dziuba=C5=82towska?= Date: Tue, 21 Nov 2023 15:58:45 +0100 Subject: [PATCH 4/4] Address comments --- components/restapi/core/accounts.go | 10 +++++----- components/restapi/core/component.go | 6 +++--- pkg/restapi/restapi.go | 4 ++-- 3 files changed, 10 insertions(+), 10 deletions(-) diff --git a/components/restapi/core/accounts.go b/components/restapi/core/accounts.go index 6a4bff320..0efcdbb59 100644 --- a/components/restapi/core/accounts.go +++ b/components/restapi/core/accounts.go @@ -32,14 +32,14 @@ func congestionByAccountAddress(c echo.Context) (*apimodels.CongestionResponse, } hrp := deps.Protocol.CommittedAPI().ProtocolParameters().Bech32HRP() - address, err := httpserver.ParseBech32AddressParam(c, hrp, restapipkg.ParameterAddress) + 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(echo.ErrInternalServerError, "failed to assert account address %s", c.Param(restapipkg.ParameterAddress)) + return nil, ierrors.Wrapf(httpserver.ErrInvalidParameter, "address %s is not an account address", c.Param(restapipkg.ParameterBech32Address)) } accountID := accountAddress.AccountID() @@ -116,14 +116,14 @@ func validators(c echo.Context) (*apimodels.ValidatorsResponse, error) { func validatorByAccountAddress(c echo.Context) (*apimodels.ValidatorResponse, error) { hrp := deps.Protocol.CommittedAPI().ProtocolParameters().Bech32HRP() - address, err := httpserver.ParseBech32AddressQueryParam(c, hrp, restapipkg.ParameterAddress) + address, err := httpserver.ParseBech32AddressParam(c, hrp, restapipkg.ParameterBech32Address) if err != nil { - return nil, ierrors.Wrapf(err, "failed to parse account address %s", c.Param(restapipkg.ParameterAddress)) + return nil, err } accountAddress, ok := address.(*iotago.AccountAddress) if !ok { - return nil, ierrors.Wrapf(echo.ErrInternalServerError, "failed to assert account address %s", c.Param(restapipkg.ParameterAddress)) + return nil, ierrors.Wrapf(httpserver.ErrInvalidParameter, "address %s is not an account address", c.Param(restapipkg.ParameterBech32Address)) } latestCommittedSlot := deps.Protocol.MainEngineInstance().SyncManager.LatestCommitment().Slot() diff --git a/components/restapi/core/component.go b/components/restapi/core/component.go index 92c69fe39..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.ParameterAddress + "/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. @@ -127,7 +127,7 @@ const ( // GET returns the validator details. // MIMEApplicationJSON => json. // MIMEApplicationVendorIOTASerializerV2 => bytes. - RouteValidatorsAccount = "/validators/:" + restapipkg.ParameterAddress + 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. diff --git a/pkg/restapi/restapi.go b/pkg/restapi/restapi.go index cd094afa4..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" - // ParameterAddress is used to identify an account by its address. - ParameterAddress = "address" + // ParameterBech32Address is used to to represent bech32 address. + ParameterBech32Address = "bech32Address" // ParameterPeerID is used to identify a peer. ParameterPeerID = "peerID"