Skip to content

Commit 348ccbb

Browse files
feat: Oracle tutorial and example (cosmos#1508)
* Add oracle * updates * update docs * last bits * linting * reviewal comments --------- Co-authored-by: Facundo <[email protected]>
1 parent 8c12a68 commit 348ccbb

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

59 files changed

+13557
-0
lines changed

tutorials/oracle/base/Makefile

+34
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
BRANCH := $(shell git rev-parse --abbrev-ref HEAD)
2+
COMMIT := $(shell git log -1 --format='%H')
3+
4+
# don't override user values
5+
ifeq (,$(VERSION))
6+
VERSION := $(shell git describe --exact-match 2>/dev/null)
7+
# if VERSION is empty, then populate it with branch's name and raw commit hash
8+
ifeq (,$(VERSION))
9+
VERSION := $(BRANCH)-$(COMMIT)
10+
endif
11+
endif
12+
13+
# Update the ldflags with the app, client & server names
14+
ldflags = -X github.com/cosmos/cosmos-sdk/version.Name=tutorial \
15+
-X github.com/cosmos/cosmos-sdk/version.AppName=tutoriald \
16+
-X github.com/cosmos/cosmos-sdk/version.Version=$(VERSION) \
17+
-X github.com/cosmos/cosmos-sdk/version.Commit=$(COMMIT)
18+
19+
BUILD_FLAGS := -ldflags '$(ldflags)'
20+
21+
###########
22+
# Install #
23+
###########
24+
25+
all: install
26+
27+
install:
28+
@echo "--> ensure dependencies have not been modified"
29+
@go mod verify
30+
@echo "--> installing tutoriald"
31+
@go install $(BUILD_FLAGS) -mod=readonly ./cmd/tutoriald
32+
33+
init:
34+
./scripts/init.sh

tutorials/oracle/base/app/app.go

+230
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,230 @@
1+
package app
2+
3+
import (
4+
_ "embed"
5+
"io"
6+
"os"
7+
"path/filepath"
8+
"time"
9+
10+
dbm "github.com/cosmos/cosmos-db"
11+
12+
"cosmossdk.io/core/appconfig"
13+
"cosmossdk.io/depinject"
14+
"cosmossdk.io/log"
15+
16+
storetypes "cosmossdk.io/store/types"
17+
18+
"github.com/cosmos/cosmos-sdk/baseapp"
19+
"github.com/cosmos/cosmos-sdk/client"
20+
"github.com/cosmos/cosmos-sdk/codec"
21+
codectypes "github.com/cosmos/cosmos-sdk/codec/types"
22+
"github.com/cosmos/cosmos-sdk/runtime"
23+
"github.com/cosmos/cosmos-sdk/server"
24+
"github.com/cosmos/cosmos-sdk/server/api"
25+
"github.com/cosmos/cosmos-sdk/server/config"
26+
servertypes "github.com/cosmos/cosmos-sdk/server/types"
27+
"github.com/cosmos/cosmos-sdk/types/module"
28+
authkeeper "github.com/cosmos/cosmos-sdk/x/auth/keeper"
29+
bankkeeper "github.com/cosmos/cosmos-sdk/x/bank/keeper"
30+
consensuskeeper "github.com/cosmos/cosmos-sdk/x/consensus/keeper"
31+
distrkeeper "github.com/cosmos/cosmos-sdk/x/distribution/keeper"
32+
"github.com/cosmos/cosmos-sdk/x/genutil"
33+
genutiltypes "github.com/cosmos/cosmos-sdk/x/genutil/types"
34+
stakingkeeper "github.com/cosmos/cosmos-sdk/x/staking/keeper"
35+
oracle_abci "github.com/cosmos/sdk-tutorials/tutorials/oracle/base/x/oracle/abci"
36+
oraclekeeper "github.com/cosmos/sdk-tutorials/tutorials/oracle/base/x/oracle/keeper"
37+
"github.com/cosmos/sdk-tutorials/tutorials/oracle/base/x/oracle/mockprovider"
38+
39+
_ "cosmossdk.io/api/cosmos/tx/config/v1" // import for side-effects
40+
_ "github.com/cosmos/cosmos-sdk/x/auth" // import for side-effects
41+
_ "github.com/cosmos/cosmos-sdk/x/auth/tx/config" // import for side-effects
42+
_ "github.com/cosmos/cosmos-sdk/x/bank" // import for side-effects
43+
_ "github.com/cosmos/cosmos-sdk/x/consensus" // import for side-effects
44+
_ "github.com/cosmos/cosmos-sdk/x/distribution" // import for side-effects
45+
_ "github.com/cosmos/cosmos-sdk/x/mint" // import for side-effects
46+
_ "github.com/cosmos/sdk-tutorials/tutorials/oracle/base/x/oracle/module" // import for side-effects
47+
)
48+
49+
// DefaultNodeHome default home directories for the application daemon
50+
var DefaultNodeHome string
51+
52+
//go:embed app.yaml
53+
var AppConfigYAML []byte
54+
55+
var (
56+
_ runtime.AppI = (*TutorialApp)(nil)
57+
_ servertypes.Application = (*TutorialApp)(nil)
58+
)
59+
60+
// TutorialApp extends an ABCI application, but with most of its parameters exported.
61+
// They are exported for convenience in creating helper functions, as object
62+
// capabilities aren't needed for testing.
63+
type TutorialApp struct {
64+
*runtime.App
65+
legacyAmino *codec.LegacyAmino
66+
appCodec codec.Codec
67+
txConfig client.TxConfig
68+
interfaceRegistry codectypes.InterfaceRegistry
69+
70+
// keepers
71+
AccountKeeper authkeeper.AccountKeeper
72+
BankKeeper bankkeeper.Keeper
73+
StakingKeeper *stakingkeeper.Keeper
74+
DistrKeeper distrkeeper.Keeper
75+
ConsensusParamsKeeper consensuskeeper.Keeper
76+
OracleKeeper oraclekeeper.Keeper
77+
78+
// simulation manager
79+
sm *module.SimulationManager
80+
}
81+
82+
func init() {
83+
userHomeDir, err := os.UserHomeDir()
84+
if err != nil {
85+
panic(err)
86+
}
87+
88+
DefaultNodeHome = filepath.Join(userHomeDir, ".tutoriald")
89+
}
90+
91+
// AppConfig returns the default app config.
92+
func AppConfig() depinject.Config {
93+
return depinject.Configs(
94+
appconfig.LoadYAML(AppConfigYAML),
95+
depinject.Supply(
96+
// supply custom module basics
97+
map[string]module.AppModuleBasic{
98+
genutiltypes.ModuleName: genutil.NewAppModuleBasic(genutiltypes.DefaultMessageValidator),
99+
},
100+
),
101+
)
102+
}
103+
104+
// NewTutorialApp returns a reference to an initialized TutorialApp.
105+
func NewTutorialApp(
106+
logger log.Logger,
107+
db dbm.DB,
108+
traceStore io.Writer,
109+
loadLatest bool,
110+
appOpts servertypes.AppOptions,
111+
baseAppOptions ...func(*baseapp.BaseApp),
112+
) (*TutorialApp, error) {
113+
var (
114+
app = &TutorialApp{}
115+
appBuilder *runtime.AppBuilder
116+
)
117+
118+
if err := depinject.Inject(
119+
depinject.Configs(
120+
AppConfig(),
121+
depinject.Supply(
122+
logger,
123+
appOpts,
124+
),
125+
),
126+
&appBuilder,
127+
&app.appCodec,
128+
&app.legacyAmino,
129+
&app.txConfig,
130+
&app.interfaceRegistry,
131+
&app.AccountKeeper,
132+
&app.BankKeeper,
133+
&app.StakingKeeper,
134+
&app.DistrKeeper,
135+
&app.ConsensusParamsKeeper,
136+
&app.OracleKeeper,
137+
); err != nil {
138+
return nil, err
139+
}
140+
141+
voteExtHandler := oracle_abci.NewVoteExtHandler(
142+
logger,
143+
time.Second,
144+
map[string]oracle_abci.Provider{
145+
"mock": mockprovider.NewMockProvider(),
146+
},
147+
map[string][]oraclekeeper.CurrencyPair{
148+
"mock": {
149+
{Base: "ATOM", Quote: "USD"},
150+
{Base: "OSMO", Quote: "USD"},
151+
},
152+
},
153+
app.OracleKeeper,
154+
)
155+
156+
propHandler := oracle_abci.NewProposalHandler(
157+
logger,
158+
app.OracleKeeper,
159+
app.StakingKeeper,
160+
)
161+
162+
baseAppOptions = append(baseAppOptions, func(ba *baseapp.BaseApp) {
163+
ba.SetExtendVoteHandler(voteExtHandler.ExtendVoteHandler())
164+
ba.SetVerifyVoteExtensionHandler(voteExtHandler.VerifyVoteExtensionHandler())
165+
ba.SetPrepareProposal(propHandler.PrepareProposal())
166+
ba.SetProcessProposal(propHandler.ProcessProposal())
167+
ba.SetPreBlocker(propHandler.PreBlocker)
168+
})
169+
170+
app.App = appBuilder.Build(db, traceStore, baseAppOptions...)
171+
172+
// register streaming services
173+
if err := app.RegisterStreamingServices(appOpts, app.kvStoreKeys()); err != nil {
174+
return nil, err
175+
}
176+
177+
/**** Module Options ****/
178+
179+
// create the simulation manager and define the order of the modules for deterministic simulations
180+
// NOTE: this is not required apps that don't use the simulator for fuzz testing transactions
181+
app.sm = module.NewSimulationManagerFromAppModules(app.ModuleManager.Modules, make(map[string]module.AppModuleSimulation, 0))
182+
app.sm.RegisterStoreDecoders()
183+
184+
if err := app.Load(loadLatest); err != nil {
185+
return nil, err
186+
}
187+
188+
return app, nil
189+
}
190+
191+
// LegacyAmino returns TutorialApp's amino codec.
192+
func (app *TutorialApp) LegacyAmino() *codec.LegacyAmino {
193+
return app.legacyAmino
194+
}
195+
196+
// GetKey returns the KVStoreKey for the provided store key.
197+
func (app *TutorialApp) GetKey(storeKey string) *storetypes.KVStoreKey {
198+
sk := app.UnsafeFindStoreKey(storeKey)
199+
kvStoreKey, ok := sk.(*storetypes.KVStoreKey)
200+
if !ok {
201+
return nil
202+
}
203+
return kvStoreKey
204+
}
205+
206+
func (app *TutorialApp) kvStoreKeys() map[string]*storetypes.KVStoreKey {
207+
keys := make(map[string]*storetypes.KVStoreKey)
208+
for _, k := range app.GetStoreKeys() {
209+
if kv, ok := k.(*storetypes.KVStoreKey); ok {
210+
keys[kv.Name()] = kv
211+
}
212+
}
213+
214+
return keys
215+
}
216+
217+
// SimulationManager implements the SimulationApp interface
218+
func (app *TutorialApp) SimulationManager() *module.SimulationManager {
219+
return app.sm
220+
}
221+
222+
// RegisterAPIRoutes registers all application module routes with the provided
223+
// API server.
224+
func (app *TutorialApp) RegisterAPIRoutes(apiSvr *api.Server, apiConfig config.APIConfig) {
225+
app.App.RegisterAPIRoutes(apiSvr, apiConfig)
226+
// register swagger API in app.go so that other applications can override easily
227+
if err := server.RegisterSwaggerAPI(apiSvr.ClientCtx, apiSvr.Router, apiConfig.Swagger); err != nil {
228+
panic(err)
229+
}
230+
}

tutorials/oracle/base/app/app.yaml

+50
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,50 @@
1+
modules:
2+
- name: runtime
3+
config:
4+
"@type": cosmos.app.runtime.v1alpha1.Module
5+
app_name: TutorialApp
6+
# During begin block slashing happens after distr.BeginBlocker so that
7+
# there is nothing left over in the validator fee pool, so as to keep the CanWithdrawInvariant invariant.
8+
# NOTE: staking module is required if HistoricalEntries param > 0
9+
begin_blockers: [distribution, staking]
10+
end_blockers: [staking]
11+
# NOTE: The genutils module must occur after staking so that pools are properly initialized with tokens from genesis accounts.
12+
# NOTE: The genutils module must also occur after auth so that it can access the params from auth.
13+
init_genesis: [auth, bank, distribution, staking, genutil, oracle]
14+
override_store_keys:
15+
- module_name: auth
16+
kv_store_key: acc
17+
- name: auth
18+
config:
19+
"@type": cosmos.auth.module.v1.Module
20+
bech32_prefix: tutorial
21+
module_account_permissions:
22+
- account: fee_collector
23+
- account: distribution
24+
- account: bonded_tokens_pool
25+
permissions: [burner, staking]
26+
- account: not_bonded_tokens_pool
27+
permissions: [burner, staking]
28+
- name: bank
29+
config:
30+
"@type": cosmos.bank.module.v1.Module
31+
blocked_module_accounts_override:
32+
[auth, distribution, bonded_tokens_pool, not_bonded_tokens_pool]
33+
- name: staking
34+
config:
35+
"@type": cosmos.staking.module.v1.Module
36+
- name: distribution
37+
config:
38+
"@type": cosmos.distribution.module.v1.Module
39+
- name: consensus
40+
config:
41+
"@type": cosmos.consensus.module.v1.Module
42+
- name: genutil
43+
config:
44+
"@type": cosmos.genutil.module.v1.Module
45+
- name: tx
46+
config:
47+
"@type": cosmos.tx.config.v1.Config
48+
- name: oracle
49+
config:
50+
"@type": cosmos.oracle.module.v1.Module

0 commit comments

Comments
 (0)