diff --git a/genesis.go b/genesis.go index dab2980..0f66daa 100644 --- a/genesis.go +++ b/genesis.go @@ -9,29 +9,49 @@ import ( ) func InitGenesis(ctx sdk.Context, k *keeper.Keeper, genesis types.GenesisState) { - k.SetAggregatorOwner(ctx, genesis.AggregatorState.Owner) - k.SetLastRoundId(ctx, genesis.AggregatorState.LastRoundId) - k.SetNextPrice(ctx, genesis.AggregatorState.NextPrice) + if err := k.SetAggregatorOwner(ctx, genesis.AggregatorState.Owner); err != nil { + panic(err) + } + if err := k.SetLastRoundId(ctx, genesis.AggregatorState.LastRoundId); err != nil { + panic(err) + } + if err := k.SetNextPrice(ctx, genesis.AggregatorState.NextPrice); err != nil { + panic(err) + } for id, round := range genesis.AggregatorState.Rounds { - k.SetRound(ctx, id, round) + if err := k.SetRound(ctx, id, round); err != nil { + panic(err) + } } - k.SetEntitlementsOwner(ctx, genesis.EntitlementsState.Owner) + if err := k.SetEntitlementsOwner(ctx, genesis.EntitlementsState.Owner); err != nil { + panic(err) + } for method, enabled := range genesis.EntitlementsState.PublicCapabilities { - k.SetPublicCapability(ctx, method, enabled) + if err := k.SetPublicCapability(ctx, method, enabled); err != nil { + panic(err) + } } for _, entry := range genesis.EntitlementsState.RoleCapabilities { - k.SetRoleCapability(ctx, entry.Method, entry.Role, entry.Enabled) + if err := k.SetRoleCapability(ctx, entry.Method, entry.Role, entry.Enabled); err != nil { + panic(err) + } } for _, entry := range genesis.EntitlementsState.UserRoles { user := sdk.MustAccAddressFromBech32(entry.User) - k.SetUserRole(ctx, user, entry.Role, entry.Enabled) + if err := k.SetUserRole(ctx, user, entry.Role, entry.Enabled); err != nil { + panic(err) + } } - k.SetOwner(ctx, genesis.Owner) + if err := k.SetOwner(ctx, genesis.Owner); err != nil { + panic(err) + } for account, nonce := range genesis.Nonces { address := sdk.MustAccAddressFromBech32(account) - k.SetNonce(ctx, address, nonce) + if err := k.SetNonce(ctx, address, nonce); err != nil { + panic(err) + } } } diff --git a/go.mod b/go.mod index e0e1fcb..6a0fd42 100644 --- a/go.mod +++ b/go.mod @@ -11,6 +11,7 @@ require ( cosmossdk.io/math v1.3.0 cosmossdk.io/store v1.1.1 github.com/cometbft/cometbft v0.38.12 + github.com/cosmos/cosmos-db v1.0.2 github.com/cosmos/cosmos-proto v1.0.0-beta.5 github.com/cosmos/cosmos-sdk v0.50.10 github.com/cosmos/gogoproto v1.7.0 @@ -76,7 +77,6 @@ require ( github.com/cockroachdb/tokenbucket v0.0.0-20230807174530-cc333fc44b06 // indirect github.com/cometbft/cometbft-db v0.11.0 // indirect github.com/cosmos/btcutil v1.0.5 // indirect - github.com/cosmos/cosmos-db v1.0.2 // indirect github.com/cosmos/go-bip39 v1.0.0 // indirect github.com/cosmos/gogogateway v1.2.0 // indirect github.com/cosmos/iavl v1.2.0 // indirect diff --git a/go.work.sum b/go.work.sum index e5a7d48..40ea238 100644 --- a/go.work.sum +++ b/go.work.sum @@ -1,5 +1,7 @@ cloud.google.com/go v0.112.0 h1:tpFCD7hpHFlQ8yPwT3x+QeXqc2T6+n6T+hmABHfDUSM= cloud.google.com/go v0.112.0/go.mod h1:3jEEVwZ/MHU4djK5t5RHuKOA/GbLddgTdVubX1qnPD4= +cloud.google.com/go v0.112.1 h1:uJSeirPke5UNZHIb4SxfZklVSiWWVqW4oXlETwZziwM= +cloud.google.com/go v0.112.1/go.mod h1:+Vbu+Y1UU+I1rjmzeMOb/8RfkKJK2Gyxi1X6jJCZLo4= cloud.google.com/go/accessapproval v1.7.5 h1:uzmAMSgYcnlHa9X9YSQZ4Q1wlfl4NNkZyQgho1Z6p04= cloud.google.com/go/accessapproval v1.7.5/go.mod h1:g88i1ok5dvQ9XJsxpUInWWvUBrIZhyPDPbk4T01OoJ0= cloud.google.com/go/accesscontextmanager v1.8.5 h1:2GLNaNu9KRJhJBFTIVRoPwk6xE5mUDgD47abBq4Zp/I= @@ -100,6 +102,8 @@ cloud.google.com/go/filestore v1.8.1 h1:X5G4y/vrUo1B8Nsz93qSWTMAcM8LXbGUldq33Odc cloud.google.com/go/filestore v1.8.1/go.mod h1:MbN9KcaM47DRTIuLfQhJEsjaocVebNtNQhSLhKCF5GM= cloud.google.com/go/firestore v1.14.0 h1:8aLcKnMPoldYU3YHgu4t2exrKhLQkqaXAGqT0ljrFVw= cloud.google.com/go/firestore v1.14.0/go.mod h1:96MVaHLsEhbvkBEdZgfN+AS/GIkco1LRpH9Xp9YZfzQ= +cloud.google.com/go/firestore v1.15.0 h1:/k8ppuWOtNuDHt2tsRV42yI21uaGnKDEQnRFeBpbFF8= +cloud.google.com/go/firestore v1.15.0/go.mod h1:GWOxFXcv8GZUtYpWHw/w6IuYNux/BtmeVTMmjrm4yhk= cloud.google.com/go/functions v1.16.0 h1:IWVylmK5F6hJ3R5zaRW7jI5PrWhCvtBVU4axQLmXSo4= cloud.google.com/go/functions v1.16.0/go.mod h1:nbNpfAG7SG7Duw/o1iZ6ohvL7mc6MapWQVpqtM29n8k= cloud.google.com/go/gkebackup v1.3.5 h1:iuE8KNtTsPOc79qeWoNS8zOWoXPD9SAdOmwgxtlCmh8= @@ -251,7 +255,8 @@ github.com/Joker/jade v1.1.3/go.mod h1:T+2WLyt7VH6Lp0TRxQrUYEs64nRc83wkMQrfeIQKd github.com/Knetic/govaluate v3.0.1-0.20171022003610-9aa49832a739+incompatible h1:1G1pk05UrOh0NlF1oeaaix1x8XzrfjIDK47TY0Zehcw= github.com/Masterminds/semver/v3 v3.2.0 h1:3MEsd0SM6jqZojhjLWWeBY+Kcjy9i6MQAeY7YgDP83g= github.com/Masterminds/semver/v3 v3.2.0/go.mod h1:qvl/7zhW3nngYb5+80sSMF+FG2BjYrf8m9wsX0PNOMQ= -github.com/OpenPeeDeeP/depguard v1.1.1 h1:TSUznLjvp/4IUP+OQ0t/4jF4QUyxIcVX8YnghZdunyA= +github.com/Masterminds/semver/v3 v3.3.0 h1:B8LGeaivUe71a5qox1ICM/JLl0NqZSW5CHyL+hmvYS0= +github.com/Masterminds/semver/v3 v3.3.0/go.mod h1:4V+yj/TJE1HU9XfppCwVMZq3I84lprf4nC11bSS5beM= github.com/OpenPeeDeeP/depguard v1.1.1/go.mod h1:JtAMzWkmFEzDPyAd+W0NHl1lvpQKTvT9jnRVsohBKpc= github.com/ProtonMail/go-crypto v0.0.0-20230828082145-3c4c8a2d2371 h1:kkhsdkhsCvIsutKu5zLMgWtgh9YxGCNAw8Ad8hjwfYg= github.com/ProtonMail/go-crypto v0.0.0-20230828082145-3c4c8a2d2371/go.mod h1:EjAoLdwvbIOoOQr3ihjnSoLZRtE8azugULFRteWMNc0= @@ -325,6 +330,7 @@ github.com/coreos/go-systemd/v22 v22.5.0 h1:RrqgGjYQKalulkV8NGVIfkXQf6YYmOyiJKk8 github.com/coreos/pkg v0.0.0-20160727233714-3ac0863d7acf h1:CAKfRE2YtTUIjjh1bkBtyYFaUT/WmOqsJjgtihT0vMI= github.com/cpuguy83/go-md2man v1.0.10 h1:BSKMNlYxDvnunlTymqtgONjNnaRV1sTpcovwwjF22jk= github.com/cpuguy83/go-md2man/v2 v2.0.3 h1:qMCsGGgs+MAzDFyp9LpAe1Lqy/fY/qCovCm0qnXZOBM= +github.com/cpuguy83/go-md2man/v2 v2.0.4 h1:wfIWP927BUkWJb2NmU/kNDYIBTh/ziUX91+lVfRxZq4= github.com/creachadair/command v0.0.0-20220916173946-56a74cdd66b6 h1:uKuolOJonQOb/2+z/wFSJeVREP6fSoigr/X4Wlfhwwg= github.com/creachadair/command v0.0.0-20220916173946-56a74cdd66b6/go.mod h1:jN7ZJM5YSVtD3SHmkAdN/cOC1dXiqg2Y9K5Sr5a8Nxw= github.com/creack/pty v1.1.9 h1:uDmaGzcdjhF4i/plgjmEsriH11Y0o7RKapEf/LDaM3w= @@ -363,7 +369,6 @@ github.com/fatih/structs v1.1.0 h1:Q7juDM0QtcnhCpeyLGQKyg4TOIghuNXrkL32pHAUMxo= github.com/fatih/structs v1.1.0/go.mod h1:9NiDSp5zOcgEDl+j00MP/WkGVPOlPRLejGD8Ga6PJ7M= github.com/felixge/fgprof v0.9.3 h1:VvyZxILNuCiUCSXtPtYmmtGvb65nqXh2QFWc0Wpf2/g= github.com/felixge/fgprof v0.9.3/go.mod h1:RdbpDgzqYVh/T9fPELJyV7EYJuHB55UTEULNun8eiPw= -github.com/felixge/httpsnoop v1.0.4/go.mod h1:m8KPJKqk1gH5J9DgRY2ASl2lWCfGKXixSwevea8zH2U= github.com/flosch/pongo2/v4 v4.0.2 h1:gv+5Pe3vaSVmiJvh/BZa82b7/00YUGm0PIyVVLop0Hw= github.com/flosch/pongo2/v4 v4.0.2/go.mod h1:B5ObFANs/36VwxxlgKpdchIJHMvHB562PW+BWPhwZD8= github.com/franela/goblin v0.0.0-20200105215937-c9ffbefa60db h1:gb2Z18BhTPJPpLQWj4T+rfKHYCHxRHCtRxhKKjRidVw= @@ -381,7 +386,6 @@ github.com/go-git/go-git/v5 v5.11.0 h1:XIZc1p+8YzypNr34itUfSvYJcv+eYdTnTvOZ2vD3c github.com/go-git/go-git/v5 v5.11.0/go.mod h1:6GFcX2P3NM7FPBfpePbpLd21XxsgdAt+lKqXmCUiUCY= github.com/go-gl/glfw v0.0.0-20190409004039-e6da0acd62b1 h1:QbL/5oDUmRBzO9/Z7Seo6zf912W/a6Sr4Eu0G/3Jho0= github.com/go-gl/glfw/v3.3/glfw v0.0.0-20200222043503-6f7a984d4dc4 h1:WtGNWLvXpe6ZudgnXrq0barxBImvnnJoMEhXAzcbM0I= -github.com/go-logr/logr v1.4.1/go.mod h1:9T104GzyrTigFIr8wt5mBrctHMim0Nb2HLGrmQ40KvY= github.com/go-logr/stdr v1.2.2 h1:hSWxHoqTgW2S2qGc0LTAI563KZ5YKYRhT3MFKZMbjag= github.com/go-logr/stdr v1.2.2/go.mod h1:mMo/vtBO5dYbehREoey6XUKy/eSumjCCveDpRre4VKE= github.com/go-martini/martini v0.0.0-20170121215854-22fa46961aab h1:xveKWz2iaueeTaUgdetzel+U7exyigDYBryyVfV/rZk= @@ -419,6 +423,8 @@ github.com/googleapis/enterprise-certificate-proxy v0.3.2 h1:Vie5ybvEvT75RniqhfF github.com/googleapis/enterprise-certificate-proxy v0.3.2/go.mod h1:VLSiSSBs/ksPL8kq3OBOQ6WRI2QnaFynd1DCjZ62+V0= github.com/googleapis/gax-go/v2 v2.12.0 h1:A+gCJKdRfqXkr+BIRGtZLibNXf0m1f9E4HG56etFpas= github.com/googleapis/gax-go/v2 v2.12.0/go.mod h1:y+aIqrI5eb1YGMVJfuV3185Ts/D7qKpsEkdD5+I6QGU= +github.com/googleapis/gax-go/v2 v2.12.3 h1:5/zPPDvw8Q1SuXjrqrZslrqT7dL/uJT2CQii/cLCKqA= +github.com/googleapis/gax-go/v2 v2.12.3/go.mod h1:AKloxT6GtNbaLm8QTNSidHUVsHYcBHwWRvkNFJUQcS4= github.com/googleapis/google-cloud-go-testing v0.0.0-20210719221736-1c9a4c676720 h1:zC34cGQu69FG7qzJ3WiKW244WfhDC3xxYMeNOX2gtUQ= github.com/googleapis/google-cloud-go-testing v0.0.0-20210719221736-1c9a4c676720/go.mod h1:dvDLG8qkwmyD9a/MJJN3XJcT3xFxOKAvTZGvuZmac9g= github.com/gookit/color v1.5.4 h1:FZmqs7XOyGgCAxmWyPslpiok1k05wmY3SJTytgvYFs0= @@ -434,6 +440,8 @@ github.com/guptarohit/asciigraph v0.5.5 h1:ccFnUF8xYIOUPPY3tmdvRyHqmn1MYI9iv1pLK github.com/guptarohit/asciigraph v0.5.5/go.mod h1:dYl5wwK4gNsnFf9Zp+l06rFiDZ5YtXM6x7SRWZ3KGag= github.com/hashicorp/consul/api v1.25.1 h1:CqrdhYzc8XZuPnhIYZWH45toM0LB9ZeYr/gvpLVI3PE= github.com/hashicorp/consul/api v1.25.1/go.mod h1:iiLVwR/htV7mas/sy0O+XSuEnrdBUUydemjxcUrAt4g= +github.com/hashicorp/consul/api v1.28.2 h1:mXfkRHrpHN4YY3RqL09nXU1eHKLNiuAN4kHvDQ16k/8= +github.com/hashicorp/consul/api v1.28.2/go.mod h1:KyzqzgMEya+IZPcD65YFoOVAgPpbfERu4I/tzG6/ueE= github.com/hashicorp/consul/sdk v0.3.0 h1:UOxjlb4xVNF93jak1mzzoBatyFju9nrkxpVwIp/QqxQ= github.com/hashicorp/go-cleanhttp v0.5.2 h1:035FKYIWjmULyFRBKPs8TBQoi0x6d9G4xc9neXJWAZQ= github.com/hashicorp/go-cleanhttp v0.5.2/go.mod h1:kO/YDlP8L1346E6Sodw+PrpBSV4/SoxCXGY6BqNFT48= @@ -552,8 +560,12 @@ github.com/nats-io/nats-server/v2 v2.5.0 h1:wsnVaaXH9VRSg+A2MVg5Q727/CqxnmPLGFQ3 github.com/nats-io/nats-server/v2 v2.5.0/go.mod h1:Kj86UtrXAL6LwYRA6H4RqzkHhK0Vcv2ZnKD5WbQ1t3g= github.com/nats-io/nats.go v1.31.0 h1:/WFBHEc/dOKBF6qf1TZhrdEfTmOZ5JzdJ+Y3m6Y/p7E= github.com/nats-io/nats.go v1.31.0/go.mod h1:di3Bm5MLsoB4Bx61CBTsxuarI36WbhAwOm8QrW39+i8= +github.com/nats-io/nats.go v1.34.0 h1:fnxnPCNiwIG5w08rlMcEKTUw4AV/nKyGCOJE8TdhSPk= +github.com/nats-io/nats.go v1.34.0/go.mod h1:Ubdu4Nh9exXdSz0RVWRFBbRfrbSxOYd26oF0wkWclB8= github.com/nats-io/nkeys v0.4.6 h1:IzVe95ru2CT6ta874rt9saQRkWfe2nFj1NtvYSLqMzY= github.com/nats-io/nkeys v0.4.6/go.mod h1:4DxZNzenSVd1cYQoAa8948QY3QDjrHfcfVADymtkpts= +github.com/nats-io/nkeys v0.4.7 h1:RwNJbbIdYCoClSDNY7QVKZlyb/wfT6ugvFCiKy6vDvI= +github.com/nats-io/nkeys v0.4.7/go.mod h1:kqXRgRDPlGy7nGaEDMuYzmiJCIAAWDK0IMBtDmGD0nc= github.com/nats-io/nuid v1.0.1 h1:5iA8DT8V7q8WK2EScv2padNa/rTESc1KdnPw4TC2paw= github.com/nbutton23/zxcvbn-go v0.0.0-20210217022336-fa2cb2858354 h1:4kuARK6Y6FxaNu/BnU2OAaLF86eTVhP2hjTB6iMvItA= github.com/nbutton23/zxcvbn-go v0.0.0-20210217022336-fa2cb2858354/go.mod h1:KSVJerMDfblTH7p5MZaTt+8zaT2iEk3AkVb9PQdZuE8= @@ -608,6 +620,8 @@ github.com/russross/blackfriday/v2 v2.1.0 h1:JIOH55/0cWyOuilr9/qlrm0BSXldqnqwMsf github.com/ryanuber/columnize v0.0.0-20160712163229-9b3edd62028f h1:UFr9zpz4xgTnIE5yIMtWAMngCdZ9p/+q6lTbgelo80M= github.com/sagikazarmark/crypt v0.17.0 h1:ZA/7pXyjkHoK4bW4mIdnCLvL8hd+Nrbiw7Dqk7D4qUk= github.com/sagikazarmark/crypt v0.17.0/go.mod h1:SMtHTvdmsZMuY/bpZoqokSoChIrcJ/epOxZN58PbZDg= +github.com/sagikazarmark/crypt v0.19.0 h1:WMyLTjHBo64UvNcWqpzY3pbZTYgnemZU8FBZigKc42E= +github.com/sagikazarmark/crypt v0.19.0/go.mod h1:c6vimRziqqERhtSe0MhIvzE1w54FrCHtrXb5NH/ja78= github.com/samuel/go-zookeeper v0.0.0-20190923202752-2cc03de413da h1:p3Vo3i64TCLY7gIfzeQaUJ+kppEO5WQG3cL8iE8tGHU= github.com/satori/go.uuid v1.2.0 h1:0uYX9dsZ2yD7q2RtLRtPSdGDWzjeM3TbMJP9utgA0ww= github.com/satori/go.uuid v1.2.0/go.mod h1:dA0hQrYB0VpLJoorglMZABFdXlWrHn1NEOzdhQKdks0= @@ -682,22 +696,40 @@ github.com/yusufpapurcu/wmi v1.2.3/go.mod h1:SBZ9tNy3G9/m5Oi98Zks0QjeHVDvuK0qfxQ go.etcd.io/etcd v0.0.0-20191023171146-3cf2f69b5738 h1:VcrIfasaLFkyjk6KNlXQSzO+B0fZcnECiDrKJsfxka0= go.etcd.io/etcd/api/v3 v3.5.10 h1:szRajuUUbLyppkhs9K6BRtjY37l66XQQmw7oZRANE4k= go.etcd.io/etcd/api/v3 v3.5.10/go.mod h1:TidfmT4Uycad3NM/o25fG3J07odo4GBB9hoxaodFCtI= +go.etcd.io/etcd/api/v3 v3.5.12 h1:W4sw5ZoU2Juc9gBWuLk5U6fHfNVyY1WC5g9uiXZio/c= +go.etcd.io/etcd/api/v3 v3.5.12/go.mod h1:Ot+o0SWSyT6uHhA56al1oCED0JImsRiU9Dc26+C2a+4= go.etcd.io/etcd/client/pkg/v3 v3.5.10 h1:kfYIdQftBnbAq8pUWFXfpuuxFSKzlmM5cSn76JByiT0= go.etcd.io/etcd/client/pkg/v3 v3.5.10/go.mod h1:DYivfIviIuQ8+/lCq4vcxuseg2P2XbHygkKwFo9fc8U= +go.etcd.io/etcd/client/pkg/v3 v3.5.12 h1:EYDL6pWwyOsylrQyLp2w+HkQ46ATiOvoEdMarindU2A= +go.etcd.io/etcd/client/pkg/v3 v3.5.12/go.mod h1:seTzl2d9APP8R5Y2hFL3NVlD6qC/dOT+3kvrqPyTas4= go.etcd.io/etcd/client/v2 v2.305.10 h1:MrmRktzv/XF8CvtQt+P6wLUlURaNpSDJHFZhe//2QE4= go.etcd.io/etcd/client/v2 v2.305.10/go.mod h1:m3CKZi69HzilhVqtPDcjhSGp+kA1OmbNn0qamH80xjA= +go.etcd.io/etcd/client/v2 v2.305.12 h1:0m4ovXYo1CHaA/Mp3X/Fak5sRNIWf01wk/X1/G3sGKI= +go.etcd.io/etcd/client/v2 v2.305.12/go.mod h1:aQ/yhsxMu+Oht1FOupSr60oBvcS9cKXHrzBpDsPTf9E= go.etcd.io/etcd/client/v3 v3.5.10 h1:W9TXNZ+oB3MCd/8UjxHTWK5J9Nquw9fQBLJd5ne5/Ao= go.etcd.io/etcd/client/v3 v3.5.10/go.mod h1:RVeBnDz2PUEZqTpgqwAtUd8nAPf5kjyFyND7P1VkOKc= +go.etcd.io/etcd/client/v3 v3.5.12 h1:v5lCPXn1pf1Uu3M4laUE2hp/geOTc5uPcYYsNe1lDxg= +go.etcd.io/etcd/client/v3 v3.5.12/go.mod h1:tSbBCakoWmmddL+BKVAJHa9km+O/E+bumDe9mSbPiqw= go.etcd.io/gofail v0.1.0 h1:XItAMIhOojXFQMgrxjnd2EIIHun/d5qL0Pf7FzVTkFg= go.etcd.io/gofail v0.1.0/go.mod h1:VZBCXYGZhHAinaBiiqYvuDynvahNsAyLFwB3kEHKz1M= go.opencensus.io v0.24.0 h1:y73uSU6J157QMP2kn2r30vwW1A2W2WFwSCGnAVxeaD0= go.opencensus.io v0.24.0/go.mod h1:vNK8G9p7aAivkbmorf4v+7Hgx+Zs0yY+0fOtgBfjQKo= +go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.49.0 h1:4Pp6oUg3+e/6M4C0A/3kJ2VYa++dsWVTtGgLVj5xtHg= +go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.49.0/go.mod h1:Mjt1i1INqiaoZOMGR1RIUJN+i3ChKoFRqzrRQhlkbs0= +go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.49.0 h1:jq9TW8u3so/bN+JPT166wjOI6/vQPF6Xe7nMNIltagk= +go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.49.0/go.mod h1:p8pYQP+m5XfbZm9fxtSKAbM6oIllS7s2AfxrChvc7iw= go.opentelemetry.io/otel v1.14.0 h1:/79Huy8wbf5DnIPhemGB+zEPVwnN6fuQybr/SRXa6hM= go.opentelemetry.io/otel v1.14.0/go.mod h1:o4buv+dJzx8rohcUeRmWUZhqupFvzWis188WlggnNeU= +go.opentelemetry.io/otel v1.24.0 h1:0LAOdjNmQeSTzGBzduGe/rU4tZhMwL5rWgtp9Ku5Jfo= +go.opentelemetry.io/otel v1.24.0/go.mod h1:W7b9Ozg4nkF5tWI5zsXkaKKDjdVjpD4oAt9Qi/MArHo= +go.opentelemetry.io/otel/metric v1.24.0 h1:6EhoGWWK28x1fbpA4tYTOWBkPefTDQnb8WSGXlc88kI= +go.opentelemetry.io/otel/metric v1.24.0/go.mod h1:VYhLe1rFfxuTXLgj4CBiyz+9WYBA8pNGJgDcSFRKBco= go.opentelemetry.io/otel/sdk v1.14.0 h1:PDCppFRDq8A1jL9v6KMI6dYesaq+DFcDZvjsoGvxGzY= go.opentelemetry.io/otel/sdk v1.14.0/go.mod h1:bwIC5TjrNG6QDCHNWvW4HLHtUQ4I+VQDsnjhvyZCALM= go.opentelemetry.io/otel/trace v1.14.0 h1:wp2Mmvj41tDsyAJXiWDWpfNsOiIyd38fy85pyKcFq/M= go.opentelemetry.io/otel/trace v1.14.0/go.mod h1:8avnQLK+CG77yNLUae4ea2JDQ6iT+gozhnZjy/rw9G8= +go.opentelemetry.io/otel/trace v1.24.0 h1:CsKnnL4dUAr/0llH9FKuc698G04IrpWV0MQA/Y1YELI= +go.opentelemetry.io/otel/trace v1.24.0/go.mod h1:HPc3Xr/cOApsBI154IU0OI0HJexz+aw5uPdbs3UCjNU= go.opentelemetry.io/proto/otlp v0.7.0 h1:rwOQPCuKAKmwGKq2aVNnYIibI6wnV7EvzgfTCzcdGg8= go.uber.org/tools v0.0.0-20190618225709-2cfd321de3ee h1:0mgffUl7nfd+FpvXMVz4IDEaUSmT1ysygQC7qYo7sG4= golang.org/x/image v0.0.0-20190802002840-cff245a6509b h1:+qEpEAPhDZ1o0x3tHzZTQDArnOixOzGD9HUJfcg0mb4= @@ -706,6 +738,8 @@ golang.org/x/lint v0.0.0-20210508222113-6edffad5e616/go.mod h1:3xt1FjdF8hUf6vQPI golang.org/x/mobile v0.0.0-20190719004257-d2bd2a29d028 h1:4+4C/Iv2U4fMZBiMCc98MG1In4gJY5YRhtpDNeDeHWs= golang.org/x/oauth2 v0.18.0 h1:09qnuIAgzdx1XplqJvW6CQqMCtGZykZWcXzPMPUusvI= golang.org/x/oauth2 v0.18.0/go.mod h1:Wf7knwG0MPoWIMMBgFlEaSUDaKskp0dCfrlJRJXbBi8= +golang.org/x/oauth2 v0.21.0 h1:tsimM75w1tF/uws5rbeHzIWxEqElMehnc+iW793zsZs= +golang.org/x/oauth2 v0.21.0/go.mod h1:XYTD2NtWslqkgxebSiOHnXEap4TF09sJSc7H1sXbhtI= golang.org/x/perf v0.0.0-20230113213139-801c7ef9e5c5 h1:ObuXPmIgI4ZMyQLIz48cJYgSyWdjUXc2SZAdyJMwEAU= golang.org/x/perf v0.0.0-20230113213139-801c7ef9e5c5/go.mod h1:UBKtEnL8aqnd+0JHqZ+2qoMDwtuy6cYhhKNoHLBiTQc= golang.org/x/telemetry v0.0.0-20240228155512-f48c80bd79b2 h1:IRJeR9r1pYWsHKTRe/IInb7lYvbBVIqOgsX/u0mbOWY= @@ -718,6 +752,8 @@ gonum.org/v1/gonum v0.12.0 h1:xKuo6hzt+gMav00meVPUlXwSdoEJP46BR+wdxQEFK2o= gonum.org/v1/gonum v0.12.0/go.mod h1:73TDxJfAAHeA8Mk9mf8NlIppyhQNo5GLTcYeqgo2lvY= google.golang.org/api v0.153.0 h1:N1AwGhielyKFaUqH07/ZSIQR3uNPcV7NVw0vj+j4iR4= google.golang.org/api v0.153.0/go.mod h1:3qNJX5eOmhiWYc67jRA/3GsDw97UFb5ivv7Y2PrriAY= +google.golang.org/api v0.171.0 h1:w174hnBPqut76FzW5Qaupt7zY8Kql6fiVjgys4f58sU= +google.golang.org/api v0.171.0/go.mod h1:Hnq5AHm4OTMt2BUVjael2CWZFD6vksJdWCWiUAmjC9o= google.golang.org/appengine v1.6.8 h1:IhEN5q69dyKagZPYMSdIjS2HqprW324FRQZJcGqPAsM= google.golang.org/appengine v1.6.8/go.mod h1:1jJ3jBArFh5pcgW8gCtRJnepW8FzD1V44FJffLiz/Ds= gopkg.in/alecthomas/kingpin.v2 v2.2.6 h1:jMFz6MfLP0/4fUyZle81rXUoxOBFi19VUFKVDOQfozc= diff --git a/keeper/keeper.go b/keeper/keeper.go index ac90e1c..ec8eec9 100644 --- a/keeper/keeper.go +++ b/keeper/keeper.go @@ -124,11 +124,16 @@ func (k *Keeper) VerifyWithdrawSignature(ctx sdk.Context, recipient sdk.AccAddre return false } + nonce, err := k.IncrementNonce(ctx, recipient) + if err != nil { + return false + } + bz, err := json.Marshal(types.WithdrawSignatureWrapper{ Data: types.WithdrawSignatureData{ Recipient: recipient, Amount: amount, - Nonce: k.IncrementNonce(ctx, recipient), + Nonce: nonce, }, }) if err != nil { diff --git a/keeper/keeper_test.go b/keeper/keeper_test.go index 5ed320d..42438b3 100644 --- a/keeper/keeper_test.go +++ b/keeper/keeper_test.go @@ -51,12 +51,14 @@ func TestSendRestrictionBurn(t *testing.T) { for _, testCase := range testCases { t.Run(testCase.name, func(t *testing.T) { // ARRANGE: Set paused state. - keeper.SetPaused(ctx, testCase.paused) + err := keeper.SetPaused(ctx, testCase.paused) + require.NoError(t, err) // ARRANGE: Set allowed state. - keeper.SetUserRole(ctx, user.Bytes, entitlements.ROLE_INTERNATIONAL_FEEDER, testCase.allowed) + err = keeper.SetUserRole(ctx, user.Bytes, entitlements.ROLE_INTERNATIONAL_FEEDER, testCase.allowed) + require.NoError(t, err) // ACT: Attempt to burn. - _, err := keeper.SendRestrictionFn(ctx, user.Bytes, types.ModuleAddress, coins) + _, err = keeper.SendRestrictionFn(ctx, user.Bytes, types.ModuleAddress, coins) // ASSERT: Send restriction correctly handled test case. if testCase.err != "" { @@ -107,12 +109,14 @@ func TestSendRestrictionMint(t *testing.T) { for _, testCase := range testCases { t.Run(testCase.name, func(t *testing.T) { // ARRANGE: Set paused state. - keeper.SetPaused(ctx, testCase.paused) + err := keeper.SetPaused(ctx, testCase.paused) + require.NoError(t, err) // ARRANGE: Set allowed state. - keeper.SetUserRole(ctx, user.Bytes, entitlements.ROLE_INTERNATIONAL_FEEDER, testCase.allowed) + err = keeper.SetUserRole(ctx, user.Bytes, entitlements.ROLE_INTERNATIONAL_FEEDER, testCase.allowed) + require.NoError(t, err) // ACT: Attempt to mint. - _, err := keeper.SendRestrictionFn(ctx, types.ModuleAddress, user.Bytes, coins) + _, err = keeper.SendRestrictionFn(ctx, types.ModuleAddress, user.Bytes, coins) // ASSERT: Send restriction correctly handled test case. if testCase.err != "" { @@ -214,14 +218,17 @@ func TestSendRestrictionTransfer(t *testing.T) { for _, testCase := range testCases { t.Run(testCase.name, func(t *testing.T) { // ARRANGE: Set paused state. - keeper.SetPaused(ctx, testCase.paused) + err := keeper.SetPaused(ctx, testCase.paused) + require.NoError(t, err) // ARRANGE: Set sender allowed state. - keeper.SetUserRole(ctx, alice.Bytes, entitlements.ROLE_INTERNATIONAL_FEEDER, testCase.senderAllowed) + err = keeper.SetUserRole(ctx, alice.Bytes, entitlements.ROLE_INTERNATIONAL_FEEDER, testCase.senderAllowed) + require.NoError(t, err) // ARRANGE: Set recipient allowed state. - keeper.SetUserRole(ctx, bob.Bytes, entitlements.ROLE_INTERNATIONAL_FEEDER, testCase.recipientAllowed) + err = keeper.SetUserRole(ctx, bob.Bytes, entitlements.ROLE_INTERNATIONAL_FEEDER, testCase.recipientAllowed) + require.NoError(t, err) // ACT: Attempt to transfer. - _, err := keeper.SendRestrictionFn(ctx, alice.Bytes, bob.Bytes, testCase.coins) + _, err = keeper.SendRestrictionFn(ctx, alice.Bytes, bob.Bytes, testCase.coins) // ASSERT: Send restriction correctly handled test case. if testCase.err != "" { diff --git a/keeper/msg_server.go b/keeper/msg_server.go index 41110e0..1483b75 100644 --- a/keeper/msg_server.go +++ b/keeper/msg_server.go @@ -260,7 +260,9 @@ func (k msgServer) TransferOwnership(goCtx context.Context, msg *types.MsgTransf return nil, types.ErrSameOwner } - k.SetOwner(ctx, msg.NewOwner) + if err := k.SetOwner(ctx, msg.NewOwner); err != nil { + return nil, err + } return &types.MsgTransferOwnershipResponse{}, ctx.EventManager().EmitTypedEvent(&types.OwnershipTransferred{ PreviousOwner: owner, diff --git a/keeper/msg_server_aggregator.go b/keeper/msg_server_aggregator.go index c5b6a8c..5832777 100644 --- a/keeper/msg_server_aggregator.go +++ b/keeper/msg_server_aggregator.go @@ -27,7 +27,10 @@ func (k aggregatorMsgServer) ReportBalance(goCtx context.Context, msg *aggregato balance := msg.Principal.Add(msg.Interest) - id := k.IncrementLastRoundId(ctx) + id, err := k.IncrementLastRoundId(ctx) + if err != nil { + return nil, err + } round, found := k.GetRound(ctx, id) if found && round.Balance.Equal(balance) && round.Interest.Equal(msg.Interest) && round.Supply.Equal(msg.TotalSupply) { return nil, aggregator.ErrAlreadyReported @@ -46,12 +49,16 @@ func (k aggregatorMsgServer) ReportBalance(goCtx context.Context, msg *aggregato Supply: msg.TotalSupply, UpdatedAt: ctx.BlockTime().Unix(), } - k.SetRound(ctx, id, round) + if err = k.SetRound(ctx, id, round); err != nil { + return nil, err + } if !msg.NextPrice.IsPositive() || msg.NextPrice.LTE(answer) { return nil, aggregator.ErrInvalidNextPrice } - k.Keeper.SetNextPrice(ctx, msg.NextPrice) + if err = k.Keeper.SetNextPrice(ctx, msg.NextPrice); err != nil { + return nil, err + } return &aggregator.MsgReportBalanceResponse{ RoundId: id, @@ -78,7 +85,9 @@ func (k aggregatorMsgServer) SetNextPrice(goCtx context.Context, msg *aggregator return nil, aggregator.ErrInvalidNextPrice } - k.Keeper.SetNextPrice(ctx, msg.NextPrice) + if err = k.Keeper.SetNextPrice(ctx, msg.NextPrice); err != nil { + return nil, err + } return &aggregator.MsgSetNextPriceResponse{}, ctx.EventManager().EmitTypedEvent(&aggregator.NextPriceReported{ Price: msg.NextPrice, @@ -96,7 +105,9 @@ func (k aggregatorMsgServer) TransferOwnership(goCtx context.Context, msg *aggre return nil, aggregator.ErrSameOwner } - k.SetAggregatorOwner(ctx, msg.NewOwner) + if err = k.SetAggregatorOwner(ctx, msg.NewOwner); err != nil { + return nil, err + } return &aggregator.MsgTransferOwnershipResponse{}, ctx.EventManager().EmitTypedEvent(&aggregator.OwnershipTransferred{ PreviousOwner: owner, diff --git a/keeper/msg_server_aggregator_test.go b/keeper/msg_server_aggregator_test.go index 9a641dd..bb4b032 100644 --- a/keeper/msg_server_aggregator_test.go +++ b/keeper/msg_server_aggregator_test.go @@ -3,8 +3,12 @@ package keeper_test import ( "testing" + "cosmossdk.io/collections" "cosmossdk.io/math" + "github.com/cosmos/cosmos-sdk/codec" + sdk "github.com/cosmos/cosmos-sdk/types" "github.com/noble-assets/halo/v2/keeper" + "github.com/noble-assets/halo/v2/types" "github.com/noble-assets/halo/v2/types/aggregator" "github.com/noble-assets/halo/v2/utils" "github.com/noble-assets/halo/v2/utils/data" @@ -23,7 +27,8 @@ func TestReportBalance(t *testing.T) { // ARRANGE: Set aggregator owner in state. owner := utils.TestAccount() - k.SetAggregatorOwner(ctx, owner.Address) + err = k.SetAggregatorOwner(ctx, owner.Address) + require.NoError(t, err) // ARRANGE: Save the original LastRoundIDKey and reset it to an empty byte slice. tmpLastRoundIDKey := aggregator.LastRoundIDKey @@ -91,7 +96,8 @@ func TestReportBalance(t *testing.T) { require.ErrorContains(t, err, aggregator.ErrInvalidNextPrice.Error()) // ARRANGE: Set the next round in state. - k.SetRound(ctx, k.GetLastRoundId(ctx)+1, aggregator.RoundData{}) + err = k.SetRound(ctx, k.GetLastRoundId(ctx)+1, aggregator.RoundData{}) + require.NoError(t, err) // ACT: Attempt to report balance with existing next round. // https://etherscan.io/tx/0x1a628856cb74de37357a35c29ec22509b72b1fc826ac7bb1020c73a99f9f80fc @@ -105,6 +111,45 @@ func TestReportBalance(t *testing.T) { _, err = server.ReportBalance(ctx, &msg) // ASSERT: The action should've failed due to existing round. require.ErrorContains(t, err, aggregator.ErrAlreadyReported.Error()) + + // ARRANGE: Set up a failing collection store for the attribute setter. + tmpRounds := k.Rounds + k.Rounds = collections.NewMap( + collections.NewSchemaBuilder(mocks.FailingStore(mocks.Set, utils.GetKVStore(ctx, types.ModuleName))), + aggregator.RoundPrefix, "aggregator_rounds", collections.Uint64Key, codec.CollValue[aggregator.RoundData]( + mocks.MakeTestEncodingConfig("noble").Codec, + ), + ) + + // ACT: Attempt to report balance with failing Rounds store. + _, err = server.ReportBalance(ctx, &msg) + // ASSERT: The action should've failed due to collection store setter error. + require.Error(t, err, mocks.ErrorStoreAccess) + k.Rounds = tmpRounds + + // ARRANGE: Set up a failing collection store for the attribute setter. + tmpLastRoundId := k.LastRoundId + k.LastRoundId = collections.NewSequence( + collections.NewSchemaBuilder(mocks.FailingStore(mocks.Set, utils.GetKVStore(ctx, types.ModuleName))), + aggregator.LastRoundIDKey, "aggregator_last_round_id", + ) + + // ACT: Attempt to report balance with failing LastRoundId store. + _, err = server.ReportBalance(ctx, &msg) + // ASSERT: The action should've failed due to collection store setter error. + require.Error(t, err, mocks.ErrorStoreAccess) + k.LastRoundId = tmpLastRoundId + + // ARRANGE: Set up a failing collection store for the attribute setter. + k.NextPrice = collections.NewItem( + collections.NewSchemaBuilder(mocks.FailingStore(mocks.Set, utils.GetKVStore(ctx, types.ModuleName))), + aggregator.NextPriceKey, "aggregator_next_price", sdk.IntValue, + ) + + // ACT: Attempt to report balance with failing NextPrice store. + _, err = server.ReportBalance(ctx, &msg) + // ASSERT: The action should've failed due to collection store setter error. + require.Error(t, err, mocks.ErrorStoreAccess) } func TestSetNextPrice(t *testing.T) { @@ -118,7 +163,8 @@ func TestSetNextPrice(t *testing.T) { // ARRANGE: Set aggregator owner in state. owner := utils.TestAccount() - k.SetAggregatorOwner(ctx, owner.Address) + err = k.SetAggregatorOwner(ctx, owner.Address) + require.NoError(t, err) // ACT: Attempt to set next price with invalid signer. _, err = server.SetNextPrice(ctx, &aggregator.MsgSetNextPrice{ @@ -145,6 +191,20 @@ func TestSetNextPrice(t *testing.T) { // ASSERT: The action should've succeeded, and set next price in state. require.NoError(t, err) require.Equal(t, price, k.GetNextPrice(ctx)) + + // ARRANGE: Set up a failing collection store for the attribute setter. + k.NextPrice = collections.NewItem( + collections.NewSchemaBuilder(mocks.FailingStore(mocks.Set, utils.GetKVStore(ctx, types.ModuleName))), + aggregator.NextPriceKey, "aggregator_next_price", sdk.IntValue, + ) + + // ACT: Attempt to set next price. + _, err = server.SetNextPrice(ctx, &aggregator.MsgSetNextPrice{ + Signer: owner.Address, + NextPrice: price, + }) + // ASSERT: The action should've failed due to collection store setter error. + require.Error(t, err, mocks.ErrorStoreAccess) } func TestAggregatorTransferOwnership(t *testing.T) { @@ -158,7 +218,8 @@ func TestAggregatorTransferOwnership(t *testing.T) { // ARRANGE: Set aggregator owner in state. owner := utils.TestAccount() - k.SetAggregatorOwner(ctx, owner.Address) + err = k.SetAggregatorOwner(ctx, owner.Address) + require.NoError(t, err) // ACT: Attempt to transfer ownership with invalid signer. _, err = server.TransferOwnership(ctx, &aggregator.MsgTransferOwnership{ @@ -178,6 +239,22 @@ func TestAggregatorTransferOwnership(t *testing.T) { // ARRANGE: Generate a new owner account. newOwner := utils.TestAccount() + // ARRANGE: Set up a failing collection store for the attribute setter. + tmp := k.AggregatorOwner + k.AggregatorOwner = collections.NewItem( + collections.NewSchemaBuilder(mocks.FailingStore(mocks.Set, utils.GetKVStore(ctx, types.ModuleName))), + aggregator.OwnerKey, "aggregator_owner", collections.StringValue, + ) + + // ACT: Attempt to transfer ownership. + _, err = server.TransferOwnership(ctx, &aggregator.MsgTransferOwnership{ + Signer: owner.Address, + NewOwner: newOwner.Address, + }) + // ASSERT: The action should've failed due to collection store setter error. + require.Error(t, err, mocks.ErrorStoreAccess) + k.AggregatorOwner = tmp + // ACT: Attempt to transfer ownership. _, err = server.TransferOwnership(ctx, &aggregator.MsgTransferOwnership{ Signer: owner.Address, diff --git a/keeper/msg_server_entitlements.go b/keeper/msg_server_entitlements.go index af41267..33f26c3 100644 --- a/keeper/msg_server_entitlements.go +++ b/keeper/msg_server_entitlements.go @@ -31,7 +31,9 @@ func (k entitlementsMsgServer) SetPublicCapability(goCtx context.Context, msg *e return nil, errors.Wrapf(entitlements.ErrInvalidMethod, "method %s does not exist or is not allowed", msg.Method) } - k.Keeper.SetPublicCapability(ctx, msg.Method, msg.Enabled) + if err = k.Keeper.SetPublicCapability(ctx, msg.Method, msg.Enabled); err != nil { + return nil, err + } return &entitlements.MsgSetPublicCapabilityResponse{}, ctx.EventManager().EmitTypedEvent(&entitlements.PublicCapabilityUpdated{ Method: msg.Method, @@ -56,7 +58,9 @@ func (k entitlementsMsgServer) SetRoleCapability(goCtx context.Context, msg *ent return nil, errors.Wrapf(entitlements.ErrInvalidMethod, "method %s does not exist or is not allowed", msg.Method) } - k.Keeper.SetRoleCapability(ctx, msg.Method, msg.Role, msg.Enabled) + if err = k.Keeper.SetRoleCapability(ctx, msg.Method, msg.Role, msg.Enabled); err != nil { + return nil, err + } return &entitlements.MsgSetRoleCapabilityResponse{}, ctx.EventManager().EmitTypedEvent(&entitlements.RoleCapabilityUpdated{ Role: msg.Role, @@ -82,7 +86,9 @@ func (k entitlementsMsgServer) SetUserRole(goCtx context.Context, msg *entitleme return nil, errors.Wrapf(entitlements.ErrInvalidRole, "role %s does not exist", msg.Role) } - k.Keeper.SetUserRole(ctx, user, msg.Role, msg.Enabled) + if err = k.Keeper.SetUserRole(ctx, user, msg.Role, msg.Enabled); err != nil { + return nil, err + } return &entitlements.MsgSetUserRoleResponse{}, ctx.EventManager().EmitTypedEvent(&entitlements.UserRoleUpdated{ User: msg.User, @@ -98,7 +104,9 @@ func (k entitlementsMsgServer) Pause(goCtx context.Context, msg *entitlements.Ms return nil, err } - k.SetPaused(ctx, true) + if err = k.SetPaused(ctx, true); err != nil { + return nil, err + } return &entitlements.MsgPauseResponse{}, ctx.EventManager().EmitTypedEvent(&entitlements.Paused{ Account: msg.Signer, @@ -112,7 +120,9 @@ func (k entitlementsMsgServer) Unpause(goCtx context.Context, msg *entitlements. return nil, err } - k.SetPaused(ctx, false) + if err = k.SetPaused(ctx, false); err != nil { + return nil, err + } return &entitlements.MsgUnpauseResponse{}, ctx.EventManager().EmitTypedEvent(&entitlements.Unpaused{ Account: msg.Signer, @@ -130,7 +140,9 @@ func (k entitlementsMsgServer) TransferOwnership(goCtx context.Context, msg *ent return nil, entitlements.ErrSameOwner } - k.SetEntitlementsOwner(ctx, msg.NewOwner) + if err = k.SetEntitlementsOwner(ctx, msg.NewOwner); err != nil { + return nil, err + } return &entitlements.MsgTransferOwnershipResponse{}, ctx.EventManager().EmitTypedEvent(&entitlements.OwnershipTransferred{ PreviousOwner: owner, diff --git a/keeper/msg_server_entitlements_test.go b/keeper/msg_server_entitlements_test.go index 8540f2f..f317a49 100644 --- a/keeper/msg_server_entitlements_test.go +++ b/keeper/msg_server_entitlements_test.go @@ -3,8 +3,10 @@ package keeper_test import ( "testing" + "cosmossdk.io/collections" sdk "github.com/cosmos/cosmos-sdk/types" "github.com/noble-assets/halo/v2/keeper" + "github.com/noble-assets/halo/v2/types" "github.com/noble-assets/halo/v2/types/entitlements" "github.com/noble-assets/halo/v2/utils" "github.com/noble-assets/halo/v2/utils/mocks" @@ -22,7 +24,8 @@ func TestPause(t *testing.T) { // ARRANGE: Set entitlements owner in state. owner := utils.TestAccount() - k.SetEntitlementsOwner(ctx, owner.Address) + err = k.SetEntitlementsOwner(ctx, owner.Address) + require.NoError(t, err) // ACT: Attempt to pause with invalid signer. _, err = server.Pause(ctx, &entitlements.MsgPause{ @@ -31,6 +34,21 @@ func TestPause(t *testing.T) { // ASSERT: The action should've failed due to invalid signer. require.ErrorContains(t, err, entitlements.ErrInvalidOwner.Error()) + // ARRANGE: Set up a failing collection store for the attribute setter. + tmp := k.Paused + k.Paused = collections.NewItem( + collections.NewSchemaBuilder(mocks.FailingStore(mocks.Set, utils.GetKVStore(ctx, types.ModuleName))), + entitlements.PausedKey, "entitlements_paused", collections.BoolValue, + ) + + // ACT: Attempt to pause with failing Paused collection store. + _, err = server.Pause(ctx, &entitlements.MsgPause{ + Signer: owner.Address, + }) + // ASSERT: The action should've failed due to collection store setter error. + require.Error(t, err, mocks.ErrorStoreAccess) + k.Paused = tmp + // ACT: Attempt to pause. _, err = server.Pause(ctx, &entitlements.MsgPause{ Signer: owner.Address, @@ -45,16 +63,18 @@ func TestUnpause(t *testing.T) { server := keeper.NewEntitlementsMsgServer(k) // ARRANGE: Set paused state to true. - k.SetPaused(ctx, true) + err := k.SetPaused(ctx, true) + require.NoError(t, err) // ACT: Attempt to unpause with no owner set. - _, err := server.Unpause(ctx, &entitlements.MsgUnpause{}) + _, err = server.Unpause(ctx, &entitlements.MsgUnpause{}) // ASSERT: The action should've failed due to no owner set. require.ErrorContains(t, err, "there is no owner") // ARRANGE: Set entitlements owner in state. owner := utils.TestAccount() - k.SetEntitlementsOwner(ctx, owner.Address) + err = k.SetEntitlementsOwner(ctx, owner.Address) + require.NoError(t, err) // ACT: Attempt to unpause with invalid signer. _, err = server.Unpause(ctx, &entitlements.MsgUnpause{ @@ -63,6 +83,21 @@ func TestUnpause(t *testing.T) { // ASSERT: The action should've failed due to invalid signer. require.ErrorContains(t, err, entitlements.ErrInvalidOwner.Error()) + // ARRANGE: Set up a failing collection store for the attribute setter. + tmp := k.Paused + k.Paused = collections.NewItem( + collections.NewSchemaBuilder(mocks.FailingStore(mocks.Set, utils.GetKVStore(ctx, types.ModuleName))), + entitlements.PausedKey, "entitlements_paused", collections.BoolValue, + ) + + // ACT: Attempt to unpause with failing Paused collection store. + _, err = server.Unpause(ctx, &entitlements.MsgUnpause{ + Signer: owner.Address, + }) + // ASSERT: The action should've failed due to collection store setter error. + require.Error(t, err, mocks.ErrorStoreAccess) + k.Paused = tmp + // ACT: Attempt to unpause. _, err = server.Unpause(ctx, &entitlements.MsgUnpause{ Signer: owner.Address, @@ -83,7 +118,8 @@ func TestEntitlementsTransferOwnership(t *testing.T) { // ARRANGE: Set entitlements owner in state. owner := utils.TestAccount() - k.SetEntitlementsOwner(ctx, owner.Address) + err = k.SetEntitlementsOwner(ctx, owner.Address) + require.NoError(t, err) // ACT: Attempt to transfer ownership with invalid signer. _, err = server.TransferOwnership(ctx, &entitlements.MsgTransferOwnership{ @@ -103,6 +139,22 @@ func TestEntitlementsTransferOwnership(t *testing.T) { // ARRANGE: Generate a new owner account. newOwner := utils.TestAccount() + // ARRANGE: Set up a failing collection store for the attribute setter. + tmp := k.EntitlementsOwner + k.EntitlementsOwner = collections.NewItem( + collections.NewSchemaBuilder(mocks.FailingStore(mocks.Set, utils.GetKVStore(ctx, types.ModuleName))), + entitlements.OwnerKey, "entitlements_owner", collections.StringValue, + ) + + // ACT: Attempt to transfer ownership with failing EntitlementsOwner collection store. + _, err = server.TransferOwnership(ctx, &entitlements.MsgTransferOwnership{ + Signer: owner.Address, + NewOwner: newOwner.Address, + }) + // ASSERT: The action should've failed due to collection store setter error. + require.Error(t, err, mocks.ErrorStoreAccess) + k.EntitlementsOwner = tmp + // ACT: Attempt to transfer ownership. _, err = server.TransferOwnership(ctx, &entitlements.MsgTransferOwnership{ Signer: owner.Address, @@ -127,7 +179,8 @@ func TestEntitlementsPublicCapabilities(t *testing.T) { // ARRANGE: Set entitlements owner in state. owner := utils.TestAccount() - k.SetEntitlementsOwner(ctx, owner.Address) + err = k.SetEntitlementsOwner(ctx, owner.Address) + require.NoError(t, err) // ACT: Attempt set public capability with invalid signer. _, err = server.SetPublicCapability(ctx, &entitlements.MsgSetPublicCapability{ @@ -165,6 +218,23 @@ func TestEntitlementsPublicCapabilities(t *testing.T) { require.Equal(t, true, k.IsPublicCapability(ctx, "/halo.entitlements.v1.MsgSetRoleCapability")) require.Equal(t, 1, len(k.GetPublicCapabilities(ctx))) + // ARRANGE: Set up a failing collection store for the attribute setter. + tmp := k.PublicCapabilities + k.PublicCapabilities = collections.NewMap( + collections.NewSchemaBuilder(mocks.FailingStore(mocks.Set, utils.GetKVStore(ctx, types.ModuleName))), + entitlements.PublicPrefix, "entitlements_public_capabilities", collections.StringKey, collections.BoolValue, + ) + + // ACT: Attempt set public capability with failing PublicCapabilities collection store. + _, err = server.SetPublicCapability(ctx, &entitlements.MsgSetPublicCapability{ + Signer: owner.Address, + Method: "transfer", + Enabled: true, + }) + // ASSERT: The action should've failed due to collection store setter error. + require.Error(t, err, mocks.ErrorStoreAccess) + k.PublicCapabilities = tmp + // ACT: Attempt set public capability a valid capability. _, err = server.SetPublicCapability(ctx, &entitlements.MsgSetPublicCapability{ Signer: owner.Address, @@ -199,7 +269,8 @@ func TestEntitlementsUserRoles(t *testing.T) { // ARRANGE: Set entitlements owner in state. owner, bob, alice := utils.TestAccount(), utils.TestAccount(), utils.TestAccount() userAddress, _ := sdk.AccAddressFromBech32(bob.Address) - k.SetEntitlementsOwner(ctx, owner.Address) + err = k.SetEntitlementsOwner(ctx, owner.Address) + require.NoError(t, err) // ACT: Attempt set user role with invalid signer. _, err = server.SetUserRole(ctx, &entitlements.MsgSetUserRole{ @@ -238,6 +309,24 @@ func TestEntitlementsUserRoles(t *testing.T) { // ASSERT: The action should've failed due to a non-existing role. require.ErrorContains(t, err, entitlements.ErrInvalidRole.Error()) + // ARRANGE: Set up a failing collection store for the attribute setter. + tmp := k.UserRoles + k.UserRoles = collections.NewMap( + collections.NewSchemaBuilder(mocks.FailingStore(mocks.Set, utils.GetKVStore(ctx, types.ModuleName))), + entitlements.UserPrefix, "entitlements_user_roles", collections.PairKeyCodec(collections.BytesKey, collections.Uint64Key), collections.BoolValue, + ) + + // ACT: Attempt set user role with failing UserRoles collection store. + _, err = server.SetUserRole(ctx, &entitlements.MsgSetUserRole{ + Signer: owner.Address, + User: bob.Address, + Role: entitlements.ROLE_INTERNATIONAL_FEEDER, + Enabled: true, + }) + // ASSERT: The action should've failed due to collection store setter error. + require.Error(t, err, mocks.ErrorStoreAccess) + k.UserRoles = tmp + // ACT: Attempt set user role with valid message. _, err = server.SetUserRole(ctx, &entitlements.MsgSetUserRole{ Signer: owner.Address, @@ -304,7 +393,8 @@ func TestEntitlementsUserCapability(t *testing.T) { // ARRANGE: Set entitlements owner in state. owner := utils.TestAccount() - k.SetEntitlementsOwner(ctx, owner.Address) + err = k.SetEntitlementsOwner(ctx, owner.Address) + require.NoError(t, err) // ACT: Attempt set role capability with invalid signer. _, err = server.SetUserRole(ctx, &entitlements.MsgSetUserRole{ @@ -313,7 +403,7 @@ func TestEntitlementsUserCapability(t *testing.T) { // ASSERT: The action should've failed due to invalid signer. require.ErrorContains(t, err, entitlements.ErrInvalidOwner.Error()) - // ACT: Attempt set user role with a negative invalid role. + // ACT: Attempt set role capability with a negative invalid role. _, err = server.SetRoleCapability(ctx, &entitlements.MsgSetRoleCapability{ Signer: owner.Address, Role: -1000, @@ -323,7 +413,7 @@ func TestEntitlementsUserCapability(t *testing.T) { // ASSERT: The action should've failed due to an invalid negative role. require.ErrorContains(t, err, entitlements.ErrInvalidRole.Error()) - // ACT: Attempt set user role with a non-existing role. + // ACT: Attempt set role capability with a non-existing role. _, err = server.SetRoleCapability(ctx, &entitlements.MsgSetRoleCapability{ Signer: owner.Address, Method: "transfer", @@ -333,7 +423,7 @@ func TestEntitlementsUserCapability(t *testing.T) { // ASSERT: The action should've failed due to a non-existing role. require.ErrorContains(t, err, entitlements.ErrInvalidRole.Error()) - // ACT: Attempt set user role with a non-existing role. + // ACT: Attempt set role capability with a non-existing role. _, err = server.SetRoleCapability(ctx, &entitlements.MsgSetRoleCapability{ Signer: owner.Address, Method: "transfer", @@ -344,7 +434,7 @@ func TestEntitlementsUserCapability(t *testing.T) { require.ErrorContains(t, err, entitlements.ErrInvalidRole.Error()) require.Equal(t, 4, len(k.GetCapabilityRoles(ctx, "transfer"))) - // ACT: Attempt set user role with a non-existing method. + // ACT: Attempt set role capability with a non-existing method. _, err = server.SetRoleCapability(ctx, &entitlements.MsgSetRoleCapability{ Signer: owner.Address, Method: "transfer2", @@ -354,7 +444,7 @@ func TestEntitlementsUserCapability(t *testing.T) { // ASSERT: The action should've failed due to a non-existing role. require.ErrorContains(t, err, entitlements.ErrInvalidMethod.Error()) - // ACT: Attempt set user role with a non-allowed method. + // ACT: Attempt set role capability with a non-allowed method. _, err = server.SetRoleCapability(ctx, &entitlements.MsgSetRoleCapability{ Signer: owner.Address, Method: "/cosmos.bank.v1beta1.MsgSend", @@ -364,7 +454,25 @@ func TestEntitlementsUserCapability(t *testing.T) { // ASSERT: The action should've failed due to a non-allowed role. require.ErrorContains(t, err, entitlements.ErrInvalidMethod.Error()) - // ACT: Attempt set user role with valid message. + // ARRANGE: Set up a failing collection store for the attribute setter. + tmpRole := k.RoleCapabilities + k.RoleCapabilities = collections.NewMap( + collections.NewSchemaBuilder(mocks.FailingStore(mocks.Set, utils.GetKVStore(ctx, types.ModuleName))), + entitlements.CapabilityPrefix, "entitlements_role_capabilities", collections.PairKeyCodec(collections.StringKey, collections.Uint64Key), collections.BoolValue, + ) + + // ACT: Attempt set role capability with failing RoleCapabilities collection store. + _, err = server.SetRoleCapability(ctx, &entitlements.MsgSetRoleCapability{ + Signer: owner.Address, + Method: "transfer", + Role: 5, + Enabled: true, + }) + // ASSERT: The action should've failed due to collection store setter error. + require.Error(t, err, mocks.ErrorStoreAccess) + k.RoleCapabilities = tmpRole + + // ACT: Attempt set role capability with valid message. _, err = server.SetRoleCapability(ctx, &entitlements.MsgSetRoleCapability{ Signer: owner.Address, Method: "transfer", @@ -375,7 +483,7 @@ func TestEntitlementsUserCapability(t *testing.T) { require.NoError(t, err) require.Equal(t, 5, len(k.GetCapabilityRoles(ctx, "transfer"))) - // ACT: Attempt remove user role. + // ACT: Attempt remove role capability. _, err = server.SetRoleCapability(ctx, &entitlements.MsgSetRoleCapability{ Signer: owner.Address, Method: "transfer", diff --git a/keeper/msg_server_test.go b/keeper/msg_server_test.go index 2a1cb78..6ca7871 100644 --- a/keeper/msg_server_test.go +++ b/keeper/msg_server_test.go @@ -5,6 +5,7 @@ import ( "fmt" "testing" + "cosmossdk.io/collections" "cosmossdk.io/math" sdk "github.com/cosmos/cosmos-sdk/types" authtypes "github.com/cosmos/cosmos-sdk/x/auth/types" @@ -49,17 +50,20 @@ func TestDeposit(t *testing.T) { require.ErrorContains(t, err, "cannot execute /halo.v1.MsgDeposit") // ARRANGE: Assign the international feeder role to user. - k.SetUserRole(ctx, user.Bytes, entitlements.ROLE_INTERNATIONAL_FEEDER, true) + err = k.SetUserRole(ctx, user.Bytes, entitlements.ROLE_INTERNATIONAL_FEEDER, true) + require.NoError(t, err) // ARRANGE: Report Ethereum Round #229. // https://etherscan.io/tx/0xcff68ffc6f79afadf835f559f8a51ed7092bc679d2a4f34cd153ef321d6bc8ec - k.SetRound(ctx, 229, aggregator.RoundData{ + err = k.SetRound(ctx, 229, aggregator.RoundData{ Answer: math.NewInt(104572478), Balance: math.NewInt(7016169453), Interest: math.NewInt(1005815), Supply: math.NewInt(67093843285741), UpdatedAt: 1717153499, }) - k.SetLastRoundId(ctx, 229) + require.NoError(t, err) + err = k.SetLastRoundId(ctx, 229) + require.NoError(t, err) // ACT: Attempt to deposit with insufficient funds. _, err = server.Deposit(ctx, &types.MsgDeposit{ @@ -121,7 +125,8 @@ func TestDepositFor(t *testing.T) { require.ErrorContains(t, err, "cannot execute /halo.v1.MsgDepositFor") // ARRANGE: Assign the international feeder role to user. - k.SetUserRole(ctx, user.Bytes, entitlements.ROLE_INTERNATIONAL_FEEDER, true) + err = k.SetUserRole(ctx, user.Bytes, entitlements.ROLE_INTERNATIONAL_FEEDER, true) + require.NoError(t, err) // ACT: Attempt to deposit for with an invalid recipient address. _, err = server.DepositFor(ctx, &types.MsgDepositFor{ @@ -140,7 +145,8 @@ func TestDepositFor(t *testing.T) { require.ErrorContains(t, err, "cannot receive uusyc") // ARRANGE: Assign the international feeder role to recipient. - k.SetUserRole(ctx, recipient.Bytes, entitlements.ROLE_INTERNATIONAL_FEEDER, true) + err = k.SetUserRole(ctx, recipient.Bytes, entitlements.ROLE_INTERNATIONAL_FEEDER, true) + require.NoError(t, err) // ACT: Attempt to deposit for with non-existing round. _, err = server.DepositFor(ctx, &types.MsgDepositFor{ @@ -153,14 +159,16 @@ func TestDepositFor(t *testing.T) { // ARRANGE: Report Ethereum Round #229. // https://etherscan.io/tx/0xcff68ffc6f79afadf835f559f8a51ed7092bc679d2a4f34cd153ef321d6bc8ec - k.SetRound(ctx, 229, aggregator.RoundData{ + err = k.SetRound(ctx, 229, aggregator.RoundData{ Answer: math.NewInt(104572478), Balance: math.NewInt(7016169453), Interest: math.NewInt(1005815), Supply: math.NewInt(67093843285741), UpdatedAt: 1717153499, }) - k.SetLastRoundId(ctx, 229) + require.NoError(t, err) + err = k.SetLastRoundId(ctx, 229) + require.NoError(t, err) // ACT: Attempt to deposit for with insufficient funds. _, err = server.DepositFor(ctx, &types.MsgDepositFor{ @@ -210,27 +218,31 @@ func TestDepositForWithRestrictions(t *testing.T) { user, recipient := utils.TestAccount(), utils.TestAccount() // ARRANGE: Assign the international feeder role to user. - k.SetUserRole(ctx, user.Bytes, entitlements.ROLE_INTERNATIONAL_FEEDER, true) + err := k.SetUserRole(ctx, user.Bytes, entitlements.ROLE_INTERNATIONAL_FEEDER, true) + require.NoError(t, err) // ARRANGE: Assign the international feeder role to recipient. - k.SetUserRole(ctx, recipient.Bytes, entitlements.ROLE_INTERNATIONAL_FEEDER, true) + err = k.SetUserRole(ctx, recipient.Bytes, entitlements.ROLE_INTERNATIONAL_FEEDER, true) + require.NoError(t, err) // ARRANGE: Report Ethereum Round #229. // https://etherscan.io/tx/0xcff68ffc6f79afadf835f559f8a51ed7092bc679d2a4f34cd153ef321d6bc8ec - k.SetRound(ctx, 229, aggregator.RoundData{ + err = k.SetRound(ctx, 229, aggregator.RoundData{ Answer: math.NewInt(104572478), Balance: math.NewInt(7016169453), Interest: math.NewInt(1005815), Supply: math.NewInt(67093843285741), UpdatedAt: 1717153499, }) - k.SetLastRoundId(ctx, 229) + require.NoError(t, err) + err = k.SetLastRoundId(ctx, 229) + require.NoError(t, err) // ARRANGE: Give user 202.40 $USDC. bank.Balances[user.Address] = sdk.NewCoins(sdk.NewCoin(k.Underlying, amount)) bank.Balances[recipient.Address] = sdk.Coins{} // ACT: Attempt to deposit for. - _, err := server.DepositFor(ctx, &types.MsgDepositFor{ + _, err = server.DepositFor(ctx, &types.MsgDepositFor{ Signer: user.Address, Recipient: recipient.Address, Amount: amount, @@ -272,10 +284,12 @@ func TestWithdraw(t *testing.T) { require.ErrorContains(t, err, "cannot execute /halo.v1.MsgWithdraw") // ARRANGE: Assign the international feeder role to user. - k.SetUserRole(ctx, user.Bytes, entitlements.ROLE_INTERNATIONAL_FEEDER, true) + err = k.SetUserRole(ctx, user.Bytes, entitlements.ROLE_INTERNATIONAL_FEEDER, true) + require.NoError(t, err) // ARRANGE: Generate an owner account. owner := utils.TestAccount() - k.SetOwner(ctx, owner.Address) + err = k.SetOwner(ctx, owner.Address) + require.NoError(t, err) // ARRANGE: Generate a withdrawal signature signature, err := owner.Key.Sign([]byte(fmt.Sprintf( "{\"halo_withdraw\":{\"recipient\":\"%s\",\"amount\":\"%s\",\"nonce\":%d}}", @@ -309,17 +323,20 @@ func TestWithdraw(t *testing.T) { require.ErrorContains(t, err, types.ErrInvalidSignature.Error()) // ARRANGE: Set user withdrawal nonce in state. - k.SetNonce(ctx, user.Bytes, 10) + err = k.SetNonce(ctx, user.Bytes, 10) + require.NoError(t, err) // ARRANGE: Report Ethereum Round #139. // https://etherscan.io/tx/0x9095266d81856a28b80c4500228ab994197652fc4ad1c05cd4345d1454fccfd7 - k.SetRound(ctx, 139, aggregator.RoundData{ + err = k.SetRound(ctx, 139, aggregator.RoundData{ Answer: math.NewInt(102847997), Balance: math.NewInt(4986480452), Interest: math.NewInt(708258), Supply: math.NewInt(48483293336746), UpdatedAt: 1706011979, }) - k.SetLastRoundId(ctx, 139) + require.NoError(t, err) + err = k.SetLastRoundId(ctx, 139) + require.NoError(t, err) // ACT: Attempt to withdraw with insufficient funds. _, err = server.Withdraw(ctx, &types.MsgWithdraw{ @@ -331,7 +348,8 @@ func TestWithdraw(t *testing.T) { require.ErrorContains(t, err, "unable to transfer from account to module") // ARRANGE: Set user withdrawal nonce in state. - k.SetNonce(ctx, user.Bytes, 10) + err = k.SetNonce(ctx, user.Bytes, 10) + require.NoError(t, err) // ARRANGE: Give user 150,634.259038 $USYC. bank.Balances[user.Address] = sdk.NewCoins(sdk.NewCoin(k.Denom, amount)) @@ -345,12 +363,30 @@ func TestWithdraw(t *testing.T) { require.ErrorContains(t, err, "unable to transfer from module to account") // ARRANGE: Set user withdrawal nonce in state. - k.SetNonce(ctx, user.Bytes, 10) + err = k.SetNonce(ctx, user.Bytes, 10) + require.NoError(t, err) // ARRANGE: Give user 150,634.259038 $USYC. bank.Balances[user.Address] = sdk.NewCoins(sdk.NewCoin(k.Denom, amount)) // ARRANGE: Give module 154,924.31 $USDC. bank.Balances[types.ModuleAddress.String()] = sdk.NewCoins(sdk.NewCoin(k.Underlying, expected)) + // ARRANGE: Set up a failing collection store for the attribute setter. + tmp := k.Nonces + k.Nonces = collections.NewMap( + collections.NewSchemaBuilder(mocks.FailingStore(mocks.Set, utils.GetKVStore(ctx, types.ModuleName))), + types.NoncePrefix, "nonces", collections.BytesKey, collections.Uint64Value, + ) + + // ACT: Attempt to withdraw with failing Nonces collection store. + _, err = server.Withdraw(ctx, &types.MsgWithdraw{ + Signer: user.Address, + Amount: amount, + Signature: signature, + }) + // ASSERT: The action should've failed due to collection store setter error. + require.Error(t, err, mocks.ErrorStoreAccess) + k.Nonces = tmp + // ACT: Attempt to withdraw. _, err = server.Withdraw(ctx, &types.MsgWithdraw{ Signer: user.Address, @@ -411,7 +447,8 @@ func TestWithdrawTo(t *testing.T) { require.ErrorContains(t, err, "cannot execute /halo.v1.MsgWithdrawTo") // ARRANGE: Assign the international feeder role to user. - k.SetUserRole(ctx, user.Bytes, entitlements.ROLE_INTERNATIONAL_FEEDER, true) + err = k.SetUserRole(ctx, user.Bytes, entitlements.ROLE_INTERNATIONAL_FEEDER, true) + require.NoError(t, err) // ACT: Attempt to withdraw to with an invalid recipient address. _, err = server.WithdrawTo(ctx, &types.MsgWithdrawTo{ @@ -430,10 +467,12 @@ func TestWithdrawTo(t *testing.T) { require.ErrorContains(t, err, "cannot receive uusyc") // ARRANGE: Assign the international feeder role to recipient. - k.SetUserRole(ctx, recipient.Bytes, entitlements.ROLE_INTERNATIONAL_FEEDER, true) + err = k.SetUserRole(ctx, recipient.Bytes, entitlements.ROLE_INTERNATIONAL_FEEDER, true) + require.NoError(t, err) // ARRANGE: Generate an owner account. owner := utils.TestAccount() - k.SetOwner(ctx, owner.Address) + err = k.SetOwner(ctx, owner.Address) + require.NoError(t, err) // ARRANGE: Generate a withdrawal signature signature, err := owner.Key.Sign([]byte(fmt.Sprintf( "{\"halo_withdraw\":{\"recipient\":\"%s\",\"amount\":\"%s\",\"nonce\":%d}}", @@ -469,7 +508,8 @@ func TestWithdrawTo(t *testing.T) { require.ErrorContains(t, err, types.ErrInvalidSignature.Error()) // ARRANGE: Set user withdrawal nonce in state. - k.SetNonce(ctx, recipient.Bytes, 10) + err = k.SetNonce(ctx, recipient.Bytes, 10) + require.NoError(t, err) // ACT: Attempt to withdraw to with non-existing last round. _, err = server.WithdrawTo(ctx, &types.MsgWithdrawTo{ @@ -483,17 +523,20 @@ func TestWithdrawTo(t *testing.T) { // ARRANGE: Report Ethereum Round #139. // https://etherscan.io/tx/0x9095266d81856a28b80c4500228ab994197652fc4ad1c05cd4345d1454fccfd7 - k.SetRound(ctx, 139, aggregator.RoundData{ + err = k.SetRound(ctx, 139, aggregator.RoundData{ Answer: math.NewInt(102847997), Balance: math.NewInt(4986480452), Interest: math.NewInt(708258), Supply: math.NewInt(48483293336746), UpdatedAt: 1706011979, }) - k.SetLastRoundId(ctx, 139) + require.NoError(t, err) + err = k.SetLastRoundId(ctx, 139) + require.NoError(t, err) // ARRANGE: Set user withdrawal nonce in state. - k.SetNonce(ctx, recipient.Bytes, 10) + err = k.SetNonce(ctx, recipient.Bytes, 10) + require.NoError(t, err) // ACT: Attempt to withdraw to with insufficient funds. _, err = server.WithdrawTo(ctx, &types.MsgWithdrawTo{ @@ -506,7 +549,8 @@ func TestWithdrawTo(t *testing.T) { require.ErrorContains(t, err, "unable to transfer from account to module") // ARRANGE: Set user withdrawal nonce in state. - k.SetNonce(ctx, recipient.Bytes, 10) + err = k.SetNonce(ctx, recipient.Bytes, 10) + require.NoError(t, err) // ARRANGE: Give user 150,634.259038 $USYC. bank.Balances[user.Address] = sdk.NewCoins(sdk.NewCoin(k.Denom, amount)) @@ -521,7 +565,8 @@ func TestWithdrawTo(t *testing.T) { require.ErrorContains(t, err, "unable to transfer from module to account") // ARRANGE: Set user withdrawal nonce in state. - k.SetNonce(ctx, recipient.Bytes, 10) + err = k.SetNonce(ctx, recipient.Bytes, 10) + require.NoError(t, err) // ARRANGE: Give user 150,634.259038 $USYC. bank.Balances[user.Address] = sdk.NewCoins(sdk.NewCoin(k.Denom, amount)) // ARRANGE: Give module 154,924.31 $USDC. @@ -571,12 +616,15 @@ func TestWithdrawToAdmin(t *testing.T) { // ARRANGE: Generate admin, user and recipient accounts. admin, user, recipient := utils.TestAccount(), utils.TestAccount(), utils.TestAccount() - k.SetUserRole(ctx, admin.Bytes, entitlements.ROLE_FUND_ADMIN, true) - k.SetUserRole(ctx, user.Bytes, entitlements.ROLE_INTERNATIONAL_FEEDER, true) - k.SetUserRole(ctx, recipient.Bytes, entitlements.ROLE_INTERNATIONAL_FEEDER, true) + err := k.SetUserRole(ctx, admin.Bytes, entitlements.ROLE_FUND_ADMIN, true) + require.NoError(t, err) + err = k.SetUserRole(ctx, user.Bytes, entitlements.ROLE_INTERNATIONAL_FEEDER, true) + require.NoError(t, err) + err = k.SetUserRole(ctx, recipient.Bytes, entitlements.ROLE_INTERNATIONAL_FEEDER, true) + require.NoError(t, err) // ACT: Attempt to withdraw to admin with an invalid signer address. - _, err := server.WithdrawToAdmin(ctx, &types.MsgWithdrawToAdmin{ + _, err = server.WithdrawToAdmin(ctx, &types.MsgWithdrawToAdmin{ Signer: utils.TestAccount().Invalid, }) // ASSERT: The action should've failed due to invalid signer address. @@ -608,14 +656,16 @@ func TestWithdrawToAdmin(t *testing.T) { // ARRANGE: Report Ethereum Round #139. // https://etherscan.io/tx/0x9095266d81856a28b80c4500228ab994197652fc4ad1c05cd4345d1454fccfd7 - k.SetRound(ctx, 139, aggregator.RoundData{ + err = k.SetRound(ctx, 139, aggregator.RoundData{ Answer: math.NewInt(102847997), Balance: math.NewInt(4986480452), Interest: math.NewInt(708258), Supply: math.NewInt(48483293336746), UpdatedAt: 1706011979, }) - k.SetLastRoundId(ctx, 139) + require.NoError(t, err) + err = k.SetLastRoundId(ctx, 139) + require.NoError(t, err) // ACT: Attempt to withdraw to admin with insufficient funds. _, err = server.WithdrawToAdmin(ctx, &types.MsgWithdrawToAdmin{ @@ -685,7 +735,8 @@ func TestBurn(t *testing.T) { require.ErrorContains(t, err, "cannot execute /halo.v1.MsgBurn") // ARRANGE: Assign the international feeder role to user. - k.SetUserRole(ctx, user.Bytes, entitlements.ROLE_INTERNATIONAL_FEEDER, true) + err = k.SetUserRole(ctx, user.Bytes, entitlements.ROLE_INTERNATIONAL_FEEDER, true) + require.NoError(t, err) // ACT: Attempt to burn with insufficient funds. _, err = server.Burn(ctx, &types.MsgBurn{ @@ -727,11 +778,13 @@ func TestBurnFor(t *testing.T) { // ARRANGE: Generate admin and user accounts. admin, user := utils.TestAccount(), utils.TestAccount() - k.SetUserRole(ctx, admin.Bytes, entitlements.ROLE_FUND_ADMIN, true) - k.SetUserRole(ctx, user.Bytes, entitlements.ROLE_INTERNATIONAL_FEEDER, true) + err := k.SetUserRole(ctx, admin.Bytes, entitlements.ROLE_FUND_ADMIN, true) + require.NoError(t, err) + err = k.SetUserRole(ctx, user.Bytes, entitlements.ROLE_INTERNATIONAL_FEEDER, true) + require.NoError(t, err) // ACT: Attempt to burn for with an invalid signer address. - _, err := server.BurnFor(ctx, &types.MsgBurnFor{ + _, err = server.BurnFor(ctx, &types.MsgBurnFor{ Signer: admin.Invalid, }) // ASSERT: The action should've failed due to invalid signer address. @@ -795,11 +848,13 @@ func TestMint(t *testing.T) { // ARRANGE: Generate admin and user accounts. admin, user := utils.TestAccount(), utils.TestAccount() - k.SetUserRole(ctx, admin.Bytes, entitlements.ROLE_FUND_ADMIN, true) - k.SetUserRole(ctx, user.Bytes, entitlements.ROLE_INTERNATIONAL_FEEDER, true) + err := k.SetUserRole(ctx, admin.Bytes, entitlements.ROLE_FUND_ADMIN, true) + require.NoError(t, err) + err = k.SetUserRole(ctx, user.Bytes, entitlements.ROLE_INTERNATIONAL_FEEDER, true) + require.NoError(t, err) // ACT: Attempt to mint with an invalid signer address. - _, err := server.Mint(ctx, &types.MsgMint{ + _, err = server.Mint(ctx, &types.MsgMint{ Signer: admin.Invalid, }) // ASSERT: The action should've failed due to invalid signer address. @@ -859,10 +914,12 @@ func TestMintWithRestrictions(t *testing.T) { // ARRANGE: Generate admin and user accounts. admin, user := utils.TestAccount(), utils.TestAccount() - k.SetUserRole(ctx, admin.Bytes, entitlements.ROLE_FUND_ADMIN, true) - k.SetUserRole(ctx, user.Bytes, entitlements.ROLE_INTERNATIONAL_FEEDER, true) + err := k.SetUserRole(ctx, admin.Bytes, entitlements.ROLE_FUND_ADMIN, true) + require.NoError(t, err) + err = k.SetUserRole(ctx, user.Bytes, entitlements.ROLE_INTERNATIONAL_FEEDER, true) + require.NoError(t, err) // ACT: Attempt to mint with send restrictions. - _, err := server.Mint(ctx, &types.MsgMint{ + _, err = server.Mint(ctx, &types.MsgMint{ Signer: admin.Address, To: user.Address, Amount: math.NewInt(1_000_000), @@ -897,7 +954,8 @@ func TestTradeToFiat(t *testing.T) { require.ErrorContains(t, err, types.ErrInvalidFundAdmin.Error()) // ARRANGE: Set fund admin in state. - k.SetUserRole(ctx, admin.Bytes, entitlements.ROLE_FUND_ADMIN, true) + err = k.SetUserRole(ctx, admin.Bytes, entitlements.ROLE_FUND_ADMIN, true) + require.NoError(t, err) // ACT: Attempt to trade to fiat with an invalid recipient address. _, err = server.TradeToFiat(ctx, &types.MsgTradeToFiat{ @@ -916,7 +974,8 @@ func TestTradeToFiat(t *testing.T) { require.ErrorContains(t, err, types.ErrInvalidLiquidityProvider.Error()) // ARRANGE: Set liquidity provider in state. - k.SetUserRole(ctx, recipient.Bytes, entitlements.ROLE_LIQUIDITY_PROVIDER, true) + err = k.SetUserRole(ctx, recipient.Bytes, entitlements.ROLE_LIQUIDITY_PROVIDER, true) + require.NoError(t, err) // ACT: Attempt to trade to fiat with insufficient funds. _, err = server.TradeToFiat(ctx, &types.MsgTradeToFiat{ @@ -962,7 +1021,8 @@ func TestTransferOwnership(t *testing.T) { // ARRANGE: Set owner in state. owner := utils.TestAccount() - k.SetOwner(ctx, owner.Address) + err = k.SetOwner(ctx, owner.Address) + require.NoError(t, err) // ACT: Attempt to transfer ownership with invalid signer. _, err = server.TransferOwnership(ctx, &types.MsgTransferOwnership{ @@ -982,6 +1042,22 @@ func TestTransferOwnership(t *testing.T) { // ARRANGE: Generate a new owner account. newOwner := utils.TestAccount() + // ARRANGE: Set up a failing collection store for the attribute setter. + tmp := k.Owner + k.Owner = collections.NewItem( + collections.NewSchemaBuilder(mocks.FailingStore(mocks.Set, utils.GetKVStore(ctx, types.ModuleName))), + types.OwnerKey, "owner", collections.StringValue, + ) + + // ACT: Attempt to transfer ownership with failing Owner collection store. + _, err = server.TransferOwnership(ctx, &types.MsgTransferOwnership{ + Signer: owner.Address, + NewOwner: newOwner.Address, + }) + // ASSERT: The action should've failed due to collection store setter error. + require.Error(t, err, mocks.ErrorStoreAccess) + k.Owner = tmp + // ACT: Attempt to transfer ownership. _, err = server.TransferOwnership(ctx, &types.MsgTransferOwnership{ Signer: owner.Address, diff --git a/keeper/query_server_aggregator_test.go b/keeper/query_server_aggregator_test.go index eb21174..c344594 100644 --- a/keeper/query_server_aggregator_test.go +++ b/keeper/query_server_aggregator_test.go @@ -23,7 +23,8 @@ func TestAggregatorOwnerQuery(t *testing.T) { // ARRANGE: Set aggregator owner in state. owner := utils.TestAccount() - k.SetAggregatorOwner(ctx, owner.Address) + err = k.SetAggregatorOwner(ctx, owner.Address) + require.NoError(t, err) // ACT: Attempt to query aggregator owner. res, err := server.Owner(ctx, &aggregator.QueryOwner{}) @@ -50,7 +51,8 @@ func TestNextPriceQuery(t *testing.T) { // ARRANGE: Set next price in state. // https://etherscan.io/tx/0xfd21979418ce5e6686c624841f48d11ed241b387b08eb60e2bd361de5ed1a061 expected := math.NewInt(103780600) - k.SetNextPrice(ctx, expected) + err = k.SetNextPrice(ctx, expected) + require.NoError(t, err) // ACT: Attempt to query next price with state. res, err = server.NextPrice(ctx, &aggregator.QueryNextPrice{}) @@ -70,13 +72,14 @@ func TestRoundDataQuery(t *testing.T) { // ARRANGE: Set a round in state. // https://etherscan.io/tx/0xbcba4db502a72e51a05b378d2e5867be4c60936585cedaf5aad90002f0599428 - k.SetRound(ctx, 187, aggregator.RoundData{ + err = k.SetRound(ctx, 187, aggregator.RoundData{ Answer: math.NewInt(103780685), Balance: math.NewInt(4791541000), Interest: math.NewInt(701123), Supply: math.NewInt(46169872257060), UpdatedAt: 1712071487, }) + require.NoError(t, err) // ACT: Attempt to query round data of unknown round. _, err = server.RoundData(ctx, &aggregator.QueryRoundData{RoundId: 0}) @@ -105,14 +108,16 @@ func TestLatestRoundDataQuery(t *testing.T) { // ARRANGE: Set a round in state. // https://etherscan.io/tx/0xbcba4db502a72e51a05b378d2e5867be4c60936585cedaf5aad90002f0599428 - k.SetRound(ctx, 187, aggregator.RoundData{ + err = k.SetRound(ctx, 187, aggregator.RoundData{ Answer: math.NewInt(103780685), Balance: math.NewInt(4791541000), Interest: math.NewInt(701123), Supply: math.NewInt(46169872257060), UpdatedAt: 1712071487, }) - k.SetLastRoundId(ctx, 187) + require.NoError(t, err) + err = k.SetLastRoundId(ctx, 187) + require.NoError(t, err) // ACT: Attempt to query latest round details. res, err := server.LatestRoundData(ctx, &aggregator.QueryLatestRoundData{}) @@ -136,13 +141,14 @@ func TestRoundDetailsQuery(t *testing.T) { // ARRANGE: Set a round in state. // https://etherscan.io/tx/0xbcba4db502a72e51a05b378d2e5867be4c60936585cedaf5aad90002f0599428 - k.SetRound(ctx, 187, aggregator.RoundData{ + err = k.SetRound(ctx, 187, aggregator.RoundData{ Answer: math.NewInt(103780685), Balance: math.NewInt(4791541000), Interest: math.NewInt(701123), Supply: math.NewInt(46169872257060), UpdatedAt: 1712071487, }) + require.NoError(t, err) // ACT: Attempt to query round details of unknown round. _, err = server.RoundDetails(ctx, &aggregator.QueryRoundDetails{RoundId: 0}) @@ -171,14 +177,16 @@ func TestLatestRoundDetailsQuery(t *testing.T) { // ARRANGE: Set a round in state. // https://etherscan.io/tx/0xbcba4db502a72e51a05b378d2e5867be4c60936585cedaf5aad90002f0599428 - k.SetRound(ctx, 187, aggregator.RoundData{ + err = k.SetRound(ctx, 187, aggregator.RoundData{ Answer: math.NewInt(103780685), Balance: math.NewInt(4791541000), Interest: math.NewInt(701123), Supply: math.NewInt(46169872257060), UpdatedAt: 1712071487, }) - k.SetLastRoundId(ctx, 187) + require.NoError(t, err) + err = k.SetLastRoundId(ctx, 187) + require.NoError(t, err) // ACT: Attempt to query latest round details. res, err := server.LatestRoundDetails(ctx, &aggregator.QueryLatestRoundDetails{}) diff --git a/keeper/query_server_entitlements_test.go b/keeper/query_server_entitlements_test.go index e7c5edf..f3b76f5 100644 --- a/keeper/query_server_entitlements_test.go +++ b/keeper/query_server_entitlements_test.go @@ -23,7 +23,8 @@ func TestEntitlementsOwnerQuery(t *testing.T) { // ARRANGE: Set entitlements owner in state. owner := utils.TestAccount() - k.SetEntitlementsOwner(ctx, owner.Address) + err = k.SetEntitlementsOwner(ctx, owner.Address) + require.NoError(t, err) // ACT: Attempt to query entitlements owner. res, err := server.Owner(ctx, &entitlements.QueryOwner{}) @@ -48,7 +49,8 @@ func TestPausedQuery(t *testing.T) { require.False(t, res.Paused) // ARRANGE: Set paused state to true. - k.SetPaused(ctx, true) + err = k.SetPaused(ctx, true) + require.NoError(t, err) // ACT: Attempt to query paused state with state. res, err = server.Paused(ctx, &entitlements.QueryPaused{}) @@ -83,7 +85,8 @@ func TestPublicCapabilityQuery(t *testing.T) { // ARRANGE: Set public capability in state. // NOTE: Transferring will never be public, this is just for testing. - k.SetPublicCapability(ctx, "transfer", true) + err = k.SetPublicCapability(ctx, "transfer", true) + require.NoError(t, err) // ACT: Attempt to query public capability that is enabled. res, err = server.PublicCapability(ctx, &entitlements.QueryPublicCapability{ @@ -168,7 +171,8 @@ func TestUserCapabilityQuery(t *testing.T) { require.Equal(t, 0, len(res.Roles)) userAddress, _ := sdk.AccAddressFromBech32(user.Address) - k.SetUserRole(ctx, userAddress, 2, true) + err = k.SetUserRole(ctx, userAddress, 2, true) + require.NoError(t, err) // ACT: Attempt to query role capability with an existing user and capability. res, err = server.UserCapability(ctx, &entitlements.QueryUserCapability{ @@ -181,7 +185,8 @@ func TestUserCapabilityQuery(t *testing.T) { {User: user.Address, Role: 2, Enabled: true}, }, k.GetAllUserRoles(ctx)) - k.SetUserRole(ctx, userAddress, 3, true) + err = k.SetUserRole(ctx, userAddress, 3, true) + require.NoError(t, err) // ACT: Attempt to query role capability with an existing user and multiple capabilities. res, err = server.UserCapability(ctx, &entitlements.QueryUserCapability{ Address: user.Address, diff --git a/keeper/query_server_test.go b/keeper/query_server_test.go index 9ce293a..2ee5a0f 100644 --- a/keeper/query_server_test.go +++ b/keeper/query_server_test.go @@ -22,7 +22,8 @@ func TestOwnerQuery(t *testing.T) { // ARRANGE: Set owner in state. owner := utils.TestAccount() - k.SetOwner(ctx, owner.Address) + err = k.SetOwner(ctx, owner.Address) + require.NoError(t, err) // ACT: Attempt to query owner. res, err := server.Owner(ctx, &types.QueryOwner{}) @@ -50,8 +51,10 @@ func TestNoncesQuery(t *testing.T) { // ARRANGE: Set nonces in state. user1, user2 := utils.TestAccount(), utils.TestAccount() - k.SetNonce(ctx, user1.Bytes, 1) - k.SetNonce(ctx, user2.Bytes, 2) + err = k.SetNonce(ctx, user1.Bytes, 1) + require.NoError(t, err) + err = k.SetNonce(ctx, user2.Bytes, 2) + require.NoError(t, err) // ACT: Attempt to query nonces with state. res, err = server.Nonces(ctx, &types.QueryNonces{}) @@ -88,7 +91,8 @@ func TestNonceQuery(t *testing.T) { // ARRANGE: Set nonce in state. user := utils.TestAccount() - k.SetNonce(ctx, user.Bytes, 1) + err = k.SetNonce(ctx, user.Bytes, 1) + require.NoError(t, err) // ACT: Attempt to query nonce of used account. res, err = server.Nonce(ctx, &types.QueryNonce{ diff --git a/keeper/state.go b/keeper/state.go index e8b17e4..9e6720b 100644 --- a/keeper/state.go +++ b/keeper/state.go @@ -9,8 +9,8 @@ func (k *Keeper) GetOwner(ctx context.Context) string { return owner } -func (k *Keeper) SetOwner(ctx context.Context, owner string) { - _ = k.Owner.Set(ctx, owner) +func (k *Keeper) SetOwner(ctx context.Context, owner string) error { + return k.Owner.Set(ctx, owner) } // @@ -33,12 +33,14 @@ func (k *Keeper) GetNonces(ctx context.Context) map[string]uint64 { return nonces } -func (k *Keeper) IncrementNonce(ctx context.Context, address []byte) uint64 { +func (k *Keeper) IncrementNonce(ctx context.Context, address []byte) (uint64, error) { nonce := k.GetNonce(ctx, address) - k.SetNonce(ctx, address, nonce+1) - return nonce + if err := k.SetNonce(ctx, address, nonce+1); err != nil { + return 0, err + } + return nonce, nil } -func (k *Keeper) SetNonce(ctx context.Context, address []byte, nonce uint64) { - _ = k.Nonces.Set(ctx, address, nonce) +func (k *Keeper) SetNonce(ctx context.Context, address []byte, nonce uint64) error { + return k.Nonces.Set(ctx, address, nonce) } diff --git a/keeper/state_aggregator.go b/keeper/state_aggregator.go index 2f80e33..d21b3c1 100644 --- a/keeper/state_aggregator.go +++ b/keeper/state_aggregator.go @@ -14,8 +14,8 @@ func (k *Keeper) GetAggregatorOwner(ctx context.Context) string { return owner } -func (k *Keeper) SetAggregatorOwner(ctx context.Context, owner string) { - _ = k.AggregatorOwner.Set(ctx, owner) +func (k *Keeper) SetAggregatorOwner(ctx context.Context, owner string) error { + return k.AggregatorOwner.Set(ctx, owner) } // @@ -25,13 +25,12 @@ func (k *Keeper) GetLastRoundId(ctx context.Context) uint64 { return id } -func (k *Keeper) IncrementLastRoundId(ctx context.Context) uint64 { - id, _ := k.LastRoundId.Next(ctx) - return id +func (k *Keeper) IncrementLastRoundId(ctx context.Context) (uint64, error) { + return k.LastRoundId.Next(ctx) } -func (k *Keeper) SetLastRoundId(ctx context.Context, id uint64) { - _ = k.LastRoundId.Set(ctx, id) +func (k *Keeper) SetLastRoundId(ctx context.Context, id uint64) error { + return k.LastRoundId.Set(ctx, id) } // @@ -41,8 +40,8 @@ func (k *Keeper) GetNextPrice(ctx context.Context) math.Int { return price } -func (k *Keeper) SetNextPrice(ctx context.Context, price math.Int) { - _ = k.NextPrice.Set(ctx, price) +func (k *Keeper) SetNextPrice(ctx context.Context, price math.Int) error { + return k.NextPrice.Set(ctx, price) } // @@ -67,6 +66,6 @@ func (k *Keeper) GetRounds(ctx context.Context) map[uint64]aggregator.RoundData return rounds } -func (k *Keeper) SetRound(ctx context.Context, id uint64, round aggregator.RoundData) { - _ = k.Rounds.Set(ctx, id, round) +func (k *Keeper) SetRound(ctx context.Context, id uint64, round aggregator.RoundData) error { + return k.Rounds.Set(ctx, id, round) } diff --git a/keeper/state_entitlements.go b/keeper/state_entitlements.go index 3d2c48f..3192718 100644 --- a/keeper/state_entitlements.go +++ b/keeper/state_entitlements.go @@ -32,8 +32,8 @@ func (k *Keeper) GetEntitlementsOwner(ctx context.Context) string { return owner } -func (k *Keeper) SetEntitlementsOwner(ctx context.Context, owner string) { - _ = k.EntitlementsOwner.Set(ctx, owner) +func (k *Keeper) SetEntitlementsOwner(ctx context.Context, owner string) error { + return k.EntitlementsOwner.Set(ctx, owner) } // @@ -43,8 +43,8 @@ func (k *Keeper) GetPaused(ctx context.Context) bool { return paused } -func (k *Keeper) SetPaused(ctx context.Context, paused bool) { - _ = k.Paused.Set(ctx, paused) +func (k *Keeper) SetPaused(ctx context.Context, paused bool) error { + return k.Paused.Set(ctx, paused) } // @@ -65,8 +65,8 @@ func (k *Keeper) GetPublicCapabilities(ctx context.Context) map[string]bool { return publicCapabilities } -func (k *Keeper) SetPublicCapability(ctx context.Context, method string, enabled bool) { - _ = k.PublicCapabilities.Set(ctx, method, enabled) +func (k *Keeper) SetPublicCapability(ctx context.Context, method string, enabled bool) error { + return k.PublicCapabilities.Set(ctx, method, enabled) } // @@ -101,8 +101,8 @@ func (k *Keeper) GetAllCapabilityRoles(ctx context.Context) []entitlements.RoleC return capabilityRoles } -func (k *Keeper) SetRoleCapability(ctx context.Context, method string, role entitlements.Role, enabled bool) { - _ = k.RoleCapabilities.Set(ctx, collections.Join(method, uint64(role)), enabled) +func (k *Keeper) SetRoleCapability(ctx context.Context, method string, role entitlements.Role, enabled bool) error { + return k.RoleCapabilities.Set(ctx, collections.Join(method, uint64(role)), enabled) } // @@ -143,6 +143,6 @@ func (k *Keeper) HasRole(ctx context.Context, address []byte, role entitlements. return enabled } -func (k *Keeper) SetUserRole(ctx context.Context, address []byte, role entitlements.Role, enabled bool) { - _ = k.UserRoles.Set(ctx, collections.Join(address, uint64(role)), enabled) +func (k *Keeper) SetUserRole(ctx context.Context, address []byte, role entitlements.Role, enabled bool) error { + return k.UserRoles.Set(ctx, collections.Join(address, uint64(role)), enabled) } diff --git a/keeper/state_test.go b/keeper/state_test.go index 82e3753..6ff2eab 100644 --- a/keeper/state_test.go +++ b/keeper/state_test.go @@ -18,8 +18,10 @@ func TestGetNonces(t *testing.T) { // ARRANGE: Set nonces in state. user1, user2 := utils.TestAccount(), utils.TestAccount() - keeper.SetNonce(ctx, user1.Bytes, 1) - keeper.SetNonce(ctx, user2.Bytes, 2) + err := keeper.SetNonce(ctx, user1.Bytes, 1) + require.NoError(t, err) + err = keeper.SetNonce(ctx, user2.Bytes, 2) + require.NoError(t, err) // ACT: Retrieve all nonces. nonces = keeper.GetNonces(ctx) diff --git a/utils/mocks/store.go b/utils/mocks/store.go new file mode 100644 index 0000000..86d99c1 --- /dev/null +++ b/utils/mocks/store.go @@ -0,0 +1,99 @@ +package mocks + +import ( + "context" + + "cosmossdk.io/core/store" + "cosmossdk.io/errors" + "cosmossdk.io/store/types" + db "github.com/cosmos/cosmos-db" +) + +var ErrorStoreAccess = errors.New("store", 1, "error accessing store") + +type FailingMethod string + +type StoreService struct { + failingMethod FailingMethod + original types.KVStore +} + +type testStore struct { + db db.DB + failingMethod FailingMethod + original types.KVStore +} + +type contextStoreKey struct{} + +const ( + Get FailingMethod = "get" + Has FailingMethod = "has" + Set FailingMethod = "set" + Delete FailingMethod = "delete" + Iterator FailingMethod = "iterator" + ReverseIterator FailingMethod = "reverseIterator" +) + +// FailingStore returns a store.KVStoreService that can be used to test specific errors within collections. +func FailingStore(failingMethod FailingMethod, original types.KVStore) *StoreService { + return &StoreService{failingMethod, original} +} + +func (s StoreService) OpenKVStore(_ context.Context) store.KVStore { + return testStore{ + failingMethod: s.failingMethod, + original: s.original, + } +} + +func (s StoreService) NewStoreContext() context.Context { + kv := db.NewMemDB() + return context.WithValue(context.Background(), contextStoreKey{}, &testStore{kv, s.failingMethod, s.original}) +} + +func (t testStore) Get(key []byte) ([]byte, error) { + if t.failingMethod == Get { + return nil, ErrorStoreAccess + } + return t.original.Get(key), nil +} + +func (t testStore) Has(key []byte) (bool, error) { + if t.failingMethod == Has { + return false, ErrorStoreAccess + } + return t.original.Has(key), nil +} + +func (t testStore) Set(key, value []byte) error { + if t.failingMethod == Set { + return ErrorStoreAccess + } + t.original.Set(key, value) + return nil +} + +func (t testStore) Delete(key []byte) error { + if t.failingMethod == Delete { + return ErrorStoreAccess + } + t.original.Delete(key) + return nil +} + +func (t testStore) Iterator(start, end []byte) (store.Iterator, error) { + if t.failingMethod == Iterator { + return nil, ErrorStoreAccess + } + return t.original.Iterator(start, end), nil +} + +func (t testStore) ReverseIterator(start, end []byte) (store.Iterator, error) { + if t.failingMethod == ReverseIterator { + return nil, ErrorStoreAccess + } + return t.original.ReverseIterator(start, end), nil +} + +var _ store.KVStore = testStore{} diff --git a/utils/store.go b/utils/store.go new file mode 100644 index 0000000..c3c25fa --- /dev/null +++ b/utils/store.go @@ -0,0 +1,12 @@ +package utils + +import ( + "cosmossdk.io/store/rootmulti" + "cosmossdk.io/store/types" + sdk "github.com/cosmos/cosmos-sdk/types" +) + +// GetKVStore retrieves the KVStore for the specified module from the context. +func GetKVStore(ctx sdk.Context, moduleName string) types.KVStore { + return ctx.KVStore(ctx.MultiStore().(*rootmulti.Store).StoreKeysByName()[moduleName]) +}