Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: implement approve oracle upgrade tx #582

Merged
merged 54 commits into from
Jan 4, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
54 commits
Select commit Hold shift + click to select a range
3893eae
feat: add extra commission rate flags to genoracle cmd
audtlr24 Dec 19, 2022
8330472
feat: add v2.1.0 upgrade handler (#552)
0xHansLee Dec 15, 2022
eda304c
ci: make actions work for main branch (#555)
Dec 16, 2022
fecab14
feat: add oracle upgrade proposal tx & cli
audtlr24 Dec 26, 2022
af4a238
feat: add test code
audtlr24 Dec 26, 2022
402eeb1
feat: add oracle upgrade proposal tx & cli
audtlr24 Dec 26, 2022
468a132
feat: add test code
audtlr24 Dec 26, 2022
31557d5
Merge remote-tracking branch 'origin/ft/569/oracle-upgrade-handler' i…
audtlr24 Dec 26, 2022
ec72841
feat: proto for oracle upgrade and its skeleton
Dec 26, 2022
8eec577
fix test
Dec 26, 2022
69bc58b
add event type of oracle upgrade
Dec 26, 2022
860223d
feat: add oracle upgrade to EndBlocker
audtlr24 Dec 26, 2022
909c3d8
add oracle upgrade key
Dec 27, 2022
07b94cc
fix
audtlr24 Dec 27, 2022
cb6b661
fix
audtlr24 Dec 27, 2022
1ee72d5
fix
audtlr24 Dec 27, 2022
34fee18
fix
audtlr24 Dec 27, 2022
660d959
Merge remote-tracking branch 'origin/ft/569/oracle-upgrade-handler' i…
audtlr24 Dec 27, 2022
12f0e02
feat: add upgrade oracle tx cli
audtlr24 Dec 27, 2022
c634f6f
Merge remote-tracking branch 'origin/ft/570/upgrade-endblocker' into …
audtlr24 Dec 27, 2022
6ebe8b6
feat: add upgrade oracle keeper
audtlr24 Dec 27, 2022
f290bf2
feat: add test code for oracle upgrade
audtlr24 Dec 27, 2022
61e8e4e
Merge remote-tracking branch 'origin/ft/570/upgrade-endblocker' into …
Dec 27, 2022
c66ff61
remove duplicated grpc query
Dec 27, 2022
f73a2ca
use the same request/response message for approval of oracle upgrade
Dec 28, 2022
44a3f47
fix
Dec 28, 2022
442479b
Revert "fix"
Dec 28, 2022
5da5d80
Revert "use the same request/response message for approval of oracle …
Dec 28, 2022
b7a94d9
Merge remote-tracking branch 'origin/ft/575/upgrade-proto' into ft/57…
audtlr24 Dec 28, 2022
9630dfb
fix
audtlr24 Dec 28, 2022
db97922
chore: rename ApproveOracleRegistration to reuse
Dec 28, 2022
0b4fae8
feat: implement approve oracle upgrade tx
Dec 29, 2022
d5866b7
add test
Dec 29, 2022
ea8f814
fix lint
Dec 29, 2022
c2d2532
fix
Dec 29, 2022
a3cd3e3
fix test
Dec 29, 2022
9b5944b
add msg server
Dec 29, 2022
115bb01
fix
Dec 29, 2022
d462a4c
fix
Dec 29, 2022
b54727f
feat: improve apply oracle using OracleUpgradeQueue
audtlr24 Dec 30, 2022
a23289e
Revert "feat: improve apply oracle using OracleUpgradeQueue"
audtlr24 Dec 30, 2022
4fe4352
remove duplicated validation
Dec 30, 2022
df49732
delete unnecessary test
Dec 30, 2022
159a4fe
fix
audtlr24 Dec 30, 2022
1c69a6d
review applied
Dec 30, 2022
41d0d4b
fix
audtlr24 Jan 2, 2023
272412f
rename var
Jan 3, 2023
7ed8894
Update x/oracle/keeper/upgrade_test.go
audtlr24 Jan 3, 2023
e992219
Merge branch 'ft/571/upgrade-oracle-tx' into ft/na/rename-approve-ora…
0xHansLee Jan 3, 2023
19d1163
Merge remote-tracking branch 'origin/main' into ft/na/rename-approve-…
Jan 4, 2023
b283a3e
fix
Jan 4, 2023
dbd7886
Merge remote-tracking branch 'origin/ft/na/rename-approve-oracle-reg'…
Jan 4, 2023
1fceade
fix
Jan 4, 2023
0104a89
Merge remote-tracking branch 'origin/main' into ft/574/approve-oracle…
Jan 4, 2023
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions proto/panacea/oracle/v2/tx.proto
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,7 @@ message MsgApproveOracleRegistration {

// ApprovalSharingOracleKey defines approval for sharing oracle key encrypted with target oracle's node public key
message ApprovalSharingOracleKey {
// approver's unique ID
string unique_id = 1;
string approver_oracle_address = 2;
string target_oracle_address = 3;
Expand Down
14 changes: 13 additions & 1 deletion x/oracle/keeper/msg_server_oracle.go
Original file line number Diff line number Diff line change
Expand Up @@ -67,6 +67,18 @@ func (m msgServer) UpgradeOracle(goCtx context.Context, msg *types.MsgUpgradeOra
}

func (m msgServer) ApproveOracleUpgrade(goCtx context.Context, msg *types.MsgApproveOracleUpgrade) (*types.MsgApproveOracleUpgradeResponse, error) {
// TODO: Implementation
ctx := sdk.UnwrapSDKContext(goCtx)

if err := m.Keeper.ApproveOracleUpgrade(ctx, msg); err != nil {
return nil, err
}

ctx.EventManager().EmitEvent(
sdk.NewEvent(
sdk.EventTypeMessage,
sdk.NewAttribute(sdk.AttributeKeyModule, types.ModuleName),
),
)

return &types.MsgApproveOracleUpgradeResponse{}, nil
}
82 changes: 44 additions & 38 deletions x/oracle/keeper/oracle.go
Original file line number Diff line number Diff line change
Expand Up @@ -12,25 +12,21 @@ import (
func (k Keeper) RegisterOracle(ctx sdk.Context, msg *types.MsgRegisterOracle) error {
oracleRegistration := types.NewOracleRegistration(msg)

if err := oracleRegistration.ValidateBasic(); err != nil {
return err
}

Comment on lines -15 to -18
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

As commented in the previous PR, I deleted this validation.

params := k.GetParams(ctx)
if params.UniqueId != oracleRegistration.UniqueId {
return sdkerrors.Wrapf(types.ErrOracleRegistration, "is not match the currently active uniqueID")
if params.UniqueId != msg.UniqueId {
return sdkerrors.Wrapf(types.ErrRegisterOracle, types.ErrInvalidUniqueID.Error())
}

if oracle, err := k.GetOracle(ctx, oracleRegistration.OracleAddress); !errors.Is(types.ErrOracleNotFound, err) {
if oracle != nil {
return sdkerrors.Wrapf(types.ErrOracleRegistration, "already registered oracle. address(%s)", oracleRegistration.OracleAddress)
} else {
return sdkerrors.Wrapf(types.ErrOracleRegistration, err.Error())
}
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Modified to return an error if the OracleRegistration has been stored already regardless of whether Oracle has been registered.
That is, re-requests to be shared the oracle private key again are not considered.
The reason for this is that exploits of re-requests are expected to be possible.

For example, an oracle may be free to set a new commission rate overriding the commission max rate and commission max change rate initially set via a RegisterOracle re-request.
I can't think of a proper way to prevent this, so I'd like to limit the re-request feature.

Since there is no way for oracles to be re-shared the oracle private key, it is necessary to safely manage the shared oracle private key or the node private key that can decrypt the EncryptedOraclePrivKey stored on the chain.
If all keys are lost, oracle will have to request a new registration with a new oracle address.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

understand. In the current situation, if Oracle loses the key, the only way is to change the address and request a new registration.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

In the current situation, if Oracle loses the key, the only way is to change the address and request a new registration.

Exactly.

existing, err := k.GetOracleRegistration(ctx, msg.GetUniqueId(), msg.GetOracleAddress())
if err != nil && !errors.Is(err, types.ErrOracleRegistrationNotFound) {
return sdkerrors.Wrapf(types.ErrRegisterOracle, err.Error())
}
if existing != nil {
return sdkerrors.Wrapf(types.ErrRegisterOracle, fmt.Sprintf("already registered oracle. address(%s)", msg.OracleAddress))
}

if err := k.SetOracleRegistration(ctx, oracleRegistration); err != nil {
return err
return sdkerrors.Wrapf(types.ErrRegisterOracle, err.Error())
}

ctx.EventManager().EmitEvent(
Expand All @@ -40,20 +36,27 @@ func (k Keeper) RegisterOracle(ctx sdk.Context, msg *types.MsgRegisterOracle) er
sdk.NewAttribute(types.AttributeKeyOracleAddress, oracleRegistration.OracleAddress),
),
)

return nil
}

func (k Keeper) ApproveOracleRegistration(ctx sdk.Context, msg *types.MsgApproveOracleRegistration) error {

if err := k.validateApproveOracleRegistration(ctx, msg); err != nil {
// validate approval for oracle registration
if err := k.validateApprovalSharingOracleKey(ctx, msg.GetApprovalSharingOracleKey(), msg.GetSignature()); err != nil {
return sdkerrors.Wrapf(types.ErrApproveOracleRegistration, err.Error())
}

// get oracle registration
oracleRegistration, err := k.GetOracleRegistration(ctx, msg.ApprovalSharingOracleKey.UniqueId, msg.ApprovalSharingOracleKey.TargetOracleAddress)
if err != nil {
return sdkerrors.Wrapf(types.ErrApproveOracleRegistration, err.Error())
}

// if EncryptedOraclePrivKey is already set, return error
if oracleRegistration.EncryptedOraclePrivKey != nil {
return sdkerrors.Wrapf(types.ErrApproveOracleRegistration, "already approved oracle registration. if you want to be shared oracle private key again, please register oracle again")
}

Comment on lines +56 to +59
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Instead of checking that if oracle is set by k.HasOracle() which was in validateApproveOracleRegistration, it returns error if the oracleRegistration.EncryptedOraclePrivKey is not nil.
That means someone approved the oracle registration, so that the EncryptedOraclePrivKey is not nil.

oracleRegistration.EncryptedOraclePrivKey = msg.ApprovalSharingOracleKey.EncryptedOraclePrivKey

// add an encrypted oracle private key to oracleRegistration
Expand Down Expand Up @@ -88,33 +91,31 @@ func (k Keeper) ApproveOracleRegistration(ctx sdk.Context, msg *types.MsgApprove

}

// validateApproveOracleRegistration checks signature
func (k Keeper) validateApproveOracleRegistration(ctx sdk.Context, msg *types.MsgApproveOracleRegistration) error {

// validateApprovalSharingOracleKey validate unique ID of ApprovalSharingOracleKey and its signature
func (k Keeper) validateApprovalSharingOracleKey(ctx sdk.Context, approval *types.ApprovalSharingOracleKey, signature []byte) error {
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This validation function is used in both ApproveOracleRegistration and ApproveOracleUpgrade.

params := k.GetParams(ctx)
targetOracleAddress := msg.ApprovalSharingOracleKey.TargetOracleAddress

// check unique id
if msg.ApprovalSharingOracleKey.UniqueId != params.UniqueId {
if approval.UniqueId != params.UniqueId {
return types.ErrInvalidUniqueID
}

// verify signature
if err := k.VerifyOracleSignature(ctx, msg.ApprovalSharingOracleKey, msg.Signature); err != nil {
return err
// check if the approver oracle exists
isActive, err := k.IsActiveOracle(ctx, approval.ApproverOracleAddress)
if err != nil {
return fmt.Errorf("error occurs while checking if the oracle(%s) exists: %w", approval.ApproverOracleAddress, err)
}

if msg.ApprovalSharingOracleKey.EncryptedOraclePrivKey == nil {
return fmt.Errorf("encrypted oracle private key is nil")
if !isActive {
return fmt.Errorf("oracle(%s) is not an active oracle", approval.ApproverOracleAddress)
}

// check if the oracle has been already registered
hasOracle, err := k.HasOracle(ctx, targetOracleAddress)
if err != nil {
// verify signature
if err := k.VerifyOracleSignature(ctx, approval, signature); err != nil {
return err
}
if hasOracle {
return fmt.Errorf("already registered oracle. address(%s)", targetOracleAddress)

if approval.EncryptedOraclePrivKey == nil {
return fmt.Errorf("encrypted oracle private key is empty")
}

return nil
Expand Down Expand Up @@ -189,12 +190,12 @@ func (k Keeper) GetOracleRegistration(ctx sdk.Context, uniqueID, address string)
store := ctx.KVStore(k.storeKey)
accAddr, err := sdk.AccAddressFromBech32(address)
if err != nil {
return nil, err
return nil, sdkerrors.Wrapf(types.ErrGetOracleRegistration, err.Error())
}
key := types.GetOracleRegistrationKey(uniqueID, accAddr)
bz := store.Get(key)
if bz == nil {
return nil, sdkerrors.Wrapf(types.ErrGetOracleRegistration, "oracle registration not found")
return nil, types.ErrOracleRegistrationNotFound
}

oracleRegistration := &types.OracleRegistration{}
Expand Down Expand Up @@ -249,7 +250,7 @@ func (k Keeper) GetOracle(ctx sdk.Context, address string) (*types.Oracle, error
store := ctx.KVStore(k.storeKey)
accAddr, err := sdk.AccAddressFromBech32(address)
if err != nil {
return nil, err
return nil, sdkerrors.Wrapf(types.ErrGetOracle, err.Error())
}
key := types.GetOracleKey(accAddr)
bz := store.Get(key)
Expand All @@ -267,12 +268,17 @@ func (k Keeper) GetOracle(ctx sdk.Context, address string) (*types.Oracle, error
return oracle, nil
}

func (k Keeper) HasOracle(ctx sdk.Context, address string) (bool, error) {
store := ctx.KVStore(k.storeKey)
accAddr, err := sdk.AccAddressFromBech32(address)
func (k Keeper) IsActiveOracle(ctx sdk.Context, oracleAddress string) (bool, error) {
oracle, err := k.GetOracle(ctx, oracleAddress)
if err != nil {
return false, err
}

return store.Has(types.GetOracleKey(accAddr)), nil
params := k.GetParams(ctx)

if oracle.GetUniqueId() != params.GetUniqueId() {
return false, types.ErrInvalidUniqueID
}

return true, nil
}
89 changes: 15 additions & 74 deletions x/oracle/keeper/oracle_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,6 @@ import (
"github.com/cosmos/cosmos-sdk/crypto/keys/secp256k1"
cryptotypes "github.com/cosmos/cosmos-sdk/crypto/types"
sdk "github.com/cosmos/cosmos-sdk/types"
sdkerrors "github.com/cosmos/cosmos-sdk/types/errors"
"github.com/medibloc/panacea-core/v2/types/testsuite"
"github.com/medibloc/panacea-core/v2/x/oracle/types"
"github.com/stretchr/testify/suite"
Expand Down Expand Up @@ -133,10 +132,11 @@ func (suite *oracleTestSuite) TestRegisterOracleSuccess() {
suite.Require().Equal(suite.oracleCommissionMaxChangeRate, oracleFromKeeper.OracleCommissionMaxChangeRate)
}

func (suite *oracleTestSuite) TestRegisterOracleFailedValidateToMsgOracleRegistration() {
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Accordingly this, deleted validation test code.

func (suite *oracleTestSuite) TestRegisterOracleAlreadyExistOracleRegistration() {
ctx := suite.Ctx

msgRegisterOracle := &types.MsgRegisterOracle{
UniqueId: suite.uniqueID,
OracleAddress: suite.oracleAccAddr.String(),
NodePubKey: suite.nodePubKey.SerializeCompressed(),
NodePubKeyRemoteReport: suite.nodePubKeyRemoteReport,
Expand All @@ -148,76 +148,12 @@ func (suite *oracleTestSuite) TestRegisterOracleFailedValidateToMsgOracleRegistr
OracleCommissionMaxChangeRate: suite.oracleCommissionMaxChangeRate,
}

// first registration
err := suite.OracleKeeper.RegisterOracle(ctx, msgRegisterOracle)
suite.Require().Error(err, sdkerrors.ErrInvalidRequest)
suite.Require().ErrorContains(err, "uniqueID is empty")

msgRegisterOracle.UniqueId = suite.uniqueID
msgRegisterOracle.NodePubKey = nil
err = suite.OracleKeeper.RegisterOracle(ctx, msgRegisterOracle)
suite.Require().Error(err, sdkerrors.ErrInvalidRequest)
suite.Require().ErrorContains(err, "node public key is empty")

msgRegisterOracle.NodePubKey = []byte("invalidNodePubKey")
err = suite.OracleKeeper.RegisterOracle(ctx, msgRegisterOracle)
suite.Require().Error(err, sdkerrors.ErrInvalidRequest)
suite.Require().ErrorContains(err, "invalid node public key")

msgRegisterOracle.NodePubKey = suite.nodePubKey.SerializeCompressed()
msgRegisterOracle.NodePubKeyRemoteReport = nil
err = suite.OracleKeeper.RegisterOracle(ctx, msgRegisterOracle)
suite.Require().Error(err, sdkerrors.ErrInvalidRequest)
suite.Require().ErrorContains(err, "remote report of node public key is empty")

msgRegisterOracle.NodePubKeyRemoteReport = suite.nodePubKeyRemoteReport
msgRegisterOracle.TrustedBlockHeight = 0
err = suite.OracleKeeper.RegisterOracle(ctx, msgRegisterOracle)
suite.Require().Error(err, sdkerrors.ErrInvalidRequest)
suite.Require().ErrorContains(err, "trusted block height must be greater than zero")

msgRegisterOracle.TrustedBlockHeight = suite.trustedBlockHeight
msgRegisterOracle.TrustedBlockHash = nil
err = suite.OracleKeeper.RegisterOracle(ctx, msgRegisterOracle)
suite.Require().Error(err, sdkerrors.ErrInvalidRequest)
suite.Require().ErrorContains(err, "trusted block hash should not be nil")

msgRegisterOracle.TrustedBlockHash = suite.trustedBlockHash
msgRegisterOracle.OracleCommissionRate = sdk.NewInt(-1).ToDec()
err = suite.OracleKeeper.RegisterOracle(ctx, msgRegisterOracle)
suite.Require().Error(err, sdkerrors.ErrInvalidRequest)
suite.Require().ErrorContains(err, "oracleCommissionRate must be between 0 and OracleCommissionMaxRate")

msgRegisterOracle.OracleCommissionRate = sdk.NewInt(2).ToDec()
err = suite.OracleKeeper.RegisterOracle(ctx, msgRegisterOracle)
suite.Require().Error(err, sdkerrors.ErrInvalidRequest)
suite.Require().ErrorContains(err, "oracleCommissionRate must be between 0 and OracleCommissionMaxRate")

events := suite.Ctx.EventManager().Events()
suite.Require().Equal(0, len(events))
}

func (suite *oracleTestSuite) TestRegisterOracleAlreadyExistOracle() {
ctx := suite.Ctx

oracle := types.NewOracle(suite.oracleAccAddr.String(), suite.uniqueID, suite.endpoint, suite.oracleCommissionRate, suite.oracleCommissionMaxRate, suite.oracleCommissionMaxChangeRate, ctx.BlockTime())
err := suite.OracleKeeper.SetOracle(ctx, oracle)
suite.Require().NoError(err)

msgRegisterOracle := &types.MsgRegisterOracle{
UniqueId: suite.uniqueID,
OracleAddress: suite.oracleAccAddr.String(),
NodePubKey: suite.nodePubKey.SerializeCompressed(),
NodePubKeyRemoteReport: suite.nodePubKeyRemoteReport,
TrustedBlockHeight: suite.trustedBlockHeight,
TrustedBlockHash: suite.trustedBlockHash,
Endpoint: suite.endpoint,
OracleCommissionRate: suite.oracleCommissionRate,
OracleCommissionMaxRate: suite.oracleCommissionMaxRate,
OracleCommissionMaxChangeRate: suite.oracleCommissionMaxChangeRate,
}

err = suite.OracleKeeper.RegisterOracle(ctx, msgRegisterOracle)
suite.Require().Error(err, types.ErrOracleRegistration)
suite.Require().Error(err, types.ErrRegisterOracle)
suite.Require().ErrorContains(err, fmt.Sprintf("already registered oracle. address(%s)", msgRegisterOracle.OracleAddress))
}

Expand All @@ -238,13 +174,17 @@ func (suite *oracleTestSuite) TestRegisterOracleNotSameUniqueID() {
}

err := suite.OracleKeeper.RegisterOracle(ctx, msgRegisterOracle)
suite.Require().Error(err, types.ErrOracleRegistration)
suite.Require().ErrorContains(err, "is not match the currently active uniqueID")
suite.Require().Error(err, types.ErrRegisterOracle)
suite.Require().ErrorContains(err, types.ErrInvalidUniqueID.Error())
}

func (suite *oracleTestSuite) TestApproveOracleRegistrationSuccess() {
ctx := suite.Ctx

oracle := types.NewOracle(suite.oracleAccAddr.String(), suite.uniqueID, suite.endpoint, suite.oracleCommissionRate, suite.oracleCommissionMaxRate, suite.oracleCommissionMaxChangeRate, ctx.BlockTime())
err := suite.OracleKeeper.SetOracle(ctx, oracle)
suite.Require().NoError(err)

msgRegisterOracle := &types.MsgRegisterOracle{
UniqueId: suite.uniqueID,
OracleAddress: suite.oracleAccAddr.String(),
Expand All @@ -258,7 +198,7 @@ func (suite *oracleTestSuite) TestApproveOracleRegistrationSuccess() {
OracleCommissionMaxChangeRate: suite.oracleCommissionMaxChangeRate,
}

err := suite.OracleKeeper.RegisterOracle(ctx, msgRegisterOracle)
err = suite.OracleKeeper.RegisterOracle(ctx, msgRegisterOracle)
suite.Require().NoError(err)

encryptedOraclePrivKey, err := btcec.Encrypt(suite.nodePubKey, suite.oraclePrivKey.Serialize())
Expand Down Expand Up @@ -384,7 +324,7 @@ func (suite *oracleTestSuite) TestApproveOracleRegistrationFailedInvalidSignatur
suite.Require().Error(err, "failed to signature validation")
}

func (suite *oracleTestSuite) TestApproveOracleRegistrationFailedAlreadyExistOracle() {
func (suite *oracleTestSuite) TestApproveOracleRegistrationFailedAlreadyApprovedOracleRegistration() {
ctx := suite.Ctx

oracle := types.NewOracle(suite.oracleAccAddr.String(), suite.uniqueID, suite.endpoint, suite.oracleCommissionRate, suite.oracleCommissionMaxRate, suite.oracleCommissionMaxChangeRate, ctx.BlockTime())
Expand All @@ -405,6 +345,7 @@ func (suite *oracleTestSuite) TestApproveOracleRegistrationFailedAlreadyExistOra
}

oracleRegistration := types.NewOracleRegistration(msgRegisterOracle)
oracleRegistration.EncryptedOraclePrivKey = []byte("already registered")

err = suite.OracleKeeper.SetOracleRegistration(ctx, oracleRegistration)
suite.Require().NoError(err)
Expand All @@ -426,8 +367,8 @@ func (suite *oracleTestSuite) TestApproveOracleRegistrationFailedAlreadyExistOra
msgApproveOracleRegistration := types.NewMsgApproveOracleRegistration(approveOracleRegistration, signature.Serialize())

err = suite.OracleKeeper.ApproveOracleRegistration(ctx, msgApproveOracleRegistration)
suite.Require().Error(err, types.ErrOracleRegistration)
suite.Require().ErrorContains(err, fmt.Sprintf("already registered oracle. address(%s)", msgRegisterOracle.OracleAddress))
suite.Require().Error(err, types.ErrRegisterOracle)
suite.Require().ErrorContains(err, "already approved oracle registration")
}

func (suite *oracleTestSuite) TestUpdateOracleInfoSuccess() {
Expand Down
44 changes: 44 additions & 0 deletions x/oracle/keeper/upgrade.go
Original file line number Diff line number Diff line change
Expand Up @@ -156,3 +156,47 @@ func (k Keeper) GetAllOracleUpgradeList(ctx sdk.Context) ([]types.OracleUpgrade,

return oracleUpgrades, nil
}

func (k Keeper) ApproveOracleUpgrade(ctx sdk.Context, msg *types.MsgApproveOracleUpgrade) error {
// validate approval for oracle upgrade
if err := k.validateApprovalSharingOracleKey(ctx, msg.GetApprovalSharingOracleKey(), msg.GetSignature()); err != nil {
return sdkerrors.Wrapf(types.ErrApproveOracleUpgrade, err.Error())
}

// get oracle upgrade and upgrade info
upgradeInfo, err := k.GetOracleUpgradeInfo(ctx)
if err != nil {
return sdkerrors.Wrapf(types.ErrApproveOracleUpgrade, err.Error())
}

oracleUpgrade, err := k.GetOracleUpgrade(ctx, upgradeInfo.GetUniqueId(), msg.GetApprovalSharingOracleKey().GetTargetOracleAddress())
if err != nil {
return sdkerrors.Wrapf(types.ErrApproveOracleUpgrade, err.Error())
}

// if EncryptedOraclePrivKey is already set, return error
if oracleUpgrade.EncryptedOraclePrivKey != nil {
return sdkerrors.Wrapf(types.ErrApproveOracleUpgrade, "already approved oracle upgrade. if you want to be shared oracle private key again, please upgrade oracle again")
}

// update encrypted oracle private key
oracleUpgrade.EncryptedOraclePrivKey = msg.GetApprovalSharingOracleKey().EncryptedOraclePrivKey

// set oracle upgrade
if err := k.SetOracleUpgrade(ctx, oracleUpgrade); err != nil {
return sdkerrors.Wrapf(types.ErrApproveOracleUpgrade, err.Error())
}

// emit event
ctx.EventManager().EmitEvent(
sdk.NewEvent(
types.EventTypeApproveOracleUpgrade,
sdk.NewAttribute(types.AttributeKeyOracleAddress, msg.GetApprovalSharingOracleKey().GetTargetOracleAddress()),
sdk.NewAttribute(types.AttributeKeyUniqueID, upgradeInfo.GetUniqueId()),
),
)

// TODO: add to queue(?) for update unique ID
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

As discussed offline, it seems that you can check if the encryptedOraclePrivKey of OracleUpgrade is not nil without putting it in the queue.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@audtlr24, we probably don't need to use queue to update unique ID for upgraded oracles.
As @gyuguen said, we can know that which oracles are upgraded through the EncryptedOralePrivKey in OracleUpgrade. It makes simpler I think.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Okay, I understand. I will reflect it in PR #584.


return nil
}
Loading