From 0125ca5ee7f5c5d3b618e8c62a2beb4180a3693b Mon Sep 17 00:00:00 2001 From: gamarin Date: Mon, 20 May 2019 14:08:56 +0200 Subject: [PATCH 001/196] consolidate intro --- docs/intro/README.md | 110 +++++------------------------ docs/intro/sdk-app-architecture.md | 96 +++++++++++++++++++++++++ docs/intro/why-app-specific.md | 78 ++++++++++++++++++++ 3 files changed, 190 insertions(+), 94 deletions(-) create mode 100644 docs/intro/sdk-app-architecture.md create mode 100644 docs/intro/why-app-specific.md diff --git a/docs/intro/README.md b/docs/intro/README.md index f7b51e67f588..b1463d80a08a 100644 --- a/docs/intro/README.md +++ b/docs/intro/README.md @@ -1,108 +1,30 @@ # SDK Intro -The [Cosmos-SDK](https://github.com/cosmos/cosmos-sdk) is a framework for building multi-asset public Proof-of-Stake (PoS) blockchains, like the Cosmos Hub, as well as permissionned Proof-Of-Authority (PoA) blockchains. +## What is the SDK? -The goal of the Cosmos SDK is to allow developers to easily create custom blockchains from scratch that can natively interoperate with other blockchains. We envision the SDK as the npm-like framework to build secure blockchain applications on top of [Tendermint](https://github.com/tendermint/tendermint). +The [Cosmos-SDK](https://github.com/cosmos/cosmos-sdk) is a framework for building multi-asset public Proof-of-Stake (PoS) blockchains, like the Cosmos Hub, as well as permissionned Proof-Of-Authority (PoA) blockchains. Blockchains built with the Cosmos SDK are generally referred to as **application-specific blockchains**. -It is based on two major principles: +The goal of the Cosmos SDK is to allow developers to easily create custom blockchains from scratch that can natively interoperate with other blockchains. We envision the SDK as the npm-like framework to build secure blockchain applications on top of [Tendermint](https://github.com/tendermint/tendermint). SDK-based blockchains are built out of composable modules, most of which are open source and readily available for any developers to use. Anyone can create a module for the Cosmos-SDK, and integrating already-built modules is as simple as importing them into your blockchain application. What's more, the Cosmos SDK is a capabilities-based system, which allows developer to better reason about the security of interactions between modules. For a deeper look at capabilities, jump to [this section](./ocap.md). -- **Composability:** Anyone can create a module for the Cosmos-SDK, and integrating the already-built modules is as simple as importing them into your blockchain application. +## What are Application-Specific Blockchains? -- **Capabilities:** The SDK is inspired by capabilities-based security, and informed by years of wrestling with blockchain state-machines. Most developers will need to access other 3rd party modules when building their own modules. Given that the Cosmos-SDK is an open framework, some of the modules may be malicious, which means there is a need for security principles to reason about inter-module interactions. These principles are based on object-capabilities. In practice, this means that instead of having each module keep an access control list for other modules, each module implements special objects called keepers that can be passed to other modules to grant a pre-defined set of capabilities. For example, if an instance of module A's keepers is passed to module B, the latter will be able to call a restricted set of module A's functions. The capabilities of each keeper are defined by the module's developer, and it's the developer's job to understand and audit the safety of foreign code from 3rd party modules based on the capabilities they are passing into each third party module. For a deeper look at capabilities, jump to [this section](./ocap.md). +One development paradigm in the blockchain world today is that of virtual-machine blockchains like Ethereum, where development generally revolves around building a decentralised applications on top of an existing blockchain as a set of smart contracts. While smart contracts can be very good for some use cases like single-use applications (e.g. ICOs), they often fall short for building complex decentralised platforms. More generally, smart contracts can be limiting in terms of flexibility, sovereignty and performance. -## SDK Application Architecture +Application-specific blockchains offer a radically different development paradigm than virtual-machine blockchains. An application-specific blockchain is a blockchain customized to operate a single application: developers have all the freedom to make the design decisions required for the application to run optimally. They can also provide better sovereignty, security and performance. -### State machine +To learn more about application-specific blockchains, [click here](./why-app-specific.md). -At its core, a blockchain is a [replicated deterministic state machine](https://en.wikipedia.org/wiki/State_machine_replication). +## Why the Cosmos SDK? -A state machine is a computer science concept whereby a machine can have multiple states, but only one at any given time. There is a `state`, which describes the current state of the system, and `transactions`, that trigger state transitions. +The Cosmos SDK is the most advanced framework for building custom application-specific blockchains today. Here are a few reasons why you might want to consider building your decentralised application with the Cosmos SDK: -Given a state S and a transaction T, the state machine will return a new state S'. +- The default consensus engine available within the SDK is [Tendermint Core](https://github.com/tendermint/tendermint). Tendermint is the most (and only) mature BFT consensus engine in existence. It is widely used accross the industry and is considered the gold standard consensus engine for building Proof-of-Stake systems. +- The SDK is open source and designed to make it easy to build blockchains out of composable modules. As the ecosystem of open source SDK modules grow, it will become increasingly easier to build complex decentralised platforms with it. +- The SDK is inspired by capabilities-based security, and informed by years of wrestling with blockchain state-machines. This makes the Cosmos SDK a very secure environment to build blockchains. +- Most importantly, the Cosmos SDK has already been used to build many application-specific blockchains that are already in production. Among others, we can cite [Cosmos Hub](https://hub.cosmos.network), [Iris](https://irisnet.org), [Binance Chain](https://docs.binance.org/), [Terra](https://terra.money/) or [Lino](https://lino.network/). Many more are building on the Cosmos SDK. You can get a view of the ecosystem [here](https://cosmos.network/ecosystem). -``` -+--------+ +--------+ -| | | | -| S +---------------->+ S' | -| | apply(T) | | -+--------+ +--------+ -``` +## Getting started with the Cosmos SDK -In practice, the transactions are bundled in blocks to make the process more efficient. Given a state S and a block of transactions B, the state machine will return a new state S'. +- Learn more about the [architecture of an SDK application](./sdk-app-architecture.md) +- Learn how to build an application-specific blockchain from scratch with the [SDK Tutorial](https://cosmos.network/docs/tutorial) -``` -+--------+ +--------+ -| | | | -| S +----------------------------> | S' | -| | For each T in B: apply(T) | | -+--------+ +--------+ -``` - -In a blockchain context, the state machine is deterministic. This means that if you start at a given state and replay the same sequence of transactions, you will always end up with the same final state. - -The Cosmos SDK gives you maximum flexibility to define the state of your application, transaction types and state transition functions. The process of building the state-machine with the SDK will be described more in depth in the following sections. But first, let us see how it is replicated using **Tendermint**. - -### Tendermint - -As a developer, you just have to define the state machine using the Cosmos-SDK, and [*Tendermint*](https://tendermint.com/docs/introduction/what-is-tendermint.html) will handle replication over the network for you. - - -``` - ^ +-------------------------------+ ^ - | | | | Built with Cosmos SDK - | | State-machine = Application | | - | | | v - | +-------------------------------+ - | | | ^ -Blockchain node | | Consensus | | - | | | | - | +-------------------------------+ | Tendermint Core - | | | | - | | Networking | | - | | | | - v +-------------------------------+ v -``` - - -Tendermint is an application-agnostic engine that is responsible for handling the *networking* and *consensus* layers of your blockchain. In practice, this means that Tendermint is responsible for propagating and ordering transaction bytes. Tendermint Core relies on an eponymous Byzantine-Fault-Tolerant (BFT) algorithm to reach consensus on the order of transactions. For more on Tendermint, click [here](https://tendermint.com/docs/introduction/what-is-tendermint.html). - -Tendermint consensus algorithm works with a set of special nodes called *Validators*. Validators are responsible for adding blocks of transactions to the blockchain. At any given block, there is a validator set V. A validator in V is chosen by the algorithm to be the proposer of the next block. This block is considered valid if more than two thirds of V signed a *[prevote](https://tendermint.com/docs/spec/consensus/consensus.html#prevote-step-height-h-round-r)* and a *[precommit](https://tendermint.com/docs/spec/consensus/consensus.html#precommit-step-height-h-round-r)* on it, and if all the transactions that it contains are valid. The validator set can be changed by rules written in the state-machine. For a deeper look at the algorithm, click [here](https://tendermint.com/docs/introduction/what-is-tendermint.html#consensus-overview). - - -The main part of a Cosmos SDK application is a blockchain daemon that is run by each node in the network locally. If less than one third of the *validator set* is byzantine (i.e. malicious), then each node should obtain the same result when querying the state at the same time. - -## ABCI - -Tendermint passes transactions from the network to the application through an interface called the [ABCI](https://github.com/tendermint/tendermint/tree/master/abci), which the application must implement. - -``` -+---------------------+ -| | -| Application | -| | -+--------+---+--------+ - ^ | - | | ABCI - | v -+--------+---+--------+ -| | -| | -| Tendermint | -| | -| | -+---------------------+ -``` - -Note that **Tendermint only handles transaction bytes**. It has no knowledge of what these bytes mean. All Tendermint does is order these transaction bytes deterministically. Tendermint passes the bytes to the application via the ABCI, and expects a return code to inform it if the messages contained in the transactions were successfully processed or not. - -Here are the most important messages of the ABCI: - -- `CheckTx`: When a transaction is received by Tendermint Core, it is passed to the application to check if a few basic requirements are met. `CheckTx` is used to protect the mempool of full-nodes against spam. A special handler called the "Ante Handler" is used to execute a series of validation steps such as checking for sufficient fees and validating the signatures. If the check is valid, the transaction is added to the [mempool](https://tendermint.com/docs/spec/reactors/mempool/functionality.html#mempool-functionality) and relayed to peer nodes. Note that transactions are not processed (i.e. no modification of the state occurs) with `CheckTx` since they have not been included in a block yet. -- `DeliverTx`: When a [valid block](https://tendermint.com/docs/spec/blockchain/blockchain.html#validation) is received by Tendermint Core, each transaction in the given block is passed to the application via `DeliverTx` to be processed. It is during this stage that the state transitions occur. The "Ante Handler" executes again along with the actual handlers for each message in the transaction. - - `BeginBlock`/`EndBlock`: These messages are executed at the beginning and the end of each block, whether the block contains transaction or not. It is useful to trigger automatic execution of logic. Proceed with caution though, as computationally expensive loops could slow down your blockchain, or even freeze it if the loop is infinite. - -For a more detailed view of the ABCI methods and types, click [here](https://tendermint.com/docs/spec/abci/abci.html#overview). - -Any application built on Tendermint needs to implement the ABCI interface in order to communicate with the underlying local Tendermint engine. Fortunately, you do not have to implement the ABCI interface. The Cosmos SDK provides a boilerplate implementation of it in the form of [baseapp](./sdk-design.md#baseapp). - -### Next, let us go into the [high-level design principles of the SDK](./sdk-design.md) \ No newline at end of file diff --git a/docs/intro/sdk-app-architecture.md b/docs/intro/sdk-app-architecture.md new file mode 100644 index 000000000000..ab6a93e9b745 --- /dev/null +++ b/docs/intro/sdk-app-architecture.md @@ -0,0 +1,96 @@ +# SDK Application Architecture + +## State machine + +At its core, a blockchain is a [replicated deterministic state machine](https://en.wikipedia.org/wiki/State_machine_replication). + +A state machine is a computer science concept whereby a machine can have multiple states, but only one at any given time. There is a `state`, which describes the current state of the system, and `transactions`, that trigger state transitions. + +Given a state S and a transaction T, the state machine will return a new state S'. + +``` ++--------+ +--------+ +| | | | +| S +---------------->+ S' | +| | apply(T) | | ++--------+ +--------+ +``` + +In practice, the transactions are bundled in blocks to make the process more efficient. Given a state S and a block of transactions B, the state machine will return a new state S'. + +``` ++--------+ +--------+ +| | | | +| S +----------------------------> | S' | +| | For each T in B: apply(T) | | ++--------+ +--------+ +``` + +In a blockchain context, the state machine is deterministic. This means that if you start at a given state and replay the same sequence of transactions, you will always end up with the same final state. + +The Cosmos SDK gives you maximum flexibility to define the state of your application, transaction types and state transition functions. The process of building the state-machine with the SDK will be described more in depth in the following sections. But first, let us see how it is replicated using **Tendermint**. + +### Tendermint + +As a developer, you just have to define the state machine using the Cosmos-SDK, and [*Tendermint*](https://tendermint.com/docs/introduction/what-is-tendermint.html) will handle replication over the network for you. + + +``` + ^ +-------------------------------+ ^ + | | | | Built with Cosmos SDK + | | State-machine = Application | | + | | | v + | +-------------------------------+ + | | | ^ +Blockchain node | | Consensus | | + | | | | + | +-------------------------------+ | Tendermint Core + | | | | + | | Networking | | + | | | | + v +-------------------------------+ v +``` + + +Tendermint is an application-agnostic engine that is responsible for handling the *networking* and *consensus* layers of your blockchain. In practice, this means that Tendermint is responsible for propagating and ordering transaction bytes. Tendermint Core relies on an eponymous Byzantine-Fault-Tolerant (BFT) algorithm to reach consensus on the order of transactions. For more on Tendermint, click [here](https://tendermint.com/docs/introduction/what-is-tendermint.html). + +Tendermint consensus algorithm works with a set of special nodes called *Validators*. Validators are responsible for adding blocks of transactions to the blockchain. At any given block, there is a validator set V. A validator in V is chosen by the algorithm to be the proposer of the next block. This block is considered valid if more than two thirds of V signed a *[prevote](https://tendermint.com/docs/spec/consensus/consensus.html#prevote-step-height-h-round-r)* and a *[precommit](https://tendermint.com/docs/spec/consensus/consensus.html#precommit-step-height-h-round-r)* on it, and if all the transactions that it contains are valid. The validator set can be changed by rules written in the state-machine. For a deeper look at the algorithm, click [here](https://tendermint.com/docs/introduction/what-is-tendermint.html#consensus-overview). + + +The main part of a Cosmos SDK application is a blockchain daemon that is run by each node in the network locally. If less than one third of the *validator set* is byzantine (i.e. malicious), then each node should obtain the same result when querying the state at the same time. + +## ABCI + +Tendermint passes transactions from the network to the application through an interface called the [ABCI](https://github.com/tendermint/tendermint/tree/master/abci), which the application must implement. + +``` ++---------------------+ +| | +| Application | +| | ++--------+---+--------+ + ^ | + | | ABCI + | v ++--------+---+--------+ +| | +| | +| Tendermint | +| | +| | ++---------------------+ +``` + +Note that **Tendermint only handles transaction bytes**. It has no knowledge of what these bytes mean. All Tendermint does is order these transaction bytes deterministically. Tendermint passes the bytes to the application via the ABCI, and expects a return code to inform it if the messages contained in the transactions were successfully processed or not. + +Here are the most important messages of the ABCI: + +- `CheckTx`: When a transaction is received by Tendermint Core, it is passed to the application to check if a few basic requirements are met. `CheckTx` is used to protect the mempool of full-nodes against spam. A special handler called the "Ante Handler" is used to execute a series of validation steps such as checking for sufficient fees and validating the signatures. If the check is valid, the transaction is added to the [mempool](https://tendermint.com/docs/spec/reactors/mempool/functionality.html#mempool-functionality) and relayed to peer nodes. Note that transactions are not processed (i.e. no modification of the state occurs) with `CheckTx` since they have not been included in a block yet. +- `DeliverTx`: When a [valid block](https://tendermint.com/docs/spec/blockchain/blockchain.html#validation) is received by Tendermint Core, each transaction in the given block is passed to the application via `DeliverTx` to be processed. It is during this stage that the state transitions occur. The "Ante Handler" executes again along with the actual handlers for each message in the transaction. + - `BeginBlock`/`EndBlock`: These messages are executed at the beginning and the end of each block, whether the block contains transaction or not. It is useful to trigger automatic execution of logic. Proceed with caution though, as computationally expensive loops could slow down your blockchain, or even freeze it if the loop is infinite. + +For a more detailed view of the ABCI methods and types, click [here](https://tendermint.com/docs/spec/abci/abci.html#overview). + +Any application built on Tendermint needs to implement the ABCI interface in order to communicate with the underlying local Tendermint engine. Fortunately, you do not have to implement the ABCI interface. The Cosmos SDK provides a boilerplate implementation of it in the form of [baseapp](./sdk-design.md#baseapp). + +### Next, let us go into the [high-level design principles of the SDK](./sdk-design.md) \ No newline at end of file diff --git a/docs/intro/why-app-specific.md b/docs/intro/why-app-specific.md new file mode 100644 index 000000000000..078b0d388d6b --- /dev/null +++ b/docs/intro/why-app-specific.md @@ -0,0 +1,78 @@ +# Application-Specific Blockchains + +This document explains what application-specific blockchains are, and why developers would want to build one as opposed to writing Smart Contracts. + +## What are application-specific blockchains? + +Application-specific blockchains are blockchains customized to operate a single application. Instead of building a decentralised application on top of an underlying blockchain like Ethereum, developers build their own blockchain from the ground up. This means building a full-node client, a light-client, and all the necessary interfaces (CLI, REST, ...) to interract with the nodes. + +``` + ^ +-------------------------------+ ^ + | | | | Built with Cosmos SDK + | | State-machine = Application | | + | | | v + | +-------------------------------+ + | | | ^ +Blockchain node | | Consensus | | + | | | | + | +-------------------------------+ | Tendermint Core + | | | | + | | Networking | | + | | | | + v +-------------------------------+ v +``` + +## What are the shortcomings of Smart Contracts? + +Virtual-machine blockchains like Ethereum addressed the demand for more programmability back in 2014. At the time, the options available for building decentralised applications were quite limited. Most developers would build on top of the complex and limited Bitcoin scripting language, or fork the Bitcoin codebase which was hard to work with and customize. + +Virtual-machine blockchains came in with a new value proposition. Their state-machine incorporates a virtual-machine that is able to interpret turing-complete programs called Smart Contracts. These Smart Contracts are very good for use cases like one-time events (e.g. ICOs), but they can fall short for building complex decentralised platforms: + +- Smart Contracts are generally developed with specific programming languages that can be interpreted by the underlying virtual-machine. These programming languages are often immature and inherently limited by the constraints of the virtual-machine. For example, the Ethereum Virtual Machine does not allow developers to implement automatic execution of code. Developers are also limited to the account-based system of the EVM, and they can only choose from a limited set of functions for their cryptographic operations. These are examples, but they hint at the lack of **flexibility** a smart contract environment often entails. +- Smart Contracts are all run by the same virtual machine. This means that they compete for resources, which can severly restrain **performance**. And even if the state-machine were to be split in multiple subsets (e.g. via sharding), Smart Contracts would still need to be interpeted by a virtual machine, which would limit performance compared to a native application implemented at state-machine level (our benchmarks show an improvement on the order of x10 in performance when the virtual-machine is removed). +- Another issue with the fact that Smart Contracts share the same underlying environment is the resulting limitation in **sovereignty**. A decentralised application is an ecosystem that involves multiple players. If the application is built on a general-purpose virtual-machine blockchain, these players have very limited sovereignty over it, and are ultimately superseded by the governance of the underlying blockchain. If there is a bug in the application, very little can be done about it. + +Application-Specific Blockchains are designed to address these shortcomings. + +## Application-Specific Blockchains Benefits + +### Flexibility + +Application-specific blockchains give maximum flexibility to developers: + +- Developers can choose among multiple frameworks to build their state-machine. The most widely used today is the Cosmos SDK, but others exist (e.g. Lotion, Weave, ...). The choice will most of the time be done based on the programming language they want to use (Cosmos SDK and Weave are in Golang, Lotion is in Javascript, ...). +- Developers can swap consensus engine. Today, only Tendermint is production-ready, but in the future other engines are expected to emerge. +- Even when they settle for a framework and consensus engine, developers still have the freedom to tweak them if they don't perfectly match their requirements in their pristine forms. +- Developers are free to explore the full spectrum of tradeoffs (e.g. number of validators vs transaction throughput, safety vs availability in asynchrony, ...) and design choices (DB or IAVL tree for storage, UTXO or account model, ...). +- Developers can implement automatic execution of code. In the Cosmos SDK, logic can be automatically triggered at the beginning and the end of each block. They are also free to choose the cryptographic library used in their application, as opposed to being constrained by what is made available by the underlying environment in the case of virtual-machine blockchains. + +The list above contains a few examples that show how much flexibility application-specific blockchains give to developers. The goal of Cosmos and the Cosmos SDK is to make developer tooling as generic and composable as possible, so that each part of the stack can be forked, tweaked and improved without losing compatibility. As the community grows, more alternative for each of the core building blocks will emerge, giving more options to developers. + +### Performance + +Decentralised applications built with Smart Contracts are inherently capped in performance by the underlying environment. For a decentralised application to optimise performance, it needs to be built as an application-specific blockchains. Here are the benefits of an application-specific blockchains with regards to performance: + +- Developers of application-specific blockchains can choose to operate with novel consensus engine such as Tendermint BFT. Compared to Proof-of-Work (used by most virtual-machine blockchains today), it offers significant gains in throuhgput. +- An application-specific blockchain only operates a single application, so that the application does not compete with others for computation. This is the opposite of most non-sharded virtual-machine blockchains today, where smart contracts all compete for computation. +- Even if a virtual-machine blockchain offered application-based sharding coupled with an efficient consensus algorithm, performance would still be limited by the virtual-machine itself. The real throughput bottleneck is the state-machine, and requiring transactions to be interpreted by a virtual-machine significantly increases the computational complexity of processing them. + +### Security + +Security is hard to quantify, and greatly varies from platform to platform. That said here are some important benefits an application-specific blockchain can bring in terms of security: + +- Developers can choose proven programming language like Golang when building their application-specific blockchains, as opposed to smart contract programming languages that are often more immature. +- Developers are not constrained by the cryptographic functions made available by the underlying virtual-machines. They can use their own custom cryptography, and rely on well-audited crypto libraries. +- Developers do not have to worry about potential bugs or exploitable mechanisms in the underlying virtual-machine, making it easier to reason about the security of the application. + +### Sovereignty + +One of the major benefits of application-specific blockchains is sovereignty. A decentralised application is an ecosystem that involves many actors: users, developers, third-party services, and more. When developers build on virtual-machine blockchain where many decentralised applications coexist, the community of the application is different than the community of the underlying blockchain, and the latter supersedes the former. If there is a bug or if a new feature is needed, the community of the application has very little sovereignty to upgrade the code. If the community of the underlying blockchain refuses to act, nothing can happen. + +The fundamental issue here is that the governance of the application and the governance of the network are not aligned. This issue is solved by application-specific blockchains. Because application-specific blockchains specialize to operate a single application, the community of the application has full control over the entire chain. This ensures the community will not be stuck if a bug is discovered, and that it has the entire freedom to choose how it is going to evolve. + +## Start Building Your Application-Specific Blockchain Today + +Clearly, application-specific blockchains are awesome. The Cosmos SDK makes it easier than ever to build them. What are you waiting for? + +- Learn how to build an application-specific blockchain from scratch with the [SDK tutorial](https://cosmos.network/docs/tutorial) +- Learn more about the [high-level architecture](./sdk-app-architecture) of an SDK application. \ No newline at end of file From a004c57af5dabf59e6af998cafde7e0c660ba7f2 Mon Sep 17 00:00:00 2001 From: gamarin Date: Tue, 21 May 2019 12:11:52 +0200 Subject: [PATCH 002/196] start anatomy of sdk app --- docs/concepts/app-anatomy.md | 41 ++++++++++++++++++++++++++++++++++++ 1 file changed, 41 insertions(+) create mode 100644 docs/concepts/app-anatomy.md diff --git a/docs/concepts/app-anatomy.md b/docs/concepts/app-anatomy.md new file mode 100644 index 000000000000..9f2d545c2225 --- /dev/null +++ b/docs/concepts/app-anatomy.md @@ -0,0 +1,41 @@ +# Anatomy of an SDK Application + +## Pre-requisite reading + +- [High-level overview of an SDK application architecture](../intro/sdk-app-architecture.md) +- [Cosmos SDK design overview](../intro/sdk-design.md) + +## Synopsis + +This document describes the core parts of a Cosmos SDK application. + +- [Core Application File](#core-application-file) +- [Modules](#modules) +- [Client](#client) +- [Intefaces](#interfaces) +- [Dependencies and Makefile](#dependencies-and-makefile) + +The core parts above will generally translate to the following file tree in the application directory: + +``` +./application +├── app.go +├── x/ +├── cmd +│ ├── nsd +│ └── nscli +├── Gopkg.toml +└── Makefile +``` + +## Core Application File + +In general, the core of the state-machine is defined in a file called `app.go`. + +## Modules (`./x/`) + +## Client (Daemon) + +## Interfaces + +## Dependencies and Makefile \ No newline at end of file From 07b7415540312c03fed8f75c67cc2cdcfeae47c7 Mon Sep 17 00:00:00 2001 From: gamarin Date: Tue, 21 May 2019 17:29:45 +0200 Subject: [PATCH 003/196] wokring --- docs/concepts/app-anatomy.md | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/docs/concepts/app-anatomy.md b/docs/concepts/app-anatomy.md index 9f2d545c2225..315a4fdacad5 100644 --- a/docs/concepts/app-anatomy.md +++ b/docs/concepts/app-anatomy.md @@ -30,7 +30,13 @@ The core parts above will generally translate to the following file tree in the ## Core Application File -In general, the core of the state-machine is defined in a file called `app.go`. +In general, the core of the state-machine is defined in a file called `app.go`. It mainly contains the **type definition of the application** and functions to **create and initialize it**. + +### Type Definition of the Application + +### Constructor Function + +This function constructs a new application of the type defined above. It is called in the dae ## Modules (`./x/`) From 4a86564d6e583086d0e29f9fb2edb7348040aad3 Mon Sep 17 00:00:00 2001 From: gamarin Date: Fri, 24 May 2019 12:41:21 +0200 Subject: [PATCH 004/196] working --- docs/concepts/app-anatomy.md | 55 +++++++++++++++++++++++++++++------- docs/concepts/node.md | 11 ++++++++ 2 files changed, 56 insertions(+), 10 deletions(-) create mode 100644 docs/concepts/node.md diff --git a/docs/concepts/app-anatomy.md b/docs/concepts/app-anatomy.md index 315a4fdacad5..5679f3043e2b 100644 --- a/docs/concepts/app-anatomy.md +++ b/docs/concepts/app-anatomy.md @@ -7,40 +7,75 @@ ## Synopsis -This document describes the core parts of a Cosmos SDK application. +This document describes the core parts of a Cosmos SDK application. The placeholder name for this application will be `app`. +- [Node Client](#node-client) - [Core Application File](#core-application-file) - [Modules](#modules) -- [Client](#client) - [Intefaces](#interfaces) - [Dependencies and Makefile](#dependencies-and-makefile) -The core parts above will generally translate to the following file tree in the application directory: +The core parts listed above will generally translate to the following file tree in the application directory: ``` ./application +├── cmd/ +│ ├── appd +│ └── appcli ├── app.go ├── x/ -├── cmd -│ ├── nsd -│ └── nscli +│ ├── auth +│ └── bank ├── Gopkg.toml └── Makefile ``` +## Node Client (Daemon) + +The Daemon, or Full-Node Client, is the core process of an SDK-based blockchain. Participants in the network run this process to initialize their state-machine, connect with other full-nodes and update their state-machine as new blocks come in. + +``` + ^ +-------------------------------+ ^ + | | | | Built with Cosmos SDK + | | State-machine = Application | | + | | | v + | +-------------------------------+ + | | | ^ +Blockchain node | | Consensus | | + | | | | + | +-------------------------------+ | Tendermint Core + | | | | + | | Networking | | + | | | | + v +-------------------------------+ v +``` +The blockchain full-node presents itself as a binary, generally suffixed by `-d` (e.g. `appd` for `app` or `gaiad` for the `gaia`) for "daemon". This binary is built by running a simple `main.go` function placed in `cmd/appd/`. This operation usually happens through the [Makefil](#dependencies-and-makefile). + +To learn more about the `main.go` function, [click here](./node#`main.go`). + +Once the main binary is built, the node can be started by running the `start` command. The core logic behind the `start` command is implemented in the SDK itself in the [`/server/start.go`](https://github.com/cosmos/cosmos-sdk/blob/master/server/start.go) file. The main [`start` command function](https://github.com/cosmos/cosmos-sdk/blob/master/server/start.go#L31) takes a [`context`](https://godoc.org/github.com/cosmos/cosmos-sdk/client/context) and [`appCreator`](#constructor-function-(`appCreator`)) as arguments. The `appCreator` is a constructor function for the SDK application, and is used in the starting process of the full-node. + +The `start` command function primarily does three things: + +1- Create an instance of the state-machine defined in [`app.go`](#core-application-file) using the `appCreator`. +2- Initialize the state-machine with the latest known state, extracted from the `db` stored in the `~/.appd/data` folder. +3- Create and start a new Tendermint instance. Among other things, the node will perform a handshake with its peer. It will get the latest `appBlockHeight` from them, and replay blocks to get there if `appBlockHeight`is greater than the current height. If the node is starte + +To learn more about the `start` command, [click here](./node#`start`-command). + ## Core Application File In general, the core of the state-machine is defined in a file called `app.go`. It mainly contains the **type definition of the application** and functions to **create and initialize it**. ### Type Definition of the Application -### Constructor Function +### Constructor Function (`appCreator`) -This function constructs a new application of the type defined above. It is called in the dae +This function constructs a new application of the type defined above. It is passed to the `start` function that runs the daemon, and called in the `InitChain` -## Modules (`./x/`) +### InitChainer -## Client (Daemon) +## Modules (`./x/`) ## Interfaces diff --git a/docs/concepts/node.md b/docs/concepts/node.md new file mode 100644 index 000000000000..ca7d2927f413 --- /dev/null +++ b/docs/concepts/node.md @@ -0,0 +1,11 @@ +# Node Client (Daemon) + +## Pre-Requisite Reading + +## `main.go` + +TODO + +## `start` command + +TODO \ No newline at end of file From a9e303ce4c0ba68755a6d6a1e62a9f4b8a19efd0 Mon Sep 17 00:00:00 2001 From: gamarin Date: Tue, 28 May 2019 17:32:29 +0200 Subject: [PATCH 005/196] querier --- docs/concepts/amino.md | 3 + docs/concepts/app-anatomy.md | 124 ++++++++++++++++++++++++++++++---- docs/concepts/baseapp.md | 4 ++ docs/concepts/genesis.md | 3 + docs/concepts/handler.md | 1 + docs/concepts/keeper.md | 0 docs/concepts/modules.md | 3 + docs/concepts/node.md | 2 +- docs/concepts/querier.md | 3 + docs/concepts/tx-lifecycle.md | 0 docs/intro/README.md | 2 +- 11 files changed, 128 insertions(+), 17 deletions(-) create mode 100644 docs/concepts/amino.md create mode 100644 docs/concepts/genesis.md create mode 100644 docs/concepts/handler.md create mode 100644 docs/concepts/keeper.md create mode 100644 docs/concepts/modules.md create mode 100644 docs/concepts/querier.md create mode 100644 docs/concepts/tx-lifecycle.md diff --git a/docs/concepts/amino.md b/docs/concepts/amino.md new file mode 100644 index 000000000000..8113f63e9630 --- /dev/null +++ b/docs/concepts/amino.md @@ -0,0 +1,3 @@ +# Amnio Encoding + +TODO \ No newline at end of file diff --git a/docs/concepts/app-anatomy.md b/docs/concepts/app-anatomy.md index 5679f3043e2b..7c7598e9c164 100644 --- a/docs/concepts/app-anatomy.md +++ b/docs/concepts/app-anatomy.md @@ -2,7 +2,7 @@ ## Pre-requisite reading -- [High-level overview of an SDK application architecture](../intro/sdk-app-architecture.md) +- [High-level overview of the architecture of an SDK application](../intro/sdk-app-architecture.md) - [Cosmos SDK design overview](../intro/sdk-design.md) ## Synopsis @@ -15,10 +15,10 @@ This document describes the core parts of a Cosmos SDK application. The placehol - [Intefaces](#interfaces) - [Dependencies and Makefile](#dependencies-and-makefile) -The core parts listed above will generally translate to the following file tree in the application directory: +The core parts listed above will generally translate to the following directory tree: ``` -./application +./app ├── cmd/ │ ├── appd │ └── appcli @@ -35,11 +35,13 @@ The core parts listed above will generally translate to the following file tree The Daemon, or Full-Node Client, is the core process of an SDK-based blockchain. Participants in the network run this process to initialize their state-machine, connect with other full-nodes and update their state-machine as new blocks come in. ``` - ^ +-------------------------------+ ^ + +-------------------------------+ + | | + ^ | State+machine = Application | ^ | | | | Built with Cosmos SDK - | | State-machine = Application | | - | | | v - | +-------------------------------+ + | | ^ + | | + | +----------- | ABCI | ----------+ v + | | + v | | | | ^ Blockchain node | | Consensus | | | | | | @@ -51,17 +53,17 @@ Blockchain node | | Consensus | | ``` The blockchain full-node presents itself as a binary, generally suffixed by `-d` (e.g. `appd` for `app` or `gaiad` for the `gaia`) for "daemon". This binary is built by running a simple `main.go` function placed in `cmd/appd/`. This operation usually happens through the [Makefil](#dependencies-and-makefile). -To learn more about the `main.go` function, [click here](./node#`main.go`). +To learn more about the `main.go` function, [click here](./node.md#main-function). Once the main binary is built, the node can be started by running the `start` command. The core logic behind the `start` command is implemented in the SDK itself in the [`/server/start.go`](https://github.com/cosmos/cosmos-sdk/blob/master/server/start.go) file. The main [`start` command function](https://github.com/cosmos/cosmos-sdk/blob/master/server/start.go#L31) takes a [`context`](https://godoc.org/github.com/cosmos/cosmos-sdk/client/context) and [`appCreator`](#constructor-function-(`appCreator`)) as arguments. The `appCreator` is a constructor function for the SDK application, and is used in the starting process of the full-node. The `start` command function primarily does three things: 1- Create an instance of the state-machine defined in [`app.go`](#core-application-file) using the `appCreator`. -2- Initialize the state-machine with the latest known state, extracted from the `db` stored in the `~/.appd/data` folder. -3- Create and start a new Tendermint instance. Among other things, the node will perform a handshake with its peer. It will get the latest `appBlockHeight` from them, and replay blocks to get there if `appBlockHeight`is greater than the current height. If the node is starte +2- Initialize the state-machine with the latest known state, extracted from the `db` stored in the `~/.appd/data` folder. At this point, the state-machine is at height `appBlockHeight`. +3- Create and start a new Tendermint instance. Among other things, the node will perform a handshake with its peers. It will get the latest `blockHeight` from them, and replay blocks to sync to this height if it is greater than the local `appBlockHeight`. If `appBlockHeight` is `0`, the node is starting from genesis and Tendermint sends an `InitChain` message via the ABCI to the `app`, which triggers the [`InitChainer`](#initchainer). -To learn more about the `start` command, [click here](./node#`start`-command). +To learn more about the `start` command, [click here](./node.md#start-command). ## Core Application File @@ -69,14 +71,106 @@ In general, the core of the state-machine is defined in a file called `app.go`. ### Type Definition of the Application -### Constructor Function (`appCreator`) +The first thing defined in `app.go` is the `type` of the application. It is generally comprised of the following parts: -This function constructs a new application of the type defined above. It is passed to the `start` function that runs the daemon, and called in the `InitChain` +- **A reference to [`baseapp`](./baseapp.md).** The custom application defined in `app.go` is a golang embedding of the `baseapp` type. `baseapp` implements most of the core logic for the application, including all the [ABCI methods](https://tendermint.com/docs/spec/abci/abci.html#overview) and the routing logic. When a transaction is relayed by Tendermint to the application, the latter uses `baseapp`'s methods to route them to the appropriate module. +- **A list of store keys**. The [store](./store.md), which contains the entire state, is implemented as a multistore (i.e. a store of stores) in the Cosmos SDK. Each module uses one or multiple stores in the multistore to persist their part of the state. These stores can be accessed with specific keys that are declared in the `app` type. These keys, along with the `keepers`, are at the heart of the [object-capabilities model](../intro/ocap.md) of the Cosmos SDK. +- **A list of module's `keepers`.** Each module defines an abstraction called `keeper`, which handles reads and writes for this module's store(s). The `keeper`'s methods of one module can be called from other modules (if authorized), which is why they are declared in the application's type. +- **A reference to a `codec`.** The Cosmos SDK gives developers the freedom to choose the encoding framework for their application. The application's `codec` is used to serialize and deserialize data structures in order to store them, as stores can only persist `[]bytes`. The `codec` must be deterministic. Most SDK application use [amino](./amino.md) as their `codec`. + +You can see an example of application type definition [here](https://github.com/cosmos/sdk-application-tutorial/blob/master/app.go#L27-L43). + +### Constructor Function + +This function constructs a new application of the type defined above. It is [called](https://github.com/cosmos/cosmos-sdk/blob/master/server/start.go#L117) everytime the full-node is started with the `start` command. Here are the main actions performed by this function: + +- Instanciate a new application with a reference to a `baseapp` instance, a codec and all the appropriate store keys. +- Instanciate all the `keepers` defined in the application's `type`. +- Initialize the application's [`routes`](./baseapp.md#routing) with the [`handlers`](#handler) of each one of the application's modules. When a transaction is relayed to the application by Tendermint via the ABCI, it is routed to the appropriate module's handler using the routes defined here. +- Initialize the application's [query routes](./baseapp.md#query-routing) with the [`queriers`](#querier) of each of the application's modules. When a user query comes in, it is routed to the appropriate module using the query routes defined here. +- Set the application's [`initChainer`](#initchainer) and mount the stores. +- Return the application. + +Note that this function only creates an instance of the app, while the actual state is either carried over from the `~/.appd/data` folder if the node is restarted, or generated from the genesis file if the node is started for the first time. + +You can see an example of application constructor [here](https://github.com/cosmos/sdk-application-tutorial/blob/master/app.go#L46-L128). ### InitChainer -## Modules (`./x/`) +The `initChainer` is a function that initializes the state of the application from a [genesis file](./genesis.md) (i.e. token balances of genesis accounts). It is called when the application received the `InitChain` message from the Tendermint engine, which happens when the node is started at `appBlockHeight == 0` (i.e. on genesis). The application must set the `initChainer` in its constructor via the [`setInitChainer`](https://godoc.org/github.com/cosmos/cosmos-sdk/baseapp#BaseApp.SetInitChainer) method. + +You can see an example of an `initChainer` [here](https://github.com/cosmos/sdk-application-tutorial/blob/master/app.go#L137-L155). + +### Register Codec + +The `MakeCodec` function is the last important function of the `app.go` file. The goal of this function is to instanciate a codec `cdc` (e.g. [amino](./amino.md)) and calls the `RegisterCodec(*codec.Codec)` method of each module used within the application to register `cdc` to each module. + +In turn, the `RegisterCodec` function of each module register the custom interfaces and type structures of their respective module so that they can be marhsaled and unmarshaled. + +You can see an example of a `MakeCodec` [here](You can see an example of an `initChainer` [here](https://github.com/cosmos/sdk-application-tutorial/blob/master/app.go#L189-L198).). + +## Modules + +Modules are the heart and soul of an SDK application. They can be considered as state-machines within the state-machine. When a transaction is relayed from the underlying Tendermint engine via the ABCI to the application, it is routed by `baseapp` to the appropriate module in order to be processed. This paradigm enables developers to easily build complex state-machines, as most of the modules they need often already exist. For developers, most of the work involved in building an SDK application revolves around building custom modules required by their application that do not exist, and integrating them with modules that do already exist into one coherent application. In the application directory, the standard practice is to store modules in the `x/` folder. + +To learn more about modules, [click here](./modules.md) + +### Message Types + +A message is a custom type defined by each module that implements the [`message`](https://github.com/cosmos/cosmos-sdk/blob/master/types/tx_msg.go#L8-L29) interface. Each `transaction` contains one or multiple `messages`. When a valid block of transactions is received by the full-node, Tendermint relays each one to the application via [`DeliverTx`](https://tendermint.com/docs/app-dev/abci-spec.html#delivertx). Upon receiving the transaction, the application first unmarshalls it. Then, it extracts the message(s) contained in the application. With the [`Type()`](https://github.com/cosmos/cosmos-sdk/blob/master/types/tx_msg.go#L16) method, `baseapp` is able to know which modules defines the message. It is then able to route it to the appropriate module's [handler](#handler) in order for the message to be processed. If the message is succesfully processed, the state is updated. + +Module developers create custom message types when they build their own module. The general practice is to prefix the type declaration of the message with `Msg`. For example, the message type `MsgSend` allows users to transfer tokens. It is processed by the handler of the `bank` module, which ultimately calls the `keeper` of the `auth` module in order to update the state. + +To learn more about messages, [click here](./tx-msgs.md) + +### Handler + +The `handler` refers to the part of the module responsible for processing the message after it is routed by `baseapp`. `handler` functions of modules (except those of the `auth` module) are only executed if the transaction is relayed from Tendermint by the `DeliverTx` ABCI message. If the transaction is realyed by `CheckTx`, only stateless checks and fee-related (i.e. `auth` module-related) stateful checks are performed. To better understand the difference between `DeliverTx`and `CheckTx`, as well as the difference between stateful and stateless checks, click [here](./tx-lifecycle.md). + +The handler of a module is generally defined in a file called `handler.go` and consists of: + +- A **switch function** `NewHandler` to route the message to the appropriate handler function. This function returns a `handler` function, and is used in `app.go` to initialize the [application's router](./baseapp.md#routing). See an example of such a switch [here](https://github.com/cosmos/sdk-application-tutorial/blob/master/x/nameservice/handler.go#L10-L22). +- **One handler function for each message type defined by the module**. Developers write the message processing logic in these functions. This generally involves doing stateful checks to ensure the message is valid and calling [`keeper`](#keeper)'s methods to update the state. + +Handler functions return a result of type [`sdk.Result`](https://github.com/cosmos/cosmos-sdk/blob/master/types/result.go#L14-L37), which informs the application on wether the message was succesfully processed and. + +To learn more about handlers, [click here](./handler.md). + +### Keeper + +`Keepers` are the gatekeepers of their module's store(s). To read or write in a module's store, it is mandatory to go through one of its `keeper`'s methods. This is ensured by the [object-capabilities](./ocap.md) model of the Cosmos SDK. Only objects that hold the key to a store can access it, and only the module's `keeper` should hold the key(s) to the module's store(s). + +`Keepers` are generally defined in a file called `keeper.go`. It contains the `keeper`'s type definition and methods. + +The `keeper` type definition generally consists of: + +- **Key(s)** to the module's store(s) in the multistore. +- Reference to **other module's `keepers`**. Only needed if the `keeper` needs to access other module's store(s) (either to read or write from them). +- A reference to the application's **codec**. The `keeper` needs it to marshal structs before storing them, or to unmarhsal them when it retrieves them, because stores only accept `[]bytes` as value. + +The rest of the file defines the `keeper`'s methods, primarily getters and setters. You can check an example of a `keeper` implementation [here](https://github.com/cosmos/sdk-application-tutorial/blob/master/x/nameservice/keeper.go). + +To learn more about `keepers`, [click here](./keeper.md). + +### Querier + +`Queriers` are very similar to `handlers`, except they serve user queries to the state as opposed to processing transactions. A query is initiated from an [interface](#intefaces) by an end-user who provides a `queryRoute` and some `data`. The query is then routed to the correct application's `querier` by `baseapp`'s [`handleQueryCustom`](https://github.com/cosmos/cosmos-sdk/blob/master/baseapp/baseapp.go#L519-L556) method using `queryRoute`. + +The `Querier` of a module are defined in a file called `querier.go`, and consists of: + +- A **switch function** `NewQuerier` to route the query to the appropriate `querier` function. This function returns a `querier` function, and is used in `app.go` to initialize the [application's query router](./baseapp.md#query-routing). See an example of such a switch [here](https://github.com/cosmos/sdk-application-tutorial/blob/master/x/nameservice/querier.go#L21-L34). +- - **One querier function for each data type defined by the module that needs to be queryable**. Developers write the query processing logic in these functions. This generally involves calling [`keeper`](#keeper)'s methods to query the state and marshalling it to JSON. See an example of `querier` functions [here](https://github.com/cosmos/sdk-application-tutorial/blob/master/x/nameservice/querier.go#L37-L101). + +To learn more about `queriers`, [click here](./querier.md). ## Interfaces -## Dependencies and Makefile \ No newline at end of file +### Module Intefaces + +### Application Interfaces + +## Dependencies and Makefile + +## Next + +Learn more about the [Lifecycle of a transaction](./tx-lifecycle.md). \ No newline at end of file diff --git a/docs/concepts/baseapp.md b/docs/concepts/baseapp.md index e96cec525e5c..c4f71f33f696 100644 --- a/docs/concepts/baseapp.md +++ b/docs/concepts/baseapp.md @@ -32,6 +32,10 @@ The BaseApp is responsible for managing the context passed into handlers - it makes the block header available and provides the right stores for `CheckTx` and `DeliverTx`. BaseApp is completely agnostic to serialization formats. +## Routing + +TODO + ## Transaction Life Cycle During the execution of a transaction, it may pass through both `CheckTx` and diff --git a/docs/concepts/genesis.md b/docs/concepts/genesis.md new file mode 100644 index 000000000000..5e3dbd31dcad --- /dev/null +++ b/docs/concepts/genesis.md @@ -0,0 +1,3 @@ +# Genesis File + +TODO \ No newline at end of file diff --git a/docs/concepts/handler.md b/docs/concepts/handler.md new file mode 100644 index 000000000000..f8fc820df8de --- /dev/null +++ b/docs/concepts/handler.md @@ -0,0 +1 @@ +# Handlers \ No newline at end of file diff --git a/docs/concepts/keeper.md b/docs/concepts/keeper.md new file mode 100644 index 000000000000..e69de29bb2d1 diff --git a/docs/concepts/modules.md b/docs/concepts/modules.md new file mode 100644 index 000000000000..cfd71f817963 --- /dev/null +++ b/docs/concepts/modules.md @@ -0,0 +1,3 @@ +# SDK Modules + +Todo: Intro concept docs on modules \ No newline at end of file diff --git a/docs/concepts/node.md b/docs/concepts/node.md index ca7d2927f413..08687164db87 100644 --- a/docs/concepts/node.md +++ b/docs/concepts/node.md @@ -2,7 +2,7 @@ ## Pre-Requisite Reading -## `main.go` +## main function TODO diff --git a/docs/concepts/querier.md b/docs/concepts/querier.md new file mode 100644 index 000000000000..3afa9f0cc308 --- /dev/null +++ b/docs/concepts/querier.md @@ -0,0 +1,3 @@ +# Queriers + +TODO \ No newline at end of file diff --git a/docs/concepts/tx-lifecycle.md b/docs/concepts/tx-lifecycle.md new file mode 100644 index 000000000000..e69de29bb2d1 diff --git a/docs/intro/README.md b/docs/intro/README.md index b1463d80a08a..d172351845cb 100644 --- a/docs/intro/README.md +++ b/docs/intro/README.md @@ -2,7 +2,7 @@ ## What is the SDK? -The [Cosmos-SDK](https://github.com/cosmos/cosmos-sdk) is a framework for building multi-asset public Proof-of-Stake (PoS) blockchains, like the Cosmos Hub, as well as permissionned Proof-Of-Authority (PoA) blockchains. Blockchains built with the Cosmos SDK are generally referred to as **application-specific blockchains**. +The [Cosmos-SDK](https://github.com/cosmos/cosmos-sdk) is an open-source framework for building multi-asset public Proof-of-Stake (PoS) blockchains, like the Cosmos Hub, as well as permissionned Proof-Of-Authority (PoA) blockchains. Blockchains built with the Cosmos SDK are generally referred to as **application-specific blockchains**. The goal of the Cosmos SDK is to allow developers to easily create custom blockchains from scratch that can natively interoperate with other blockchains. We envision the SDK as the npm-like framework to build secure blockchain applications on top of [Tendermint](https://github.com/tendermint/tendermint). SDK-based blockchains are built out of composable modules, most of which are open source and readily available for any developers to use. Anyone can create a module for the Cosmos-SDK, and integrating already-built modules is as simple as importing them into your blockchain application. What's more, the Cosmos SDK is a capabilities-based system, which allows developer to better reason about the security of interactions between modules. For a deeper look at capabilities, jump to [this section](./ocap.md). From 0913fb6a058249e94df9fe2364f5819bbdc47b89 Mon Sep 17 00:00:00 2001 From: gamarin Date: Mon, 3 Jun 2019 18:44:08 +0200 Subject: [PATCH 006/196] working --- docs/concepts/app-anatomy.md | 43 ++++++++++++++++++++++++++------- docs/concepts/interfaces.md | 3 +++ docs/concepts/module-interfaces | 5 ++++ docs/concepts/node.md | 4 ++- 4 files changed, 45 insertions(+), 10 deletions(-) create mode 100644 docs/concepts/interfaces.md create mode 100644 docs/concepts/module-interfaces diff --git a/docs/concepts/app-anatomy.md b/docs/concepts/app-anatomy.md index 7c7598e9c164..53b070ebf30e 100644 --- a/docs/concepts/app-anatomy.md +++ b/docs/concepts/app-anatomy.md @@ -35,15 +35,15 @@ The core parts listed above will generally translate to the following directory The Daemon, or Full-Node Client, is the core process of an SDK-based blockchain. Participants in the network run this process to initialize their state-machine, connect with other full-nodes and update their state-machine as new blocks come in. ``` - +-------------------------------+ - | | - ^ | State+machine = Application | ^ + ^ +-------------------------------+ ^ + | | | | + | | State+machine = Application | | | | | | Built with Cosmos SDK | | ^ + | | | +----------- | ABCI | ----------+ v - | | + v | - | | | ^ -Blockchain node | | Consensus | | + | | + v | ^ + | | | | +Blockchain Node | | Consensus | | | | | | | +-------------------------------+ | Tendermint Core | | | | @@ -163,11 +163,36 @@ The `Querier` of a module are defined in a file called `querier.go`, and consist To learn more about `queriers`, [click here](./querier.md). -## Interfaces +### Command-Line and REST Interfaces + +Each module defines command-line commands and REST routes to be exposed to end-user via the [application's interfaces](#application-interfaces). This enables end-users to create messages of the types defined in the module, or to query the subset of the state managed by the module. + +#### CLI + +Generally, the commands related to a module are defined in a folder called `client/cli` in the module's folder. The CLI divides commands in two category, transactions and queries, defined in `client/cli/tx.go` and `client/cli/query.go` respectively. Both build commands on top of the [Cobra Library](https://github.com/spf13/cobra): + +- Transactions commands let users generate new transactions so that they can be included in a block and eventually update the state. One command should be created for each [message type](#message-types) defined in the module. The command calls the constructor of the message with the parameters provided by the end-user, and wraps it into a transaction. The SDK handles signing and the addition of other transaction metadata. See examples of transactions commands [here](https://github.com/cosmos/sdk-application-tutorial/blob/master/x/nameservice/client/cli/tx.go). +- Queries let users query the subset of the state defined by the module. Query commands forward queries to the [application's query router](./baseapp.md#query-routing), which routes them to the appropriate [querier](#querier) the `queryRoute` parameter supplied. See examples of query commands [here](https://github.com/cosmos/sdk-application-tutorial/blob/master/x/nameservice/client/cli/query.go). + +To learn more about modules CLI, [click here](./module-interfaces.md#cli). + +#### REST + + + +## Application Interfaces + +Developers build interfaces to let end-users interract with full-node clients. This means querying data from the full-node or creating and sending new transactions to be relayed by the full-node and eventually included in a block. + +### Command-Line Interface (CLI) + +The main interface is the [Command-Line Interface](./interfaces.md#cli). The CLI of an SDK application is built from aggregating commands defined in each of the modules used by the application. + +### REST Interface -### Module Intefaces +A second important interface is the [REST interface](./interfaces.md#rest). It interract with the [Light Client Daemon](./node.md#lcd) -### Application Interfaces +To learn more about interfaces, [click here](./interfaces.md) ## Dependencies and Makefile diff --git a/docs/concepts/interfaces.md b/docs/concepts/interfaces.md new file mode 100644 index 000000000000..bb580a5cf171 --- /dev/null +++ b/docs/concepts/interfaces.md @@ -0,0 +1,3 @@ +# Interfaces + +TODO \ No newline at end of file diff --git a/docs/concepts/module-interfaces b/docs/concepts/module-interfaces new file mode 100644 index 000000000000..0cd27c895326 --- /dev/null +++ b/docs/concepts/module-interfaces @@ -0,0 +1,5 @@ +# Module Interfaces + +## CLI + +## REST \ No newline at end of file diff --git a/docs/concepts/node.md b/docs/concepts/node.md index 08687164db87..ec860bbdf18a 100644 --- a/docs/concepts/node.md +++ b/docs/concepts/node.md @@ -8,4 +8,6 @@ TODO ## `start` command -TODO \ No newline at end of file +TODO + +## LCD \ No newline at end of file From 6346e8b07a2bd63e78414bbb3a69324518b09465 Mon Sep 17 00:00:00 2001 From: gamarin Date: Wed, 5 Jun 2019 17:10:54 +0200 Subject: [PATCH 007/196] workiiiing --- docs/.vuepress/config.js | 4 +++- docs/concepts/app-anatomy.md | 23 +++++++++++++++++------ docs/intro/why-app-specific.md | 2 +- 3 files changed, 21 insertions(+), 8 deletions(-) diff --git a/docs/.vuepress/config.js b/docs/.vuepress/config.js index 005ba4ae18d5..282c3dec5797 100644 --- a/docs/.vuepress/config.js +++ b/docs/.vuepress/config.js @@ -29,8 +29,10 @@ module.exports = { collapsable: true, children: [ "/intro/", + "/intro/why-app-specific", + "/intro/sdk-app-architecture", "/intro/sdk-design", - "/intro/ocap" + "intro/ocap" ] }, { diff --git a/docs/concepts/app-anatomy.md b/docs/concepts/app-anatomy.md index 53b070ebf30e..346b35abab80 100644 --- a/docs/concepts/app-anatomy.md +++ b/docs/concepts/app-anatomy.md @@ -178,24 +178,35 @@ To learn more about modules CLI, [click here](./module-interfaces.md#cli). #### REST +The module's REST interface lets users generate transactions and query the state through REST calls to the application's [light-client daemon](./node.md#lcd). REST routes are defined in a file `client/rest/rest.go`, which is composed of: +- A `RegisterRoutes` function, which registers each route defined in the file. This function is called from the [main application's interface](#application-interfaces) for each module used within the application. The router used in the SDK is [Gorilla's mux](https://github.com/gorilla/mux). +- Custom request type definitions for each query or transaction creation function that needs to be exposed. These custom request types build on the [base `request` type](https://github.com/cosmos/cosmos-sdk/blob/master/types/rest/rest.go#L32-L43) of the Cosmos SDK. +- One handler function for each request that can be routed to the given module. These functions implement the core logic necessary to serve the request. -## Application Interfaces +See an example of a module's `rest.go` file [here](https://github.com/cosmos/sdk-application-tutorial/blob/master/x/nameservice/client/rest/rest.go). -Developers build interfaces to let end-users interract with full-node clients. This means querying data from the full-node or creating and sending new transactions to be relayed by the full-node and eventually included in a block. +To learn more about modules REST interface, [click here](./module-interfaces.md#rest). -### Command-Line Interface (CLI) +## Application Interface -The main interface is the [Command-Line Interface](./interfaces.md#cli). The CLI of an SDK application is built from aggregating commands defined in each of the modules used by the application. +Interfaces let end-users interract with full-node clients. This means querying data from the full-node or creating and sending new transactions to be relayed by the full-node and eventually included in a block. -### REST Interface +The main interface is the [Command-Line Interface](./interfaces.md#cli). The CLI of an SDK application is built by aggregating [CLI commands](#cli) defined in each of the modules used by the application. The CLI of an application generally has the `-cli` suffix (e.g. `appcli`), and defined in a file called `cmd/appcli/main.go`. The file contains: -A second important interface is the [REST interface](./interfaces.md#rest). It interract with the [Light Client Daemon](./node.md#lcd) +- **A `main()` function**, which is executed to build the `appcli` interface client. This function prepares each command and adds them to the `rootCmd` before building them. At the root of `appCli`, the function adds generic commands like `status`, `keys` and `config`, query commands, tx commands and `rest-server`. +- **Query commands** are added by calling the `queryCmd` function, also defined in `appcli/main.go`. This function returns a Cobra command that contains the query commands defined in each of the application's modules (passed as an array of `sdk.ModuleClients` from the `main()` function), as well as some other lower level query commands such as block or validator queries. Query command are called by using the command `appcli query [query]` of the CLI. +- **Transaction commands** are added by calling the `txCmd` function. Similar to `queryCmd`, the function returns a Cobra command that contains the tx commands defined in each of the application's modules, as well as lower level tx commands like transaction signing or broadcasting. Tx commands are called by using the command `appcli tx [tx]` of the CLI. +- **A `registerRoutes` function**, which is called from the `main()` function when initializing the [application's light-client daemon (LCD)](./node.md#lcd) (i.e. `rest-server`). `registerRoutes` calls the `RegisterRoutes` function of each of the application's module, thereby registering the routes of the module to the lcd's router. The LCD can be started by running the following command `appcli rest-server`. + +See an example of an application's main command-line file [here](https://github.com/cosmos/sdk-application-tutorial/blob/master/cmd/nscli/main.go). To learn more about interfaces, [click here](./interfaces.md) ## Dependencies and Makefile + + ## Next Learn more about the [Lifecycle of a transaction](./tx-lifecycle.md). \ No newline at end of file diff --git a/docs/intro/why-app-specific.md b/docs/intro/why-app-specific.md index 473603a512d2..1b160429f6eb 100644 --- a/docs/intro/why-app-specific.md +++ b/docs/intro/why-app-specific.md @@ -75,5 +75,5 @@ The fundamental issue here is that the governance of the application and the gov Clearly, application-specific blockchains are awesome. The Cosmos SDK makes it easier than ever to build them. What are you waiting for? +- Learn more about the [high-level architecture](./sdk-app-architecture) of an SDK application. - Learn how to build an application-specific blockchain from scratch with the [SDK tutorial](https://cosmos.network/docs/tutorial) -- Learn more about the [high-level architecture](./sdk-app-architecture) of an SDK application. \ No newline at end of file From 23f8f78a9c4e92209aa918174996b443c4e4b78b Mon Sep 17 00:00:00 2001 From: gamarin Date: Wed, 5 Jun 2019 17:48:36 +0200 Subject: [PATCH 008/196] finish --- docs/concepts/app-anatomy.md | 7 +------ 1 file changed, 1 insertion(+), 6 deletions(-) diff --git a/docs/concepts/app-anatomy.md b/docs/concepts/app-anatomy.md index 346b35abab80..7609e2e32f5c 100644 --- a/docs/concepts/app-anatomy.md +++ b/docs/concepts/app-anatomy.md @@ -13,7 +13,6 @@ This document describes the core parts of a Cosmos SDK application. The placehol - [Core Application File](#core-application-file) - [Modules](#modules) - [Intefaces](#interfaces) -- [Dependencies and Makefile](#dependencies-and-makefile) The core parts listed above will generally translate to the following directory tree: @@ -26,7 +25,7 @@ The core parts listed above will generally translate to the following directory ├── x/ │ ├── auth │ └── bank -├── Gopkg.toml +├── go.mod └── Makefile ``` @@ -203,10 +202,6 @@ See an example of an application's main command-line file [here](https://github. To learn more about interfaces, [click here](./interfaces.md) -## Dependencies and Makefile - - - ## Next Learn more about the [Lifecycle of a transaction](./tx-lifecycle.md). \ No newline at end of file From 9c2fd4efa48078aafd781cb77e7dd9dbad65a51b Mon Sep 17 00:00:00 2001 From: gamarin Date: Wed, 5 Jun 2019 19:06:30 +0200 Subject: [PATCH 009/196] add dep and makefile --- docs/concepts/app-anatomy.md | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/docs/concepts/app-anatomy.md b/docs/concepts/app-anatomy.md index 7609e2e32f5c..e0a34aa33c58 100644 --- a/docs/concepts/app-anatomy.md +++ b/docs/concepts/app-anatomy.md @@ -13,6 +13,7 @@ This document describes the core parts of a Cosmos SDK application. The placehol - [Core Application File](#core-application-file) - [Modules](#modules) - [Intefaces](#interfaces) +- [Dependencies and Makefile](#dependencies-and-makefile) The core parts listed above will generally translate to the following directory tree: @@ -29,7 +30,7 @@ The core parts listed above will generally translate to the following directory └── Makefile ``` -## Node Client (Daemon) +## Node Client The Daemon, or Full-Node Client, is the core process of an SDK-based blockchain. Participants in the network run this process to initialize their state-machine, connect with other full-nodes and update their state-machine as new blocks come in. @@ -200,7 +201,13 @@ The main interface is the [Command-Line Interface](./interfaces.md#cli). The CLI See an example of an application's main command-line file [here](https://github.com/cosmos/sdk-application-tutorial/blob/master/cmd/nscli/main.go). -To learn more about interfaces, [click here](./interfaces.md) +To learn more about interfaces, [click here](./interfaces.md). + +## Dependencies and Makefile + +This section is optional, as developers are free to choose their depencency manager and project building method. That said, the current most used framework for versioning control is [`go.mod`](https://github.com/golang/go/wiki/Modules). It ensures each of the libraries used throughout the application are imported with the correct version. An example can be found [here](https://github.com/cosmos/sdk-application-tutorial/blob/master/go.mod). + +For building the application, a [Makefile](https://en.wikipedia.org/wiki/Makefile) is generally used. The Makefile primarily ensures that the `go.mod` is run before building the two entrypoints to the application, [`appd`](#node-client) and [`appcli`](#application-interface). An example of Makefile can be found [here](https://github.com/cosmos/sdk-application-tutorial/blob/master/Makefile). ## Next From 9baaed748555ad1831a55a8edba327a918914ed3 Mon Sep 17 00:00:00 2001 From: gamarin2 Date: Wed, 5 Jun 2019 19:07:50 +0200 Subject: [PATCH 010/196] Apply suggestions from code review Co-Authored-By: Alessio Treglia --- docs/concepts/app-anatomy.md | 24 ++++++++++++------------ 1 file changed, 12 insertions(+), 12 deletions(-) diff --git a/docs/concepts/app-anatomy.md b/docs/concepts/app-anatomy.md index e0a34aa33c58..f891c83efcd3 100644 --- a/docs/concepts/app-anatomy.md +++ b/docs/concepts/app-anatomy.md @@ -12,7 +12,7 @@ This document describes the core parts of a Cosmos SDK application. The placehol - [Node Client](#node-client) - [Core Application File](#core-application-file) - [Modules](#modules) -- [Intefaces](#interfaces) +- [Interfaces](#interfaces) - [Dependencies and Makefile](#dependencies-and-makefile) The core parts listed above will generally translate to the following directory tree: @@ -51,7 +51,7 @@ Blockchain Node | | Consensus | | | | | | v +-------------------------------+ v ``` -The blockchain full-node presents itself as a binary, generally suffixed by `-d` (e.g. `appd` for `app` or `gaiad` for the `gaia`) for "daemon". This binary is built by running a simple `main.go` function placed in `cmd/appd/`. This operation usually happens through the [Makefil](#dependencies-and-makefile). +The blockchain full-node presents itself as a binary, generally suffixed by `-d` (e.g. `appd` for `app` or `gaiad` for the `gaia`) for "daemon". This binary is built by running a simple `main.go` function placed in `cmd/appd/`. This operation usually happens through the [Makefile](#dependencies-and-makefile). To learn more about the `main.go` function, [click here](./node.md#main-function). @@ -73,7 +73,7 @@ In general, the core of the state-machine is defined in a file called `app.go`. The first thing defined in `app.go` is the `type` of the application. It is generally comprised of the following parts: -- **A reference to [`baseapp`](./baseapp.md).** The custom application defined in `app.go` is a golang embedding of the `baseapp` type. `baseapp` implements most of the core logic for the application, including all the [ABCI methods](https://tendermint.com/docs/spec/abci/abci.html#overview) and the routing logic. When a transaction is relayed by Tendermint to the application, the latter uses `baseapp`'s methods to route them to the appropriate module. +- **A reference to [`baseapp`](./baseapp.md).** The custom application defined in `app.go` is a Golang embedding of the `baseapp` type. `baseapp` implements most of the core logic for the application, including all the [ABCI methods](https://tendermint.com/docs/spec/abci/abci.html#overview) and the routing logic. When a transaction is relayed by Tendermint to the application, the latter uses `baseapp`'s methods to route them to the appropriate module. - **A list of store keys**. The [store](./store.md), which contains the entire state, is implemented as a multistore (i.e. a store of stores) in the Cosmos SDK. Each module uses one or multiple stores in the multistore to persist their part of the state. These stores can be accessed with specific keys that are declared in the `app` type. These keys, along with the `keepers`, are at the heart of the [object-capabilities model](../intro/ocap.md) of the Cosmos SDK. - **A list of module's `keepers`.** Each module defines an abstraction called `keeper`, which handles reads and writes for this module's store(s). The `keeper`'s methods of one module can be called from other modules (if authorized), which is why they are declared in the application's type. - **A reference to a `codec`.** The Cosmos SDK gives developers the freedom to choose the encoding framework for their application. The application's `codec` is used to serialize and deserialize data structures in order to store them, as stores can only persist `[]bytes`. The `codec` must be deterministic. Most SDK application use [amino](./amino.md) as their `codec`. @@ -82,10 +82,10 @@ You can see an example of application type definition [here](https://github.com/ ### Constructor Function -This function constructs a new application of the type defined above. It is [called](https://github.com/cosmos/cosmos-sdk/blob/master/server/start.go#L117) everytime the full-node is started with the `start` command. Here are the main actions performed by this function: +This function constructs a new application of the type defined above. It is [called](https://github.com/cosmos/cosmos-sdk/blob/master/server/start.go#L117) every time the full-node is started with the `start` command. Here are the main actions performed by this function: - Instanciate a new application with a reference to a `baseapp` instance, a codec and all the appropriate store keys. -- Instanciate all the `keepers` defined in the application's `type`. +- Instantiate all the `keepers` defined in the application's `type`. - Initialize the application's [`routes`](./baseapp.md#routing) with the [`handlers`](#handler) of each one of the application's modules. When a transaction is relayed to the application by Tendermint via the ABCI, it is routed to the appropriate module's handler using the routes defined here. - Initialize the application's [query routes](./baseapp.md#query-routing) with the [`queriers`](#querier) of each of the application's modules. When a user query comes in, it is routed to the appropriate module using the query routes defined here. - Set the application's [`initChainer`](#initchainer) and mount the stores. @@ -103,7 +103,7 @@ You can see an example of an `initChainer` [here](https://github.com/cosmos/sdk- ### Register Codec -The `MakeCodec` function is the last important function of the `app.go` file. The goal of this function is to instanciate a codec `cdc` (e.g. [amino](./amino.md)) and calls the `RegisterCodec(*codec.Codec)` method of each module used within the application to register `cdc` to each module. +The `MakeCodec` function is the last important function of the `app.go` file. The goal of this function is to instantiate a codec `cdc` (e.g. [amino](./amino.md)) and calls the `RegisterCodec(*codec.Codec)` method of each module used within the application to register `cdc` to each module. In turn, the `RegisterCodec` function of each module register the custom interfaces and type structures of their respective module so that they can be marhsaled and unmarshaled. @@ -117,7 +117,7 @@ To learn more about modules, [click here](./modules.md) ### Message Types -A message is a custom type defined by each module that implements the [`message`](https://github.com/cosmos/cosmos-sdk/blob/master/types/tx_msg.go#L8-L29) interface. Each `transaction` contains one or multiple `messages`. When a valid block of transactions is received by the full-node, Tendermint relays each one to the application via [`DeliverTx`](https://tendermint.com/docs/app-dev/abci-spec.html#delivertx). Upon receiving the transaction, the application first unmarshalls it. Then, it extracts the message(s) contained in the application. With the [`Type()`](https://github.com/cosmos/cosmos-sdk/blob/master/types/tx_msg.go#L16) method, `baseapp` is able to know which modules defines the message. It is then able to route it to the appropriate module's [handler](#handler) in order for the message to be processed. If the message is succesfully processed, the state is updated. +A message is a custom type defined by each module that implements the [`message`](https://github.com/cosmos/cosmos-sdk/blob/master/types/tx_msg.go#L8-L29) interface. Each `transaction` contains one or multiple `messages`. When a valid block of transactions is received by the full-node, Tendermint relays each one to the application via [`DeliverTx`](https://tendermint.com/docs/app-dev/abci-spec.html#delivertx). Upon receiving the transaction, the application first unmarshalls it. Then, it extracts the message(s) contained in the application. With the [`Type()`](https://github.com/cosmos/cosmos-sdk/blob/master/types/tx_msg.go#L16) method, `baseapp` is able to know which modules defines the message. It is then able to route it to the appropriate module's [handler](#handler) in order for the message to be processed. If the message is successfully processed, the state is updated. Module developers create custom message types when they build their own module. The general practice is to prefix the type declaration of the message with `Msg`. For example, the message type `MsgSend` allows users to transfer tokens. It is processed by the handler of the `bank` module, which ultimately calls the `keeper` of the `auth` module in order to update the state. @@ -125,14 +125,14 @@ To learn more about messages, [click here](./tx-msgs.md) ### Handler -The `handler` refers to the part of the module responsible for processing the message after it is routed by `baseapp`. `handler` functions of modules (except those of the `auth` module) are only executed if the transaction is relayed from Tendermint by the `DeliverTx` ABCI message. If the transaction is realyed by `CheckTx`, only stateless checks and fee-related (i.e. `auth` module-related) stateful checks are performed. To better understand the difference between `DeliverTx`and `CheckTx`, as well as the difference between stateful and stateless checks, click [here](./tx-lifecycle.md). +The `handler` refers to the part of the module responsible for processing the message after it is routed by `baseapp`. `handler` functions of modules (except those of the `auth` module) are only executed if the transaction is relayed from Tendermint by the `DeliverTx` ABCI message. If the transaction is relayed by `CheckTx`, only stateless checks and fee-related (i.e. `auth` module-related) stateful checks are performed. To better understand the difference between `DeliverTx`and `CheckTx`, as well as the difference between stateful and stateless checks, click [here](./tx-lifecycle.md). The handler of a module is generally defined in a file called `handler.go` and consists of: - A **switch function** `NewHandler` to route the message to the appropriate handler function. This function returns a `handler` function, and is used in `app.go` to initialize the [application's router](./baseapp.md#routing). See an example of such a switch [here](https://github.com/cosmos/sdk-application-tutorial/blob/master/x/nameservice/handler.go#L10-L22). - **One handler function for each message type defined by the module**. Developers write the message processing logic in these functions. This generally involves doing stateful checks to ensure the message is valid and calling [`keeper`](#keeper)'s methods to update the state. -Handler functions return a result of type [`sdk.Result`](https://github.com/cosmos/cosmos-sdk/blob/master/types/result.go#L14-L37), which informs the application on wether the message was succesfully processed and. +Handler functions return a result of type [`sdk.Result`](https://github.com/cosmos/cosmos-sdk/blob/master/types/result.go#L14-L37), which informs the application on wether the message was successfully processed and. To learn more about handlers, [click here](./handler.md). @@ -146,7 +146,7 @@ The `keeper` type definition generally consists of: - **Key(s)** to the module's store(s) in the multistore. - Reference to **other module's `keepers`**. Only needed if the `keeper` needs to access other module's store(s) (either to read or write from them). -- A reference to the application's **codec**. The `keeper` needs it to marshal structs before storing them, or to unmarhsal them when it retrieves them, because stores only accept `[]bytes` as value. +- A reference to the application's **codec**. The `keeper` needs it to marshal structs before storing them, or to unmarshal them when it retrieves them, because stores only accept `[]bytes` as value. The rest of the file defines the `keeper`'s methods, primarily getters and setters. You can check an example of a `keeper` implementation [here](https://github.com/cosmos/sdk-application-tutorial/blob/master/x/nameservice/keeper.go). @@ -190,7 +190,7 @@ To learn more about modules REST interface, [click here](./module-interfaces.md# ## Application Interface -Interfaces let end-users interract with full-node clients. This means querying data from the full-node or creating and sending new transactions to be relayed by the full-node and eventually included in a block. +Interfaces let end-users interact with full-node clients. This means querying data from the full-node or creating and sending new transactions to be relayed by the full-node and eventually included in a block. The main interface is the [Command-Line Interface](./interfaces.md#cli). The CLI of an SDK application is built by aggregating [CLI commands](#cli) defined in each of the modules used by the application. The CLI of an application generally has the `-cli` suffix (e.g. `appcli`), and defined in a file called `cmd/appcli/main.go`. The file contains: @@ -211,4 +211,4 @@ For building the application, a [Makefile](https://en.wikipedia.org/wiki/Makefil ## Next -Learn more about the [Lifecycle of a transaction](./tx-lifecycle.md). \ No newline at end of file +Learn more about the [Lifecycle of a transaction](./tx-lifecycle.md). From 45f56545488a673824578325efd7f17fe106d443 Mon Sep 17 00:00:00 2001 From: gamarin Date: Wed, 5 Jun 2019 20:11:45 +0200 Subject: [PATCH 011/196] typo --- docs/concepts/app-anatomy.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/concepts/app-anatomy.md b/docs/concepts/app-anatomy.md index f891c83efcd3..1cf0334218d2 100644 --- a/docs/concepts/app-anatomy.md +++ b/docs/concepts/app-anatomy.md @@ -51,7 +51,7 @@ Blockchain Node | | Consensus | | | | | | v +-------------------------------+ v ``` -The blockchain full-node presents itself as a binary, generally suffixed by `-d` (e.g. `appd` for `app` or `gaiad` for the `gaia`) for "daemon". This binary is built by running a simple `main.go` function placed in `cmd/appd/`. This operation usually happens through the [Makefile](#dependencies-and-makefile). +The blockchain full-node presents itself as a binary, generally suffixed by `-d` (e.g. `appd` for `app` or `gaiad` for `gaia`) for "daemon". This binary is built by running a simple `main.go` function placed in `cmd/appd/`. This operation usually happens through the [Makefile](#dependencies-and-makefile). To learn more about the `main.go` function, [click here](./node.md#main-function). From 265ed8eae853ac8a832892eff0213f4fe75ef0bb Mon Sep 17 00:00:00 2001 From: gamarin Date: Wed, 5 Jun 2019 20:12:45 +0200 Subject: [PATCH 012/196] typo --- docs/concepts/app-anatomy.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/concepts/app-anatomy.md b/docs/concepts/app-anatomy.md index 1cf0334218d2..a546f2472b1e 100644 --- a/docs/concepts/app-anatomy.md +++ b/docs/concepts/app-anatomy.md @@ -51,7 +51,7 @@ Blockchain Node | | Consensus | | | | | | v +-------------------------------+ v ``` -The blockchain full-node presents itself as a binary, generally suffixed by `-d` (e.g. `appd` for `app` or `gaiad` for `gaia`) for "daemon". This binary is built by running a simple `main.go` function placed in `cmd/appd/`. This operation usually happens through the [Makefile](#dependencies-and-makefile). +The blockchain full-node presents itself as a binary, generally suffixed by `-d` for "daemon" (e.g. `appd` for `app` or `gaiad` for `gaia`). This binary is built by running a simple `main.go` function placed in `cmd/appd/`. This operation usually happens through the [Makefile](#dependencies-and-makefile). To learn more about the `main.go` function, [click here](./node.md#main-function). From 0a83404e39e4f967e3f3af63a5082bc8a6483b62 Mon Sep 17 00:00:00 2001 From: gamarin2 Date: Thu, 6 Jun 2019 15:35:19 +0200 Subject: [PATCH 013/196] Apply suggestions from code review Co-Authored-By: Alexander Bezobchuk Co-Authored-By: Federico Kunze <31522760+fedekunze@users.noreply.github.com> Co-Authored-By: Alessio Treglia Co-Authored-By: frog power 4000 --- docs/concepts/app-anatomy.md | 33 +++++++++++++++++---------------- docs/intro/README.md | 4 ++-- 2 files changed, 19 insertions(+), 18 deletions(-) diff --git a/docs/concepts/app-anatomy.md b/docs/concepts/app-anatomy.md index a546f2472b1e..238ef9c1a8d0 100644 --- a/docs/concepts/app-anatomy.md +++ b/docs/concepts/app-anatomy.md @@ -25,6 +25,7 @@ The core parts listed above will generally translate to the following directory ├── app.go ├── x/ │ ├── auth +│ ├── ... │ └── bank ├── go.mod └── Makefile @@ -59,9 +60,9 @@ Once the main binary is built, the node can be started by running the `start` co The `start` command function primarily does three things: -1- Create an instance of the state-machine defined in [`app.go`](#core-application-file) using the `appCreator`. -2- Initialize the state-machine with the latest known state, extracted from the `db` stored in the `~/.appd/data` folder. At this point, the state-machine is at height `appBlockHeight`. -3- Create and start a new Tendermint instance. Among other things, the node will perform a handshake with its peers. It will get the latest `blockHeight` from them, and replay blocks to sync to this height if it is greater than the local `appBlockHeight`. If `appBlockHeight` is `0`, the node is starting from genesis and Tendermint sends an `InitChain` message via the ABCI to the `app`, which triggers the [`InitChainer`](#initchainer). +1. Create an instance of the state-machine defined in [`app.go`](#core-application-file) using the `appCreator`. +2. Initialize the state-machine with the latest known state, extracted from the `db` stored in the `~/.appd/data` folder. At this point, the state-machine is at height `appBlockHeight`. +3. Create and start a new Tendermint instance. Among other things, the node will perform a handshake with its peers. It will get the latest `blockHeight` from them, and replay blocks to sync to this height if it is greater than the local `appBlockHeight`. If `appBlockHeight` is `0`, the node is starting from genesis and Tendermint sends an `InitChain` message via the ABCI to the `app`, which triggers the [`InitChainer`](#initchainer). To learn more about the `start` command, [click here](./node.md#start-command). @@ -75,18 +76,18 @@ The first thing defined in `app.go` is the `type` of the application. It is gene - **A reference to [`baseapp`](./baseapp.md).** The custom application defined in `app.go` is a Golang embedding of the `baseapp` type. `baseapp` implements most of the core logic for the application, including all the [ABCI methods](https://tendermint.com/docs/spec/abci/abci.html#overview) and the routing logic. When a transaction is relayed by Tendermint to the application, the latter uses `baseapp`'s methods to route them to the appropriate module. - **A list of store keys**. The [store](./store.md), which contains the entire state, is implemented as a multistore (i.e. a store of stores) in the Cosmos SDK. Each module uses one or multiple stores in the multistore to persist their part of the state. These stores can be accessed with specific keys that are declared in the `app` type. These keys, along with the `keepers`, are at the heart of the [object-capabilities model](../intro/ocap.md) of the Cosmos SDK. -- **A list of module's `keepers`.** Each module defines an abstraction called `keeper`, which handles reads and writes for this module's store(s). The `keeper`'s methods of one module can be called from other modules (if authorized), which is why they are declared in the application's type. +- **A list of module's `keepers`.** Each module defines an abstraction called `keeper`, which handles reads and writes for this module's store(s). The `keeper`'s methods of one module can be called from other modules (if authorized), which is why they are declared in the application's type and exported as interfaces to other modules so that they are only allowed to access the authorized functions. - **A reference to a `codec`.** The Cosmos SDK gives developers the freedom to choose the encoding framework for their application. The application's `codec` is used to serialize and deserialize data structures in order to store them, as stores can only persist `[]bytes`. The `codec` must be deterministic. Most SDK application use [amino](./amino.md) as their `codec`. You can see an example of application type definition [here](https://github.com/cosmos/sdk-application-tutorial/blob/master/app.go#L27-L43). ### Constructor Function -This function constructs a new application of the type defined above. It is [called](https://github.com/cosmos/cosmos-sdk/blob/master/server/start.go#L117) every time the full-node is started with the `start` command. Here are the main actions performed by this function: +This function constructs a new application of the type defined above. It is called every time the full-node is started with the [`start`](https://github.com/cosmos/cosmos-sdk/blob/master/server/start.go#L117) command. Here are the main actions performed by this function: -- Instanciate a new application with a reference to a `baseapp` instance, a codec and all the appropriate store keys. -- Instantiate all the `keepers` defined in the application's `type`. -- Initialize the application's [`routes`](./baseapp.md#routing) with the [`handlers`](#handler) of each one of the application's modules. When a transaction is relayed to the application by Tendermint via the ABCI, it is routed to the appropriate module's handler using the routes defined here. +- Instantiate a new application with a reference to a `baseapp` instance, a codec and all the appropriate store keys. +- Instantiate all module `keeper`s defined in the application's `type`. +- Initialize the application's [`transaction routes`](./baseapp.md#routing) with the [`handlers`](#handler) of each one of the application's modules. When a transaction is relayed to the application by Tendermint via the ABCI, it is routed to the appropriate module's handler using the routes defined here. - Initialize the application's [query routes](./baseapp.md#query-routing) with the [`queriers`](#querier) of each of the application's modules. When a user query comes in, it is routed to the appropriate module using the query routes defined here. - Set the application's [`initChainer`](#initchainer) and mount the stores. - Return the application. @@ -97,7 +98,7 @@ You can see an example of application constructor [here](https://github.com/cosm ### InitChainer -The `initChainer` is a function that initializes the state of the application from a [genesis file](./genesis.md) (i.e. token balances of genesis accounts). It is called when the application received the `InitChain` message from the Tendermint engine, which happens when the node is started at `appBlockHeight == 0` (i.e. on genesis). The application must set the `initChainer` in its constructor via the [`setInitChainer`](https://godoc.org/github.com/cosmos/cosmos-sdk/baseapp#BaseApp.SetInitChainer) method. +The `initChainer` is a function that initializes the state of the application from a [genesis file](./genesis.md) (i.e. genesis accounts and their balance, modules' genesis state, etc). It is called when the application received the `InitChain` message from the Tendermint engine, which happens when the node is started at `appBlockHeight == 0` (i.e. on genesis). The application must set the `initChainer` in its constructor via the [`setInitChainer`](https://godoc.org/github.com/cosmos/cosmos-sdk/baseapp#BaseApp.SetInitChainer) method. You can see an example of an `initChainer` [here](https://github.com/cosmos/sdk-application-tutorial/blob/master/app.go#L137-L155). @@ -105,9 +106,9 @@ You can see an example of an `initChainer` [here](https://github.com/cosmos/sdk- The `MakeCodec` function is the last important function of the `app.go` file. The goal of this function is to instantiate a codec `cdc` (e.g. [amino](./amino.md)) and calls the `RegisterCodec(*codec.Codec)` method of each module used within the application to register `cdc` to each module. -In turn, the `RegisterCodec` function of each module register the custom interfaces and type structures of their respective module so that they can be marhsaled and unmarshaled. +In turn, the `RegisterCodec` function of each module register the custom interfaces and type structures of their respective module so that they can be marshaled and unmarshaled. -You can see an example of a `MakeCodec` [here](You can see an example of an `initChainer` [here](https://github.com/cosmos/sdk-application-tutorial/blob/master/app.go#L189-L198).). +You can see an example of a `MakeCodec` [here](https://github.com/cosmos/sdk-application-tutorial/blob/master/app.go#L189-L198). ## Modules @@ -119,7 +120,7 @@ To learn more about modules, [click here](./modules.md) A message is a custom type defined by each module that implements the [`message`](https://github.com/cosmos/cosmos-sdk/blob/master/types/tx_msg.go#L8-L29) interface. Each `transaction` contains one or multiple `messages`. When a valid block of transactions is received by the full-node, Tendermint relays each one to the application via [`DeliverTx`](https://tendermint.com/docs/app-dev/abci-spec.html#delivertx). Upon receiving the transaction, the application first unmarshalls it. Then, it extracts the message(s) contained in the application. With the [`Type()`](https://github.com/cosmos/cosmos-sdk/blob/master/types/tx_msg.go#L16) method, `baseapp` is able to know which modules defines the message. It is then able to route it to the appropriate module's [handler](#handler) in order for the message to be processed. If the message is successfully processed, the state is updated. -Module developers create custom message types when they build their own module. The general practice is to prefix the type declaration of the message with `Msg`. For example, the message type `MsgSend` allows users to transfer tokens. It is processed by the handler of the `bank` module, which ultimately calls the `keeper` of the `auth` module in order to update the state. +Module developers create custom message types when they build their own module. The general practice is to prefix the type declaration of the message with `Msg`. For example, the message type `MsgSend` allows users to transfer tokens. It is processed by the handler of the `bank` module, which ultimately calls the `keeper` of the `auth` module in order to update the accounts' state. To learn more about messages, [click here](./tx-msgs.md) @@ -132,7 +133,7 @@ The handler of a module is generally defined in a file called `handler.go` and c - A **switch function** `NewHandler` to route the message to the appropriate handler function. This function returns a `handler` function, and is used in `app.go` to initialize the [application's router](./baseapp.md#routing). See an example of such a switch [here](https://github.com/cosmos/sdk-application-tutorial/blob/master/x/nameservice/handler.go#L10-L22). - **One handler function for each message type defined by the module**. Developers write the message processing logic in these functions. This generally involves doing stateful checks to ensure the message is valid and calling [`keeper`](#keeper)'s methods to update the state. -Handler functions return a result of type [`sdk.Result`](https://github.com/cosmos/cosmos-sdk/blob/master/types/result.go#L14-L37), which informs the application on wether the message was successfully processed and. +Handler functions return a result of type [`sdk.Result`](https://github.com/cosmos/cosmos-sdk/blob/master/types/result.go#L14-L37), which informs the application on whether the message was successfully processed. To learn more about handlers, [click here](./handler.md). @@ -156,10 +157,10 @@ To learn more about `keepers`, [click here](./keeper.md). `Queriers` are very similar to `handlers`, except they serve user queries to the state as opposed to processing transactions. A query is initiated from an [interface](#intefaces) by an end-user who provides a `queryRoute` and some `data`. The query is then routed to the correct application's `querier` by `baseapp`'s [`handleQueryCustom`](https://github.com/cosmos/cosmos-sdk/blob/master/baseapp/baseapp.go#L519-L556) method using `queryRoute`. -The `Querier` of a module are defined in a file called `querier.go`, and consists of: +The `Querier` of a module is defined in a file called `querier.go`, and consists of: - A **switch function** `NewQuerier` to route the query to the appropriate `querier` function. This function returns a `querier` function, and is used in `app.go` to initialize the [application's query router](./baseapp.md#query-routing). See an example of such a switch [here](https://github.com/cosmos/sdk-application-tutorial/blob/master/x/nameservice/querier.go#L21-L34). -- - **One querier function for each data type defined by the module that needs to be queryable**. Developers write the query processing logic in these functions. This generally involves calling [`keeper`](#keeper)'s methods to query the state and marshalling it to JSON. See an example of `querier` functions [here](https://github.com/cosmos/sdk-application-tutorial/blob/master/x/nameservice/querier.go#L37-L101). +- **One querier function for each data type defined by the module that needs to be queryable**. Developers write the query processing logic in these functions. This generally involves calling [`keeper`](#keeper)'s methods to query the state and marshalling it to JSON. See an example of `querier` functions [here](https://github.com/cosmos/sdk-application-tutorial/blob/master/x/nameservice/querier.go#L37-L101). To learn more about `queriers`, [click here](./querier.md). @@ -178,7 +179,7 @@ To learn more about modules CLI, [click here](./module-interfaces.md#cli). #### REST -The module's REST interface lets users generate transactions and query the state through REST calls to the application's [light-client daemon](./node.md#lcd). REST routes are defined in a file `client/rest/rest.go`, which is composed of: +The module's REST interface lets users generate transactions and query the state through REST calls to the application's [light client daemon](./node.md#lcd) (LCD). REST routes are defined in a file `client/rest/rest.go`, which is composed of: - A `RegisterRoutes` function, which registers each route defined in the file. This function is called from the [main application's interface](#application-interfaces) for each module used within the application. The router used in the SDK is [Gorilla's mux](https://github.com/gorilla/mux). - Custom request type definitions for each query or transaction creation function that needs to be exposed. These custom request types build on the [base `request` type](https://github.com/cosmos/cosmos-sdk/blob/master/types/rest/rest.go#L32-L43) of the Cosmos SDK. diff --git a/docs/intro/README.md b/docs/intro/README.md index d172351845cb..a183764355ff 100644 --- a/docs/intro/README.md +++ b/docs/intro/README.md @@ -2,7 +2,7 @@ ## What is the SDK? -The [Cosmos-SDK](https://github.com/cosmos/cosmos-sdk) is an open-source framework for building multi-asset public Proof-of-Stake (PoS) blockchains, like the Cosmos Hub, as well as permissionned Proof-Of-Authority (PoA) blockchains. Blockchains built with the Cosmos SDK are generally referred to as **application-specific blockchains**. +The [Cosmos-SDK](https://github.com/cosmos/cosmos-sdk) is an open-source framework for building multi-asset public Proof-of-Stake (PoS) blockchains, like the Cosmos Hub, as well as permissioned Proof-Of-Authority (PoA) blockchains. Blockchains built with the Cosmos SDK are generally referred to as **application-specific blockchains**. The goal of the Cosmos SDK is to allow developers to easily create custom blockchains from scratch that can natively interoperate with other blockchains. We envision the SDK as the npm-like framework to build secure blockchain applications on top of [Tendermint](https://github.com/tendermint/tendermint). SDK-based blockchains are built out of composable modules, most of which are open source and readily available for any developers to use. Anyone can create a module for the Cosmos-SDK, and integrating already-built modules is as simple as importing them into your blockchain application. What's more, the Cosmos SDK is a capabilities-based system, which allows developer to better reason about the security of interactions between modules. For a deeper look at capabilities, jump to [this section](./ocap.md). @@ -18,7 +18,7 @@ To learn more about application-specific blockchains, [click here](./why-app-spe The Cosmos SDK is the most advanced framework for building custom application-specific blockchains today. Here are a few reasons why you might want to consider building your decentralised application with the Cosmos SDK: -- The default consensus engine available within the SDK is [Tendermint Core](https://github.com/tendermint/tendermint). Tendermint is the most (and only) mature BFT consensus engine in existence. It is widely used accross the industry and is considered the gold standard consensus engine for building Proof-of-Stake systems. +- The default consensus engine available within the SDK is [Tendermint Core](https://github.com/tendermint/tendermint). Tendermint is the most (and only) mature BFT consensus engine in existence. It is widely used across the industry and is considered the gold standard consensus engine for building Proof-of-Stake systems. - The SDK is open source and designed to make it easy to build blockchains out of composable modules. As the ecosystem of open source SDK modules grow, it will become increasingly easier to build complex decentralised platforms with it. - The SDK is inspired by capabilities-based security, and informed by years of wrestling with blockchain state-machines. This makes the Cosmos SDK a very secure environment to build blockchains. - Most importantly, the Cosmos SDK has already been used to build many application-specific blockchains that are already in production. Among others, we can cite [Cosmos Hub](https://hub.cosmos.network), [Iris](https://irisnet.org), [Binance Chain](https://docs.binance.org/), [Terra](https://terra.money/) or [Lino](https://lino.network/). Many more are building on the Cosmos SDK. You can get a view of the ecosystem [here](https://cosmos.network/ecosystem). From 5f883fd71af45977af116e9c369c48a40839e815 Mon Sep 17 00:00:00 2001 From: gamarin Date: Mon, 10 Jun 2019 15:13:41 +0200 Subject: [PATCH 014/196] refactor for new module interface --- docs/.vuepress/config.js | 2 +- docs/concepts/app-anatomy.md | 84 ++++++++++++++++++------- docs/concepts/{amino.md => encoding.md} | 0 docs/concepts/fees-signature.md | 7 +++ docs/concepts/invariants.md | 5 ++ docs/concepts/modules.md | 7 ++- 6 files changed, 81 insertions(+), 24 deletions(-) rename docs/concepts/{amino.md => encoding.md} (100%) create mode 100644 docs/concepts/fees-signature.md create mode 100644 docs/concepts/invariants.md diff --git a/docs/.vuepress/config.js b/docs/.vuepress/config.js index 282c3dec5797..87a2019f0f0e 100644 --- a/docs/.vuepress/config.js +++ b/docs/.vuepress/config.js @@ -32,7 +32,7 @@ module.exports = { "/intro/why-app-specific", "/intro/sdk-app-architecture", "/intro/sdk-design", - "intro/ocap" + "/intro/ocap" ] }, { diff --git a/docs/concepts/app-anatomy.md b/docs/concepts/app-anatomy.md index a546f2472b1e..db223cd61864 100644 --- a/docs/concepts/app-anatomy.md +++ b/docs/concepts/app-anatomy.md @@ -37,7 +37,7 @@ The Daemon, or Full-Node Client, is the core process of an SDK-based blockchain. ``` ^ +-------------------------------+ ^ | | | | - | | State+machine = Application | | + | | State-machine = Application | | | | | | Built with Cosmos SDK | | ^ + | | | +----------- | ABCI | ----------+ v @@ -73,55 +73,93 @@ In general, the core of the state-machine is defined in a file called `app.go`. The first thing defined in `app.go` is the `type` of the application. It is generally comprised of the following parts: -- **A reference to [`baseapp`](./baseapp.md).** The custom application defined in `app.go` is a Golang embedding of the `baseapp` type. `baseapp` implements most of the core logic for the application, including all the [ABCI methods](https://tendermint.com/docs/spec/abci/abci.html#overview) and the routing logic. When a transaction is relayed by Tendermint to the application, the latter uses `baseapp`'s methods to route them to the appropriate module. +- **A reference to [`baseapp`](./baseapp.md).** The custom application defined in `app.go` is an extension of the `baseapp` type. `baseapp` implements most of the core logic for the application, including all the [ABCI methods](https://tendermint.com/docs/spec/abci/abci.html#overview) and the routing logic. When a transaction is relayed by Tendermint to the application, the latter uses `baseapp`'s methods to route them to the appropriate module. - **A list of store keys**. The [store](./store.md), which contains the entire state, is implemented as a multistore (i.e. a store of stores) in the Cosmos SDK. Each module uses one or multiple stores in the multistore to persist their part of the state. These stores can be accessed with specific keys that are declared in the `app` type. These keys, along with the `keepers`, are at the heart of the [object-capabilities model](../intro/ocap.md) of the Cosmos SDK. -- **A list of module's `keepers`.** Each module defines an abstraction called `keeper`, which handles reads and writes for this module's store(s). The `keeper`'s methods of one module can be called from other modules (if authorized), which is why they are declared in the application's type. +- **A list of module's [`keepers`](#keeper).** Each module defines an abstraction called `keeper`, which handles reads and writes for this module's store(s). The `keeper`'s methods of one module can be called from other modules (if authorized), which is why they are declared in the application's type. - **A reference to a `codec`.** The Cosmos SDK gives developers the freedom to choose the encoding framework for their application. The application's `codec` is used to serialize and deserialize data structures in order to store them, as stores can only persist `[]bytes`. The `codec` must be deterministic. Most SDK application use [amino](./amino.md) as their `codec`. +- **A reference to a [module manager](./modules.md#module-manager)**. The module manager is an object that contains a list of the application's module. It facilitates operations related to these modules, like registering [`routes`](./baseapp.md#routing), [query routes](#./baseapp.md#query-routing) or setting the order of execution between modules for various functions like [`InitChainer`](#initchainer), [`BeginBlocker` and `EndBlocker`](#beginblocker-and-endblocker). -You can see an example of application type definition [here](https://github.com/cosmos/sdk-application-tutorial/blob/master/app.go#L27-L43). +You can see an example of application type definition [here](https://github.com/cosmos/gaia/blob/master/app/app.go#L73-L107). ### Constructor Function This function constructs a new application of the type defined above. It is [called](https://github.com/cosmos/cosmos-sdk/blob/master/server/start.go#L117) every time the full-node is started with the `start` command. Here are the main actions performed by this function: -- Instanciate a new application with a reference to a `baseapp` instance, a codec and all the appropriate store keys. -- Instantiate all the `keepers` defined in the application's `type`. -- Initialize the application's [`routes`](./baseapp.md#routing) with the [`handlers`](#handler) of each one of the application's modules. When a transaction is relayed to the application by Tendermint via the ABCI, it is routed to the appropriate module's handler using the routes defined here. -- Initialize the application's [query routes](./baseapp.md#query-routing) with the [`queriers`](#querier) of each of the application's modules. When a user query comes in, it is routed to the appropriate module using the query routes defined here. -- Set the application's [`initChainer`](#initchainer) and mount the stores. +- Instantiate a new application with a reference to a `baseapp` instance, a codec and all the appropriate store keys. +- Instantiate all the [`keeper`s](#keeper) defined in the application's `type` using the `NewKeeper` function of each of the application's modules. Note that `keepers` must be instantiated in the correct order, as the `NewKeeper` of one module might require a reference to another module's `keeper`. +- Instantiate the application's [module manager](./module-manager.md) with the [`AppModule`](#application-module-interface) object of each of the application's modules. +- With the module manager, initialize the application's [`routes`](./baseapp.md#routing) and [query routes](./baseapp.md#query-routing). When a transaction is relayed to the application by Tendermint via the ABCI, it is routed to the appropriate module's [`handler`](#handler) using the routes defined here. Likewise, when a query is received by the application, it is routed to the appropriate module's [`querier`](#querier) using the query routes defined here. +- With the module manager, register the [application's modules' invariants](./invariants.md). Invariants are variables (e.g. total supply of a token) that are evaluated at the end of each block. The process of checking invariants is done via a special module called the [`InvariantsRegistry`](./invariants.md#invariant-registry). The value of the ivnariant should be equal to a predicted value defined in the module. Should the value be different than the predicted one, special logic defined in the invariant registry will be triggered (usually the chain is halted). This is useful to make sure no critical bug goes unoticed and produces long-lasting effects that would be hard to fix. +- With the module manager, set the order of execution between the `InitGenesis`, `BegingBlocker` and `EndBlocker` functions of each of the [application's modules](#application-module-interface). Note that not all modules implement these functions. +- Set the application's [`InitChainer`](#initchainer) (used to initialize the application when it is first started), [`BeginBlocker`, `EndBlocker`](#beginblocker-and-endlbocker) (called at the beginning and the end of every block) and [`anteHandler`](#baseapp.md#antehandler) (used to handle fees and signature verification). +- Mount the stores. - Return the application. Note that this function only creates an instance of the app, while the actual state is either carried over from the `~/.appd/data` folder if the node is restarted, or generated from the genesis file if the node is started for the first time. -You can see an example of application constructor [here](https://github.com/cosmos/sdk-application-tutorial/blob/master/app.go#L46-L128). +You can see an example of application constructor [here](https://github.com/cosmos/gaia/blob/master/app/app.go#L110-L222). ### InitChainer -The `initChainer` is a function that initializes the state of the application from a [genesis file](./genesis.md) (i.e. token balances of genesis accounts). It is called when the application received the `InitChain` message from the Tendermint engine, which happens when the node is started at `appBlockHeight == 0` (i.e. on genesis). The application must set the `initChainer` in its constructor via the [`setInitChainer`](https://godoc.org/github.com/cosmos/cosmos-sdk/baseapp#BaseApp.SetInitChainer) method. +The `InitChainer` is a function that initializes the state of the application from a [genesis file](./genesis.md) (i.e. token balances of genesis accounts). It is called when the application receives the `InitChain` message from the Tendermint engine, which happens when the node is started at `appBlockHeight == 0` (i.e. on genesis). The application must set the `InitChainer` in its constructor via the [`SetInitChainer`](https://godoc.org/github.com/cosmos/cosmos-sdk/baseapp#BaseApp.SetInitChainer) method. -You can see an example of an `initChainer` [here](https://github.com/cosmos/sdk-application-tutorial/blob/master/app.go#L137-L155). +In general, the `InitChainer` is mostly composed of the `InitGenesis` function of each of the application's modules. This is done by calling the `InitGenesis` function of the module manager, which in turn will call the `InitGenesis` function of each of the modules it contains. Note that the order in which the modules' `InitGenesis` functions must be called has to be set in the module manager using the `SetOrderInitGenesis` method. This is done in the [application's constructor](#application-constructor), and the `SetOrderInitGenesis` has to be called before the `SetInitChainer`. + +You can see an example of an `InitChainer` [here](https://github.com/cosmos/gaia/blob/master/app/app.go#L235-L239). + +### BeginBlocker and EndBlocker + +The SDK offers developers the possibility to implement automatic execution of code as part of their application. This is implemented through two function called `BeginBlocker` and `EndBlocker`. They are called when the application receives respectively the `BeginBlock` and `EndBlock` messages from the Tendermint engine, which happens at the beginning and at the end of each block. The application must set the `BeginBlocker` and `EndBlocker` in its constructor via the [`SetBeginBlocker`](https://godoc.org/github.com/cosmos/cosmos-sdk/baseapp#BaseApp.SetBeginBlocker) and [`SetEndBlocker`](https://godoc.org/github.com/cosmos/cosmos-sdk/baseapp#BaseApp.SetEndBlocker) methods. + +In general, the `BeginBlocker` and `EndBlocker` functions are mostly composed of the `BeginBlock` and `EndBlock` functions of each of the application's modules. This is done by calling the `BeginBlock` and `EndBlock` functions of the module manager, which in turn will call the `BeginBLock` and `EndBlock` functions of each of the modules it contains. Note that the order in which the modules' `BegingBlock` and `EndBlock` functions must be called has to be set in the module manager using the `SetOrderBeginBlock` and `SetOrderEndBlock` methods respectively. This is done in the [application's constructor](#application-constructor), and the `SetOrderBeginBlock` and `SetOrderEndBlock` methods have to be called before the `SetBeginBlocker` and `SetEndBlocker` functions. + +As a sidenote, it is important to remember that application-specific blockchains are deterministic. Developers must be careful not to introduce non-determinism in `BeginBlocker` or `EndBlocker`, and must also be careful not to make them too computationally expensive, as [gas](./fees-signature.md/gas) does not constrain the cost of `BeginBlocker` and `EndBlocker` execution. + +You can see an example of `BeginBlocker` and `EndBlocker` functions [here](https://github.com/cosmos/gaia/blob/master/app/app.go#L224-L232). ### Register Codec -The `MakeCodec` function is the last important function of the `app.go` file. The goal of this function is to instantiate a codec `cdc` (e.g. [amino](./amino.md)) and calls the `RegisterCodec(*codec.Codec)` method of each module used within the application to register `cdc` to each module. +The `MakeCodec` function is the last important function of the `app.go` file. The goal of this function is to instantiate a codec `cdc` (e.g. [amino](./amino.md)) initiliaze the codec of the SDK and each of the application's modules using the `RegisterCodec` function. -In turn, the `RegisterCodec` function of each module register the custom interfaces and type structures of their respective module so that they can be marhsaled and unmarshaled. +To register the application's modules, the `MakeCodec` function calls `RegisterCodec` on `ModuleBasics`. `ModuleBasics` is a [basic manager](./modules.md#basic-manager) which lists all of the application's modules. It is instanciated in the `init()` function, and only serves to easily register non-dependant elements of application's modules (such as codec). To learn more about the basic module manager, click [here](./modules.md#basic-manager). -You can see an example of a `MakeCodec` [here](You can see an example of an `initChainer` [here](https://github.com/cosmos/sdk-application-tutorial/blob/master/app.go#L189-L198).). +You can see an example of a `MakeCodec` [here](https://github.com/cosmos/gaia/blob/master/app/app.go#L64-L70) ## Modules -Modules are the heart and soul of an SDK application. They can be considered as state-machines within the state-machine. When a transaction is relayed from the underlying Tendermint engine via the ABCI to the application, it is routed by `baseapp` to the appropriate module in order to be processed. This paradigm enables developers to easily build complex state-machines, as most of the modules they need often already exist. For developers, most of the work involved in building an SDK application revolves around building custom modules required by their application that do not exist, and integrating them with modules that do already exist into one coherent application. In the application directory, the standard practice is to store modules in the `x/` folder. +Modules are the heart and soul of an SDK application. They can be considered as state-machines within the state-machine. When a transaction is relayed from the underlying Tendermint engine via the ABCI to the application, it is routed by `baseapp` to the appropriate module in order to be processed. This paradigm enables developers to easily build complex state-machines, as most of the modules they need often already exist. For developers, most of the work involved in building an SDK application revolves around building custom modules required by their application that do not exist, and integrating them with modules that do already exist into one coherent application. In the application directory, the standard practice is to store modules in the `x/` folder (not to be confused with the SDK's `x/` folder, which contains already-built modules). To learn more about modules, [click here](./modules.md) +### Application Module Interface + +Modules implement two interfaces defined in the Cosmos SDK, [`AppModuleBasic`](https://github.com/cosmos/cosmos-sdk/blob/master/types/module/module.go#L44-L57) and [`AppModule`](https://github.com/cosmos/cosmos-sdk/blob/master/types/module/module.go#L44-L57). The former implements basic non-dependant elements of the module, such as the `codec`, while the latter handles the bulk of the module methods (including methods that require references to other modules' `keeper`s). Both the `AppModule` and `AppModuleBasic` types are defined in a file called `./module.go`. + +`AppModule` exposes a collection of useful methods on the module that facilitates the composition of modules into a coherent application. Important methods include: + +- `Route()` and `QueryRoute()`: These methods the name of the route and querier route for the module, for [messages](#message-types) to be routed to the module's [`handler`](#handler) and queries to be routes to the module's [`querier`](#querier). +- `NewHandler()` and `NewQuerierHandler()`: These methods return a `handler` and `querierHandler` respectively, in order to process a message or a query once they are routed. +- `BeginBlock()`, `EndBlock()` and `InitGenesis()`: These methods are executed respectively at the beginning of each block, at the end of each block and at the start of the chain. They implement special logic the module requires to be triggered during those events. For example, the `EndBlock` function is frequently used by modules where voting occurs to tally the result of the votes. +- `RegisterInvariants()`: This method registers the [invariants](./invariants.md) for the module. Invariants are checked at the end of every block to make sure no unpredicted behaviour is occuring. + +`AppModule`'s methods are called from the `module manager`(./modules.md#module-manager), which manages the application's collection of modules. + +To learn more about the application module interface, [click here](./modules.md#application-module-interface). + ### Message Types -A message is a custom type defined by each module that implements the [`message`](https://github.com/cosmos/cosmos-sdk/blob/master/types/tx_msg.go#L8-L29) interface. Each `transaction` contains one or multiple `messages`. When a valid block of transactions is received by the full-node, Tendermint relays each one to the application via [`DeliverTx`](https://tendermint.com/docs/app-dev/abci-spec.html#delivertx). Upon receiving the transaction, the application first unmarshalls it. Then, it extracts the message(s) contained in the application. With the [`Type()`](https://github.com/cosmos/cosmos-sdk/blob/master/types/tx_msg.go#L16) method, `baseapp` is able to know which modules defines the message. It is then able to route it to the appropriate module's [handler](#handler) in order for the message to be processed. If the message is successfully processed, the state is updated. +A message is a custom type defined by each module that implements the [`message`](https://github.com/cosmos/cosmos-sdk/blob/master/types/tx_msg.go#L8-L29) interface. Each `transaction` contains one or multiple `messages`. When a valid block of transactions is received by the full-node, Tendermint relays each one to the application via [`DeliverTx`](https://tendermint.com/docs/app-dev/abci-spec.html#delivertx). Then, the application handles the transaction: -Module developers create custom message types when they build their own module. The general practice is to prefix the type declaration of the message with `Msg`. For example, the message type `MsgSend` allows users to transfer tokens. It is processed by the handler of the `bank` module, which ultimately calls the `keeper` of the `auth` module in order to update the state. +1. Upon receiving the transaction, the application first unmarshalls it from `[]bytes`. +2. Then, it verifies a few things about the transaction like [fee payment and signatures](#fees-signature.md) before extracting the message(s) contained in the transaction. +3. With the [`Type()`](https://github.com/cosmos/cosmos-sdk/blob/master/types/tx_msg.go#L16) method, `baseapp` is able to know which modules defines the message. It is then able to route it to the appropriate module's [handler](#handler) in order for the message to be processed. +4. If the message is successfully processed, the state is updated. -To learn more about messages, [click here](./tx-msgs.md) +For a more detailed look at a transaction lifecycle, click [here](./tx-lifecycle.md). + +Module developers create custom message types when they build their own module. The general practice is to prefix the type declaration of the message with `Msg`. For example, the message type [`MsgSend`](https://github.com/cosmos/cosmos-sdk/blob/master/x/bank/types/msgs.go#L10-L15) allows users to transfer tokens. It is processed by the handler of the `bank` module, which ultimately calls the `keeper` of the `auth` module in order to update the state. + +To learn more about messages, [click here](./tx-msgs.md). ### Handler @@ -129,7 +167,7 @@ The `handler` refers to the part of the module responsible for processing the me The handler of a module is generally defined in a file called `handler.go` and consists of: -- A **switch function** `NewHandler` to route the message to the appropriate handler function. This function returns a `handler` function, and is used in `app.go` to initialize the [application's router](./baseapp.md#routing). See an example of such a switch [here](https://github.com/cosmos/sdk-application-tutorial/blob/master/x/nameservice/handler.go#L10-L22). +- A **switch function** `NewHandler` to route the message to the appropriate handler function. This function returns a `handler` function, and is registered in the [`AppModule`](#application-module-interface) to be used in the application's module manager to initialize the [application's router](./baseapp.md#routing). See an example of such a switch [here](https://github.com/cosmos/sdk-application-tutorial/blob/master/x/nameservice/handler.go#L10-L22). - **One handler function for each message type defined by the module**. Developers write the message processing logic in these functions. This generally involves doing stateful checks to ensure the message is valid and calling [`keeper`](#keeper)'s methods to update the state. Handler functions return a result of type [`sdk.Result`](https://github.com/cosmos/cosmos-sdk/blob/master/types/result.go#L14-L37), which informs the application on wether the message was successfully processed and. @@ -148,6 +186,8 @@ The `keeper` type definition generally consists of: - Reference to **other module's `keepers`**. Only needed if the `keeper` needs to access other module's store(s) (either to read or write from them). - A reference to the application's **codec**. The `keeper` needs it to marshal structs before storing them, or to unmarshal them when it retrieves them, because stores only accept `[]bytes` as value. +Along with the type definition, the next important component of the `keeper.go` file is the `keeper`'s constructor function, `NewKeeper`. This function instantiates a new `keeper` of the type defined above, with a `codec`, store `keys` and potentially references to other modules' `keeper`s as parameters. The `NewKeeper` function is called from the [application's constructor](#constructor-function). + The rest of the file defines the `keeper`'s methods, primarily getters and setters. You can check an example of a `keeper` implementation [here](https://github.com/cosmos/sdk-application-tutorial/blob/master/x/nameservice/keeper.go). To learn more about `keepers`, [click here](./keeper.md). @@ -158,7 +198,7 @@ To learn more about `keepers`, [click here](./keeper.md). The `Querier` of a module are defined in a file called `querier.go`, and consists of: -- A **switch function** `NewQuerier` to route the query to the appropriate `querier` function. This function returns a `querier` function, and is used in `app.go` to initialize the [application's query router](./baseapp.md#query-routing). See an example of such a switch [here](https://github.com/cosmos/sdk-application-tutorial/blob/master/x/nameservice/querier.go#L21-L34). +- A **switch function** `NewQuerier` to route the query to the appropriate `querier` function. This function returns a `querier` function, and is is registered in the [`AppModule`](#application-module-interface) to be used in the application's module manager to initialize the [application's query router](./baseapp.md#query-routing). See an example of such a switch [here](https://github.com/cosmos/sdk-application-tutorial/blob/master/x/nameservice/querier.go#L21-L34). - - **One querier function for each data type defined by the module that needs to be queryable**. Developers write the query processing logic in these functions. This generally involves calling [`keeper`](#keeper)'s methods to query the state and marshalling it to JSON. See an example of `querier` functions [here](https://github.com/cosmos/sdk-application-tutorial/blob/master/x/nameservice/querier.go#L37-L101). To learn more about `queriers`, [click here](./querier.md). @@ -169,7 +209,7 @@ Each module defines command-line commands and REST routes to be exposed to end-u #### CLI -Generally, the commands related to a module are defined in a folder called `client/cli` in the module's folder. The CLI divides commands in two category, transactions and queries, defined in `client/cli/tx.go` and `client/cli/query.go` respectively. Both build commands on top of the [Cobra Library](https://github.com/spf13/cobra): +Generally, the commands related to a module are defined in a folder called `client/cli` in the module's folder. The CLI divides commands in two category, transactions and queries, defined in `client/cli/tx.go` and `client/cli/query.go` respectively. Both commands are built on top of the [Cobra Library](https://github.com/spf13/cobra): - Transactions commands let users generate new transactions so that they can be included in a block and eventually update the state. One command should be created for each [message type](#message-types) defined in the module. The command calls the constructor of the message with the parameters provided by the end-user, and wraps it into a transaction. The SDK handles signing and the addition of other transaction metadata. See examples of transactions commands [here](https://github.com/cosmos/sdk-application-tutorial/blob/master/x/nameservice/client/cli/tx.go). - Queries let users query the subset of the state defined by the module. Query commands forward queries to the [application's query router](./baseapp.md#query-routing), which routes them to the appropriate [querier](#querier) the `queryRoute` parameter supplied. See examples of query commands [here](https://github.com/cosmos/sdk-application-tutorial/blob/master/x/nameservice/client/cli/query.go). diff --git a/docs/concepts/amino.md b/docs/concepts/encoding.md similarity index 100% rename from docs/concepts/amino.md rename to docs/concepts/encoding.md diff --git a/docs/concepts/fees-signature.md b/docs/concepts/fees-signature.md new file mode 100644 index 000000000000..36982a97b5d8 --- /dev/null +++ b/docs/concepts/fees-signature.md @@ -0,0 +1,7 @@ +# Fees and Signatures + +## Signatures + +## Fees + +## Gas \ No newline at end of file diff --git a/docs/concepts/invariants.md b/docs/concepts/invariants.md new file mode 100644 index 000000000000..18cd9ad6224f --- /dev/null +++ b/docs/concepts/invariants.md @@ -0,0 +1,5 @@ +# Invariants + +## What is an invariant + +## Invariant Registry \ No newline at end of file diff --git a/docs/concepts/modules.md b/docs/concepts/modules.md index cfd71f817963..5c65c4d89f92 100644 --- a/docs/concepts/modules.md +++ b/docs/concepts/modules.md @@ -1,3 +1,8 @@ # SDK Modules -Todo: Intro concept docs on modules \ No newline at end of file +Todo: Intro concept docs on modules + +## Application Module Interface + +## Module Manager + From dde15aefbe641586b3502c58714636553648d7d5 Mon Sep 17 00:00:00 2001 From: gamarin Date: Tue, 11 Jun 2019 16:09:21 +0200 Subject: [PATCH 015/196] karoly review --- docs/concepts/app-anatomy.md | 7 +++++-- docs/concepts/{module-interfaces => module-interfaces.md} | 0 2 files changed, 5 insertions(+), 2 deletions(-) rename docs/concepts/{module-interfaces => module-interfaces.md} (100%) diff --git a/docs/concepts/app-anatomy.md b/docs/concepts/app-anatomy.md index 20761912d1e4..54803a1b6eaa 100644 --- a/docs/concepts/app-anatomy.md +++ b/docs/concepts/app-anatomy.md @@ -77,7 +77,7 @@ The first thing defined in `app.go` is the `type` of the application. It is gene - **A reference to [`baseapp`](./baseapp.md).** The custom application defined in `app.go` is an extension of the `baseapp` type. `baseapp` implements most of the core logic for the application, including all the [ABCI methods](https://tendermint.com/docs/spec/abci/abci.html#overview) and the routing logic. When a transaction is relayed by Tendermint to the application, the latter uses `baseapp`'s methods to route them to the appropriate module. - **A list of store keys**. The [store](./store.md), which contains the entire state, is implemented as a multistore (i.e. a store of stores) in the Cosmos SDK. Each module uses one or multiple stores in the multistore to persist their part of the state. These stores can be accessed with specific keys that are declared in the `app` type. These keys, along with the `keepers`, are at the heart of the [object-capabilities model](../intro/ocap.md) of the Cosmos SDK. - **A list of module's `keepers`.** Each module defines an abstraction called `keeper`, which handles reads and writes for this module's store(s). The `keeper`'s methods of one module can be called from other modules (if authorized), which is why they are declared in the application's type and exported as interfaces to other modules so that they are only allowed to access the authorized functions. -- **A reference to a `codec`.** The Cosmos SDK gives developers the freedom to choose the encoding framework for their application. The application's `codec` is used to serialize and deserialize data structures in order to store them, as stores can only persist `[]bytes`. The `codec` must be deterministic. Most SDK application use [amino](./amino.md) as their `codec`. +- **A reference to a `codec`.** The Cosmos SDK gives developers the freedom to choose the encoding framework for their application. The application's `codec` is used to serialize and deserialize data structures in order to store them, as stores can only persist `[]bytes`. The `codec` must be deterministic. The default codec is [amino](./amino.md). - **A reference to a [module manager](./modules.md#module-manager)**. The module manager is an object that contains a list of the application's module. It facilitates operations related to these modules, like registering [`routes`](./baseapp.md#routing), [query routes](#./baseapp.md#query-routing) or setting the order of execution between modules for various functions like [`InitChainer`](#initchainer), [`BeginBlocker` and `EndBlocker`](#beginblocker-and-endblocker). You can see an example of application type definition [here](https://github.com/cosmos/gaia/blob/master/app/app.go#L73-L107). @@ -92,7 +92,10 @@ This function constructs a new application of the type defined above. It is call - With the module manager, initialize the application's [`routes`](./baseapp.md#routing) and [query routes](./baseapp.md#query-routing). When a transaction is relayed to the application by Tendermint via the ABCI, it is routed to the appropriate module's [`handler`](#handler) using the routes defined here. Likewise, when a query is received by the application, it is routed to the appropriate module's [`querier`](#querier) using the query routes defined here. - With the module manager, register the [application's modules' invariants](./invariants.md). Invariants are variables (e.g. total supply of a token) that are evaluated at the end of each block. The process of checking invariants is done via a special module called the [`InvariantsRegistry`](./invariants.md#invariant-registry). The value of the ivnariant should be equal to a predicted value defined in the module. Should the value be different than the predicted one, special logic defined in the invariant registry will be triggered (usually the chain is halted). This is useful to make sure no critical bug goes unoticed and produces long-lasting effects that would be hard to fix. - With the module manager, set the order of execution between the `InitGenesis`, `BegingBlocker` and `EndBlocker` functions of each of the [application's modules](#application-module-interface). Note that not all modules implement these functions. -- Set the application's [`InitChainer`](#initchainer) (used to initialize the application when it is first started), [`BeginBlocker`, `EndBlocker`](#beginblocker-and-endlbocker) (called at the beginning and the end of every block) and [`anteHandler`](#baseapp.md#antehandler) (used to handle fees and signature verification). +- Set the remainer of application's parameters: + + [`InitChainer`](#initchainer): used to initialize the application when it is first started. + + [`BeginBlocker`, `EndBlocker`](#beginblocker-and-endlbocker): called at the beginning and the end of every block). + + [`anteHandler`](#baseapp.md#antehandler): used to handle fees and signature verification. - Mount the stores. - Return the application. diff --git a/docs/concepts/module-interfaces b/docs/concepts/module-interfaces.md similarity index 100% rename from docs/concepts/module-interfaces rename to docs/concepts/module-interfaces.md From da2514f933532ec162d598baa5cb958f88c7d13a Mon Sep 17 00:00:00 2001 From: gamarin2 Date: Tue, 11 Jun 2019 16:10:24 +0200 Subject: [PATCH 016/196] Apply suggestions from code review Co-Authored-By: Karoly Albert Szabo Co-Authored-By: Federico Kunze <31522760+fedekunze@users.noreply.github.com> --- docs/concepts/app-anatomy.md | 2 +- docs/concepts/encoding.md | 4 ++-- docs/concepts/node.md | 4 ++-- docs/intro/README.md | 2 +- 4 files changed, 6 insertions(+), 6 deletions(-) diff --git a/docs/concepts/app-anatomy.md b/docs/concepts/app-anatomy.md index 54803a1b6eaa..3c6dca17cb9e 100644 --- a/docs/concepts/app-anatomy.md +++ b/docs/concepts/app-anatomy.md @@ -90,7 +90,7 @@ This function constructs a new application of the type defined above. It is call - Instantiate all the [`keeper`s](#keeper) defined in the application's `type` using the `NewKeeper` function of each of the application's modules. Note that `keepers` must be instantiated in the correct order, as the `NewKeeper` of one module might require a reference to another module's `keeper`. - Instantiate the application's [module manager](./module-manager.md) with the [`AppModule`](#application-module-interface) object of each of the application's modules. - With the module manager, initialize the application's [`routes`](./baseapp.md#routing) and [query routes](./baseapp.md#query-routing). When a transaction is relayed to the application by Tendermint via the ABCI, it is routed to the appropriate module's [`handler`](#handler) using the routes defined here. Likewise, when a query is received by the application, it is routed to the appropriate module's [`querier`](#querier) using the query routes defined here. -- With the module manager, register the [application's modules' invariants](./invariants.md). Invariants are variables (e.g. total supply of a token) that are evaluated at the end of each block. The process of checking invariants is done via a special module called the [`InvariantsRegistry`](./invariants.md#invariant-registry). The value of the ivnariant should be equal to a predicted value defined in the module. Should the value be different than the predicted one, special logic defined in the invariant registry will be triggered (usually the chain is halted). This is useful to make sure no critical bug goes unoticed and produces long-lasting effects that would be hard to fix. +- With the module manager, register the [application's modules' invariants](./invariants.md). Invariants are variables (e.g. total supply of a token) that are evaluated at the end of each block. The process of checking invariants is done via a special module called the [`InvariantsRegistry`](./invariants.md#invariant-registry). The value of the invariant should be equal to a predicted value defined in the module. Should the value be different than the predicted one, special logic defined in the invariant registry will be triggered (usually the chain is halted). This is useful to make sure no critical bug goes unnoticed and produces long-lasting effects that would be hard to fix. - With the module manager, set the order of execution between the `InitGenesis`, `BegingBlocker` and `EndBlocker` functions of each of the [application's modules](#application-module-interface). Note that not all modules implement these functions. - Set the remainer of application's parameters: + [`InitChainer`](#initchainer): used to initialize the application when it is first started. diff --git a/docs/concepts/encoding.md b/docs/concepts/encoding.md index 8113f63e9630..faa2f6d5fc05 100644 --- a/docs/concepts/encoding.md +++ b/docs/concepts/encoding.md @@ -1,3 +1,3 @@ -# Amnio Encoding +# Amino Encoding -TODO \ No newline at end of file +TODO diff --git a/docs/concepts/node.md b/docs/concepts/node.md index ec860bbdf18a..85c6152542ad 100644 --- a/docs/concepts/node.md +++ b/docs/concepts/node.md @@ -2,7 +2,7 @@ ## Pre-Requisite Reading -## main function +## `main` function TODO @@ -10,4 +10,4 @@ TODO TODO -## LCD \ No newline at end of file +## Light-Client Daemon (LCD) diff --git a/docs/intro/README.md b/docs/intro/README.md index a183764355ff..8d2dbe0903c6 100644 --- a/docs/intro/README.md +++ b/docs/intro/README.md @@ -4,7 +4,7 @@ The [Cosmos-SDK](https://github.com/cosmos/cosmos-sdk) is an open-source framework for building multi-asset public Proof-of-Stake (PoS) blockchains, like the Cosmos Hub, as well as permissioned Proof-Of-Authority (PoA) blockchains. Blockchains built with the Cosmos SDK are generally referred to as **application-specific blockchains**. -The goal of the Cosmos SDK is to allow developers to easily create custom blockchains from scratch that can natively interoperate with other blockchains. We envision the SDK as the npm-like framework to build secure blockchain applications on top of [Tendermint](https://github.com/tendermint/tendermint). SDK-based blockchains are built out of composable modules, most of which are open source and readily available for any developers to use. Anyone can create a module for the Cosmos-SDK, and integrating already-built modules is as simple as importing them into your blockchain application. What's more, the Cosmos SDK is a capabilities-based system, which allows developer to better reason about the security of interactions between modules. For a deeper look at capabilities, jump to [this section](./ocap.md). +The goal of the Cosmos SDK is to allow developers to easily create custom blockchains from scratch that can natively interoperate with other blockchains. We envision the SDK as the npm-like framework to build secure blockchain applications on top of [Tendermint](https://github.com/tendermint/tendermint). SDK-based blockchains are built out of composable modules, most of which are open source and readily available for any developers to use. Anyone can create a module for the Cosmos-SDK, and integrating already-built modules is as simple as importing them into your blockchain application. What's more, the Cosmos SDK is a capabilities-based system, which allows developers to better reason about the security of interactions between modules. For a deeper look at capabilities, jump to [this section](./ocap.md). ## What are Application-Specific Blockchains? From 56c3f5b0785276026a22cbe10f9c6d4791bcd1d7 Mon Sep 17 00:00:00 2001 From: gamarin Date: Tue, 11 Jun 2019 17:50:49 +0200 Subject: [PATCH 017/196] encoding --- docs/concepts/encoding.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/docs/concepts/encoding.md b/docs/concepts/encoding.md index faa2f6d5fc05..1dcfba3b2313 100644 --- a/docs/concepts/encoding.md +++ b/docs/concepts/encoding.md @@ -1,3 +1,3 @@ -# Amino Encoding +# Encoding -TODO +TODO \ No newline at end of file From 4f7c6b4513d17d17eec8544309c18802fdfbff5c Mon Sep 17 00:00:00 2001 From: gamarin Date: Mon, 17 Jun 2019 16:55:53 +0200 Subject: [PATCH 018/196] working on baseapp doc --- docs/concepts/baseapp.md | 151 +++++++++++++---------------------- docs/concepts/baseapp_old.md | 128 +++++++++++++++++++++++++++++ docs/concepts/store.md | 8 ++ docs/concepts/tx-msgs.md | 5 ++ 4 files changed, 197 insertions(+), 95 deletions(-) create mode 100644 docs/concepts/baseapp_old.md create mode 100644 docs/concepts/store.md create mode 100644 docs/concepts/tx-msgs.md diff --git a/docs/concepts/baseapp.md b/docs/concepts/baseapp.md index c4f71f33f696..855b03cf1b55 100644 --- a/docs/concepts/baseapp.md +++ b/docs/concepts/baseapp.md @@ -1,128 +1,89 @@ # BaseApp -The BaseApp defines the foundational implementation for a basic ABCI application -so that your Cosmos-SDK application can communicate with an underlying -Tendermint node. - -The BaseApp is composed of many internal components. Some of the most important -include the `CommitMultiStore` and its internal state. The internal state is -essentially two sub-states, both of which are used for transaction execution -during different phases, `CheckTx` and `DeliverTx` respectively. During block -commitment, only the `DeliverTx` is persisted. - -The BaseApp requires stores to be mounted via capabilities keys - handlers can -only access stores they're given the key to. The `baseApp` ensures all stores are -properly loaded, cached, and committed. One mounted store is considered the -"main" (`baseApp.MainStoreKey`) - it holds the latest block header, from which we can find and load the -most recent state. - -The BaseApp distinguishes between two handler types - the `AnteHandler` and the -`MsgHandler`. The former is a global validity check (checking nonces, sigs and -sufficient balances to pay fees, e.g. things that apply to all transaction from -all modules), the later is the full state transition function. - -During `CheckTx` the state transition function is only applied to the `checkTxState` -and should return before any expensive state transitions are run -(this is up to each developer). It also needs to return the estimated gas cost. - -During `DeliverTx` the state transition function is applied to the blockchain -state and the transactions need to be fully executed. - -The BaseApp is responsible for managing the context passed into handlers - -it makes the block header available and provides the right stores for `CheckTx` -and `DeliverTx`. BaseApp is completely agnostic to serialization formats. +## Pre-requisite Reading -## Routing +- [Anatomy of an SDK application](./app-anatomy.md) +- [Lifecycle of an SDK transaction](./tx-lifecycle.md) -TODO +## Synopsis -## Transaction Life Cycle +This document describes `baseapp`, the abstraction that implements most of the common functionalities of an SDK application. -During the execution of a transaction, it may pass through both `CheckTx` and -`DeliverTx` as defined in the ABCI specification. `CheckTx` is executed by the -proposing validator and is used for the Tendermint mempool for all full nodes. +- [Introduction](#introduction) +- [Type Definition](#type-definition) +- [States and Modes](#states-and-modes) +- [Routing](#routing) +- [ABCI](#abci) +- [CheckTx](#abci-checktx) +- [DeliverTx](#abci-delivertx) +- [Commit](#abbci-commit) +- [Other ABCI Message](#other-abci-message) + + [Info](#info) + + [SetOption](#setoption) + + [Query](#query) + + [InitChain](#initchain) + + [BeginBlock](#beginblock) + + [EndBlock](#endblock) +- [Gas](#gas) -Both `CheckTx` and `DeliverTx` execute the application's AnteHandler (if -defined), where the AnteHandler is responsible for pre-message validation -checks such as account and signature validation, fee deduction and collection, -and incrementing sequence numbers. -### CheckTx +## Introduction -During the execution of `CheckTx`, only the AnteHandler is executed. +`baseapp` is an abstraction that implements the core of an SDK application, namely: -State transitions due to the AnteHandler are persisted between subsequent calls -of `CheckTx` in the check-tx state, unless the AnteHandler fails and aborts. +- The [Application-Blockchain Interface](#abci), for the state-machine to communicate with the underlying consensus engine (e.g. Tendermint). +- A [Router](#routing), to route [messages](./tx-msgs.md) and [queries](./querier.md) to the appropriate [module](./modules.md). +- Different [states and modes](#states-and-modes), as the state-machine can be in different modes depending on the ABCI message it processes. -### DeliverTx +The goal of `baseapp` is to provide a boilerplate SDK application that developers can easily extend to build their own custom application. Usually, developers will create a custom type for their application, like so: -During the execution of `DeliverTx`, the AnteHandler and Handler is executed. +```go +type app struct { + *bam.BaseApp // reference to baseapp + cdc *codec.Codec -The transaction execution during `DeliverTx` operates in a similar fashion to -`CheckTx`. However, state transitions that occur during the AnteHandler are -persisted even when the following Handler processing logic fails. + // list of application store keys -It is possible that a malicious proposer may include a transaction in a block -that fails the AnteHandler. In this case, all state transitions for the -offending transaction are discarded. + // list of application keepers + // module manager +} +``` -## Other ABCI Messages +Extending the application with `baseapp` gives the former access to all of `baseapp`'s methods. This allows developers to compose their custom application with the modules they want, while not having to concern themselves with the hard work of implementing the ABCI, the routing and state management logic. -Besides `CheckTx` and `DeliverTx`, BaseApp handles the following ABCI messages. +## Type Definition -### Info -TODO complete description +The [`baseapp` type](https://github.com/cosmos/cosmos-sdk/blob/master/baseapp/baseapp.go#L45-L91) holds many important parameters for any Cosmos SDK based application. Let us go through the most important components: -### SetOption -TODO complete description +- A [`CommitMultiStore`](./store.md#commit-multi-store). This is the main store of the application, which holds the canonical state that is committed at the [end of each block](#endblock). This store is **not** cached, meaning it is not used to update the application's intermediate (un-committed) states. The `CommitMultiStore` is a multi-store, meaning a store of stores. Each module of the application uses one or multiple `KVStores` in the multi-store to persist their subset of the state. +- A [database](./store.md#database) `db`, which is used by the `CommitMultiStore` to handle data storage. +- -### Query -TODO complete description +## States and Modes -### InitChain -TODO complete description - -During chain initialization InitChain runs the initialization logic directly on -the CommitMultiStore. The deliver and check states are initialized with the -ChainID. - -Note that we do not commit after InitChain, so BeginBlock for block 1 starts -from the deliver state as initialized by InitChain. - -### BeginBlock -TODO complete description +## Routing -### EndBlock -TODO complete description +## ABCI -### Commit -TODO complete description +## ABCI - CheckTx +## ABCI - DeliverTx -## Gas Management +## ABCI - Commit -### Gas: InitChain +## Other ABCI Messages -During InitChain, the block gas meter is initialized with an infinite amount of -gas to run any genesis transactions. +### Info -Additionally, the InitChain request message includes ConsensusParams as -declared in the genesis.json file. +### SetOption -### Gas: BeginBlock +### Query -The block gas meter is reset during BeginBlock for the deliver state. If no -maximum block gas is set within baseapp then an infinite gas meter is set, -otherwise a gas meter with `ConsensusParam.BlockSize.MaxGas` is initialized. +### InitChain -### Gas: DeliverTx +### BeginBlock -Before the transaction logic is run, the `BlockGasMeter` is first checked to -see if any gas remains. If no gas remains, then `DeliverTx` immediately returns -an error. +### EndBlock -After the transaction has been processed, the used gas (up to the transaction -gas limit) is deducted from the BlockGasMeter. If the remaining gas exceeds the -meter's limits, then DeliverTx returns an error and the transaction is not -committed. +## Gas \ No newline at end of file diff --git a/docs/concepts/baseapp_old.md b/docs/concepts/baseapp_old.md new file mode 100644 index 000000000000..c4f71f33f696 --- /dev/null +++ b/docs/concepts/baseapp_old.md @@ -0,0 +1,128 @@ +# BaseApp + +The BaseApp defines the foundational implementation for a basic ABCI application +so that your Cosmos-SDK application can communicate with an underlying +Tendermint node. + +The BaseApp is composed of many internal components. Some of the most important +include the `CommitMultiStore` and its internal state. The internal state is +essentially two sub-states, both of which are used for transaction execution +during different phases, `CheckTx` and `DeliverTx` respectively. During block +commitment, only the `DeliverTx` is persisted. + +The BaseApp requires stores to be mounted via capabilities keys - handlers can +only access stores they're given the key to. The `baseApp` ensures all stores are +properly loaded, cached, and committed. One mounted store is considered the +"main" (`baseApp.MainStoreKey`) - it holds the latest block header, from which we can find and load the +most recent state. + +The BaseApp distinguishes between two handler types - the `AnteHandler` and the +`MsgHandler`. The former is a global validity check (checking nonces, sigs and +sufficient balances to pay fees, e.g. things that apply to all transaction from +all modules), the later is the full state transition function. + +During `CheckTx` the state transition function is only applied to the `checkTxState` +and should return before any expensive state transitions are run +(this is up to each developer). It also needs to return the estimated gas cost. + +During `DeliverTx` the state transition function is applied to the blockchain +state and the transactions need to be fully executed. + +The BaseApp is responsible for managing the context passed into handlers - +it makes the block header available and provides the right stores for `CheckTx` +and `DeliverTx`. BaseApp is completely agnostic to serialization formats. + +## Routing + +TODO + +## Transaction Life Cycle + +During the execution of a transaction, it may pass through both `CheckTx` and +`DeliverTx` as defined in the ABCI specification. `CheckTx` is executed by the +proposing validator and is used for the Tendermint mempool for all full nodes. + +Both `CheckTx` and `DeliverTx` execute the application's AnteHandler (if +defined), where the AnteHandler is responsible for pre-message validation +checks such as account and signature validation, fee deduction and collection, +and incrementing sequence numbers. + +### CheckTx + +During the execution of `CheckTx`, only the AnteHandler is executed. + +State transitions due to the AnteHandler are persisted between subsequent calls +of `CheckTx` in the check-tx state, unless the AnteHandler fails and aborts. + +### DeliverTx + +During the execution of `DeliverTx`, the AnteHandler and Handler is executed. + +The transaction execution during `DeliverTx` operates in a similar fashion to +`CheckTx`. However, state transitions that occur during the AnteHandler are +persisted even when the following Handler processing logic fails. + +It is possible that a malicious proposer may include a transaction in a block +that fails the AnteHandler. In this case, all state transitions for the +offending transaction are discarded. + + +## Other ABCI Messages + +Besides `CheckTx` and `DeliverTx`, BaseApp handles the following ABCI messages. + +### Info +TODO complete description + +### SetOption +TODO complete description + +### Query +TODO complete description + +### InitChain +TODO complete description + +During chain initialization InitChain runs the initialization logic directly on +the CommitMultiStore. The deliver and check states are initialized with the +ChainID. + +Note that we do not commit after InitChain, so BeginBlock for block 1 starts +from the deliver state as initialized by InitChain. + +### BeginBlock +TODO complete description + +### EndBlock +TODO complete description + +### Commit +TODO complete description + + +## Gas Management + +### Gas: InitChain + +During InitChain, the block gas meter is initialized with an infinite amount of +gas to run any genesis transactions. + +Additionally, the InitChain request message includes ConsensusParams as +declared in the genesis.json file. + +### Gas: BeginBlock + +The block gas meter is reset during BeginBlock for the deliver state. If no +maximum block gas is set within baseapp then an infinite gas meter is set, +otherwise a gas meter with `ConsensusParam.BlockSize.MaxGas` is initialized. + +### Gas: DeliverTx + +Before the transaction logic is run, the `BlockGasMeter` is first checked to +see if any gas remains. If no gas remains, then `DeliverTx` immediately returns +an error. + +After the transaction has been processed, the used gas (up to the transaction +gas limit) is deducted from the BlockGasMeter. If the remaining gas exceeds the +meter's limits, then DeliverTx returns an error and the transaction is not +committed. diff --git a/docs/concepts/store.md b/docs/concepts/store.md new file mode 100644 index 000000000000..067eea3b79bd --- /dev/null +++ b/docs/concepts/store.md @@ -0,0 +1,8 @@ +# Store + +## Commit Multi Store + +## Database + +## Main Store + diff --git a/docs/concepts/tx-msgs.md b/docs/concepts/tx-msgs.md new file mode 100644 index 000000000000..35e8aeb39e42 --- /dev/null +++ b/docs/concepts/tx-msgs.md @@ -0,0 +1,5 @@ +# Transactions and Messages + +## Transactions + +## Messages \ No newline at end of file From e37310fcdbb003b65255bf443c481ddbb03de945 Mon Sep 17 00:00:00 2001 From: gamarin Date: Thu, 27 Jun 2019 11:47:33 +0200 Subject: [PATCH 019/196] baseapp work --- docs/concepts/accounts-fees.md | 11 +++++ docs/concepts/app-anatomy.md | 4 +- docs/concepts/baseapp.md | 85 ++++++++++++++++++++++++++++----- docs/concepts/fees-signature.md | 7 --- 4 files changed, 85 insertions(+), 22 deletions(-) create mode 100644 docs/concepts/accounts-fees.md delete mode 100644 docs/concepts/fees-signature.md diff --git a/docs/concepts/accounts-fees.md b/docs/concepts/accounts-fees.md new file mode 100644 index 000000000000..9f03e0eb033d --- /dev/null +++ b/docs/concepts/accounts-fees.md @@ -0,0 +1,11 @@ +# Accounts, Fees and Signatures + +## Accounts + +## AnteHandler + +## Signatures + +## Fees + +## Gas \ No newline at end of file diff --git a/docs/concepts/app-anatomy.md b/docs/concepts/app-anatomy.md index 3c6dca17cb9e..8fb120d86f5c 100644 --- a/docs/concepts/app-anatomy.md +++ b/docs/concepts/app-anatomy.md @@ -117,7 +117,7 @@ The SDK offers developers the possibility to implement automatic execution of co In general, the `BeginBlocker` and `EndBlocker` functions are mostly composed of the `BeginBlock` and `EndBlock` functions of each of the application's modules. This is done by calling the `BeginBlock` and `EndBlock` functions of the module manager, which in turn will call the `BeginBLock` and `EndBlock` functions of each of the modules it contains. Note that the order in which the modules' `BegingBlock` and `EndBlock` functions must be called has to be set in the module manager using the `SetOrderBeginBlock` and `SetOrderEndBlock` methods respectively. This is done in the [application's constructor](#application-constructor), and the `SetOrderBeginBlock` and `SetOrderEndBlock` methods have to be called before the `SetBeginBlocker` and `SetEndBlocker` functions. -As a sidenote, it is important to remember that application-specific blockchains are deterministic. Developers must be careful not to introduce non-determinism in `BeginBlocker` or `EndBlocker`, and must also be careful not to make them too computationally expensive, as [gas](./fees-signature.md/gas) does not constrain the cost of `BeginBlocker` and `EndBlocker` execution. +As a sidenote, it is important to remember that application-specific blockchains are deterministic. Developers must be careful not to introduce non-determinism in `BeginBlocker` or `EndBlocker`, and must also be careful not to make them too computationally expensive, as [gas](./accounts-fees.md/gas) does not constrain the cost of `BeginBlocker` and `EndBlocker` execution. You can see an example of `BeginBlocker` and `EndBlocker` functions [here](https://github.com/cosmos/gaia/blob/master/app/app.go#L224-L232). @@ -155,7 +155,7 @@ To learn more about the application module interface, [click here](./modules.md# A message is a custom type defined by each module that implements the [`message`](https://github.com/cosmos/cosmos-sdk/blob/master/types/tx_msg.go#L8-L29) interface. Each `transaction` contains one or multiple `messages`. When a valid block of transactions is received by the full-node, Tendermint relays each one to the application via [`DeliverTx`](https://tendermint.com/docs/app-dev/abci-spec.html#delivertx). Then, the application handles the transaction: 1. Upon receiving the transaction, the application first unmarshalls it from `[]bytes`. -2. Then, it verifies a few things about the transaction like [fee payment and signatures](#fees-signature.md) before extracting the message(s) contained in the transaction. +2. Then, it verifies a few things about the transaction like [fee payment and signatures](#accounts-fees.md) before extracting the message(s) contained in the transaction. 3. With the [`Type()`](https://github.com/cosmos/cosmos-sdk/blob/master/types/tx_msg.go#L16) method, `baseapp` is able to know which modules defines the message. It is then able to route it to the appropriate module's [handler](#handler) in order for the message to be processed. 4. If the message is successfully processed, the state is updated. diff --git a/docs/concepts/baseapp.md b/docs/concepts/baseapp.md index 855b03cf1b55..c239272fcba3 100644 --- a/docs/concepts/baseapp.md +++ b/docs/concepts/baseapp.md @@ -11,7 +11,7 @@ This document describes `baseapp`, the abstraction that implements most of the c - [Introduction](#introduction) - [Type Definition](#type-definition) -- [States and Modes](#states-and-modes) +- [States](#states) - [Routing](#routing) - [ABCI](#abci) - [CheckTx](#abci-checktx) @@ -33,7 +33,7 @@ This document describes `baseapp`, the abstraction that implements most of the c - The [Application-Blockchain Interface](#abci), for the state-machine to communicate with the underlying consensus engine (e.g. Tendermint). - A [Router](#routing), to route [messages](./tx-msgs.md) and [queries](./querier.md) to the appropriate [module](./modules.md). -- Different [states and modes](#states-and-modes), as the state-machine can be in different modes depending on the ABCI message it processes. +- Different [states](#states), as the state-machine can have different parallel states updated based on the ABCI message received. The goal of `baseapp` is to provide a boilerplate SDK application that developers can easily extend to build their own custom application. Usually, developers will create a custom type for their application, like so: @@ -54,26 +54,87 @@ Extending the application with `baseapp` gives the former access to all of `base ## Type Definition -The [`baseapp` type](https://github.com/cosmos/cosmos-sdk/blob/master/baseapp/baseapp.go#L45-L91) holds many important parameters for any Cosmos SDK based application. Let us go through the most important components: +The [`baseapp` type](https://github.com/cosmos/cosmos-sdk/blob/master/baseapp/baseapp.go#L45-L91) holds many important parameters for any Cosmos SDK based application. Let us go through the most important components. -- A [`CommitMultiStore`](./store.md#commit-multi-store). This is the main store of the application, which holds the canonical state that is committed at the [end of each block](#endblock). This store is **not** cached, meaning it is not used to update the application's intermediate (un-committed) states. The `CommitMultiStore` is a multi-store, meaning a store of stores. Each module of the application uses one or multiple `KVStores` in the multi-store to persist their subset of the state. +*Note: Not all parameters are described, only the most important ones. Refer to the [type definition](https://github.com/cosmos/cosmos-sdk/blob/master/baseapp/baseapp.go#L45-L91) for the full list* + +First, the important parameters that are initialized during the initialization of the application: + +- A [`CommitMultiStore`](./store.md#commit-multi-store). This is the main store of the application, which holds the canonical state that is committed at the [end of each block](#commit). This store is **not** cached, meaning it is not used to update the application's intermediate (un-committed) states. The `CommitMultiStore` is a multi-store, meaning a store of stores. Each module of the application uses one or multiple `KVStores` in the multi-store to persist their subset of the state. - A [database](./store.md#database) `db`, which is used by the `CommitMultiStore` to handle data storage. -- +- A [router](#messages). The `router` facilitates the routing of [messages](./tx-msgs.md) to the appropriate module for it to be processed. +- A [query router](#queries). The `query router` facilitates the routing of [queries](./querier.md) to the appropriate module for it to be processed. +- A [`txDecoder`](https://godoc.org/github.com/cosmos/cosmos-sdk/types#TxDecoder), used to decode transaction `[]byte` relayed by the underlying Tendermint engine. +- A [`baseKey`], to access the [main store](./store.md#main-store) in the `CommitMultiStore`. The main store is used to persist data related to the core of the application, like consensus parameters. +- A [`anteHandler`](./accounts-fees.md#antehandler), to handle signature verification and fee paiement when a transaction is received. +- An [`initChainer`](./app-anatomy.md#initchainer), [`beginBlocker` and `endBlocker`](./app-anatomy.md#beginblocker-and-endblocker), which are the functions executed when the application received the [InitChain], [BeginBlock] and [EndBlock] messages from the underlying Tendermint engine. + +Then, parameters used to define [volatile states](#volatile-states) (i.e. cached states): + +- `checkState`: This state is updated during [`CheckTx`](#checktx), and reset on [`Commit`](#commit). +- `deliverState`: This state is updated during [`DeliverTx`](#delivertx), and reset on [`Commit`](#commit). + +Finally, a few more important parameterd: + +- `voteInfos`: This parameter carries the list of validators whose precommit is missing, either because they did not vote or because the proposer did not include their vote. This information is carried by the [context](#context) and can be used by the application for various things like punishing absent validators. +- `minGasPrices`: This parameter defines the minimum [gas prices](./accounts-fees.md#gas) accepted by the node. This is a local parameter, meaning each full-node can set a different `minGasPrices`. It is run by the [`anteHandler`](./accounts-fees.md#antehandler) during `CheckTx`, mainly as a spam protection mechanism. The transaction enters the [mempool](https://tendermint.com/docs/tendermint-core/mempool.html#transaction-ordering) only if the gas price of the transaction is superior to one of the minimum gas price in `minGasPrices` (i.e. if `minGasPrices == 1uatom, 1upho`, the `gas-price` of the transaction must be superior to `1uatom` OR `1upho`). +- `appVersion`: Version of the application. It is set in the [application's constructor function](./baseapp.md#constructor-function). + +## States + +`baseapp` handles various parallel states for different purposes. There is the [main state](#main-state), which is the canonical state of the application, and volatile states like [`checkState`](#checkState) and [`deliverState`](#deliverstate), which are used to handle temporary states inbetween updates of the main state. + +### Main State + +The main state is the canonical state of the application. It is initialized on [`InitChain`](#initchain and updated on [`Commit`](#abci-commit) at the end of each block. + +``` ++--------+ +--------+ +| | | | +| S +----------------------------> | S' | +| | For each T in B: apply(T) | | ++--------+ +--------+ +``` + +The main state is held by `baseapp` in a structure called the [`CommitMultiStore`](./store.md#commit-multi-store). This multi-store is used by developers to instantiate all the stores they need for each of their application's modules. -## States and Modes +### Volatile States + +Volatile - or cached - states are used in between [`Commit`s](#commit) to manage temporary states. They are reset to the latest version of the main state after it is committed. There are two main volatile states: + +- `checkState`: This cached state is initialized during [`InitChain`](#initchain), updated during [`CheckTx`](#abci-checktx) when an unconfirmed transaction is received, and reset to the [main state](#main-state) on [`Commit`](#abci-commit). +- `deliverState`: This cached state is initialized during [`BeginBlock`](#beginblock), updated during [`DeliverTx`](#abci-delivertx) when a transaction included in a block is processed, and reset to the [main state](#main-state) on [`Commit`](#abci-commit). ## Routing -## ABCI +When messages and queries are received by the application, they must be routed to the appropriate module in order to be processed. Routing is done via `baseapp`, which holds a `router` for messages, and a `query router` for queries. + +### Message Routing + +Messages need to be routed after they are extracted from transactions, which are sent from the underlying Tendermint engine via the [`CheckTx`](#checktx) and [`DeliverTx`](#delivertx) ABCI messages. To do so, `baseapp` holds a [`router`](https://github.com/cosmos/cosmos-sdk/blob/master/baseapp/router.go) which maps `paths` (`string`) to the appropriate module [`handler`](./handler.md). Usually, the `path` is the name of the module. + +The application's `router` is initilalized with all the routes using the application's [module manager](./modules.md#module-manager), which itself is initialized with all the application's modules in the application's [constructor](./app-anatomy.md#app-constructor). + +### Query Routing + +Similar to messages, queries need to be routed to the appropriate module's [querier](./querier.md). To do so, `baseapp` holds a [`query router`](https://github.com/cosmos/cosmos-sdk/blob/master/baseapp/queryrouter.go), which maps `paths` (`string`) to the appropriate module [`querier`](./querier.md). Usually, the `path` is the name of the module. -## ABCI - CheckTx +Just like the `router`, the `query router` is initilalized with all the query routes using the application's [module manager](./modules.md#module-manager), which itself is initialized with all the application's modules in the application's [constructor](./app-anatomy.md#app-constructor). -## ABCI - DeliverTx +## Main ABCI Messages -## ABCI - Commit + + +### CheckTx + +### DeliverTx + +## RunTx and RunMsg ## Other ABCI Messages +### Commit + ### Info ### SetOption @@ -84,6 +145,4 @@ The [`baseapp` type](https://github.com/cosmos/cosmos-sdk/blob/master/baseapp/ba ### BeginBlock -### EndBlock - -## Gas \ No newline at end of file +### EndBlock \ No newline at end of file diff --git a/docs/concepts/fees-signature.md b/docs/concepts/fees-signature.md deleted file mode 100644 index 36982a97b5d8..000000000000 --- a/docs/concepts/fees-signature.md +++ /dev/null @@ -1,7 +0,0 @@ -# Fees and Signatures - -## Signatures - -## Fees - -## Gas \ No newline at end of file From 92a0db93a8b2381ac85759202834da6ff63e896d Mon Sep 17 00:00:00 2001 From: gamarin Date: Thu, 27 Jun 2019 11:59:31 +0200 Subject: [PATCH 020/196] reorg --- .../adr-002-docs-structure.md | 0 docs/{concepts => basics}/accounts-fees.md | 0 docs/{concepts => basics}/app-anatomy.md | 0 docs/{concepts => basics}/tx-lifecycle.md | 0 docs/concepts/store/README.md | 0 docs/{concepts => core}/baseapp.md | 0 docs/{concepts => core}/baseapp_old.md | 0 docs/{concepts => core}/encoding.md | 0 docs/{concepts => core}/genesis.md | 0 docs/{concepts => core}/node.md | 0 docs/{concepts => core}/store.md | 0 docs/{concepts => core}/tx-msgs.md | 0 docs/{clients => interfaces}/README.md | 0 docs/{clients => interfaces}/cli.md | 0 docs/{concepts => interfaces}/interfaces.md | 0 .../{clients => interfaces}/lite/getting_started.md | 0 docs/{clients => interfaces}/lite/pics/C2H.png | Bin docs/{clients => interfaces}/lite/pics/H2C.png | Bin docs/{clients => interfaces}/lite/pics/MA.png | Bin docs/{clients => interfaces}/lite/pics/absence1.png | Bin docs/{clients => interfaces}/lite/pics/absence2.png | Bin docs/{clients => interfaces}/lite/pics/absence3.png | Bin .../lite/pics/architecture.png | Bin .../lite/pics/changeProcess.png | Bin .../lite/pics/commitValidation.png | Bin .../lite/pics/create-account.png | Bin docs/{clients => interfaces}/lite/pics/deposit.png | Bin .../lite/pics/existProof.png | Bin .../lite/pics/high-level.png | Bin .../lite/pics/light-client-architecture.png | Bin .../lite/pics/loadbalanceDiagram.png | Bin .../lite/pics/simpleMerkleTree.png | Bin .../lite/pics/substoreProof.png | Bin .../lite/pics/transfer-tokens.png | Bin docs/{clients => interfaces}/lite/pics/transfer.png | Bin .../lite/pics/trustPropagate.png | Bin .../lite/pics/updateValidatorToHeight.png | Bin .../lite/pics/validatorSetChange.png | Bin docs/{clients => interfaces}/lite/pics/withdraw.png | Bin docs/{clients => interfaces}/lite/readme.md | 0 docs/{clients => interfaces}/lite/specification.md | 0 docs/{clients => interfaces}/service-providers.md | 0 docs/{concepts => modules}/handler.md | 0 docs/{concepts => modules}/invariants.md | 0 docs/{concepts => modules}/keeper.md | 0 docs/{concepts => modules}/module-interfaces.md | 0 docs/{concepts => modules}/modules.md | 0 docs/{concepts => modules}/querier.md | 0 48 files changed, 0 insertions(+), 0 deletions(-) rename docs/{architecture => _architecture}/adr-002-docs-structure.md (100%) rename docs/{concepts => basics}/accounts-fees.md (100%) rename docs/{concepts => basics}/app-anatomy.md (100%) rename docs/{concepts => basics}/tx-lifecycle.md (100%) delete mode 100644 docs/concepts/store/README.md rename docs/{concepts => core}/baseapp.md (100%) rename docs/{concepts => core}/baseapp_old.md (100%) rename docs/{concepts => core}/encoding.md (100%) rename docs/{concepts => core}/genesis.md (100%) rename docs/{concepts => core}/node.md (100%) rename docs/{concepts => core}/store.md (100%) rename docs/{concepts => core}/tx-msgs.md (100%) rename docs/{clients => interfaces}/README.md (100%) rename docs/{clients => interfaces}/cli.md (100%) rename docs/{concepts => interfaces}/interfaces.md (100%) rename docs/{clients => interfaces}/lite/getting_started.md (100%) rename docs/{clients => interfaces}/lite/pics/C2H.png (100%) rename docs/{clients => interfaces}/lite/pics/H2C.png (100%) rename docs/{clients => interfaces}/lite/pics/MA.png (100%) rename docs/{clients => interfaces}/lite/pics/absence1.png (100%) rename docs/{clients => interfaces}/lite/pics/absence2.png (100%) rename docs/{clients => interfaces}/lite/pics/absence3.png (100%) rename docs/{clients => interfaces}/lite/pics/architecture.png (100%) rename docs/{clients => interfaces}/lite/pics/changeProcess.png (100%) rename docs/{clients => interfaces}/lite/pics/commitValidation.png (100%) rename docs/{clients => interfaces}/lite/pics/create-account.png (100%) rename docs/{clients => interfaces}/lite/pics/deposit.png (100%) rename docs/{clients => interfaces}/lite/pics/existProof.png (100%) rename docs/{clients => interfaces}/lite/pics/high-level.png (100%) rename docs/{clients => interfaces}/lite/pics/light-client-architecture.png (100%) rename docs/{clients => interfaces}/lite/pics/loadbalanceDiagram.png (100%) rename docs/{clients => interfaces}/lite/pics/simpleMerkleTree.png (100%) rename docs/{clients => interfaces}/lite/pics/substoreProof.png (100%) rename docs/{clients => interfaces}/lite/pics/transfer-tokens.png (100%) rename docs/{clients => interfaces}/lite/pics/transfer.png (100%) rename docs/{clients => interfaces}/lite/pics/trustPropagate.png (100%) rename docs/{clients => interfaces}/lite/pics/updateValidatorToHeight.png (100%) rename docs/{clients => interfaces}/lite/pics/validatorSetChange.png (100%) rename docs/{clients => interfaces}/lite/pics/withdraw.png (100%) rename docs/{clients => interfaces}/lite/readme.md (100%) rename docs/{clients => interfaces}/lite/specification.md (100%) rename docs/{clients => interfaces}/service-providers.md (100%) rename docs/{concepts => modules}/handler.md (100%) rename docs/{concepts => modules}/invariants.md (100%) rename docs/{concepts => modules}/keeper.md (100%) rename docs/{concepts => modules}/module-interfaces.md (100%) rename docs/{concepts => modules}/modules.md (100%) rename docs/{concepts => modules}/querier.md (100%) diff --git a/docs/architecture/adr-002-docs-structure.md b/docs/_architecture/adr-002-docs-structure.md similarity index 100% rename from docs/architecture/adr-002-docs-structure.md rename to docs/_architecture/adr-002-docs-structure.md diff --git a/docs/concepts/accounts-fees.md b/docs/basics/accounts-fees.md similarity index 100% rename from docs/concepts/accounts-fees.md rename to docs/basics/accounts-fees.md diff --git a/docs/concepts/app-anatomy.md b/docs/basics/app-anatomy.md similarity index 100% rename from docs/concepts/app-anatomy.md rename to docs/basics/app-anatomy.md diff --git a/docs/concepts/tx-lifecycle.md b/docs/basics/tx-lifecycle.md similarity index 100% rename from docs/concepts/tx-lifecycle.md rename to docs/basics/tx-lifecycle.md diff --git a/docs/concepts/store/README.md b/docs/concepts/store/README.md deleted file mode 100644 index e69de29bb2d1..000000000000 diff --git a/docs/concepts/baseapp.md b/docs/core/baseapp.md similarity index 100% rename from docs/concepts/baseapp.md rename to docs/core/baseapp.md diff --git a/docs/concepts/baseapp_old.md b/docs/core/baseapp_old.md similarity index 100% rename from docs/concepts/baseapp_old.md rename to docs/core/baseapp_old.md diff --git a/docs/concepts/encoding.md b/docs/core/encoding.md similarity index 100% rename from docs/concepts/encoding.md rename to docs/core/encoding.md diff --git a/docs/concepts/genesis.md b/docs/core/genesis.md similarity index 100% rename from docs/concepts/genesis.md rename to docs/core/genesis.md diff --git a/docs/concepts/node.md b/docs/core/node.md similarity index 100% rename from docs/concepts/node.md rename to docs/core/node.md diff --git a/docs/concepts/store.md b/docs/core/store.md similarity index 100% rename from docs/concepts/store.md rename to docs/core/store.md diff --git a/docs/concepts/tx-msgs.md b/docs/core/tx-msgs.md similarity index 100% rename from docs/concepts/tx-msgs.md rename to docs/core/tx-msgs.md diff --git a/docs/clients/README.md b/docs/interfaces/README.md similarity index 100% rename from docs/clients/README.md rename to docs/interfaces/README.md diff --git a/docs/clients/cli.md b/docs/interfaces/cli.md similarity index 100% rename from docs/clients/cli.md rename to docs/interfaces/cli.md diff --git a/docs/concepts/interfaces.md b/docs/interfaces/interfaces.md similarity index 100% rename from docs/concepts/interfaces.md rename to docs/interfaces/interfaces.md diff --git a/docs/clients/lite/getting_started.md b/docs/interfaces/lite/getting_started.md similarity index 100% rename from docs/clients/lite/getting_started.md rename to docs/interfaces/lite/getting_started.md diff --git a/docs/clients/lite/pics/C2H.png b/docs/interfaces/lite/pics/C2H.png similarity index 100% rename from docs/clients/lite/pics/C2H.png rename to docs/interfaces/lite/pics/C2H.png diff --git a/docs/clients/lite/pics/H2C.png b/docs/interfaces/lite/pics/H2C.png similarity index 100% rename from docs/clients/lite/pics/H2C.png rename to docs/interfaces/lite/pics/H2C.png diff --git a/docs/clients/lite/pics/MA.png b/docs/interfaces/lite/pics/MA.png similarity index 100% rename from docs/clients/lite/pics/MA.png rename to docs/interfaces/lite/pics/MA.png diff --git a/docs/clients/lite/pics/absence1.png b/docs/interfaces/lite/pics/absence1.png similarity index 100% rename from docs/clients/lite/pics/absence1.png rename to docs/interfaces/lite/pics/absence1.png diff --git a/docs/clients/lite/pics/absence2.png b/docs/interfaces/lite/pics/absence2.png similarity index 100% rename from docs/clients/lite/pics/absence2.png rename to docs/interfaces/lite/pics/absence2.png diff --git a/docs/clients/lite/pics/absence3.png b/docs/interfaces/lite/pics/absence3.png similarity index 100% rename from docs/clients/lite/pics/absence3.png rename to docs/interfaces/lite/pics/absence3.png diff --git a/docs/clients/lite/pics/architecture.png b/docs/interfaces/lite/pics/architecture.png similarity index 100% rename from docs/clients/lite/pics/architecture.png rename to docs/interfaces/lite/pics/architecture.png diff --git a/docs/clients/lite/pics/changeProcess.png b/docs/interfaces/lite/pics/changeProcess.png similarity index 100% rename from docs/clients/lite/pics/changeProcess.png rename to docs/interfaces/lite/pics/changeProcess.png diff --git a/docs/clients/lite/pics/commitValidation.png b/docs/interfaces/lite/pics/commitValidation.png similarity index 100% rename from docs/clients/lite/pics/commitValidation.png rename to docs/interfaces/lite/pics/commitValidation.png diff --git a/docs/clients/lite/pics/create-account.png b/docs/interfaces/lite/pics/create-account.png similarity index 100% rename from docs/clients/lite/pics/create-account.png rename to docs/interfaces/lite/pics/create-account.png diff --git a/docs/clients/lite/pics/deposit.png b/docs/interfaces/lite/pics/deposit.png similarity index 100% rename from docs/clients/lite/pics/deposit.png rename to docs/interfaces/lite/pics/deposit.png diff --git a/docs/clients/lite/pics/existProof.png b/docs/interfaces/lite/pics/existProof.png similarity index 100% rename from docs/clients/lite/pics/existProof.png rename to docs/interfaces/lite/pics/existProof.png diff --git a/docs/clients/lite/pics/high-level.png b/docs/interfaces/lite/pics/high-level.png similarity index 100% rename from docs/clients/lite/pics/high-level.png rename to docs/interfaces/lite/pics/high-level.png diff --git a/docs/clients/lite/pics/light-client-architecture.png b/docs/interfaces/lite/pics/light-client-architecture.png similarity index 100% rename from docs/clients/lite/pics/light-client-architecture.png rename to docs/interfaces/lite/pics/light-client-architecture.png diff --git a/docs/clients/lite/pics/loadbalanceDiagram.png b/docs/interfaces/lite/pics/loadbalanceDiagram.png similarity index 100% rename from docs/clients/lite/pics/loadbalanceDiagram.png rename to docs/interfaces/lite/pics/loadbalanceDiagram.png diff --git a/docs/clients/lite/pics/simpleMerkleTree.png b/docs/interfaces/lite/pics/simpleMerkleTree.png similarity index 100% rename from docs/clients/lite/pics/simpleMerkleTree.png rename to docs/interfaces/lite/pics/simpleMerkleTree.png diff --git a/docs/clients/lite/pics/substoreProof.png b/docs/interfaces/lite/pics/substoreProof.png similarity index 100% rename from docs/clients/lite/pics/substoreProof.png rename to docs/interfaces/lite/pics/substoreProof.png diff --git a/docs/clients/lite/pics/transfer-tokens.png b/docs/interfaces/lite/pics/transfer-tokens.png similarity index 100% rename from docs/clients/lite/pics/transfer-tokens.png rename to docs/interfaces/lite/pics/transfer-tokens.png diff --git a/docs/clients/lite/pics/transfer.png b/docs/interfaces/lite/pics/transfer.png similarity index 100% rename from docs/clients/lite/pics/transfer.png rename to docs/interfaces/lite/pics/transfer.png diff --git a/docs/clients/lite/pics/trustPropagate.png b/docs/interfaces/lite/pics/trustPropagate.png similarity index 100% rename from docs/clients/lite/pics/trustPropagate.png rename to docs/interfaces/lite/pics/trustPropagate.png diff --git a/docs/clients/lite/pics/updateValidatorToHeight.png b/docs/interfaces/lite/pics/updateValidatorToHeight.png similarity index 100% rename from docs/clients/lite/pics/updateValidatorToHeight.png rename to docs/interfaces/lite/pics/updateValidatorToHeight.png diff --git a/docs/clients/lite/pics/validatorSetChange.png b/docs/interfaces/lite/pics/validatorSetChange.png similarity index 100% rename from docs/clients/lite/pics/validatorSetChange.png rename to docs/interfaces/lite/pics/validatorSetChange.png diff --git a/docs/clients/lite/pics/withdraw.png b/docs/interfaces/lite/pics/withdraw.png similarity index 100% rename from docs/clients/lite/pics/withdraw.png rename to docs/interfaces/lite/pics/withdraw.png diff --git a/docs/clients/lite/readme.md b/docs/interfaces/lite/readme.md similarity index 100% rename from docs/clients/lite/readme.md rename to docs/interfaces/lite/readme.md diff --git a/docs/clients/lite/specification.md b/docs/interfaces/lite/specification.md similarity index 100% rename from docs/clients/lite/specification.md rename to docs/interfaces/lite/specification.md diff --git a/docs/clients/service-providers.md b/docs/interfaces/service-providers.md similarity index 100% rename from docs/clients/service-providers.md rename to docs/interfaces/service-providers.md diff --git a/docs/concepts/handler.md b/docs/modules/handler.md similarity index 100% rename from docs/concepts/handler.md rename to docs/modules/handler.md diff --git a/docs/concepts/invariants.md b/docs/modules/invariants.md similarity index 100% rename from docs/concepts/invariants.md rename to docs/modules/invariants.md diff --git a/docs/concepts/keeper.md b/docs/modules/keeper.md similarity index 100% rename from docs/concepts/keeper.md rename to docs/modules/keeper.md diff --git a/docs/concepts/module-interfaces.md b/docs/modules/module-interfaces.md similarity index 100% rename from docs/concepts/module-interfaces.md rename to docs/modules/module-interfaces.md diff --git a/docs/concepts/modules.md b/docs/modules/modules.md similarity index 100% rename from docs/concepts/modules.md rename to docs/modules/modules.md diff --git a/docs/concepts/querier.md b/docs/modules/querier.md similarity index 100% rename from docs/concepts/querier.md rename to docs/modules/querier.md From 94664fe971dbb841b4f743fa8243a968c60766fc Mon Sep 17 00:00:00 2001 From: gamarin Date: Fri, 5 Jul 2019 12:00:14 +0200 Subject: [PATCH 021/196] almost there --- docs/basics/accounts-fees.md | 2 +- .../README.md | 0 .../handler.md | 0 .../invariants.md | 0 .../keeper.md | 0 .../module-interfaces.md | 0 .../modules.md | 0 .../querier.md | 0 docs/core/baseapp.md | 181 ++++++++++++++++-- docs/core/context.md | 0 docs/{intro => core}/ocap.md | 0 docs/intro/sdk-design.md | 2 +- 12 files changed, 167 insertions(+), 18 deletions(-) rename docs/{modules => building-modules.md}/README.md (100%) rename docs/{modules => building-modules.md}/handler.md (100%) rename docs/{modules => building-modules.md}/invariants.md (100%) rename docs/{modules => building-modules.md}/keeper.md (100%) rename docs/{modules => building-modules.md}/module-interfaces.md (100%) rename docs/{modules => building-modules.md}/modules.md (100%) rename docs/{modules => building-modules.md}/querier.md (100%) create mode 100644 docs/core/context.md rename docs/{intro => core}/ocap.md (100%) diff --git a/docs/basics/accounts-fees.md b/docs/basics/accounts-fees.md index 9f03e0eb033d..20fe1fb2dac8 100644 --- a/docs/basics/accounts-fees.md +++ b/docs/basics/accounts-fees.md @@ -1,4 +1,4 @@ -# Accounts, Fees and Signatures +# Accounts, Fees and Gas ## Accounts diff --git a/docs/modules/README.md b/docs/building-modules.md/README.md similarity index 100% rename from docs/modules/README.md rename to docs/building-modules.md/README.md diff --git a/docs/modules/handler.md b/docs/building-modules.md/handler.md similarity index 100% rename from docs/modules/handler.md rename to docs/building-modules.md/handler.md diff --git a/docs/modules/invariants.md b/docs/building-modules.md/invariants.md similarity index 100% rename from docs/modules/invariants.md rename to docs/building-modules.md/invariants.md diff --git a/docs/modules/keeper.md b/docs/building-modules.md/keeper.md similarity index 100% rename from docs/modules/keeper.md rename to docs/building-modules.md/keeper.md diff --git a/docs/modules/module-interfaces.md b/docs/building-modules.md/module-interfaces.md similarity index 100% rename from docs/modules/module-interfaces.md rename to docs/building-modules.md/module-interfaces.md diff --git a/docs/modules/modules.md b/docs/building-modules.md/modules.md similarity index 100% rename from docs/modules/modules.md rename to docs/building-modules.md/modules.md diff --git a/docs/modules/querier.md b/docs/building-modules.md/querier.md similarity index 100% rename from docs/modules/querier.md rename to docs/building-modules.md/querier.md diff --git a/docs/core/baseapp.md b/docs/core/baseapp.md index c239272fcba3..a327da2a3d40 100644 --- a/docs/core/baseapp.md +++ b/docs/core/baseapp.md @@ -11,21 +11,26 @@ This document describes `baseapp`, the abstraction that implements most of the c - [Introduction](#introduction) - [Type Definition](#type-definition) +- [Constructor](#constructor) - [States](#states) - [Routing](#routing) -- [ABCI](#abci) -- [CheckTx](#abci-checktx) -- [DeliverTx](#abci-delivertx) -- [Commit](#abbci-commit) +- [Main ABCI Messages](#abci) + + [CheckTx](#checktx) + + [DeliverTx](#delivertx) +- [RunTx, AnteHandler and RunMsgs](#runtx-,antehandler-and-runmsgs) + + [RunTx](#runtx) + + [AnteHandler](#antehandler) + + [RunMsgs](#runmsgs) - [Other ABCI Message](#other-abci-message) - + [Info](#info) - + [SetOption](#setoption) - + [Query](#query) + [InitChain](#initchain) + [BeginBlock](#beginblock) + [EndBlock](#endblock) -- [Gas](#gas) - + + [Commit](#commit) + + [Info](#info) + + [Query](#query) + + + ## Introduction @@ -66,7 +71,7 @@ First, the important parameters that are initialized during the initialization o - A [query router](#queries). The `query router` facilitates the routing of [queries](./querier.md) to the appropriate module for it to be processed. - A [`txDecoder`](https://godoc.org/github.com/cosmos/cosmos-sdk/types#TxDecoder), used to decode transaction `[]byte` relayed by the underlying Tendermint engine. - A [`baseKey`], to access the [main store](./store.md#main-store) in the `CommitMultiStore`. The main store is used to persist data related to the core of the application, like consensus parameters. -- A [`anteHandler`](./accounts-fees.md#antehandler), to handle signature verification and fee paiement when a transaction is received. +- A [`anteHandler`](#antehandler), to handle signature verification and fee paiement when a transaction is received. - An [`initChainer`](./app-anatomy.md#initchainer), [`beginBlocker` and `endBlocker`](./app-anatomy.md#beginblocker-and-endblocker), which are the functions executed when the application received the [InitChain], [BeginBlock] and [EndBlock] messages from the underlying Tendermint engine. Then, parameters used to define [volatile states](#volatile-states) (i.e. cached states): @@ -80,10 +85,61 @@ Finally, a few more important parameterd: - `minGasPrices`: This parameter defines the minimum [gas prices](./accounts-fees.md#gas) accepted by the node. This is a local parameter, meaning each full-node can set a different `minGasPrices`. It is run by the [`anteHandler`](./accounts-fees.md#antehandler) during `CheckTx`, mainly as a spam protection mechanism. The transaction enters the [mempool](https://tendermint.com/docs/tendermint-core/mempool.html#transaction-ordering) only if the gas price of the transaction is superior to one of the minimum gas price in `minGasPrices` (i.e. if `minGasPrices == 1uatom, 1upho`, the `gas-price` of the transaction must be superior to `1uatom` OR `1upho`). - `appVersion`: Version of the application. It is set in the [application's constructor function](./baseapp.md#constructor-function). +## Constructor + + + ## States `baseapp` handles various parallel states for different purposes. There is the [main state](#main-state), which is the canonical state of the application, and volatile states like [`checkState`](#checkState) and [`deliverState`](#deliverstate), which are used to handle temporary states inbetween updates of the main state. +``` + To perform stateful checks To execute state To answer queries + on received transactions transitions during DeliverTx about last-committed state + +----------------------+ +----------------------+ +----------------------+ + | CheckState(t)(0) | | DeliverState(t)(0) | | QueryState(t) | + +----------------------+ | | | | +CheckTx(tx1) | | | | | + v | | | | + +----------------------+ | | | | + | CheckState(t)(1) | | | | | + +----------------------+ | | | | +CheckTx(tx2) | | | | | + v | | | | + +----------------------+ | | | | + | CheckState(t)(2) | | | | | + +----------------------+ | | | | +CheckTx(tx3) | | | | | + v | | | | + +----------------------+ | | | | + | CheckState(t)(3) | | | | | + +----------------------+ +----------------------+ | | +DeliverTx(tx1) | | | | + v v | | + +----------------------+ +----------------------+ | | + | | | DeliverState(t)(1) | | | + | | +----------------------+ | | +DeliverTx(tx2) | | | | | + | | v | | + | | +----------------------+ | | + | | | DeliverState(t)(2) | | | + | | +----------------------+ | | +DeliverTx(tx3) | | | | | + | | v | | + | | +----------------------+ | | + | | | DeliverState(t)(3) | | | + +----------------------+ +----------------------+ +----------------------+ +Commit() | | | + v v v + +----------------------+ +----------------------+ +----------------------+ + | CheckState(t+1)(0) | | DeliverState(t+1)(0) | | QueryState(t+1) | + +----------------------+ | | | | + . . . + . . . + . . . + +``` + ### Main State The main state is the canonical state of the application. It is initialized on [`InitChain`](#initchain and updated on [`Commit`](#abci-commit) at the end of each block. @@ -105,6 +161,11 @@ Volatile - or cached - states are used in between [`Commit`s](#commit) to manage - `checkState`: This cached state is initialized during [`InitChain`](#initchain), updated during [`CheckTx`](#abci-checktx) when an unconfirmed transaction is received, and reset to the [main state](#main-state) on [`Commit`](#abci-commit). - `deliverState`: This cached state is initialized during [`BeginBlock`](#beginblock), updated during [`DeliverTx`](#abci-delivertx) when a transaction included in a block is processed, and reset to the [main state](#main-state) on [`Commit`](#abci-commit). +Both `checkState` and `deliverState` are of type [`state`](https://github.com/cosmos/cosmos-sdk/blob/master/baseapp/baseapp.go#L973-L976), which includes: + +- A [`CacheMultiStore`](https://github.com/cosmos/cosmos-sdk/blob/master/store/cachemulti/store.go), which is a cached version of the main `CommitMultiStore`. A new version of this store is committed at the end of each successful `CheckTx`/`DeliverTx` execution. +- A [`Context`](./context.md), which carries general information (like raw transaction size, block height, ...) that might be needed in order to process the transaction during `CheckTx` and `DeliverTx`. The `context` also holds a cache-wrapped version of the `CacheMultiStore`, so that the `CacheMultiStore` can maintain the correct version even if an internal step of `CheckTx` or `DeliverTx` fails. + ## Routing When messages and queries are received by the application, they must be routed to the appropriate module in order to be processed. Routing is done via `baseapp`, which holds a `router` for messages, and a `query router` for queries. @@ -123,26 +184,114 @@ Just like the `router`, the `query router` is initilalized with all the query ro ## Main ABCI Messages +The [Application-Blockchain Interface](https://tendermint.com/docs/spec/abci/) (ABCI) is a generic interface that connects a state-machine with a consensus engine to form a functional full-node. It can be wrapped in any language, and needs to be implemented by each application-specific blockchain built on top of an ABCI-compatible consensus engine like Tendermint. + +The consensus engine handles two main tasks: +- The networking logic, which mainly consists in gossiping block parts, transactions and consensus votes. +- The consensus logic, which results in the deterministic ordering of transactions in the form of blocks. + +It is **not** the role of the consensus engine to define the state or the validity of transactions. Generally, transactions are handled by the consensus engine in the form of `[]bytes`, and relayed to the application via the ABCI to be decoded and processed. At keys moments in the networking and consensus processes (e.g. beginning of a block, commit of a block, reception of an unconfirmed transaction, ...), the consensus engine emits ABCI messages for the state-machine to act on. + +Developers building on top of the Cosmos SDK need not implement the ABCI themselves, as `baseapp` comes with a built-in implementation of the interface. Let us go through the main ABCI messages that `baseapp` implements: [`CheckTx`](#checktx) and [`DeliverTx`](#delivertx) ### CheckTx +`CheckTx` is sent by the underlying consensus engine when a new unconfirmed (i.e. not yet included in a valid block) transaction is received by a full-node. The role of `CheckTx` is to guard the full-node's mempool (where unconfirmed transactions are stored until they are included in a block) from spam transactions. Unconfirmed transactions are relayed to peers only if they pass `CheckTx`. + +`CheckTx` can perform both *stateful* and *stateless* checks, but developers should strive to make them lightweight. In the Cosmos SDK, after [decoding transactions](./encoding.md), `CheckTx` is implemented to do the following checks: + +1. Extract the `message`s from the transaction. +2. Perform *stateless* checks by calling `ValidateBasic()` on each of the `messages`. This is done first, as *stateless* checks are less computationally expensive than *stateful* checks. If `ValidateBasic()` fail, `CheckTx` returns before running *stateful* checks, which saves resources. +3. Perform non-module related *stateful* checks on the account. This step is mainly about checking that the `message` signatures are valid, that enough fees are provided and that the sending account has enough funds to pay for said fees. Note that no precise [`gas`](./accounts-fees.md#gas) counting occurs here, as `message`s are not processed. Usually, the [`anteHandler`](./accounts-fees.md#antehandler) will check that the `gas` provided with the transaction is superior to a minimum reference gas amount based on the raw transaction size, in order to avoid spam with transactions that provide 0 gas. +4. Ensure that a [`Route`](#message-routing) exists for each `message`, but do **not** actually process `message`s. `Message`s only need to be processed when the canonical state need to be updated, which happens during `DeliverTx`. + +Steps 2. and 3. are performed by the [`anteHandler`](./accounts-fees.md#antehandler) in the [`RunTx`](#runtx-,antehandler-and-runmsgs) function, which `CheckTx` calls with the `runTxModeCheck` mode. During each step of `CheckTx`, a special [volatile state](#volatile-states) called `checkState` is updated. This state is used to keep track of the temporary changes triggered by the `CheckTx` calls of each transaction without modifying the [main canonical state](#main-state) . For example, when a transaction goes through `CheckTx`, the transaction's fees are deducted from the sender's account in `checkState`. If a second transaction is received from the same account before the first is processed, and the account has consumed all its funds in `checkState` during the first transaction, the second transaction will fail `CheckTx` and be rejected. In any case, the sender's account will not actually pay the fees until the transaction is actually included in a block, because `checkState` never gets committed to the main state. `checkState` is reset to the latest state of the main state each time a blocks gets [committed](#commit). + +`CheckTx` returns a response to the underlying consensus engine of type [`abci.ResponseCheckTx`](https://tendermint.com/docs/spec/abci/abci.html#messages). The response contains: + +- `Code (uint32)`: Response Code. `0` if successful. +- `Data ([]byte)`: Result bytes, if any. +- `Log (string):` The output of the application's logger. May be non-deterministic. +- `Info (string):` Additional information. May be non-deterministic. +- `GasWanted (int64)`: Amount of gas requested for transaction. It is provided by users when they generate the transaction. +- `GasUsed (int64)`: Amount of gas consumed by transaction. During `CheckTx`, this value is computed by multiplying the standard cost of a transaction byte by the size of the raw transaction (click [here](https://github.com/cosmos/cosmos-sdk/blob/master/x/auth/ante.go#L101) for an example). +- `Tags ([]cmn.KVPair)`: Key-Value tags for filtering and indexing transactions (eg. by account). +- `Codespace (string)`: Namespace for the Code. + ### DeliverTx -## RunTx and RunMsg +When the underlying consensus engine receives a block proposal, each transaction in the block needs to be processed by the application. To that end, the underlying consensus engine sends a `DeliverTx` message to the application for each transaction in a sequential order. + +Before the first transaction of a given block is processed, a [volatile state](#volatile-states) called `deliverState` is intialized during [`BeginBlock`](#beginblock). This state is updated each time a transaction is processed via `DeliverTx`, and committed to the [main state](#main-state) when the block is [committed](#commit), after what is is set to `nil`. + +`DeliverTx` performs the **exact same steps as `CheckTx`**, with a little caveat at step 3 and the addition of a fifth step: + +3. The `anteHandler` does **not** check that the transaction's `gas-prices` is sufficient. That is because the `min-gas-prices` value `gas-prices` is checked against is local to the node, and therefore what is enough for one full-node might not be for another. This means that the proposer can potentially include transactions for free, although they are not incentivised to do so, as they earn a bonus on the total fee of the block they propose. +5. For each `message` in the transaction, route to the appropriate module's [`handler`](../building-modules/handler.md). Additional *stateful* checks are performed, and the cache-wrapped multistore held in `deliverState`'s `context` is updated by the module's `keeper`. If the `handler` returns successfully, the cache-wrapped multistore held in `context` is written to `deliverState` `CacheMultiStore`. + +During step 5., each read/write to the store increases the value of `GasConsumed`. You can find the default cost of each operation [here](https://github.com/cosmos/cosmos-sdk/blob/master/store/types/gas.go#L142-L150). At any point, if `GasConsumed > GasWanted`, the function returns with `Code != 0` and `DeliverTx` fails. + +`DeliverTx` returns a response to the underlying consensus engine of type [`abci.ResponseCheckTx`](https://tendermint.com/docs/spec/abci/abci.html#messages). The response contains: + +- `Code (uint32)`: Response Code. `0` if successful. +- `Data ([]byte)`: Result bytes, if any. +- `Log (string):` The output of the application's logger. May be non-deterministic. +- `Info (string):` Additional information. May be non-deterministic. +- `GasWanted (int64)`: Amount of gas requested for transaction. It is provided by users when they generate the transaction. +- `GasUsed (int64)`: Amount of gas consumed by transaction. During `DeliverTx`, this value is computed by multiplying the standard cost of a transaction byte by the size of the raw transaction (click [here](https://github.com/cosmos/cosmos-sdk/blob/master/x/auth/ante.go#L101) for an example), and by adding gas each time a read/write to the store occurs. +- `Tags ([]cmn.KVPair)`: Key-Value tags for filtering and indexing transactions (eg. by account). +- `Codespace (string)`: Namespace for the Code. + +## RunTx, AnteHandler and RunMsgs + +### RunTx + +`RunTx` is called from `CheckTx`/`DeliverTx` to handle the transaction, with `runTxModeCheck` or `runTxModeDeliver` as parameter to differentiate between the two modes of execution. Note that when `RunTx` receives a transaction, it has already been decoded. + +The first thing `RunTx` does upon being called is to retrieve the `context`'s `CacheMultiStore` by calling the `getContextForTx()` function with the appropriate mode (either `runTxModeCheck` or `runTxModeDeliver`). This `CacheMultiStore` is a cached version of the main store instantiated during `BeginBlock` for `DeliverTx` and during the `Commit` of the previous block for `CheckTx`. After that, two `defer func()` are called for [`gas`](./accounts-fees.md#gas) management. They are executed when `runTx` returns and make sure `gas` is actually consumed, and will throw errors, if any. + +After that, `RunTx` calls `ValidateBasic()` on each `message`in the `Tx`, which runs prelimary *stateless* validity checks. If any `message` fails to pass `ValidateBasic()`, `RunTx` returns with an error. + +Then, the [`anteHandler`](#antehandler) of the application is run (if it exists). In preparation of this step, both the `checkState`/`deliverState`'s `context` and `context`'s `CacheMultiStore` are cached-wrapped using the [`cacheTxContext()`](https://github.com/cosmos/cosmos-sdk/blob/master/baseapp/baseapp.go#L781-L798) function. This allows `RunTx` not to commit the changes made to the state during the execution of `anteHandler` if it ends up failing. It also prevents the module implementing the `anteHandler` from writing to state, which is an important part of the [object-capabilities](./ocap.md) of the Cosmos SDK. + +Finally, the [`RunMsgs`](#runmsgs) function is called to process the `messages`s in the `Tx`. In preparation of this step, just like with the `anteHandler`, both the `checkState`/`deliverState`'s `context` and `context`'s `CacheMultiStore` are cached-wrapped using the `cacheTxContext()` function. + +### AnteHandler + +The `AnteHandler` is a special handler that implements the [`anteHandler` interface](https://github.com/cosmos/cosmos-sdk/blob/master/types/handler.go#L8) and is used to authenticate the transaction before the transaction's internal messages are processed. + +The `AnteHandler` is theoretically optional, but still a very important component of public blockchain networks. It serves 3 primary purposes: + +- Be a primary line of defense against spam and second line of defense (the first one being the mempool) against transaction replay with fees deduction and [`sequence`](./tx-msgs.md#sequence) checking. +- Perform preliminary *stateful* validity checks like ensuring signatures are valid or that the sender has enough funds to pay for fees. +- Play a role in the incentivisation of stakeholders via the collection of transaction fees. + +`baseapp` holds an `anteHandler` as paraemter, which is initialized in the [application's constructor](../basics/app-anatomy.md#application-constructor). The most widely used `anteHandler` today is that of the [`auth` module](https://github.com/cosmos/cosmos-sdk/blob/master/x/auth/ante.go). + +### RunMsgs + +`RunMsgs` is called from `RunTx` with `runTxModeCheck` as parameter to check the existence of a route for each message the transaction, and with `runTxModeDeliver` to actually process the `message`s. + +First, it retreives the `message`'s `route` using the `Msg.Route()` method. Then, using the application's [`router`](#routing) and the `route`, it checks for the existence of a `handler`. At this point, if `mode == runTxModeCheck`, `RunMsgs` returns. If instead `mode == runTxModeDeliver`, the [`handler`](../building-modules.md#handler) function for the message is executed, before `RunMsgs` returns. ## Other ABCI Messages +### InitChain + +The `InitChain` ABCI message is sent from the underlying Tendermint engine when the chain is first started. + +### BeginBlock + +### EndBlock + ### Commit ### Info -### SetOption - ### Query -### InitChain -### BeginBlock -### EndBlock \ No newline at end of file + + diff --git a/docs/core/context.md b/docs/core/context.md new file mode 100644 index 000000000000..e69de29bb2d1 diff --git a/docs/intro/ocap.md b/docs/core/ocap.md similarity index 100% rename from docs/intro/ocap.md rename to docs/core/ocap.md diff --git a/docs/intro/sdk-design.md b/docs/intro/sdk-design.md index 9549cad4dc5e..0fedc146a9ee 100644 --- a/docs/intro/sdk-design.md +++ b/docs/intro/sdk-design.md @@ -76,7 +76,7 @@ Here is a simplified view of how a transaction is processed by the application o v ``` -Each module can be seen as a little state-machine. Developers need to define the subset of the state handled by the module, as well as custom message types that modify the state (*Note:* `messages` are extracted from `transactions` using `baseapp`). In general, each module declares its own `KVStore` in the multistore to persist the subset of the state it defines. Most developers will need to access other 3rd party modules when building their own modules. Given that the Cosmos-SDK is an open framework, some of the modules may be malicious, which means there is a need for security principles to reason about inter-module interactions. These principles are based on [object-capabilities](./ocap.md). In practice, this means that instead of having each module keep an access control list for other modules, each module implements special objects called `keepers` that can be passed to other modules to grant a pre-defined set of capabilities. +Each module can be seen as a little state-machine. Developers need to define the subset of the state handled by the module, as well as custom message types that modify the state (*Note:* `messages` are extracted from `transactions` using `baseapp`). In general, each module declares its own `KVStore` in the multistore to persist the subset of the state it defines. Most developers will need to access other 3rd party modules when building their own modules. Given that the Cosmos-SDK is an open framework, some of the modules may be malicious, which means there is a need for security principles to reason about inter-module interactions. These principles are based on [object-capabilities](../coore/ocap.md). In practice, this means that instead of having each module keep an access control list for other modules, each module implements special objects called `keepers` that can be passed to other modules to grant a pre-defined set of capabilities. SDK modules are defined in the `x/` folder of the SDK. Some core modules include: From 2624fec9505c5f2c8b09de590a7e70133b446f15 Mon Sep 17 00:00:00 2001 From: gamarin Date: Fri, 5 Jul 2019 19:53:40 +0200 Subject: [PATCH 022/196] finish first draft --- ...{accounts-fees.md => accounts-fees-gas.md} | 6 +- docs/basics/app-anatomy.md | 4 +- docs/core/baseapp.md | 72 +++++++++++++------ 3 files changed, 59 insertions(+), 23 deletions(-) rename docs/basics/{accounts-fees.md => accounts-fees-gas.md} (66%) diff --git a/docs/basics/accounts-fees.md b/docs/basics/accounts-fees-gas.md similarity index 66% rename from docs/basics/accounts-fees.md rename to docs/basics/accounts-fees-gas.md index 20fe1fb2dac8..10b0d82885ed 100644 --- a/docs/basics/accounts-fees.md +++ b/docs/basics/accounts-fees-gas.md @@ -8,4 +8,8 @@ ## Fees -## Gas \ No newline at end of file +## Gas + +## Gas Meter + +## Block Gas Meter \ No newline at end of file diff --git a/docs/basics/app-anatomy.md b/docs/basics/app-anatomy.md index 8fb120d86f5c..dcbe732cca60 100644 --- a/docs/basics/app-anatomy.md +++ b/docs/basics/app-anatomy.md @@ -117,7 +117,7 @@ The SDK offers developers the possibility to implement automatic execution of co In general, the `BeginBlocker` and `EndBlocker` functions are mostly composed of the `BeginBlock` and `EndBlock` functions of each of the application's modules. This is done by calling the `BeginBlock` and `EndBlock` functions of the module manager, which in turn will call the `BeginBLock` and `EndBlock` functions of each of the modules it contains. Note that the order in which the modules' `BegingBlock` and `EndBlock` functions must be called has to be set in the module manager using the `SetOrderBeginBlock` and `SetOrderEndBlock` methods respectively. This is done in the [application's constructor](#application-constructor), and the `SetOrderBeginBlock` and `SetOrderEndBlock` methods have to be called before the `SetBeginBlocker` and `SetEndBlocker` functions. -As a sidenote, it is important to remember that application-specific blockchains are deterministic. Developers must be careful not to introduce non-determinism in `BeginBlocker` or `EndBlocker`, and must also be careful not to make them too computationally expensive, as [gas](./accounts-fees.md/gas) does not constrain the cost of `BeginBlocker` and `EndBlocker` execution. +As a sidenote, it is important to remember that application-specific blockchains are deterministic. Developers must be careful not to introduce non-determinism in `BeginBlocker` or `EndBlocker`, and must also be careful not to make them too computationally expensive, as [gas](./accounts-fees-gas.md/gas) does not constrain the cost of `BeginBlocker` and `EndBlocker` execution. You can see an example of `BeginBlocker` and `EndBlocker` functions [here](https://github.com/cosmos/gaia/blob/master/app/app.go#L224-L232). @@ -155,7 +155,7 @@ To learn more about the application module interface, [click here](./modules.md# A message is a custom type defined by each module that implements the [`message`](https://github.com/cosmos/cosmos-sdk/blob/master/types/tx_msg.go#L8-L29) interface. Each `transaction` contains one or multiple `messages`. When a valid block of transactions is received by the full-node, Tendermint relays each one to the application via [`DeliverTx`](https://tendermint.com/docs/app-dev/abci-spec.html#delivertx). Then, the application handles the transaction: 1. Upon receiving the transaction, the application first unmarshalls it from `[]bytes`. -2. Then, it verifies a few things about the transaction like [fee payment and signatures](#accounts-fees.md) before extracting the message(s) contained in the transaction. +2. Then, it verifies a few things about the transaction like [fee payment and signatures](#accounts-fees-gas.md) before extracting the message(s) contained in the transaction. 3. With the [`Type()`](https://github.com/cosmos/cosmos-sdk/blob/master/types/tx_msg.go#L16) method, `baseapp` is able to know which modules defines the message. It is then able to route it to the appropriate module's [handler](#handler) in order for the message to be processed. 4. If the message is successfully processed, the state is updated. diff --git a/docs/core/baseapp.md b/docs/core/baseapp.md index a327da2a3d40..1f0d6ead44ae 100644 --- a/docs/core/baseapp.md +++ b/docs/core/baseapp.md @@ -2,8 +2,8 @@ ## Pre-requisite Reading -- [Anatomy of an SDK application](./app-anatomy.md) -- [Lifecycle of an SDK transaction](./tx-lifecycle.md) +- [Anatomy of an SDK application](../basics/app-anatomy.md) +- [Lifecycle of an SDK transaction](../basics/tx-lifecycle.md) ## Synopsis @@ -29,15 +29,12 @@ This document describes `baseapp`, the abstraction that implements most of the c + [Info](#info) + [Query](#query) - - - ## Introduction `baseapp` is an abstraction that implements the core of an SDK application, namely: - The [Application-Blockchain Interface](#abci), for the state-machine to communicate with the underlying consensus engine (e.g. Tendermint). -- A [Router](#routing), to route [messages](./tx-msgs.md) and [queries](./querier.md) to the appropriate [module](./modules.md). +- A [Router](#routing), to route [messages](./tx-msgs.md) and [queries](./querier.md) to the appropriate [module](../building-modules/modules.md). - Different [states](#states), as the state-machine can have different parallel states updated based on the ABCI message received. The goal of `baseapp` is to provide a boilerplate SDK application that developers can easily extend to build their own custom application. Usually, developers will create a custom type for their application, like so: @@ -67,12 +64,12 @@ First, the important parameters that are initialized during the initialization o - A [`CommitMultiStore`](./store.md#commit-multi-store). This is the main store of the application, which holds the canonical state that is committed at the [end of each block](#commit). This store is **not** cached, meaning it is not used to update the application's intermediate (un-committed) states. The `CommitMultiStore` is a multi-store, meaning a store of stores. Each module of the application uses one or multiple `KVStores` in the multi-store to persist their subset of the state. - A [database](./store.md#database) `db`, which is used by the `CommitMultiStore` to handle data storage. -- A [router](#messages). The `router` facilitates the routing of [messages](./tx-msgs.md) to the appropriate module for it to be processed. -- A [query router](#queries). The `query router` facilitates the routing of [queries](./querier.md) to the appropriate module for it to be processed. +- A [router](#message-routing). The `router` facilitates the routing of [messages](./tx-msgs.md) to the appropriate module for it to be processed. +- A [query router](#query-routing). The `query router` facilitates the routing of [queries](./querier.md) to the appropriate module for it to be processed. - A [`txDecoder`](https://godoc.org/github.com/cosmos/cosmos-sdk/types#TxDecoder), used to decode transaction `[]byte` relayed by the underlying Tendermint engine. - A [`baseKey`], to access the [main store](./store.md#main-store) in the `CommitMultiStore`. The main store is used to persist data related to the core of the application, like consensus parameters. - A [`anteHandler`](#antehandler), to handle signature verification and fee paiement when a transaction is received. -- An [`initChainer`](./app-anatomy.md#initchainer), [`beginBlocker` and `endBlocker`](./app-anatomy.md#beginblocker-and-endblocker), which are the functions executed when the application received the [InitChain], [BeginBlock] and [EndBlock] messages from the underlying Tendermint engine. +- An [`initChainer`](../basics/app-anatomy.md#initchainer), [`beginBlocker` and `endBlocker`](../basics/app-anatomy.md#beginblocker-and-endblocker), which are the functions executed when the application received the [InitChain], [BeginBlock] and [EndBlock] messages from the underlying Tendermint engine. Then, parameters used to define [volatile states](#volatile-states) (i.e. cached states): @@ -82,20 +79,24 @@ Then, parameters used to define [volatile states](#volatile-states) (i.e. cached Finally, a few more important parameterd: - `voteInfos`: This parameter carries the list of validators whose precommit is missing, either because they did not vote or because the proposer did not include their vote. This information is carried by the [context](#context) and can be used by the application for various things like punishing absent validators. -- `minGasPrices`: This parameter defines the minimum [gas prices](./accounts-fees.md#gas) accepted by the node. This is a local parameter, meaning each full-node can set a different `minGasPrices`. It is run by the [`anteHandler`](./accounts-fees.md#antehandler) during `CheckTx`, mainly as a spam protection mechanism. The transaction enters the [mempool](https://tendermint.com/docs/tendermint-core/mempool.html#transaction-ordering) only if the gas price of the transaction is superior to one of the minimum gas price in `minGasPrices` (i.e. if `minGasPrices == 1uatom, 1upho`, the `gas-price` of the transaction must be superior to `1uatom` OR `1upho`). -- `appVersion`: Version of the application. It is set in the [application's constructor function](./baseapp.md#constructor-function). +- `minGasPrices`: This parameter defines the minimum [gas prices](./accounts-fees-gas.md#gas) accepted by the node. This is a local parameter, meaning each full-node can set a different `minGasPrices`. It is run by the [`anteHandler`](./accounts-fees-gas.md#antehandler) during `CheckTx`, mainly as a spam protection mechanism. The transaction enters the [mempool](https://tendermint.com/docs/tendermint-core/mempool.html#transaction-ordering) only if the gas price of the transaction is superior to one of the minimum gas price in `minGasPrices` (i.e. if `minGasPrices == 1uatom, 1upho`, the `gas-price` of the transaction must be superior to `1uatom` OR `1upho`). +- `appVersion`: Version of the application. It is set in the [application's constructor function](../basics/app-anatomy.md#constructor-function). ## Constructor +`NewBaseApp(name string, logger log.Logger, db dbm.DB, txDecoder sdk.TxDecoder, options ...func(*BaseApp),)` is the constructor function for `baseapp`. It is called from the [application's constructor function](../basics/app-anatomy.md#constructor-function) each time the full-node is started. + +`baseapp`'s constructor function is pretty straightforward. The only thing worth noting is the possibility to add additional [`options`](https://github.com/cosmos/cosmos-sdk/blob/master/baseapp/options.go) to `baseapp` by passing `options functions` to the constructor function, which will execute them in order. `options` are generally `setters` function for important parameters, like `SetPruning()` to active pruning or `SetMinGasPrices()` to set the node's `min-gas-prices`. +A list of `options` example can be found [here](https://github.com/cosmos/cosmos-sdk/blob/master/baseapp/options.go). Naturally, developers can add additional `options` based on their application's needs. ## States `baseapp` handles various parallel states for different purposes. There is the [main state](#main-state), which is the canonical state of the application, and volatile states like [`checkState`](#checkState) and [`deliverState`](#deliverstate), which are used to handle temporary states inbetween updates of the main state. ``` - To perform stateful checks To execute state To answer queries - on received transactions transitions during DeliverTx about last-committed state + To perform stateful checks To execute state To serve queries + on received transactions transitions during DeliverTx on last-committed state +----------------------+ +----------------------+ +----------------------+ | CheckState(t)(0) | | DeliverState(t)(0) | | QueryState(t) | +----------------------+ | | | | @@ -174,13 +175,13 @@ When messages and queries are received by the application, they must be routed t Messages need to be routed after they are extracted from transactions, which are sent from the underlying Tendermint engine via the [`CheckTx`](#checktx) and [`DeliverTx`](#delivertx) ABCI messages. To do so, `baseapp` holds a [`router`](https://github.com/cosmos/cosmos-sdk/blob/master/baseapp/router.go) which maps `paths` (`string`) to the appropriate module [`handler`](./handler.md). Usually, the `path` is the name of the module. -The application's `router` is initilalized with all the routes using the application's [module manager](./modules.md#module-manager), which itself is initialized with all the application's modules in the application's [constructor](./app-anatomy.md#app-constructor). +The application's `router` is initilalized with all the routes using the application's [module manager](./modules.md#module-manager), which itself is initialized with all the application's modules in the application's [constructor](../basics/app-anatomy.md#app-constructor). ### Query Routing Similar to messages, queries need to be routed to the appropriate module's [querier](./querier.md). To do so, `baseapp` holds a [`query router`](https://github.com/cosmos/cosmos-sdk/blob/master/baseapp/queryrouter.go), which maps `paths` (`string`) to the appropriate module [`querier`](./querier.md). Usually, the `path` is the name of the module. -Just like the `router`, the `query router` is initilalized with all the query routes using the application's [module manager](./modules.md#module-manager), which itself is initialized with all the application's modules in the application's [constructor](./app-anatomy.md#app-constructor). +Just like the `router`, the `query router` is initilalized with all the query routes using the application's [module manager](./modules.md#module-manager), which itself is initialized with all the application's modules in the application's [constructor](../basics/app-anatomy.md#app-constructor). ## Main ABCI Messages @@ -191,7 +192,7 @@ The consensus engine handles two main tasks: - The networking logic, which mainly consists in gossiping block parts, transactions and consensus votes. - The consensus logic, which results in the deterministic ordering of transactions in the form of blocks. -It is **not** the role of the consensus engine to define the state or the validity of transactions. Generally, transactions are handled by the consensus engine in the form of `[]bytes`, and relayed to the application via the ABCI to be decoded and processed. At keys moments in the networking and consensus processes (e.g. beginning of a block, commit of a block, reception of an unconfirmed transaction, ...), the consensus engine emits ABCI messages for the state-machine to act on. +It is **not** the role of the consensus engine to define the state or the validity of transactions. Generally, transactions are handled by the consensus engine in the form of `[]bytes`, and relayed to the application via the ABCI to be decoded and processed. At keys moments in the networking and consensus processes (e.g. beginning of a block, commit of a block, reception of an unconfirmed transaction, ...), the consensus engine emits ABCI messages for the state-machine to act on. Developers building on top of the Cosmos SDK need not implement the ABCI themselves, as `baseapp` comes with a built-in implementation of the interface. Let us go through the main ABCI messages that `baseapp` implements: [`CheckTx`](#checktx) and [`DeliverTx`](#delivertx) @@ -203,10 +204,10 @@ Developers building on top of the Cosmos SDK need not implement the ABCI themsel 1. Extract the `message`s from the transaction. 2. Perform *stateless* checks by calling `ValidateBasic()` on each of the `messages`. This is done first, as *stateless* checks are less computationally expensive than *stateful* checks. If `ValidateBasic()` fail, `CheckTx` returns before running *stateful* checks, which saves resources. -3. Perform non-module related *stateful* checks on the account. This step is mainly about checking that the `message` signatures are valid, that enough fees are provided and that the sending account has enough funds to pay for said fees. Note that no precise [`gas`](./accounts-fees.md#gas) counting occurs here, as `message`s are not processed. Usually, the [`anteHandler`](./accounts-fees.md#antehandler) will check that the `gas` provided with the transaction is superior to a minimum reference gas amount based on the raw transaction size, in order to avoid spam with transactions that provide 0 gas. +3. Perform non-module related *stateful* checks on the account. This step is mainly about checking that the `message` signatures are valid, that enough fees are provided and that the sending account has enough funds to pay for said fees. Note that no precise [`gas`](./accounts-fees-gas.md#gas) counting occurs here, as `message`s are not processed. Usually, the [`anteHandler`](./accounts-fees-gas.md#antehandler) will check that the `gas` provided with the transaction is superior to a minimum reference gas amount based on the raw transaction size, in order to avoid spam with transactions that provide 0 gas. 4. Ensure that a [`Route`](#message-routing) exists for each `message`, but do **not** actually process `message`s. `Message`s only need to be processed when the canonical state need to be updated, which happens during `DeliverTx`. -Steps 2. and 3. are performed by the [`anteHandler`](./accounts-fees.md#antehandler) in the [`RunTx`](#runtx-,antehandler-and-runmsgs) function, which `CheckTx` calls with the `runTxModeCheck` mode. During each step of `CheckTx`, a special [volatile state](#volatile-states) called `checkState` is updated. This state is used to keep track of the temporary changes triggered by the `CheckTx` calls of each transaction without modifying the [main canonical state](#main-state) . For example, when a transaction goes through `CheckTx`, the transaction's fees are deducted from the sender's account in `checkState`. If a second transaction is received from the same account before the first is processed, and the account has consumed all its funds in `checkState` during the first transaction, the second transaction will fail `CheckTx` and be rejected. In any case, the sender's account will not actually pay the fees until the transaction is actually included in a block, because `checkState` never gets committed to the main state. `checkState` is reset to the latest state of the main state each time a blocks gets [committed](#commit). +Steps 2. and 3. are performed by the [`anteHandler`](./accounts-fees-gas.md#antehandler) in the [`RunTx`](#runtx-,antehandler-and-runmsgs) function, which `CheckTx` calls with the `runTxModeCheck` mode. During each step of `CheckTx`, a special [volatile state](#volatile-states) called `checkState` is updated. This state is used to keep track of the temporary changes triggered by the `CheckTx` calls of each transaction without modifying the [main canonical state](#main-state) . For example, when a transaction goes through `CheckTx`, the transaction's fees are deducted from the sender's account in `checkState`. If a second transaction is received from the same account before the first is processed, and the account has consumed all its funds in `checkState` during the first transaction, the second transaction will fail `CheckTx` and be rejected. In any case, the sender's account will not actually pay the fees until the transaction is actually included in a block, because `checkState` never gets committed to the main state. `checkState` is reset to the latest state of the main state each time a blocks gets [committed](#commit). `CheckTx` returns a response to the underlying consensus engine of type [`abci.ResponseCheckTx`](https://tendermint.com/docs/spec/abci/abci.html#messages). The response contains: @@ -249,7 +250,7 @@ During step 5., each read/write to the store increases the value of `GasConsumed `RunTx` is called from `CheckTx`/`DeliverTx` to handle the transaction, with `runTxModeCheck` or `runTxModeDeliver` as parameter to differentiate between the two modes of execution. Note that when `RunTx` receives a transaction, it has already been decoded. -The first thing `RunTx` does upon being called is to retrieve the `context`'s `CacheMultiStore` by calling the `getContextForTx()` function with the appropriate mode (either `runTxModeCheck` or `runTxModeDeliver`). This `CacheMultiStore` is a cached version of the main store instantiated during `BeginBlock` for `DeliverTx` and during the `Commit` of the previous block for `CheckTx`. After that, two `defer func()` are called for [`gas`](./accounts-fees.md#gas) management. They are executed when `runTx` returns and make sure `gas` is actually consumed, and will throw errors, if any. +The first thing `RunTx` does upon being called is to retrieve the `context`'s `CacheMultiStore` by calling the `getContextForTx()` function with the appropriate mode (either `runTxModeCheck` or `runTxModeDeliver`). This `CacheMultiStore` is a cached version of the main store instantiated during `BeginBlock` for `DeliverTx` and during the `Commit` of the previous block for `CheckTx`. After that, two `defer func()` are called for [`gas`](./accounts-fees-gas.md#gas) management. They are executed when `runTx` returns and make sure `gas` is actually consumed, and will throw errors, if any. After that, `RunTx` calls `ValidateBasic()` on each `message`in the `Tx`, which runs prelimary *stateless* validity checks. If any `message` fails to pass `ValidateBasic()`, `RunTx` returns with an error. @@ -279,19 +280,50 @@ First, it retreives the `message`'s `route` using the `Msg.Route()` method. Then ### InitChain -The `InitChain` ABCI message is sent from the underlying Tendermint engine when the chain is first started. +The [`InitChain` ABCI message](https://tendermint.com/docs/app-dev/abci-spec.html#initchain) is sent from the underlying Tendermint engine when the chain is first started. It is mainly used to **initialize** parameters and state like: + +- [Consensus Parameters](https://tendermint.com/docs/spec/abci/apps.html#consensus-parameters) via `setConsensusParams`. +- [`checkState` and `deliverState`](#volatile-states) via `setCheckState` and `setDeliverState`. +- The [block gas meter](../basics/accounts-fees-gas.md#block-gas-meter), with infinite gas to process genesis transactions. + +Finally, the `InitChain(req abci.RequestInitChain)` method of `baseapp` calls the [`initChainer()`](../basics/app-anatomy.md#initchainer) of the application in order to initialize the main state of the application from the [`genesis file`](./genesis.md) and, if defined, call the `InitGenesis` function of each of the application's modules. ### BeginBlock +The [`BeginBlock` ABCI message](#https://tendermint.com/docs/app-dev/abci-spec.html#beginblock) is sent from the underlying Tendermint engine when a block proposal created by the correct proposer is received, before [`DeliverTx`](#delivertx) is run for each transaction in the block. It allows developers to have logic be executed at the beginning of each block. In the Cosmos SDK, the `BeginBlock(req abci.RequestBeginBlock)` method does the following: + +- Initialize [`deliverState`](#volatile-states) with the latest header using the `req abci.RequestBeginBlock` passed as parameter via the [`setDeliverState`](https://github.com/cosmos/cosmos-sdk/blob/master/baseapp/baseapp.go#L283-L289) function. +- Initialize the [block gas meter](../basics/accounts-fees-gas.md#block-gas-meter) with the `maxGas` limit. The `gas` consumed within the block cannot go above `maxGas`. This parameter is defined in the application's consensus parameters. +- Run the application's [`begingBlocker()`](../basics/app-anatomy.md#beginblocker-and-endblock), which mainly runs the `BeginBlocker()` method of each of the application's modules. +- Set the [`VoteInfos`](https://tendermint.com/docs/app-dev/abci-spec.html#voteinfo) of the application, i.e. the list of validators whose *precommit* for the previous block was included by the proposer of the current block. This information is carried into the [`Context`](./context.md) so that it can be used during `DeliverTx` and `EndBlock`. + ### EndBlock +The [`EndBlock` ABCI message](#https://tendermint.com/docs/app-dev/abci-spec.html#endblock) is sent from the underlying Tendermint engine after [`DeliverTx`](#delivertx) as been run for each transactioni n the block. It allows developers to have logic be executed at the end of each block. In the Cosmos SDK, the bulk `EndBlock(req abci.RequestEndBlock)` method is to run the application's [`endBlocker()`](../basics/app-anatomy.md#beginblocker-and-endblock), which mainly runs the `EndBlocker()` method of each of the application's modules. + ### Commit +The [`Commit` ABCI message](https://tendermint.com/docs/app-dev/abci-spec.html#commit) is sent from the underlying Tendermint engine after the full-node has received *precommits* from 2/3+ of validators (weighted by voting power). On the `baseapp` end, the `Commit(res abci.ResponseCommit)` function is implemented to commit all the valid state transitions that occured during `BeginBlock`, `DeliverTx` and `EndBlock` and to reset state for the next block. + +To commit state-transitions, the `Commit` function calls the `Write()` function on `deliverState.ms`, where `deliverState.ms` is a cached multistore of the main store `app.cms`. Then, the `Commit` function sets `checkState` to the latest header (obtbained from `deliverState.ctx.BlockHeader`) and `deliverState` to `nil`. + +Finally, `Commit` returns the hash of the commitment of `app.cms` back to the underlying consensus engine. This hash is used as a reference in the header of the next block. + ### Info +The [`Info` ABCI message](https://tendermint.com/docs/app-dev/abci-spec.html#info) is a simple query from the underlying consensus engine, notably used to sync the latter with the application during a handshake that happens on startup. When called, the `Info(res abci.ResponseInfo)` function from `baseapp` will return the application's name, version and the hash of the last commit of `app.cms`. + ### Query +The [`Query` ABCI message](https://tendermint.com/docs/app-dev/abci-spec.html#query) is used to serve queries received from the underlying consensus engine, including queries received via RPC like Tendermint RPC. It is the main entrypoint to build interfaces with the application. The application must respect a few rules when implementing the `Query` method, which are outlined [here](https://tendermint.com/docs/app-dev/abci-spec.html#query). +The `baseapp` implementation of the `Query(req abci.RequestQuery)` method is a simple dispatcher serving 4 main categories of queries: +- Application-related queries like querying the application's version, which are served via the `handleQueryApp` method. +- Direct queries to the multistore, which are served by the `handlerQueryStore` method. These direct queryeis are different from custom queries which go through `app.queryRouter`, and are mainly used by third-party service provider like block explorers. +- P2P queries, which are served via the `handleQueryP2P` method. These queries return either `app.addrPeerFilter` or `app.ipPeerFilter` that contain the list of peers filtered by address or IP respectively. These lists are first initialized via `options` in `baseapp`'s [constructor](#constructor). +- Custom queries, which encompass most queries, are served via the `handleQueryCustom` method. The `handleQueryCustom` cache-wraps the multistore before using the `queryRoute` obtained from [`app.queryRouter`](#query-routing) to map the query to the appropriate module's [`querier`](../building-modules/querier.md). +## Next +Learn more about [stores](./store.md). \ No newline at end of file From 3496625dfd35b4e92c1d74a433070f7c52ba1663 Mon Sep 17 00:00:00 2001 From: gamarin Date: Fri, 5 Jul 2019 19:59:09 +0200 Subject: [PATCH 023/196] remove old files --- docs/concepts/app-anatomy.md | 258 ----------------------------- docs/concepts/encoding.md | 3 - docs/concepts/fees-signature.md | 7 - docs/concepts/genesis.md | 3 - docs/concepts/handler.md | 1 - docs/concepts/interfaces.md | 3 - docs/concepts/invariants.md | 5 - docs/concepts/keeper.md | 0 docs/concepts/module-interfaces.md | 5 - docs/concepts/modules.md | 8 - docs/concepts/node.md | 13 -- docs/concepts/querier.md | 3 - docs/concepts/tx-lifecycle.md | 0 13 files changed, 309 deletions(-) delete mode 100644 docs/concepts/app-anatomy.md delete mode 100644 docs/concepts/encoding.md delete mode 100644 docs/concepts/fees-signature.md delete mode 100644 docs/concepts/genesis.md delete mode 100644 docs/concepts/handler.md delete mode 100644 docs/concepts/interfaces.md delete mode 100644 docs/concepts/invariants.md delete mode 100644 docs/concepts/keeper.md delete mode 100644 docs/concepts/module-interfaces.md delete mode 100644 docs/concepts/modules.md delete mode 100644 docs/concepts/node.md delete mode 100644 docs/concepts/querier.md delete mode 100644 docs/concepts/tx-lifecycle.md diff --git a/docs/concepts/app-anatomy.md b/docs/concepts/app-anatomy.md deleted file mode 100644 index 3c6dca17cb9e..000000000000 --- a/docs/concepts/app-anatomy.md +++ /dev/null @@ -1,258 +0,0 @@ -# Anatomy of an SDK Application - -## Pre-requisite reading - -- [High-level overview of the architecture of an SDK application](../intro/sdk-app-architecture.md) -- [Cosmos SDK design overview](../intro/sdk-design.md) - -## Synopsis - -This document describes the core parts of a Cosmos SDK application. The placeholder name for this application will be `app`. - -- [Node Client](#node-client) -- [Core Application File](#core-application-file) -- [Modules](#modules) -- [Interfaces](#interfaces) -- [Dependencies and Makefile](#dependencies-and-makefile) - -The core parts listed above will generally translate to the following directory tree: - -``` -./app -├── cmd/ -│ ├── appd -│ └── appcli -├── app.go -├── x/ -│ ├── auth -│ ├── ... -│ └── bank -├── go.mod -└── Makefile -``` - -## Node Client - -The Daemon, or Full-Node Client, is the core process of an SDK-based blockchain. Participants in the network run this process to initialize their state-machine, connect with other full-nodes and update their state-machine as new blocks come in. - -``` - ^ +-------------------------------+ ^ - | | | | - | | State-machine = Application | | - | | | | Built with Cosmos SDK - | | ^ + | | - | +----------- | ABCI | ----------+ v - | | + v | ^ - | | | | -Blockchain Node | | Consensus | | - | | | | - | +-------------------------------+ | Tendermint Core - | | | | - | | Networking | | - | | | | - v +-------------------------------+ v -``` -The blockchain full-node presents itself as a binary, generally suffixed by `-d` for "daemon" (e.g. `appd` for `app` or `gaiad` for `gaia`). This binary is built by running a simple `main.go` function placed in `cmd/appd/`. This operation usually happens through the [Makefile](#dependencies-and-makefile). - -To learn more about the `main.go` function, [click here](./node.md#main-function). - -Once the main binary is built, the node can be started by running the `start` command. The core logic behind the `start` command is implemented in the SDK itself in the [`/server/start.go`](https://github.com/cosmos/cosmos-sdk/blob/master/server/start.go) file. The main [`start` command function](https://github.com/cosmos/cosmos-sdk/blob/master/server/start.go#L31) takes a [`context`](https://godoc.org/github.com/cosmos/cosmos-sdk/client/context) and [`appCreator`](#constructor-function-(`appCreator`)) as arguments. The `appCreator` is a constructor function for the SDK application, and is used in the starting process of the full-node. - -The `start` command function primarily does three things: - -1. Create an instance of the state-machine defined in [`app.go`](#core-application-file) using the `appCreator`. -2. Initialize the state-machine with the latest known state, extracted from the `db` stored in the `~/.appd/data` folder. At this point, the state-machine is at height `appBlockHeight`. -3. Create and start a new Tendermint instance. Among other things, the node will perform a handshake with its peers. It will get the latest `blockHeight` from them, and replay blocks to sync to this height if it is greater than the local `appBlockHeight`. If `appBlockHeight` is `0`, the node is starting from genesis and Tendermint sends an `InitChain` message via the ABCI to the `app`, which triggers the [`InitChainer`](#initchainer). - -To learn more about the `start` command, [click here](./node.md#start-command). - -## Core Application File - -In general, the core of the state-machine is defined in a file called `app.go`. It mainly contains the **type definition of the application** and functions to **create and initialize it**. - -### Type Definition of the Application - -The first thing defined in `app.go` is the `type` of the application. It is generally comprised of the following parts: - -- **A reference to [`baseapp`](./baseapp.md).** The custom application defined in `app.go` is an extension of the `baseapp` type. `baseapp` implements most of the core logic for the application, including all the [ABCI methods](https://tendermint.com/docs/spec/abci/abci.html#overview) and the routing logic. When a transaction is relayed by Tendermint to the application, the latter uses `baseapp`'s methods to route them to the appropriate module. -- **A list of store keys**. The [store](./store.md), which contains the entire state, is implemented as a multistore (i.e. a store of stores) in the Cosmos SDK. Each module uses one or multiple stores in the multistore to persist their part of the state. These stores can be accessed with specific keys that are declared in the `app` type. These keys, along with the `keepers`, are at the heart of the [object-capabilities model](../intro/ocap.md) of the Cosmos SDK. -- **A list of module's `keepers`.** Each module defines an abstraction called `keeper`, which handles reads and writes for this module's store(s). The `keeper`'s methods of one module can be called from other modules (if authorized), which is why they are declared in the application's type and exported as interfaces to other modules so that they are only allowed to access the authorized functions. -- **A reference to a `codec`.** The Cosmos SDK gives developers the freedom to choose the encoding framework for their application. The application's `codec` is used to serialize and deserialize data structures in order to store them, as stores can only persist `[]bytes`. The `codec` must be deterministic. The default codec is [amino](./amino.md). -- **A reference to a [module manager](./modules.md#module-manager)**. The module manager is an object that contains a list of the application's module. It facilitates operations related to these modules, like registering [`routes`](./baseapp.md#routing), [query routes](#./baseapp.md#query-routing) or setting the order of execution between modules for various functions like [`InitChainer`](#initchainer), [`BeginBlocker` and `EndBlocker`](#beginblocker-and-endblocker). - -You can see an example of application type definition [here](https://github.com/cosmos/gaia/blob/master/app/app.go#L73-L107). - -### Constructor Function - -This function constructs a new application of the type defined above. It is called every time the full-node is started with the [`start`](https://github.com/cosmos/cosmos-sdk/blob/master/server/start.go#L117) command. Here are the main actions performed by this function: - -- Instantiate a new application with a reference to a `baseapp` instance, a codec and all the appropriate store keys. -- Instantiate all the [`keeper`s](#keeper) defined in the application's `type` using the `NewKeeper` function of each of the application's modules. Note that `keepers` must be instantiated in the correct order, as the `NewKeeper` of one module might require a reference to another module's `keeper`. -- Instantiate the application's [module manager](./module-manager.md) with the [`AppModule`](#application-module-interface) object of each of the application's modules. -- With the module manager, initialize the application's [`routes`](./baseapp.md#routing) and [query routes](./baseapp.md#query-routing). When a transaction is relayed to the application by Tendermint via the ABCI, it is routed to the appropriate module's [`handler`](#handler) using the routes defined here. Likewise, when a query is received by the application, it is routed to the appropriate module's [`querier`](#querier) using the query routes defined here. -- With the module manager, register the [application's modules' invariants](./invariants.md). Invariants are variables (e.g. total supply of a token) that are evaluated at the end of each block. The process of checking invariants is done via a special module called the [`InvariantsRegistry`](./invariants.md#invariant-registry). The value of the invariant should be equal to a predicted value defined in the module. Should the value be different than the predicted one, special logic defined in the invariant registry will be triggered (usually the chain is halted). This is useful to make sure no critical bug goes unnoticed and produces long-lasting effects that would be hard to fix. -- With the module manager, set the order of execution between the `InitGenesis`, `BegingBlocker` and `EndBlocker` functions of each of the [application's modules](#application-module-interface). Note that not all modules implement these functions. -- Set the remainer of application's parameters: - + [`InitChainer`](#initchainer): used to initialize the application when it is first started. - + [`BeginBlocker`, `EndBlocker`](#beginblocker-and-endlbocker): called at the beginning and the end of every block). - + [`anteHandler`](#baseapp.md#antehandler): used to handle fees and signature verification. -- Mount the stores. -- Return the application. - -Note that this function only creates an instance of the app, while the actual state is either carried over from the `~/.appd/data` folder if the node is restarted, or generated from the genesis file if the node is started for the first time. - -You can see an example of application constructor [here](https://github.com/cosmos/gaia/blob/master/app/app.go#L110-L222). - -### InitChainer - -The `InitChainer` is a function that initializes the state of the application from a [genesis file](./genesis.md) (i.e. token balances of genesis accounts). It is called when the application receives the `InitChain` message from the Tendermint engine, which happens when the node is started at `appBlockHeight == 0` (i.e. on genesis). The application must set the `InitChainer` in its constructor via the [`SetInitChainer`](https://godoc.org/github.com/cosmos/cosmos-sdk/baseapp#BaseApp.SetInitChainer) method. - -In general, the `InitChainer` is mostly composed of the `InitGenesis` function of each of the application's modules. This is done by calling the `InitGenesis` function of the module manager, which in turn will call the `InitGenesis` function of each of the modules it contains. Note that the order in which the modules' `InitGenesis` functions must be called has to be set in the module manager using the `SetOrderInitGenesis` method. This is done in the [application's constructor](#application-constructor), and the `SetOrderInitGenesis` has to be called before the `SetInitChainer`. - -You can see an example of an `InitChainer` [here](https://github.com/cosmos/gaia/blob/master/app/app.go#L235-L239). - -### BeginBlocker and EndBlocker - -The SDK offers developers the possibility to implement automatic execution of code as part of their application. This is implemented through two function called `BeginBlocker` and `EndBlocker`. They are called when the application receives respectively the `BeginBlock` and `EndBlock` messages from the Tendermint engine, which happens at the beginning and at the end of each block. The application must set the `BeginBlocker` and `EndBlocker` in its constructor via the [`SetBeginBlocker`](https://godoc.org/github.com/cosmos/cosmos-sdk/baseapp#BaseApp.SetBeginBlocker) and [`SetEndBlocker`](https://godoc.org/github.com/cosmos/cosmos-sdk/baseapp#BaseApp.SetEndBlocker) methods. - -In general, the `BeginBlocker` and `EndBlocker` functions are mostly composed of the `BeginBlock` and `EndBlock` functions of each of the application's modules. This is done by calling the `BeginBlock` and `EndBlock` functions of the module manager, which in turn will call the `BeginBLock` and `EndBlock` functions of each of the modules it contains. Note that the order in which the modules' `BegingBlock` and `EndBlock` functions must be called has to be set in the module manager using the `SetOrderBeginBlock` and `SetOrderEndBlock` methods respectively. This is done in the [application's constructor](#application-constructor), and the `SetOrderBeginBlock` and `SetOrderEndBlock` methods have to be called before the `SetBeginBlocker` and `SetEndBlocker` functions. - -As a sidenote, it is important to remember that application-specific blockchains are deterministic. Developers must be careful not to introduce non-determinism in `BeginBlocker` or `EndBlocker`, and must also be careful not to make them too computationally expensive, as [gas](./fees-signature.md/gas) does not constrain the cost of `BeginBlocker` and `EndBlocker` execution. - -You can see an example of `BeginBlocker` and `EndBlocker` functions [here](https://github.com/cosmos/gaia/blob/master/app/app.go#L224-L232). - -### Register Codec - -The `MakeCodec` function is the last important function of the `app.go` file. The goal of this function is to instantiate a codec `cdc` (e.g. [amino](./amino.md)) initiliaze the codec of the SDK and each of the application's modules using the `RegisterCodec` function. - -To register the application's modules, the `MakeCodec` function calls `RegisterCodec` on `ModuleBasics`. `ModuleBasics` is a [basic manager](./modules.md#basic-manager) which lists all of the application's modules. It is instanciated in the `init()` function, and only serves to easily register non-dependant elements of application's modules (such as codec). To learn more about the basic module manager, click [here](./modules.md#basic-manager). - -You can see an example of a `MakeCodec` [here](https://github.com/cosmos/gaia/blob/master/app/app.go#L64-L70) - -## Modules - -Modules are the heart and soul of an SDK application. They can be considered as state-machines within the state-machine. When a transaction is relayed from the underlying Tendermint engine via the ABCI to the application, it is routed by `baseapp` to the appropriate module in order to be processed. This paradigm enables developers to easily build complex state-machines, as most of the modules they need often already exist. For developers, most of the work involved in building an SDK application revolves around building custom modules required by their application that do not exist, and integrating them with modules that do already exist into one coherent application. In the application directory, the standard practice is to store modules in the `x/` folder (not to be confused with the SDK's `x/` folder, which contains already-built modules). - -To learn more about modules, [click here](./modules.md) - -### Application Module Interface - -Modules implement two interfaces defined in the Cosmos SDK, [`AppModuleBasic`](https://github.com/cosmos/cosmos-sdk/blob/master/types/module/module.go#L44-L57) and [`AppModule`](https://github.com/cosmos/cosmos-sdk/blob/master/types/module/module.go#L44-L57). The former implements basic non-dependant elements of the module, such as the `codec`, while the latter handles the bulk of the module methods (including methods that require references to other modules' `keeper`s). Both the `AppModule` and `AppModuleBasic` types are defined in a file called `./module.go`. - -`AppModule` exposes a collection of useful methods on the module that facilitates the composition of modules into a coherent application. Important methods include: - -- `Route()` and `QueryRoute()`: These methods the name of the route and querier route for the module, for [messages](#message-types) to be routed to the module's [`handler`](#handler) and queries to be routes to the module's [`querier`](#querier). -- `NewHandler()` and `NewQuerierHandler()`: These methods return a `handler` and `querierHandler` respectively, in order to process a message or a query once they are routed. -- `BeginBlock()`, `EndBlock()` and `InitGenesis()`: These methods are executed respectively at the beginning of each block, at the end of each block and at the start of the chain. They implement special logic the module requires to be triggered during those events. For example, the `EndBlock` function is frequently used by modules where voting occurs to tally the result of the votes. -- `RegisterInvariants()`: This method registers the [invariants](./invariants.md) for the module. Invariants are checked at the end of every block to make sure no unpredicted behaviour is occuring. - -`AppModule`'s methods are called from the `module manager`(./modules.md#module-manager), which manages the application's collection of modules. - -To learn more about the application module interface, [click here](./modules.md#application-module-interface). - -### Message Types - -A message is a custom type defined by each module that implements the [`message`](https://github.com/cosmos/cosmos-sdk/blob/master/types/tx_msg.go#L8-L29) interface. Each `transaction` contains one or multiple `messages`. When a valid block of transactions is received by the full-node, Tendermint relays each one to the application via [`DeliverTx`](https://tendermint.com/docs/app-dev/abci-spec.html#delivertx). Then, the application handles the transaction: - -1. Upon receiving the transaction, the application first unmarshalls it from `[]bytes`. -2. Then, it verifies a few things about the transaction like [fee payment and signatures](#fees-signature.md) before extracting the message(s) contained in the transaction. -3. With the [`Type()`](https://github.com/cosmos/cosmos-sdk/blob/master/types/tx_msg.go#L16) method, `baseapp` is able to know which modules defines the message. It is then able to route it to the appropriate module's [handler](#handler) in order for the message to be processed. -4. If the message is successfully processed, the state is updated. - -For a more detailed look at a transaction lifecycle, click [here](./tx-lifecycle.md). - -Module developers create custom message types when they build their own module. The general practice is to prefix the type declaration of the message with `Msg`. For example, the message type [`MsgSend`](https://github.com/cosmos/cosmos-sdk/blob/master/x/bank/types/msgs.go#L10-L15) allows users to transfer tokens. It is processed by the handler of the `bank` module, which ultimately calls the `keeper` of the `auth` module in order to update the state. - -To learn more about messages, [click here](./tx-msgs.md). - -### Handler - -The `handler` refers to the part of the module responsible for processing the message after it is routed by `baseapp`. `handler` functions of modules (except those of the `auth` module) are only executed if the transaction is relayed from Tendermint by the `DeliverTx` ABCI message. If the transaction is relayed by `CheckTx`, only stateless checks and fee-related (i.e. `auth` module-related) stateful checks are performed. To better understand the difference between `DeliverTx`and `CheckTx`, as well as the difference between stateful and stateless checks, click [here](./tx-lifecycle.md). - -The handler of a module is generally defined in a file called `handler.go` and consists of: - -- A **switch function** `NewHandler` to route the message to the appropriate handler function. This function returns a `handler` function, and is registered in the [`AppModule`](#application-module-interface) to be used in the application's module manager to initialize the [application's router](./baseapp.md#routing). See an example of such a switch [here](https://github.com/cosmos/sdk-application-tutorial/blob/master/x/nameservice/handler.go#L10-L22). -- **One handler function for each message type defined by the module**. Developers write the message processing logic in these functions. This generally involves doing stateful checks to ensure the message is valid and calling [`keeper`](#keeper)'s methods to update the state. - -Handler functions return a result of type [`sdk.Result`](https://github.com/cosmos/cosmos-sdk/blob/master/types/result.go#L14-L37), which informs the application on whether the message was successfully processed. - -To learn more about handlers, [click here](./handler.md). - -### Keeper - -`Keepers` are the gatekeepers of their module's store(s). To read or write in a module's store, it is mandatory to go through one of its `keeper`'s methods. This is ensured by the [object-capabilities](./ocap.md) model of the Cosmos SDK. Only objects that hold the key to a store can access it, and only the module's `keeper` should hold the key(s) to the module's store(s). - -`Keepers` are generally defined in a file called `keeper.go`. It contains the `keeper`'s type definition and methods. - -The `keeper` type definition generally consists of: - -- **Key(s)** to the module's store(s) in the multistore. -- Reference to **other module's `keepers`**. Only needed if the `keeper` needs to access other module's store(s) (either to read or write from them). -- A reference to the application's **codec**. The `keeper` needs it to marshal structs before storing them, or to unmarshal them when it retrieves them, because stores only accept `[]bytes` as value. - -Along with the type definition, the next important component of the `keeper.go` file is the `keeper`'s constructor function, `NewKeeper`. This function instantiates a new `keeper` of the type defined above, with a `codec`, store `keys` and potentially references to other modules' `keeper`s as parameters. The `NewKeeper` function is called from the [application's constructor](#constructor-function). - -The rest of the file defines the `keeper`'s methods, primarily getters and setters. You can check an example of a `keeper` implementation [here](https://github.com/cosmos/sdk-application-tutorial/blob/master/x/nameservice/keeper.go). - -To learn more about `keepers`, [click here](./keeper.md). - -### Querier - -`Queriers` are very similar to `handlers`, except they serve user queries to the state as opposed to processing transactions. A query is initiated from an [interface](#intefaces) by an end-user who provides a `queryRoute` and some `data`. The query is then routed to the correct application's `querier` by `baseapp`'s [`handleQueryCustom`](https://github.com/cosmos/cosmos-sdk/blob/master/baseapp/baseapp.go#L519-L556) method using `queryRoute`. - -The `Querier` of a module is defined in a file called `querier.go`, and consists of: - -- A **switch function** `NewQuerier` to route the query to the appropriate `querier` function. This function returns a `querier` function, and is is registered in the [`AppModule`](#application-module-interface) to be used in the application's module manager to initialize the [application's query router](./baseapp.md#query-routing). See an example of such a switch [here](https://github.com/cosmos/sdk-application-tutorial/blob/master/x/nameservice/querier.go#L21-L34). -- - **One querier function for each data type defined by the module that needs to be queryable**. Developers write the query processing logic in these functions. This generally involves calling [`keeper`](#keeper)'s methods to query the state and marshalling it to JSON. See an example of `querier` functions [here](https://github.com/cosmos/sdk-application-tutorial/blob/master/x/nameservice/querier.go#L37-L101). - -To learn more about `queriers`, [click here](./querier.md). - -### Command-Line and REST Interfaces - -Each module defines command-line commands and REST routes to be exposed to end-user via the [application's interfaces](#application-interfaces). This enables end-users to create messages of the types defined in the module, or to query the subset of the state managed by the module. - -#### CLI - -Generally, the commands related to a module are defined in a folder called `client/cli` in the module's folder. The CLI divides commands in two category, transactions and queries, defined in `client/cli/tx.go` and `client/cli/query.go` respectively. Both commands are built on top of the [Cobra Library](https://github.com/spf13/cobra): - -- Transactions commands let users generate new transactions so that they can be included in a block and eventually update the state. One command should be created for each [message type](#message-types) defined in the module. The command calls the constructor of the message with the parameters provided by the end-user, and wraps it into a transaction. The SDK handles signing and the addition of other transaction metadata. See examples of transactions commands [here](https://github.com/cosmos/sdk-application-tutorial/blob/master/x/nameservice/client/cli/tx.go). -- Queries let users query the subset of the state defined by the module. Query commands forward queries to the [application's query router](./baseapp.md#query-routing), which routes them to the appropriate [querier](#querier) the `queryRoute` parameter supplied. See examples of query commands [here](https://github.com/cosmos/sdk-application-tutorial/blob/master/x/nameservice/client/cli/query.go). - -To learn more about modules CLI, [click here](./module-interfaces.md#cli). - -#### REST - -The module's REST interface lets users generate transactions and query the state through REST calls to the application's [light client daemon](./node.md#lcd) (LCD). REST routes are defined in a file `client/rest/rest.go`, which is composed of: - -- A `RegisterRoutes` function, which registers each route defined in the file. This function is called from the [main application's interface](#application-interfaces) for each module used within the application. The router used in the SDK is [Gorilla's mux](https://github.com/gorilla/mux). -- Custom request type definitions for each query or transaction creation function that needs to be exposed. These custom request types build on the [base `request` type](https://github.com/cosmos/cosmos-sdk/blob/master/types/rest/rest.go#L32-L43) of the Cosmos SDK. -- One handler function for each request that can be routed to the given module. These functions implement the core logic necessary to serve the request. - -See an example of a module's `rest.go` file [here](https://github.com/cosmos/sdk-application-tutorial/blob/master/x/nameservice/client/rest/rest.go). - -To learn more about modules REST interface, [click here](./module-interfaces.md#rest). - -## Application Interface - -Interfaces let end-users interact with full-node clients. This means querying data from the full-node or creating and sending new transactions to be relayed by the full-node and eventually included in a block. - -The main interface is the [Command-Line Interface](./interfaces.md#cli). The CLI of an SDK application is built by aggregating [CLI commands](#cli) defined in each of the modules used by the application. The CLI of an application generally has the `-cli` suffix (e.g. `appcli`), and defined in a file called `cmd/appcli/main.go`. The file contains: - -- **A `main()` function**, which is executed to build the `appcli` interface client. This function prepares each command and adds them to the `rootCmd` before building them. At the root of `appCli`, the function adds generic commands like `status`, `keys` and `config`, query commands, tx commands and `rest-server`. -- **Query commands** are added by calling the `queryCmd` function, also defined in `appcli/main.go`. This function returns a Cobra command that contains the query commands defined in each of the application's modules (passed as an array of `sdk.ModuleClients` from the `main()` function), as well as some other lower level query commands such as block or validator queries. Query command are called by using the command `appcli query [query]` of the CLI. -- **Transaction commands** are added by calling the `txCmd` function. Similar to `queryCmd`, the function returns a Cobra command that contains the tx commands defined in each of the application's modules, as well as lower level tx commands like transaction signing or broadcasting. Tx commands are called by using the command `appcli tx [tx]` of the CLI. -- **A `registerRoutes` function**, which is called from the `main()` function when initializing the [application's light-client daemon (LCD)](./node.md#lcd) (i.e. `rest-server`). `registerRoutes` calls the `RegisterRoutes` function of each of the application's module, thereby registering the routes of the module to the lcd's router. The LCD can be started by running the following command `appcli rest-server`. - -See an example of an application's main command-line file [here](https://github.com/cosmos/sdk-application-tutorial/blob/master/cmd/nscli/main.go). - -To learn more about interfaces, [click here](./interfaces.md). - -## Dependencies and Makefile - -This section is optional, as developers are free to choose their depencency manager and project building method. That said, the current most used framework for versioning control is [`go.mod`](https://github.com/golang/go/wiki/Modules). It ensures each of the libraries used throughout the application are imported with the correct version. An example can be found [here](https://github.com/cosmos/sdk-application-tutorial/blob/master/go.mod). - -For building the application, a [Makefile](https://en.wikipedia.org/wiki/Makefile) is generally used. The Makefile primarily ensures that the `go.mod` is run before building the two entrypoints to the application, [`appd`](#node-client) and [`appcli`](#application-interface). An example of Makefile can be found [here](https://github.com/cosmos/sdk-application-tutorial/blob/master/Makefile). - -## Next - -Learn more about the [Lifecycle of a transaction](./tx-lifecycle.md). diff --git a/docs/concepts/encoding.md b/docs/concepts/encoding.md deleted file mode 100644 index 1dcfba3b2313..000000000000 --- a/docs/concepts/encoding.md +++ /dev/null @@ -1,3 +0,0 @@ -# Encoding - -TODO \ No newline at end of file diff --git a/docs/concepts/fees-signature.md b/docs/concepts/fees-signature.md deleted file mode 100644 index 36982a97b5d8..000000000000 --- a/docs/concepts/fees-signature.md +++ /dev/null @@ -1,7 +0,0 @@ -# Fees and Signatures - -## Signatures - -## Fees - -## Gas \ No newline at end of file diff --git a/docs/concepts/genesis.md b/docs/concepts/genesis.md deleted file mode 100644 index 5e3dbd31dcad..000000000000 --- a/docs/concepts/genesis.md +++ /dev/null @@ -1,3 +0,0 @@ -# Genesis File - -TODO \ No newline at end of file diff --git a/docs/concepts/handler.md b/docs/concepts/handler.md deleted file mode 100644 index f8fc820df8de..000000000000 --- a/docs/concepts/handler.md +++ /dev/null @@ -1 +0,0 @@ -# Handlers \ No newline at end of file diff --git a/docs/concepts/interfaces.md b/docs/concepts/interfaces.md deleted file mode 100644 index bb580a5cf171..000000000000 --- a/docs/concepts/interfaces.md +++ /dev/null @@ -1,3 +0,0 @@ -# Interfaces - -TODO \ No newline at end of file diff --git a/docs/concepts/invariants.md b/docs/concepts/invariants.md deleted file mode 100644 index 18cd9ad6224f..000000000000 --- a/docs/concepts/invariants.md +++ /dev/null @@ -1,5 +0,0 @@ -# Invariants - -## What is an invariant - -## Invariant Registry \ No newline at end of file diff --git a/docs/concepts/keeper.md b/docs/concepts/keeper.md deleted file mode 100644 index e69de29bb2d1..000000000000 diff --git a/docs/concepts/module-interfaces.md b/docs/concepts/module-interfaces.md deleted file mode 100644 index 0cd27c895326..000000000000 --- a/docs/concepts/module-interfaces.md +++ /dev/null @@ -1,5 +0,0 @@ -# Module Interfaces - -## CLI - -## REST \ No newline at end of file diff --git a/docs/concepts/modules.md b/docs/concepts/modules.md deleted file mode 100644 index 5c65c4d89f92..000000000000 --- a/docs/concepts/modules.md +++ /dev/null @@ -1,8 +0,0 @@ -# SDK Modules - -Todo: Intro concept docs on modules - -## Application Module Interface - -## Module Manager - diff --git a/docs/concepts/node.md b/docs/concepts/node.md deleted file mode 100644 index 85c6152542ad..000000000000 --- a/docs/concepts/node.md +++ /dev/null @@ -1,13 +0,0 @@ -# Node Client (Daemon) - -## Pre-Requisite Reading - -## `main` function - -TODO - -## `start` command - -TODO - -## Light-Client Daemon (LCD) diff --git a/docs/concepts/querier.md b/docs/concepts/querier.md deleted file mode 100644 index 3afa9f0cc308..000000000000 --- a/docs/concepts/querier.md +++ /dev/null @@ -1,3 +0,0 @@ -# Queriers - -TODO \ No newline at end of file diff --git a/docs/concepts/tx-lifecycle.md b/docs/concepts/tx-lifecycle.md deleted file mode 100644 index e69de29bb2d1..000000000000 From c90c9971e6ce4ac0d39a31d94f1907802b0781c7 Mon Sep 17 00:00:00 2001 From: gamarin Date: Wed, 10 Jul 2019 14:59:56 +0200 Subject: [PATCH 024/196] module doc start --- docs/building-modules.md/modules.md | 27 +++++++++++++++++++++++++-- 1 file changed, 25 insertions(+), 2 deletions(-) diff --git a/docs/building-modules.md/modules.md b/docs/building-modules.md/modules.md index 5c65c4d89f92..249162183a5c 100644 --- a/docs/building-modules.md/modules.md +++ b/docs/building-modules.md/modules.md @@ -1,6 +1,29 @@ -# SDK Modules +# Modules and Module Manager -Todo: Intro concept docs on modules +## Pre-requisite Reading + +- [Anatomy of an SDK application](../basics/app-anatomy.md) +- [Lifecycle of an SDK transaction](../basics/tx-lifecycle.md) + +## Synopsis + +Modules define most of the logic of any SDK application. Developers compose module together to build their custom application-specific blockchains. This document outlines the basic concepts behind SDK modules and how to approach module management. + +- [Role of Modules in an SDK application](#role-of-modules-in-an-sdk-application) +- [How to Approach Building Modules as a Developer](#how-to-approach-building-modules-as-a-developer) +- [Application Module Interface](#application-module-interface) +- [Module Manager](#module-manager) + +## Role of Modules in an SDK Application + +The Cosmos SDK can be thought as the Ruby-on-Rails of blockchain development. It comes with a core that provides the basic functionalities every blockchain application need, like a boilerplate implementation of the ABCI to communicate with the underlying consensus engine, a multistore to persist state, a server to form a full-node and interfaces to handle queries. + +## How to Approach Building Modules as a Developer + +Composability +Separation of concern/specialization +ocap +x/ ## Application Module Interface From 1239fcbed5959eea314315251b575e481f3d4b72 Mon Sep 17 00:00:00 2001 From: gamarin Date: Thu, 11 Jul 2019 18:43:04 +0200 Subject: [PATCH 025/196] finish intro --- docs/building-modules.md/module-interfaces.md | 5 - docs/building-modules.md/modules.md | 31 ------ .../README.md | 0 .../handler.md | 0 docs/building-modules/intro.md | 95 +++++++++++++++++++ .../invariants.md | 0 .../keeper.md | 0 docs/building-modules/module-interfaces.md | 5 + docs/building-modules/modules-manager.md | 6 ++ .../querier.md | 0 docs/core/baseapp.md | 8 +- 11 files changed, 110 insertions(+), 40 deletions(-) delete mode 100644 docs/building-modules.md/module-interfaces.md delete mode 100644 docs/building-modules.md/modules.md rename docs/{building-modules.md => building-modules}/README.md (100%) rename docs/{building-modules.md => building-modules}/handler.md (100%) create mode 100644 docs/building-modules/intro.md rename docs/{building-modules.md => building-modules}/invariants.md (100%) rename docs/{building-modules.md => building-modules}/keeper.md (100%) create mode 100644 docs/building-modules/module-interfaces.md create mode 100644 docs/building-modules/modules-manager.md rename docs/{building-modules.md => building-modules}/querier.md (100%) diff --git a/docs/building-modules.md/module-interfaces.md b/docs/building-modules.md/module-interfaces.md deleted file mode 100644 index 0cd27c895326..000000000000 --- a/docs/building-modules.md/module-interfaces.md +++ /dev/null @@ -1,5 +0,0 @@ -# Module Interfaces - -## CLI - -## REST \ No newline at end of file diff --git a/docs/building-modules.md/modules.md b/docs/building-modules.md/modules.md deleted file mode 100644 index 249162183a5c..000000000000 --- a/docs/building-modules.md/modules.md +++ /dev/null @@ -1,31 +0,0 @@ -# Modules and Module Manager - -## Pre-requisite Reading - -- [Anatomy of an SDK application](../basics/app-anatomy.md) -- [Lifecycle of an SDK transaction](../basics/tx-lifecycle.md) - -## Synopsis - -Modules define most of the logic of any SDK application. Developers compose module together to build their custom application-specific blockchains. This document outlines the basic concepts behind SDK modules and how to approach module management. - -- [Role of Modules in an SDK application](#role-of-modules-in-an-sdk-application) -- [How to Approach Building Modules as a Developer](#how-to-approach-building-modules-as-a-developer) -- [Application Module Interface](#application-module-interface) -- [Module Manager](#module-manager) - -## Role of Modules in an SDK Application - -The Cosmos SDK can be thought as the Ruby-on-Rails of blockchain development. It comes with a core that provides the basic functionalities every blockchain application need, like a boilerplate implementation of the ABCI to communicate with the underlying consensus engine, a multistore to persist state, a server to form a full-node and interfaces to handle queries. - -## How to Approach Building Modules as a Developer - -Composability -Separation of concern/specialization -ocap -x/ - -## Application Module Interface - -## Module Manager - diff --git a/docs/building-modules.md/README.md b/docs/building-modules/README.md similarity index 100% rename from docs/building-modules.md/README.md rename to docs/building-modules/README.md diff --git a/docs/building-modules.md/handler.md b/docs/building-modules/handler.md similarity index 100% rename from docs/building-modules.md/handler.md rename to docs/building-modules/handler.md diff --git a/docs/building-modules/intro.md b/docs/building-modules/intro.md new file mode 100644 index 000000000000..3f9253cda1dc --- /dev/null +++ b/docs/building-modules/intro.md @@ -0,0 +1,95 @@ +# Introduction to SDK Modules + +## Pre-requisite Reading + +- [Anatomy of an SDK application](../basics/app-anatomy.md) +- [Lifecycle of an SDK transaction](../basics/tx-lifecycle.md) + +## Synopsis + +Modules define most of the logic of any SDK application. Developers compose module together to build their custom application-specific blockchains. This document outlines the basic concepts behind SDK modules and how to approach module management. + +- [Role of Modules in an SDK application](#role-of-modules-in-an-sdk-application) +- [How to Approach Building Modules as a Developer](#how-to-approach-building-modules-as-a-developer) +- [Application Module Interface](#application-module-interface) +- [Module Manager](#module-manager) + +## Role of Modules in an SDK Application + +The Cosmos SDK can be thought as the Ruby-on-Rails of blockchain development. It comes with a core that provides the basic functionalities every blockchain application need, like a boilerplate implementation of the ABCI to communicate with the underlying consensus engine, a multistore to persist state, a server to form a full-node and interfaces to handle queries. + +On top of this core, the SDK enables developers to build modules that implement the business logic of their application. In other words, SDK modules implement the bulk of the logic of applications, while the core does the wiring and enables modules to be composed together. The end goal is to build a robust ecosystem of open-source SDK modules, making it increasingly easier to build complex blockchain applications. + +SDK Modules can be seen as little state-machines within the state-machine. They generally define a subset of the state using one ore multiple `KVStore` in the [main multistore](../core/store.md), as well as a subset of [`message` types](./message.md). These `message`s are routed by one of the main component of SDK core, [`baseapp`](../core/baseapp.md), to the [`handler`](./handler.md) of the module that define them. + +``` + + + | + | Transaction relayed from the full-node's consensus engine + | to the node's application via DeliverTx + | + | + | + +---------------------v--------------------------+ + | APPLICATION | + | | + | Using baseapp's methods: Decode the Tx, | + | extract and route the message(s) | + | | + +---------------------+--------------------------+ + | + | + | + +---------------------------+ + | + | + | + | Message routed to the correct + | module to be processed + | + | ++----------------+ +---------------+ +----------------+ +------v----------+ +| | | | | | | | +| AUTH MODULE | | BANK MODULE | | STAKING MODULE | | GOV MODULE | +| | | | | | | | +| | | | | | | Handles message,| +| | | | | | | Updates state | +| | | | | | | | ++----------------+ +---------------+ +----------------+ +------+----------+ + | + | + | + | + +--------------------------+ + | + | Return result to the underlying consensus engine (e.g. Tendermint) + | (0=Ok, 1=Err) + v +``` + +As a result of this architecture, building an SDK application usually revolves around writing modules to implement the specialized logic of the application, and composing them with existing modules to complete the application. Developers will generally work on modules that implement logic needed for their specific use case that do not exist yet, and will use existing modules for more generic functionalities like staking, accounts or token management. + +## How to Approach Building Modules as a Developer + +While there is no definitive guidelines for writing modules, here are some important design principles developers should keep in mind when building them: + +- **Composability**: SDK applications are almost always composed of multiple modules. This means developers need to carefully consider the integration of their module not only with the core of the Cosmos SDK, but also with other modules. The former is achieved by following standard design patterns outlined [here](#main-components-of-sdk-modules), while the latter is achieved by properly exposing the store(s) of the module via the [`keeper`](./keeper.md). +- **Specialization**: A direct consequence of the **composability** feature is that modules should be **specialized**. Developers should carefully establish the scope of their module and not batch multiple functionalities into the same module. This separation of concern enables modules to be re-used in other projects and improves the upgradability of the application. **Specialization** also plays an important role in the [object-capabilities model](../core/ocap.md) of the Cosmos SDK. +- **Capabilities**: Most modules need to read and/or write to the store(s) of other modules. However, in an open-source environment, it is possible for some module to be malicious. That is why module developers need to carefully think not only about how their module interracts with other modules, and how to give access to the module's store(s). The Cosmos SDK takes a capabilities-oriented approach to inter-module security. This means that each store defined by a module is accessed by a `key`, which is held by the module's [`keeper`](./keeper.md). This `keeper` defines how to access the store(s) and under what conditions. Access to the module's store(s) is done by passing a reference to the module's `keeper`. + +## Main Components of SDK Module + +Modules generally share the same core components: + +- Custom [`message` types](./message.md) to trigger state-transitions. +- A [`handler`](./handler.md) used to process messages when they are routed to the module by [`baseapp`](../core/baseapp.md#message-routing). +- A [`keeper`](./keeper.md), used to access the module's store(s) and update the state. +- A [`querier`](./querier.md), used to process user queries when they are routed to the module by [`baseapp`](../core/baseapp.md#query-routing). +- Interfaces, for end users to query the subset of the state defined by the module and create `message`s of the custom types defined in the module. + +In addition to these components, modules implement the `module` interface in order to be managed by the [`module manager`](./module-manager.md). + +## Next + +Read more on the [`module interface` and the `module manager`](./module-manager.md) + diff --git a/docs/building-modules.md/invariants.md b/docs/building-modules/invariants.md similarity index 100% rename from docs/building-modules.md/invariants.md rename to docs/building-modules/invariants.md diff --git a/docs/building-modules.md/keeper.md b/docs/building-modules/keeper.md similarity index 100% rename from docs/building-modules.md/keeper.md rename to docs/building-modules/keeper.md diff --git a/docs/building-modules/module-interfaces.md b/docs/building-modules/module-interfaces.md new file mode 100644 index 000000000000..5c2d158bbc94 --- /dev/null +++ b/docs/building-modules/module-interfaces.md @@ -0,0 +1,5 @@ +# Module Manager + +## Application Module Interface + +## Module Manager \ No newline at end of file diff --git a/docs/building-modules/modules-manager.md b/docs/building-modules/modules-manager.md new file mode 100644 index 000000000000..c10974af7609 --- /dev/null +++ b/docs/building-modules/modules-manager.md @@ -0,0 +1,6 @@ +# Module Manager + +## Application Module Interface + +## Module Manager + diff --git a/docs/building-modules.md/querier.md b/docs/building-modules/querier.md similarity index 100% rename from docs/building-modules.md/querier.md rename to docs/building-modules/querier.md diff --git a/docs/core/baseapp.md b/docs/core/baseapp.md index 1f0d6ead44ae..12aabb3bb735 100644 --- a/docs/core/baseapp.md +++ b/docs/core/baseapp.md @@ -34,7 +34,7 @@ This document describes `baseapp`, the abstraction that implements most of the c `baseapp` is an abstraction that implements the core of an SDK application, namely: - The [Application-Blockchain Interface](#abci), for the state-machine to communicate with the underlying consensus engine (e.g. Tendermint). -- A [Router](#routing), to route [messages](./tx-msgs.md) and [queries](./querier.md) to the appropriate [module](../building-modules/modules.md). +- A [Router](#routing), to route [messages](./tx-msgs.md) and [queries](./querier.md) to the appropriate [module](../building-modules/intro.md). - Different [states](#states), as the state-machine can have different parallel states updated based on the ABCI message received. The goal of `baseapp` is to provide a boilerplate SDK application that developers can easily extend to build their own custom application. Usually, developers will create a custom type for their application, like so: @@ -175,13 +175,13 @@ When messages and queries are received by the application, they must be routed t Messages need to be routed after they are extracted from transactions, which are sent from the underlying Tendermint engine via the [`CheckTx`](#checktx) and [`DeliverTx`](#delivertx) ABCI messages. To do so, `baseapp` holds a [`router`](https://github.com/cosmos/cosmos-sdk/blob/master/baseapp/router.go) which maps `paths` (`string`) to the appropriate module [`handler`](./handler.md). Usually, the `path` is the name of the module. -The application's `router` is initilalized with all the routes using the application's [module manager](./modules.md#module-manager), which itself is initialized with all the application's modules in the application's [constructor](../basics/app-anatomy.md#app-constructor). +The application's `router` is initilalized with all the routes using the application's [module manager](../building-modules/module-manager.md), which itself is initialized with all the application's modules in the application's [constructor](../basics/app-anatomy.md#app-constructor). ### Query Routing Similar to messages, queries need to be routed to the appropriate module's [querier](./querier.md). To do so, `baseapp` holds a [`query router`](https://github.com/cosmos/cosmos-sdk/blob/master/baseapp/queryrouter.go), which maps `paths` (`string`) to the appropriate module [`querier`](./querier.md). Usually, the `path` is the name of the module. -Just like the `router`, the `query router` is initilalized with all the query routes using the application's [module manager](./modules.md#module-manager), which itself is initialized with all the application's modules in the application's [constructor](../basics/app-anatomy.md#app-constructor). +Just like the `router`, the `query router` is initilalized with all the query routes using the application's [module manager](../building-modules/module-manager.md), which itself is initialized with all the application's modules in the application's [constructor](../basics/app-anatomy.md#app-constructor). ## Main ABCI Messages @@ -274,7 +274,7 @@ The `AnteHandler` is theoretically optional, but still a very important componen `RunMsgs` is called from `RunTx` with `runTxModeCheck` as parameter to check the existence of a route for each message the transaction, and with `runTxModeDeliver` to actually process the `message`s. -First, it retreives the `message`'s `route` using the `Msg.Route()` method. Then, using the application's [`router`](#routing) and the `route`, it checks for the existence of a `handler`. At this point, if `mode == runTxModeCheck`, `RunMsgs` returns. If instead `mode == runTxModeDeliver`, the [`handler`](../building-modules.md#handler) function for the message is executed, before `RunMsgs` returns. +First, it retreives the `message`'s `route` using the `Msg.Route()` method. Then, using the application's [`router`](#routing) and the `route`, it checks for the existence of a `handler`. At this point, if `mode == runTxModeCheck`, `RunMsgs` returns. If instead `mode == runTxModeDeliver`, the [`handler`](../building-modules/handler.md) function for the message is executed, before `RunMsgs` returns. ## Other ABCI Messages From a2e24e8e559fad77da3c264f3e014d3835cc5b4f Mon Sep 17 00:00:00 2001 From: gamarin Date: Mon, 15 Jul 2019 11:48:06 +0200 Subject: [PATCH 026/196] working --- docs/building-modules/intro.md | 6 ++-- docs/building-modules/module-interfaces.md | 6 ++-- docs/building-modules/modules-manager.md | 33 ++++++++++++++++++++-- docs/core/baseapp.md | 4 +-- 4 files changed, 39 insertions(+), 10 deletions(-) diff --git a/docs/building-modules/intro.md b/docs/building-modules/intro.md index 3f9253cda1dc..403eb755a2a2 100644 --- a/docs/building-modules/intro.md +++ b/docs/building-modules/intro.md @@ -79,7 +79,7 @@ While there is no definitive guidelines for writing modules, here are some impor ## Main Components of SDK Module -Modules generally share the same core components: +Modules are by convention defined in the `.x/` subfolder (e.g. the `bank` module will be defined in the `./x/bank` folder). They generally share the same core components: - Custom [`message` types](./message.md) to trigger state-transitions. - A [`handler`](./handler.md) used to process messages when they are routed to the module by [`baseapp`](../core/baseapp.md#message-routing). @@ -87,9 +87,9 @@ Modules generally share the same core components: - A [`querier`](./querier.md), used to process user queries when they are routed to the module by [`baseapp`](../core/baseapp.md#query-routing). - Interfaces, for end users to query the subset of the state defined by the module and create `message`s of the custom types defined in the module. -In addition to these components, modules implement the `module` interface in order to be managed by the [`module manager`](./module-manager.md). +In addition to these components, modules implement the `AppModule` interface in order to be managed by the [`module manager`](./module-manager.md). ## Next -Read more on the [`module interface` and the `module manager`](./module-manager.md) +Read more on the [`AppModule` interface and the `module manager`](./module-manager.md) diff --git a/docs/building-modules/module-interfaces.md b/docs/building-modules/module-interfaces.md index 5c2d158bbc94..0cd27c895326 100644 --- a/docs/building-modules/module-interfaces.md +++ b/docs/building-modules/module-interfaces.md @@ -1,5 +1,5 @@ -# Module Manager +# Module Interfaces -## Application Module Interface +## CLI -## Module Manager \ No newline at end of file +## REST \ No newline at end of file diff --git a/docs/building-modules/modules-manager.md b/docs/building-modules/modules-manager.md index c10974af7609..e84587ff5c69 100644 --- a/docs/building-modules/modules-manager.md +++ b/docs/building-modules/modules-manager.md @@ -1,6 +1,35 @@ -# Module Manager +# Module Manager and `AppModule` Interface -## Application Module Interface +## Pre-requisite Reading + +- [Introduction to SDK Modules](./intro.md) + +## Synopsis + +Cosmos SDK modules need to implement the [`AppModule` interfaces](#application-module-interfaces), in order to be managed by the application's [module manager](#module-manager). The module manager plays an important role in [`message` and `query` routing](../core/baseapp.md#routing), and allows the application developer to set the order of execution of a variety of functions like [`BeginBlocker` and `EndBlocker`](../basics/app-anatomy.md#begingblocker-and-endblocker). + +## Application Module Interfaces + +[Application module interfaces](https://github.com/cosmos/cosmos-sdk/blob/master/types/module/module.go) exist to facilitate the composition of modules together to form a functional SDK application. There are 3 main application module interfaces: + +- [`AppModuleBasic`](#appmodulebasic) for independent module functionalities. +- [`AppModule`](#appmodule) for inter-dependent module functionalities (except genesis-related functionalities). +- [`AppModuleGenesis`](#appmodulegenesis) for inter-dependent genesis-related module functionalities. + +The `AppModuleBasic` interface exists to define independent methods of the module, i.e. those that do not depend on other modules in the application. This allows for the construction of the basic application structure early in the application definition, generally in the `init()` function of the [main application file](../basics/app-antomy.md#core-application-file). + +The `AppModule` interface exists to define inter-dependent module methods. Many modules need to interract with other modules, typically through [`keeper`s](./keeper.md), which means there is a need for an interface where modules list their `keeper`s and other methods that require a reference to another module's object. `AppModule` interface also enables the module manager to set the order of execution between module's methods like `BeginBlock` and `EndBlock`, which is important in cases where the order of execution between modules matters in the context of the application. + +Lastly the interface for genesis functionality `AppModuleGenesis` is separated out from full module functionality `AppModule` so that modules which +are only used for genesis can take advantage of the `Module` patterns without having to define many placeholder functions. + +### `AppModuleBasic` + +### `AppModule` + +### `AppModuleGenesis` + +### Implementing the Application Module Interfaces ## Module Manager diff --git a/docs/core/baseapp.md b/docs/core/baseapp.md index 12aabb3bb735..963a751ea7ae 100644 --- a/docs/core/baseapp.md +++ b/docs/core/baseapp.md @@ -17,7 +17,7 @@ This document describes `baseapp`, the abstraction that implements most of the c - [Main ABCI Messages](#abci) + [CheckTx](#checktx) + [DeliverTx](#delivertx) -- [RunTx, AnteHandler and RunMsgs](#runtx-,antehandler-and-runmsgs) +- [RunTx, AnteHandler and RunMsgs](#runtx-antehandler-and-runmsgs) + [RunTx](#runtx) + [AnteHandler](#antehandler) + [RunMsgs](#runmsgs) @@ -207,7 +207,7 @@ Developers building on top of the Cosmos SDK need not implement the ABCI themsel 3. Perform non-module related *stateful* checks on the account. This step is mainly about checking that the `message` signatures are valid, that enough fees are provided and that the sending account has enough funds to pay for said fees. Note that no precise [`gas`](./accounts-fees-gas.md#gas) counting occurs here, as `message`s are not processed. Usually, the [`anteHandler`](./accounts-fees-gas.md#antehandler) will check that the `gas` provided with the transaction is superior to a minimum reference gas amount based on the raw transaction size, in order to avoid spam with transactions that provide 0 gas. 4. Ensure that a [`Route`](#message-routing) exists for each `message`, but do **not** actually process `message`s. `Message`s only need to be processed when the canonical state need to be updated, which happens during `DeliverTx`. -Steps 2. and 3. are performed by the [`anteHandler`](./accounts-fees-gas.md#antehandler) in the [`RunTx`](#runtx-,antehandler-and-runmsgs) function, which `CheckTx` calls with the `runTxModeCheck` mode. During each step of `CheckTx`, a special [volatile state](#volatile-states) called `checkState` is updated. This state is used to keep track of the temporary changes triggered by the `CheckTx` calls of each transaction without modifying the [main canonical state](#main-state) . For example, when a transaction goes through `CheckTx`, the transaction's fees are deducted from the sender's account in `checkState`. If a second transaction is received from the same account before the first is processed, and the account has consumed all its funds in `checkState` during the first transaction, the second transaction will fail `CheckTx` and be rejected. In any case, the sender's account will not actually pay the fees until the transaction is actually included in a block, because `checkState` never gets committed to the main state. `checkState` is reset to the latest state of the main state each time a blocks gets [committed](#commit). +Steps 2. and 3. are performed by the [`anteHandler`](./accounts-fees-gas.md#antehandler) in the [`RunTx`](#runtx-antehandler-and-runmsgs) function, which `CheckTx` calls with the `runTxModeCheck` mode. During each step of `CheckTx`, a special [volatile state](#volatile-states) called `checkState` is updated. This state is used to keep track of the temporary changes triggered by the `CheckTx` calls of each transaction without modifying the [main canonical state](#main-state) . For example, when a transaction goes through `CheckTx`, the transaction's fees are deducted from the sender's account in `checkState`. If a second transaction is received from the same account before the first is processed, and the account has consumed all its funds in `checkState` during the first transaction, the second transaction will fail `CheckTx` and be rejected. In any case, the sender's account will not actually pay the fees until the transaction is actually included in a block, because `checkState` never gets committed to the main state. `checkState` is reset to the latest state of the main state each time a blocks gets [committed](#commit). `CheckTx` returns a response to the underlying consensus engine of type [`abci.ResponseCheckTx`](https://tendermint.com/docs/spec/abci/abci.html#messages). The response contains: From 0f1b61ddac0283d9b0888c20b7e282f61738a711 Mon Sep 17 00:00:00 2001 From: gamarin Date: Thu, 18 Jul 2019 17:20:03 +0200 Subject: [PATCH 027/196] workinnn --- docs/basics/app-anatomy.md | 73 +++++------ docs/building-modules/events.md | 1 + docs/building-modules/genesis.md | 5 + docs/building-modules/messages-and-queries.md | 5 + docs/building-modules/module-interfaces.md | 4 + docs/building-modules/modules-manager.md | 117 +++++++++++++++++- docs/core/baseapp.md | 8 +- 7 files changed, 167 insertions(+), 46 deletions(-) create mode 100644 docs/building-modules/events.md create mode 100644 docs/building-modules/genesis.md create mode 100644 docs/building-modules/messages-and-queries.md diff --git a/docs/basics/app-anatomy.md b/docs/basics/app-anatomy.md index dcbe732cca60..9664accca78c 100644 --- a/docs/basics/app-anatomy.md +++ b/docs/basics/app-anatomy.md @@ -54,7 +54,7 @@ Blockchain Node | | Consensus | | ``` The blockchain full-node presents itself as a binary, generally suffixed by `-d` for "daemon" (e.g. `appd` for `app` or `gaiad` for `gaia`). This binary is built by running a simple `main.go` function placed in `cmd/appd/`. This operation usually happens through the [Makefile](#dependencies-and-makefile). -To learn more about the `main.go` function, [click here](./node.md#main-function). +To learn more about the `main.go` function, [click here](../core/node.md#main-function). Once the main binary is built, the node can be started by running the `start` command. The core logic behind the `start` command is implemented in the SDK itself in the [`/server/start.go`](https://github.com/cosmos/cosmos-sdk/blob/master/server/start.go) file. The main [`start` command function](https://github.com/cosmos/cosmos-sdk/blob/master/server/start.go#L31) takes a [`context`](https://godoc.org/github.com/cosmos/cosmos-sdk/client/context) and [`appCreator`](#constructor-function-(`appCreator`)) as arguments. The `appCreator` is a constructor function for the SDK application, and is used in the starting process of the full-node. @@ -64,7 +64,7 @@ The `start` command function primarily does three things: 2. Initialize the state-machine with the latest known state, extracted from the `db` stored in the `~/.appd/data` folder. At this point, the state-machine is at height `appBlockHeight`. 3. Create and start a new Tendermint instance. Among other things, the node will perform a handshake with its peers. It will get the latest `blockHeight` from them, and replay blocks to sync to this height if it is greater than the local `appBlockHeight`. If `appBlockHeight` is `0`, the node is starting from genesis and Tendermint sends an `InitChain` message via the ABCI to the `app`, which triggers the [`InitChainer`](#initchainer). -To learn more about the `start` command, [click here](./node.md#start-command). +To learn more about the `start` command, [click here](../core/node.md#start-command). ## Core Application File @@ -74,11 +74,11 @@ In general, the core of the state-machine is defined in a file called `app.go`. The first thing defined in `app.go` is the `type` of the application. It is generally comprised of the following parts: -- **A reference to [`baseapp`](./baseapp.md).** The custom application defined in `app.go` is an extension of the `baseapp` type. `baseapp` implements most of the core logic for the application, including all the [ABCI methods](https://tendermint.com/docs/spec/abci/abci.html#overview) and the routing logic. When a transaction is relayed by Tendermint to the application, the latter uses `baseapp`'s methods to route them to the appropriate module. -- **A list of store keys**. The [store](./store.md), which contains the entire state, is implemented as a multistore (i.e. a store of stores) in the Cosmos SDK. Each module uses one or multiple stores in the multistore to persist their part of the state. These stores can be accessed with specific keys that are declared in the `app` type. These keys, along with the `keepers`, are at the heart of the [object-capabilities model](../intro/ocap.md) of the Cosmos SDK. -- **A list of module's `keepers`.** Each module defines an abstraction called `keeper`, which handles reads and writes for this module's store(s). The `keeper`'s methods of one module can be called from other modules (if authorized), which is why they are declared in the application's type and exported as interfaces to other modules so that they are only allowed to access the authorized functions. -- **A reference to a `codec`.** The Cosmos SDK gives developers the freedom to choose the encoding framework for their application. The application's `codec` is used to serialize and deserialize data structures in order to store them, as stores can only persist `[]bytes`. The `codec` must be deterministic. The default codec is [amino](./amino.md). -- **A reference to a [module manager](./modules.md#module-manager)**. The module manager is an object that contains a list of the application's module. It facilitates operations related to these modules, like registering [`routes`](./baseapp.md#routing), [query routes](#./baseapp.md#query-routing) or setting the order of execution between modules for various functions like [`InitChainer`](#initchainer), [`BeginBlocker` and `EndBlocker`](#beginblocker-and-endblocker). +- **A reference to [`baseapp`](../core/baseapp.md).** The custom application defined in `app.go` is an extension of the `baseapp` type. `baseapp` implements most of the core logic for the application, including all the [ABCI methods](https://tendermint.com/docs/spec/abci/abci.html#overview) and the routing logic. When a transaction is relayed by Tendermint to the application, the latter uses `baseapp`'s methods to route them to the appropriate module. +- **A list of store keys**. The [store](../core/store.md), which contains the entire state, is implemented as a multistore (i.e. a store of stores) in the Cosmos SDK. Each module uses one or multiple stores in the multistore to persist their part of the state. These stores can be accessed with specific keys that are declared in the `app` type. These keys, along with the `keepers`, are at the heart of the [object-capabilities model](../intro/ocap.md) of the Cosmos SDK. +- **A list of module's `keepers`.** Each module defines an abstraction called [`keeper`](../building-modules/keeper.md), which handles reads and writes for this module's store(s). The `keeper`'s methods of one module can be called from other modules (if authorized), which is why they are declared in the application's type and exported as interfaces to other modules so that they are only allowed to access the authorized functions. +- **A reference to a [`codec`](../core/encoding.md).** The Cosmos SDK gives developers the freedom to choose the encoding framework for their application. The application's `codec` is used to serialize and deserialize data structures in order to store them, as stores can only persist `[]bytes`. The `codec` must be deterministic. The default codec is [amino](./amino.md). +- **A reference to a [module manager](../building-modules/module-manager.md#manager)** and a [basic module manager](../building-modules/module-manager.md#basicmanager). The module manager is an object that contains a list of the application's module. It facilitates operations related to these modules, like registering [`routes`](./baseapp.md#routing), [query routes](#./baseapp.md#query-routing) or setting the order of execution between modules for various functions like [`InitChainer`](#initchainer), [`BeginBlocker` and `EndBlocker`](#beginblocker-and-endblocker). You can see an example of application type definition [here](https://github.com/cosmos/gaia/blob/master/app/app.go#L73-L107). @@ -88,14 +88,14 @@ This function constructs a new application of the type defined above. It is call - Instantiate a new application with a reference to a `baseapp` instance, a codec and all the appropriate store keys. - Instantiate all the [`keeper`s](#keeper) defined in the application's `type` using the `NewKeeper` function of each of the application's modules. Note that `keepers` must be instantiated in the correct order, as the `NewKeeper` of one module might require a reference to another module's `keeper`. -- Instantiate the application's [module manager](./module-manager.md) with the [`AppModule`](#application-module-interface) object of each of the application's modules. -- With the module manager, initialize the application's [`routes`](./baseapp.md#routing) and [query routes](./baseapp.md#query-routing). When a transaction is relayed to the application by Tendermint via the ABCI, it is routed to the appropriate module's [`handler`](#handler) using the routes defined here. Likewise, when a query is received by the application, it is routed to the appropriate module's [`querier`](#querier) using the query routes defined here. -- With the module manager, register the [application's modules' invariants](./invariants.md). Invariants are variables (e.g. total supply of a token) that are evaluated at the end of each block. The process of checking invariants is done via a special module called the [`InvariantsRegistry`](./invariants.md#invariant-registry). The value of the invariant should be equal to a predicted value defined in the module. Should the value be different than the predicted one, special logic defined in the invariant registry will be triggered (usually the chain is halted). This is useful to make sure no critical bug goes unnoticed and produces long-lasting effects that would be hard to fix. +- Instantiate the application's [module manager](../building-modules/module-manager.md#manager) with the [`AppModule`](#application-module-interface) object of each of the application's modules. +- With the module manager, initialize the application's [`routes`](../core/baseapp.md#routing) and [query routes](../core/baseapp.md#query-routing). When a transaction is relayed to the application by Tendermint via the ABCI, it is routed to the appropriate module's [`handler`](#handler) using the routes defined here. Likewise, when a query is received by the application, it is routed to the appropriate module's [`querier`](#querier) using the query routes defined here. +- With the module manager, register the [application's modules' invariants](./invariants.md). Invariants are variables (e.g. total supply of a token) that are evaluated at the end of each block. The process of checking invariants is done via a special module called the [`InvariantsRegistry`](../building-modules/invariants.md#invariant-registry). The value of the invariant should be equal to a predicted value defined in the module. Should the value be different than the predicted one, special logic defined in the invariant registry will be triggered (usually the chain is halted). This is useful to make sure no critical bug goes unnoticed and produces long-lasting effects that would be hard to fix. - With the module manager, set the order of execution between the `InitGenesis`, `BegingBlocker` and `EndBlocker` functions of each of the [application's modules](#application-module-interface). Note that not all modules implement these functions. - Set the remainer of application's parameters: + [`InitChainer`](#initchainer): used to initialize the application when it is first started. + [`BeginBlocker`, `EndBlocker`](#beginblocker-and-endlbocker): called at the beginning and the end of every block). - + [`anteHandler`](#baseapp.md#antehandler): used to handle fees and signature verification. + + [`anteHandler`](../core/baseapp.md#antehandler): used to handle fees and signature verification. - Mount the stores. - Return the application. @@ -105,7 +105,7 @@ You can see an example of application constructor [here](https://github.com/cosm ### InitChainer -The `InitChainer` is a function that initializes the state of the application from a [genesis file](./genesis.md) (i.e. token balances of genesis accounts). It is called when the application receives the `InitChain` message from the Tendermint engine, which happens when the node is started at `appBlockHeight == 0` (i.e. on genesis). The application must set the `InitChainer` in its constructor via the [`SetInitChainer`](https://godoc.org/github.com/cosmos/cosmos-sdk/baseapp#BaseApp.SetInitChainer) method. +The `InitChainer` is a function that initializes the state of the application from a [genesis file](../core/genesis.md) (i.e. token balances of genesis accounts). It is called when the application receives the `InitChain` message from the Tendermint engine, which happens when the node is started at `appBlockHeight == 0` (i.e. on genesis). The application must set the `InitChainer` in its constructor via the [`SetInitChainer`](https://godoc.org/github.com/cosmos/cosmos-sdk/baseapp#BaseApp.SetInitChainer) method. In general, the `InitChainer` is mostly composed of the `InitGenesis` function of each of the application's modules. This is done by calling the `InitGenesis` function of the module manager, which in turn will call the `InitGenesis` function of each of the modules it contains. Note that the order in which the modules' `InitGenesis` functions must be called has to be set in the module manager using the `SetOrderInitGenesis` method. This is done in the [application's constructor](#application-constructor), and the `SetOrderInitGenesis` has to be called before the `SetInitChainer`. @@ -125,34 +125,27 @@ You can see an example of `BeginBlocker` and `EndBlocker` functions [here](https The `MakeCodec` function is the last important function of the `app.go` file. The goal of this function is to instantiate a codec `cdc` (e.g. [amino](./amino.md)) initiliaze the codec of the SDK and each of the application's modules using the `RegisterCodec` function. -To register the application's modules, the `MakeCodec` function calls `RegisterCodec` on `ModuleBasics`. `ModuleBasics` is a [basic manager](./modules.md#basic-manager) which lists all of the application's modules. It is instanciated in the `init()` function, and only serves to easily register non-dependant elements of application's modules (such as codec). To learn more about the basic module manager, click [here](./modules.md#basic-manager). +To register the application's modules, the `MakeCodec` function calls `RegisterCodec` on `ModuleBasics`. `ModuleBasics` is a [basic manager](../building-modules/module-manager.md#basicmanager) which lists all of the application's modules. It is instanciated in the `init()` function, and only serves to easily register non-dependant elements of application's modules (such as codec). To learn more about the basic module manager, click [here](../building-modules/module-manager.md#basicmanager). You can see an example of a `MakeCodec` [here](https://github.com/cosmos/gaia/blob/master/app/app.go#L64-L70) ## Modules -Modules are the heart and soul of an SDK application. They can be considered as state-machines within the state-machine. When a transaction is relayed from the underlying Tendermint engine via the ABCI to the application, it is routed by `baseapp` to the appropriate module in order to be processed. This paradigm enables developers to easily build complex state-machines, as most of the modules they need often already exist. For developers, most of the work involved in building an SDK application revolves around building custom modules required by their application that do not exist, and integrating them with modules that do already exist into one coherent application. In the application directory, the standard practice is to store modules in the `x/` folder (not to be confused with the SDK's `x/` folder, which contains already-built modules). +Modules are the heart and soul of an SDK application. They can be considered as state-machines within the state-machine. When a transaction is relayed from the underlying Tendermint engine via the ABCI to the application, it is routed by [`baseapp`](../core/baseapp.md) to the appropriate module in order to be processed. This paradigm enables developers to easily build complex state-machines, as most of the modules they need often already exist. For developers, most of the work involved in building an SDK application revolves around building custom modules required by their application that do not exist, and integrating them with modules that do already exist into one coherent application. In the application directory, the standard practice is to store modules in the `x/` folder (not to be confused with the SDK's `x/` folder, which contains already-built modules). To learn more about modules, [click here](./modules.md) ### Application Module Interface -Modules implement two interfaces defined in the Cosmos SDK, [`AppModuleBasic`](https://github.com/cosmos/cosmos-sdk/blob/master/types/module/module.go#L44-L57) and [`AppModule`](https://github.com/cosmos/cosmos-sdk/blob/master/types/module/module.go#L44-L57). The former implements basic non-dependant elements of the module, such as the `codec`, while the latter handles the bulk of the module methods (including methods that require references to other modules' `keeper`s). Both the `AppModule` and `AppModuleBasic` types are defined in a file called `./module.go`. +Modules implement two interfaces defined in the Cosmos SDK, [`AppModuleBasic`](../building-modules/module-manager.md#appmodulebasic) and [`AppModule`](../building-modules/module-manager.md#appmodule). The former implements basic non-dependant elements of the module, such as the `codec`, while the latter handles the bulk of the module methods (including methods that require references to other modules' `keeper`s). Both the `AppModule` and `AppModuleBasic` types are defined in a file called `./module.go`. -`AppModule` exposes a collection of useful methods on the module that facilitates the composition of modules into a coherent application. Important methods include: +`AppModule` exposes a collection of useful methods on the module that facilitates the composition of modules into a coherent application. These methods are are called from the `module manager`(../building-modules/module-manager.md#manager), which manages the application's collection of modules. -- `Route()` and `QueryRoute()`: These methods the name of the route and querier route for the module, for [messages](#message-types) to be routed to the module's [`handler`](#handler) and queries to be routes to the module's [`querier`](#querier). -- `NewHandler()` and `NewQuerierHandler()`: These methods return a `handler` and `querierHandler` respectively, in order to process a message or a query once they are routed. -- `BeginBlock()`, `EndBlock()` and `InitGenesis()`: These methods are executed respectively at the beginning of each block, at the end of each block and at the start of the chain. They implement special logic the module requires to be triggered during those events. For example, the `EndBlock` function is frequently used by modules where voting occurs to tally the result of the votes. -- `RegisterInvariants()`: This method registers the [invariants](./invariants.md) for the module. Invariants are checked at the end of every block to make sure no unpredicted behaviour is occuring. - -`AppModule`'s methods are called from the `module manager`(./modules.md#module-manager), which manages the application's collection of modules. - -To learn more about the application module interface, [click here](./modules.md#application-module-interface). +To learn more about the application module interface, [click here](../building-modules/module-manager.md#application-module-interfaces). ### Message Types -A message is a custom type defined by each module that implements the [`message`](https://github.com/cosmos/cosmos-sdk/blob/master/types/tx_msg.go#L8-L29) interface. Each `transaction` contains one or multiple `messages`. When a valid block of transactions is received by the full-node, Tendermint relays each one to the application via [`DeliverTx`](https://tendermint.com/docs/app-dev/abci-spec.html#delivertx). Then, the application handles the transaction: +A message is a custom type defined by each module that implements the [`message`](../building-modules/messages-and-queries.md#messages) interface. Each [`transaction`](../core/transaction.md) contains one or multiple `messages`. When a valid block of transactions is received by the full-node, Tendermint relays each one to the application via [`DeliverTx`](https://tendermint.com/docs/app-dev/abci-spec.html#delivertx). Then, the application handles the transaction: 1. Upon receiving the transaction, the application first unmarshalls it from `[]bytes`. 2. Then, it verifies a few things about the transaction like [fee payment and signatures](#accounts-fees-gas.md) before extracting the message(s) contained in the transaction. @@ -163,24 +156,24 @@ For a more detailed look at a transaction lifecycle, click [here](./tx-lifecycle Module developers create custom message types when they build their own module. The general practice is to prefix the type declaration of the message with `Msg`. For example, the message type [`MsgSend`](https://github.com/cosmos/cosmos-sdk/blob/master/x/bank/types/msgs.go#L10-L15) allows users to transfer tokens. It is processed by the handler of the `bank` module, which ultimately calls the `keeper` of the `auth` module in order to update the state. -To learn more about messages, [click here](./tx-msgs.md). +To learn more about messages, [click here](../building-modules/messages-and-queries.md#messages). ### Handler -The `handler` refers to the part of the module responsible for processing the message after it is routed by `baseapp`. `handler` functions of modules (except those of the `auth` module) are only executed if the transaction is relayed from Tendermint by the `DeliverTx` ABCI message. If the transaction is relayed by `CheckTx`, only stateless checks and fee-related (i.e. `auth` module-related) stateful checks are performed. To better understand the difference between `DeliverTx`and `CheckTx`, as well as the difference between stateful and stateless checks, click [here](./tx-lifecycle.md). +The [`handler`](../building-modules/handler.md) refers to the part of the module responsible for processing the message after it is routed by `baseapp`. `handler` functions of modules (except those of the `auth` module) are only executed if the transaction is relayed from Tendermint by the `DeliverTx` ABCI message. If the transaction is relayed by `CheckTx`, only stateless checks and fee-related (i.e. `auth` module-related) stateful checks are performed. To better understand the difference between `DeliverTx`and `CheckTx`, as well as the difference between stateful and stateless checks, click [here](./tx-lifecycle.md). The handler of a module is generally defined in a file called `handler.go` and consists of: -- A **switch function** `NewHandler` to route the message to the appropriate handler function. This function returns a `handler` function, and is registered in the [`AppModule`](#application-module-interface) to be used in the application's module manager to initialize the [application's router](./baseapp.md#routing). See an example of such a switch [here](https://github.com/cosmos/sdk-application-tutorial/blob/master/x/nameservice/handler.go#L10-L22). +- A **switch function** `NewHandler` to route the message to the appropriate handler function. This function returns a `handler` function, and is registered in the [`AppModule`](#application-module-interface) to be used in the application's module manager to initialize the [application's router](../core/baseapp.md#routing). See an example of such a switch [here](https://github.com/cosmos/sdk-application-tutorial/blob/master/x/nameservice/handler.go#L10-L22). - **One handler function for each message type defined by the module**. Developers write the message processing logic in these functions. This generally involves doing stateful checks to ensure the message is valid and calling [`keeper`](#keeper)'s methods to update the state. Handler functions return a result of type [`sdk.Result`](https://github.com/cosmos/cosmos-sdk/blob/master/types/result.go#L14-L37), which informs the application on whether the message was successfully processed. -To learn more about handlers, [click here](./handler.md). +To learn more about handlers, [click here](../building-modules/handler.md). ### Keeper -`Keepers` are the gatekeepers of their module's store(s). To read or write in a module's store, it is mandatory to go through one of its `keeper`'s methods. This is ensured by the [object-capabilities](./ocap.md) model of the Cosmos SDK. Only objects that hold the key to a store can access it, and only the module's `keeper` should hold the key(s) to the module's store(s). +[`Keepers`](../building-module/keeper.md) are the gatekeepers of their module's store(s). To read or write in a module's store, it is mandatory to go through one of its `keeper`'s methods. This is ensured by the [object-capabilities](../core/ocap.md) model of the Cosmos SDK. Only objects that hold the key to a store can access it, and only the module's `keeper` should hold the key(s) to the module's store(s). `Keepers` are generally defined in a file called `keeper.go`. It contains the `keeper`'s type definition and methods. @@ -194,18 +187,18 @@ Along with the type definition, the next important component of the `keeper.go` The rest of the file defines the `keeper`'s methods, primarily getters and setters. You can check an example of a `keeper` implementation [here](https://github.com/cosmos/sdk-application-tutorial/blob/master/x/nameservice/keeper.go). -To learn more about `keepers`, [click here](./keeper.md). +To learn more about `keepers`, [click here](../building-modules/keeper.md). ### Querier -`Queriers` are very similar to `handlers`, except they serve user queries to the state as opposed to processing transactions. A query is initiated from an [interface](#intefaces) by an end-user who provides a `queryRoute` and some `data`. The query is then routed to the correct application's `querier` by `baseapp`'s [`handleQueryCustom`](https://github.com/cosmos/cosmos-sdk/blob/master/baseapp/baseapp.go#L519-L556) method using `queryRoute`. +[`Queriers`](../building-modules/querier.md) are very similar to `handlers`, except they serve user queries to the state as opposed to processing transactions. A [query](../building-modules/messages-and-queries.md#queries) is initiated from an [interface](#interfaces) by an end-user who provides a `queryRoute` and some `data`. The query is then routed to the correct application's `querier` by `baseapp`'s [`handleQueryCustom`](https://github.com/cosmos/cosmos-sdk/blob/master/baseapp/baseapp.go#L519-L556) method using `queryRoute`. The `Querier` of a module is defined in a file called `querier.go`, and consists of: -- A **switch function** `NewQuerier` to route the query to the appropriate `querier` function. This function returns a `querier` function, and is is registered in the [`AppModule`](#application-module-interface) to be used in the application's module manager to initialize the [application's query router](./baseapp.md#query-routing). See an example of such a switch [here](https://github.com/cosmos/sdk-application-tutorial/blob/master/x/nameservice/querier.go#L21-L34). +- A **switch function** `NewQuerier` to route the query to the appropriate `querier` function. This function returns a `querier` function, and is is registered in the [`AppModule`](#application-module-interface) to be used in the application's module manager to initialize the [application's query router](../core/baseapp.md#query-routing). See an example of such a switch [here](https://github.com/cosmos/sdk-application-tutorial/blob/master/x/nameservice/querier.go#L21-L34). - - **One querier function for each data type defined by the module that needs to be queryable**. Developers write the query processing logic in these functions. This generally involves calling [`keeper`](#keeper)'s methods to query the state and marshalling it to JSON. See an example of `querier` functions [here](https://github.com/cosmos/sdk-application-tutorial/blob/master/x/nameservice/querier.go#L37-L101). -To learn more about `queriers`, [click here](./querier.md). +To learn more about `queriers`, [click here](../building-modules/querier.md). ### Command-Line and REST Interfaces @@ -218,11 +211,11 @@ Generally, the commands related to a module are defined in a folder called `clie - Transactions commands let users generate new transactions so that they can be included in a block and eventually update the state. One command should be created for each [message type](#message-types) defined in the module. The command calls the constructor of the message with the parameters provided by the end-user, and wraps it into a transaction. The SDK handles signing and the addition of other transaction metadata. See examples of transactions commands [here](https://github.com/cosmos/sdk-application-tutorial/blob/master/x/nameservice/client/cli/tx.go). - Queries let users query the subset of the state defined by the module. Query commands forward queries to the [application's query router](./baseapp.md#query-routing), which routes them to the appropriate [querier](#querier) the `queryRoute` parameter supplied. See examples of query commands [here](https://github.com/cosmos/sdk-application-tutorial/blob/master/x/nameservice/client/cli/query.go). -To learn more about modules CLI, [click here](./module-interfaces.md#cli). +To learn more about modules CLI, [click here](../building-modules/module-interfaces.md#cli). #### REST -The module's REST interface lets users generate transactions and query the state through REST calls to the application's [light client daemon](./node.md#lcd) (LCD). REST routes are defined in a file `client/rest/rest.go`, which is composed of: +The module's REST interface lets users generate transactions and query the state through REST calls to the application's [light client daemon](../core/node.md#lcd) (LCD). REST routes are defined in a file `client/rest/rest.go`, which is composed of: - A `RegisterRoutes` function, which registers each route defined in the file. This function is called from the [main application's interface](#application-interfaces) for each module used within the application. The router used in the SDK is [Gorilla's mux](https://github.com/gorilla/mux). - Custom request type definitions for each query or transaction creation function that needs to be exposed. These custom request types build on the [base `request` type](https://github.com/cosmos/cosmos-sdk/blob/master/types/rest/rest.go#L32-L43) of the Cosmos SDK. @@ -230,22 +223,22 @@ The module's REST interface lets users generate transactions and query the state See an example of a module's `rest.go` file [here](https://github.com/cosmos/sdk-application-tutorial/blob/master/x/nameservice/client/rest/rest.go). -To learn more about modules REST interface, [click here](./module-interfaces.md#rest). +To learn more about modules REST interface, [click here](../building-modules/module-interfaces.md#rest). ## Application Interface Interfaces let end-users interact with full-node clients. This means querying data from the full-node or creating and sending new transactions to be relayed by the full-node and eventually included in a block. -The main interface is the [Command-Line Interface](./interfaces.md#cli). The CLI of an SDK application is built by aggregating [CLI commands](#cli) defined in each of the modules used by the application. The CLI of an application generally has the `-cli` suffix (e.g. `appcli`), and defined in a file called `cmd/appcli/main.go`. The file contains: +The main interface is the [Command-Line Interface](../interfaces/cli.md). The CLI of an SDK application is built by aggregating [CLI commands](#cli) defined in each of the modules used by the application. The CLI of an application generally has the `-cli` suffix (e.g. `appcli`), and defined in a file called `cmd/appcli/main.go`. The file contains: - **A `main()` function**, which is executed to build the `appcli` interface client. This function prepares each command and adds them to the `rootCmd` before building them. At the root of `appCli`, the function adds generic commands like `status`, `keys` and `config`, query commands, tx commands and `rest-server`. - **Query commands** are added by calling the `queryCmd` function, also defined in `appcli/main.go`. This function returns a Cobra command that contains the query commands defined in each of the application's modules (passed as an array of `sdk.ModuleClients` from the `main()` function), as well as some other lower level query commands such as block or validator queries. Query command are called by using the command `appcli query [query]` of the CLI. - **Transaction commands** are added by calling the `txCmd` function. Similar to `queryCmd`, the function returns a Cobra command that contains the tx commands defined in each of the application's modules, as well as lower level tx commands like transaction signing or broadcasting. Tx commands are called by using the command `appcli tx [tx]` of the CLI. -- **A `registerRoutes` function**, which is called from the `main()` function when initializing the [application's light-client daemon (LCD)](./node.md#lcd) (i.e. `rest-server`). `registerRoutes` calls the `RegisterRoutes` function of each of the application's module, thereby registering the routes of the module to the lcd's router. The LCD can be started by running the following command `appcli rest-server`. +- **A `registerRoutes` function**, which is called from the `main()` function when initializing the [application's light-client daemon (LCD)](../core/node.md#lcd) (i.e. `rest-server`). `registerRoutes` calls the `RegisterRoutes` function of each of the application's module, thereby registering the routes of the module to the lcd's router. The LCD can be started by running the following command `appcli rest-server`. See an example of an application's main command-line file [here](https://github.com/cosmos/sdk-application-tutorial/blob/master/cmd/nscli/main.go). -To learn more about interfaces, [click here](./interfaces.md). +To learn more about interfaces, [click here](../interfaces/intro.md). ## Dependencies and Makefile diff --git a/docs/building-modules/events.md b/docs/building-modules/events.md new file mode 100644 index 000000000000..cbf945847cd4 --- /dev/null +++ b/docs/building-modules/events.md @@ -0,0 +1 @@ +# Events \ No newline at end of file diff --git a/docs/building-modules/genesis.md b/docs/building-modules/genesis.md new file mode 100644 index 000000000000..2667616ff802 --- /dev/null +++ b/docs/building-modules/genesis.md @@ -0,0 +1,5 @@ +# Module Genesis + +## `GenesisState` + +## `ValidateGenesis` \ No newline at end of file diff --git a/docs/building-modules/messages-and-queries.md b/docs/building-modules/messages-and-queries.md new file mode 100644 index 000000000000..55c14281b99a --- /dev/null +++ b/docs/building-modules/messages-and-queries.md @@ -0,0 +1,5 @@ +# Messages and Queries + +## Messages + +## Queries \ No newline at end of file diff --git a/docs/building-modules/module-interfaces.md b/docs/building-modules/module-interfaces.md index 0cd27c895326..744c439c67f2 100644 --- a/docs/building-modules/module-interfaces.md +++ b/docs/building-modules/module-interfaces.md @@ -2,4 +2,8 @@ ## CLI +### Tx + +### Query + ## REST \ No newline at end of file diff --git a/docs/building-modules/modules-manager.md b/docs/building-modules/modules-manager.md index e84587ff5c69..d43207ba05ba 100644 --- a/docs/building-modules/modules-manager.md +++ b/docs/building-modules/modules-manager.md @@ -25,11 +25,124 @@ are only used for genesis can take advantage of the `Module` patterns without ha ### `AppModuleBasic` -### `AppModule` +The [`AppModuleBasic`](https://github.com/cosmos/cosmos-sdk/blob/master/types/module/module.go#L45-L57) interface defines the independent methods modules need to implement. + +```go +type AppModuleBasic interface { + Name() string + RegisterCodec(*codec.Codec) + + // genesis + DefaultGenesis() json.RawMessage + ValidateGenesis(json.RawMessage) error + + // client functionality + RegisterRESTRoutes(context.CLIContext, *mux.Router) + GetTxCmd(*codec.Codec) *cobra.Command + GetQueryCmd(*codec.Codec) *cobra.Command +} +``` + +Let us go through the methods: + +- `Name()`: Returns the name of the module as a `string`. +- `RegisterCodec(*codec.Codec)`: Registers the `codec` for the module, which is used to marhsal and unmarshal structs to/from `[]byte` in order to persist them in the moduel's `KVStore`. +- `DefaultGenesis()`: Returns a default [`GenesisState`](./genesis.md#genesisstate) for the module, marshalled to `json.RawMessage`. The default `GenesisState` need to be defined by the module developer and is primarily used for testing. +- `ValidateGenesis(json.RawMessage)`: Used to validate the `GenesisState` defined by a module, given in its `json.RawMessage` form. It will usually unmarshall the `json` before running a custom [`ValidateGenesis`](./genesis.md#validategenesis) function defined by the module developer. +- `RegisterRESTRoutes(context.CLIContext, *mux.Router)`: Registers the REST routes for the module. These routes will be used to map REST request to the module in order to process them. See [../interfaces/rest.md] for more. +- `GetTxCmd(*codec.Codec)`: Returns the root [`Tx` command](./module-interfaces.md#tx) for the module. The subcommands of this root command are used by end-users to generate new transactions containing [`message`s](./messages-and-queries.md#queries) defined in the module. +- `GetQueryCmd(*codec.Codec)`: Return the root [`query` command](./module-intefaces.md#query) for the module. The subcommands of this root command are used by end-users to generate new queries to the subset of the state defined by the module. + +All the `AppModuleBasic` of an application are managed by the [`BasicManager`](#basicmanager). ### `AppModuleGenesis` +The [`AppModuleGenesis`](https://github.com/cosmos/cosmos-sdk/blob/master/types/module/module.go#L123-L127) interface is a simple embedding of the `AppModuleBasic` interface with two added methods. + +```go +type AppModuleGenesis interface { + AppModuleBasic + InitGenesis(sdk.Context, json.RawMessage) []abci.ValidatorUpdate + ExportGenesis(sdk.Context) json.RawMessage +} +``` + +Let us go through the two added methods: + +- `InitGenesis(sdk.Context, json.RawMessage)`: Initializes the subset of the state managed by the module. It is called at genesis (i.e. when the chain is first started). +- `ExportGenesis(sdk.Context)`: Exports the latest subset of the state managed by the module to be used in a new genesis file. `ExportGenesis` is called for each module when a new chain is started from the state of an existing chain. + +It does not have its own manager, and exists separately from [`AppModule`](#appmodule) only for modules that exist only to implement genesis functionalities, so that they can be managed without having to implement all of `AppModule`'s methods. If the module is not only used during genesis, `InitGenesis(sdk.Context, json.RawMessage)` and `ExportGenesis(sdk.Context)` will generally be defined as methods of the concrete type implementing hte `AppModule` interface. + +### `AppModule` + +The [`AppModule`](https://github.com/cosmos/cosmos-sdk/blob/master/types/module/module.go#L130-L144) interface defines the inter-dependent methods modules need to implement. + +```go +type AppModule interface { + AppModuleGenesis + + // registers + RegisterInvariants(sdk.InvariantRegistry) + + // routes + Route() string + NewHandler() sdk.Handler + QuerierRoute() string + NewQuerierHandler() sdk.Querier + + BeginBlock(sdk.Context, abci.RequestBeginBlock) + EndBlock(sdk.Context, abci.RequestEndBlock) []abci.ValidatorUpdate +} +``` + +`AppModule`s are managed by the [module manager](#manager). This interface embeds the `AppModuleGenesis` interface so that the manager can access all the independent and genesis inter-dependent methods of the module. This means that a concrete type implementing the `AppModule` interface must either implement all the methods of `AppModuleGenesis` (and by extension `AppModuleBasic`), or include a concrete type that does as parameter. + +Let us go through the methods of `AppModule`: + +- `RegisterInvariants(sdk.InvariantRegistry)`: Registers the [`invariants`](./invariants.md) of the module. If the invariants deviates from its predicted value, the [`InvariantRegistry`](./invariants.md#registry) triggers appropriate logic (most often the chain will be halted). +- `Route()`: Returns the name of the module's route, for [`message`s](./messages-and-queries.md#messages) to be routed to the module by [`baseapp`](../core/baseapp.md#message-routing). +- `NewHandler()`: Returns a [`handler`](./handler.md) given the `Type()` of the `message`, in order to process the `message`. +- `QuerierRoute()`: Returns the name of the module's query route, for [`queries`](./messages-and-queries.md#queries) to be routes to the module by [`baseapp`](../core/baseapp.md#query-routing). +- `NewQuerierHandler()`: Returns a [`querier`](./querier.md) given the query `path`, in order to process the `query`. +- `BeginBlock(sdk.Context, abci.RequestBeginBlock)`: This method gives module developers the option to implement logic that is automatically triggered at the beginning of each block. Implement empty if no logic needs to be triggered at the beginning of each block for this module. +- `EndBlock(sdk.Context, abci.RequestEndBlock)`: This method gives module developers the option to implement logic that is automatically triggered at the beginning of each block. This is also where the module can inform the underlying consensus engine of validator set changes (e.g. the `staking` module). Implement empty if no logic needs to be triggered at the beginning of each block for this module. + ### Implementing the Application Module Interfaces -## Module Manager +Typically, the various application module interfaces are implemented in a file called `module.go`, located in the module's folder (e.g. `./x/module/module.go`). + +Almost every module need to implement the `AppModuleBasic` and `AppModule` interfaces. If the module is only used for genesis, it will implement `AppModuleGenesis` instead of `AppModule`. The concrete type that implements the interface can add parameters that are required for the implementation of the various methods of the interface. For example, the `NewHandler()` function often calls a `NewHandler(k keeper)` function defined in [`handler.go`](./handler.md) and therefore needs to pass the module's [`keeper`](./keeper.md) as parameter. + +```go +// example +type AppModule struct { + AppModuleBasic + keeper Keeper +} +``` + +In the example above, you can see that the `AppModule` concrete type references an `AppModuleBasic`, and not an `AppModuleGenesis`. That is because `AppModuleGenesis` only needs to be implemented in modules that focus on genesis-related functionalities. In most modules, the concrete `AppModule` type will have a reference to an `AppModuleBasic` and implement the two added methods of `AppModuleGenesis` directly in the `AppModule` type. + +If no parameter is required (which is often the case for `AppModuleBasic`), just declare an empty concrete type like so: + +```go +type AppModuleBasic struct{} +``` + +## Module Managers + +Module managers are used to manage collections of `AppModuleBasic` and `AppModule`. + +### `BasicManager` + +The `BasicManager` is a structure that lists all the `AppModuleBasic` of an application: + +```go +type BasicManager map[string]AppModuleBasic +``` + + + +### `Manager` diff --git a/docs/core/baseapp.md b/docs/core/baseapp.md index 963a751ea7ae..5bfe27117f08 100644 --- a/docs/core/baseapp.md +++ b/docs/core/baseapp.md @@ -64,8 +64,8 @@ First, the important parameters that are initialized during the initialization o - A [`CommitMultiStore`](./store.md#commit-multi-store). This is the main store of the application, which holds the canonical state that is committed at the [end of each block](#commit). This store is **not** cached, meaning it is not used to update the application's intermediate (un-committed) states. The `CommitMultiStore` is a multi-store, meaning a store of stores. Each module of the application uses one or multiple `KVStores` in the multi-store to persist their subset of the state. - A [database](./store.md#database) `db`, which is used by the `CommitMultiStore` to handle data storage. -- A [router](#message-routing). The `router` facilitates the routing of [messages](./tx-msgs.md) to the appropriate module for it to be processed. -- A [query router](#query-routing). The `query router` facilitates the routing of [queries](./querier.md) to the appropriate module for it to be processed. +- A [router](#message-routing). The `router` facilitates the routing of [messages](../building-modules/messages-and-queries.md#messages) to the appropriate module for it to be processed. +- A [query router](#query-routing). The `query router` facilitates the routing of [queries](../building-modules/messages-and-queries.md#queries) to the appropriate module for it to be processed. - A [`txDecoder`](https://godoc.org/github.com/cosmos/cosmos-sdk/types#TxDecoder), used to decode transaction `[]byte` relayed by the underlying Tendermint engine. - A [`baseKey`], to access the [main store](./store.md#main-store) in the `CommitMultiStore`. The main store is used to persist data related to the core of the application, like consensus parameters. - A [`anteHandler`](#antehandler), to handle signature verification and fee paiement when a transaction is received. @@ -173,13 +173,13 @@ When messages and queries are received by the application, they must be routed t ### Message Routing -Messages need to be routed after they are extracted from transactions, which are sent from the underlying Tendermint engine via the [`CheckTx`](#checktx) and [`DeliverTx`](#delivertx) ABCI messages. To do so, `baseapp` holds a [`router`](https://github.com/cosmos/cosmos-sdk/blob/master/baseapp/router.go) which maps `paths` (`string`) to the appropriate module [`handler`](./handler.md). Usually, the `path` is the name of the module. +[`Message`s](#../building-modules/messages-and-queries.md#messages) need to be routed after they are extracted from transactions, which are sent from the underlying Tendermint engine via the [`CheckTx`](#checktx) and [`DeliverTx`](#delivertx) ABCI messages. To do so, `baseapp` holds a [`router`](https://github.com/cosmos/cosmos-sdk/blob/master/baseapp/router.go) which maps `paths` (`string`) to the appropriate module [`handler`](./handler.md). Usually, the `path` is the name of the module. The application's `router` is initilalized with all the routes using the application's [module manager](../building-modules/module-manager.md), which itself is initialized with all the application's modules in the application's [constructor](../basics/app-anatomy.md#app-constructor). ### Query Routing -Similar to messages, queries need to be routed to the appropriate module's [querier](./querier.md). To do so, `baseapp` holds a [`query router`](https://github.com/cosmos/cosmos-sdk/blob/master/baseapp/queryrouter.go), which maps `paths` (`string`) to the appropriate module [`querier`](./querier.md). Usually, the `path` is the name of the module. +Similar to `message`s, [`queries`](../building-modules/messages-and-queries.md#queries) need to be routed to the appropriate module's [querier](../building-modules/querier.md). To do so, `baseapp` holds a [`query router`](https://github.com/cosmos/cosmos-sdk/blob/master/baseapp/queryrouter.go), which maps `paths` (`string`) to the appropriate module `querier`. Usually, the `path` is the name of the module. Just like the `router`, the `query router` is initilalized with all the query routes using the application's [module manager](../building-modules/module-manager.md), which itself is initialized with all the application's modules in the application's [constructor](../basics/app-anatomy.md#app-constructor). From c5bb53846299f13867fa72d798fea5e7c9cfc5a8 Mon Sep 17 00:00:00 2001 From: Gloria Zhao Date: Thu, 18 Jul 2019 10:23:21 -0700 Subject: [PATCH 028/196] add transactions into core --- docs/core/transactions.md | 84 +++++++++++++++++++++++++++++++++++++++ 1 file changed, 84 insertions(+) create mode 100644 docs/core/transactions.md diff --git a/docs/core/transactions.md b/docs/core/transactions.md new file mode 100644 index 000000000000..69a260d3edce --- /dev/null +++ b/docs/core/transactions.md @@ -0,0 +1,84 @@ +# Transactions + +## Prerequisites + +* [Anatomy of an SDK Application](./app-anatomy.md) + +## Synopsis + +This document describes how various components are defined to enable transactions. It also describes how transactions are generated. + +1. [Transactions](#transactions) +2. [Transaction Definition](#transaction-definition) +3. [CLI and REST Interfaces](#cli-and-rest-interfaces) +4. [Messages](#messages) +5. [Transaction Generation](#transaction-generation) +6. [Handlers](#handlers) + + +## Transactions + +[**Transactions**](https://github.com/cosmos/cosmos-sdk/blob/97d10210beb55ad4bd6722f7186a80bf7cb140e2/types/tx_msg.go#L36-L43) are objects that wrap messages and transaction data, created to enable a user interact with an application. Specifically, they are comprised of metadata held in [contexts](./contexts) and [messages](../modules.md#messages) that trigger state changes within a module and are handled by the module's Handler. + +When users want to interact with an application and make state changes (e.g. sending coins), they create transactions. Each of a transaction's messages must be signed using the private key associated with the appropriate account(s), and then the transaction broadcasted to the network. A transaction must then be included in a block, validated, and approved by the network through the consensus process. To read more about the lifecycle of a transaction, click [here](../basics/tx-lifecycle.md). + +## Transaction Definition + +Transactions are defined by module developers. They must implement the [`Tx`](https://github.com/cosmos/cosmos-sdk/blob/73700df8c39d1fe6c3d3a1a635ac03d4bacecf55/types/tx_msg.go#L34-L41) interface and include an encoder and decoder: + +* **GetMsgs:** unwraps the transaction and returns a list of its message(s) - one transaction may have one or multiple messages. +* **ValidateBasic:** includes lightweight, [*stateless*](../basics/tx-lifecycle.md#types-of-checks) checks used by ABCI messages [`CheckTx`](../basics/baseapp.md#checktx) and [`DeliverTx`](../basics/baseapp.md#delivertx) to validate transactions. The `StdTx` `ValidateBasic` function checks that its transactions are signed by the correct number of signers and that the fees do not exceed what the user's maximum. Note that this function is distinct from the `ValidateBasic` functions for *messages*, which are also for transaction validation but only check messages. For example, when [`runTx`](../basics/baseapp.md#runtx-and-runmsgs) is checking a transaction created from the [`auth`](https://github.com/cosmos/cosmos-sdk/tree/67f6b021180c7ef0bcf25b6597a629aca27766b8/docs/spec/auth) module, it first runs `ValidateBasic` on each message, then runs the `auth` module AnteHandler which calls `ValidateBasic` for the transaction itself. +* **TxEncoder:** Nodes running the consensus engine (e.g. Tendermint Core) are responsible for gossiping transactions and ordering them into blocks, but only handle them in the generic `[]byte` form. Transactions are always marshaled (encoded) before they are relayed to nodes, which compacts them to facilitate gossiping and helps maintain the consensus engine's agnosticism with applications. The Cosmos SDK allows developers to specify any deterministic encoding format for their applications; the default is [`Amino`](./amino.md). +* **TxDecoder:** [ABCI](https://tendermint.com/docs/spec/abci/) calls from the consensus engine to the application, such as `CheckTx` and `DeliverTx`, are used to process transaction data to determine validity and state changes. Since transactions are passed in as `txBytes []byte`, they need to first be unmarshaled (decoded) using `TxDecoder` before any logic is applied. + +A transaction is created through one of the possible [interfaces](#interfaces). In the process, two contexts and an array of [messages](#messages) are created, which are then used to [generate](#transaction-generation) the transaction itself. The actual state changes triggered by transactions are enabled by the [handlers](#handlers). The rest of the document will describe each of these components, in this order. + +## CLI and REST Interfaces + +The SDK uses several tools for building [interfaces](./interfaces.md) through which users can create transactions. Application developers create entrypoints to the application by creating a [command-line interface](./interfaces.md#cli) or [REST interface](./interfaces.md#rest), typically found in the application's `/cmd` folder. These interfaces allow users to interact with the application through command-line or through HTTP requests. + +In order for module messages to be utilized in transactions created through these interfaces, module developers must also specify possible user [interactions](../modules/interfaces.md), typically in the module's `/client` folder. For the [command-line interface](../modules/interfaces.md#cli), module developers create subcommands that will be added to the application `tx` command. For [HTTP requests](../modules/interfaces.md#rest), module developers specify acceptable request types, register REST routes, and create HTTP Request Handlers. + +When users interact with the application's interfaces, they invoke the underlying modules' handlers or command functions, directly creating messages. + +## Messages + +**Messages** are module-specific objects that trigger state transitions within the scope of the module they belong to. Module developers define the messages for their module by implementing the [`Msg`](https://github.com/cosmos/cosmos-sdk/blob/97d10210beb55ad4bd6722f7186a80bf7cb140e2/types/tx_msg.go#L10-L31) interface, and also define a [`Handler`](../building-modules/handler.md) to process them. Messages in a module are typically defined in a `msgs.go` file (though not always), and one handler with multiple functions to handle each of the module's messages is defined in a `handler.go` file. + +Note: module messages are not to be confused with [ABCI Messages](https://tendermint.com/docs/spec/abci/abci.html#messages) which define interactions between the Tendermint and application layers. + +The [`Msg`](https://github.com/cosmos/cosmos-sdk/blob/97d10210beb55ad4bd6722f7186a80bf7cb140e2/types/tx_msg.go#L10-L31) interface has five required functions. + +* **Route** returns a string that specifies which module this message is a part of and, thus, which module contains the handler used to implement the actions of this message. [Baseapp](./baseapp.md) uses this function to deliver transactions by invoking the correct handler(s). For example, `MsgSend` is defined in and handled by the `bank` module; its `Route` function returns the name of the `bank` module so `Baseapp` understands to use that module's handler. +* **Type** returns a short, human-readable string that describes what the message does. For example, `MsgSend`'s type is `"send"`. +* **ValidateBasic** implements a set of stateless sanity checks for the message and returns an `Error`. For example, the `validateBasic` method for `MsgSend`, the message which sends coins from one account to another, checks that both sender and recipient addresses are valid and the amount is nonnegative. +* **GetSignBytes** returns a `[]byte` representation of the message which is used by the signer to sign it. +* **GetSigners** returns a list of addresses whose corresponding signatures are required for the message to be valid. For example, `MsgSend` requires a signature from the sender of the coins. + +While messages contain the information for state transition logic, a transaction's other metadata and relevant information are stored in the `TxBuilder` and `CLIContext`. + +## Transaction Generation + +[`Contexts`](https://godoc.org/context) are immutable objects that contain all the information needed to process a request. In the process of creating a transaction, two contexts are created: the [`CLIContext`](../interfaces/query-lifecycle.md#clicontext) and `TxBuilder`. Both are automatically generated and do not need to be defined by application developers, but do require input from the transaction creator (e.g. using flags through the CLI). + +The [`TxBuilder`](https://github.com/cosmos/cosmos-sdk/blob/73700df8c39d1fe6c3d3a1a635ac03d4bacecf55/x/auth/types/txbuilder.go) contains data closely related with the processing of transactions: + +* `TxEncoder` defined by the developer for this type of transaction. Used to encode messages before being processed by nodes running Tendermint. +* `Keybase` that manages the user's keys and is used to perform signing operations. +* `AccountNumber` from which this transaction originated. +* `Sequence`, the number of transactions that the user has sent out, used to prevent replay attacks. +* `Gas` option chosen by the users for how to calculate how much gas they will need to pay. A common option is "auto" which generates an automatic estimate. +* `GasAdjustment` to adjust the estimate of gas by a scalar value, used to avoid underestimating the amount of gas required. +* `SimulateAndExecute` option to simply simulate the transaction execution without broadcasting. +* `ChainID` representing which blockchain this transaction pertains to. +* `Memo` to send with the transaction. +* `Fees`, the maximum amount the user is willing to pay in fees. Alternative to specifying gas prices. +* `GasPrices`, the amount per unit of gas the user is willing to pay in fees. Alternative to specifying fees. + +The `CLIContext` is initialized using the application's `codec` and data more closely related to the user interaction with the interface, holding data such as the output to the user and the broadcast mode. Read more about `CLIContext` [here](../interfaces/query-lifecycle.md#clicontext). + +Every message in a transaction must be signed by the addresses specified by `GetSigners`. The signing process must be handled by a module, and the most widely used one is the [`auth`](https://github.com/cosmos/cosmos-sdk/tree/67f6b021180c7ef0bcf25b6597a629aca27766b8/docs/spec/auth) module. Signing is automatically performed when the transaction is created, unless the user choses to generate and sign separately. The `TxBuilder` (namely, the `KeyBase`) is used to perform the signing operations, and the `CLIContext` is used to broadcast transactions. + +## Handlers + +The final components developers must implement to enable transactions are handlers and keeprs. Each module has a [`Handler`](../building-modules/handler.md) to process all of the module's message types. From 3c7d3887e161606aaf826c8ba710770b04f05edb Mon Sep 17 00:00:00 2001 From: Gloria Zhao Date: Wed, 24 Jul 2019 20:16:22 -0700 Subject: [PATCH 029/196] hans comments --- docs/core/transactions.md | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/docs/core/transactions.md b/docs/core/transactions.md index 69a260d3edce..60c2c9f9ac20 100644 --- a/docs/core/transactions.md +++ b/docs/core/transactions.md @@ -18,26 +18,26 @@ This document describes how various components are defined to enable transaction ## Transactions -[**Transactions**](https://github.com/cosmos/cosmos-sdk/blob/97d10210beb55ad4bd6722f7186a80bf7cb140e2/types/tx_msg.go#L36-L43) are objects that wrap messages and transaction data, created to enable a user interact with an application. Specifically, they are comprised of metadata held in [contexts](./contexts) and [messages](../modules.md#messages) that trigger state changes within a module and are handled by the module's Handler. +[**Transactions**](https://github.com/cosmos/cosmos-sdk/blob/97d10210beb55ad4bd6722f7186a80bf7cb140e2/types/tx_msg.go#L36-L43) are objects that wrap messages and transaction data, created to enable a user to interact with an application. Specifically, they are comprised of metadata held in [contexts](./contexts) and [messages](../modules.md#messages) that trigger state changes within a module and are handled by the module's Handler. -When users want to interact with an application and make state changes (e.g. sending coins), they create transactions. Each of a transaction's messages must be signed using the private key associated with the appropriate account(s), and then the transaction broadcasted to the network. A transaction must then be included in a block, validated, and approved by the network through the consensus process. To read more about the lifecycle of a transaction, click [here](../basics/tx-lifecycle.md). +When users want to interact with an application and make state changes (e.g. sending coins), they create transactions. Each of a transaction's messages must be signed using the private key associated with the appropriate account(s), and then the transaction is broadcasted to the network. A transaction must then be included in a block, validated, and approved by the network through the consensus process. To read more about the lifecycle of a transaction, click [here](../basics/tx-lifecycle.md). ## Transaction Definition -Transactions are defined by module developers. They must implement the [`Tx`](https://github.com/cosmos/cosmos-sdk/blob/73700df8c39d1fe6c3d3a1a635ac03d4bacecf55/types/tx_msg.go#L34-L41) interface and include an encoder and decoder: +Transactions messages are defined by module developers. The transaction objects themselves are SDK types that implement the [`Tx`](https://github.com/cosmos/cosmos-sdk/blob/73700df8c39d1fe6c3d3a1a635ac03d4bacecf55/types/tx_msg.go#L34-L41) interface and include an encoder and decoder: * **GetMsgs:** unwraps the transaction and returns a list of its message(s) - one transaction may have one or multiple messages. * **ValidateBasic:** includes lightweight, [*stateless*](../basics/tx-lifecycle.md#types-of-checks) checks used by ABCI messages [`CheckTx`](../basics/baseapp.md#checktx) and [`DeliverTx`](../basics/baseapp.md#delivertx) to validate transactions. The `StdTx` `ValidateBasic` function checks that its transactions are signed by the correct number of signers and that the fees do not exceed what the user's maximum. Note that this function is distinct from the `ValidateBasic` functions for *messages*, which are also for transaction validation but only check messages. For example, when [`runTx`](../basics/baseapp.md#runtx-and-runmsgs) is checking a transaction created from the [`auth`](https://github.com/cosmos/cosmos-sdk/tree/67f6b021180c7ef0bcf25b6597a629aca27766b8/docs/spec/auth) module, it first runs `ValidateBasic` on each message, then runs the `auth` module AnteHandler which calls `ValidateBasic` for the transaction itself. -* **TxEncoder:** Nodes running the consensus engine (e.g. Tendermint Core) are responsible for gossiping transactions and ordering them into blocks, but only handle them in the generic `[]byte` form. Transactions are always marshaled (encoded) before they are relayed to nodes, which compacts them to facilitate gossiping and helps maintain the consensus engine's agnosticism with applications. The Cosmos SDK allows developers to specify any deterministic encoding format for their applications; the default is [`Amino`](./amino.md). +* **TxEncoder:** Nodes running the consensus engine (e.g. Tendermint Core) are responsible for gossiping transactions and ordering them into blocks, but only handle them in the generic `[]byte` form. Transactions are always marshaled (encoded) before they are relayed to nodes, which compacts them to facilitate gossiping and helps maintain the consensus engine's separation from from application logic. The Cosmos SDK allows developers to specify any deterministic encoding format for their applications; the default is [`Amino`](./amino.md). * **TxDecoder:** [ABCI](https://tendermint.com/docs/spec/abci/) calls from the consensus engine to the application, such as `CheckTx` and `DeliverTx`, are used to process transaction data to determine validity and state changes. Since transactions are passed in as `txBytes []byte`, they need to first be unmarshaled (decoded) using `TxDecoder` before any logic is applied. A transaction is created through one of the possible [interfaces](#interfaces). In the process, two contexts and an array of [messages](#messages) are created, which are then used to [generate](#transaction-generation) the transaction itself. The actual state changes triggered by transactions are enabled by the [handlers](#handlers). The rest of the document will describe each of these components, in this order. ## CLI and REST Interfaces -The SDK uses several tools for building [interfaces](./interfaces.md) through which users can create transactions. Application developers create entrypoints to the application by creating a [command-line interface](./interfaces.md#cli) or [REST interface](./interfaces.md#rest), typically found in the application's `/cmd` folder. These interfaces allow users to interact with the application through command-line or through HTTP requests. +The SDK uses several tools for building [interfaces](./interfaces.md) through which users can create transactions through the command-line or HTTP Requests. Application developers create entrypoints to the application by creating a [command-line interface](./interfaces.md#cli) or [REST interface](./interfaces.md#rest), typically found in the application's `/cmd` folder. These interfaces allow users to interact with the application through command-line or through HTTP requests. -In order for module messages to be utilized in transactions created through these interfaces, module developers must also specify possible user [interactions](../modules/interfaces.md), typically in the module's `/client` folder. For the [command-line interface](../modules/interfaces.md#cli), module developers create subcommands that will be added to the application `tx` command. For [HTTP requests](../modules/interfaces.md#rest), module developers specify acceptable request types, register REST routes, and create HTTP Request Handlers. +In order for module messages to be utilized in transactions created through these interfaces, module developers must also specify possible user [interactions](../modules/interfaces.md), typically in the module's `/client` folder. For the [command-line interface](../modules/interfaces.md#cli), module developers create subcommands to add as children to the application top-level transaction command `TxCmd`. For [HTTP requests](../modules/interfaces.md#rest), module developers specify acceptable request types, register REST routes, and create HTTP Request Handlers. When users interact with the application's interfaces, they invoke the underlying modules' handlers or command functions, directly creating messages. @@ -45,7 +45,7 @@ When users interact with the application's interfaces, they invoke the underlyin **Messages** are module-specific objects that trigger state transitions within the scope of the module they belong to. Module developers define the messages for their module by implementing the [`Msg`](https://github.com/cosmos/cosmos-sdk/blob/97d10210beb55ad4bd6722f7186a80bf7cb140e2/types/tx_msg.go#L10-L31) interface, and also define a [`Handler`](../building-modules/handler.md) to process them. Messages in a module are typically defined in a `msgs.go` file (though not always), and one handler with multiple functions to handle each of the module's messages is defined in a `handler.go` file. -Note: module messages are not to be confused with [ABCI Messages](https://tendermint.com/docs/spec/abci/abci.html#messages) which define interactions between the Tendermint and application layers. +Note: module messages are not to be confused with [ABCI Messages](https://tendermint.com/docs/spec/abci/abci.html#messages) which define interactions between the Tendermint and application layers. While ABCI messages such as CheckTx and DeliverTx contain Transactions, which contain module Messages, they are not to be confused with the module level messages themselves The [`Msg`](https://github.com/cosmos/cosmos-sdk/blob/97d10210beb55ad4bd6722f7186a80bf7cb140e2/types/tx_msg.go#L10-L31) interface has five required functions. @@ -81,4 +81,4 @@ Every message in a transaction must be signed by the addresses specified by `Get ## Handlers -The final components developers must implement to enable transactions are handlers and keeprs. Each module has a [`Handler`](../building-modules/handler.md) to process all of the module's message types. +The final components developers must implement to enable transactions are handlers and keeprs. Each module has a Handler to process all of the module's message types. To read more about handlers, visit the documentation for building modules [here](../building-modules/handler.md). From 41e922cd99d2d755e37f105472d8a52fb92bdfce Mon Sep 17 00:00:00 2001 From: Gloria Zhao Date: Thu, 18 Jul 2019 10:23:21 -0700 Subject: [PATCH 030/196] add transactions into core --- docs/core/transactions.md | 84 +++++++++++++++++++++++++++++++++++++++ 1 file changed, 84 insertions(+) create mode 100644 docs/core/transactions.md diff --git a/docs/core/transactions.md b/docs/core/transactions.md new file mode 100644 index 000000000000..69a260d3edce --- /dev/null +++ b/docs/core/transactions.md @@ -0,0 +1,84 @@ +# Transactions + +## Prerequisites + +* [Anatomy of an SDK Application](./app-anatomy.md) + +## Synopsis + +This document describes how various components are defined to enable transactions. It also describes how transactions are generated. + +1. [Transactions](#transactions) +2. [Transaction Definition](#transaction-definition) +3. [CLI and REST Interfaces](#cli-and-rest-interfaces) +4. [Messages](#messages) +5. [Transaction Generation](#transaction-generation) +6. [Handlers](#handlers) + + +## Transactions + +[**Transactions**](https://github.com/cosmos/cosmos-sdk/blob/97d10210beb55ad4bd6722f7186a80bf7cb140e2/types/tx_msg.go#L36-L43) are objects that wrap messages and transaction data, created to enable a user interact with an application. Specifically, they are comprised of metadata held in [contexts](./contexts) and [messages](../modules.md#messages) that trigger state changes within a module and are handled by the module's Handler. + +When users want to interact with an application and make state changes (e.g. sending coins), they create transactions. Each of a transaction's messages must be signed using the private key associated with the appropriate account(s), and then the transaction broadcasted to the network. A transaction must then be included in a block, validated, and approved by the network through the consensus process. To read more about the lifecycle of a transaction, click [here](../basics/tx-lifecycle.md). + +## Transaction Definition + +Transactions are defined by module developers. They must implement the [`Tx`](https://github.com/cosmos/cosmos-sdk/blob/73700df8c39d1fe6c3d3a1a635ac03d4bacecf55/types/tx_msg.go#L34-L41) interface and include an encoder and decoder: + +* **GetMsgs:** unwraps the transaction and returns a list of its message(s) - one transaction may have one or multiple messages. +* **ValidateBasic:** includes lightweight, [*stateless*](../basics/tx-lifecycle.md#types-of-checks) checks used by ABCI messages [`CheckTx`](../basics/baseapp.md#checktx) and [`DeliverTx`](../basics/baseapp.md#delivertx) to validate transactions. The `StdTx` `ValidateBasic` function checks that its transactions are signed by the correct number of signers and that the fees do not exceed what the user's maximum. Note that this function is distinct from the `ValidateBasic` functions for *messages*, which are also for transaction validation but only check messages. For example, when [`runTx`](../basics/baseapp.md#runtx-and-runmsgs) is checking a transaction created from the [`auth`](https://github.com/cosmos/cosmos-sdk/tree/67f6b021180c7ef0bcf25b6597a629aca27766b8/docs/spec/auth) module, it first runs `ValidateBasic` on each message, then runs the `auth` module AnteHandler which calls `ValidateBasic` for the transaction itself. +* **TxEncoder:** Nodes running the consensus engine (e.g. Tendermint Core) are responsible for gossiping transactions and ordering them into blocks, but only handle them in the generic `[]byte` form. Transactions are always marshaled (encoded) before they are relayed to nodes, which compacts them to facilitate gossiping and helps maintain the consensus engine's agnosticism with applications. The Cosmos SDK allows developers to specify any deterministic encoding format for their applications; the default is [`Amino`](./amino.md). +* **TxDecoder:** [ABCI](https://tendermint.com/docs/spec/abci/) calls from the consensus engine to the application, such as `CheckTx` and `DeliverTx`, are used to process transaction data to determine validity and state changes. Since transactions are passed in as `txBytes []byte`, they need to first be unmarshaled (decoded) using `TxDecoder` before any logic is applied. + +A transaction is created through one of the possible [interfaces](#interfaces). In the process, two contexts and an array of [messages](#messages) are created, which are then used to [generate](#transaction-generation) the transaction itself. The actual state changes triggered by transactions are enabled by the [handlers](#handlers). The rest of the document will describe each of these components, in this order. + +## CLI and REST Interfaces + +The SDK uses several tools for building [interfaces](./interfaces.md) through which users can create transactions. Application developers create entrypoints to the application by creating a [command-line interface](./interfaces.md#cli) or [REST interface](./interfaces.md#rest), typically found in the application's `/cmd` folder. These interfaces allow users to interact with the application through command-line or through HTTP requests. + +In order for module messages to be utilized in transactions created through these interfaces, module developers must also specify possible user [interactions](../modules/interfaces.md), typically in the module's `/client` folder. For the [command-line interface](../modules/interfaces.md#cli), module developers create subcommands that will be added to the application `tx` command. For [HTTP requests](../modules/interfaces.md#rest), module developers specify acceptable request types, register REST routes, and create HTTP Request Handlers. + +When users interact with the application's interfaces, they invoke the underlying modules' handlers or command functions, directly creating messages. + +## Messages + +**Messages** are module-specific objects that trigger state transitions within the scope of the module they belong to. Module developers define the messages for their module by implementing the [`Msg`](https://github.com/cosmos/cosmos-sdk/blob/97d10210beb55ad4bd6722f7186a80bf7cb140e2/types/tx_msg.go#L10-L31) interface, and also define a [`Handler`](../building-modules/handler.md) to process them. Messages in a module are typically defined in a `msgs.go` file (though not always), and one handler with multiple functions to handle each of the module's messages is defined in a `handler.go` file. + +Note: module messages are not to be confused with [ABCI Messages](https://tendermint.com/docs/spec/abci/abci.html#messages) which define interactions between the Tendermint and application layers. + +The [`Msg`](https://github.com/cosmos/cosmos-sdk/blob/97d10210beb55ad4bd6722f7186a80bf7cb140e2/types/tx_msg.go#L10-L31) interface has five required functions. + +* **Route** returns a string that specifies which module this message is a part of and, thus, which module contains the handler used to implement the actions of this message. [Baseapp](./baseapp.md) uses this function to deliver transactions by invoking the correct handler(s). For example, `MsgSend` is defined in and handled by the `bank` module; its `Route` function returns the name of the `bank` module so `Baseapp` understands to use that module's handler. +* **Type** returns a short, human-readable string that describes what the message does. For example, `MsgSend`'s type is `"send"`. +* **ValidateBasic** implements a set of stateless sanity checks for the message and returns an `Error`. For example, the `validateBasic` method for `MsgSend`, the message which sends coins from one account to another, checks that both sender and recipient addresses are valid and the amount is nonnegative. +* **GetSignBytes** returns a `[]byte` representation of the message which is used by the signer to sign it. +* **GetSigners** returns a list of addresses whose corresponding signatures are required for the message to be valid. For example, `MsgSend` requires a signature from the sender of the coins. + +While messages contain the information for state transition logic, a transaction's other metadata and relevant information are stored in the `TxBuilder` and `CLIContext`. + +## Transaction Generation + +[`Contexts`](https://godoc.org/context) are immutable objects that contain all the information needed to process a request. In the process of creating a transaction, two contexts are created: the [`CLIContext`](../interfaces/query-lifecycle.md#clicontext) and `TxBuilder`. Both are automatically generated and do not need to be defined by application developers, but do require input from the transaction creator (e.g. using flags through the CLI). + +The [`TxBuilder`](https://github.com/cosmos/cosmos-sdk/blob/73700df8c39d1fe6c3d3a1a635ac03d4bacecf55/x/auth/types/txbuilder.go) contains data closely related with the processing of transactions: + +* `TxEncoder` defined by the developer for this type of transaction. Used to encode messages before being processed by nodes running Tendermint. +* `Keybase` that manages the user's keys and is used to perform signing operations. +* `AccountNumber` from which this transaction originated. +* `Sequence`, the number of transactions that the user has sent out, used to prevent replay attacks. +* `Gas` option chosen by the users for how to calculate how much gas they will need to pay. A common option is "auto" which generates an automatic estimate. +* `GasAdjustment` to adjust the estimate of gas by a scalar value, used to avoid underestimating the amount of gas required. +* `SimulateAndExecute` option to simply simulate the transaction execution without broadcasting. +* `ChainID` representing which blockchain this transaction pertains to. +* `Memo` to send with the transaction. +* `Fees`, the maximum amount the user is willing to pay in fees. Alternative to specifying gas prices. +* `GasPrices`, the amount per unit of gas the user is willing to pay in fees. Alternative to specifying fees. + +The `CLIContext` is initialized using the application's `codec` and data more closely related to the user interaction with the interface, holding data such as the output to the user and the broadcast mode. Read more about `CLIContext` [here](../interfaces/query-lifecycle.md#clicontext). + +Every message in a transaction must be signed by the addresses specified by `GetSigners`. The signing process must be handled by a module, and the most widely used one is the [`auth`](https://github.com/cosmos/cosmos-sdk/tree/67f6b021180c7ef0bcf25b6597a629aca27766b8/docs/spec/auth) module. Signing is automatically performed when the transaction is created, unless the user choses to generate and sign separately. The `TxBuilder` (namely, the `KeyBase`) is used to perform the signing operations, and the `CLIContext` is used to broadcast transactions. + +## Handlers + +The final components developers must implement to enable transactions are handlers and keeprs. Each module has a [`Handler`](../building-modules/handler.md) to process all of the module's message types. From c3623e9e6b97bdd4fc3bb89d57fc62484f5b1d10 Mon Sep 17 00:00:00 2001 From: gamarin Date: Thu, 8 Aug 2019 17:11:26 +0200 Subject: [PATCH 031/196] working --- docs/basics/app-anatomy.md | 1 + .../{modules-manager.md => module-manager.md} | 6 +++++- 2 files changed, 6 insertions(+), 1 deletion(-) rename docs/building-modules/{modules-manager.md => module-manager.md} (91%) diff --git a/docs/basics/app-anatomy.md b/docs/basics/app-anatomy.md index 9664accca78c..411ce6e70f49 100644 --- a/docs/basics/app-anatomy.md +++ b/docs/basics/app-anatomy.md @@ -86,6 +86,7 @@ You can see an example of application type definition [here](https://github.com/ This function constructs a new application of the type defined above. It is called every time the full-node is started with the [`start`](https://github.com/cosmos/cosmos-sdk/blob/master/server/start.go#L117) command. Here are the main actions performed by this function: +- Instantiate a new [`codec`](../core/encoding.md) and initialize the `codec` of each of the application's module using the [basic manager](../building-modules/module-manager.md#basicmanager) - Instantiate a new application with a reference to a `baseapp` instance, a codec and all the appropriate store keys. - Instantiate all the [`keeper`s](#keeper) defined in the application's `type` using the `NewKeeper` function of each of the application's modules. Note that `keepers` must be instantiated in the correct order, as the `NewKeeper` of one module might require a reference to another module's `keeper`. - Instantiate the application's [module manager](../building-modules/module-manager.md#manager) with the [`AppModule`](#application-module-interface) object of each of the application's modules. diff --git a/docs/building-modules/modules-manager.md b/docs/building-modules/module-manager.md similarity index 91% rename from docs/building-modules/modules-manager.md rename to docs/building-modules/module-manager.md index d43207ba05ba..d96760f69429 100644 --- a/docs/building-modules/modules-manager.md +++ b/docs/building-modules/module-manager.md @@ -136,12 +136,16 @@ Module managers are used to manage collections of `AppModuleBasic` and `AppModul ### `BasicManager` -The `BasicManager` is a structure that lists all the `AppModuleBasic` of an application: +The [`BasicManager`](https://github.com/cosmos/cosmos-sdk/blob/master/types/module/module.go#L60) is a structure that lists all the `AppModuleBasic` of an application: ```go type BasicManager map[string]AppModuleBasic ``` +It implements the following methods: + +- `NewBasicManager(modules ...AppModuleBasic)`: Constructor function. It takes a list of the application's `AppModuleBasic` and builds a new `BasicManager`. This function is generally called in the `init()` function of [`app.go`](../basics/app-anatomy.md#core-application-file) to quickly initialize the independent elements of the application's modules (click [here](https://github.com/cosmos/gaia/blob/master/app/app.go#L59-L74) to see an example). +- `RegisterCodec(cdc *codec.Codec)`: Registers the [`codec`s](../core/encoding.md) of each of the application's `AppModuleBasic`. This function is usually early on in the [application's construction](../basics/app-anatomy.md#constructor) ### `Manager` From 1e70aafcd5ae63879498c5639ade228cfbef9e09 Mon Sep 17 00:00:00 2001 From: Gloria Zhao Date: Sat, 10 Aug 2019 16:56:47 -0400 Subject: [PATCH 032/196] gautier comments --- docs/core/transactions.md | 28 ++++++++++++---------------- 1 file changed, 12 insertions(+), 16 deletions(-) diff --git a/docs/core/transactions.md b/docs/core/transactions.md index 43fb49988e36..a2cd7bb494ee 100644 --- a/docs/core/transactions.md +++ b/docs/core/transactions.md @@ -18,26 +18,26 @@ This document describes how various components are defined to enable transaction ## Transactions -[**Transactions**](https://github.com/cosmos/cosmos-sdk/blob/master/types/tx_msg.go#L36-L43) are objects that wrap messages and transaction data, created to enable a user to interact with an application. Specifically, they are comprised of metadata held in [contexts](./contexts) and [messages](../modules.md#messages) that trigger state changes within a module through the module's Handler. +[**Transactions**](https://github.com/cosmos/cosmos-sdk/blob/master/types/tx_msg.go#L36-L43) are objects created by end-users to trigger state changes in the application. Specifically, they are comprised of metadata held in [contexts](./context.md) and [messages](../building-modules/messages-and-queries.md) that trigger state changes within a module through the module's Handler. When users want to interact with an application and make state changes (e.g. sending coins), they create transactions. Each of a transaction's messages must be signed using the private key associated with the appropriate account(s), and then the transaction is broadcasted to the network. A transaction must then be included in a block, validated, and approved by the network through the consensus process. To read more about the lifecycle of a transaction, click [here](../basics/tx-lifecycle.md). ## Transaction Definition -Transactions messages are defined by module developers. The transaction objects themselves are SDK types that implement the [`Tx`](https://github.com/cosmos/cosmos-sdk/blob/master/types/tx_msg.go#L34-L41) interface and include an encoder and decoder: +The transaction objects themselves are SDK types that implement the [`Tx`](https://github.com/cosmos/cosmos-sdk/blob/master/types/tx_msg.go#L34-L41) interface and include an encoder and decoder: -* **GetMsgs:** unwraps the transaction and returns a list of its message(s) - one transaction may have one or multiple messages. -* **ValidateBasic:** includes lightweight, [*stateless*](../basics/tx-lifecycle.md#types-of-checks) checks used by ABCI messages [`CheckTx`](../basics/baseapp.md#checktx) and [`DeliverTx`](../basics/baseapp.md#delivertx) to validate transactions. The `StdTx` `ValidateBasic` function checks that its transactions are signed by the correct number of signers and that the fees do not exceed what the user's maximum. Note that this function is distinct from the `ValidateBasic` functions for *messages*, which are also for transaction validation but only check messages. For example, when [`runTx`](../basics/baseapp.md#runtx-and-runmsgs) is checking a transaction created from the [`auth`](https://github.com/cosmos/cosmos-sdk/blob/master/docs/spec/auth) module, it first runs `ValidateBasic` on each message, then runs the `auth` module AnteHandler which calls `ValidateBasic` for the transaction itself. -* **TxEncoder:** Nodes running the consensus engine (e.g. Tendermint Core) are responsible for gossiping transactions and ordering them into blocks, but only handle them in the generic `[]byte` form. Transactions are always marshaled (encoded) before they are relayed to nodes, which compacts them to facilitate gossiping and helps maintain the consensus engine's separation from from application logic. The Cosmos SDK allows developers to specify any deterministic encoding format for their applications; the default is [`Amino`](./amino.md). +* **GetMsgs:** unwraps the transaction and returns a list of its message(s) - one transaction may have one or multiple [messages](../building-modules/messages-and-queries.md#messages), which are defined by module developers. +* **ValidateBasic:** includes lightweight, [*stateless*](../basics/tx-lifecycle.md#types-of-checks) checks used by ABCI messages [`CheckTx`](../basics/baseapp.md#checktx) and [`DeliverTx`](../basics/baseapp.md#delivertx) to make sure transactions are not invalid. The `StdTx` `ValidateBasic` function checks that its transactions are signed by the correct number of signers and that the fees do not exceed what the user's maximum. Note that this function is distinct from the `ValidateBasic` functions for *messages*, which perform basic validity checks on messages only. For example, when [`runTx`](../basics/baseapp.md#runtx-and-runmsgs) is checking a transaction created from the [`auth`](https://github.com/cosmos/cosmos-sdk/blob/master/docs/spec/auth) module, it first runs `ValidateBasic` on each message, then runs the `auth` module AnteHandler which calls `ValidateBasic` for the transaction itself. +* **TxEncoder:** Nodes running the consensus engine (e.g. Tendermint Core) are responsible for gossiping transactions and ordering them into blocks, but only handle them in the generic `[]byte` form. Transactions are always [marshaled](./encoding.md) (encoded) before they are relayed to nodes, which compacts them to facilitate gossiping and helps maintain the consensus engine's separation from from application logic. The Cosmos SDK allows developers to specify any deterministic encoding format for their applications; the default is Amino. * **TxDecoder:** [ABCI](https://tendermint.com/docs/spec/abci/) calls from the consensus engine to the application, such as `CheckTx` and `DeliverTx`, are used to process transaction data to determine validity and state changes. Since transactions are passed in as `txBytes []byte`, they need to first be unmarshaled (decoded) using `TxDecoder` before any logic is applied. A transaction is created through one of the possible [interfaces](#interfaces). In the process, two contexts and an array of [messages](#messages) are created, which are then used to [generate](#transaction-generation) the transaction itself. The actual state changes triggered by transactions are enabled by the [handlers](#handlers). The rest of the document will describe each of these components, in this order. ## CLI and REST Interfaces -The SDK uses several tools for building [interfaces](./interfaces.md) through which users can create transactions through the command-line or HTTP Requests. Application developers create entrypoints to the application by creating a [command-line interface](./interfaces.md#cli) or [REST interface](./interfaces.md#rest), typically found in the application's `/cmd` folder. These interfaces allow users to interact with the application through command-line or through HTTP requests. +Application developers create entrypoints to the application by creating a [command-line interface](../interfaces/cli.md) or [REST interface](../interfaces/rest.md), typically found in the application's `/cmd` folder. These interfaces allow users to interact with the application through command-line or through HTTP requests. -In order for module messages to be utilized in transactions created through these interfaces, module developers must also specify possible user [interactions](../modules/interfaces.md), typically in the module's `/client` folder. For the [command-line interface](../modules/interfaces.md#cli), module developers create subcommands to add as children to the application top-level transaction command `TxCmd`. For [HTTP requests](../modules/interfaces.md#rest), module developers specify acceptable request types, register REST routes, and create HTTP Request Handlers. +In order for module messages to be utilized in transactions created through these interfaces, module developers must also specify possible user [interactions](../building-modules/interfaces.md), typically in the module's `/client` folder. For the [command-line interface](../building-modules/interfaces.md#cli), module developers create subcommands to add as children to the application top-level transaction command `TxCmd`. For [HTTP requests](../building-modules/interfaces.md#rest), module developers specify acceptable request types, register REST routes, and create HTTP Request Handlers. When users interact with the application's interfaces, they invoke the underlying modules' handlers or command functions, directly creating messages. @@ -47,19 +47,15 @@ When users interact with the application's interfaces, they invoke the underlyin Note: module messages are not to be confused with [ABCI Messages](https://tendermint.com/docs/spec/abci/abci.html#messages) which define interactions between the Tendermint and application layers. While ABCI messages such as CheckTx and DeliverTx contain Transactions, which contain module Messages, they are not to be confused with the module level messages themselves -The [`Msg`](https://github.com/cosmos/cosmos-sdk/blob/master/types/tx_msg.go#L10-L31) interface has five required functions. - -* **Route** returns a string that specifies which module this message is a part of and, thus, which module contains the handler used to implement the actions of this message. [Baseapp](./baseapp.md) uses this function to deliver transactions by invoking the correct handler(s). For example, `MsgSend` is defined in and handled by the `bank` module; its `Route` function returns the name of the `bank` module so `Baseapp` understands to use that module's handler. -* **Type** returns a short, human-readable string that describes what the message does. For example, `MsgSend`'s type is `"send"`. -* **ValidateBasic** implements a set of stateless sanity checks for the message and returns an `Error`. For example, the `validateBasic` method for `MsgSend`, the message which sends coins from one account to another, checks that both sender and recipient addresses are valid and the amount is nonnegative. -* **GetSignBytes** returns a `[]byte` representation of the message which is used by the signer to sign it. -* **GetSigners** returns a list of addresses whose corresponding signatures are required for the message to be valid. For example, `MsgSend` requires a signature from the sender of the coins. +To learn more about messages, click [here](../building-modules/messages-and-queries.md#messages). While messages contain the information for state transition logic, a transaction's other metadata and relevant information are stored in the `TxBuilder` and `CLIContext`. ## Transaction Generation -[`Contexts`](https://godoc.org/context) are immutable objects that contain all the information needed to process a request. In the process of creating a transaction, two contexts are created: the [`CLIContext`](../interfaces/query-lifecycle.md#clicontext) and `TxBuilder`. Both are automatically generated and do not need to be defined by application developers, but do require input from the transaction creator (e.g. using flags through the CLI). +Transactions are first created by end-users through an `appcli tx` command through the command-line or a POST request to an HTTPS server. For details about transaction creation, click [here](../basics/tx-lifecycle.md#transaction-creation). + +[`Contexts`](https://godoc.org/context) are immutable objects that contain all the information needed to process a request. In the process of creating a transaction through the `auth` module (though it is not mandatory to create transactions this way), two contexts are created: the [`CLIContext`](../interfaces/query-lifecycle.md#clicontext) and `TxBuilder`. Both are automatically generated and do not need to be defined by application developers, but do require input from the transaction creator (e.g. using flags through the CLI). The [`TxBuilder`](https://github.com/cosmos/cosmos-sdk/blob/master/x/auth/types/txbuilder.go) contains data closely related with the processing of transactions: @@ -81,4 +77,4 @@ Every message in a transaction must be signed by the addresses specified by `Get ## Handlers -The final components developers must implement to enable transactions are handlers and keeprs. Each module has a Handler to process all of the module's message types. To read more about handlers, visit the documentation for building modules [here](../building-modules/handler.md). +The final components developers must implement to enable transactions are handlers and keepers. Since messages are module types, each module needs a Handler to process all of its message types and enact the state changes within the module's scope. This design puts more responsibility in module developers, allowing application developers to reuse common functionalities without having to implement state transition logic repetitively. To read more about handlers, visit the documentation for building modules [here](../building-modules/handler.md). From 81cf8e63337ac29fa59c95756de197e9fb73a68a Mon Sep 17 00:00:00 2001 From: gamarin Date: Tue, 20 Aug 2019 12:49:12 +0200 Subject: [PATCH 033/196] clean --- docs/basics/app-anatomy.md | 105 -------- docs/building-modules.md/README.md | 78 ------ docs/building-modules/README.md | 78 ------ docs/core/baseapp.md | 246 ------------------ docs/{modules/SPEC.md => spec/MODULE-SPEC.md} | 0 5 files changed, 507 deletions(-) delete mode 100644 docs/building-modules.md/README.md delete mode 100644 docs/building-modules/README.md rename docs/{modules/SPEC.md => spec/MODULE-SPEC.md} (100%) diff --git a/docs/basics/app-anatomy.md b/docs/basics/app-anatomy.md index fe06375cb436..15e1c9fc1e22 100644 --- a/docs/basics/app-anatomy.md +++ b/docs/basics/app-anatomy.md @@ -65,11 +65,6 @@ The `start` command function primarily does three things: 2. Initialize the state-machine with the latest known state, extracted from the `db` stored in the `~/.appd/data` folder. At this point, the state-machine is at height `appBlockHeight`. 3. Create and start a new Tendermint instance. Among other things, the node will perform a handshake with its peers. It will get the latest `blockHeight` from them, and replay blocks to sync to this height if it is greater than the local `appBlockHeight`. If `appBlockHeight` is `0`, the node is starting from genesis and Tendermint sends an `InitChain` message via the ABCI to the `app`, which triggers the [`InitChainer`](#initchainer). -<<<<<<< HEAD:docs/basics/app-anatomy.md -To learn more about the `start` command, [click here](../core/node.md#start-command). - -======= ->>>>>>> master:docs/basics/app-anatomy.md ## Core Application File In general, the core of the state-machine is defined in a file called `app.go`. It mainly contains the **type definition of the application** and functions to **create and initialize it**. @@ -78,19 +73,11 @@ In general, the core of the state-machine is defined in a file called `app.go`. The first thing defined in `app.go` is the `type` of the application. It is generally comprised of the following parts: -<<<<<<< HEAD:docs/basics/app-anatomy.md - **A reference to [`baseapp`](../core/baseapp.md).** The custom application defined in `app.go` is an extension of the `baseapp` type. `baseapp` implements most of the core logic for the application, including all the [ABCI methods](https://tendermint.com/docs/spec/abci/abci.html#overview) and the routing logic. When a transaction is relayed by Tendermint to the application, the latter uses `baseapp`'s methods to route them to the appropriate module. - **A list of store keys**. The [store](../core/store.md), which contains the entire state, is implemented as a multistore (i.e. a store of stores) in the Cosmos SDK. Each module uses one or multiple stores in the multistore to persist their part of the state. These stores can be accessed with specific keys that are declared in the `app` type. These keys, along with the `keepers`, are at the heart of the [object-capabilities model](../intro/ocap.md) of the Cosmos SDK. - **A list of module's `keepers`.** Each module defines an abstraction called [`keeper`](../building-modules/keeper.md), which handles reads and writes for this module's store(s). The `keeper`'s methods of one module can be called from other modules (if authorized), which is why they are declared in the application's type and exported as interfaces to other modules so that they are only allowed to access the authorized functions. - **A reference to a [`codec`](../core/encoding.md).** The Cosmos SDK gives developers the freedom to choose the encoding framework for their application. The application's `codec` is used to serialize and deserialize data structures in order to store them, as stores can only persist `[]bytes`. The `codec` must be deterministic. The default codec is [amino](./amino.md). - **A reference to a [module manager](../building-modules/module-manager.md#manager)** and a [basic module manager](../building-modules/module-manager.md#basicmanager). The module manager is an object that contains a list of the application's module. It facilitates operations related to these modules, like registering [`routes`](./baseapp.md#routing), [query routes](#./baseapp.md#query-routing) or setting the order of execution between modules for various functions like [`InitChainer`](#initchainer), [`BeginBlocker` and `EndBlocker`](#beginblocker-and-endblocker). -======= -- **A reference to [`baseapp`](./baseapp.md).** The custom application defined in `app.go` is an extension of the `baseapp` type. `baseapp` implements most of the core logic for the application, including all the [ABCI methods](https://tendermint.com/docs/spec/abci/abci.html#overview) and the routing logic. When a transaction is relayed by Tendermint to the application, the latter uses `baseapp`'s methods to route them to the appropriate module. -- **A list of store keys**. The [store](./store.md), which contains the entire state, is implemented as a multistore (i.e. a store of stores) in the Cosmos SDK. Each module uses one or multiple stores in the multistore to persist their part of the state. These stores can be accessed with specific keys that are declared in the `app` type. These keys, along with the `keepers`, are at the heart of the [object-capabilities model](../intro/ocap.md) of the Cosmos SDK. -- **A list of module's `keepers`.** Each module defines an abstraction called `keeper`, which handles reads and writes for this module's store(s). The `keeper`'s methods of one module can be called from other modules (if authorized), which is why they are declared in the application's type and exported as interfaces to other modules so that they are only allowed to access the authorized functions. -- **A reference to a `codec`.** The Cosmos SDK gives developers the freedom to choose the encoding framework for their application. The application's `codec` is used to serialize and deserialize data structures in order to store them, as stores can only persist `[]bytes`. The `codec` must be deterministic. The default codec is [amino](./amino.md). -- **A reference to a [module manager](./modules.md#module-manager)**. The module manager is an object that contains a list of the application's module. It facilitates operations related to these modules, like registering [`routes`](./baseapp.md#routing), [query routes](#./baseapp.md#query-routing) or setting the order of execution between modules for various functions like [`InitChainer`](#initchainer), [`BeginBlocker` and `EndBlocker`](#beginblocker-and-endblocker). ->>>>>>> master:docs/basics/app-anatomy.md You can see an example of application type definition [here](https://github.com/cosmos/gaia/blob/master/app/app.go#L73-L107). @@ -100,7 +87,6 @@ This function constructs a new application of the type defined above. It is call - Instantiate a new [`codec`](../core/encoding.md) and initialize the `codec` of each of the application's module using the [basic manager](../building-modules/module-manager.md#basicmanager) - Instantiate a new application with a reference to a `baseapp` instance, a codec and all the appropriate store keys. -<<<<<<< HEAD:docs/basics/app-anatomy.md - Instantiate all the [`keeper`s](#keeper) defined in the application's `type` using the `NewKeeper` function of each of the application's modules. Note that `keepers` must be instantiated in the correct order, as the `NewKeeper` of one module might require a reference to another module's `keeper`. - Instantiate the application's [module manager](../building-modules/module-manager.md#manager) with the [`AppModule`](#application-module-interface) object of each of the application's modules. - With the module manager, initialize the application's [`routes`](../core/baseapp.md#routing) and [query routes](../core/baseapp.md#query-routing). When a transaction is relayed to the application by Tendermint via the ABCI, it is routed to the appropriate module's [`handler`](#handler) using the routes defined here. Likewise, when a query is received by the application, it is routed to the appropriate module's [`querier`](#querier) using the query routes defined here. @@ -112,19 +98,6 @@ This function constructs a new application of the type defined above. It is call + [`anteHandler`](../core/baseapp.md#antehandler): used to handle fees and signature verification. - Mount the stores. - Return the application. -======= -- Instantiate all the [`keeper`s](#keeper) defined in the application's `type` using the `NewKeeper` function of each of the application's modules. Note that `keepers` must be instantiated in the correct order, as the `NewKeeper` of one module might require a reference to another module's `keeper`. -- Instantiate the application's [module manager](./module-manager.md) with the [`AppModule`](#application-module-interface) object of each of the application's modules. -- With the module manager, initialize the application's [`routes`](./baseapp.md#routing) and [query routes](./baseapp.md#query-routing). When a transaction is relayed to the application by Tendermint via the ABCI, it is routed to the appropriate module's [`handler`](#handler) using the routes defined here. Likewise, when a query is received by the application, it is routed to the appropriate module's [`querier`](#querier) using the query routes defined here. -- With the module manager, register the [application's modules' invariants](./invariants.md). Invariants are variables (e.g. total supply of a token) that are evaluated at the end of each block. The process of checking invariants is done via a special module called the [`InvariantsRegistry`](./invariants.md#invariant-registry). The value of the invariant should be equal to a predicted value defined in the module. Should the value be different than the predicted one, special logic defined in the invariant registry will be triggered (usually the chain is halted). This is useful to make sure no critical bug goes unnoticed and produces long-lasting effects that would be hard to fix. -- With the module manager, set the order of execution between the `InitGenesis`, `BegingBlocker` and `EndBlocker` functions of each of the [application's modules](#application-module-interface). Note that not all modules implement these functions. -- Set the remainer of application's parameters: - - [`InitChainer`](#initchainer): used to initialize the application when it is first started. - - [`BeginBlocker`, `EndBlocker`](#beginblocker-and-endlbocker): called at the beginning and the end of every block). - - [`anteHandler`](#baseapp.md#antehandler): used to handle fees and signature verification. -- Mount the stores. -- Return the application. ->>>>>>> master:docs/basics/app-anatomy.md Note that this function only creates an instance of the app, while the actual state is either carried over from the `~/.appd/data` folder if the node is restarted, or generated from the genesis file if the node is started for the first time. @@ -132,11 +105,7 @@ You can see an example of application constructor [here](https://github.com/cosm ### InitChainer -<<<<<<< HEAD:docs/basics/app-anatomy.md The `InitChainer` is a function that initializes the state of the application from a [genesis file](../core/genesis.md) (i.e. token balances of genesis accounts). It is called when the application receives the `InitChain` message from the Tendermint engine, which happens when the node is started at `appBlockHeight == 0` (i.e. on genesis). The application must set the `InitChainer` in its constructor via the [`SetInitChainer`](https://godoc.org/github.com/cosmos/cosmos-sdk/baseapp#BaseApp.SetInitChainer) method. -======= -The `InitChainer` is a function that initializes the state of the application from a [genesis file](./genesis.md) (i.e. token balances of genesis accounts). It is called when the application receives the `InitChain` message from the Tendermint engine, which happens when the node is started at `appBlockHeight == 0` (i.e. on genesis). The application must set the `InitChainer` in its constructor via the [`SetInitChainer`](https://godoc.org/github.com/cosmos/cosmos-sdk/baseapp#BaseApp.SetInitChainer) method. ->>>>>>> master:docs/basics/app-anatomy.md In general, the `InitChainer` is mostly composed of the `InitGenesis` function of each of the application's modules. This is done by calling the `InitGenesis` function of the module manager, which in turn will call the `InitGenesis` function of each of the modules it contains. Note that the order in which the modules' `InitGenesis` functions must be called has to be set in the module manager using the `SetOrderInitGenesis` method. This is done in the [application's constructor](#application-constructor), and the `SetOrderInitGenesis` has to be called before the `SetInitChainer`. @@ -148,11 +117,7 @@ The SDK offers developers the possibility to implement automatic execution of co In general, the `BeginBlocker` and `EndBlocker` functions are mostly composed of the `BeginBlock` and `EndBlock` functions of each of the application's modules. This is done by calling the `BeginBlock` and `EndBlock` functions of the module manager, which in turn will call the `BeginBLock` and `EndBlock` functions of each of the modules it contains. Note that the order in which the modules' `BegingBlock` and `EndBlock` functions must be called has to be set in the module manager using the `SetOrderBeginBlock` and `SetOrderEndBlock` methods respectively. This is done in the [application's constructor](#application-constructor), and the `SetOrderBeginBlock` and `SetOrderEndBlock` methods have to be called before the `SetBeginBlocker` and `SetEndBlocker` functions. -<<<<<<< HEAD:docs/basics/app-anatomy.md As a sidenote, it is important to remember that application-specific blockchains are deterministic. Developers must be careful not to introduce non-determinism in `BeginBlocker` or `EndBlocker`, and must also be careful not to make them too computationally expensive, as [gas](./accounts-fees-gas.md/gas) does not constrain the cost of `BeginBlocker` and `EndBlocker` execution. -======= -As a sidenote, it is important to remember that application-specific blockchains are deterministic. Developers must be careful not to introduce non-determinism in `BeginBlocker` or `EndBlocker`, and must also be careful not to make them too computationally expensive, as gas does not constrain the cost of `BeginBlocker` and `EndBlocker` execution. ->>>>>>> master:docs/basics/app-anatomy.md You can see an example of `BeginBlocker` and `EndBlocker` functions [here](https://github.com/cosmos/gaia/blob/master/app/app.go#L224-L232). @@ -160,17 +125,12 @@ You can see an example of `BeginBlocker` and `EndBlocker` functions [here](https The `MakeCodec` function is the last important function of the `app.go` file. The goal of this function is to instantiate a codec `cdc` (e.g. amino) initialize the codec of the SDK and each of the application's modules using the `RegisterCodec` function. -<<<<<<< HEAD:docs/basics/app-anatomy.md To register the application's modules, the `MakeCodec` function calls `RegisterCodec` on `ModuleBasics`. `ModuleBasics` is a [basic manager](../building-modules/module-manager.md#basicmanager) which lists all of the application's modules. It is instanciated in the `init()` function, and only serves to easily register non-dependant elements of application's modules (such as codec). To learn more about the basic module manager, click [here](../building-modules/module-manager.md#basicmanager). -======= -To register the application's modules, the `MakeCodec` function calls `RegisterCodec` on `ModuleBasics`. `ModuleBasics` is a basic manager which lists all of the application's modules. It is instantiated in the `init()` function, and only serves to easily register non-dependent elements of application's modules (such as codec). To learn more about the basic module manager,. ->>>>>>> master:docs/basics/app-anatomy.md You can see an example of a `MakeCodec` [here](https://github.com/cosmos/gaia/blob/master/app/app.go#L64-L70) ## Modules -<<<<<<< HEAD:docs/basics/app-anatomy.md Modules are the heart and soul of an SDK application. They can be considered as state-machines within the state-machine. When a transaction is relayed from the underlying Tendermint engine via the ABCI to the application, it is routed by [`baseapp`](../core/baseapp.md) to the appropriate module in order to be processed. This paradigm enables developers to easily build complex state-machines, as most of the modules they need often already exist. For developers, most of the work involved in building an SDK application revolves around building custom modules required by their application that do not exist, and integrating them with modules that do already exist into one coherent application. In the application directory, the standard practice is to store modules in the `x/` folder (not to be confused with the SDK's `x/` folder, which contains already-built modules). To learn more about modules, [click here](./modules.md) @@ -178,58 +138,32 @@ To learn more about modules, [click here](./modules.md) ### Application Module Interface Modules implement two interfaces defined in the Cosmos SDK, [`AppModuleBasic`](../building-modules/module-manager.md#appmodulebasic) and [`AppModule`](../building-modules/module-manager.md#appmodule). The former implements basic non-dependant elements of the module, such as the `codec`, while the latter handles the bulk of the module methods (including methods that require references to other modules' `keeper`s). Both the `AppModule` and `AppModuleBasic` types are defined in a file called `./module.go`. -======= -Modules are the heart and soul of an SDK application. They can be considered as state-machines within the state-machine. When a transaction is relayed from the underlying Tendermint engine via the ABCI to the application, it is routed by `baseapp` to the appropriate module in order to be processed. This paradigm enables developers to easily build complex state-machines, as most of the modules they need often already exist. For developers, most of the work involved in building an SDK application revolves around building custom modules required by their application that do not exist, and integrating them with modules that do already exist into one coherent application. In the application directory, the standard practice is to store modules in the `x/` folder (not to be confused with the SDK's `x/` folder, which contains already-built modules). - -### Application Module Interface - -Modules implement two interfaces defined in the Cosmos SDK, [`AppModuleBasic`](https://github.com/cosmos/cosmos-sdk/blob/master/types/module/module.go#L44-L57) and [`AppModule`](https://github.com/cosmos/cosmos-sdk/blob/master/types/module/module.go#L44-L57). The former implements basic non-dependant elements of the module, such as the `codec`, while the latter handles the bulk of the module methods (including methods that require references to other modules' `keeper`s). Both the `AppModule` and `AppModuleBasic` types are defined in a file called `./module.go`. ->>>>>>> master:docs/basics/app-anatomy.md `AppModule` exposes a collection of useful methods on the module that facilitates the composition of modules into a coherent application. These methods are are called from the `module manager`(../building-modules/module-manager.md#manager), which manages the application's collection of modules. -<<<<<<< HEAD:docs/basics/app-anatomy.md To learn more about the application module interface, [click here](../building-modules/module-manager.md#application-module-interfaces). -======= -- `Route()` and `QueryRoute()`: These methods the name of the route and querier route for the module, for [messages](#message-types) to be routed to the module's [`handler`](#handler) and queries to be routes to the module's [`querier`](#querier). -- `NewHandler()` and `NewQuerierHandler()`: These methods return a `handler` and `querierHandler` respectively, in order to process a message or a query once they are routed. -- `BeginBlock()`, `EndBlock()` and `InitGenesis()`: These methods are executed respectively at the beginning of each block, at the end of each block and at the start of the chain. They implement special logic the module requires to be triggered during those events. For example, the `EndBlock` function is frequently used by modules where voting occurs to tally the result of the votes. -- `RegisterInvariants()`: This method registers the [invariants](./invariants.md) for the module. Invariants are checked at the end of every block to make sure no unpredicted behaviour is occuring. -- `AppModule`'s methods are called from the `module manager`, which manages the application's collection of modules. ->>>>>>> master:docs/basics/app-anatomy.md ### Message Types A message is a custom type defined by each module that implements the [`message`](../building-modules/messages-and-queries.md#messages) interface. Each [`transaction`](../core/transaction.md) contains one or multiple `messages`. When a valid block of transactions is received by the full-node, Tendermint relays each one to the application via [`DeliverTx`](https://tendermint.com/docs/app-dev/abci-spec.html#delivertx). Then, the application handles the transaction: -<<<<<<< HEAD:docs/basics/app-anatomy.md 1. Upon receiving the transaction, the application first unmarshalls it from `[]bytes`. 2. Then, it verifies a few things about the transaction like [fee payment and signatures](#accounts-fees-gas.md) before extracting the message(s) contained in the transaction. 3. With the [`Type()`](https://github.com/cosmos/cosmos-sdk/blob/master/types/tx_msg.go#L16) method, `baseapp` is able to know which modules defines the message. It is then able to route it to the appropriate module's [handler](#handler) in order for the message to be processed. 4. If the message is successfully processed, the state is updated. -======= -1. Upon receiving the transaction, the application first unmarshals it from `[]bytes`. -2. Then, it verifies a few things about the transaction like [fee payment and signatures](#accounts-fees-gas.md) before extracting the message(s) contained in the transaction. -3. With the [`Type()`](https://github.com/cosmos/cosmos-sdk/blob/master/types/tx_msg.go#L16) method, `baseapp` is able to know which modules defines the message. It is then able to route it to the appropriate module's [handler](#handler) in order for the message to be processed. -4. If the message is successfully processed, the state is updated. ->>>>>>> master:docs/basics/app-anatomy.md For a more detailed look at a transaction lifecycle, click [here](./tx-lifecycle.md). Module developers create custom message types when they build their own module. The general practice is to prefix the type declaration of the message with `Msg`. For example, the message type [`MsgSend`](https://github.com/cosmos/cosmos-sdk/blob/master/x/bank/types/msgs.go#L10-L15) allows users to transfer tokens. It is processed by the handler of the `bank` module, which ultimately calls the `keeper` of the `auth` module in order to update the state. -<<<<<<< HEAD:docs/basics/app-anatomy.md To learn more about messages, [click here](../building-modules/messages-and-queries.md#messages). -======= ->>>>>>> master:docs/basics/app-anatomy.md ### Handler The [`handler`](../building-modules/handler.md) refers to the part of the module responsible for processing the message after it is routed by `baseapp`. `handler` functions of modules (except those of the `auth` module) are only executed if the transaction is relayed from Tendermint by the `DeliverTx` ABCI message. If the transaction is relayed by `CheckTx`, only stateless checks and fee-related (i.e. `auth` module-related) stateful checks are performed. To better understand the difference between `DeliverTx`and `CheckTx`, as well as the difference between stateful and stateless checks, click [here](./tx-lifecycle.md). The handler of a module is generally defined in a file called `handler.go` and consists of: -<<<<<<< HEAD:docs/basics/app-anatomy.md - A **switch function** `NewHandler` to route the message to the appropriate handler function. This function returns a `handler` function, and is registered in the [`AppModule`](#application-module-interface) to be used in the application's module manager to initialize the [application's router](../core/baseapp.md#routing). See an example of such a switch [here](https://github.com/cosmos/sdk-application-tutorial/blob/master/x/nameservice/handler.go#L10-L22). - **One handler function for each message type defined by the module**. Developers write the message processing logic in these functions. This generally involves doing stateful checks to ensure the message is valid and calling [`keeper`](#keeper)'s methods to update the state. @@ -237,13 +171,6 @@ Handler functions return a result of type [`sdk.Result`](https://github.com/cosm To learn more about handlers, [click here](../building-modules/handler.md). -======= -- A **switch function** `NewHandler` to route the message to the appropriate handler function. This function returns a `handler` function, and is registered in the [`AppModule`](#application-module-interface) to be used in the application's module manager to initialize the application's router. See an example of such a switch [here](https://github.com/cosmos/sdk-application-tutorial/blob/master/x/nameservice/handler.go#L10-L22). -- **One handler function for each message type defined by the module**. Developers write the message processing logic in these functions. This generally involves doing stateful checks to ensure the message is valid and calling [`keeper`](#keeper)'s methods to update the state. - -Handler functions return a result of type [`sdk.Result`](https://github.com/cosmos/cosmos-sdk/blob/master/types/result.go#L14-L37), which informs the application on whether the message was successfully processed. - ->>>>>>> master:docs/basics/app-anatomy.md ### Keeper [`Keepers`](../building-module/keeper.md) are the gatekeepers of their module's store(s). To read or write in a module's store, it is mandatory to go through one of its `keeper`'s methods. This is ensured by the [object-capabilities](../core/ocap.md) model of the Cosmos SDK. Only objects that hold the key to a store can access it, and only the module's `keeper` should hold the key(s) to the module's store(s). @@ -260,7 +187,6 @@ Along with the type definition, the next important component of the `keeper.go` The rest of the file defines the `keeper`'s methods, primarily getters and setters. You can check an example of a `keeper` implementation [here](https://github.com/cosmos/sdk-application-tutorial/blob/master/x/nameservice/keeper.go). -<<<<<<< HEAD:docs/basics/app-anatomy.md To learn more about `keepers`, [click here](../building-modules/keeper.md). ### Querier @@ -273,16 +199,6 @@ The `Querier` of a module is defined in a file called `querier.go`, and consists - - **One querier function for each data type defined by the module that needs to be queryable**. Developers write the query processing logic in these functions. This generally involves calling [`keeper`](#keeper)'s methods to query the state and marshalling it to JSON. See an example of `querier` functions [here](https://github.com/cosmos/sdk-application-tutorial/blob/master/x/nameservice/querier.go#L37-L101). To learn more about `queriers`, [click here](../building-modules/querier.md). -======= -### Querier - -`Queriers` are very similar to `handlers`, except they serve user queries to the state as opposed to processing transactions. A query is initiated from an [interface](#intefaces) by an end-user who provides a `queryRoute` and some `data`. The query is then routed to the correct application's `querier` by `baseapp`'s [`handleQueryCustom`](https://github.com/cosmos/cosmos-sdk/blob/master/baseapp/baseapp.go#L519-L556) method using `queryRoute`. - -The `Querier` of a module is defined in a file called `querier.go`, and consists of: - -- A **switch function** `NewQuerier` to route the query to the appropriate `querier` function. This function returns a `querier` function, and is is registered in the [`AppModule`](#application-module-interface) to be used in the application's module manager to initialize the application's query router. See an example of such a switch [here](https://github.com/cosmos/sdk-application-tutorial/blob/master/x/nameservice/querier.go#L21-L34). -- - **One querier function for each data type defined by the module that needs to be queryable**. Developers write the query processing logic in these functions. This generally involves calling [`keeper`](#keeper)'s methods to query the state and marshaling it to JSON. See an example of `querier` functions [here](https://github.com/cosmos/sdk-application-tutorial/blob/master/x/nameservice/querier.go#L37-L101). ->>>>>>> master:docs/basics/app-anatomy.md ### Command-Line and REST Interfaces @@ -295,17 +211,11 @@ Generally, the commands related to a module are defined in a folder called `clie - Transactions commands let users generate new transactions so that they can be included in a block and eventually update the state. One command should be created for each [message type](#message-types) defined in the module. The command calls the constructor of the message with the parameters provided by the end-user, and wraps it into a transaction. The SDK handles signing and the addition of other transaction metadata. See examples of transactions commands [here](https://github.com/cosmos/sdk-application-tutorial/blob/master/x/nameservice/client/cli/tx.go). - Queries let users query the subset of the state defined by the module. Query commands forward queries to the [application's query router](./baseapp.md#query-routing), which routes them to the appropriate [querier](#querier) the `queryRoute` parameter supplied. See examples of query commands [here](https://github.com/cosmos/sdk-application-tutorial/blob/master/x/nameservice/client/cli/query.go). -<<<<<<< HEAD:docs/basics/app-anatomy.md To learn more about modules CLI, [click here](../building-modules/module-interfaces.md#cli). #### REST The module's REST interface lets users generate transactions and query the state through REST calls to the application's [light client daemon](../core/node.md#lcd) (LCD). REST routes are defined in a file `client/rest/rest.go`, which is composed of: -======= -#### REST - -The module's REST interface lets users generate transactions and query the state through REST calls to the application's light client daemon (LCD). REST routes are defined in a file `client/rest/rest.go`, which is composed of: ->>>>>>> master:docs/basics/app-anatomy.md - A `RegisterRoutes` function, which registers each route defined in the file. This function is called from the [main application's interface](#application-interfaces) for each module used within the application. The router used in the SDK is [Gorilla's mux](https://github.com/gorilla/mux). - Custom request type definitions for each query or transaction creation function that needs to be exposed. These custom request types build on the [base `request` type](https://github.com/cosmos/cosmos-sdk/blob/master/types/rest/rest.go#L32-L43) of the Cosmos SDK. @@ -313,16 +223,12 @@ The module's REST interface lets users generate transactions and query the state See an example of a module's `rest.go` file [here](https://github.com/cosmos/sdk-application-tutorial/blob/master/x/nameservice/client/rest/rest.go). -<<<<<<< HEAD:docs/basics/app-anatomy.md To learn more about modules REST interface, [click here](../building-modules/module-interfaces.md#rest). -======= ->>>>>>> master:docs/basics/app-anatomy.md ## Application Interface Interfaces let end-users interact with full-node clients. This means querying data from the full-node or creating and sending new transactions to be relayed by the full-node and eventually included in a block. -<<<<<<< HEAD:docs/basics/app-anatomy.md The main interface is the [Command-Line Interface](../interfaces/cli.md). The CLI of an SDK application is built by aggregating [CLI commands](#cli) defined in each of the modules used by the application. The CLI of an application generally has the `-cli` suffix (e.g. `appcli`), and defined in a file called `cmd/appcli/main.go`. The file contains: - **A `main()` function**, which is executed to build the `appcli` interface client. This function prepares each command and adds them to the `rootCmd` before building them. At the root of `appCli`, the function adds generic commands like `status`, `keys` and `config`, query commands, tx commands and `rest-server`. @@ -334,17 +240,6 @@ See an example of an application's main command-line file [here](https://github. To learn more about interfaces, [click here](../interfaces/intro.md). -======= -The main interface is the Command-Line Interface. The CLI of an SDK application is built by aggregating [CLI commands](#cli) defined in each of the modules used by the application. The CLI of an application generally has the `-cli` suffix (e.g. `appcli`), and defined in a file called `cmd/appcli/main.go`. The file contains: - -- **A `main()` function**, which is executed to build the `appcli` interface client. This function prepares each command and adds them to the `rootCmd` before building them. At the root of `appCli`, the function adds generic commands like `status`, `keys` and `config`, query commands, tx commands and `rest-server`. -- **Query commands** are added by calling the `queryCmd` function, also defined in `appcli/main.go`. This function returns a Cobra command that contains the query commands defined in each of the application's modules (passed as an array of `sdk.ModuleClients` from the `main()` function), as well as some other lower level query commands such as block or validator queries. Query command are called by using the command `appcli query [query]` of the CLI. -- **Transaction commands** are added by calling the `txCmd` function. Similar to `queryCmd`, the function returns a Cobra command that contains the tx commands defined in each of the application's modules, as well as lower level tx commands like transaction signing or broadcasting. Tx commands are called by using the command `appcli tx [tx]` of the CLI. -- **A `registerRoutes` function**, which is called from the `main()` function when initializing the [application's light-client daemon (LCD)](./node.md#lcd) (i.e. `rest-server`). `registerRoutes` calls the `RegisterRoutes` function of each of the application's module, thereby registering the routes of the module to the lcd's router. The LCD can be started by running the following command `appcli rest-server`. - -See an example of an application's main command-line file [here](https://github.com/cosmos/sdk-application-tutorial/blob/master/cmd/nscli/main.go). - ->>>>>>> master:docs/basics/app-anatomy.md ## Dependencies and Makefile This section is optional, as developers are free to choose their depencency manager and project building method. That said, the current most used framework for versioning control is [`go.mod`](https://github.com/golang/go/wiki/Modules). It ensures each of the libraries used throughout the application are imported with the correct version. An example can be found [here](https://github.com/cosmos/sdk-application-tutorial/blob/master/go.mod). diff --git a/docs/building-modules.md/README.md b/docs/building-modules.md/README.md deleted file mode 100644 index 5b5743671751..000000000000 --- a/docs/building-modules.md/README.md +++ /dev/null @@ -1,78 +0,0 @@ -# Auth - -The `x/auth` modules is used for accounts - -See the [API docs](https://godoc.org/github.com/cosmos/cosmos-sdk/x/auth) - -See the [specification](https://github.com/cosmos/cosmos-sdk/tree/master/docs/spec/auth) - -# Bank - -The `x/bank` module is for transferring coins between accounts. - -See the [API docs](https://godoc.org/github.com/cosmos/cosmos-sdk/x/bank). - -See the [specification](https://github.com/cosmos/cosmos-sdk/tree/master/docs/spec/bank) - -# Stake - -The `x/staking` module is for Cosmos Delegated-Proof-of-Stake. - -See the [API docs](https://godoc.org/github.com/cosmos/cosmos-sdk/x/staking). - -See the -[specification](https://github.com/cosmos/cosmos-sdk/tree/master/docs/spec/staking) - -# Slashing - -The `x/slashing` module is for Cosmos Delegated-Proof-of-Stake. - -See the [API docs](https://godoc.org/github.com/cosmos/cosmos-sdk/x/slashing) - -See the -[specification](https://github.com/cosmos/cosmos-sdk/tree/master/docs/spec/slashing) - -# Distribution - -The `x/distribution` module is for distributing fees and inflation across bonded -stakeholders. - -See the [API docs](https://godoc.org/github.com/cosmos/cosmos-sdk/x/distribution) - -See the -[specification](https://github.com/cosmos/cosmos-sdk/tree/master/docs/spec/distribution) - -# Governance - -The `x/gov` module is for bonded stakeholders to make proposals and vote on them. - -See the [API docs](https://godoc.org/github.com/cosmos/cosmos-sdk/x/gov) - -See the -[specification](https://github.com/cosmos/cosmos-sdk/tree/master/docs/spec/governance) - -To keep up with the current status of IBC, follow and contribute to [ICS](https://github.com/cosmos/ics) - -# Crisis - -The `x/crisis` module is for halting the blockchain under certain circumstances. - -See the [API Docs](https://godoc.org/github.com/cosmos/cosmos-sdk/x/crisis) - -See the [specification](https://github.com/cosmos/cosmos-sdk/blob/master/docs/spec/crisis) - -# Mint - -The `x/mint` module is for flexible inflation rates and effect a balance between market liquidity and staked supply. - -See the [API Docs](https://godoc.org/github.com/cosmos/cosmos-sdk/x/mint) - -See the [specification](https://github.com/cosmos/cosmos-sdk/blob/master/docs/spec/mint) - -# Params - -The `x/params` module provides a globally available parameter store. - -See the [API Docs](https://godoc.org/github.com/cosmos/cosmos-sdk/x/params) - -See the [specification](https://github.com/cosmos/cosmos-sdk/blob/master/docs/spec/params) diff --git a/docs/building-modules/README.md b/docs/building-modules/README.md deleted file mode 100644 index 5b5743671751..000000000000 --- a/docs/building-modules/README.md +++ /dev/null @@ -1,78 +0,0 @@ -# Auth - -The `x/auth` modules is used for accounts - -See the [API docs](https://godoc.org/github.com/cosmos/cosmos-sdk/x/auth) - -See the [specification](https://github.com/cosmos/cosmos-sdk/tree/master/docs/spec/auth) - -# Bank - -The `x/bank` module is for transferring coins between accounts. - -See the [API docs](https://godoc.org/github.com/cosmos/cosmos-sdk/x/bank). - -See the [specification](https://github.com/cosmos/cosmos-sdk/tree/master/docs/spec/bank) - -# Stake - -The `x/staking` module is for Cosmos Delegated-Proof-of-Stake. - -See the [API docs](https://godoc.org/github.com/cosmos/cosmos-sdk/x/staking). - -See the -[specification](https://github.com/cosmos/cosmos-sdk/tree/master/docs/spec/staking) - -# Slashing - -The `x/slashing` module is for Cosmos Delegated-Proof-of-Stake. - -See the [API docs](https://godoc.org/github.com/cosmos/cosmos-sdk/x/slashing) - -See the -[specification](https://github.com/cosmos/cosmos-sdk/tree/master/docs/spec/slashing) - -# Distribution - -The `x/distribution` module is for distributing fees and inflation across bonded -stakeholders. - -See the [API docs](https://godoc.org/github.com/cosmos/cosmos-sdk/x/distribution) - -See the -[specification](https://github.com/cosmos/cosmos-sdk/tree/master/docs/spec/distribution) - -# Governance - -The `x/gov` module is for bonded stakeholders to make proposals and vote on them. - -See the [API docs](https://godoc.org/github.com/cosmos/cosmos-sdk/x/gov) - -See the -[specification](https://github.com/cosmos/cosmos-sdk/tree/master/docs/spec/governance) - -To keep up with the current status of IBC, follow and contribute to [ICS](https://github.com/cosmos/ics) - -# Crisis - -The `x/crisis` module is for halting the blockchain under certain circumstances. - -See the [API Docs](https://godoc.org/github.com/cosmos/cosmos-sdk/x/crisis) - -See the [specification](https://github.com/cosmos/cosmos-sdk/blob/master/docs/spec/crisis) - -# Mint - -The `x/mint` module is for flexible inflation rates and effect a balance between market liquidity and staked supply. - -See the [API Docs](https://godoc.org/github.com/cosmos/cosmos-sdk/x/mint) - -See the [specification](https://github.com/cosmos/cosmos-sdk/blob/master/docs/spec/mint) - -# Params - -The `x/params` module provides a globally available parameter store. - -See the [API Docs](https://godoc.org/github.com/cosmos/cosmos-sdk/x/params) - -See the [specification](https://github.com/cosmos/cosmos-sdk/blob/master/docs/spec/params) diff --git a/docs/core/baseapp.md b/docs/core/baseapp.md index 34a3934975fd..6c3d2dd9e506 100644 --- a/docs/core/baseapp.md +++ b/docs/core/baseapp.md @@ -7,11 +7,7 @@ ## Synopsis -<<<<<<< HEAD This document describes `baseapp`, the abstraction that implements most of the common functionalities of an SDK application. -======= -This document describes `baseapp`, the abstraction that implements most of the common functionalities of an SDK application. ->>>>>>> master - [Introduction](#introduction) - [Type Definition](#type-definition) @@ -19,7 +15,6 @@ This document describes `baseapp`, the abstraction that implements most of the c - [States](#states) - [Routing](#routing) - [Main ABCI Messages](#abci) -<<<<<<< HEAD + [CheckTx](#checktx) + [DeliverTx](#delivertx) - [RunTx, AnteHandler and RunMsgs](#runtx-antehandler-and-runmsgs) @@ -45,33 +40,6 @@ This document describes `baseapp`, the abstraction that implements most of the c The goal of `baseapp` is to provide a boilerplate SDK application that developers can easily extend to build their own custom application. Usually, developers will create a custom type for their application, like so: ```go -======= - - [CheckTx](#checktx) - - [DeliverTx](#delivertx) -- [RunTx(), AnteHandler and RunMsgs](<#runtx()-,antehandler-and-runmsgs()>) - - [RunTx()](<#runtx()>) - - [AnteHandler](#antehandler) - - [RunMsgs()](<#runmsgs()>) -- [Other ABCI Message](#other-abci-message) - - [InitChain](#initchain) - - [BeginBlock](#beginblock) - - [EndBlock](#endblock) - - [Commit](#commit) - - [Info](#info) - - [Query](#query) - -## Introduction - -`baseapp` is a base class that implements the core of an SDK application, namely: - -- The [Application-Blockchain Interface](#abci), for the state-machine to communicate with the underlying consensus engine (e.g. Tendermint). -- A [Router](#routing), to route messages and queries to the appropriate module. -- Different [states](#states), as the state-machine can have different parallel states updated based on the ABCI message received. - -The goal of `baseapp` is to provide the fundamental layer of an SDK application that developers can easily extend to build their own custom application. Usually, developers will create a custom type for their application, like so: - -```go ->>>>>>> master type app struct { *bam.BaseApp // reference to baseapp cdc *codec.Codec @@ -84,17 +52,12 @@ type app struct { } ``` -<<<<<<< HEAD Extending the application with `baseapp` gives the former access to all of `baseapp`'s methods. This allows developers to compose their custom application with the modules they want, while not having to concern themselves with the hard work of implementing the ABCI, the routing and state management logic. -======= -Extending the application with `baseapp` gives the former access to all of `baseapp`'s methods. This allows developers to compose their custom application with the modules they want, while not having to concern themselves with the hard work of implementing the ABCI, the routing and state management logic. ->>>>>>> master ## Type Definition The [`baseapp` type](https://github.com/cosmos/cosmos-sdk/blob/master/baseapp/baseapp.go#L45-L91) holds many important parameters for any Cosmos SDK based application. Let us go through the most important components. -<<<<<<< HEAD *Note: Not all parameters are described, only the most important ones. Refer to the [type definition](https://github.com/cosmos/cosmos-sdk/blob/master/baseapp/baseapp.go#L45-L91) for the full list* First, the important parameters that are initialized during the initialization of the application: @@ -107,42 +70,20 @@ First, the important parameters that are initialized during the initialization o - A [`baseKey`], to access the [main store](./store.md#main-store) in the `CommitMultiStore`. The main store is used to persist data related to the core of the application, like consensus parameters. - A [`anteHandler`](#antehandler), to handle signature verification and fee paiement when a transaction is received. - An [`initChainer`](../basics/app-anatomy.md#initchainer), [`beginBlocker` and `endBlocker`](../basics/app-anatomy.md#beginblocker-and-endblocker), which are the functions executed when the application received the [InitChain], [BeginBlock] and [EndBlock] messages from the underlying Tendermint engine. -======= -_Note: Not all parameters are described, only the most important ones. Refer to the [type definition](https://github.com/cosmos/cosmos-sdk/blob/master/baseapp/baseapp.go#L45-L91) for the full list_ - -First, the important parameters that are initialized during the initialization of the application: - -- [`CommitMultiStore`](./store.md#commit-multi-store): This is the main store of the application, which holds the canonical state that is committed at the [end of each block](#commit). This store is **not** cached, meaning it is not used to update the application's intermediate (un-committed) states. The `CommitMultiStore` is a multi-store, meaning a store of stores. Each module of the application uses one or multiple `KVStores` in the multi-store to persist their subset of the state. -- Database: The `db` is used by the `CommitMultiStore` to handle data storage. -- [Router](#message-routing): The `router` facilitates the routing of `messages` to the appropriate module for it to be processed. Here `message` refers to the transaction components that need to be processed by the application in order to update the state, and not to ABCI messages which implement the interface between the application and the underlying consensus engine. -- [Query Router](#query-routing): The `query router` facilitates the routing of queries to the appropriate module for it to be processed. These `queries` are not ABCI messages themselves, but they are relayed to the application from the underlying consensus engine via the ABCI message [`Query`](#query). -- [`TxDecoder`](https://godoc.org/github.com/cosmos/cosmos-sdk/types#TxDecoder): It is used to decode transaction `[]byte` relayed by the underlying Tendermint engine. -- [`BaseKey`]: This key is used to access the [main store](./store.md#main-store) in the `CommitMultiStore`. The main store is used to persist data related to the core of the application, like consensus parameters. -- [`AnteHandler`](#antehandler): This handler is used to handle signature verification and fee payment when a transaction is received. -- [`initChainer`](../basics/app-anatomy.md#initchainer), [`beginBlocker` and `endBlocker`](../basics/app-anatomy.md#beginblocker-and-endblocker): These are the functions executed when the application receives the [InitChain], [BeginBlock] and [EndBlock] ABCI messages from the underlying Tendermint engine. ->>>>>>> master Then, parameters used to define [volatile states](#volatile-states) (i.e. cached states): - `checkState`: This state is updated during [`CheckTx`](#checktx), and reset on [`Commit`](#commit). - `deliverState`: This state is updated during [`DeliverTx`](#delivertx), and reset on [`Commit`](#commit). -<<<<<<< HEAD Finally, a few more important parameterd: - `voteInfos`: This parameter carries the list of validators whose precommit is missing, either because they did not vote or because the proposer did not include their vote. This information is carried by the [context](#context) and can be used by the application for various things like punishing absent validators. - `minGasPrices`: This parameter defines the minimum [gas prices](./accounts-fees-gas.md#gas) accepted by the node. This is a local parameter, meaning each full-node can set a different `minGasPrices`. It is run by the [`anteHandler`](./accounts-fees-gas.md#antehandler) during `CheckTx`, mainly as a spam protection mechanism. The transaction enters the [mempool](https://tendermint.com/docs/tendermint-core/mempool.html#transaction-ordering) only if the gas price of the transaction is superior to one of the minimum gas price in `minGasPrices` (i.e. if `minGasPrices == 1uatom, 1upho`, the `gas-price` of the transaction must be superior to `1uatom` OR `1upho`). -======= -Finally, a few more important parameters: - -- `voteInfos`: This parameter carries the list of validators whose precommit is missing, either because they did not vote or because the proposer did not include their vote. This information is carried by the [context](#context) and can be used by the application for various things like punishing absent validators. -- `minGasPrices`: This parameter defines the minimum gas prices accepted by the node. This is a local parameter, meaning each full-node can set a different `minGasPrices`. It is run by the `anteHandler` during `CheckTx`, mainly as a spam protection mechanism. The transaction enters the [mempool](https://tendermint.com/docs/tendermint-core/mempool.html#transaction-ordering) only if the gas prices of the transaction is superior to one of the minimum gas price in `minGasPrices` (i.e. if `minGasPrices == 1uatom, 1upho`, the `gas-price` of the transaction must be superior to `1uatom` OR `1upho`). ->>>>>>> master - `appVersion`: Version of the application. It is set in the [application's constructor function](../basics/app-anatomy.md#constructor-function). ## Constructor -<<<<<<< HEAD `NewBaseApp(name string, logger log.Logger, db dbm.DB, txDecoder sdk.TxDecoder, options ...func(*BaseApp),)` is the constructor function for `baseapp`. It is called from the [application's constructor function](../basics/app-anatomy.md#constructor-function) each time the full-node is started. `baseapp`'s constructor function is pretty straightforward. The only thing worth noting is the possibility to add additional [`options`](https://github.com/cosmos/cosmos-sdk/blob/master/baseapp/options.go) to `baseapp` by passing `options functions` to the constructor function, which will execute them in order. `options` are generally `setters` function for important parameters, like `SetPruning()` to active pruning or `SetMinGasPrices()` to set the node's `min-gas-prices`. @@ -156,23 +97,6 @@ A list of `options` example can be found [here](https://github.com/cosmos/cosmos ``` To perform stateful checks To execute state To serve queries on received transactions transitions during DeliverTx on last-committed state -======= -`NewBaseApp(name string, logger log.Logger, db dbm.DB, txDecoder sdk.TxDecoder, options ...func(*BaseApp),)` is the constructor function for `baseapp`. It is called from the [application's constructor function](../basics/app-anatomy.md#constructor-function) each time the full-node is started. - -`baseapp`'s constructor function is pretty straightforward. The only thing worth noting is the possibility to add additional [`options`](https://github.com/cosmos/cosmos-sdk/blob/master/baseapp/options.go) to `baseapp` by passing `options functions` to the constructor function, which will execute them in order. `options` are generally `setter` functions for important parameters, like `SetPruning()` to active pruning or `SetMinGasPrices()` to set the node's `min-gas-prices`. - -A list of `options` examples can be found [here](https://github.com/cosmos/cosmos-sdk/blob/master/baseapp/options.go). Naturally, developers can add additional `options` based on their application's needs. - -## States - -`baseapp` handles various parallel states for different purposes. There is the [main state](#main-state), which is the canonical state of the application, and volatile states like [`checkState`](#checkState) and [`deliverState`](#deliverstate), which are used to handle temporary states in-between updates of the main state made during [`Commit`](#commit). - -``` - Updated whenever an unconfirmed Updated whenever a transaction To serve user queries relayed - transaction is received from the is received from the underlying from the underlying consensus - underlying consensus engine via consensus engine (as part of a block) engine via the Query ABCI message - CheckTx proposal via DeliverTx ->>>>>>> master +----------------------+ +----------------------+ +----------------------+ | CheckState(t)(0) | | DeliverState(t)(0) | | QueryState(t) | +----------------------+ | | | | @@ -196,11 +120,7 @@ DeliverTx(tx1) | | | +----------------------+ +----------------------+ | | | | | DeliverState(t)(1) | | | | | +----------------------+ | | -<<<<<<< HEAD DeliverTx(tx2) | | | | | -======= -DeliverTx(tx2) | | | | | ->>>>>>> master | | v | | | | +----------------------+ | | | | | DeliverState(t)(2) | | | @@ -218,20 +138,12 @@ Commit() | | . . . . . . . . . -<<<<<<< HEAD -======= - ->>>>>>> master ``` ### Main State -<<<<<<< HEAD The main state is the canonical state of the application. It is initialized on [`InitChain`](#initchain and updated on [`Commit`](#abci-commit) at the end of each block. -======= -The main state is the canonical state of the application. It is initialized on [`InitChain`](#initchain) and updated on [`Commit`](#abci-commit) at the end of each block. ->>>>>>> master ``` +--------+ +--------+ @@ -241,32 +153,19 @@ The main state is the canonical state of the application. It is initialized on [ +--------+ +--------+ ``` -<<<<<<< HEAD The main state is held by `baseapp` in a structure called the [`CommitMultiStore`](./store.md#commit-multi-store). This multi-store is used by developers to instantiate all the stores they need for each of their application's modules. -======= -The main state is held by `baseapp` in a structure called the `CommitMultiStore`. This multi-store is used by developers to instantiate all the stores they need for each of their application's modules. ->>>>>>> master ### Volatile States Volatile - or cached - states are used in between [`Commit`s](#commit) to manage temporary states. They are reset to the latest version of the main state after it is committed. There are two main volatile states: -<<<<<<< HEAD - `checkState`: This cached state is initialized during [`InitChain`](#initchain), updated during [`CheckTx`](#abci-checktx) when an unconfirmed transaction is received, and reset to the [main state](#main-state) on [`Commit`](#abci-commit). -======= -- `checkState`: This cached state is initialized during [`InitChain`](#initchain), updated during [`CheckTx`](#abci-checktx) when an unconfirmed transaction is received, and reset to the [main state](#main-state) on [`Commit`](#abci-commit). ->>>>>>> master - `deliverState`: This cached state is initialized during [`BeginBlock`](#beginblock), updated during [`DeliverTx`](#abci-delivertx) when a transaction included in a block is processed, and reset to the [main state](#main-state) on [`Commit`](#abci-commit). Both `checkState` and `deliverState` are of type [`state`](https://github.com/cosmos/cosmos-sdk/blob/master/baseapp/baseapp.go#L973-L976), which includes: -<<<<<<< HEAD - A [`CacheMultiStore`](https://github.com/cosmos/cosmos-sdk/blob/master/store/cachemulti/store.go), which is a cached version of the main `CommitMultiStore`. A new version of this store is committed at the end of each successful `CheckTx`/`DeliverTx` execution. - A [`Context`](./context.md), which carries general information (like raw transaction size, block height, ...) that might be needed in order to process the transaction during `CheckTx` and `DeliverTx`. The `context` also holds a cache-wrapped version of the `CacheMultiStore`, so that the `CacheMultiStore` can maintain the correct version even if an internal step of `CheckTx` or `DeliverTx` fails. -======= -- A [`CacheMultiStore`](https://github.com/cosmos/cosmos-sdk/blob/master/store/cachemulti/store.go), which is a cached version of the main `CommitMultiStore`. A new version of this store is committed at the end of each successful `CheckTx()`/`DeliverTx()` execution. -- A `Context`, which carries general information (like raw transaction size, block height, ...) that might be needed in order to process the transaction during `CheckTx()` and `DeliverTx()`. The `context` also holds a cache-wrapped version of the `CacheMultiStore`, so that the `CacheMultiStore` can maintain the correct version even if an internal step of `CheckTx()` or `DeliverTx()` fails. ->>>>>>> master ## Routing @@ -274,7 +173,6 @@ When messages and queries are received by the application, they must be routed t ### Message Routing -<<<<<<< HEAD [`Message`s](#../building-modules/messages-and-queries.md#messages) need to be routed after they are extracted from transactions, which are sent from the underlying Tendermint engine via the [`CheckTx`](#checktx) and [`DeliverTx`](#delivertx) ABCI messages. To do so, `baseapp` holds a [`router`](https://github.com/cosmos/cosmos-sdk/blob/master/baseapp/router.go) which maps `paths` (`string`) to the appropriate module [`handler`](./handler.md). Usually, the `path` is the name of the module. The application's `router` is initilalized with all the routes using the application's [module manager](../building-modules/module-manager.md), which itself is initialized with all the application's modules in the application's [constructor](../basics/app-anatomy.md#app-constructor). @@ -288,26 +186,10 @@ Just like the `router`, the `query router` is initilalized with all the query ro ## Main ABCI Messages The [Application-Blockchain Interface](https://tendermint.com/docs/spec/abci/) (ABCI) is a generic interface that connects a state-machine with a consensus engine to form a functional full-node. It can be wrapped in any language, and needs to be implemented by each application-specific blockchain built on top of an ABCI-compatible consensus engine like Tendermint. -======= -`Message`s need to be routed after they are extracted from transactions, which are sent from the underlying Tendermint engine via the [`CheckTx`](#checktx) and [`DeliverTx`](#delivertx) ABCI messages. To do so, `baseapp` holds a [`router`](https://github.com/cosmos/cosmos-sdk/blob/master/baseapp/router.go) which maps `paths` (`string`) to the appropriate module `handler`. Usually, the `path` is the name of the module. - -The application's `router` is initialized with all the routes using the application's module manager, which itself is initialized with all the application's modules in the application's [constructor](../basics/app-anatomy.md#app-constructor). - -### Query Routing - -Similar to messages, queries need to be routed to the appropriate module's querier. To do so, `baseapp` holds a [`query router`](https://github.com/cosmos/cosmos-sdk/blob/master/baseapp/queryrouter.go), which maps `paths` (`string`) to the appropriate module `querier`. Usually, the `path` is the name of the module. - -Just like the `router`, the `query router` is initialized with all the query routes using the application's module manager, which itself is initialized with all the application's modules in the application's [constructor](../basics/app-anatomy.md#app-constructor). - -## Main ABCI Messages - -The [Application-Blockchain Interface](https://tendermint.com/docs/spec/abci/) (ABCI) is a generic interface that connects a state-machine with a consensus engine to form a functional full-node. It can be wrapped in any language, and needs to be implemented by each application-specific blockchain built on top of an ABCI-compatible consensus engine like Tendermint. ->>>>>>> master The consensus engine handles two main tasks: - The networking logic, which mainly consists in gossiping block parts, transactions and consensus votes. -<<<<<<< HEAD - The consensus logic, which results in the deterministic ordering of transactions in the form of blocks. It is **not** the role of the consensus engine to define the state or the validity of transactions. Generally, transactions are handled by the consensus engine in the form of `[]bytes`, and relayed to the application via the ABCI to be decoded and processed. At keys moments in the networking and consensus processes (e.g. beginning of a block, commit of a block, reception of an unconfirmed transaction, ...), the consensus engine emits ABCI messages for the state-machine to act on. @@ -335,41 +217,11 @@ Steps 2. and 3. are performed by the [`anteHandler`](./accounts-fees-gas.md#ant - `Info (string):` Additional information. May be non-deterministic. - `GasWanted (int64)`: Amount of gas requested for transaction. It is provided by users when they generate the transaction. - `GasUsed (int64)`: Amount of gas consumed by transaction. During `CheckTx`, this value is computed by multiplying the standard cost of a transaction byte by the size of the raw transaction (click [here](https://github.com/cosmos/cosmos-sdk/blob/master/x/auth/ante.go#L101) for an example). -======= -- The consensus logic, which results in the deterministic ordering of transactions in the form of blocks. - -It is **not** the role of the consensus engine to define the state or the validity of transactions. Generally, transactions are handled by the consensus engine in the form of `[]bytes`, and relayed to the application via the ABCI to be decoded and processed. At keys moments in the networking and consensus processes (e.g. beginning of a block, commit of a block, reception of an unconfirmed transaction, ...), the consensus engine emits ABCI messages for the state-machine to act on. - -Developers building on top of the Cosmos SDK need not implement the ABCI themselves, as all the ABCI messages are implemented as a set of `baseapp`'s methods in the Cosmos SDK. Let us go through the main ABCI messages that `baseapp` handles: [`CheckTx`](#checktx) and [`DeliverTx`](#delivertx). Note that these ABCI messages are different from the `message`s contained in `transactions`, the purpose of which is to trigger state-transitions. - -### CheckTx - -The `CheckTx` ABCI message is sent by the underlying consensus engine when a new unconfirmed (i.e. not yet included in a valid block) transaction is received by a full-node, and it is handled by the `CheckTx(req abci.RequestCheckTx)` method of `baseapp` (abbreviated to `CheckTx()` thereafter). The role of `CheckTx()` is to guard the full-node's mempool (where unconfirmed transactions are stored until they are included in a block) from spam transactions. Unconfirmed transactions are relayed to peers only if they pass `CheckTx()`. - -`CheckTx()` can perform both _stateful_ and _stateless_ checks, but developers should strive to make them lightweight. In the Cosmos SDK, after decoding transactions, `CheckTx()` is implemented to do the following checks: - -1. Extract the `message`s from the transaction. -2. Perform _stateless_ checks by calling `ValidateBasic()` on each of the `messages`. This is done first, as _stateless_ checks are less computationally expensive than _stateful_ checks. If `ValidateBasic()` fail, `CheckTx` returns before running _stateful_ checks, which saves resources. -3. Perform non-module related _stateful_ checks on the account. This step is mainly about checking that the `message` signatures are valid, that enough fees are provided and that the sending account has enough funds to pay for said fees. Note that no precise `gas` counting occurs here, as `message`s are not processed. Usually, the `anteHandler` will check that the `gas` provided with the transaction is superior to a minimum reference gas amount based on the raw transaction size, in order to avoid spam with transactions that provide 0 gas. -4. Ensure that a [`Route`](#message-routing) exists for each `message`, but do **not** actually process `message`s. `Message`s only need to be processed when the canonical state need to be updated, which happens during `DeliverTx`. - -Steps 2. and 3. are performed by the `anteHandler` in the [`RunTx()`](<#runtx()-,antehandler-and-runmsgs()>) function, which `CheckTx()` calls with the `runTxModeCheck` mode. During each step of `CheckTx()`, a special [volatile state](#volatile-states) called `checkState` is updated. This state is used to keep track of the temporary changes triggered by the `CheckTx()` calls of each transaction without modifying the [main canonical state](#main-state) . For example, when a transaction goes through `CheckTx()`, the transaction's fees are deducted from the sender's account in `checkState`. If a second transaction is received from the same account before the first is processed, and the account has consumed all its funds in `checkState` during the first transaction, the second transaction will fail `CheckTx`() and be rejected. In any case, the sender's account will not actually pay the fees until the transaction is actually included in a block, because `checkState` never gets committed to the main state. `checkState` is reset to the latest state of the main state each time a blocks gets [committed](#commit). - -`CheckTx()` returns a response to the underlying consensus engine of type [`abci.ResponseCheckTx`](https://tendermint.com/docs/spec/abci/abci.html#messages). The response contains: - -- `Code (uint32)`: Response Code. `0` if successful. -- `Data ([]byte)`: Result bytes, if any. -- `Log (string):` The output of the application's logger. May be non-deterministic. -- `Info (string):` Additional information. May be non-deterministic. -- `GasWanted (int64)`: Amount of gas requested for transaction. It is provided by users when they generate the transaction. -- `GasUsed (int64)`: Amount of gas consumed by transaction. During `CheckTx`, this value is computed by multiplying the standard cost of a transaction byte by the size of the raw transaction (click [here](https://github.com/cosmos/cosmos-sdk/blob/master/x/auth/ante.go#L101) for an example). ->>>>>>> master - `Tags ([]cmn.KVPair)`: Key-Value tags for filtering and indexing transactions (eg. by account). - `Codespace (string)`: Namespace for the Code. ### DeliverTx -<<<<<<< HEAD When the underlying consensus engine receives a block proposal, each transaction in the block needs to be processed by the application. To that end, the underlying consensus engine sends a `DeliverTx` message to the application for each transaction in a sequential order. Before the first transaction of a given block is processed, a [volatile state](#volatile-states) called `deliverState` is intialized during [`BeginBlock`](#beginblock). This state is updated each time a transaction is processed via `DeliverTx`, and committed to the [main state](#main-state) when the block is [committed](#commit), after what is is set to `nil`. @@ -405,43 +257,6 @@ After that, `RunTx` calls `ValidateBasic()` on each `message`in the `Tx`, which Then, the [`anteHandler`](#antehandler) of the application is run (if it exists). In preparation of this step, both the `checkState`/`deliverState`'s `context` and `context`'s `CacheMultiStore` are cached-wrapped using the [`cacheTxContext()`](https://github.com/cosmos/cosmos-sdk/blob/master/baseapp/baseapp.go#L781-L798) function. This allows `RunTx` not to commit the changes made to the state during the execution of `anteHandler` if it ends up failing. It also prevents the module implementing the `anteHandler` from writing to state, which is an important part of the [object-capabilities](./ocap.md) of the Cosmos SDK. Finally, the [`RunMsgs`](#runmsgs) function is called to process the `messages`s in the `Tx`. In preparation of this step, just like with the `anteHandler`, both the `checkState`/`deliverState`'s `context` and `context`'s `CacheMultiStore` are cached-wrapped using the `cacheTxContext()` function. -======= -When the underlying consensus engine receives a block proposal, each transaction in the block needs to be processed by the application. To that end, the underlying consensus engine sends a `DeliverTx` message to the application for each transaction in a sequential order. This ABCI message is handled by the `DeliverTx()` method of `baseapp` (abbreviated to `DeliverTx()` thereafter). - -Before the first transaction of a given block is processed, a [volatile state](#volatile-states) called `deliverState` is initialized during [`BeginBlock`](#beginblock). This state is updated each time a transaction is processed via `DeliverTx()`, and committed to the [main state](#main-state) when the block is [committed](#commit), after what is is set to `nil`. - -`DeliverTx()` performs the **exact same steps as `CheckTx()`**, with a little caveat at step 3 and the addition of a fifth step: - -3. The `anteHandler` does **not** check that the transaction's `gas-prices` is sufficient. That is because the `min-gas-prices` value `gas-prices` is checked against is local to the node, and therefore what is enough for one full-node might not be for another. This means that the proposer can potentially include transactions for free, although they are not incentivised to do so, as they earn a bonus on the total fee of the block they propose. -4. For each `message` in the transaction, route to the appropriate module's `handler`. Additional _stateful_ checks are performed, and the cache-wrapped multistore held in `deliverState`'s `context` is updated by the module's `keeper`. If the `handler` returns successfully, the cache-wrapped multistore held in `context` is written to `deliverState` `CacheMultiStore`. - -During step 5., each read/write to the store increases the value of `GasConsumed`. You can find the default cost of each operation [here](https://github.com/cosmos/cosmos-sdk/blob/master/store/types/gas.go#L142-L150). At any point, if `GasConsumed > GasWanted`, the function returns with `Code != 0` and `DeliverTx()` fails. - -`DeliverTx()` returns a response to the underlying consensus engine of type [`abci.ResponseCheckTx`](https://tendermint.com/docs/spec/abci/abci.html#messages). The response contains: - -- `Code (uint32)`: Response Code. `0` if successful. -- `Data ([]byte)`: Result bytes, if any. -- `Log (string):` The output of the application's logger. May be non-deterministic. -- `Info (string):` Additional information. May be non-deterministic. -- `GasWanted (int64)`: Amount of gas requested for transaction. It is provided by users when they generate the transaction. -- `GasUsed (int64)`: Amount of gas consumed by transaction. During `DeliverTx`, this value is computed by multiplying the standard cost of a transaction byte by the size of the raw transaction (click [here](https://github.com/cosmos/cosmos-sdk/blob/master/x/auth/ante.go#L101) for an example), and by adding gas each time a read/write to the store occurs. -- `Tags ([]cmn.KVPair)`: Key-Value tags for filtering and indexing transactions (eg. by account). -- `Codespace (string)`: Namespace for the Code. - -## RunTx(), AnteHandler and RunMsgs() - -### RunTx() - -`RunTx()` is called from `CheckTx()`/`DeliverTx()` to handle the transaction, with `runTxModeCheck` or `runTxModeDeliver` as parameter to differentiate between the two modes of execution. Note that when `RunTx()` receives a transaction, it has already been decoded. - -The first thing `RunTx()` does upon being called is to retrieve the `context`'s `CacheMultiStore` by calling the `getContextForTx()` function with the appropriate mode (either `runTxModeCheck` or `runTxModeDeliver`). This `CacheMultiStore` is a cached version of the main store instantiated during `BeginBlock` for `DeliverTx` and during the `Commit` of the previous block for `CheckTx`. After that, two `defer func()` are called for `gas` management. They are executed when `RunTx()` returns and make sure `gas` is actually consumed, and will throw errors, if any. - -After that, `RunTx()` calls `ValidateBasic()` on each `message`in the `Tx`, which runs prelimary _stateless_ validity checks. If any `message` fails to pass `ValidateBasic()`, `RunTx()` returns with an error. - -Then, the [`anteHandler`](#antehandler) of the application is run (if it exists). In preparation of this step, both the `checkState`/`deliverState`'s `context` and `context`'s `CacheMultiStore` are cached-wrapped using the [`cacheTxContext()`](https://github.com/cosmos/cosmos-sdk/blob/master/baseapp/baseapp.go#L781-L798) function. This allows `RunTx()` not to commit the changes made to the state during the execution of `anteHandler` if it ends up failing. It also prevents the module implementing the `anteHandler` from writing to state, which is an important part of the [object-capabilities](./ocap.md) of the Cosmos SDK. - -Finally, the [`RunMsgs()`](<#runmsgs()>) function is called to process the `messages`s in the `Tx`. In preparation of this step, just like with the `anteHandler`, both the `checkState`/`deliverState`'s `context` and `context`'s `CacheMultiStore` are cached-wrapped using the `cacheTxContext()` function. ->>>>>>> master ### AnteHandler @@ -449,7 +264,6 @@ The `AnteHandler` is a special handler that implements the [`anteHandler` interf The `AnteHandler` is theoretically optional, but still a very important component of public blockchain networks. It serves 3 primary purposes: -<<<<<<< HEAD - Be a primary line of defense against spam and second line of defense (the first one being the mempool) against transaction replay with fees deduction and [`sequence`](./tx-msgs.md#sequence) checking. - Perform preliminary *stateful* validity checks like ensuring signatures are valid or that the sender has enough funds to pay for fees. - Play a role in the incentivisation of stakeholders via the collection of transaction fees. @@ -461,43 +275,21 @@ The `AnteHandler` is theoretically optional, but still a very important componen `RunMsgs` is called from `RunTx` with `runTxModeCheck` as parameter to check the existence of a route for each message the transaction, and with `runTxModeDeliver` to actually process the `message`s. First, it retreives the `message`'s `route` using the `Msg.Route()` method. Then, using the application's [`router`](#routing) and the `route`, it checks for the existence of a `handler`. At this point, if `mode == runTxModeCheck`, `RunMsgs` returns. If instead `mode == runTxModeDeliver`, the [`handler`](../building-modules/handler.md) function for the message is executed, before `RunMsgs` returns. -======= -- Be a primary line of defense against spam and second line of defense (the first one being the mempool) against transaction replay with fees deduction and `sequence`checking. -- Perform preliminary _stateful_ validity checks like ensuring signatures are valid or that the sender has enough funds to pay for fees. -- Play a role in the incentivisation of stakeholders via the collection of transaction fees. - -`baseapp` holds an `anteHandler` as parameter, which is initialized in the [application's constructor](../basics/app-anatomy.md#application-constructor). The most widely used `anteHandler` today is that of the [`auth` module](https://github.com/cosmos/cosmos-sdk/blob/master/x/auth/ante.go). - -### RunMsgs() - -`RunMsgs()` is called from `RunTx()` with `runTxModeCheck` as parameter to check the existence of a route for each message contained in the transaction, and with `runTxModeDeliver` to actually process the `message`s. - -First, it retrieves the `message`'s `route` using the `Msg.Route()` method. Then, using the application's [`router`](#routing) and the `route`, it checks for the existence of a `handler`. At this point, if `mode == runTxModeCheck`, `RunMsgs()` returns. If instead `mode == runTxModeDeliver`, the `handler` function for the message is executed, before `RunMsgs()` returns. ->>>>>>> master ## Other ABCI Messages ### InitChain -<<<<<<< HEAD The [`InitChain` ABCI message](https://tendermint.com/docs/app-dev/abci-spec.html#initchain) is sent from the underlying Tendermint engine when the chain is first started. It is mainly used to **initialize** parameters and state like: - [Consensus Parameters](https://tendermint.com/docs/spec/abci/apps.html#consensus-parameters) via `setConsensusParams`. - [`checkState` and `deliverState`](#volatile-states) via `setCheckState` and `setDeliverState`. - The [block gas meter](../basics/accounts-fees-gas.md#block-gas-meter), with infinite gas to process genesis transactions. -======= -The [`InitChain` ABCI message](https://tendermint.com/docs/app-dev/abci-spec.html#initchain) is sent from the underlying Tendermint engine when the chain is first started, and is handled by the `InitChain(req abci.RequestInitChain)` method of `baseapp`. It is mainly used to **initialize** parameters and state like: - -- [Consensus Parameters](https://tendermint.com/docs/spec/abci/apps.html#consensus-parameters) via `setConsensusParams`. -- [`checkState` and `deliverState`](#volatile-states) via `setCheckState` and `setDeliverState`. -- The block gas meter, with infinite gas to process genesis transactions. ->>>>>>> master Finally, the `InitChain(req abci.RequestInitChain)` method of `baseapp` calls the [`initChainer()`](../basics/app-anatomy.md#initchainer) of the application in order to initialize the main state of the application from the [`genesis file`](./genesis.md) and, if defined, call the `InitGenesis` function of each of the application's modules. ### BeginBlock -<<<<<<< HEAD The [`BeginBlock` ABCI message](#https://tendermint.com/docs/app-dev/abci-spec.html#beginblock) is sent from the underlying Tendermint engine when a block proposal created by the correct proposer is received, before [`DeliverTx`](#delivertx) is run for each transaction in the block. It allows developers to have logic be executed at the beginning of each block. In the Cosmos SDK, the `BeginBlock(req abci.RequestBeginBlock)` method does the following: - Initialize [`deliverState`](#volatile-states) with the latest header using the `req abci.RequestBeginBlock` passed as parameter via the [`setDeliverState`](https://github.com/cosmos/cosmos-sdk/blob/master/baseapp/baseapp.go#L283-L289) function. @@ -524,39 +316,10 @@ The [`Info` ABCI message](https://tendermint.com/docs/app-dev/abci-spec.html#inf ### Query The [`Query` ABCI message](https://tendermint.com/docs/app-dev/abci-spec.html#query) is used to serve queries received from the underlying consensus engine, including queries received via RPC like Tendermint RPC. It is the main entrypoint to build interfaces with the application. The application must respect a few rules when implementing the `Query` method, which are outlined [here](https://tendermint.com/docs/app-dev/abci-spec.html#query). -======= -The [`BeginBlock` ABCI message](#https://tendermint.com/docs/app-dev/abci-spec.html#beginblock) is sent from the underlying Tendermint engine when a block proposal created by the correct proposer is received, before [`DeliverTx()`](#delivertx) is run for each transaction in the block. It allows developers to have logic be executed at the beginning of each block. In the Cosmos SDK, the `BeginBlock(req abci.RequestBeginBlock)` method does the following: - -- Initialize [`deliverState`](#volatile-states) with the latest header using the `req abci.RequestBeginBlock` passed as parameter via the [`setDeliverState`](https://github.com/cosmos/cosmos-sdk/blob/master/baseapp/baseapp.go#L283-L289) function. -- Initialize the block gas meter with the `maxGas` limit. The `gas` consumed within the block cannot go above `maxGas`. This parameter is defined in the application's consensus parameters. -- Run the application's [`begingBlocker()`](../basics/app-anatomy.md#beginblocker-and-endblock), which mainly runs the `BeginBlocker()` method of each of the application's modules. -- Set the [`VoteInfos`](https://tendermint.com/docs/app-dev/abci-spec.html#voteinfo) of the application, i.e. the list of validators whose _precommit_ for the previous block was included by the proposer of the current block. This information is carried into the [`Context`](./context.md) so that it can be used during `DeliverTx` and `EndBlock`. - -### EndBlock - -The [`EndBlock` ABCI message](#https://tendermint.com/docs/app-dev/abci-spec.html#endblock) is sent from the underlying Tendermint engine after [`DeliverTx`](#delivertx) as been run for each transactioni n the block. It allows developers to have logic be executed at the end of each block. In the Cosmos SDK, the bulk `EndBlock(req abci.RequestEndBlock)` method is to run the application's [`endBlocker()`](../basics/app-anatomy.md#beginblocker-and-endblock), which mainly runs the `EndBlocker()` method of each of the application's modules. - -### Commit - -The [`Commit` ABCI message](https://tendermint.com/docs/app-dev/abci-spec.html#commit) is sent from the underlying Tendermint engine after the full-node has received _precommits_ from 2/3+ of validators (weighted by voting power). On the `baseapp` end, the `Commit(res abci.ResponseCommit)` function is implemented to commit all the valid state transitions that occured during `BeginBlock()`, `DeliverTx()` and `EndBlock()` and to reset state for the next block. - -To commit state-transitions, the `Commit` function calls the `Write()` function on `deliverState.ms`, where `deliverState.ms` is a cached multistore of the main store `app.cms`. Then, the `Commit` function sets `checkState` to the latest header (obtained from `deliverState.ctx.BlockHeader`) and `deliverState` to `nil`. - -Finally, `Commit` returns the hash of the commitment of `app.cms` back to the underlying consensus engine. This hash is used as a reference in the header of the next block. - -### Info - -The [`Info` ABCI message](https://tendermint.com/docs/app-dev/abci-spec.html#info) is a simple query from the underlying consensus engine, notably used to sync the latter with the application during a handshake that happens on startup. When called, the `Info(res abci.ResponseInfo)` function from `baseapp` will return the application's name, version and the hash of the last commit of `app.cms`. - -### Query - -The [`Query` ABCI message](https://tendermint.com/docs/app-dev/abci-spec.html#query) is used to serve queries received from the underlying consensus engine, including queries received via RPC like Tendermint RPC. It is the main entrypoint to build interfaces with the application. The application must respect a few rules when implementing the `Query` method, which are outlined [here](https://tendermint.com/docs/app-dev/abci-spec.html#query). ->>>>>>> master The `baseapp` implementation of the `Query(req abci.RequestQuery)` method is a simple dispatcher serving 4 main categories of queries: - Application-related queries like querying the application's version, which are served via the `handleQueryApp` method. -<<<<<<< HEAD - Direct queries to the multistore, which are served by the `handlerQueryStore` method. These direct queryeis are different from custom queries which go through `app.queryRouter`, and are mainly used by third-party service provider like block explorers. - P2P queries, which are served via the `handleQueryP2P` method. These queries return either `app.addrPeerFilter` or `app.ipPeerFilter` that contain the list of peers filtered by address or IP respectively. These lists are first initialized via `options` in `baseapp`'s [constructor](#constructor). - Custom queries, which encompass most queries, are served via the `handleQueryCustom` method. The `handleQueryCustom` cache-wraps the multistore before using the `queryRoute` obtained from [`app.queryRouter`](#query-routing) to map the query to the appropriate module's [`querier`](../building-modules/querier.md). @@ -564,12 +327,3 @@ The `baseapp` implementation of the `Query(req abci.RequestQuery)` method is a s ## Next Learn more about [stores](./store.md). -======= -- Direct queries to the multistore, which are served by the `handlerQueryStore` method. These direct queries are different from custom queries which go through `app.queryRouter`, and are mainly used by third-party service provider like block explorers. -- P2P queries, which are served via the `handleQueryP2P` method. These queries return either `app.addrPeerFilter` or `app.ipPeerFilter` that contain the list of peers filtered by address or IP respectively. These lists are first initialized via `options` in `baseapp`'s [constructor](#constructor). -- Custom queries, which encompass most queries, are served via the `handleQueryCustom` method. The `handleQueryCustom` cache-wraps the multistore before using the `queryRoute` obtained from [`app.queryRouter`](#query-routing) to map the query to the appropriate module's [`querier`](../building-modules/querier.md). - -## Next - -Learn more about [stores](./store.md). ->>>>>>> master diff --git a/docs/modules/SPEC.md b/docs/spec/MODULE-SPEC.md similarity index 100% rename from docs/modules/SPEC.md rename to docs/spec/MODULE-SPEC.md From a6788cdb3fe849de949431cd28f2475ae0e2be70 Mon Sep 17 00:00:00 2001 From: gamarin Date: Tue, 20 Aug 2019 19:24:59 +0200 Subject: [PATCH 034/196] working --- docs/{spec/MODULE-SPEC.md => modules/SPEC.md} | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename docs/{spec/MODULE-SPEC.md => modules/SPEC.md} (100%) diff --git a/docs/spec/MODULE-SPEC.md b/docs/modules/SPEC.md similarity index 100% rename from docs/spec/MODULE-SPEC.md rename to docs/modules/SPEC.md From 16d78da8b0e5e92bb27deb27f66d53e3fee6d690 Mon Sep 17 00:00:00 2001 From: gamarin Date: Mon, 20 May 2019 14:08:56 +0200 Subject: [PATCH 035/196] consolidate intro --- docs/intro/README.md | 15 +++++------ docs/intro/sdk-app-architecture.md | 26 +++++++++---------- docs/intro/why-app-specific.md | 41 +++++++++++++++--------------- 3 files changed, 40 insertions(+), 42 deletions(-) diff --git a/docs/intro/README.md b/docs/intro/README.md index 9df4e13e443c..e753330be21b 100644 --- a/docs/intro/README.md +++ b/docs/intro/README.md @@ -2,15 +2,15 @@ ## What is the SDK? -The [Cosmos-SDK](https://github.com/cosmos/cosmos-sdk) is an open-source framework for building multi-asset public Proof-of-Stake (PoS) blockchains, like the Cosmos Hub, as well as permissioned Proof-Of-Authority (PoA) blockchains. Blockchains built with the Cosmos SDK are generally referred to as **application-specific blockchains**. +The [Cosmos-SDK](https://github.com/cosmos/cosmos-sdk) is a framework for building multi-asset public Proof-of-Stake (PoS) blockchains, like the Cosmos Hub, as well as permissionned Proof-Of-Authority (PoA) blockchains. Blockchains built with the Cosmos SDK are generally referred to as **application-specific blockchains**. -The goal of the Cosmos SDK is to allow developers to easily create custom blockchains from scratch that can natively interoperate with other blockchains. We envision the SDK as the npm-like framework to build secure blockchain applications on top of [Tendermint](https://github.com/tendermint/tendermint). SDK-based blockchains are built out of composable modules, most of which are open source and readily available for any developers to use. Anyone can create a module for the Cosmos-SDK, and integrating already-built modules is as simple as importing them into your blockchain application. What's more, the Cosmos SDK is a capabilities-based system, which allows developers to better reason about the security of interactions between modules. For a deeper look at capabilities, jump to [this section](./ocap.md). +The goal of the Cosmos SDK is to allow developers to easily create custom blockchains from scratch that can natively interoperate with other blockchains. We envision the SDK as the npm-like framework to build secure blockchain applications on top of [Tendermint](https://github.com/tendermint/tendermint). SDK-based blockchains are built out of composable modules, most of which are open source and readily available for any developers to use. Anyone can create a module for the Cosmos-SDK, and integrating already-built modules is as simple as importing them into your blockchain application. What's more, the Cosmos SDK is a capabilities-based system, which allows developer to better reason about the security of interactions between modules. For a deeper look at capabilities, jump to [this section](./ocap.md). ## What are Application-Specific Blockchains? One development paradigm in the blockchain world today is that of virtual-machine blockchains like Ethereum, where development generally revolves around building a decentralised applications on top of an existing blockchain as a set of smart contracts. While smart contracts can be very good for some use cases like single-use applications (e.g. ICOs), they often fall short for building complex decentralised platforms. More generally, smart contracts can be limiting in terms of flexibility, sovereignty and performance. -Application-specific blockchains offer a radically different development paradigm than virtual-machine blockchains. An application-specific blockchain is a blockchain customized to operate a single application: developers have all the freedom to make the design decisions required for the application to run optimally. They can also provide better sovereignty, security and performance. +Application-specific blockchains offer a radically different development paradigm than virtual-machine blockchains. An application-specific blockchain is a blockchain customized to operate a single application: developers have all the freedom to make the design decisions required for the application to run optimally. They can also provide better sovereignty, security and performance. To learn more about application-specific blockchains, [click here](./why-app-specific.md). @@ -18,13 +18,12 @@ To learn more about application-specific blockchains, [click here](./why-app-spe The Cosmos SDK is the most advanced framework for building custom application-specific blockchains today. Here are a few reasons why you might want to consider building your decentralised application with the Cosmos SDK: -- The default consensus engine available within the SDK is [Tendermint Core](https://github.com/tendermint/tendermint). Tendermint is the most (and only) mature BFT consensus engine in existence. It is widely used across the industry and is considered the gold standard consensus engine for building Proof-of-Stake systems. -- The SDK is open source and designed to make it easy to build blockchains out of composable modules. As the ecosystem of open source SDK modules grow, it will become increasingly easier to build complex decentralised platforms with it. -- The SDK is inspired by capabilities-based security, and informed by years of wrestling with blockchain state-machines. This makes the Cosmos SDK a very secure environment to build blockchains. -- Most importantly, the Cosmos SDK has already been used to build many application-specific blockchains that are already in production. Among others, we can cite [Cosmos Hub](https://hub.cosmos.network), [IRIS Hub](https://irisnet.org), [Binance Chain](https://docs.binance.org/), [Terra](https://terra.money/) or [Lino](https://lino.network/). Many more are building on the Cosmos SDK. You can get a view of the ecosystem [here](https://cosmos.network/ecosystem). +- The default consensus engine available within the SDK is [Tendermint Core](https://github.com/tendermint/tendermint). Tendermint is the most (and only) mature BFT consensus engine in existence. It is widely used accross the industry and is considered the gold standard consensus engine for building Proof-of-Stake systems. +- The SDK is open source and designed to make it easy to build blockchains out of composable modules. As the ecosystem of open source SDK modules grow, it will become increasingly easier to build complex decentralised platforms with it. +- The SDK is inspired by capabilities-based security, and informed by years of wrestling with blockchain state-machines. This makes the Cosmos SDK a very secure environment to build blockchains. +- Most importantly, the Cosmos SDK has already been used to build many application-specific blockchains that are already in production. Among others, we can cite [Cosmos Hub](https://hub.cosmos.network), [Iris](https://irisnet.org), [Binance Chain](https://docs.binance.org/), [Terra](https://terra.money/) or [Lino](https://lino.network/). Many more are building on the Cosmos SDK. You can get a view of the ecosystem [here](https://cosmos.network/ecosystem). ## Getting started with the Cosmos SDK - Learn more about the [architecture of an SDK application](./sdk-app-architecture.md) - Learn how to build an application-specific blockchain from scratch with the [SDK Tutorial](https://cosmos.network/docs/tutorial) - diff --git a/docs/intro/sdk-app-architecture.md b/docs/intro/sdk-app-architecture.md index 94007a2742dc..a420fe627c33 100644 --- a/docs/intro/sdk-app-architecture.md +++ b/docs/intro/sdk-app-architecture.md @@ -1,12 +1,12 @@ # SDK Application Architecture -## State machine +## State machine -At its core, a blockchain is a [replicated deterministic state machine](https://en.wikipedia.org/wiki/State_machine_replication). +At its core, a blockchain is a [replicated deterministic state machine](https://en.wikipedia.org/wiki/State_machine_replication). -A state machine is a computer science concept whereby a machine can have multiple states, but only one at any given time. There is a `state`, which describes the current state of the system, and `transactions`, that trigger state transitions. +A state machine is a computer science concept whereby a machine can have multiple states, but only one at any given time. There is a `state`, which describes the current state of the system, and `transactions`, that trigger state transitions. -Given a state S and a transaction T, the state machine will return a new state S'. +Given a state S and a transaction T, the state machine will return a new state S'. ``` +--------+ +--------+ @@ -26,9 +26,9 @@ In practice, the transactions are bundled in blocks to make the process more eff +--------+ +--------+ ``` -In a blockchain context, the state machine is deterministic. This means that if you start at a given state and replay the same sequence of transactions, you will always end up with the same final state. +In a blockchain context, the state machine is deterministic. This means that if you start at a given state and replay the same sequence of transactions, you will always end up with the same final state. -The Cosmos SDK gives you maximum flexibility to define the state of your application, transaction types and state transition functions. The process of building the state-machine with the SDK will be described more in depth in the following sections. But first, let us see how it is replicated using **Tendermint**. +The Cosmos SDK gives you maximum flexibility to define the state of your application, transaction types and state transition functions. The process of building the state-machine with the SDK will be described more in depth in the following sections. But first, let us see how it is replicated using **Tendermint**. ### Tendermint @@ -54,14 +54,14 @@ Blockchain node | | Consensus | | Tendermint is an application-agnostic engine that is responsible for handling the *networking* and *consensus* layers of your blockchain. In practice, this means that Tendermint is responsible for propagating and ordering transaction bytes. Tendermint Core relies on an eponymous Byzantine-Fault-Tolerant (BFT) algorithm to reach consensus on the order of transactions. For more on Tendermint, click [here](https://tendermint.com/docs/introduction/what-is-tendermint.html). -The Tendermint consensus algorithm works with a set of special nodes called *Validators*. Validators are responsible for adding blocks of transactions to the blockchain. At any given block, there is a validator set V. A validator in V is chosen by the algorithm to be the proposer of the next block. This block is considered valid if more than two thirds of V signed a *[prevote](https://tendermint.com/docs/spec/consensus/consensus.html#prevote-step-height-h-round-r)* and a *[precommit](https://tendermint.com/docs/spec/consensus/consensus.html#precommit-step-height-h-round-r)* on it, and if all the transactions that it contains are valid. The validator set can be changed by rules written in the state-machine. For a deeper look at the algorithm, click [here](https://tendermint.com/docs/introduction/what-is-tendermint.html#consensus-overview). +Tendermint consensus algorithm works with a set of special nodes called *Validators*. Validators are responsible for adding blocks of transactions to the blockchain. At any given block, there is a validator set V. A validator in V is chosen by the algorithm to be the proposer of the next block. This block is considered valid if more than two thirds of V signed a *[prevote](https://tendermint.com/docs/spec/consensus/consensus.html#prevote-step-height-h-round-r)* and a *[precommit](https://tendermint.com/docs/spec/consensus/consensus.html#precommit-step-height-h-round-r)* on it, and if all the transactions that it contains are valid. The validator set can be changed by rules written in the state-machine. For a deeper look at the algorithm, click [here](https://tendermint.com/docs/introduction/what-is-tendermint.html#consensus-overview). -The main part of a Cosmos SDK application is a blockchain daemon that is run by each node in the network locally. If less than one third of the *validator set* is byzantine (i.e. malicious), then each node should obtain the same result when querying the state at the same time. +The main part of a Cosmos SDK application is a blockchain daemon that is run by each node in the network locally. If less than one third of the *validator set* is byzantine (i.e. malicious), then each node should obtain the same result when querying the state at the same time. ## ABCI -Tendermint passes transactions from the network to the application through an interface called the [ABCI](https://github.com/tendermint/tendermint/tree/master/abci), which the application must implement. +Tendermint passes transactions from the network to the application through an interface called the [ABCI](https://github.com/tendermint/tendermint/tree/master/abci), which the application must implement. ``` +---------------------+ @@ -81,16 +81,16 @@ Tendermint passes transactions from the network to the application through an in +---------------------+ ``` -Note that **Tendermint only handles transaction bytes**. It has no knowledge of what these bytes mean. All Tendermint does is order these transaction bytes deterministically. Tendermint passes the bytes to the application via the ABCI, and expects a return code to inform it if the messages contained in the transactions were successfully processed or not. +Note that **Tendermint only handles transaction bytes**. It has no knowledge of what these bytes mean. All Tendermint does is order these transaction bytes deterministically. Tendermint passes the bytes to the application via the ABCI, and expects a return code to inform it if the messages contained in the transactions were successfully processed or not. Here are the most important messages of the ABCI: -- `CheckTx`: When a transaction is received by Tendermint Core, it is passed to the application to check if a few basic requirements are met. `CheckTx` is used to protect the mempool of full-nodes against spam. A special handler called the "Ante Handler" is used to execute a series of validation steps such as checking for sufficient fees and validating the signatures. If the check is valid, the transaction is added to the [mempool](https://tendermint.com/docs/spec/reactors/mempool/functionality.html#mempool-functionality) and relayed to peer nodes. Note that transactions are not processed (i.e. no modification of the state occurs) with `CheckTx` since they have not been included in a block yet. +- `CheckTx`: When a transaction is received by Tendermint Core, it is passed to the application to check if a few basic requirements are met. `CheckTx` is used to protect the mempool of full-nodes against spam. A special handler called the "Ante Handler" is used to execute a series of validation steps such as checking for sufficient fees and validating the signatures. If the check is valid, the transaction is added to the [mempool](https://tendermint.com/docs/spec/reactors/mempool/functionality.html#mempool-functionality) and relayed to peer nodes. Note that transactions are not processed (i.e. no modification of the state occurs) with `CheckTx` since they have not been included in a block yet. - `DeliverTx`: When a [valid block](https://tendermint.com/docs/spec/blockchain/blockchain.html#validation) is received by Tendermint Core, each transaction in the given block is passed to the application via `DeliverTx` to be processed. It is during this stage that the state transitions occur. The "Ante Handler" executes again along with the actual handlers for each message in the transaction. - - `BeginBlock`/`EndBlock`: These messages are executed at the beginning and the end of each block, whether the block contains transaction or not. It is useful to trigger automatic execution of logic. Proceed with caution though, as computationally expensive loops could slow down your blockchain, or even freeze it if the loop is infinite. + - `BeginBlock`/`EndBlock`: These messages are executed at the beginning and the end of each block, whether the block contains transaction or not. It is useful to trigger automatic execution of logic. Proceed with caution though, as computationally expensive loops could slow down your blockchain, or even freeze it if the loop is infinite. For a more detailed view of the ABCI methods and types, click [here](https://tendermint.com/docs/spec/abci/abci.html#overview). Any application built on Tendermint needs to implement the ABCI interface in order to communicate with the underlying local Tendermint engine. Fortunately, you do not have to implement the ABCI interface. The Cosmos SDK provides a boilerplate implementation of it in the form of [baseapp](./sdk-design.md#baseapp). -### Next, let us go into the [high-level design principles of the SDK](./sdk-design.md) \ No newline at end of file +### Next, let us go into the [high-level design principles of the SDK](./sdk-design.md) diff --git a/docs/intro/why-app-specific.md b/docs/intro/why-app-specific.md index 1b160429f6eb..ce454383711c 100644 --- a/docs/intro/why-app-specific.md +++ b/docs/intro/why-app-specific.md @@ -4,7 +4,7 @@ This document explains what application-specific blockchains are, and why develo ## What are application-specific blockchains? -Application-specific blockchains are blockchains customized to operate a single application. Instead of building a decentralised application on top of an underlying blockchain like Ethereum, developers build their own blockchain from the ground up. This means building a full-node client, a light-client, and all the necessary interfaces (CLI, REST, ...) to interract with the nodes. +Application-specific blockchains are blockchains customized to operate a single application. Instead of building a decentralised application on top of an underlying blockchain like Ethereum, developers build their own blockchain from the ground up. This means building a full-node client, a light-client, and all the necessary interfaces (CLI, REST, ...) to interract with the nodes. ``` ^ +-------------------------------+ ^ @@ -24,13 +24,13 @@ Blockchain node | | Consensus | | ## What are the shortcomings of Smart Contracts? -Virtual-machine blockchains like Ethereum addressed the demand for more programmability back in 2014. At the time, the options available for building decentralised applications were quite limited. Most developers would build on top of the complex and limited Bitcoin scripting language, or fork the Bitcoin codebase which was hard to work with and customize. +Virtual-machine blockchains like Ethereum addressed the demand for more programmability back in 2014. At the time, the options available for building decentralised applications were quite limited. Most developers would build on top of the complex and limited Bitcoin scripting language, or fork the Bitcoin codebase which was hard to work with and customize. Virtual-machine blockchains came in with a new value proposition. Their state-machine incorporates a virtual-machine that is able to interpret turing-complete programs called Smart Contracts. These Smart Contracts are very good for use cases like one-time events (e.g. ICOs), but they can fall short for building complex decentralised platforms: -- Smart Contracts are generally developed with specific programming languages that can be interpreted by the underlying virtual-machine. These programming languages are often immature and inherently limited by the constraints of the virtual-machine. For example, the Ethereum Virtual Machine does not allow developers to implement automatic execution of code. Developers are also limited to the account-based system of the EVM, and they can only choose from a limited set of functions for their cryptographic operations. These are examples, but they hint at the lack of **flexibility** a smart contract environment often entails. +- Smart Contracts are generally developed with specific programming languages that can be interpreted by the underlying virtual-machine. These programming languages are often immature and inherently limited by the constraints of the virtual-machine. For example, the Ethereum Virtual Machine does not allow developers to implement automatic execution of code. Developers are also limited to the account-based system of the EVM, and they can only choose from a limited set of functions for their cryptographic operations. These are examples, but they hint at the lack of **flexibility** a smart contract environment often entails. - Smart Contracts are all run by the same virtual machine. This means that they compete for resources, which can severly restrain **performance**. And even if the state-machine were to be split in multiple subsets (e.g. via sharding), Smart Contracts would still need to be interpeted by a virtual machine, which would limit performance compared to a native application implemented at state-machine level (our benchmarks show an improvement on the order of x10 in performance when the virtual-machine is removed). -- Another issue with the fact that Smart Contracts share the same underlying environment is the resulting limitation in **sovereignty**. A decentralised application is an ecosystem that involves multiple players. If the application is built on a general-purpose virtual-machine blockchain, these players have very limited sovereignty over it, and are ultimately superseded by the governance of the underlying blockchain. If there is a bug in the application, very little can be done about it. +- Another issue with the fact that Smart Contracts share the same underlying environment is the resulting limitation in **sovereignty**. A decentralised application is an ecosystem that involves multiple players. If the application is built on a general-purpose virtual-machine blockchain, these players have very limited sovereignty over it, and are ultimately superseded by the governance of the underlying blockchain. If there is a bug in the application, very little can be done about it. Application-Specific Blockchains are designed to address these shortcomings. @@ -40,40 +40,39 @@ Application-Specific Blockchains are designed to address these shortcomings. Application-specific blockchains give maximum flexibility to developers: -- In Cosmos blockchains, the state-machine is typically connected to the underlying consensus engine via an interface called the [ABCI](https://tendermint.com/docs/spec/abci/). This interface can be wrapped in any programming language, meaning developers can build their state-machine in the programming language of their choice. -- Developers can choose among multiple frameworks to build their state-machine. The most widely used today is the Cosmos SDK, but others exist (e.g. [Lotion](https://github.com/nomic-io/lotion), [Weave](https://github.com/iov-one/weave), ...). The choice will most of the time be done based on the programming language they want to use (Cosmos SDK and Weave are in Golang, Lotion is in Javascript, ...). -- The ABCI also allows developers to swap the consensus engine of their application-specific blockchain. Today, only Tendermint is production-ready, but in the future other engines are expected to emerge. -- Even when they settle for a framework and consensus engine, developers still have the freedom to tweak them if they don't perfectly match their requirements in their pristine forms. -- Developers are free to explore the full spectrum of tradeoffs (e.g. number of validators vs transaction throughput, safety vs availability in asynchrony, ...) and design choices (DB or IAVL tree for storage, UTXO or account model, ...). -- Developers can implement automatic execution of code. In the Cosmos SDK, logic can be automatically triggered at the beginning and the end of each block. They are also free to choose the cryptographic library used in their application, as opposed to being constrained by what is made available by the underlying environment in the case of virtual-machine blockchains. +- Developers can choose among multiple frameworks to build their state-machine. The most widely used today is the Cosmos SDK, but others exist (e.g. Lotion, Weave, ...). The choice will most of the time be done based on the programming language they want to use (Cosmos SDK and Weave are in Golang, Lotion is in Javascript, ...). +- Developers can swap consensus engine. Today, only Tendermint is production-ready, but in the future other engines are expected to emerge. +- Even when they settle for a framework and consensus engine, developers still have the freedom to tweak them if they don't perfectly match their requirements in their pristine forms. +- Developers are free to explore the full spectrum of tradeoffs (e.g. number of validators vs transaction throughput, safety vs availability in asynchrony, ...) and design choices (DB or IAVL tree for storage, UTXO or account model, ...). +- Developers can implement automatic execution of code. In the Cosmos SDK, logic can be automatically triggered at the beginning and the end of each block. They are also free to choose the cryptographic library used in their application, as opposed to being constrained by what is made available by the underlying environment in the case of virtual-machine blockchains. -The list above contains a few examples that show how much flexibility application-specific blockchains give to developers. The goal of Cosmos and the Cosmos SDK is to make developer tooling as generic and composable as possible, so that each part of the stack can be forked, tweaked and improved without losing compatibility. As the community grows, more alternative for each of the core building blocks will emerge, giving more options to developers. +The list above contains a few examples that show how much flexibility application-specific blockchains give to developers. The goal of Cosmos and the Cosmos SDK is to make developer tooling as generic and composable as possible, so that each part of the stack can be forked, tweaked and improved without losing compatibility. As the community grows, more alternative for each of the core building blocks will emerge, giving more options to developers. ### Performance Decentralised applications built with Smart Contracts are inherently capped in performance by the underlying environment. For a decentralised application to optimise performance, it needs to be built as an application-specific blockchains. Here are the benefits of an application-specific blockchains with regards to performance: -- Developers of application-specific blockchains can choose to operate with novel consensus engine such as Tendermint BFT. Compared to Proof-of-Work (used by most virtual-machine blockchains today), it offers significant gains in throuhgput. -- An application-specific blockchain only operates a single application, so that the application does not compete with others for computation and storage. This is the opposite of most non-sharded virtual-machine blockchains today, where smart contracts all compete for computation and storage. -- Even if a virtual-machine blockchain offered application-based sharding coupled with an efficient consensus algorithm, performance would still be limited by the virtual-machine itself. The real throughput bottleneck is the state-machine, and requiring transactions to be interpreted by a virtual-machine significantly increases the computational complexity of processing them. +- Developers of application-specific blockchains can choose to operate with novel consensus engine such as Tendermint BFT. Compared to Proof-of-Work (used by most virtual-machine blockchains today), it offers significant gains in throuhgput. +- An application-specific blockchain only operates a single application, so that the application does not compete with others for computation. This is the opposite of most non-sharded virtual-machine blockchains today, where smart contracts all compete for computation. +- Even if a virtual-machine blockchain offered application-based sharding coupled with an efficient consensus algorithm, performance would still be limited by the virtual-machine itself. The real throughput bottleneck is the state-machine, and requiring transactions to be interpreted by a virtual-machine significantly increases the computational complexity of processing them. -### Security +### Security Security is hard to quantify, and greatly varies from platform to platform. That said here are some important benefits an application-specific blockchain can bring in terms of security: -- Developers can choose proven programming languages like Golang when building their application-specific blockchains, as opposed to smart contract programming languages that are often more immature. -- Developers are not constrained by the cryptographic functions made available by the underlying virtual-machines. They can use their own custom cryptography, and rely on well-audited crypto libraries. -- Developers do not have to worry about potential bugs or exploitable mechanisms in the underlying virtual-machine, making it easier to reason about the security of the application. +- Developers can choose proven programming language like Golang when building their application-specific blockchains, as opposed to smart contract programming languages that are often more immature. +- Developers are not constrained by the cryptographic functions made available by the underlying virtual-machines. They can use their own custom cryptography, and rely on well-audited crypto libraries. +- Developers do not have to worry about potential bugs or exploitable mechanisms in the underlying virtual-machine, making it easier to reason about the security of the application. ### Sovereignty -One of the major benefits of application-specific blockchains is sovereignty. A decentralised application is an ecosystem that involves many actors: users, developers, third-party services, and more. When developers build on virtual-machine blockchain where many decentralised applications coexist, the community of the application is different than the community of the underlying blockchain, and the latter supersedes the former. If there is a bug or if a new feature is needed, the community of the application has very little sovereignty to upgrade the code. If the community of the underlying blockchain refuses to act, nothing can happen. +One of the major benefits of application-specific blockchains is sovereignty. A decentralised application is an ecosystem that involves many actors: users, developers, third-party services, and more. When developers build on virtual-machine blockchain where many decentralised applications coexist, the community of the application is different than the community of the underlying blockchain, and the latter supersedes the former. If there is a bug or if a new feature is needed, the community of the application has very little sovereignty to upgrade the code. If the community of the underlying blockchain refuses to act, nothing can happen. -The fundamental issue here is that the governance of the application and the governance of the network are not aligned. This issue is solved by application-specific blockchains. Because application-specific blockchains specialize to operate a single application, the community of the application has full control over the entire chain. This ensures the community will not be stuck if a bug is discovered, and that it has the entire freedom to choose how it is going to evolve. +The fundamental issue here is that the governance of the application and the governance of the network are not aligned. This issue is solved by application-specific blockchains. Because application-specific blockchains specialize to operate a single application, the community of the application has full control over the entire chain. This ensures the community will not be stuck if a bug is discovered, and that it has the entire freedom to choose how it is going to evolve. ## Start Building Your Application-Specific Blockchain Today Clearly, application-specific blockchains are awesome. The Cosmos SDK makes it easier than ever to build them. What are you waiting for? -- Learn more about the [high-level architecture](./sdk-app-architecture) of an SDK application. - Learn how to build an application-specific blockchain from scratch with the [SDK tutorial](https://cosmos.network/docs/tutorial) +- Learn more about the [high-level architecture](./sdk-app-architecture) of an SDK application. From 66dd67509b41365516d2ec16fab2da4dc21c2e26 Mon Sep 17 00:00:00 2001 From: gamarin Date: Tue, 28 May 2019 17:32:29 +0200 Subject: [PATCH 036/196] querier --- docs/concepts/amino.md | 3 +++ docs/concepts/genesis.md | 3 +++ docs/concepts/handler.md | 1 + docs/concepts/keeper.md | 0 docs/concepts/modules.md | 3 +++ docs/concepts/querier.md | 3 +++ docs/core/node.md | 2 +- docs/intro/README.md | 2 +- 8 files changed, 15 insertions(+), 2 deletions(-) create mode 100644 docs/concepts/amino.md create mode 100644 docs/concepts/genesis.md create mode 100644 docs/concepts/handler.md create mode 100644 docs/concepts/keeper.md create mode 100644 docs/concepts/modules.md create mode 100644 docs/concepts/querier.md diff --git a/docs/concepts/amino.md b/docs/concepts/amino.md new file mode 100644 index 000000000000..8113f63e9630 --- /dev/null +++ b/docs/concepts/amino.md @@ -0,0 +1,3 @@ +# Amnio Encoding + +TODO \ No newline at end of file diff --git a/docs/concepts/genesis.md b/docs/concepts/genesis.md new file mode 100644 index 000000000000..5e3dbd31dcad --- /dev/null +++ b/docs/concepts/genesis.md @@ -0,0 +1,3 @@ +# Genesis File + +TODO \ No newline at end of file diff --git a/docs/concepts/handler.md b/docs/concepts/handler.md new file mode 100644 index 000000000000..f8fc820df8de --- /dev/null +++ b/docs/concepts/handler.md @@ -0,0 +1 @@ +# Handlers \ No newline at end of file diff --git a/docs/concepts/keeper.md b/docs/concepts/keeper.md new file mode 100644 index 000000000000..e69de29bb2d1 diff --git a/docs/concepts/modules.md b/docs/concepts/modules.md new file mode 100644 index 000000000000..cfd71f817963 --- /dev/null +++ b/docs/concepts/modules.md @@ -0,0 +1,3 @@ +# SDK Modules + +Todo: Intro concept docs on modules \ No newline at end of file diff --git a/docs/concepts/querier.md b/docs/concepts/querier.md new file mode 100644 index 000000000000..3afa9f0cc308 --- /dev/null +++ b/docs/concepts/querier.md @@ -0,0 +1,3 @@ +# Queriers + +TODO \ No newline at end of file diff --git a/docs/core/node.md b/docs/core/node.md index 85c6152542ad..36fe12602d0d 100644 --- a/docs/core/node.md +++ b/docs/core/node.md @@ -2,7 +2,7 @@ ## Pre-Requisite Reading -## `main` function +## main function TODO diff --git a/docs/intro/README.md b/docs/intro/README.md index e753330be21b..e676fd179b16 100644 --- a/docs/intro/README.md +++ b/docs/intro/README.md @@ -2,7 +2,7 @@ ## What is the SDK? -The [Cosmos-SDK](https://github.com/cosmos/cosmos-sdk) is a framework for building multi-asset public Proof-of-Stake (PoS) blockchains, like the Cosmos Hub, as well as permissionned Proof-Of-Authority (PoA) blockchains. Blockchains built with the Cosmos SDK are generally referred to as **application-specific blockchains**. +The [Cosmos-SDK](https://github.com/cosmos/cosmos-sdk) is an open-source framework for building multi-asset public Proof-of-Stake (PoS) blockchains, like the Cosmos Hub, as well as permissionned Proof-Of-Authority (PoA) blockchains. Blockchains built with the Cosmos SDK are generally referred to as **application-specific blockchains**. The goal of the Cosmos SDK is to allow developers to easily create custom blockchains from scratch that can natively interoperate with other blockchains. We envision the SDK as the npm-like framework to build secure blockchain applications on top of [Tendermint](https://github.com/tendermint/tendermint). SDK-based blockchains are built out of composable modules, most of which are open source and readily available for any developers to use. Anyone can create a module for the Cosmos-SDK, and integrating already-built modules is as simple as importing them into your blockchain application. What's more, the Cosmos SDK is a capabilities-based system, which allows developer to better reason about the security of interactions between modules. For a deeper look at capabilities, jump to [this section](./ocap.md). From 6d1df2ef4e246fda17d46eded014d7b32073cba5 Mon Sep 17 00:00:00 2001 From: gamarin Date: Wed, 5 Jun 2019 17:10:54 +0200 Subject: [PATCH 037/196] workiiiing --- docs/.vuepress/config.js | 3 +- docs/concepts/app-anatomy.md | 212 +++++++++++++++++++++++++++++++++ docs/intro/why-app-specific.md | 2 +- 3 files changed, 215 insertions(+), 2 deletions(-) create mode 100644 docs/concepts/app-anatomy.md diff --git a/docs/.vuepress/config.js b/docs/.vuepress/config.js index 9ee6a31059c5..d8756aae2385 100644 --- a/docs/.vuepress/config.js +++ b/docs/.vuepress/config.js @@ -31,7 +31,8 @@ module.exports = { "/intro/", "/intro/why-app-specific", "/intro/sdk-app-architecture", - "/intro/sdk-design" + "/intro/sdk-design", + "intro/ocap" ] }, { diff --git a/docs/concepts/app-anatomy.md b/docs/concepts/app-anatomy.md new file mode 100644 index 000000000000..346b35abab80 --- /dev/null +++ b/docs/concepts/app-anatomy.md @@ -0,0 +1,212 @@ +# Anatomy of an SDK Application + +## Pre-requisite reading + +- [High-level overview of the architecture of an SDK application](../intro/sdk-app-architecture.md) +- [Cosmos SDK design overview](../intro/sdk-design.md) + +## Synopsis + +This document describes the core parts of a Cosmos SDK application. The placeholder name for this application will be `app`. + +- [Node Client](#node-client) +- [Core Application File](#core-application-file) +- [Modules](#modules) +- [Intefaces](#interfaces) +- [Dependencies and Makefile](#dependencies-and-makefile) + +The core parts listed above will generally translate to the following directory tree: + +``` +./app +├── cmd/ +│ ├── appd +│ └── appcli +├── app.go +├── x/ +│ ├── auth +│ └── bank +├── Gopkg.toml +└── Makefile +``` + +## Node Client (Daemon) + +The Daemon, or Full-Node Client, is the core process of an SDK-based blockchain. Participants in the network run this process to initialize their state-machine, connect with other full-nodes and update their state-machine as new blocks come in. + +``` + ^ +-------------------------------+ ^ + | | | | + | | State+machine = Application | | + | | | | Built with Cosmos SDK + | | ^ + | | + | +----------- | ABCI | ----------+ v + | | + v | ^ + | | | | +Blockchain Node | | Consensus | | + | | | | + | +-------------------------------+ | Tendermint Core + | | | | + | | Networking | | + | | | | + v +-------------------------------+ v +``` +The blockchain full-node presents itself as a binary, generally suffixed by `-d` (e.g. `appd` for `app` or `gaiad` for the `gaia`) for "daemon". This binary is built by running a simple `main.go` function placed in `cmd/appd/`. This operation usually happens through the [Makefil](#dependencies-and-makefile). + +To learn more about the `main.go` function, [click here](./node.md#main-function). + +Once the main binary is built, the node can be started by running the `start` command. The core logic behind the `start` command is implemented in the SDK itself in the [`/server/start.go`](https://github.com/cosmos/cosmos-sdk/blob/master/server/start.go) file. The main [`start` command function](https://github.com/cosmos/cosmos-sdk/blob/master/server/start.go#L31) takes a [`context`](https://godoc.org/github.com/cosmos/cosmos-sdk/client/context) and [`appCreator`](#constructor-function-(`appCreator`)) as arguments. The `appCreator` is a constructor function for the SDK application, and is used in the starting process of the full-node. + +The `start` command function primarily does three things: + +1- Create an instance of the state-machine defined in [`app.go`](#core-application-file) using the `appCreator`. +2- Initialize the state-machine with the latest known state, extracted from the `db` stored in the `~/.appd/data` folder. At this point, the state-machine is at height `appBlockHeight`. +3- Create and start a new Tendermint instance. Among other things, the node will perform a handshake with its peers. It will get the latest `blockHeight` from them, and replay blocks to sync to this height if it is greater than the local `appBlockHeight`. If `appBlockHeight` is `0`, the node is starting from genesis and Tendermint sends an `InitChain` message via the ABCI to the `app`, which triggers the [`InitChainer`](#initchainer). + +To learn more about the `start` command, [click here](./node.md#start-command). + +## Core Application File + +In general, the core of the state-machine is defined in a file called `app.go`. It mainly contains the **type definition of the application** and functions to **create and initialize it**. + +### Type Definition of the Application + +The first thing defined in `app.go` is the `type` of the application. It is generally comprised of the following parts: + +- **A reference to [`baseapp`](./baseapp.md).** The custom application defined in `app.go` is a golang embedding of the `baseapp` type. `baseapp` implements most of the core logic for the application, including all the [ABCI methods](https://tendermint.com/docs/spec/abci/abci.html#overview) and the routing logic. When a transaction is relayed by Tendermint to the application, the latter uses `baseapp`'s methods to route them to the appropriate module. +- **A list of store keys**. The [store](./store.md), which contains the entire state, is implemented as a multistore (i.e. a store of stores) in the Cosmos SDK. Each module uses one or multiple stores in the multistore to persist their part of the state. These stores can be accessed with specific keys that are declared in the `app` type. These keys, along with the `keepers`, are at the heart of the [object-capabilities model](../intro/ocap.md) of the Cosmos SDK. +- **A list of module's `keepers`.** Each module defines an abstraction called `keeper`, which handles reads and writes for this module's store(s). The `keeper`'s methods of one module can be called from other modules (if authorized), which is why they are declared in the application's type. +- **A reference to a `codec`.** The Cosmos SDK gives developers the freedom to choose the encoding framework for their application. The application's `codec` is used to serialize and deserialize data structures in order to store them, as stores can only persist `[]bytes`. The `codec` must be deterministic. Most SDK application use [amino](./amino.md) as their `codec`. + +You can see an example of application type definition [here](https://github.com/cosmos/sdk-application-tutorial/blob/master/app.go#L27-L43). + +### Constructor Function + +This function constructs a new application of the type defined above. It is [called](https://github.com/cosmos/cosmos-sdk/blob/master/server/start.go#L117) everytime the full-node is started with the `start` command. Here are the main actions performed by this function: + +- Instanciate a new application with a reference to a `baseapp` instance, a codec and all the appropriate store keys. +- Instanciate all the `keepers` defined in the application's `type`. +- Initialize the application's [`routes`](./baseapp.md#routing) with the [`handlers`](#handler) of each one of the application's modules. When a transaction is relayed to the application by Tendermint via the ABCI, it is routed to the appropriate module's handler using the routes defined here. +- Initialize the application's [query routes](./baseapp.md#query-routing) with the [`queriers`](#querier) of each of the application's modules. When a user query comes in, it is routed to the appropriate module using the query routes defined here. +- Set the application's [`initChainer`](#initchainer) and mount the stores. +- Return the application. + +Note that this function only creates an instance of the app, while the actual state is either carried over from the `~/.appd/data` folder if the node is restarted, or generated from the genesis file if the node is started for the first time. + +You can see an example of application constructor [here](https://github.com/cosmos/sdk-application-tutorial/blob/master/app.go#L46-L128). + +### InitChainer + +The `initChainer` is a function that initializes the state of the application from a [genesis file](./genesis.md) (i.e. token balances of genesis accounts). It is called when the application received the `InitChain` message from the Tendermint engine, which happens when the node is started at `appBlockHeight == 0` (i.e. on genesis). The application must set the `initChainer` in its constructor via the [`setInitChainer`](https://godoc.org/github.com/cosmos/cosmos-sdk/baseapp#BaseApp.SetInitChainer) method. + +You can see an example of an `initChainer` [here](https://github.com/cosmos/sdk-application-tutorial/blob/master/app.go#L137-L155). + +### Register Codec + +The `MakeCodec` function is the last important function of the `app.go` file. The goal of this function is to instanciate a codec `cdc` (e.g. [amino](./amino.md)) and calls the `RegisterCodec(*codec.Codec)` method of each module used within the application to register `cdc` to each module. + +In turn, the `RegisterCodec` function of each module register the custom interfaces and type structures of their respective module so that they can be marhsaled and unmarshaled. + +You can see an example of a `MakeCodec` [here](You can see an example of an `initChainer` [here](https://github.com/cosmos/sdk-application-tutorial/blob/master/app.go#L189-L198).). + +## Modules + +Modules are the heart and soul of an SDK application. They can be considered as state-machines within the state-machine. When a transaction is relayed from the underlying Tendermint engine via the ABCI to the application, it is routed by `baseapp` to the appropriate module in order to be processed. This paradigm enables developers to easily build complex state-machines, as most of the modules they need often already exist. For developers, most of the work involved in building an SDK application revolves around building custom modules required by their application that do not exist, and integrating them with modules that do already exist into one coherent application. In the application directory, the standard practice is to store modules in the `x/` folder. + +To learn more about modules, [click here](./modules.md) + +### Message Types + +A message is a custom type defined by each module that implements the [`message`](https://github.com/cosmos/cosmos-sdk/blob/master/types/tx_msg.go#L8-L29) interface. Each `transaction` contains one or multiple `messages`. When a valid block of transactions is received by the full-node, Tendermint relays each one to the application via [`DeliverTx`](https://tendermint.com/docs/app-dev/abci-spec.html#delivertx). Upon receiving the transaction, the application first unmarshalls it. Then, it extracts the message(s) contained in the application. With the [`Type()`](https://github.com/cosmos/cosmos-sdk/blob/master/types/tx_msg.go#L16) method, `baseapp` is able to know which modules defines the message. It is then able to route it to the appropriate module's [handler](#handler) in order for the message to be processed. If the message is succesfully processed, the state is updated. + +Module developers create custom message types when they build their own module. The general practice is to prefix the type declaration of the message with `Msg`. For example, the message type `MsgSend` allows users to transfer tokens. It is processed by the handler of the `bank` module, which ultimately calls the `keeper` of the `auth` module in order to update the state. + +To learn more about messages, [click here](./tx-msgs.md) + +### Handler + +The `handler` refers to the part of the module responsible for processing the message after it is routed by `baseapp`. `handler` functions of modules (except those of the `auth` module) are only executed if the transaction is relayed from Tendermint by the `DeliverTx` ABCI message. If the transaction is realyed by `CheckTx`, only stateless checks and fee-related (i.e. `auth` module-related) stateful checks are performed. To better understand the difference between `DeliverTx`and `CheckTx`, as well as the difference between stateful and stateless checks, click [here](./tx-lifecycle.md). + +The handler of a module is generally defined in a file called `handler.go` and consists of: + +- A **switch function** `NewHandler` to route the message to the appropriate handler function. This function returns a `handler` function, and is used in `app.go` to initialize the [application's router](./baseapp.md#routing). See an example of such a switch [here](https://github.com/cosmos/sdk-application-tutorial/blob/master/x/nameservice/handler.go#L10-L22). +- **One handler function for each message type defined by the module**. Developers write the message processing logic in these functions. This generally involves doing stateful checks to ensure the message is valid and calling [`keeper`](#keeper)'s methods to update the state. + +Handler functions return a result of type [`sdk.Result`](https://github.com/cosmos/cosmos-sdk/blob/master/types/result.go#L14-L37), which informs the application on wether the message was succesfully processed and. + +To learn more about handlers, [click here](./handler.md). + +### Keeper + +`Keepers` are the gatekeepers of their module's store(s). To read or write in a module's store, it is mandatory to go through one of its `keeper`'s methods. This is ensured by the [object-capabilities](./ocap.md) model of the Cosmos SDK. Only objects that hold the key to a store can access it, and only the module's `keeper` should hold the key(s) to the module's store(s). + +`Keepers` are generally defined in a file called `keeper.go`. It contains the `keeper`'s type definition and methods. + +The `keeper` type definition generally consists of: + +- **Key(s)** to the module's store(s) in the multistore. +- Reference to **other module's `keepers`**. Only needed if the `keeper` needs to access other module's store(s) (either to read or write from them). +- A reference to the application's **codec**. The `keeper` needs it to marshal structs before storing them, or to unmarhsal them when it retrieves them, because stores only accept `[]bytes` as value. + +The rest of the file defines the `keeper`'s methods, primarily getters and setters. You can check an example of a `keeper` implementation [here](https://github.com/cosmos/sdk-application-tutorial/blob/master/x/nameservice/keeper.go). + +To learn more about `keepers`, [click here](./keeper.md). + +### Querier + +`Queriers` are very similar to `handlers`, except they serve user queries to the state as opposed to processing transactions. A query is initiated from an [interface](#intefaces) by an end-user who provides a `queryRoute` and some `data`. The query is then routed to the correct application's `querier` by `baseapp`'s [`handleQueryCustom`](https://github.com/cosmos/cosmos-sdk/blob/master/baseapp/baseapp.go#L519-L556) method using `queryRoute`. + +The `Querier` of a module are defined in a file called `querier.go`, and consists of: + +- A **switch function** `NewQuerier` to route the query to the appropriate `querier` function. This function returns a `querier` function, and is used in `app.go` to initialize the [application's query router](./baseapp.md#query-routing). See an example of such a switch [here](https://github.com/cosmos/sdk-application-tutorial/blob/master/x/nameservice/querier.go#L21-L34). +- - **One querier function for each data type defined by the module that needs to be queryable**. Developers write the query processing logic in these functions. This generally involves calling [`keeper`](#keeper)'s methods to query the state and marshalling it to JSON. See an example of `querier` functions [here](https://github.com/cosmos/sdk-application-tutorial/blob/master/x/nameservice/querier.go#L37-L101). + +To learn more about `queriers`, [click here](./querier.md). + +### Command-Line and REST Interfaces + +Each module defines command-line commands and REST routes to be exposed to end-user via the [application's interfaces](#application-interfaces). This enables end-users to create messages of the types defined in the module, or to query the subset of the state managed by the module. + +#### CLI + +Generally, the commands related to a module are defined in a folder called `client/cli` in the module's folder. The CLI divides commands in two category, transactions and queries, defined in `client/cli/tx.go` and `client/cli/query.go` respectively. Both build commands on top of the [Cobra Library](https://github.com/spf13/cobra): + +- Transactions commands let users generate new transactions so that they can be included in a block and eventually update the state. One command should be created for each [message type](#message-types) defined in the module. The command calls the constructor of the message with the parameters provided by the end-user, and wraps it into a transaction. The SDK handles signing and the addition of other transaction metadata. See examples of transactions commands [here](https://github.com/cosmos/sdk-application-tutorial/blob/master/x/nameservice/client/cli/tx.go). +- Queries let users query the subset of the state defined by the module. Query commands forward queries to the [application's query router](./baseapp.md#query-routing), which routes them to the appropriate [querier](#querier) the `queryRoute` parameter supplied. See examples of query commands [here](https://github.com/cosmos/sdk-application-tutorial/blob/master/x/nameservice/client/cli/query.go). + +To learn more about modules CLI, [click here](./module-interfaces.md#cli). + +#### REST + +The module's REST interface lets users generate transactions and query the state through REST calls to the application's [light-client daemon](./node.md#lcd). REST routes are defined in a file `client/rest/rest.go`, which is composed of: + +- A `RegisterRoutes` function, which registers each route defined in the file. This function is called from the [main application's interface](#application-interfaces) for each module used within the application. The router used in the SDK is [Gorilla's mux](https://github.com/gorilla/mux). +- Custom request type definitions for each query or transaction creation function that needs to be exposed. These custom request types build on the [base `request` type](https://github.com/cosmos/cosmos-sdk/blob/master/types/rest/rest.go#L32-L43) of the Cosmos SDK. +- One handler function for each request that can be routed to the given module. These functions implement the core logic necessary to serve the request. + +See an example of a module's `rest.go` file [here](https://github.com/cosmos/sdk-application-tutorial/blob/master/x/nameservice/client/rest/rest.go). + +To learn more about modules REST interface, [click here](./module-interfaces.md#rest). + +## Application Interface + +Interfaces let end-users interract with full-node clients. This means querying data from the full-node or creating and sending new transactions to be relayed by the full-node and eventually included in a block. + +The main interface is the [Command-Line Interface](./interfaces.md#cli). The CLI of an SDK application is built by aggregating [CLI commands](#cli) defined in each of the modules used by the application. The CLI of an application generally has the `-cli` suffix (e.g. `appcli`), and defined in a file called `cmd/appcli/main.go`. The file contains: + +- **A `main()` function**, which is executed to build the `appcli` interface client. This function prepares each command and adds them to the `rootCmd` before building them. At the root of `appCli`, the function adds generic commands like `status`, `keys` and `config`, query commands, tx commands and `rest-server`. +- **Query commands** are added by calling the `queryCmd` function, also defined in `appcli/main.go`. This function returns a Cobra command that contains the query commands defined in each of the application's modules (passed as an array of `sdk.ModuleClients` from the `main()` function), as well as some other lower level query commands such as block or validator queries. Query command are called by using the command `appcli query [query]` of the CLI. +- **Transaction commands** are added by calling the `txCmd` function. Similar to `queryCmd`, the function returns a Cobra command that contains the tx commands defined in each of the application's modules, as well as lower level tx commands like transaction signing or broadcasting. Tx commands are called by using the command `appcli tx [tx]` of the CLI. +- **A `registerRoutes` function**, which is called from the `main()` function when initializing the [application's light-client daemon (LCD)](./node.md#lcd) (i.e. `rest-server`). `registerRoutes` calls the `RegisterRoutes` function of each of the application's module, thereby registering the routes of the module to the lcd's router. The LCD can be started by running the following command `appcli rest-server`. + +See an example of an application's main command-line file [here](https://github.com/cosmos/sdk-application-tutorial/blob/master/cmd/nscli/main.go). + +To learn more about interfaces, [click here](./interfaces.md) + +## Dependencies and Makefile + + + +## Next + +Learn more about the [Lifecycle of a transaction](./tx-lifecycle.md). \ No newline at end of file diff --git a/docs/intro/why-app-specific.md b/docs/intro/why-app-specific.md index ce454383711c..0873f87d0e4a 100644 --- a/docs/intro/why-app-specific.md +++ b/docs/intro/why-app-specific.md @@ -74,5 +74,5 @@ The fundamental issue here is that the governance of the application and the gov Clearly, application-specific blockchains are awesome. The Cosmos SDK makes it easier than ever to build them. What are you waiting for? -- Learn how to build an application-specific blockchain from scratch with the [SDK tutorial](https://cosmos.network/docs/tutorial) - Learn more about the [high-level architecture](./sdk-app-architecture) of an SDK application. +- Learn how to build an application-specific blockchain from scratch with the [SDK tutorial](https://cosmos.network/docs/tutorial) From afbaba58e490008cd7baa176d2c31d973a30cddc Mon Sep 17 00:00:00 2001 From: gamarin Date: Mon, 10 Jun 2019 15:13:41 +0200 Subject: [PATCH 038/196] refactor for new module interface --- docs/.vuepress/config.js | 2 +- docs/concepts/app-anatomy.md | 132 +++++++++++++++--------- docs/concepts/{amino.md => encoding.md} | 0 docs/concepts/fees-signature.md | 7 ++ docs/concepts/invariants.md | 5 + docs/concepts/modules.md | 7 +- 6 files changed, 105 insertions(+), 48 deletions(-) rename docs/concepts/{amino.md => encoding.md} (100%) create mode 100644 docs/concepts/fees-signature.md create mode 100644 docs/concepts/invariants.md diff --git a/docs/.vuepress/config.js b/docs/.vuepress/config.js index d8756aae2385..602d20781420 100644 --- a/docs/.vuepress/config.js +++ b/docs/.vuepress/config.js @@ -32,7 +32,7 @@ module.exports = { "/intro/why-app-specific", "/intro/sdk-app-architecture", "/intro/sdk-design", - "intro/ocap" + "/intro/ocap" ] }, { diff --git a/docs/concepts/app-anatomy.md b/docs/concepts/app-anatomy.md index 346b35abab80..1646e0f39e8a 100644 --- a/docs/concepts/app-anatomy.md +++ b/docs/concepts/app-anatomy.md @@ -28,16 +28,16 @@ The core parts listed above will generally translate to the following directory │ └── bank ├── Gopkg.toml └── Makefile -``` +``` -## Node Client (Daemon) +## Node Client -The Daemon, or Full-Node Client, is the core process of an SDK-based blockchain. Participants in the network run this process to initialize their state-machine, connect with other full-nodes and update their state-machine as new blocks come in. +The Daemon, or Full-Node Client, is the core process of an SDK-based blockchain. Participants in the network run this process to initialize their state-machine, connect with other full-nodes and update their state-machine as new blocks come in. ``` ^ +-------------------------------+ ^ | | | | - | | State+machine = Application | | + | | State-machine = Application | | | | | | Built with Cosmos SDK | | ^ + | | | +----------- | ABCI | ----------+ v @@ -55,73 +55,111 @@ The blockchain full-node presents itself as a binary, generally suffixed by `-d` To learn more about the `main.go` function, [click here](./node.md#main-function). -Once the main binary is built, the node can be started by running the `start` command. The core logic behind the `start` command is implemented in the SDK itself in the [`/server/start.go`](https://github.com/cosmos/cosmos-sdk/blob/master/server/start.go) file. The main [`start` command function](https://github.com/cosmos/cosmos-sdk/blob/master/server/start.go#L31) takes a [`context`](https://godoc.org/github.com/cosmos/cosmos-sdk/client/context) and [`appCreator`](#constructor-function-(`appCreator`)) as arguments. The `appCreator` is a constructor function for the SDK application, and is used in the starting process of the full-node. +Once the main binary is built, the node can be started by running the `start` command. The core logic behind the `start` command is implemented in the SDK itself in the [`/server/start.go`](https://github.com/cosmos/cosmos-sdk/blob/master/server/start.go) file. The main [`start` command function](https://github.com/cosmos/cosmos-sdk/blob/master/server/start.go#L31) takes a [`context`](https://godoc.org/github.com/cosmos/cosmos-sdk/client/context) and [`appCreator`](#constructor-function-(`appCreator`)) as arguments. The `appCreator` is a constructor function for the SDK application, and is used in the starting process of the full-node. The `start` command function primarily does three things: -1- Create an instance of the state-machine defined in [`app.go`](#core-application-file) using the `appCreator`. -2- Initialize the state-machine with the latest known state, extracted from the `db` stored in the `~/.appd/data` folder. At this point, the state-machine is at height `appBlockHeight`. -3- Create and start a new Tendermint instance. Among other things, the node will perform a handshake with its peers. It will get the latest `blockHeight` from them, and replay blocks to sync to this height if it is greater than the local `appBlockHeight`. If `appBlockHeight` is `0`, the node is starting from genesis and Tendermint sends an `InitChain` message via the ABCI to the `app`, which triggers the [`InitChainer`](#initchainer). +1. Create an instance of the state-machine defined in [`app.go`](#core-application-file) using the `appCreator`. +2. Initialize the state-machine with the latest known state, extracted from the `db` stored in the `~/.appd/data` folder. At this point, the state-machine is at height `appBlockHeight`. +3. Create and start a new Tendermint instance. Among other things, the node will perform a handshake with its peers. It will get the latest `blockHeight` from them, and replay blocks to sync to this height if it is greater than the local `appBlockHeight`. If `appBlockHeight` is `0`, the node is starting from genesis and Tendermint sends an `InitChain` message via the ABCI to the `app`, which triggers the [`InitChainer`](#initchainer). To learn more about the `start` command, [click here](./node.md#start-command). ## Core Application File -In general, the core of the state-machine is defined in a file called `app.go`. It mainly contains the **type definition of the application** and functions to **create and initialize it**. +In general, the core of the state-machine is defined in a file called `app.go`. It mainly contains the **type definition of the application** and functions to **create and initialize it**. ### Type Definition of the Application The first thing defined in `app.go` is the `type` of the application. It is generally comprised of the following parts: -- **A reference to [`baseapp`](./baseapp.md).** The custom application defined in `app.go` is a golang embedding of the `baseapp` type. `baseapp` implements most of the core logic for the application, including all the [ABCI methods](https://tendermint.com/docs/spec/abci/abci.html#overview) and the routing logic. When a transaction is relayed by Tendermint to the application, the latter uses `baseapp`'s methods to route them to the appropriate module. +- **A reference to [`baseapp`](./baseapp.md).** The custom application defined in `app.go` is an extension of the `baseapp` type. `baseapp` implements most of the core logic for the application, including all the [ABCI methods](https://tendermint.com/docs/spec/abci/abci.html#overview) and the routing logic. When a transaction is relayed by Tendermint to the application, the latter uses `baseapp`'s methods to route them to the appropriate module. - **A list of store keys**. The [store](./store.md), which contains the entire state, is implemented as a multistore (i.e. a store of stores) in the Cosmos SDK. Each module uses one or multiple stores in the multistore to persist their part of the state. These stores can be accessed with specific keys that are declared in the `app` type. These keys, along with the `keepers`, are at the heart of the [object-capabilities model](../intro/ocap.md) of the Cosmos SDK. -- **A list of module's `keepers`.** Each module defines an abstraction called `keeper`, which handles reads and writes for this module's store(s). The `keeper`'s methods of one module can be called from other modules (if authorized), which is why they are declared in the application's type. -- **A reference to a `codec`.** The Cosmos SDK gives developers the freedom to choose the encoding framework for their application. The application's `codec` is used to serialize and deserialize data structures in order to store them, as stores can only persist `[]bytes`. The `codec` must be deterministic. Most SDK application use [amino](./amino.md) as their `codec`. +- **A list of module's [`keepers`](#keeper).** Each module defines an abstraction called `keeper`, which handles reads and writes for this module's store(s). The `keeper`'s methods of one module can be called from other modules (if authorized), which is why they are declared in the application's type. +- **A reference to a `codec`.** The Cosmos SDK gives developers the freedom to choose the encoding framework for their application. The application's `codec` is used to serialize and deserialize data structures in order to store them, as stores can only persist `[]bytes`. The `codec` must be deterministic. Most SDK application use [amino](./amino.md) as their `codec`. +- **A reference to a [module manager](./modules.md#module-manager)**. The module manager is an object that contains a list of the application's module. It facilitates operations related to these modules, like registering [`routes`](./baseapp.md#routing), [query routes](#./baseapp.md#query-routing) or setting the order of execution between modules for various functions like [`InitChainer`](#initchainer), [`BeginBlocker` and `EndBlocker`](#beginblocker-and-endblocker). -You can see an example of application type definition [here](https://github.com/cosmos/sdk-application-tutorial/blob/master/app.go#L27-L43). +You can see an example of application type definition [here](https://github.com/cosmos/gaia/blob/master/app/app.go#L73-L107). ### Constructor Function This function constructs a new application of the type defined above. It is [called](https://github.com/cosmos/cosmos-sdk/blob/master/server/start.go#L117) everytime the full-node is started with the `start` command. Here are the main actions performed by this function: -- Instanciate a new application with a reference to a `baseapp` instance, a codec and all the appropriate store keys. -- Instanciate all the `keepers` defined in the application's `type`. -- Initialize the application's [`routes`](./baseapp.md#routing) with the [`handlers`](#handler) of each one of the application's modules. When a transaction is relayed to the application by Tendermint via the ABCI, it is routed to the appropriate module's handler using the routes defined here. -- Initialize the application's [query routes](./baseapp.md#query-routing) with the [`queriers`](#querier) of each of the application's modules. When a user query comes in, it is routed to the appropriate module using the query routes defined here. -- Set the application's [`initChainer`](#initchainer) and mount the stores. -- Return the application. +- Instantiate a new application with a reference to a `baseapp` instance, a codec and all the appropriate store keys. +- Instantiate all the [`keeper`s](#keeper) defined in the application's `type` using the `NewKeeper` function of each of the application's modules. Note that `keepers` must be instantiated in the correct order, as the `NewKeeper` of one module might require a reference to another module's `keeper`. +- Instantiate the application's [module manager](./module-manager.md) with the [`AppModule`](#application-module-interface) object of each of the application's modules. +- With the module manager, initialize the application's [`routes`](./baseapp.md#routing) and [query routes](./baseapp.md#query-routing). When a transaction is relayed to the application by Tendermint via the ABCI, it is routed to the appropriate module's [`handler`](#handler) using the routes defined here. Likewise, when a query is received by the application, it is routed to the appropriate module's [`querier`](#querier) using the query routes defined here. +- With the module manager, register the [application's modules' invariants](./invariants.md). Invariants are variables (e.g. total supply of a token) that are evaluated at the end of each block. The process of checking invariants is done via a special module called the [`InvariantsRegistry`](./invariants.md#invariant-registry). The value of the ivnariant should be equal to a predicted value defined in the module. Should the value be different than the predicted one, special logic defined in the invariant registry will be triggered (usually the chain is halted). This is useful to make sure no critical bug goes unoticed and produces long-lasting effects that would be hard to fix. +- With the module manager, set the order of execution between the `InitGenesis`, `BegingBlocker` and `EndBlocker` functions of each of the [application's modules](#application-module-interface). Note that not all modules implement these functions. +- Set the application's [`InitChainer`](#initchainer) (used to initialize the application when it is first started), [`BeginBlocker`, `EndBlocker`](#beginblocker-and-endlbocker) (called at the beginning and the end of every block) and [`anteHandler`](#baseapp.md#antehandler) (used to handle fees and signature verification). +- Mount the stores. +- Return the application. -Note that this function only creates an instance of the app, while the actual state is either carried over from the `~/.appd/data` folder if the node is restarted, or generated from the genesis file if the node is started for the first time. +Note that this function only creates an instance of the app, while the actual state is either carried over from the `~/.appd/data` folder if the node is restarted, or generated from the genesis file if the node is started for the first time. -You can see an example of application constructor [here](https://github.com/cosmos/sdk-application-tutorial/blob/master/app.go#L46-L128). +You can see an example of application constructor [here](https://github.com/cosmos/gaia/blob/master/app/app.go#L110-L222). ### InitChainer -The `initChainer` is a function that initializes the state of the application from a [genesis file](./genesis.md) (i.e. token balances of genesis accounts). It is called when the application received the `InitChain` message from the Tendermint engine, which happens when the node is started at `appBlockHeight == 0` (i.e. on genesis). The application must set the `initChainer` in its constructor via the [`setInitChainer`](https://godoc.org/github.com/cosmos/cosmos-sdk/baseapp#BaseApp.SetInitChainer) method. +The `InitChainer` is a function that initializes the state of the application from a [genesis file](./genesis.md) (i.e. token balances of genesis accounts). It is called when the application receives the `InitChain` message from the Tendermint engine, which happens when the node is started at `appBlockHeight == 0` (i.e. on genesis). The application must set the `InitChainer` in its constructor via the [`SetInitChainer`](https://godoc.org/github.com/cosmos/cosmos-sdk/baseapp#BaseApp.SetInitChainer) method. + +In general, the `InitChainer` is mostly composed of the `InitGenesis` function of each of the application's modules. This is done by calling the `InitGenesis` function of the module manager, which in turn will call the `InitGenesis` function of each of the modules it contains. Note that the order in which the modules' `InitGenesis` functions must be called has to be set in the module manager using the `SetOrderInitGenesis` method. This is done in the [application's constructor](#application-constructor), and the `SetOrderInitGenesis` has to be called before the `SetInitChainer`. + +You can see an example of an `InitChainer` [here](https://github.com/cosmos/gaia/blob/master/app/app.go#L235-L239). + +### BeginBlocker and EndBlocker -You can see an example of an `initChainer` [here](https://github.com/cosmos/sdk-application-tutorial/blob/master/app.go#L137-L155). +The SDK offers developers the possibility to implement automatic execution of code as part of their application. This is implemented through two function called `BeginBlocker` and `EndBlocker`. They are called when the application receives respectively the `BeginBlock` and `EndBlock` messages from the Tendermint engine, which happens at the beginning and at the end of each block. The application must set the `BeginBlocker` and `EndBlocker` in its constructor via the [`SetBeginBlocker`](https://godoc.org/github.com/cosmos/cosmos-sdk/baseapp#BaseApp.SetBeginBlocker) and [`SetEndBlocker`](https://godoc.org/github.com/cosmos/cosmos-sdk/baseapp#BaseApp.SetEndBlocker) methods. + +In general, the `BeginBlocker` and `EndBlocker` functions are mostly composed of the `BeginBlock` and `EndBlock` functions of each of the application's modules. This is done by calling the `BeginBlock` and `EndBlock` functions of the module manager, which in turn will call the `BeginBLock` and `EndBlock` functions of each of the modules it contains. Note that the order in which the modules' `BegingBlock` and `EndBlock` functions must be called has to be set in the module manager using the `SetOrderBeginBlock` and `SetOrderEndBlock` methods respectively. This is done in the [application's constructor](#application-constructor), and the `SetOrderBeginBlock` and `SetOrderEndBlock` methods have to be called before the `SetBeginBlocker` and `SetEndBlocker` functions. + +As a sidenote, it is important to remember that application-specific blockchains are deterministic. Developers must be careful not to introduce non-determinism in `BeginBlocker` or `EndBlocker`, and must also be careful not to make them too computationally expensive, as [gas](./fees-signature.md/gas) does not constrain the cost of `BeginBlocker` and `EndBlocker` execution. + +You can see an example of `BeginBlocker` and `EndBlocker` functions [here](https://github.com/cosmos/gaia/blob/master/app/app.go#L224-L232). ### Register Codec -The `MakeCodec` function is the last important function of the `app.go` file. The goal of this function is to instanciate a codec `cdc` (e.g. [amino](./amino.md)) and calls the `RegisterCodec(*codec.Codec)` method of each module used within the application to register `cdc` to each module. +The `MakeCodec` function is the last important function of the `app.go` file. The goal of this function is to instantiate a codec `cdc` (e.g. [amino](./amino.md)) initiliaze the codec of the SDK and each of the application's modules using the `RegisterCodec` function. -In turn, the `RegisterCodec` function of each module register the custom interfaces and type structures of their respective module so that they can be marhsaled and unmarshaled. +To register the application's modules, the `MakeCodec` function calls `RegisterCodec` on `ModuleBasics`. `ModuleBasics` is a [basic manager](./modules.md#basic-manager) which lists all of the application's modules. It is instanciated in the `init()` function, and only serves to easily register non-dependant elements of application's modules (such as codec). To learn more about the basic module manager, click [here](./modules.md#basic-manager). -You can see an example of a `MakeCodec` [here](You can see an example of an `initChainer` [here](https://github.com/cosmos/sdk-application-tutorial/blob/master/app.go#L189-L198).). +You can see an example of a `MakeCodec` [here](https://github.com/cosmos/gaia/blob/master/app/app.go#L64-L70) ## Modules -Modules are the heart and soul of an SDK application. They can be considered as state-machines within the state-machine. When a transaction is relayed from the underlying Tendermint engine via the ABCI to the application, it is routed by `baseapp` to the appropriate module in order to be processed. This paradigm enables developers to easily build complex state-machines, as most of the modules they need often already exist. For developers, most of the work involved in building an SDK application revolves around building custom modules required by their application that do not exist, and integrating them with modules that do already exist into one coherent application. In the application directory, the standard practice is to store modules in the `x/` folder. +Modules are the heart and soul of an SDK application. They can be considered as state-machines within the state-machine. When a transaction is relayed from the underlying Tendermint engine via the ABCI to the application, it is routed by `baseapp` to the appropriate module in order to be processed. This paradigm enables developers to easily build complex state-machines, as most of the modules they need often already exist. For developers, most of the work involved in building an SDK application revolves around building custom modules required by their application that do not exist, and integrating them with modules that do already exist into one coherent application. In the application directory, the standard practice is to store modules in the `x/` folder (not to be confused with the SDK's `x/` folder, which contains already-built modules). To learn more about modules, [click here](./modules.md) +### Application Module Interface + +Modules implement two interfaces defined in the Cosmos SDK, [`AppModuleBasic`](https://github.com/cosmos/cosmos-sdk/blob/master/types/module/module.go#L44-L57) and [`AppModule`](https://github.com/cosmos/cosmos-sdk/blob/master/types/module/module.go#L44-L57). The former implements basic non-dependant elements of the module, such as the `codec`, while the latter handles the bulk of the module methods (including methods that require references to other modules' `keeper`s). Both the `AppModule` and `AppModuleBasic` types are defined in a file called `./module.go`. + +`AppModule` exposes a collection of useful methods on the module that facilitates the composition of modules into a coherent application. Important methods include: + +- `Route()` and `QueryRoute()`: These methods the name of the route and querier route for the module, for [messages](#message-types) to be routed to the module's [`handler`](#handler) and queries to be routes to the module's [`querier`](#querier). +- `NewHandler()` and `NewQuerierHandler()`: These methods return a `handler` and `querierHandler` respectively, in order to process a message or a query once they are routed. +- `BeginBlock()`, `EndBlock()` and `InitGenesis()`: These methods are executed respectively at the beginning of each block, at the end of each block and at the start of the chain. They implement special logic the module requires to be triggered during those events. For example, the `EndBlock` function is frequently used by modules where voting occurs to tally the result of the votes. +- `RegisterInvariants()`: This method registers the [invariants](./invariants.md) for the module. Invariants are checked at the end of every block to make sure no unpredicted behaviour is occuring. + +`AppModule`'s methods are called from the `module manager`(./modules.md#module-manager), which manages the application's collection of modules. + +To learn more about the application module interface, [click here](./modules.md#application-module-interface). + ### Message Types -A message is a custom type defined by each module that implements the [`message`](https://github.com/cosmos/cosmos-sdk/blob/master/types/tx_msg.go#L8-L29) interface. Each `transaction` contains one or multiple `messages`. When a valid block of transactions is received by the full-node, Tendermint relays each one to the application via [`DeliverTx`](https://tendermint.com/docs/app-dev/abci-spec.html#delivertx). Upon receiving the transaction, the application first unmarshalls it. Then, it extracts the message(s) contained in the application. With the [`Type()`](https://github.com/cosmos/cosmos-sdk/blob/master/types/tx_msg.go#L16) method, `baseapp` is able to know which modules defines the message. It is then able to route it to the appropriate module's [handler](#handler) in order for the message to be processed. If the message is succesfully processed, the state is updated. +A message is a custom type defined by each module that implements the [`message`](https://github.com/cosmos/cosmos-sdk/blob/master/types/tx_msg.go#L8-L29) interface. Each `transaction` contains one or multiple `messages`. When a valid block of transactions is received by the full-node, Tendermint relays each one to the application via [`DeliverTx`](https://tendermint.com/docs/app-dev/abci-spec.html#delivertx). Then, the application handles the transaction: + +1. Upon receiving the transaction, the application first unmarshalls it from `[]bytes`. +2. Then, it verifies a few things about the transaction like [fee payment and signatures](#fees-signature.md) before extracting the message(s) contained in the transaction. +3. With the [`Type()`](https://github.com/cosmos/cosmos-sdk/blob/master/types/tx_msg.go#L16) method, `baseapp` is able to know which modules defines the message. It is then able to route it to the appropriate module's [handler](#handler) in order for the message to be processed. +4. If the message is successfully processed, the state is updated. -Module developers create custom message types when they build their own module. The general practice is to prefix the type declaration of the message with `Msg`. For example, the message type `MsgSend` allows users to transfer tokens. It is processed by the handler of the `bank` module, which ultimately calls the `keeper` of the `auth` module in order to update the state. +For a more detailed look at a transaction lifecycle, click [here](./tx-lifecycle.md). -To learn more about messages, [click here](./tx-msgs.md) +Module developers create custom message types when they build their own module. The general practice is to prefix the type declaration of the message with `Msg`. For example, the message type [`MsgSend`](https://github.com/cosmos/cosmos-sdk/blob/master/x/bank/types/msgs.go#L10-L15) allows users to transfer tokens. It is processed by the handler of the `bank` module, which ultimately calls the `keeper` of the `auth` module in order to update the state. + +To learn more about messages, [click here](./tx-msgs.md). ### Handler @@ -129,8 +167,8 @@ The `handler` refers to the part of the module responsible for processing the me The handler of a module is generally defined in a file called `handler.go` and consists of: -- A **switch function** `NewHandler` to route the message to the appropriate handler function. This function returns a `handler` function, and is used in `app.go` to initialize the [application's router](./baseapp.md#routing). See an example of such a switch [here](https://github.com/cosmos/sdk-application-tutorial/blob/master/x/nameservice/handler.go#L10-L22). -- **One handler function for each message type defined by the module**. Developers write the message processing logic in these functions. This generally involves doing stateful checks to ensure the message is valid and calling [`keeper`](#keeper)'s methods to update the state. +- A **switch function** `NewHandler` to route the message to the appropriate handler function. This function returns a `handler` function, and is registered in the [`AppModule`](#application-module-interface) to be used in the application's module manager to initialize the [application's router](./baseapp.md#routing). See an example of such a switch [here](https://github.com/cosmos/sdk-application-tutorial/blob/master/x/nameservice/handler.go#L10-L22). +- **One handler function for each message type defined by the module**. Developers write the message processing logic in these functions. This generally involves doing stateful checks to ensure the message is valid and calling [`keeper`](#keeper)'s methods to update the state. Handler functions return a result of type [`sdk.Result`](https://github.com/cosmos/cosmos-sdk/blob/master/types/result.go#L14-L37), which informs the application on wether the message was succesfully processed and. @@ -140,36 +178,38 @@ To learn more about handlers, [click here](./handler.md). `Keepers` are the gatekeepers of their module's store(s). To read or write in a module's store, it is mandatory to go through one of its `keeper`'s methods. This is ensured by the [object-capabilities](./ocap.md) model of the Cosmos SDK. Only objects that hold the key to a store can access it, and only the module's `keeper` should hold the key(s) to the module's store(s). -`Keepers` are generally defined in a file called `keeper.go`. It contains the `keeper`'s type definition and methods. +`Keepers` are generally defined in a file called `keeper.go`. It contains the `keeper`'s type definition and methods. The `keeper` type definition generally consists of: -- **Key(s)** to the module's store(s) in the multistore. +- **Key(s)** to the module's store(s) in the multistore. - Reference to **other module's `keepers`**. Only needed if the `keeper` needs to access other module's store(s) (either to read or write from them). -- A reference to the application's **codec**. The `keeper` needs it to marshal structs before storing them, or to unmarhsal them when it retrieves them, because stores only accept `[]bytes` as value. +- A reference to the application's **codec**. The `keeper` needs it to marshal structs before storing them, or to unmarshal them when it retrieves them, because stores only accept `[]bytes` as value. + +Along with the type definition, the next important component of the `keeper.go` file is the `keeper`'s constructor function, `NewKeeper`. This function instantiates a new `keeper` of the type defined above, with a `codec`, store `keys` and potentially references to other modules' `keeper`s as parameters. The `NewKeeper` function is called from the [application's constructor](#constructor-function). The rest of the file defines the `keeper`'s methods, primarily getters and setters. You can check an example of a `keeper` implementation [here](https://github.com/cosmos/sdk-application-tutorial/blob/master/x/nameservice/keeper.go). To learn more about `keepers`, [click here](./keeper.md). -### Querier +### Querier -`Queriers` are very similar to `handlers`, except they serve user queries to the state as opposed to processing transactions. A query is initiated from an [interface](#intefaces) by an end-user who provides a `queryRoute` and some `data`. The query is then routed to the correct application's `querier` by `baseapp`'s [`handleQueryCustom`](https://github.com/cosmos/cosmos-sdk/blob/master/baseapp/baseapp.go#L519-L556) method using `queryRoute`. +`Queriers` are very similar to `handlers`, except they serve user queries to the state as opposed to processing transactions. A query is initiated from an [interface](#intefaces) by an end-user who provides a `queryRoute` and some `data`. The query is then routed to the correct application's `querier` by `baseapp`'s [`handleQueryCustom`](https://github.com/cosmos/cosmos-sdk/blob/master/baseapp/baseapp.go#L519-L556) method using `queryRoute`. The `Querier` of a module are defined in a file called `querier.go`, and consists of: -- A **switch function** `NewQuerier` to route the query to the appropriate `querier` function. This function returns a `querier` function, and is used in `app.go` to initialize the [application's query router](./baseapp.md#query-routing). See an example of such a switch [here](https://github.com/cosmos/sdk-application-tutorial/blob/master/x/nameservice/querier.go#L21-L34). +- A **switch function** `NewQuerier` to route the query to the appropriate `querier` function. This function returns a `querier` function, and is is registered in the [`AppModule`](#application-module-interface) to be used in the application's module manager to initialize the [application's query router](./baseapp.md#query-routing). See an example of such a switch [here](https://github.com/cosmos/sdk-application-tutorial/blob/master/x/nameservice/querier.go#L21-L34). - - **One querier function for each data type defined by the module that needs to be queryable**. Developers write the query processing logic in these functions. This generally involves calling [`keeper`](#keeper)'s methods to query the state and marshalling it to JSON. See an example of `querier` functions [here](https://github.com/cosmos/sdk-application-tutorial/blob/master/x/nameservice/querier.go#L37-L101). To learn more about `queriers`, [click here](./querier.md). ### Command-Line and REST Interfaces -Each module defines command-line commands and REST routes to be exposed to end-user via the [application's interfaces](#application-interfaces). This enables end-users to create messages of the types defined in the module, or to query the subset of the state managed by the module. +Each module defines command-line commands and REST routes to be exposed to end-user via the [application's interfaces](#application-interfaces). This enables end-users to create messages of the types defined in the module, or to query the subset of the state managed by the module. #### CLI -Generally, the commands related to a module are defined in a folder called `client/cli` in the module's folder. The CLI divides commands in two category, transactions and queries, defined in `client/cli/tx.go` and `client/cli/query.go` respectively. Both build commands on top of the [Cobra Library](https://github.com/spf13/cobra): +Generally, the commands related to a module are defined in a folder called `client/cli` in the module's folder. The CLI divides commands in two category, transactions and queries, defined in `client/cli/tx.go` and `client/cli/query.go` respectively. Both commands are built on top of the [Cobra Library](https://github.com/spf13/cobra): - Transactions commands let users generate new transactions so that they can be included in a block and eventually update the state. One command should be created for each [message type](#message-types) defined in the module. The command calls the constructor of the message with the parameters provided by the end-user, and wraps it into a transaction. The SDK handles signing and the addition of other transaction metadata. See examples of transactions commands [here](https://github.com/cosmos/sdk-application-tutorial/blob/master/x/nameservice/client/cli/tx.go). - Queries let users query the subset of the state defined by the module. Query commands forward queries to the [application's query router](./baseapp.md#query-routing), which routes them to the appropriate [querier](#querier) the `queryRoute` parameter supplied. See examples of query commands [here](https://github.com/cosmos/sdk-application-tutorial/blob/master/x/nameservice/client/cli/query.go). @@ -181,7 +221,7 @@ To learn more about modules CLI, [click here](./module-interfaces.md#cli). The module's REST interface lets users generate transactions and query the state through REST calls to the application's [light-client daemon](./node.md#lcd). REST routes are defined in a file `client/rest/rest.go`, which is composed of: - A `RegisterRoutes` function, which registers each route defined in the file. This function is called from the [main application's interface](#application-interfaces) for each module used within the application. The router used in the SDK is [Gorilla's mux](https://github.com/gorilla/mux). -- Custom request type definitions for each query or transaction creation function that needs to be exposed. These custom request types build on the [base `request` type](https://github.com/cosmos/cosmos-sdk/blob/master/types/rest/rest.go#L32-L43) of the Cosmos SDK. +- Custom request type definitions for each query or transaction creation function that needs to be exposed. These custom request types build on the [base `request` type](https://github.com/cosmos/cosmos-sdk/blob/master/types/rest/rest.go#L32-L43) of the Cosmos SDK. - One handler function for each request that can be routed to the given module. These functions implement the core logic necessary to serve the request. See an example of a module's `rest.go` file [here](https://github.com/cosmos/sdk-application-tutorial/blob/master/x/nameservice/client/rest/rest.go). @@ -190,23 +230,23 @@ To learn more about modules REST interface, [click here](./module-interfaces.md# ## Application Interface -Interfaces let end-users interract with full-node clients. This means querying data from the full-node or creating and sending new transactions to be relayed by the full-node and eventually included in a block. +Interfaces let end-users interact with full-node clients. This means querying data from the full-node or creating and sending new transactions to be relayed by the full-node and eventually included in a block. The main interface is the [Command-Line Interface](./interfaces.md#cli). The CLI of an SDK application is built by aggregating [CLI commands](#cli) defined in each of the modules used by the application. The CLI of an application generally has the `-cli` suffix (e.g. `appcli`), and defined in a file called `cmd/appcli/main.go`. The file contains: - **A `main()` function**, which is executed to build the `appcli` interface client. This function prepares each command and adds them to the `rootCmd` before building them. At the root of `appCli`, the function adds generic commands like `status`, `keys` and `config`, query commands, tx commands and `rest-server`. -- **Query commands** are added by calling the `queryCmd` function, also defined in `appcli/main.go`. This function returns a Cobra command that contains the query commands defined in each of the application's modules (passed as an array of `sdk.ModuleClients` from the `main()` function), as well as some other lower level query commands such as block or validator queries. Query command are called by using the command `appcli query [query]` of the CLI. +- **Query commands** are added by calling the `queryCmd` function, also defined in `appcli/main.go`. This function returns a Cobra command that contains the query commands defined in each of the application's modules (passed as an array of `sdk.ModuleClients` from the `main()` function), as well as some other lower level query commands such as block or validator queries. Query command are called by using the command `appcli query [query]` of the CLI. - **Transaction commands** are added by calling the `txCmd` function. Similar to `queryCmd`, the function returns a Cobra command that contains the tx commands defined in each of the application's modules, as well as lower level tx commands like transaction signing or broadcasting. Tx commands are called by using the command `appcli tx [tx]` of the CLI. -- **A `registerRoutes` function**, which is called from the `main()` function when initializing the [application's light-client daemon (LCD)](./node.md#lcd) (i.e. `rest-server`). `registerRoutes` calls the `RegisterRoutes` function of each of the application's module, thereby registering the routes of the module to the lcd's router. The LCD can be started by running the following command `appcli rest-server`. +- **A `registerRoutes` function**, which is called from the `main()` function when initializing the [application's light-client daemon (LCD)](./node.md#lcd) (i.e. `rest-server`). `registerRoutes` calls the `RegisterRoutes` function of each of the application's module, thereby registering the routes of the module to the lcd's router. The LCD can be started by running the following command `appcli rest-server`. See an example of an application's main command-line file [here](https://github.com/cosmos/sdk-application-tutorial/blob/master/cmd/nscli/main.go). To learn more about interfaces, [click here](./interfaces.md) -## Dependencies and Makefile +## Dependencies and Makefile ## Next -Learn more about the [Lifecycle of a transaction](./tx-lifecycle.md). \ No newline at end of file +Learn more about the [Lifecycle of a transaction](./tx-lifecycle.md). diff --git a/docs/concepts/amino.md b/docs/concepts/encoding.md similarity index 100% rename from docs/concepts/amino.md rename to docs/concepts/encoding.md diff --git a/docs/concepts/fees-signature.md b/docs/concepts/fees-signature.md new file mode 100644 index 000000000000..36982a97b5d8 --- /dev/null +++ b/docs/concepts/fees-signature.md @@ -0,0 +1,7 @@ +# Fees and Signatures + +## Signatures + +## Fees + +## Gas \ No newline at end of file diff --git a/docs/concepts/invariants.md b/docs/concepts/invariants.md new file mode 100644 index 000000000000..18cd9ad6224f --- /dev/null +++ b/docs/concepts/invariants.md @@ -0,0 +1,5 @@ +# Invariants + +## What is an invariant + +## Invariant Registry \ No newline at end of file diff --git a/docs/concepts/modules.md b/docs/concepts/modules.md index cfd71f817963..5c65c4d89f92 100644 --- a/docs/concepts/modules.md +++ b/docs/concepts/modules.md @@ -1,3 +1,8 @@ # SDK Modules -Todo: Intro concept docs on modules \ No newline at end of file +Todo: Intro concept docs on modules + +## Application Module Interface + +## Module Manager + From a039341475901ea97d08bbbf048c566b58249839 Mon Sep 17 00:00:00 2001 From: gamarin Date: Tue, 11 Jun 2019 16:09:21 +0200 Subject: [PATCH 039/196] karoly review --- docs/concepts/app-anatomy.md | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/docs/concepts/app-anatomy.md b/docs/concepts/app-anatomy.md index 1646e0f39e8a..78d7b1eda675 100644 --- a/docs/concepts/app-anatomy.md +++ b/docs/concepts/app-anatomy.md @@ -75,8 +75,8 @@ The first thing defined in `app.go` is the `type` of the application. It is gene - **A reference to [`baseapp`](./baseapp.md).** The custom application defined in `app.go` is an extension of the `baseapp` type. `baseapp` implements most of the core logic for the application, including all the [ABCI methods](https://tendermint.com/docs/spec/abci/abci.html#overview) and the routing logic. When a transaction is relayed by Tendermint to the application, the latter uses `baseapp`'s methods to route them to the appropriate module. - **A list of store keys**. The [store](./store.md), which contains the entire state, is implemented as a multistore (i.e. a store of stores) in the Cosmos SDK. Each module uses one or multiple stores in the multistore to persist their part of the state. These stores can be accessed with specific keys that are declared in the `app` type. These keys, along with the `keepers`, are at the heart of the [object-capabilities model](../intro/ocap.md) of the Cosmos SDK. -- **A list of module's [`keepers`](#keeper).** Each module defines an abstraction called `keeper`, which handles reads and writes for this module's store(s). The `keeper`'s methods of one module can be called from other modules (if authorized), which is why they are declared in the application's type. -- **A reference to a `codec`.** The Cosmos SDK gives developers the freedom to choose the encoding framework for their application. The application's `codec` is used to serialize and deserialize data structures in order to store them, as stores can only persist `[]bytes`. The `codec` must be deterministic. Most SDK application use [amino](./amino.md) as their `codec`. +- **A list of module's `keepers`.** Each module defines an abstraction called `keeper`, which handles reads and writes for this module's store(s). The `keeper`'s methods of one module can be called from other modules (if authorized), which is why they are declared in the application's type and exported as interfaces to other modules so that they are only allowed to access the authorized functions. +- **A reference to a `codec`.** The Cosmos SDK gives developers the freedom to choose the encoding framework for their application. The application's `codec` is used to serialize and deserialize data structures in order to store them, as stores can only persist `[]bytes`. The `codec` must be deterministic. The default codec is [amino](./amino.md). - **A reference to a [module manager](./modules.md#module-manager)**. The module manager is an object that contains a list of the application's module. It facilitates operations related to these modules, like registering [`routes`](./baseapp.md#routing), [query routes](#./baseapp.md#query-routing) or setting the order of execution between modules for various functions like [`InitChainer`](#initchainer), [`BeginBlocker` and `EndBlocker`](#beginblocker-and-endblocker). You can see an example of application type definition [here](https://github.com/cosmos/gaia/blob/master/app/app.go#L73-L107). @@ -91,7 +91,10 @@ This function constructs a new application of the type defined above. It is [cal - With the module manager, initialize the application's [`routes`](./baseapp.md#routing) and [query routes](./baseapp.md#query-routing). When a transaction is relayed to the application by Tendermint via the ABCI, it is routed to the appropriate module's [`handler`](#handler) using the routes defined here. Likewise, when a query is received by the application, it is routed to the appropriate module's [`querier`](#querier) using the query routes defined here. - With the module manager, register the [application's modules' invariants](./invariants.md). Invariants are variables (e.g. total supply of a token) that are evaluated at the end of each block. The process of checking invariants is done via a special module called the [`InvariantsRegistry`](./invariants.md#invariant-registry). The value of the ivnariant should be equal to a predicted value defined in the module. Should the value be different than the predicted one, special logic defined in the invariant registry will be triggered (usually the chain is halted). This is useful to make sure no critical bug goes unoticed and produces long-lasting effects that would be hard to fix. - With the module manager, set the order of execution between the `InitGenesis`, `BegingBlocker` and `EndBlocker` functions of each of the [application's modules](#application-module-interface). Note that not all modules implement these functions. -- Set the application's [`InitChainer`](#initchainer) (used to initialize the application when it is first started), [`BeginBlocker`, `EndBlocker`](#beginblocker-and-endlbocker) (called at the beginning and the end of every block) and [`anteHandler`](#baseapp.md#antehandler) (used to handle fees and signature verification). +- Set the remainer of application's parameters: + + [`InitChainer`](#initchainer): used to initialize the application when it is first started. + + [`BeginBlocker`, `EndBlocker`](#beginblocker-and-endlbocker): called at the beginning and the end of every block). + + [`anteHandler`](#baseapp.md#antehandler): used to handle fees and signature verification. - Mount the stores. - Return the application. From dc97fb5b2fa3aa3444ba8170651c53c01363ba1f Mon Sep 17 00:00:00 2001 From: gamarin Date: Mon, 17 Jun 2019 16:55:53 +0200 Subject: [PATCH 040/196] working on baseapp doc --- docs/concepts/baseapp_old.md | 128 +++++++++++++++++++++++++++++ docs/concepts/store.md | 8 ++ docs/core/baseapp_old.md | 151 +++++++++++++---------------------- 3 files changed, 192 insertions(+), 95 deletions(-) create mode 100644 docs/concepts/baseapp_old.md create mode 100644 docs/concepts/store.md diff --git a/docs/concepts/baseapp_old.md b/docs/concepts/baseapp_old.md new file mode 100644 index 000000000000..c4f71f33f696 --- /dev/null +++ b/docs/concepts/baseapp_old.md @@ -0,0 +1,128 @@ +# BaseApp + +The BaseApp defines the foundational implementation for a basic ABCI application +so that your Cosmos-SDK application can communicate with an underlying +Tendermint node. + +The BaseApp is composed of many internal components. Some of the most important +include the `CommitMultiStore` and its internal state. The internal state is +essentially two sub-states, both of which are used for transaction execution +during different phases, `CheckTx` and `DeliverTx` respectively. During block +commitment, only the `DeliverTx` is persisted. + +The BaseApp requires stores to be mounted via capabilities keys - handlers can +only access stores they're given the key to. The `baseApp` ensures all stores are +properly loaded, cached, and committed. One mounted store is considered the +"main" (`baseApp.MainStoreKey`) - it holds the latest block header, from which we can find and load the +most recent state. + +The BaseApp distinguishes between two handler types - the `AnteHandler` and the +`MsgHandler`. The former is a global validity check (checking nonces, sigs and +sufficient balances to pay fees, e.g. things that apply to all transaction from +all modules), the later is the full state transition function. + +During `CheckTx` the state transition function is only applied to the `checkTxState` +and should return before any expensive state transitions are run +(this is up to each developer). It also needs to return the estimated gas cost. + +During `DeliverTx` the state transition function is applied to the blockchain +state and the transactions need to be fully executed. + +The BaseApp is responsible for managing the context passed into handlers - +it makes the block header available and provides the right stores for `CheckTx` +and `DeliverTx`. BaseApp is completely agnostic to serialization formats. + +## Routing + +TODO + +## Transaction Life Cycle + +During the execution of a transaction, it may pass through both `CheckTx` and +`DeliverTx` as defined in the ABCI specification. `CheckTx` is executed by the +proposing validator and is used for the Tendermint mempool for all full nodes. + +Both `CheckTx` and `DeliverTx` execute the application's AnteHandler (if +defined), where the AnteHandler is responsible for pre-message validation +checks such as account and signature validation, fee deduction and collection, +and incrementing sequence numbers. + +### CheckTx + +During the execution of `CheckTx`, only the AnteHandler is executed. + +State transitions due to the AnteHandler are persisted between subsequent calls +of `CheckTx` in the check-tx state, unless the AnteHandler fails and aborts. + +### DeliverTx + +During the execution of `DeliverTx`, the AnteHandler and Handler is executed. + +The transaction execution during `DeliverTx` operates in a similar fashion to +`CheckTx`. However, state transitions that occur during the AnteHandler are +persisted even when the following Handler processing logic fails. + +It is possible that a malicious proposer may include a transaction in a block +that fails the AnteHandler. In this case, all state transitions for the +offending transaction are discarded. + + +## Other ABCI Messages + +Besides `CheckTx` and `DeliverTx`, BaseApp handles the following ABCI messages. + +### Info +TODO complete description + +### SetOption +TODO complete description + +### Query +TODO complete description + +### InitChain +TODO complete description + +During chain initialization InitChain runs the initialization logic directly on +the CommitMultiStore. The deliver and check states are initialized with the +ChainID. + +Note that we do not commit after InitChain, so BeginBlock for block 1 starts +from the deliver state as initialized by InitChain. + +### BeginBlock +TODO complete description + +### EndBlock +TODO complete description + +### Commit +TODO complete description + + +## Gas Management + +### Gas: InitChain + +During InitChain, the block gas meter is initialized with an infinite amount of +gas to run any genesis transactions. + +Additionally, the InitChain request message includes ConsensusParams as +declared in the genesis.json file. + +### Gas: BeginBlock + +The block gas meter is reset during BeginBlock for the deliver state. If no +maximum block gas is set within baseapp then an infinite gas meter is set, +otherwise a gas meter with `ConsensusParam.BlockSize.MaxGas` is initialized. + +### Gas: DeliverTx + +Before the transaction logic is run, the `BlockGasMeter` is first checked to +see if any gas remains. If no gas remains, then `DeliverTx` immediately returns +an error. + +After the transaction has been processed, the used gas (up to the transaction +gas limit) is deducted from the BlockGasMeter. If the remaining gas exceeds the +meter's limits, then DeliverTx returns an error and the transaction is not +committed. diff --git a/docs/concepts/store.md b/docs/concepts/store.md new file mode 100644 index 000000000000..067eea3b79bd --- /dev/null +++ b/docs/concepts/store.md @@ -0,0 +1,8 @@ +# Store + +## Commit Multi Store + +## Database + +## Main Store + diff --git a/docs/core/baseapp_old.md b/docs/core/baseapp_old.md index c4f71f33f696..855b03cf1b55 100644 --- a/docs/core/baseapp_old.md +++ b/docs/core/baseapp_old.md @@ -1,128 +1,89 @@ # BaseApp -The BaseApp defines the foundational implementation for a basic ABCI application -so that your Cosmos-SDK application can communicate with an underlying -Tendermint node. - -The BaseApp is composed of many internal components. Some of the most important -include the `CommitMultiStore` and its internal state. The internal state is -essentially two sub-states, both of which are used for transaction execution -during different phases, `CheckTx` and `DeliverTx` respectively. During block -commitment, only the `DeliverTx` is persisted. - -The BaseApp requires stores to be mounted via capabilities keys - handlers can -only access stores they're given the key to. The `baseApp` ensures all stores are -properly loaded, cached, and committed. One mounted store is considered the -"main" (`baseApp.MainStoreKey`) - it holds the latest block header, from which we can find and load the -most recent state. - -The BaseApp distinguishes between two handler types - the `AnteHandler` and the -`MsgHandler`. The former is a global validity check (checking nonces, sigs and -sufficient balances to pay fees, e.g. things that apply to all transaction from -all modules), the later is the full state transition function. - -During `CheckTx` the state transition function is only applied to the `checkTxState` -and should return before any expensive state transitions are run -(this is up to each developer). It also needs to return the estimated gas cost. - -During `DeliverTx` the state transition function is applied to the blockchain -state and the transactions need to be fully executed. - -The BaseApp is responsible for managing the context passed into handlers - -it makes the block header available and provides the right stores for `CheckTx` -and `DeliverTx`. BaseApp is completely agnostic to serialization formats. +## Pre-requisite Reading -## Routing +- [Anatomy of an SDK application](./app-anatomy.md) +- [Lifecycle of an SDK transaction](./tx-lifecycle.md) -TODO +## Synopsis -## Transaction Life Cycle +This document describes `baseapp`, the abstraction that implements most of the common functionalities of an SDK application. -During the execution of a transaction, it may pass through both `CheckTx` and -`DeliverTx` as defined in the ABCI specification. `CheckTx` is executed by the -proposing validator and is used for the Tendermint mempool for all full nodes. +- [Introduction](#introduction) +- [Type Definition](#type-definition) +- [States and Modes](#states-and-modes) +- [Routing](#routing) +- [ABCI](#abci) +- [CheckTx](#abci-checktx) +- [DeliverTx](#abci-delivertx) +- [Commit](#abbci-commit) +- [Other ABCI Message](#other-abci-message) + + [Info](#info) + + [SetOption](#setoption) + + [Query](#query) + + [InitChain](#initchain) + + [BeginBlock](#beginblock) + + [EndBlock](#endblock) +- [Gas](#gas) -Both `CheckTx` and `DeliverTx` execute the application's AnteHandler (if -defined), where the AnteHandler is responsible for pre-message validation -checks such as account and signature validation, fee deduction and collection, -and incrementing sequence numbers. -### CheckTx +## Introduction -During the execution of `CheckTx`, only the AnteHandler is executed. +`baseapp` is an abstraction that implements the core of an SDK application, namely: -State transitions due to the AnteHandler are persisted between subsequent calls -of `CheckTx` in the check-tx state, unless the AnteHandler fails and aborts. +- The [Application-Blockchain Interface](#abci), for the state-machine to communicate with the underlying consensus engine (e.g. Tendermint). +- A [Router](#routing), to route [messages](./tx-msgs.md) and [queries](./querier.md) to the appropriate [module](./modules.md). +- Different [states and modes](#states-and-modes), as the state-machine can be in different modes depending on the ABCI message it processes. -### DeliverTx +The goal of `baseapp` is to provide a boilerplate SDK application that developers can easily extend to build their own custom application. Usually, developers will create a custom type for their application, like so: -During the execution of `DeliverTx`, the AnteHandler and Handler is executed. +```go +type app struct { + *bam.BaseApp // reference to baseapp + cdc *codec.Codec -The transaction execution during `DeliverTx` operates in a similar fashion to -`CheckTx`. However, state transitions that occur during the AnteHandler are -persisted even when the following Handler processing logic fails. + // list of application store keys -It is possible that a malicious proposer may include a transaction in a block -that fails the AnteHandler. In this case, all state transitions for the -offending transaction are discarded. + // list of application keepers + // module manager +} +``` -## Other ABCI Messages +Extending the application with `baseapp` gives the former access to all of `baseapp`'s methods. This allows developers to compose their custom application with the modules they want, while not having to concern themselves with the hard work of implementing the ABCI, the routing and state management logic. -Besides `CheckTx` and `DeliverTx`, BaseApp handles the following ABCI messages. +## Type Definition -### Info -TODO complete description +The [`baseapp` type](https://github.com/cosmos/cosmos-sdk/blob/master/baseapp/baseapp.go#L45-L91) holds many important parameters for any Cosmos SDK based application. Let us go through the most important components: -### SetOption -TODO complete description +- A [`CommitMultiStore`](./store.md#commit-multi-store). This is the main store of the application, which holds the canonical state that is committed at the [end of each block](#endblock). This store is **not** cached, meaning it is not used to update the application's intermediate (un-committed) states. The `CommitMultiStore` is a multi-store, meaning a store of stores. Each module of the application uses one or multiple `KVStores` in the multi-store to persist their subset of the state. +- A [database](./store.md#database) `db`, which is used by the `CommitMultiStore` to handle data storage. +- -### Query -TODO complete description +## States and Modes -### InitChain -TODO complete description - -During chain initialization InitChain runs the initialization logic directly on -the CommitMultiStore. The deliver and check states are initialized with the -ChainID. - -Note that we do not commit after InitChain, so BeginBlock for block 1 starts -from the deliver state as initialized by InitChain. - -### BeginBlock -TODO complete description +## Routing -### EndBlock -TODO complete description +## ABCI -### Commit -TODO complete description +## ABCI - CheckTx +## ABCI - DeliverTx -## Gas Management +## ABCI - Commit -### Gas: InitChain +## Other ABCI Messages -During InitChain, the block gas meter is initialized with an infinite amount of -gas to run any genesis transactions. +### Info -Additionally, the InitChain request message includes ConsensusParams as -declared in the genesis.json file. +### SetOption -### Gas: BeginBlock +### Query -The block gas meter is reset during BeginBlock for the deliver state. If no -maximum block gas is set within baseapp then an infinite gas meter is set, -otherwise a gas meter with `ConsensusParam.BlockSize.MaxGas` is initialized. +### InitChain -### Gas: DeliverTx +### BeginBlock -Before the transaction logic is run, the `BlockGasMeter` is first checked to -see if any gas remains. If no gas remains, then `DeliverTx` immediately returns -an error. +### EndBlock -After the transaction has been processed, the used gas (up to the transaction -gas limit) is deducted from the BlockGasMeter. If the remaining gas exceeds the -meter's limits, then DeliverTx returns an error and the transaction is not -committed. +## Gas \ No newline at end of file From 24570feb242331423084a37faf8ff02c27d15391 Mon Sep 17 00:00:00 2001 From: gamarin Date: Thu, 27 Jun 2019 11:47:33 +0200 Subject: [PATCH 041/196] baseapp work --- docs/concepts/accounts-fees.md | 11 +++++ docs/concepts/app-anatomy.md | 4 +- docs/concepts/fees-signature.md | 7 --- docs/core/baseapp_old.md | 85 ++++++++++++++++++++++++++++----- 4 files changed, 85 insertions(+), 22 deletions(-) create mode 100644 docs/concepts/accounts-fees.md delete mode 100644 docs/concepts/fees-signature.md diff --git a/docs/concepts/accounts-fees.md b/docs/concepts/accounts-fees.md new file mode 100644 index 000000000000..9f03e0eb033d --- /dev/null +++ b/docs/concepts/accounts-fees.md @@ -0,0 +1,11 @@ +# Accounts, Fees and Signatures + +## Accounts + +## AnteHandler + +## Signatures + +## Fees + +## Gas \ No newline at end of file diff --git a/docs/concepts/app-anatomy.md b/docs/concepts/app-anatomy.md index 78d7b1eda675..177a84f19c7e 100644 --- a/docs/concepts/app-anatomy.md +++ b/docs/concepts/app-anatomy.md @@ -116,7 +116,7 @@ The SDK offers developers the possibility to implement automatic execution of co In general, the `BeginBlocker` and `EndBlocker` functions are mostly composed of the `BeginBlock` and `EndBlock` functions of each of the application's modules. This is done by calling the `BeginBlock` and `EndBlock` functions of the module manager, which in turn will call the `BeginBLock` and `EndBlock` functions of each of the modules it contains. Note that the order in which the modules' `BegingBlock` and `EndBlock` functions must be called has to be set in the module manager using the `SetOrderBeginBlock` and `SetOrderEndBlock` methods respectively. This is done in the [application's constructor](#application-constructor), and the `SetOrderBeginBlock` and `SetOrderEndBlock` methods have to be called before the `SetBeginBlocker` and `SetEndBlocker` functions. -As a sidenote, it is important to remember that application-specific blockchains are deterministic. Developers must be careful not to introduce non-determinism in `BeginBlocker` or `EndBlocker`, and must also be careful not to make them too computationally expensive, as [gas](./fees-signature.md/gas) does not constrain the cost of `BeginBlocker` and `EndBlocker` execution. +As a sidenote, it is important to remember that application-specific blockchains are deterministic. Developers must be careful not to introduce non-determinism in `BeginBlocker` or `EndBlocker`, and must also be careful not to make them too computationally expensive, as [gas](./accounts-fees.md/gas) does not constrain the cost of `BeginBlocker` and `EndBlocker` execution. You can see an example of `BeginBlocker` and `EndBlocker` functions [here](https://github.com/cosmos/gaia/blob/master/app/app.go#L224-L232). @@ -154,7 +154,7 @@ To learn more about the application module interface, [click here](./modules.md# A message is a custom type defined by each module that implements the [`message`](https://github.com/cosmos/cosmos-sdk/blob/master/types/tx_msg.go#L8-L29) interface. Each `transaction` contains one or multiple `messages`. When a valid block of transactions is received by the full-node, Tendermint relays each one to the application via [`DeliverTx`](https://tendermint.com/docs/app-dev/abci-spec.html#delivertx). Then, the application handles the transaction: 1. Upon receiving the transaction, the application first unmarshalls it from `[]bytes`. -2. Then, it verifies a few things about the transaction like [fee payment and signatures](#fees-signature.md) before extracting the message(s) contained in the transaction. +2. Then, it verifies a few things about the transaction like [fee payment and signatures](#accounts-fees.md) before extracting the message(s) contained in the transaction. 3. With the [`Type()`](https://github.com/cosmos/cosmos-sdk/blob/master/types/tx_msg.go#L16) method, `baseapp` is able to know which modules defines the message. It is then able to route it to the appropriate module's [handler](#handler) in order for the message to be processed. 4. If the message is successfully processed, the state is updated. diff --git a/docs/concepts/fees-signature.md b/docs/concepts/fees-signature.md deleted file mode 100644 index 36982a97b5d8..000000000000 --- a/docs/concepts/fees-signature.md +++ /dev/null @@ -1,7 +0,0 @@ -# Fees and Signatures - -## Signatures - -## Fees - -## Gas \ No newline at end of file diff --git a/docs/core/baseapp_old.md b/docs/core/baseapp_old.md index 855b03cf1b55..c239272fcba3 100644 --- a/docs/core/baseapp_old.md +++ b/docs/core/baseapp_old.md @@ -11,7 +11,7 @@ This document describes `baseapp`, the abstraction that implements most of the c - [Introduction](#introduction) - [Type Definition](#type-definition) -- [States and Modes](#states-and-modes) +- [States](#states) - [Routing](#routing) - [ABCI](#abci) - [CheckTx](#abci-checktx) @@ -33,7 +33,7 @@ This document describes `baseapp`, the abstraction that implements most of the c - The [Application-Blockchain Interface](#abci), for the state-machine to communicate with the underlying consensus engine (e.g. Tendermint). - A [Router](#routing), to route [messages](./tx-msgs.md) and [queries](./querier.md) to the appropriate [module](./modules.md). -- Different [states and modes](#states-and-modes), as the state-machine can be in different modes depending on the ABCI message it processes. +- Different [states](#states), as the state-machine can have different parallel states updated based on the ABCI message received. The goal of `baseapp` is to provide a boilerplate SDK application that developers can easily extend to build their own custom application. Usually, developers will create a custom type for their application, like so: @@ -54,26 +54,87 @@ Extending the application with `baseapp` gives the former access to all of `base ## Type Definition -The [`baseapp` type](https://github.com/cosmos/cosmos-sdk/blob/master/baseapp/baseapp.go#L45-L91) holds many important parameters for any Cosmos SDK based application. Let us go through the most important components: +The [`baseapp` type](https://github.com/cosmos/cosmos-sdk/blob/master/baseapp/baseapp.go#L45-L91) holds many important parameters for any Cosmos SDK based application. Let us go through the most important components. -- A [`CommitMultiStore`](./store.md#commit-multi-store). This is the main store of the application, which holds the canonical state that is committed at the [end of each block](#endblock). This store is **not** cached, meaning it is not used to update the application's intermediate (un-committed) states. The `CommitMultiStore` is a multi-store, meaning a store of stores. Each module of the application uses one or multiple `KVStores` in the multi-store to persist their subset of the state. +*Note: Not all parameters are described, only the most important ones. Refer to the [type definition](https://github.com/cosmos/cosmos-sdk/blob/master/baseapp/baseapp.go#L45-L91) for the full list* + +First, the important parameters that are initialized during the initialization of the application: + +- A [`CommitMultiStore`](./store.md#commit-multi-store). This is the main store of the application, which holds the canonical state that is committed at the [end of each block](#commit). This store is **not** cached, meaning it is not used to update the application's intermediate (un-committed) states. The `CommitMultiStore` is a multi-store, meaning a store of stores. Each module of the application uses one or multiple `KVStores` in the multi-store to persist their subset of the state. - A [database](./store.md#database) `db`, which is used by the `CommitMultiStore` to handle data storage. -- +- A [router](#messages). The `router` facilitates the routing of [messages](./tx-msgs.md) to the appropriate module for it to be processed. +- A [query router](#queries). The `query router` facilitates the routing of [queries](./querier.md) to the appropriate module for it to be processed. +- A [`txDecoder`](https://godoc.org/github.com/cosmos/cosmos-sdk/types#TxDecoder), used to decode transaction `[]byte` relayed by the underlying Tendermint engine. +- A [`baseKey`], to access the [main store](./store.md#main-store) in the `CommitMultiStore`. The main store is used to persist data related to the core of the application, like consensus parameters. +- A [`anteHandler`](./accounts-fees.md#antehandler), to handle signature verification and fee paiement when a transaction is received. +- An [`initChainer`](./app-anatomy.md#initchainer), [`beginBlocker` and `endBlocker`](./app-anatomy.md#beginblocker-and-endblocker), which are the functions executed when the application received the [InitChain], [BeginBlock] and [EndBlock] messages from the underlying Tendermint engine. + +Then, parameters used to define [volatile states](#volatile-states) (i.e. cached states): + +- `checkState`: This state is updated during [`CheckTx`](#checktx), and reset on [`Commit`](#commit). +- `deliverState`: This state is updated during [`DeliverTx`](#delivertx), and reset on [`Commit`](#commit). + +Finally, a few more important parameterd: + +- `voteInfos`: This parameter carries the list of validators whose precommit is missing, either because they did not vote or because the proposer did not include their vote. This information is carried by the [context](#context) and can be used by the application for various things like punishing absent validators. +- `minGasPrices`: This parameter defines the minimum [gas prices](./accounts-fees.md#gas) accepted by the node. This is a local parameter, meaning each full-node can set a different `minGasPrices`. It is run by the [`anteHandler`](./accounts-fees.md#antehandler) during `CheckTx`, mainly as a spam protection mechanism. The transaction enters the [mempool](https://tendermint.com/docs/tendermint-core/mempool.html#transaction-ordering) only if the gas price of the transaction is superior to one of the minimum gas price in `minGasPrices` (i.e. if `minGasPrices == 1uatom, 1upho`, the `gas-price` of the transaction must be superior to `1uatom` OR `1upho`). +- `appVersion`: Version of the application. It is set in the [application's constructor function](./baseapp.md#constructor-function). + +## States + +`baseapp` handles various parallel states for different purposes. There is the [main state](#main-state), which is the canonical state of the application, and volatile states like [`checkState`](#checkState) and [`deliverState`](#deliverstate), which are used to handle temporary states inbetween updates of the main state. + +### Main State + +The main state is the canonical state of the application. It is initialized on [`InitChain`](#initchain and updated on [`Commit`](#abci-commit) at the end of each block. + +``` ++--------+ +--------+ +| | | | +| S +----------------------------> | S' | +| | For each T in B: apply(T) | | ++--------+ +--------+ +``` + +The main state is held by `baseapp` in a structure called the [`CommitMultiStore`](./store.md#commit-multi-store). This multi-store is used by developers to instantiate all the stores they need for each of their application's modules. -## States and Modes +### Volatile States + +Volatile - or cached - states are used in between [`Commit`s](#commit) to manage temporary states. They are reset to the latest version of the main state after it is committed. There are two main volatile states: + +- `checkState`: This cached state is initialized during [`InitChain`](#initchain), updated during [`CheckTx`](#abci-checktx) when an unconfirmed transaction is received, and reset to the [main state](#main-state) on [`Commit`](#abci-commit). +- `deliverState`: This cached state is initialized during [`BeginBlock`](#beginblock), updated during [`DeliverTx`](#abci-delivertx) when a transaction included in a block is processed, and reset to the [main state](#main-state) on [`Commit`](#abci-commit). ## Routing -## ABCI +When messages and queries are received by the application, they must be routed to the appropriate module in order to be processed. Routing is done via `baseapp`, which holds a `router` for messages, and a `query router` for queries. + +### Message Routing + +Messages need to be routed after they are extracted from transactions, which are sent from the underlying Tendermint engine via the [`CheckTx`](#checktx) and [`DeliverTx`](#delivertx) ABCI messages. To do so, `baseapp` holds a [`router`](https://github.com/cosmos/cosmos-sdk/blob/master/baseapp/router.go) which maps `paths` (`string`) to the appropriate module [`handler`](./handler.md). Usually, the `path` is the name of the module. + +The application's `router` is initilalized with all the routes using the application's [module manager](./modules.md#module-manager), which itself is initialized with all the application's modules in the application's [constructor](./app-anatomy.md#app-constructor). + +### Query Routing + +Similar to messages, queries need to be routed to the appropriate module's [querier](./querier.md). To do so, `baseapp` holds a [`query router`](https://github.com/cosmos/cosmos-sdk/blob/master/baseapp/queryrouter.go), which maps `paths` (`string`) to the appropriate module [`querier`](./querier.md). Usually, the `path` is the name of the module. -## ABCI - CheckTx +Just like the `router`, the `query router` is initilalized with all the query routes using the application's [module manager](./modules.md#module-manager), which itself is initialized with all the application's modules in the application's [constructor](./app-anatomy.md#app-constructor). -## ABCI - DeliverTx +## Main ABCI Messages -## ABCI - Commit + + +### CheckTx + +### DeliverTx + +## RunTx and RunMsg ## Other ABCI Messages +### Commit + ### Info ### SetOption @@ -84,6 +145,4 @@ The [`baseapp` type](https://github.com/cosmos/cosmos-sdk/blob/master/baseapp/ba ### BeginBlock -### EndBlock - -## Gas \ No newline at end of file +### EndBlock \ No newline at end of file From 2c412ec7251bd1e774dcb63b73b197c6c4bc3036 Mon Sep 17 00:00:00 2001 From: gamarin Date: Thu, 27 Jun 2019 11:59:31 +0200 Subject: [PATCH 042/196] reorg --- docs/{concepts => basics}/accounts-fees.md | 0 docs/basics/app-anatomy.md | 63 ++--- docs/building-modules/module-interfaces.md | 280 ++++++++++++++++++++- docs/concepts/app-anatomy.md | 4 +- docs/concepts/baseapp_old.md | 128 ---------- docs/concepts/genesis.md | 3 - docs/concepts/store.md | 8 - docs/core/baseapp_old.md | 148 ----------- docs/{concepts => modules}/handler.md | 0 docs/{concepts => modules}/invariants.md | 0 docs/{concepts => modules}/keeper.md | 0 docs/modules/module-interfaces.md | 5 + docs/{concepts => modules}/modules.md | 0 docs/{concepts => modules}/querier.md | 0 14 files changed, 319 insertions(+), 320 deletions(-) rename docs/{concepts => basics}/accounts-fees.md (100%) delete mode 100644 docs/concepts/baseapp_old.md delete mode 100644 docs/concepts/genesis.md delete mode 100644 docs/concepts/store.md delete mode 100644 docs/core/baseapp_old.md rename docs/{concepts => modules}/handler.md (100%) rename docs/{concepts => modules}/invariants.md (100%) rename docs/{concepts => modules}/keeper.md (100%) create mode 100644 docs/modules/module-interfaces.md rename docs/{concepts => modules}/modules.md (100%) rename docs/{concepts => modules}/querier.md (100%) diff --git a/docs/concepts/accounts-fees.md b/docs/basics/accounts-fees.md similarity index 100% rename from docs/concepts/accounts-fees.md rename to docs/basics/accounts-fees.md diff --git a/docs/basics/app-anatomy.md b/docs/basics/app-anatomy.md index 15e1c9fc1e22..bca2c0c2774f 100644 --- a/docs/basics/app-anatomy.md +++ b/docs/basics/app-anatomy.md @@ -57,7 +57,7 @@ The blockchain full-node presents itself as a binary, generally suffixed by `-d` To learn more about the `main.go` function, [click here](../core/node.md#main-function). -Once the main binary is built, the node can be started by running the `start` command. The core logic behind the `start` command is implemented in the SDK itself in the [`/server/start.go`](https://github.com/cosmos/cosmos-sdk/blob/master/server/start.go) file. The main [`start` command function](https://github.com/cosmos/cosmos-sdk/blob/master/server/start.go#L31) takes a [`context`](https://godoc.org/github.com/cosmos/cosmos-sdk/client/context) and [`appCreator`](<#constructor-function-(`appCreator`)>) as arguments. The `appCreator` is a constructor function for the SDK application, and is used in the starting process of the full-node. +Once the main binary is built, the node can be started by running the `start` command. The core logic behind the `start` command is implemented in the SDK itself in the [`/server/start.go`](https://github.com/cosmos/cosmos-sdk/blob/master/server/start.go) file. The main [`start` command function](https://github.com/cosmos/cosmos-sdk/blob/master/server/start.go#L31) takes a [`context`](https://godoc.org/github.com/cosmos/cosmos-sdk/client/context) and [`appCreator`](#constructor-function-(`appCreator`)) as arguments. The `appCreator` is a constructor function for the SDK application, and is used in the starting process of the full-node. The `start` command function primarily does three things: @@ -73,11 +73,11 @@ In general, the core of the state-machine is defined in a file called `app.go`. The first thing defined in `app.go` is the `type` of the application. It is generally comprised of the following parts: -- **A reference to [`baseapp`](../core/baseapp.md).** The custom application defined in `app.go` is an extension of the `baseapp` type. `baseapp` implements most of the core logic for the application, including all the [ABCI methods](https://tendermint.com/docs/spec/abci/abci.html#overview) and the routing logic. When a transaction is relayed by Tendermint to the application, the latter uses `baseapp`'s methods to route them to the appropriate module. -- **A list of store keys**. The [store](../core/store.md), which contains the entire state, is implemented as a multistore (i.e. a store of stores) in the Cosmos SDK. Each module uses one or multiple stores in the multistore to persist their part of the state. These stores can be accessed with specific keys that are declared in the `app` type. These keys, along with the `keepers`, are at the heart of the [object-capabilities model](../intro/ocap.md) of the Cosmos SDK. -- **A list of module's `keepers`.** Each module defines an abstraction called [`keeper`](../building-modules/keeper.md), which handles reads and writes for this module's store(s). The `keeper`'s methods of one module can be called from other modules (if authorized), which is why they are declared in the application's type and exported as interfaces to other modules so that they are only allowed to access the authorized functions. -- **A reference to a [`codec`](../core/encoding.md).** The Cosmos SDK gives developers the freedom to choose the encoding framework for their application. The application's `codec` is used to serialize and deserialize data structures in order to store them, as stores can only persist `[]bytes`. The `codec` must be deterministic. The default codec is [amino](./amino.md). -- **A reference to a [module manager](../building-modules/module-manager.md#manager)** and a [basic module manager](../building-modules/module-manager.md#basicmanager). The module manager is an object that contains a list of the application's module. It facilitates operations related to these modules, like registering [`routes`](./baseapp.md#routing), [query routes](#./baseapp.md#query-routing) or setting the order of execution between modules for various functions like [`InitChainer`](#initchainer), [`BeginBlocker` and `EndBlocker`](#beginblocker-and-endblocker). +- **A reference to [`baseapp`](./baseapp.md).** The custom application defined in `app.go` is an extension of the `baseapp` type. `baseapp` implements most of the core logic for the application, including all the [ABCI methods](https://tendermint.com/docs/spec/abci/abci.html#overview) and the routing logic. When a transaction is relayed by Tendermint to the application, the latter uses `baseapp`'s methods to route them to the appropriate module. +- **A list of store keys**. The [store](./store.md), which contains the entire state, is implemented as a multistore (i.e. a store of stores) in the Cosmos SDK. Each module uses one or multiple stores in the multistore to persist their part of the state. These stores can be accessed with specific keys that are declared in the `app` type. These keys, along with the `keepers`, are at the heart of the [object-capabilities model](../intro/ocap.md) of the Cosmos SDK. +- **A list of module's `keepers`.** Each module defines an abstraction called `keeper`, which handles reads and writes for this module's store(s). The `keeper`'s methods of one module can be called from other modules (if authorized), which is why they are declared in the application's type and exported as interfaces to other modules so that they are only allowed to access the authorized functions. +- **A reference to a `codec`.** The Cosmos SDK gives developers the freedom to choose the encoding framework for their application. The application's `codec` is used to serialize and deserialize data structures in order to store them, as stores can only persist `[]bytes`. The `codec` must be deterministic. The default codec is [amino](./amino.md). +- **A reference to a [module manager](./modules.md#module-manager)**. The module manager is an object that contains a list of the application's module. It facilitates operations related to these modules, like registering [`routes`](./baseapp.md#routing), [query routes](#./baseapp.md#query-routing) or setting the order of execution between modules for various functions like [`InitChainer`](#initchainer), [`BeginBlocker` and `EndBlocker`](#beginblocker-and-endblocker). You can see an example of application type definition [here](https://github.com/cosmos/gaia/blob/master/app/app.go#L73-L107). @@ -87,17 +87,17 @@ This function constructs a new application of the type defined above. It is call - Instantiate a new [`codec`](../core/encoding.md) and initialize the `codec` of each of the application's module using the [basic manager](../building-modules/module-manager.md#basicmanager) - Instantiate a new application with a reference to a `baseapp` instance, a codec and all the appropriate store keys. -- Instantiate all the [`keeper`s](#keeper) defined in the application's `type` using the `NewKeeper` function of each of the application's modules. Note that `keepers` must be instantiated in the correct order, as the `NewKeeper` of one module might require a reference to another module's `keeper`. -- Instantiate the application's [module manager](../building-modules/module-manager.md#manager) with the [`AppModule`](#application-module-interface) object of each of the application's modules. -- With the module manager, initialize the application's [`routes`](../core/baseapp.md#routing) and [query routes](../core/baseapp.md#query-routing). When a transaction is relayed to the application by Tendermint via the ABCI, it is routed to the appropriate module's [`handler`](#handler) using the routes defined here. Likewise, when a query is received by the application, it is routed to the appropriate module's [`querier`](#querier) using the query routes defined here. -- With the module manager, register the [application's modules' invariants](./invariants.md). Invariants are variables (e.g. total supply of a token) that are evaluated at the end of each block. The process of checking invariants is done via a special module called the [`InvariantsRegistry`](../building-modules/invariants.md#invariant-registry). The value of the invariant should be equal to a predicted value defined in the module. Should the value be different than the predicted one, special logic defined in the invariant registry will be triggered (usually the chain is halted). This is useful to make sure no critical bug goes unnoticed and produces long-lasting effects that would be hard to fix. +- Instantiate all the [`keeper`s](#keeper) defined in the application's `type` using the `NewKeeper` function of each of the application's modules. Note that `keepers` must be instantiated in the correct order, as the `NewKeeper` of one module might require a reference to another module's `keeper`. +- Instantiate the application's [module manager](./module-manager.md) with the [`AppModule`](#application-module-interface) object of each of the application's modules. +- With the module manager, initialize the application's [`routes`](./baseapp.md#routing) and [query routes](./baseapp.md#query-routing). When a transaction is relayed to the application by Tendermint via the ABCI, it is routed to the appropriate module's [`handler`](#handler) using the routes defined here. Likewise, when a query is received by the application, it is routed to the appropriate module's [`querier`](#querier) using the query routes defined here. +- With the module manager, register the [application's modules' invariants](./invariants.md). Invariants are variables (e.g. total supply of a token) that are evaluated at the end of each block. The process of checking invariants is done via a special module called the [`InvariantsRegistry`](./invariants.md#invariant-registry). The value of the invariant should be equal to a predicted value defined in the module. Should the value be different than the predicted one, special logic defined in the invariant registry will be triggered (usually the chain is halted). This is useful to make sure no critical bug goes unnoticed and produces long-lasting effects that would be hard to fix. - With the module manager, set the order of execution between the `InitGenesis`, `BegingBlocker` and `EndBlocker` functions of each of the [application's modules](#application-module-interface). Note that not all modules implement these functions. - Set the remainer of application's parameters: + [`InitChainer`](#initchainer): used to initialize the application when it is first started. + [`BeginBlocker`, `EndBlocker`](#beginblocker-and-endlbocker): called at the beginning and the end of every block). - + [`anteHandler`](../core/baseapp.md#antehandler): used to handle fees and signature verification. -- Mount the stores. -- Return the application. + + [`anteHandler`](#baseapp.md#antehandler): used to handle fees and signature verification. +- Mount the stores. +- Return the application. Note that this function only creates an instance of the app, while the actual state is either carried over from the `~/.appd/data` folder if the node is restarted, or generated from the genesis file if the node is started for the first time. @@ -105,7 +105,7 @@ You can see an example of application constructor [here](https://github.com/cosm ### InitChainer -The `InitChainer` is a function that initializes the state of the application from a [genesis file](../core/genesis.md) (i.e. token balances of genesis accounts). It is called when the application receives the `InitChain` message from the Tendermint engine, which happens when the node is started at `appBlockHeight == 0` (i.e. on genesis). The application must set the `InitChainer` in its constructor via the [`SetInitChainer`](https://godoc.org/github.com/cosmos/cosmos-sdk/baseapp#BaseApp.SetInitChainer) method. +The `InitChainer` is a function that initializes the state of the application from a [genesis file](./genesis.md) (i.e. token balances of genesis accounts). It is called when the application receives the `InitChain` message from the Tendermint engine, which happens when the node is started at `appBlockHeight == 0` (i.e. on genesis). The application must set the `InitChainer` in its constructor via the [`SetInitChainer`](https://godoc.org/github.com/cosmos/cosmos-sdk/baseapp#BaseApp.SetInitChainer) method. In general, the `InitChainer` is mostly composed of the `InitGenesis` function of each of the application's modules. This is done by calling the `InitGenesis` function of the module manager, which in turn will call the `InitGenesis` function of each of the modules it contains. Note that the order in which the modules' `InitGenesis` functions must be called has to be set in the module manager using the `SetOrderInitGenesis` method. This is done in the [application's constructor](#application-constructor), and the `SetOrderInitGenesis` has to be called before the `SetInitChainer`. @@ -117,13 +117,13 @@ The SDK offers developers the possibility to implement automatic execution of co In general, the `BeginBlocker` and `EndBlocker` functions are mostly composed of the `BeginBlock` and `EndBlock` functions of each of the application's modules. This is done by calling the `BeginBlock` and `EndBlock` functions of the module manager, which in turn will call the `BeginBLock` and `EndBlock` functions of each of the modules it contains. Note that the order in which the modules' `BegingBlock` and `EndBlock` functions must be called has to be set in the module manager using the `SetOrderBeginBlock` and `SetOrderEndBlock` methods respectively. This is done in the [application's constructor](#application-constructor), and the `SetOrderBeginBlock` and `SetOrderEndBlock` methods have to be called before the `SetBeginBlocker` and `SetEndBlocker` functions. -As a sidenote, it is important to remember that application-specific blockchains are deterministic. Developers must be careful not to introduce non-determinism in `BeginBlocker` or `EndBlocker`, and must also be careful not to make them too computationally expensive, as [gas](./accounts-fees-gas.md/gas) does not constrain the cost of `BeginBlocker` and `EndBlocker` execution. +As a sidenote, it is important to remember that application-specific blockchains are deterministic. Developers must be careful not to introduce non-determinism in `BeginBlocker` or `EndBlocker`, and must also be careful not to make them too computationally expensive, as [gas](./accounts-fees.md/gas) does not constrain the cost of `BeginBlocker` and `EndBlocker` execution. You can see an example of `BeginBlocker` and `EndBlocker` functions [here](https://github.com/cosmos/gaia/blob/master/app/app.go#L224-L232). ### Register Codec -The `MakeCodec` function is the last important function of the `app.go` file. The goal of this function is to instantiate a codec `cdc` (e.g. amino) initialize the codec of the SDK and each of the application's modules using the `RegisterCodec` function. +The `MakeCodec` function is the last important function of the `app.go` file. The goal of this function is to instantiate a codec `cdc` (e.g. [amino](./amino.md)) initiliaze the codec of the SDK and each of the application's modules using the `RegisterCodec` function. To register the application's modules, the `MakeCodec` function calls `RegisterCodec` on `ModuleBasics`. `ModuleBasics` is a [basic manager](../building-modules/module-manager.md#basicmanager) which lists all of the application's modules. It is instanciated in the `init()` function, and only serves to easily register non-dependant elements of application's modules (such as codec). To learn more about the basic module manager, click [here](../building-modules/module-manager.md#basicmanager). @@ -131,15 +131,22 @@ You can see an example of a `MakeCodec` [here](https://github.com/cosmos/gaia/bl ## Modules -Modules are the heart and soul of an SDK application. They can be considered as state-machines within the state-machine. When a transaction is relayed from the underlying Tendermint engine via the ABCI to the application, it is routed by [`baseapp`](../core/baseapp.md) to the appropriate module in order to be processed. This paradigm enables developers to easily build complex state-machines, as most of the modules they need often already exist. For developers, most of the work involved in building an SDK application revolves around building custom modules required by their application that do not exist, and integrating them with modules that do already exist into one coherent application. In the application directory, the standard practice is to store modules in the `x/` folder (not to be confused with the SDK's `x/` folder, which contains already-built modules). +Modules are the heart and soul of an SDK application. They can be considered as state-machines within the state-machine. When a transaction is relayed from the underlying Tendermint engine via the ABCI to the application, it is routed by `baseapp` to the appropriate module in order to be processed. This paradigm enables developers to easily build complex state-machines, as most of the modules they need often already exist. For developers, most of the work involved in building an SDK application revolves around building custom modules required by their application that do not exist, and integrating them with modules that do already exist into one coherent application. In the application directory, the standard practice is to store modules in the `x/` folder (not to be confused with the SDK's `x/` folder, which contains already-built modules). To learn more about modules, [click here](./modules.md) ### Application Module Interface -Modules implement two interfaces defined in the Cosmos SDK, [`AppModuleBasic`](../building-modules/module-manager.md#appmodulebasic) and [`AppModule`](../building-modules/module-manager.md#appmodule). The former implements basic non-dependant elements of the module, such as the `codec`, while the latter handles the bulk of the module methods (including methods that require references to other modules' `keeper`s). Both the `AppModule` and `AppModuleBasic` types are defined in a file called `./module.go`. +Modules implement two interfaces defined in the Cosmos SDK, [`AppModuleBasic`](https://github.com/cosmos/cosmos-sdk/blob/master/types/module/module.go#L44-L57) and [`AppModule`](https://github.com/cosmos/cosmos-sdk/blob/master/types/module/module.go#L44-L57). The former implements basic non-dependant elements of the module, such as the `codec`, while the latter handles the bulk of the module methods (including methods that require references to other modules' `keeper`s). Both the `AppModule` and `AppModuleBasic` types are defined in a file called `./module.go`. -`AppModule` exposes a collection of useful methods on the module that facilitates the composition of modules into a coherent application. These methods are are called from the `module manager`(../building-modules/module-manager.md#manager), which manages the application's collection of modules. +`AppModule` exposes a collection of useful methods on the module that facilitates the composition of modules into a coherent application. Important methods include: + +- `Route()` and `QueryRoute()`: These methods the name of the route and querier route for the module, for [messages](#message-types) to be routed to the module's [`handler`](#handler) and queries to be routes to the module's [`querier`](#querier). +- `NewHandler()` and `NewQuerierHandler()`: These methods return a `handler` and `querierHandler` respectively, in order to process a message or a query once they are routed. +- `BeginBlock()`, `EndBlock()` and `InitGenesis()`: These methods are executed respectively at the beginning of each block, at the end of each block and at the start of the chain. They implement special logic the module requires to be triggered during those events. For example, the `EndBlock` function is frequently used by modules where voting occurs to tally the result of the votes. +- `RegisterInvariants()`: This method registers the [invariants](./invariants.md) for the module. Invariants are checked at the end of every block to make sure no unpredicted behaviour is occuring. + +`AppModule`'s methods are called from the `module manager`(./modules.md#module-manager), which manages the application's collection of modules. To learn more about the application module interface, [click here](../building-modules/module-manager.md#application-module-interfaces). @@ -148,9 +155,9 @@ To learn more about the application module interface, [click here](../building-m A message is a custom type defined by each module that implements the [`message`](../building-modules/messages-and-queries.md#messages) interface. Each [`transaction`](../core/transaction.md) contains one or multiple `messages`. When a valid block of transactions is received by the full-node, Tendermint relays each one to the application via [`DeliverTx`](https://tendermint.com/docs/app-dev/abci-spec.html#delivertx). Then, the application handles the transaction: 1. Upon receiving the transaction, the application first unmarshalls it from `[]bytes`. -2. Then, it verifies a few things about the transaction like [fee payment and signatures](#accounts-fees-gas.md) before extracting the message(s) contained in the transaction. -3. With the [`Type()`](https://github.com/cosmos/cosmos-sdk/blob/master/types/tx_msg.go#L16) method, `baseapp` is able to know which modules defines the message. It is then able to route it to the appropriate module's [handler](#handler) in order for the message to be processed. -4. If the message is successfully processed, the state is updated. +2. Then, it verifies a few things about the transaction like [fee payment and signatures](#accounts-fees.md) before extracting the message(s) contained in the transaction. +3. With the [`Type()`](https://github.com/cosmos/cosmos-sdk/blob/master/types/tx_msg.go#L16) method, `baseapp` is able to know which modules defines the message. It is then able to route it to the appropriate module's [handler](#handler) in order for the message to be processed. +4. If the message is successfully processed, the state is updated. For a more detailed look at a transaction lifecycle, click [here](./tx-lifecycle.md). @@ -164,8 +171,8 @@ The [`handler`](../building-modules/handler.md) refers to the part of the module The handler of a module is generally defined in a file called `handler.go` and consists of: -- A **switch function** `NewHandler` to route the message to the appropriate handler function. This function returns a `handler` function, and is registered in the [`AppModule`](#application-module-interface) to be used in the application's module manager to initialize the [application's router](../core/baseapp.md#routing). See an example of such a switch [here](https://github.com/cosmos/sdk-application-tutorial/blob/master/x/nameservice/handler.go#L10-L22). -- **One handler function for each message type defined by the module**. Developers write the message processing logic in these functions. This generally involves doing stateful checks to ensure the message is valid and calling [`keeper`](#keeper)'s methods to update the state. +- A **switch function** `NewHandler` to route the message to the appropriate handler function. This function returns a `handler` function, and is registered in the [`AppModule`](#application-module-interface) to be used in the application's module manager to initialize the [application's router](./baseapp.md#routing). See an example of such a switch [here](https://github.com/cosmos/sdk-application-tutorial/blob/master/x/nameservice/handler.go#L10-L22). +- **One handler function for each message type defined by the module**. Developers write the message processing logic in these functions. This generally involves doing stateful checks to ensure the message is valid and calling [`keeper`](#keeper)'s methods to update the state. Handler functions return a result of type [`sdk.Result`](https://github.com/cosmos/cosmos-sdk/blob/master/types/result.go#L14-L37), which informs the application on whether the message was successfully processed. @@ -189,9 +196,9 @@ The rest of the file defines the `keeper`'s methods, primarily getters and sette To learn more about `keepers`, [click here](../building-modules/keeper.md). -### Querier +### Querier -[`Queriers`](../building-modules/querier.md) are very similar to `handlers`, except they serve user queries to the state as opposed to processing transactions. A [query](../building-modules/messages-and-queries.md#queries) is initiated from an [interface](#interfaces) by an end-user who provides a `queryRoute` and some `data`. The query is then routed to the correct application's `querier` by `baseapp`'s [`handleQueryCustom`](https://github.com/cosmos/cosmos-sdk/blob/master/baseapp/baseapp.go#L519-L556) method using `queryRoute`. +`Queriers` are very similar to `handlers`, except they serve user queries to the state as opposed to processing transactions. A query is initiated from an [interface](#intefaces) by an end-user who provides a `queryRoute` and some `data`. The query is then routed to the correct application's `querier` by `baseapp`'s [`handleQueryCustom`](https://github.com/cosmos/cosmos-sdk/blob/master/baseapp/baseapp.go#L519-L556) method using `queryRoute`. The `Querier` of a module is defined in a file called `querier.go`, and consists of: @@ -232,9 +239,9 @@ Interfaces let end-users interact with full-node clients. This means querying da The main interface is the [Command-Line Interface](../interfaces/cli.md). The CLI of an SDK application is built by aggregating [CLI commands](#cli) defined in each of the modules used by the application. The CLI of an application generally has the `-cli` suffix (e.g. `appcli`), and defined in a file called `cmd/appcli/main.go`. The file contains: - **A `main()` function**, which is executed to build the `appcli` interface client. This function prepares each command and adds them to the `rootCmd` before building them. At the root of `appCli`, the function adds generic commands like `status`, `keys` and `config`, query commands, tx commands and `rest-server`. -- **Query commands** are added by calling the `queryCmd` function, also defined in `appcli/main.go`. This function returns a Cobra command that contains the query commands defined in each of the application's modules (passed as an array of `sdk.ModuleClients` from the `main()` function), as well as some other lower level query commands such as block or validator queries. Query command are called by using the command `appcli query [query]` of the CLI. +- **Query commands** are added by calling the `queryCmd` function, also defined in `appcli/main.go`. This function returns a Cobra command that contains the query commands defined in each of the application's modules (passed as an array of `sdk.ModuleClients` from the `main()` function), as well as some other lower level query commands such as block or validator queries. Query command are called by using the command `appcli query [query]` of the CLI. - **Transaction commands** are added by calling the `txCmd` function. Similar to `queryCmd`, the function returns a Cobra command that contains the tx commands defined in each of the application's modules, as well as lower level tx commands like transaction signing or broadcasting. Tx commands are called by using the command `appcli tx [tx]` of the CLI. -- **A `registerRoutes` function**, which is called from the `main()` function when initializing the [application's light-client daemon (LCD)](../core/node.md#lcd) (i.e. `rest-server`). `registerRoutes` calls the `RegisterRoutes` function of each of the application's module, thereby registering the routes of the module to the lcd's router. The LCD can be started by running the following command `appcli rest-server`. +- **A `registerRoutes` function**, which is called from the `main()` function when initializing the [application's light-client daemon (LCD)](./node.md#lcd) (i.e. `rest-server`). `registerRoutes` calls the `RegisterRoutes` function of each of the application's module, thereby registering the routes of the module to the lcd's router. The LCD can be started by running the following command `appcli rest-server`. See an example of an application's main command-line file [here](https://github.com/cosmos/sdk-application-tutorial/blob/master/cmd/nscli/main.go). diff --git a/docs/building-modules/module-interfaces.md b/docs/building-modules/module-interfaces.md index 744c439c67f2..c3ddea3298aa 100644 --- a/docs/building-modules/module-interfaces.md +++ b/docs/building-modules/module-interfaces.md @@ -1,9 +1,283 @@ # Module Interfaces +## Prerequisites + +* [Building Modules Intro](./intro.md) + +## Synopsis + +This document details how to build CLI and REST interfaces for a module. Examples from various SDK modules will be included. + +- [CLI](#cli) + + [Transaction Commands](#tx-commands) + + [Query Commands](#query-commands) +- [REST](#rest) + + [Request Types](#request-types) + + [Request Handlers](#request-handlers) + + [Register Routes](#register-routes) + ## CLI -### Tx +One of the main interfaces for an application is the [command-line interface](../interfaces/cli.md). This entrypoint created by the application developer will add commands from the application's modules to let end-users create [**messages**](./messages-and-queries.md) and [**queries**](./messages-and-queries.md). The CLI files are typically found in the `./x/moduleName/client/cli` folder. + +### Transaction Commands + +[Transactions](../core/transactions.md) are created by users to wrap messages that trigger state changes when they get included in a valid block. Transaction commands typically have their own `tx.go` file in the module `./x/moduleName/client/cli` folder. The commands are specified in getter functions prefixed with `GetCmd` and include the name of the command. Here is an example from the nameservice tutorial: + +```go +func GetCmdBuyName(cdc *codec.Codec) *cobra.Command { + return &cobra.Command{ + Use: "buy-name [name] [amount]", + Short: "bid for existing name or claim new name", + Args: cobra.ExactArgs(2), + RunE: func(cmd *cobra.Command, args []string) error { + cliCtx := context.NewCLIContext().WithCodec(cdc).WithAccountDecoder(cdc) + + txBldr := authtxb.NewTxBuilderFromCLI().WithTxEncoder(utils.GetTxEncoder(cdc)) + + if err := cliCtx.EnsureAccountExists(); err != nil { + return err + } + + coins, err := sdk.ParseCoins(args[1]) + if err != nil { + return err + } + + msg := nameservice.NewMsgBuyName(args[0], coins, cliCtx.GetFromAddress()) + err = msg.ValidateBasic() + if err != nil { + return err + } + + cliCtx.PrintResponse = true + + return utils.GenerateOrBroadcastMsgs(cliCtx, txBldr, []sdk.Msg{msg}, false) + }, + } +} +``` + +This getter function creates the command for the Buy Name transaction. It does the following: + +- **`codec`**. The getter function takes in an application [`codec`](../core/encoding.md) as an argument and returns a reference to the `cobra.command`. Since a module is intended to be used by any application, the `codec` must be provided. +- **Construct the command:** Read the [Cobra Documentation](https://github.com/spf13/cobra) for details on how to create commands. + + **Use:** Specifies the format of a command-line entry users should type in order to invoke this command. In this case, the user uses `buy-name` as the name of the transaction command and provides the `name` the user wishes to buy and the `amount` the user is willing to pay. + + **Args:** The number of arguments the user provides, in this case exactly two: `name` and `amount`. + + **Short and Long:** A description for the function is provided here. A `Short` description is expected, and `Long` can be used to provide a more detailed description when a user uses the `--help` flag to ask for more information. + + **RunE:** Defines a function that can return an error, called when the command is executed. Using `Run` would do the same thing, but would not allow for errors to be returned. +- **`RunE` Function Body:** The function should be specified as a `RunE` to allow for errors to be returned. This function encapsulates all of the logic to create a new transaction that is ready to be relayed to nodes. + + The function should first initialize a [`TxBuilder`](../core/transactions.md#txbuilder) with the application `codec`'s `TxEncoder`, as well as a new [`CLIContext`](./query-lifecycle.md#clicontext) with the `codec` and `AccountDecoder`. These contexts contain all the information provided by the user and will be used to transfer this user-specific information between processes. To learn more about how contexts are used in a transaction, click [here](../core/transactions.md#transaction-generation). + + If applicable, the command's arguments are parsed. Here, the `amount` given by the user is parsed into a denomination of `coins`. + + If applicable, the `CLIContext` is used to retrieve any parameters such as the transaction originator's address to be used in the transaction. Here, the `from` address is retrieved by calling `cliCtx.getFromAddress()`. + + A [message](./messages-and-queries.md) is created using all parameters parsed from the command arguments and `CLIContext`. The constructor function of the specific message type is called directly. It is good practice to call `ValidateBasic()` on the newly created message to run a sanity check and check for invalid arguments. + + Depending on what the user wants, the transaction is either generated offline or signed and broadcasted to the preconfigured node using `GenerateOrBroadcastMsgs()`. +- **Flags.** Add any [flags](#flags) to the command. No flags were specified here, but all transaction commands have flags to provide additional information from the user (e.g. amount of fees they are willing to pay). These *persistent* [transaction flags](../interfaces/cli.md#flags) can be added to a higher-level command so that they apply to all transaction commands. + + +#### GetTxCmd + +Finally, the module needs to have a `GetTxCmd()`, which aggregates all of the transaction commands of the module. Often, each command getter function has its own file in the module's `cli` folder, and a separate `tx.go` file contains `GetTxCmd()`. Application developers wishing to include the module's transactions will call this function to add them as subcommands in their CLI. Here is the [`auth`](https://github.com/cosmos/cosmos-sdk/tree/67f6b021180c7ef0bcf25b6597a629aca27766b8/docs/spec/auth) `GetTxCmd()` function, which adds the `Sign` and `MultiSign` commands. An application using this module likely adds `auth` module commands to its root `TxCmd` command by calling `txCmd.AddCommand(authModuleClient.GetTxCmd())`. + +```go +func GetTxCmd(cdc *codec.Codec) *cobra.Command { + txCmd := &cobra.Command{ + Use: types.ModuleName, + Short: "Auth transaction subcommands", + DisableFlagParsing: true, + SuggestionsMinimumDistance: 2, + RunE: client.ValidateCmd, + } + txCmd.AddCommand( + GetMultiSignCommand(cdc), + GetSignCommand(cdc), + ) + return txCmd +} +``` + +### Query Commands + +[Queries](./messages-and-queries.md) allow users to gather information about the application or network state; they are routed by the application and processed by the module in which they are defined. Query commands typically have their own `query.go` file in the module `x/moduleName/client/cli` folder. Like transaction commands, they are specified in getter functions and have the prefix `GetCmdQuery`. Here is an example of a query command from the nameservice module: + +```go +func GetCmdWhois(queryRoute string, cdc *codec.Codec) *cobra.Command { + return &cobra.Command{ + Use: "whois [name]", + Short: "Query whois info of name", + Args: cobra.ExactArgs(1), + RunE: func(cmd *cobra.Command, args []string) error { + cliCtx := context.NewCLIContext().WithCodec(cdc) + name := args[0] + + res, err := cliCtx.QueryWithData(fmt.Sprintf("custom/%s/whois/%s", queryRoute, name), nil) + if err != nil { + fmt.Printf("could not resolve whois - %s \n", string(name)) + return nil + } + + var out nameservice.Whois + cdc.MustUnmarshalJSON(res, &out) + return cliCtx.PrintOutput(out) + }, + } +} + +``` + +This query returns the address that owns a particular name. The getter function does the following: + +- **`codec` and `queryRoute`.** In addition to taking in the application `codec`, query command getters also take a `queryRoute` used to construct a path [Baseapp](../core/baseapp.md#query-routing) uses to route the query in the application. +- **Construct the command.** Read the [Cobra Documentation](https://github.com/spf13/cobra) and the [transaction command](#transaction-commands) example above for more information. The user must type `whois` and provide the `name` they are querying for as the only argument. +- **`RunE`.** The function should be specified as a `RunE` to allow for errors to be returned. This function encapsulates all of the logic to create a new query that is ready to be relayed to nodes. + + The function should first initialize a new [`CLIContext`](./query-lifecycle.md#clicontext) with the application `codec`. + + If applicable, the `CLIContext` is used to retrieve any parameters (e.g. the query originator's address to be used in the query) and marshal them with the query parameter type, in preparation to be relayed to a node. There are no `CLIContext` parameters in this case because the query does not involve any information about the user. + + The `queryRoute` is used to construct a route Baseapp will use to route the query to the appropriate [querier](./querier.md). Module queries are `custom` type queries (some SDK modules have exceptions, such as `auth` and `gov` module queries). + + The `CLIContext` query function relays the query to a node and retrieves the response. + + The `codec` is used to nmarshal the response and the `CLIContext` is used to print the output back to the user. +- **Flags.** Add any [flags](#flags) to the command. + +#### GetQueryCmd + +Finally, the module also needs a `GetQueryCmd`, which aggregates all of the query commands of the module. Application developers wishing to include the module's queries will call this function to add them as subcommands in their CLI. Its structure is identical to the [`GetTxCmd`](#gettxcmd) command. + +### Flags + +[Flags](../interfaces/cli.md#flags) are entered by the user and allow for command customizations. Examples include the [fees](../core/accounts-fees.md) or gas prices users are willing to pay for their transactions. + +The flags for a module are typically found in a `flags.go` file in the `./x/moduleName/client/cli` folder. Module developers can create a list of possible flags including the value type, default value, and a description displayed if the user uses a `help` command. In each transaction getter function, they can add flags to the commands and, optionally, mark flags as *required* so that an error is thrown if the user does not provide values for them. + +For full details on flags, visit the [Cobra Documentation](https://github.com/spf13/cobra). + +For example, the SDK `./client/flags` package includes a [`PostCommands()`](https://github.com/cosmos/cosmos-sdk/blob/master/client/flags/flags.go#L85-L116) function that adds necessary flags to transaction commands, such as the `from` flag to indicate which address the transaction originates from. Here is an example of how to add a flag using the `from` flag from this function. + +```go +cmd.Flags().String(FlagFrom, "", "Name or address of private key with which to sign") +``` + +The input provided for this flag - called `FlagFrom` is a string with the default value of `""` if none is provided. If the user asks for a description of this flag, the description will be printed. + +A flag can be marked as *required* so that an error is automatically thrown if the user does not provide a value: + +```go +cmd.MarkFlagRequired(FlagFrom) +``` + +Since `PostCommands()` includes all of the basic flags required for a transaction command, module developers may choose not to add any of their own (specifying arguments instead may often be more appropriate). For a full list of what flags are included in the `PostCommands()` function, including which are required inputs from users, see the CLI documentation [here](../interfaces/cli.md#transaction-flags). + +## REST + +Applications are typically required to support web services that use HTTP requests (e.g. a web wallet like [Lunie.io](lunie.io)). Thus, application developers will also use REST Routes to route HTTP requests to the application's modules; these routes will be used by service providers. The module developer's responsibility is to define the REST client by defining [routes](#register-routes) for all possible [requests](#request-types) and [handlers](#request-handlers) for each of them. It's up to the module developer how to organize the REST interface files; there is typically a `rest.go` file found in the module's `./x/moduleName/client/rest` folder. + +### Request Types + +Request types must be defined for all *transaction* requests. Conventionally, each request is named with the suffix `Req`, e.g. `SendReq` for a Send transaction. Each struct should include a base request [`baseReq`](../interfaces/rest.md#basereq), the name of the transaction, and all the arguments the user must provide for the transaction. + +Here is an example of a request to buy a name from the [nameservice](https://cosmos.network/docs/tutorial/rest.html) module: + +```go +type buyNameReq struct { + BaseReq rest.BaseReq `json:"base_req"` + Name string `json:"name"` + Amount string `json:"amount"` + Buyer string `json:"buyer"` +} +``` + +The `BaseReq` includes basic information that every request needs to have, similar to required flags in a CLI. All of these values, including `GasPrices` and `AccountNumber`, will be provided in the request body. The user will also need to specify the arguments `Name` and `Amount` fields in the body and `Buyer` will be provided by the user's address. + +#### BaseReq + +`BaseReq` is a type defined in the SDK that encapsulates much of the transaction configurations similar to CLI command flags. Users must provide the information in the body of their requests. + +* `From` indicates which [account](../core/accounts-fees.md) the transaction originates from. This account is used to sign the transaction. +* `Memo` sends a memo along with the transaction. +* `ChainID` specifies the unique identifier of the blockchain the transaction pertains to. +* `AccountNumber` is an identifier for the account. +* `Sequence`is the value of a counter measuring how many transactions have been sent from the account. It is used to prevent replay attacks. +* `Gas` refers to how much [gas](../core/gas.md), which represents computational resources, Tx consumes. Gas is dependent on the transaction and is not precisely calculated until execution, but can be estimated by providing auto as the value for `Gas`. +* `GasAdjustment` can be used to scale gas up in order to avoid underestimating. For example, users can specify their gas adjustment as 1.5 to use 1.5 times the estimated gas. +* `GasPrices` specifies how much the user is willing pay per unit of gas, which can be one or multiple denominations of tokens. For example, --gas-prices=0.025uatom, 0.025upho means the user is willing to pay 0.025uatom AND 0.025upho per unit of gas. +* `Fees` specifies how much in [fees](../core/accounts-fees.md) the user is willing to pay in total. Note that the user only needs to provide either `gas-prices` or `fees`, but not both, because they can be derived from each other. +* `Simulate` instructs the application to ignore gas and simulate the transaction running without broadcasting. + +### Request Handlers + +Request handlers must be defined for both transaction and query requests. Handlers' arguments include a reference to the application's `codec` and the [`CLIContext`](../interfaces/query-lifecycle.md#clicontext) created in the user interaction. + +Here is an example of a request handler for the nameservice module `buyNameReq` request (the same one shown above): + +```go +func buyNameHandler(cdc *codec.Codec, cliCtx context.CLIContext) http.HandlerFunc { + return func(w http.ResponseWriter, r *http.Request) { + var req buyNameReq + + if !rest.ReadRESTReq(w, r, cdc, &req) { + rest.WriteErrorResponse(w, http.StatusBadRequest, "failed to parse request") + return + } + + baseReq := req.BaseReq.Sanitize() + if !baseReq.ValidateBaic(w) { + return + } + + addr, err := sdk.AccAddressFromBech32(req.Buyer) + if err != nil { + rest.WriteErrorResponse(w, http.StatusBadRequest, err.Error()) + return + } + + coins, err := sdk.ParseCoins(req.Amount) + if err != nil { + rest.WriteErrorResponse(w, http.StatusBadRequest, err.Error()) + return + } + + //create message + msg := nameservice.NewMsgBuyName(req.Name, coins, addr) + err = msg.ValidateBasic() + if err != nil { + rest.WriteErrorResponse(w, http.StatusBadRequest, err.Error()) + return + } + clientrest.WriteGenerateStdTxResponse(w, cdc, cliCtx, baseReq, []sdk.Msg{msg}) + + } +} +``` + +The request handler can be broken down as follows: + +* **Parse Request:** The request handler first attempts to parse the request, and then run `Sanitize` and `ValidateBasic` on the underlying `BaseReq` to check the validity of the request. Next, it attempts to parse the arguments `Buyer` and `Amount` to the types `AccountAddress` and `Coins` respectively. +* **Message:** Then, a [message](./messages-and-queries.md) of the type `MsgBuyName` (defined by the module developer to trigger the state changes for this transaction) is created from the values and another sanity check, `ValidateBasic` is run on it. +* **Generate Transaction:** Finally, the HTTP `ResponseWriter`, application [`codec`](../core/encoding.md), [`CLIContext`](../interfaces/query-lifecycle.md#clicontext), request [`BaseReq`](../interfaces/rest.md#basereq), and message is passed to `WriteGenerateStdTxResponse` to further process the request. + +To read more about how a transaction is generated, visit the transactions documentation [here](../core/transactions.md#transaction-generation). + +### Register Routes + +The application CLI entrypoint will have a `RegisterRoutes` function in its `main.go` file, which calls the `registerRoutes` functions of each module utilized by the application. Module developers need to implement `registerRoutes` for their modules so that applications are able to route messages and queries to their corresponding handlers and queriers. + +The router used by the SDK is [Gorilla Mux](https://github.com/gorilla/mux). The router is initialized with the Gorilla Mux `NewRouter()` function. Then, the router's `HandleFunc` function can then be used to route urls with the defined request handlers and the HTTP method (e.g. "POST", "GET") as a route matcher. It is recommended to prefix every route with the name of the module to avoid collisions with other modules that have the same query or transaction names. + +Here is a `registerRoutes` function with one query route example from the [nameservice tutorial](https://cosmos.network/docs/tutorial/rest.html): + +``` go +func RegisterRoutes(cliCtx context.CLIContext, r *mux.Router, cdc *codec.Codec, storeName string) { + // ResolveName Query + r.HandleFunc(fmt.Sprintf("/%s/names/{%s}", storeName, restName), resolveNameHandler(cdc, cliCtx, storeName)).Methods("GET") +} +``` + +A few things to note: + +* The router `r` has already been initialized by the application and is passed in here as an argument - this function is able to add on the nameservice module's routes onto any application's router. The application must also provide a [`CLIContext`](../interfaces/query-lifecycle.md#clicontext) that the querier will need to process user requests and the application [`codec`](../core/encoding.md) for encoding and decoding application-specific types. +* `"/%s/names/{%s}", storeName, restName` is the url for the HTTP request. `storeName` is the name of the module, `restName` is a variable provided by the user to specify what kind of query they are making. +* `resolveNameHandler` is the query request handler defined by the module developer. It also takes the application `codec` and `CLIContext` passed in from the user side, as well as the `storeName`. +* `"GET"` is the HTTP Request method. As to be expected, queries are typically GET requests. Transactions are typically POST and PUT requests. + -### Query +## Next -## REST \ No newline at end of file +Read about the next topic in building modules. diff --git a/docs/concepts/app-anatomy.md b/docs/concepts/app-anatomy.md index 177a84f19c7e..78d7b1eda675 100644 --- a/docs/concepts/app-anatomy.md +++ b/docs/concepts/app-anatomy.md @@ -116,7 +116,7 @@ The SDK offers developers the possibility to implement automatic execution of co In general, the `BeginBlocker` and `EndBlocker` functions are mostly composed of the `BeginBlock` and `EndBlock` functions of each of the application's modules. This is done by calling the `BeginBlock` and `EndBlock` functions of the module manager, which in turn will call the `BeginBLock` and `EndBlock` functions of each of the modules it contains. Note that the order in which the modules' `BegingBlock` and `EndBlock` functions must be called has to be set in the module manager using the `SetOrderBeginBlock` and `SetOrderEndBlock` methods respectively. This is done in the [application's constructor](#application-constructor), and the `SetOrderBeginBlock` and `SetOrderEndBlock` methods have to be called before the `SetBeginBlocker` and `SetEndBlocker` functions. -As a sidenote, it is important to remember that application-specific blockchains are deterministic. Developers must be careful not to introduce non-determinism in `BeginBlocker` or `EndBlocker`, and must also be careful not to make them too computationally expensive, as [gas](./accounts-fees.md/gas) does not constrain the cost of `BeginBlocker` and `EndBlocker` execution. +As a sidenote, it is important to remember that application-specific blockchains are deterministic. Developers must be careful not to introduce non-determinism in `BeginBlocker` or `EndBlocker`, and must also be careful not to make them too computationally expensive, as [gas](./fees-signature.md/gas) does not constrain the cost of `BeginBlocker` and `EndBlocker` execution. You can see an example of `BeginBlocker` and `EndBlocker` functions [here](https://github.com/cosmos/gaia/blob/master/app/app.go#L224-L232). @@ -154,7 +154,7 @@ To learn more about the application module interface, [click here](./modules.md# A message is a custom type defined by each module that implements the [`message`](https://github.com/cosmos/cosmos-sdk/blob/master/types/tx_msg.go#L8-L29) interface. Each `transaction` contains one or multiple `messages`. When a valid block of transactions is received by the full-node, Tendermint relays each one to the application via [`DeliverTx`](https://tendermint.com/docs/app-dev/abci-spec.html#delivertx). Then, the application handles the transaction: 1. Upon receiving the transaction, the application first unmarshalls it from `[]bytes`. -2. Then, it verifies a few things about the transaction like [fee payment and signatures](#accounts-fees.md) before extracting the message(s) contained in the transaction. +2. Then, it verifies a few things about the transaction like [fee payment and signatures](#fees-signature.md) before extracting the message(s) contained in the transaction. 3. With the [`Type()`](https://github.com/cosmos/cosmos-sdk/blob/master/types/tx_msg.go#L16) method, `baseapp` is able to know which modules defines the message. It is then able to route it to the appropriate module's [handler](#handler) in order for the message to be processed. 4. If the message is successfully processed, the state is updated. diff --git a/docs/concepts/baseapp_old.md b/docs/concepts/baseapp_old.md deleted file mode 100644 index c4f71f33f696..000000000000 --- a/docs/concepts/baseapp_old.md +++ /dev/null @@ -1,128 +0,0 @@ -# BaseApp - -The BaseApp defines the foundational implementation for a basic ABCI application -so that your Cosmos-SDK application can communicate with an underlying -Tendermint node. - -The BaseApp is composed of many internal components. Some of the most important -include the `CommitMultiStore` and its internal state. The internal state is -essentially two sub-states, both of which are used for transaction execution -during different phases, `CheckTx` and `DeliverTx` respectively. During block -commitment, only the `DeliverTx` is persisted. - -The BaseApp requires stores to be mounted via capabilities keys - handlers can -only access stores they're given the key to. The `baseApp` ensures all stores are -properly loaded, cached, and committed. One mounted store is considered the -"main" (`baseApp.MainStoreKey`) - it holds the latest block header, from which we can find and load the -most recent state. - -The BaseApp distinguishes between two handler types - the `AnteHandler` and the -`MsgHandler`. The former is a global validity check (checking nonces, sigs and -sufficient balances to pay fees, e.g. things that apply to all transaction from -all modules), the later is the full state transition function. - -During `CheckTx` the state transition function is only applied to the `checkTxState` -and should return before any expensive state transitions are run -(this is up to each developer). It also needs to return the estimated gas cost. - -During `DeliverTx` the state transition function is applied to the blockchain -state and the transactions need to be fully executed. - -The BaseApp is responsible for managing the context passed into handlers - -it makes the block header available and provides the right stores for `CheckTx` -and `DeliverTx`. BaseApp is completely agnostic to serialization formats. - -## Routing - -TODO - -## Transaction Life Cycle - -During the execution of a transaction, it may pass through both `CheckTx` and -`DeliverTx` as defined in the ABCI specification. `CheckTx` is executed by the -proposing validator and is used for the Tendermint mempool for all full nodes. - -Both `CheckTx` and `DeliverTx` execute the application's AnteHandler (if -defined), where the AnteHandler is responsible for pre-message validation -checks such as account and signature validation, fee deduction and collection, -and incrementing sequence numbers. - -### CheckTx - -During the execution of `CheckTx`, only the AnteHandler is executed. - -State transitions due to the AnteHandler are persisted between subsequent calls -of `CheckTx` in the check-tx state, unless the AnteHandler fails and aborts. - -### DeliverTx - -During the execution of `DeliverTx`, the AnteHandler and Handler is executed. - -The transaction execution during `DeliverTx` operates in a similar fashion to -`CheckTx`. However, state transitions that occur during the AnteHandler are -persisted even when the following Handler processing logic fails. - -It is possible that a malicious proposer may include a transaction in a block -that fails the AnteHandler. In this case, all state transitions for the -offending transaction are discarded. - - -## Other ABCI Messages - -Besides `CheckTx` and `DeliverTx`, BaseApp handles the following ABCI messages. - -### Info -TODO complete description - -### SetOption -TODO complete description - -### Query -TODO complete description - -### InitChain -TODO complete description - -During chain initialization InitChain runs the initialization logic directly on -the CommitMultiStore. The deliver and check states are initialized with the -ChainID. - -Note that we do not commit after InitChain, so BeginBlock for block 1 starts -from the deliver state as initialized by InitChain. - -### BeginBlock -TODO complete description - -### EndBlock -TODO complete description - -### Commit -TODO complete description - - -## Gas Management - -### Gas: InitChain - -During InitChain, the block gas meter is initialized with an infinite amount of -gas to run any genesis transactions. - -Additionally, the InitChain request message includes ConsensusParams as -declared in the genesis.json file. - -### Gas: BeginBlock - -The block gas meter is reset during BeginBlock for the deliver state. If no -maximum block gas is set within baseapp then an infinite gas meter is set, -otherwise a gas meter with `ConsensusParam.BlockSize.MaxGas` is initialized. - -### Gas: DeliverTx - -Before the transaction logic is run, the `BlockGasMeter` is first checked to -see if any gas remains. If no gas remains, then `DeliverTx` immediately returns -an error. - -After the transaction has been processed, the used gas (up to the transaction -gas limit) is deducted from the BlockGasMeter. If the remaining gas exceeds the -meter's limits, then DeliverTx returns an error and the transaction is not -committed. diff --git a/docs/concepts/genesis.md b/docs/concepts/genesis.md deleted file mode 100644 index 5e3dbd31dcad..000000000000 --- a/docs/concepts/genesis.md +++ /dev/null @@ -1,3 +0,0 @@ -# Genesis File - -TODO \ No newline at end of file diff --git a/docs/concepts/store.md b/docs/concepts/store.md deleted file mode 100644 index 067eea3b79bd..000000000000 --- a/docs/concepts/store.md +++ /dev/null @@ -1,8 +0,0 @@ -# Store - -## Commit Multi Store - -## Database - -## Main Store - diff --git a/docs/core/baseapp_old.md b/docs/core/baseapp_old.md deleted file mode 100644 index c239272fcba3..000000000000 --- a/docs/core/baseapp_old.md +++ /dev/null @@ -1,148 +0,0 @@ -# BaseApp - -## Pre-requisite Reading - -- [Anatomy of an SDK application](./app-anatomy.md) -- [Lifecycle of an SDK transaction](./tx-lifecycle.md) - -## Synopsis - -This document describes `baseapp`, the abstraction that implements most of the common functionalities of an SDK application. - -- [Introduction](#introduction) -- [Type Definition](#type-definition) -- [States](#states) -- [Routing](#routing) -- [ABCI](#abci) -- [CheckTx](#abci-checktx) -- [DeliverTx](#abci-delivertx) -- [Commit](#abbci-commit) -- [Other ABCI Message](#other-abci-message) - + [Info](#info) - + [SetOption](#setoption) - + [Query](#query) - + [InitChain](#initchain) - + [BeginBlock](#beginblock) - + [EndBlock](#endblock) -- [Gas](#gas) - - -## Introduction - -`baseapp` is an abstraction that implements the core of an SDK application, namely: - -- The [Application-Blockchain Interface](#abci), for the state-machine to communicate with the underlying consensus engine (e.g. Tendermint). -- A [Router](#routing), to route [messages](./tx-msgs.md) and [queries](./querier.md) to the appropriate [module](./modules.md). -- Different [states](#states), as the state-machine can have different parallel states updated based on the ABCI message received. - -The goal of `baseapp` is to provide a boilerplate SDK application that developers can easily extend to build their own custom application. Usually, developers will create a custom type for their application, like so: - -```go -type app struct { - *bam.BaseApp // reference to baseapp - cdc *codec.Codec - - // list of application store keys - - // list of application keepers - - // module manager -} -``` - -Extending the application with `baseapp` gives the former access to all of `baseapp`'s methods. This allows developers to compose their custom application with the modules they want, while not having to concern themselves with the hard work of implementing the ABCI, the routing and state management logic. - -## Type Definition - -The [`baseapp` type](https://github.com/cosmos/cosmos-sdk/blob/master/baseapp/baseapp.go#L45-L91) holds many important parameters for any Cosmos SDK based application. Let us go through the most important components. - -*Note: Not all parameters are described, only the most important ones. Refer to the [type definition](https://github.com/cosmos/cosmos-sdk/blob/master/baseapp/baseapp.go#L45-L91) for the full list* - -First, the important parameters that are initialized during the initialization of the application: - -- A [`CommitMultiStore`](./store.md#commit-multi-store). This is the main store of the application, which holds the canonical state that is committed at the [end of each block](#commit). This store is **not** cached, meaning it is not used to update the application's intermediate (un-committed) states. The `CommitMultiStore` is a multi-store, meaning a store of stores. Each module of the application uses one or multiple `KVStores` in the multi-store to persist their subset of the state. -- A [database](./store.md#database) `db`, which is used by the `CommitMultiStore` to handle data storage. -- A [router](#messages). The `router` facilitates the routing of [messages](./tx-msgs.md) to the appropriate module for it to be processed. -- A [query router](#queries). The `query router` facilitates the routing of [queries](./querier.md) to the appropriate module for it to be processed. -- A [`txDecoder`](https://godoc.org/github.com/cosmos/cosmos-sdk/types#TxDecoder), used to decode transaction `[]byte` relayed by the underlying Tendermint engine. -- A [`baseKey`], to access the [main store](./store.md#main-store) in the `CommitMultiStore`. The main store is used to persist data related to the core of the application, like consensus parameters. -- A [`anteHandler`](./accounts-fees.md#antehandler), to handle signature verification and fee paiement when a transaction is received. -- An [`initChainer`](./app-anatomy.md#initchainer), [`beginBlocker` and `endBlocker`](./app-anatomy.md#beginblocker-and-endblocker), which are the functions executed when the application received the [InitChain], [BeginBlock] and [EndBlock] messages from the underlying Tendermint engine. - -Then, parameters used to define [volatile states](#volatile-states) (i.e. cached states): - -- `checkState`: This state is updated during [`CheckTx`](#checktx), and reset on [`Commit`](#commit). -- `deliverState`: This state is updated during [`DeliverTx`](#delivertx), and reset on [`Commit`](#commit). - -Finally, a few more important parameterd: - -- `voteInfos`: This parameter carries the list of validators whose precommit is missing, either because they did not vote or because the proposer did not include their vote. This information is carried by the [context](#context) and can be used by the application for various things like punishing absent validators. -- `minGasPrices`: This parameter defines the minimum [gas prices](./accounts-fees.md#gas) accepted by the node. This is a local parameter, meaning each full-node can set a different `minGasPrices`. It is run by the [`anteHandler`](./accounts-fees.md#antehandler) during `CheckTx`, mainly as a spam protection mechanism. The transaction enters the [mempool](https://tendermint.com/docs/tendermint-core/mempool.html#transaction-ordering) only if the gas price of the transaction is superior to one of the minimum gas price in `minGasPrices` (i.e. if `minGasPrices == 1uatom, 1upho`, the `gas-price` of the transaction must be superior to `1uatom` OR `1upho`). -- `appVersion`: Version of the application. It is set in the [application's constructor function](./baseapp.md#constructor-function). - -## States - -`baseapp` handles various parallel states for different purposes. There is the [main state](#main-state), which is the canonical state of the application, and volatile states like [`checkState`](#checkState) and [`deliverState`](#deliverstate), which are used to handle temporary states inbetween updates of the main state. - -### Main State - -The main state is the canonical state of the application. It is initialized on [`InitChain`](#initchain and updated on [`Commit`](#abci-commit) at the end of each block. - -``` -+--------+ +--------+ -| | | | -| S +----------------------------> | S' | -| | For each T in B: apply(T) | | -+--------+ +--------+ -``` - -The main state is held by `baseapp` in a structure called the [`CommitMultiStore`](./store.md#commit-multi-store). This multi-store is used by developers to instantiate all the stores they need for each of their application's modules. - -### Volatile States - -Volatile - or cached - states are used in between [`Commit`s](#commit) to manage temporary states. They are reset to the latest version of the main state after it is committed. There are two main volatile states: - -- `checkState`: This cached state is initialized during [`InitChain`](#initchain), updated during [`CheckTx`](#abci-checktx) when an unconfirmed transaction is received, and reset to the [main state](#main-state) on [`Commit`](#abci-commit). -- `deliverState`: This cached state is initialized during [`BeginBlock`](#beginblock), updated during [`DeliverTx`](#abci-delivertx) when a transaction included in a block is processed, and reset to the [main state](#main-state) on [`Commit`](#abci-commit). - -## Routing - -When messages and queries are received by the application, they must be routed to the appropriate module in order to be processed. Routing is done via `baseapp`, which holds a `router` for messages, and a `query router` for queries. - -### Message Routing - -Messages need to be routed after they are extracted from transactions, which are sent from the underlying Tendermint engine via the [`CheckTx`](#checktx) and [`DeliverTx`](#delivertx) ABCI messages. To do so, `baseapp` holds a [`router`](https://github.com/cosmos/cosmos-sdk/blob/master/baseapp/router.go) which maps `paths` (`string`) to the appropriate module [`handler`](./handler.md). Usually, the `path` is the name of the module. - -The application's `router` is initilalized with all the routes using the application's [module manager](./modules.md#module-manager), which itself is initialized with all the application's modules in the application's [constructor](./app-anatomy.md#app-constructor). - -### Query Routing - -Similar to messages, queries need to be routed to the appropriate module's [querier](./querier.md). To do so, `baseapp` holds a [`query router`](https://github.com/cosmos/cosmos-sdk/blob/master/baseapp/queryrouter.go), which maps `paths` (`string`) to the appropriate module [`querier`](./querier.md). Usually, the `path` is the name of the module. - -Just like the `router`, the `query router` is initilalized with all the query routes using the application's [module manager](./modules.md#module-manager), which itself is initialized with all the application's modules in the application's [constructor](./app-anatomy.md#app-constructor). - -## Main ABCI Messages - - - -### CheckTx - -### DeliverTx - -## RunTx and RunMsg - -## Other ABCI Messages - -### Commit - -### Info - -### SetOption - -### Query - -### InitChain - -### BeginBlock - -### EndBlock \ No newline at end of file diff --git a/docs/concepts/handler.md b/docs/modules/handler.md similarity index 100% rename from docs/concepts/handler.md rename to docs/modules/handler.md diff --git a/docs/concepts/invariants.md b/docs/modules/invariants.md similarity index 100% rename from docs/concepts/invariants.md rename to docs/modules/invariants.md diff --git a/docs/concepts/keeper.md b/docs/modules/keeper.md similarity index 100% rename from docs/concepts/keeper.md rename to docs/modules/keeper.md diff --git a/docs/modules/module-interfaces.md b/docs/modules/module-interfaces.md new file mode 100644 index 000000000000..0cd27c895326 --- /dev/null +++ b/docs/modules/module-interfaces.md @@ -0,0 +1,5 @@ +# Module Interfaces + +## CLI + +## REST \ No newline at end of file diff --git a/docs/concepts/modules.md b/docs/modules/modules.md similarity index 100% rename from docs/concepts/modules.md rename to docs/modules/modules.md diff --git a/docs/concepts/querier.md b/docs/modules/querier.md similarity index 100% rename from docs/concepts/querier.md rename to docs/modules/querier.md From f783f03ebb3110b65f49854cdae6d705454af7b9 Mon Sep 17 00:00:00 2001 From: gamarin Date: Fri, 5 Jul 2019 12:00:14 +0200 Subject: [PATCH 043/196] almost there --- docs/basics/accounts-fees.md | 2 +- docs/concepts/app-anatomy.md | 255 ------------------------------ docs/concepts/tx-msgs.md | 5 + docs/core/baseapp.md | 194 +++++++++++++---------- docs/modules/handler.md | 1 - docs/modules/invariants.md | 5 - docs/modules/keeper.md | 0 docs/modules/module-interfaces.md | 5 - docs/modules/modules.md | 8 - docs/modules/querier.md | 3 - 10 files changed, 115 insertions(+), 363 deletions(-) delete mode 100644 docs/concepts/app-anatomy.md create mode 100644 docs/concepts/tx-msgs.md delete mode 100644 docs/modules/handler.md delete mode 100644 docs/modules/invariants.md delete mode 100644 docs/modules/keeper.md delete mode 100644 docs/modules/module-interfaces.md delete mode 100644 docs/modules/modules.md delete mode 100644 docs/modules/querier.md diff --git a/docs/basics/accounts-fees.md b/docs/basics/accounts-fees.md index 9f03e0eb033d..20fe1fb2dac8 100644 --- a/docs/basics/accounts-fees.md +++ b/docs/basics/accounts-fees.md @@ -1,4 +1,4 @@ -# Accounts, Fees and Signatures +# Accounts, Fees and Gas ## Accounts diff --git a/docs/concepts/app-anatomy.md b/docs/concepts/app-anatomy.md deleted file mode 100644 index 78d7b1eda675..000000000000 --- a/docs/concepts/app-anatomy.md +++ /dev/null @@ -1,255 +0,0 @@ -# Anatomy of an SDK Application - -## Pre-requisite reading - -- [High-level overview of the architecture of an SDK application](../intro/sdk-app-architecture.md) -- [Cosmos SDK design overview](../intro/sdk-design.md) - -## Synopsis - -This document describes the core parts of a Cosmos SDK application. The placeholder name for this application will be `app`. - -- [Node Client](#node-client) -- [Core Application File](#core-application-file) -- [Modules](#modules) -- [Intefaces](#interfaces) -- [Dependencies and Makefile](#dependencies-and-makefile) - -The core parts listed above will generally translate to the following directory tree: - -``` -./app -├── cmd/ -│ ├── appd -│ └── appcli -├── app.go -├── x/ -│ ├── auth -│ └── bank -├── Gopkg.toml -└── Makefile -``` - -## Node Client - -The Daemon, or Full-Node Client, is the core process of an SDK-based blockchain. Participants in the network run this process to initialize their state-machine, connect with other full-nodes and update their state-machine as new blocks come in. - -``` - ^ +-------------------------------+ ^ - | | | | - | | State-machine = Application | | - | | | | Built with Cosmos SDK - | | ^ + | | - | +----------- | ABCI | ----------+ v - | | + v | ^ - | | | | -Blockchain Node | | Consensus | | - | | | | - | +-------------------------------+ | Tendermint Core - | | | | - | | Networking | | - | | | | - v +-------------------------------+ v -``` -The blockchain full-node presents itself as a binary, generally suffixed by `-d` (e.g. `appd` for `app` or `gaiad` for the `gaia`) for "daemon". This binary is built by running a simple `main.go` function placed in `cmd/appd/`. This operation usually happens through the [Makefil](#dependencies-and-makefile). - -To learn more about the `main.go` function, [click here](./node.md#main-function). - -Once the main binary is built, the node can be started by running the `start` command. The core logic behind the `start` command is implemented in the SDK itself in the [`/server/start.go`](https://github.com/cosmos/cosmos-sdk/blob/master/server/start.go) file. The main [`start` command function](https://github.com/cosmos/cosmos-sdk/blob/master/server/start.go#L31) takes a [`context`](https://godoc.org/github.com/cosmos/cosmos-sdk/client/context) and [`appCreator`](#constructor-function-(`appCreator`)) as arguments. The `appCreator` is a constructor function for the SDK application, and is used in the starting process of the full-node. - -The `start` command function primarily does three things: - -1. Create an instance of the state-machine defined in [`app.go`](#core-application-file) using the `appCreator`. -2. Initialize the state-machine with the latest known state, extracted from the `db` stored in the `~/.appd/data` folder. At this point, the state-machine is at height `appBlockHeight`. -3. Create and start a new Tendermint instance. Among other things, the node will perform a handshake with its peers. It will get the latest `blockHeight` from them, and replay blocks to sync to this height if it is greater than the local `appBlockHeight`. If `appBlockHeight` is `0`, the node is starting from genesis and Tendermint sends an `InitChain` message via the ABCI to the `app`, which triggers the [`InitChainer`](#initchainer). - -To learn more about the `start` command, [click here](./node.md#start-command). - -## Core Application File - -In general, the core of the state-machine is defined in a file called `app.go`. It mainly contains the **type definition of the application** and functions to **create and initialize it**. - -### Type Definition of the Application - -The first thing defined in `app.go` is the `type` of the application. It is generally comprised of the following parts: - -- **A reference to [`baseapp`](./baseapp.md).** The custom application defined in `app.go` is an extension of the `baseapp` type. `baseapp` implements most of the core logic for the application, including all the [ABCI methods](https://tendermint.com/docs/spec/abci/abci.html#overview) and the routing logic. When a transaction is relayed by Tendermint to the application, the latter uses `baseapp`'s methods to route them to the appropriate module. -- **A list of store keys**. The [store](./store.md), which contains the entire state, is implemented as a multistore (i.e. a store of stores) in the Cosmos SDK. Each module uses one or multiple stores in the multistore to persist their part of the state. These stores can be accessed with specific keys that are declared in the `app` type. These keys, along with the `keepers`, are at the heart of the [object-capabilities model](../intro/ocap.md) of the Cosmos SDK. -- **A list of module's `keepers`.** Each module defines an abstraction called `keeper`, which handles reads and writes for this module's store(s). The `keeper`'s methods of one module can be called from other modules (if authorized), which is why they are declared in the application's type and exported as interfaces to other modules so that they are only allowed to access the authorized functions. -- **A reference to a `codec`.** The Cosmos SDK gives developers the freedom to choose the encoding framework for their application. The application's `codec` is used to serialize and deserialize data structures in order to store them, as stores can only persist `[]bytes`. The `codec` must be deterministic. The default codec is [amino](./amino.md). -- **A reference to a [module manager](./modules.md#module-manager)**. The module manager is an object that contains a list of the application's module. It facilitates operations related to these modules, like registering [`routes`](./baseapp.md#routing), [query routes](#./baseapp.md#query-routing) or setting the order of execution between modules for various functions like [`InitChainer`](#initchainer), [`BeginBlocker` and `EndBlocker`](#beginblocker-and-endblocker). - -You can see an example of application type definition [here](https://github.com/cosmos/gaia/blob/master/app/app.go#L73-L107). - -### Constructor Function - -This function constructs a new application of the type defined above. It is [called](https://github.com/cosmos/cosmos-sdk/blob/master/server/start.go#L117) everytime the full-node is started with the `start` command. Here are the main actions performed by this function: - -- Instantiate a new application with a reference to a `baseapp` instance, a codec and all the appropriate store keys. -- Instantiate all the [`keeper`s](#keeper) defined in the application's `type` using the `NewKeeper` function of each of the application's modules. Note that `keepers` must be instantiated in the correct order, as the `NewKeeper` of one module might require a reference to another module's `keeper`. -- Instantiate the application's [module manager](./module-manager.md) with the [`AppModule`](#application-module-interface) object of each of the application's modules. -- With the module manager, initialize the application's [`routes`](./baseapp.md#routing) and [query routes](./baseapp.md#query-routing). When a transaction is relayed to the application by Tendermint via the ABCI, it is routed to the appropriate module's [`handler`](#handler) using the routes defined here. Likewise, when a query is received by the application, it is routed to the appropriate module's [`querier`](#querier) using the query routes defined here. -- With the module manager, register the [application's modules' invariants](./invariants.md). Invariants are variables (e.g. total supply of a token) that are evaluated at the end of each block. The process of checking invariants is done via a special module called the [`InvariantsRegistry`](./invariants.md#invariant-registry). The value of the ivnariant should be equal to a predicted value defined in the module. Should the value be different than the predicted one, special logic defined in the invariant registry will be triggered (usually the chain is halted). This is useful to make sure no critical bug goes unoticed and produces long-lasting effects that would be hard to fix. -- With the module manager, set the order of execution between the `InitGenesis`, `BegingBlocker` and `EndBlocker` functions of each of the [application's modules](#application-module-interface). Note that not all modules implement these functions. -- Set the remainer of application's parameters: - + [`InitChainer`](#initchainer): used to initialize the application when it is first started. - + [`BeginBlocker`, `EndBlocker`](#beginblocker-and-endlbocker): called at the beginning and the end of every block). - + [`anteHandler`](#baseapp.md#antehandler): used to handle fees and signature verification. -- Mount the stores. -- Return the application. - -Note that this function only creates an instance of the app, while the actual state is either carried over from the `~/.appd/data` folder if the node is restarted, or generated from the genesis file if the node is started for the first time. - -You can see an example of application constructor [here](https://github.com/cosmos/gaia/blob/master/app/app.go#L110-L222). - -### InitChainer - -The `InitChainer` is a function that initializes the state of the application from a [genesis file](./genesis.md) (i.e. token balances of genesis accounts). It is called when the application receives the `InitChain` message from the Tendermint engine, which happens when the node is started at `appBlockHeight == 0` (i.e. on genesis). The application must set the `InitChainer` in its constructor via the [`SetInitChainer`](https://godoc.org/github.com/cosmos/cosmos-sdk/baseapp#BaseApp.SetInitChainer) method. - -In general, the `InitChainer` is mostly composed of the `InitGenesis` function of each of the application's modules. This is done by calling the `InitGenesis` function of the module manager, which in turn will call the `InitGenesis` function of each of the modules it contains. Note that the order in which the modules' `InitGenesis` functions must be called has to be set in the module manager using the `SetOrderInitGenesis` method. This is done in the [application's constructor](#application-constructor), and the `SetOrderInitGenesis` has to be called before the `SetInitChainer`. - -You can see an example of an `InitChainer` [here](https://github.com/cosmos/gaia/blob/master/app/app.go#L235-L239). - -### BeginBlocker and EndBlocker - -The SDK offers developers the possibility to implement automatic execution of code as part of their application. This is implemented through two function called `BeginBlocker` and `EndBlocker`. They are called when the application receives respectively the `BeginBlock` and `EndBlock` messages from the Tendermint engine, which happens at the beginning and at the end of each block. The application must set the `BeginBlocker` and `EndBlocker` in its constructor via the [`SetBeginBlocker`](https://godoc.org/github.com/cosmos/cosmos-sdk/baseapp#BaseApp.SetBeginBlocker) and [`SetEndBlocker`](https://godoc.org/github.com/cosmos/cosmos-sdk/baseapp#BaseApp.SetEndBlocker) methods. - -In general, the `BeginBlocker` and `EndBlocker` functions are mostly composed of the `BeginBlock` and `EndBlock` functions of each of the application's modules. This is done by calling the `BeginBlock` and `EndBlock` functions of the module manager, which in turn will call the `BeginBLock` and `EndBlock` functions of each of the modules it contains. Note that the order in which the modules' `BegingBlock` and `EndBlock` functions must be called has to be set in the module manager using the `SetOrderBeginBlock` and `SetOrderEndBlock` methods respectively. This is done in the [application's constructor](#application-constructor), and the `SetOrderBeginBlock` and `SetOrderEndBlock` methods have to be called before the `SetBeginBlocker` and `SetEndBlocker` functions. - -As a sidenote, it is important to remember that application-specific blockchains are deterministic. Developers must be careful not to introduce non-determinism in `BeginBlocker` or `EndBlocker`, and must also be careful not to make them too computationally expensive, as [gas](./fees-signature.md/gas) does not constrain the cost of `BeginBlocker` and `EndBlocker` execution. - -You can see an example of `BeginBlocker` and `EndBlocker` functions [here](https://github.com/cosmos/gaia/blob/master/app/app.go#L224-L232). - -### Register Codec - -The `MakeCodec` function is the last important function of the `app.go` file. The goal of this function is to instantiate a codec `cdc` (e.g. [amino](./amino.md)) initiliaze the codec of the SDK and each of the application's modules using the `RegisterCodec` function. - -To register the application's modules, the `MakeCodec` function calls `RegisterCodec` on `ModuleBasics`. `ModuleBasics` is a [basic manager](./modules.md#basic-manager) which lists all of the application's modules. It is instanciated in the `init()` function, and only serves to easily register non-dependant elements of application's modules (such as codec). To learn more about the basic module manager, click [here](./modules.md#basic-manager). - -You can see an example of a `MakeCodec` [here](https://github.com/cosmos/gaia/blob/master/app/app.go#L64-L70) - -## Modules - -Modules are the heart and soul of an SDK application. They can be considered as state-machines within the state-machine. When a transaction is relayed from the underlying Tendermint engine via the ABCI to the application, it is routed by `baseapp` to the appropriate module in order to be processed. This paradigm enables developers to easily build complex state-machines, as most of the modules they need often already exist. For developers, most of the work involved in building an SDK application revolves around building custom modules required by their application that do not exist, and integrating them with modules that do already exist into one coherent application. In the application directory, the standard practice is to store modules in the `x/` folder (not to be confused with the SDK's `x/` folder, which contains already-built modules). - -To learn more about modules, [click here](./modules.md) - -### Application Module Interface - -Modules implement two interfaces defined in the Cosmos SDK, [`AppModuleBasic`](https://github.com/cosmos/cosmos-sdk/blob/master/types/module/module.go#L44-L57) and [`AppModule`](https://github.com/cosmos/cosmos-sdk/blob/master/types/module/module.go#L44-L57). The former implements basic non-dependant elements of the module, such as the `codec`, while the latter handles the bulk of the module methods (including methods that require references to other modules' `keeper`s). Both the `AppModule` and `AppModuleBasic` types are defined in a file called `./module.go`. - -`AppModule` exposes a collection of useful methods on the module that facilitates the composition of modules into a coherent application. Important methods include: - -- `Route()` and `QueryRoute()`: These methods the name of the route and querier route for the module, for [messages](#message-types) to be routed to the module's [`handler`](#handler) and queries to be routes to the module's [`querier`](#querier). -- `NewHandler()` and `NewQuerierHandler()`: These methods return a `handler` and `querierHandler` respectively, in order to process a message or a query once they are routed. -- `BeginBlock()`, `EndBlock()` and `InitGenesis()`: These methods are executed respectively at the beginning of each block, at the end of each block and at the start of the chain. They implement special logic the module requires to be triggered during those events. For example, the `EndBlock` function is frequently used by modules where voting occurs to tally the result of the votes. -- `RegisterInvariants()`: This method registers the [invariants](./invariants.md) for the module. Invariants are checked at the end of every block to make sure no unpredicted behaviour is occuring. - -`AppModule`'s methods are called from the `module manager`(./modules.md#module-manager), which manages the application's collection of modules. - -To learn more about the application module interface, [click here](./modules.md#application-module-interface). - -### Message Types - -A message is a custom type defined by each module that implements the [`message`](https://github.com/cosmos/cosmos-sdk/blob/master/types/tx_msg.go#L8-L29) interface. Each `transaction` contains one or multiple `messages`. When a valid block of transactions is received by the full-node, Tendermint relays each one to the application via [`DeliverTx`](https://tendermint.com/docs/app-dev/abci-spec.html#delivertx). Then, the application handles the transaction: - -1. Upon receiving the transaction, the application first unmarshalls it from `[]bytes`. -2. Then, it verifies a few things about the transaction like [fee payment and signatures](#fees-signature.md) before extracting the message(s) contained in the transaction. -3. With the [`Type()`](https://github.com/cosmos/cosmos-sdk/blob/master/types/tx_msg.go#L16) method, `baseapp` is able to know which modules defines the message. It is then able to route it to the appropriate module's [handler](#handler) in order for the message to be processed. -4. If the message is successfully processed, the state is updated. - -For a more detailed look at a transaction lifecycle, click [here](./tx-lifecycle.md). - -Module developers create custom message types when they build their own module. The general practice is to prefix the type declaration of the message with `Msg`. For example, the message type [`MsgSend`](https://github.com/cosmos/cosmos-sdk/blob/master/x/bank/types/msgs.go#L10-L15) allows users to transfer tokens. It is processed by the handler of the `bank` module, which ultimately calls the `keeper` of the `auth` module in order to update the state. - -To learn more about messages, [click here](./tx-msgs.md). - -### Handler - -The `handler` refers to the part of the module responsible for processing the message after it is routed by `baseapp`. `handler` functions of modules (except those of the `auth` module) are only executed if the transaction is relayed from Tendermint by the `DeliverTx` ABCI message. If the transaction is realyed by `CheckTx`, only stateless checks and fee-related (i.e. `auth` module-related) stateful checks are performed. To better understand the difference between `DeliverTx`and `CheckTx`, as well as the difference between stateful and stateless checks, click [here](./tx-lifecycle.md). - -The handler of a module is generally defined in a file called `handler.go` and consists of: - -- A **switch function** `NewHandler` to route the message to the appropriate handler function. This function returns a `handler` function, and is registered in the [`AppModule`](#application-module-interface) to be used in the application's module manager to initialize the [application's router](./baseapp.md#routing). See an example of such a switch [here](https://github.com/cosmos/sdk-application-tutorial/blob/master/x/nameservice/handler.go#L10-L22). -- **One handler function for each message type defined by the module**. Developers write the message processing logic in these functions. This generally involves doing stateful checks to ensure the message is valid and calling [`keeper`](#keeper)'s methods to update the state. - -Handler functions return a result of type [`sdk.Result`](https://github.com/cosmos/cosmos-sdk/blob/master/types/result.go#L14-L37), which informs the application on wether the message was succesfully processed and. - -To learn more about handlers, [click here](./handler.md). - -### Keeper - -`Keepers` are the gatekeepers of their module's store(s). To read or write in a module's store, it is mandatory to go through one of its `keeper`'s methods. This is ensured by the [object-capabilities](./ocap.md) model of the Cosmos SDK. Only objects that hold the key to a store can access it, and only the module's `keeper` should hold the key(s) to the module's store(s). - -`Keepers` are generally defined in a file called `keeper.go`. It contains the `keeper`'s type definition and methods. - -The `keeper` type definition generally consists of: - -- **Key(s)** to the module's store(s) in the multistore. -- Reference to **other module's `keepers`**. Only needed if the `keeper` needs to access other module's store(s) (either to read or write from them). -- A reference to the application's **codec**. The `keeper` needs it to marshal structs before storing them, or to unmarshal them when it retrieves them, because stores only accept `[]bytes` as value. - -Along with the type definition, the next important component of the `keeper.go` file is the `keeper`'s constructor function, `NewKeeper`. This function instantiates a new `keeper` of the type defined above, with a `codec`, store `keys` and potentially references to other modules' `keeper`s as parameters. The `NewKeeper` function is called from the [application's constructor](#constructor-function). - -The rest of the file defines the `keeper`'s methods, primarily getters and setters. You can check an example of a `keeper` implementation [here](https://github.com/cosmos/sdk-application-tutorial/blob/master/x/nameservice/keeper.go). - -To learn more about `keepers`, [click here](./keeper.md). - -### Querier - -`Queriers` are very similar to `handlers`, except they serve user queries to the state as opposed to processing transactions. A query is initiated from an [interface](#intefaces) by an end-user who provides a `queryRoute` and some `data`. The query is then routed to the correct application's `querier` by `baseapp`'s [`handleQueryCustom`](https://github.com/cosmos/cosmos-sdk/blob/master/baseapp/baseapp.go#L519-L556) method using `queryRoute`. - -The `Querier` of a module are defined in a file called `querier.go`, and consists of: - -- A **switch function** `NewQuerier` to route the query to the appropriate `querier` function. This function returns a `querier` function, and is is registered in the [`AppModule`](#application-module-interface) to be used in the application's module manager to initialize the [application's query router](./baseapp.md#query-routing). See an example of such a switch [here](https://github.com/cosmos/sdk-application-tutorial/blob/master/x/nameservice/querier.go#L21-L34). -- - **One querier function for each data type defined by the module that needs to be queryable**. Developers write the query processing logic in these functions. This generally involves calling [`keeper`](#keeper)'s methods to query the state and marshalling it to JSON. See an example of `querier` functions [here](https://github.com/cosmos/sdk-application-tutorial/blob/master/x/nameservice/querier.go#L37-L101). - -To learn more about `queriers`, [click here](./querier.md). - -### Command-Line and REST Interfaces - -Each module defines command-line commands and REST routes to be exposed to end-user via the [application's interfaces](#application-interfaces). This enables end-users to create messages of the types defined in the module, or to query the subset of the state managed by the module. - -#### CLI - -Generally, the commands related to a module are defined in a folder called `client/cli` in the module's folder. The CLI divides commands in two category, transactions and queries, defined in `client/cli/tx.go` and `client/cli/query.go` respectively. Both commands are built on top of the [Cobra Library](https://github.com/spf13/cobra): - -- Transactions commands let users generate new transactions so that they can be included in a block and eventually update the state. One command should be created for each [message type](#message-types) defined in the module. The command calls the constructor of the message with the parameters provided by the end-user, and wraps it into a transaction. The SDK handles signing and the addition of other transaction metadata. See examples of transactions commands [here](https://github.com/cosmos/sdk-application-tutorial/blob/master/x/nameservice/client/cli/tx.go). -- Queries let users query the subset of the state defined by the module. Query commands forward queries to the [application's query router](./baseapp.md#query-routing), which routes them to the appropriate [querier](#querier) the `queryRoute` parameter supplied. See examples of query commands [here](https://github.com/cosmos/sdk-application-tutorial/blob/master/x/nameservice/client/cli/query.go). - -To learn more about modules CLI, [click here](./module-interfaces.md#cli). - -#### REST - -The module's REST interface lets users generate transactions and query the state through REST calls to the application's [light-client daemon](./node.md#lcd). REST routes are defined in a file `client/rest/rest.go`, which is composed of: - -- A `RegisterRoutes` function, which registers each route defined in the file. This function is called from the [main application's interface](#application-interfaces) for each module used within the application. The router used in the SDK is [Gorilla's mux](https://github.com/gorilla/mux). -- Custom request type definitions for each query or transaction creation function that needs to be exposed. These custom request types build on the [base `request` type](https://github.com/cosmos/cosmos-sdk/blob/master/types/rest/rest.go#L32-L43) of the Cosmos SDK. -- One handler function for each request that can be routed to the given module. These functions implement the core logic necessary to serve the request. - -See an example of a module's `rest.go` file [here](https://github.com/cosmos/sdk-application-tutorial/blob/master/x/nameservice/client/rest/rest.go). - -To learn more about modules REST interface, [click here](./module-interfaces.md#rest). - -## Application Interface - -Interfaces let end-users interact with full-node clients. This means querying data from the full-node or creating and sending new transactions to be relayed by the full-node and eventually included in a block. - -The main interface is the [Command-Line Interface](./interfaces.md#cli). The CLI of an SDK application is built by aggregating [CLI commands](#cli) defined in each of the modules used by the application. The CLI of an application generally has the `-cli` suffix (e.g. `appcli`), and defined in a file called `cmd/appcli/main.go`. The file contains: - -- **A `main()` function**, which is executed to build the `appcli` interface client. This function prepares each command and adds them to the `rootCmd` before building them. At the root of `appCli`, the function adds generic commands like `status`, `keys` and `config`, query commands, tx commands and `rest-server`. -- **Query commands** are added by calling the `queryCmd` function, also defined in `appcli/main.go`. This function returns a Cobra command that contains the query commands defined in each of the application's modules (passed as an array of `sdk.ModuleClients` from the `main()` function), as well as some other lower level query commands such as block or validator queries. Query command are called by using the command `appcli query [query]` of the CLI. -- **Transaction commands** are added by calling the `txCmd` function. Similar to `queryCmd`, the function returns a Cobra command that contains the tx commands defined in each of the application's modules, as well as lower level tx commands like transaction signing or broadcasting. Tx commands are called by using the command `appcli tx [tx]` of the CLI. -- **A `registerRoutes` function**, which is called from the `main()` function when initializing the [application's light-client daemon (LCD)](./node.md#lcd) (i.e. `rest-server`). `registerRoutes` calls the `RegisterRoutes` function of each of the application's module, thereby registering the routes of the module to the lcd's router. The LCD can be started by running the following command `appcli rest-server`. - -See an example of an application's main command-line file [here](https://github.com/cosmos/sdk-application-tutorial/blob/master/cmd/nscli/main.go). - -To learn more about interfaces, [click here](./interfaces.md) - -## Dependencies and Makefile - - - -## Next - -Learn more about the [Lifecycle of a transaction](./tx-lifecycle.md). diff --git a/docs/concepts/tx-msgs.md b/docs/concepts/tx-msgs.md new file mode 100644 index 000000000000..fde1963e3c2a --- /dev/null +++ b/docs/concepts/tx-msgs.md @@ -0,0 +1,5 @@ +# Transactions and Messages + +## Transactions + +## Messages diff --git a/docs/core/baseapp.md b/docs/core/baseapp.md index 6c3d2dd9e506..7f8214b34e4c 100644 --- a/docs/core/baseapp.md +++ b/docs/core/baseapp.md @@ -7,7 +7,7 @@ ## Synopsis -This document describes `baseapp`, the abstraction that implements most of the common functionalities of an SDK application. +This document describes `baseapp`, the abstraction that implements most of the common functionalities of an SDK application. - [Introduction](#introduction) - [Type Definition](#type-definition) @@ -17,7 +17,7 @@ This document describes `baseapp`, the abstraction that implements most of the c - [Main ABCI Messages](#abci) + [CheckTx](#checktx) + [DeliverTx](#delivertx) -- [RunTx, AnteHandler and RunMsgs](#runtx-antehandler-and-runmsgs) +- [RunTx, AnteHandler and RunMsgs](#runtx-,antehandler-and-runmsgs) + [RunTx](#runtx) + [AnteHandler](#antehandler) + [RunMsgs](#runmsgs) @@ -28,18 +28,21 @@ This document describes `baseapp`, the abstraction that implements most of the c + [Commit](#commit) + [Info](#info) + [Query](#query) - + + + + ## Introduction `baseapp` is an abstraction that implements the core of an SDK application, namely: -- The [Application-Blockchain Interface](#abci), for the state-machine to communicate with the underlying consensus engine (e.g. Tendermint). -- A [Router](#routing), to route [messages](./tx-msgs.md) and [queries](./querier.md) to the appropriate [module](../building-modules/intro.md). -- Different [states](#states), as the state-machine can have different parallel states updated based on the ABCI message received. +- The [Application-Blockchain Interface](#abci), for the state-machine to communicate with the underlying consensus engine (e.g. Tendermint). +- A [Router](#routing), to route [messages](./tx-msgs.md) and [queries](./querier.md) to the appropriate [module](../building-modules/modules.md). +- Different [states](#states), as the state-machine can have different parallel states updated based on the ABCI message received. The goal of `baseapp` is to provide a boilerplate SDK application that developers can easily extend to build their own custom application. Usually, developers will create a custom type for their application, like so: -```go +```go type app struct { *bam.BaseApp // reference to baseapp cdc *codec.Codec @@ -52,24 +55,24 @@ type app struct { } ``` -Extending the application with `baseapp` gives the former access to all of `baseapp`'s methods. This allows developers to compose their custom application with the modules they want, while not having to concern themselves with the hard work of implementing the ABCI, the routing and state management logic. +Extending the application with `baseapp` gives the former access to all of `baseapp`'s methods. This allows developers to compose their custom application with the modules they want, while not having to concern themselves with the hard work of implementing the ABCI, the routing and state management logic. ## Type Definition The [`baseapp` type](https://github.com/cosmos/cosmos-sdk/blob/master/baseapp/baseapp.go#L45-L91) holds many important parameters for any Cosmos SDK based application. Let us go through the most important components. -*Note: Not all parameters are described, only the most important ones. Refer to the [type definition](https://github.com/cosmos/cosmos-sdk/blob/master/baseapp/baseapp.go#L45-L91) for the full list* +*Note: Not all parameters are described, only the most important ones. Refer to the [type definition](https://github.com/cosmos/cosmos-sdk/blob/master/baseapp/baseapp.go#L45-L91) for the full list* First, the important parameters that are initialized during the initialization of the application: -- A [`CommitMultiStore`](./store.md#commit-multi-store). This is the main store of the application, which holds the canonical state that is committed at the [end of each block](#commit). This store is **not** cached, meaning it is not used to update the application's intermediate (un-committed) states. The `CommitMultiStore` is a multi-store, meaning a store of stores. Each module of the application uses one or multiple `KVStores` in the multi-store to persist their subset of the state. +- A [`CommitMultiStore`](./store.md#commit-multi-store). This is the main store of the application, which holds the canonical state that is committed at the [end of each block](#commit). This store is **not** cached, meaning it is not used to update the application's intermediate (un-committed) states. The `CommitMultiStore` is a multi-store, meaning a store of stores. Each module of the application uses one or multiple `KVStores` in the multi-store to persist their subset of the state. - A [database](./store.md#database) `db`, which is used by the `CommitMultiStore` to handle data storage. -- A [router](#message-routing). The `router` facilitates the routing of [messages](../building-modules/messages-and-queries.md#messages) to the appropriate module for it to be processed. -- A [query router](#query-routing). The `query router` facilitates the routing of [queries](../building-modules/messages-and-queries.md#queries) to the appropriate module for it to be processed. +- A [router](#messages). The `router` facilitates the routing of [messages](./tx-msgs.md) to the appropriate module for it to be processed. +- A [query router](#queries). The `query router` facilitates the routing of [queries](./querier.md) to the appropriate module for it to be processed. - A [`txDecoder`](https://godoc.org/github.com/cosmos/cosmos-sdk/types#TxDecoder), used to decode transaction `[]byte` relayed by the underlying Tendermint engine. - A [`baseKey`], to access the [main store](./store.md#main-store) in the `CommitMultiStore`. The main store is used to persist data related to the core of the application, like consensus parameters. - A [`anteHandler`](#antehandler), to handle signature verification and fee paiement when a transaction is received. -- An [`initChainer`](../basics/app-anatomy.md#initchainer), [`beginBlocker` and `endBlocker`](../basics/app-anatomy.md#beginblocker-and-endblocker), which are the functions executed when the application received the [InitChain], [BeginBlock] and [EndBlock] messages from the underlying Tendermint engine. +- An [`initChainer`](./app-anatomy.md#initchainer), [`beginBlocker` and `endBlocker`](./app-anatomy.md#beginblocker-and-endblocker), which are the functions executed when the application received the [InitChain], [BeginBlock] and [EndBlock] messages from the underlying Tendermint engine. Then, parameters used to define [volatile states](#volatile-states) (i.e. cached states): @@ -84,13 +87,17 @@ Finally, a few more important parameterd: ## Constructor -`NewBaseApp(name string, logger log.Logger, db dbm.DB, txDecoder sdk.TxDecoder, options ...func(*BaseApp),)` is the constructor function for `baseapp`. It is called from the [application's constructor function](../basics/app-anatomy.md#constructor-function) each time the full-node is started. +`NewBaseApp(name string, logger log.Logger, db dbm.DB, txDecoder sdk.TxDecoder, options ...func(*BaseApp),)` is the constructor function for `baseapp`. It is called from the [application's constructor function](../basics/app-anatomy.md#constructor-function) each time the full-node is started. + +`baseapp`'s constructor function is pretty straightforward. The only thing worth noting is the possibility to add additional [`options`](https://github.com/cosmos/cosmos-sdk/blob/master/baseapp/options.go) to `baseapp` by passing `options functions` to the constructor function, which will execute them in order. `options` are generally `setter` functions for important parameters, like `SetPruning()` to active pruning or `SetMinGasPrices()` to set the node's `min-gas-prices`. + +A list of `options` examples can be found [here](https://github.com/cosmos/cosmos-sdk/blob/master/baseapp/options.go). Naturally, developers can add additional `options` based on their application's needs. + +## Constructor -`baseapp`'s constructor function is pretty straightforward. The only thing worth noting is the possibility to add additional [`options`](https://github.com/cosmos/cosmos-sdk/blob/master/baseapp/options.go) to `baseapp` by passing `options functions` to the constructor function, which will execute them in order. `options` are generally `setters` function for important parameters, like `SetPruning()` to active pruning or `SetMinGasPrices()` to set the node's `min-gas-prices`. -A list of `options` example can be found [here](https://github.com/cosmos/cosmos-sdk/blob/master/baseapp/options.go). Naturally, developers can add additional `options` based on their application's needs. -## States +## States `baseapp` handles various parallel states for different purposes. There is the [main state](#main-state), which is the canonical state of the application, and volatile states like [`checkState`](#checkState) and [`deliverState`](#deliverstate), which are used to handle temporary states inbetween updates of the main state. @@ -120,7 +127,54 @@ DeliverTx(tx1) | | | +----------------------+ +----------------------+ | | | | | DeliverState(t)(1) | | | | | +----------------------+ | | -DeliverTx(tx2) | | | | | +DeliverTx(tx2) | | | | | + | | v | | + | | +----------------------+ | | + | | | DeliverState(t)(2) | | | + | | +----------------------+ | | +DeliverTx(tx3) | | | | | + | | v | | + | | +----------------------+ | | + | | | DeliverState(t)(3) | | | + +----------------------+ +----------------------+ +----------------------+ +Commit() | | | + v v v + +----------------------+ +----------------------+ +----------------------+ + | CheckState(t+1)(0) | | DeliverState(t+1)(0) | | QueryState(t+1) | + +----------------------+ | | | | + . . . + . . . + . . . + +``` + +``` + To perform stateful checks To execute state To answer queries + on received transactions transitions during DeliverTx about last-committed state + +----------------------+ +----------------------+ +----------------------+ + | CheckState(t)(0) | | DeliverState(t)(0) | | QueryState(t) | + +----------------------+ | | | | +CheckTx(tx1) | | | | | + v | | | | + +----------------------+ | | | | + | CheckState(t)(1) | | | | | + +----------------------+ | | | | +CheckTx(tx2) | | | | | + v | | | | + +----------------------+ | | | | + | CheckState(t)(2) | | | | | + +----------------------+ | | | | +CheckTx(tx3) | | | | | + v | | | | + +----------------------+ | | | | + | CheckState(t)(3) | | | | | + +----------------------+ +----------------------+ | | +DeliverTx(tx1) | | | | + v v | | + +----------------------+ +----------------------+ | | + | | | DeliverState(t)(1) | | | + | | +----------------------+ | | +DeliverTx(tx2) | | | | | | | v | | | | +----------------------+ | | | | | DeliverState(t)(2) | | | @@ -138,12 +192,12 @@ Commit() | | . . . . . . . . . - + ``` ### Main State -The main state is the canonical state of the application. It is initialized on [`InitChain`](#initchain and updated on [`Commit`](#abci-commit) at the end of each block. +The main state is the canonical state of the application. It is initialized on [`InitChain`](#initchain and updated on [`Commit`](#abci-commit) at the end of each block. ``` +--------+ +--------+ @@ -159,13 +213,13 @@ The main state is held by `baseapp` in a structure called the [`CommitMultiStore Volatile - or cached - states are used in between [`Commit`s](#commit) to manage temporary states. They are reset to the latest version of the main state after it is committed. There are two main volatile states: -- `checkState`: This cached state is initialized during [`InitChain`](#initchain), updated during [`CheckTx`](#abci-checktx) when an unconfirmed transaction is received, and reset to the [main state](#main-state) on [`Commit`](#abci-commit). +- `checkState`: This cached state is initialized during [`InitChain`](#initchain), updated during [`CheckTx`](#abci-checktx) when an unconfirmed transaction is received, and reset to the [main state](#main-state) on [`Commit`](#abci-commit). - `deliverState`: This cached state is initialized during [`BeginBlock`](#beginblock), updated during [`DeliverTx`](#abci-delivertx) when a transaction included in a block is processed, and reset to the [main state](#main-state) on [`Commit`](#abci-commit). Both `checkState` and `deliverState` are of type [`state`](https://github.com/cosmos/cosmos-sdk/blob/master/baseapp/baseapp.go#L973-L976), which includes: -- A [`CacheMultiStore`](https://github.com/cosmos/cosmos-sdk/blob/master/store/cachemulti/store.go), which is a cached version of the main `CommitMultiStore`. A new version of this store is committed at the end of each successful `CheckTx`/`DeliverTx` execution. -- A [`Context`](./context.md), which carries general information (like raw transaction size, block height, ...) that might be needed in order to process the transaction during `CheckTx` and `DeliverTx`. The `context` also holds a cache-wrapped version of the `CacheMultiStore`, so that the `CacheMultiStore` can maintain the correct version even if an internal step of `CheckTx` or `DeliverTx` fails. +- A [`CacheMultiStore`](https://github.com/cosmos/cosmos-sdk/blob/master/store/cachemulti/store.go), which is a cached version of the main `CommitMultiStore`. A new version of this store is committed at the end of each successful `CheckTx`/`DeliverTx` execution. +- A [`Context`](./context.md), which carries general information (like raw transaction size, block height, ...) that might be needed in order to process the transaction during `CheckTx` and `DeliverTx`. The `context` also holds a cache-wrapped version of the `CacheMultiStore`, so that the `CacheMultiStore` can maintain the correct version even if an internal step of `CheckTx` or `DeliverTx` fails. ## Routing @@ -175,24 +229,24 @@ When messages and queries are received by the application, they must be routed t [`Message`s](#../building-modules/messages-and-queries.md#messages) need to be routed after they are extracted from transactions, which are sent from the underlying Tendermint engine via the [`CheckTx`](#checktx) and [`DeliverTx`](#delivertx) ABCI messages. To do so, `baseapp` holds a [`router`](https://github.com/cosmos/cosmos-sdk/blob/master/baseapp/router.go) which maps `paths` (`string`) to the appropriate module [`handler`](./handler.md). Usually, the `path` is the name of the module. -The application's `router` is initilalized with all the routes using the application's [module manager](../building-modules/module-manager.md), which itself is initialized with all the application's modules in the application's [constructor](../basics/app-anatomy.md#app-constructor). +The application's `router` is initilalized with all the routes using the application's [module manager](./modules.md#module-manager), which itself is initialized with all the application's modules in the application's [constructor](../basics/app-anatomy.md#app-constructor). ### Query Routing -Similar to `message`s, [`queries`](../building-modules/messages-and-queries.md#queries) need to be routed to the appropriate module's [querier](../building-modules/querier.md). To do so, `baseapp` holds a [`query router`](https://github.com/cosmos/cosmos-sdk/blob/master/baseapp/queryrouter.go), which maps `paths` (`string`) to the appropriate module `querier`. Usually, the `path` is the name of the module. +Similar to messages, queries need to be routed to the appropriate module's [querier](./querier.md). To do so, `baseapp` holds a [`query router`](https://github.com/cosmos/cosmos-sdk/blob/master/baseapp/queryrouter.go), which maps `paths` (`string`) to the appropriate module [`querier`](./querier.md). Usually, the `path` is the name of the module. Just like the `router`, the `query router` is initilalized with all the query routes using the application's [module manager](../building-modules/module-manager.md), which itself is initialized with all the application's modules in the application's [constructor](../basics/app-anatomy.md#app-constructor). ## Main ABCI Messages -The [Application-Blockchain Interface](https://tendermint.com/docs/spec/abci/) (ABCI) is a generic interface that connects a state-machine with a consensus engine to form a functional full-node. It can be wrapped in any language, and needs to be implemented by each application-specific blockchain built on top of an ABCI-compatible consensus engine like Tendermint. +The [Application-Blockchain Interface](https://tendermint.com/docs/spec/abci/) (ABCI) is a generic interface that connects a state-machine with a consensus engine to form a functional full-node. It can be wrapped in any language, and needs to be implemented by each application-specific blockchain built on top of an ABCI-compatible consensus engine like Tendermint. The consensus engine handles two main tasks: - The networking logic, which mainly consists in gossiping block parts, transactions and consensus votes. -- The consensus logic, which results in the deterministic ordering of transactions in the form of blocks. +- The consensus logic, which results in the deterministic ordering of transactions in the form of blocks. -It is **not** the role of the consensus engine to define the state or the validity of transactions. Generally, transactions are handled by the consensus engine in the form of `[]bytes`, and relayed to the application via the ABCI to be decoded and processed. At keys moments in the networking and consensus processes (e.g. beginning of a block, commit of a block, reception of an unconfirmed transaction, ...), the consensus engine emits ABCI messages for the state-machine to act on. +It is **not** the role of the consensus engine to define the state or the validity of transactions. Generally, transactions are handled by the consensus engine in the form of `[]bytes`, and relayed to the application via the ABCI to be decoded and processed. At keys moments in the networking and consensus processes (e.g. beginning of a block, commit of a block, reception of an unconfirmed transaction, ...), the consensus engine emits ABCI messages for the state-machine to act on. Developers building on top of the Cosmos SDK need not implement the ABCI themselves, as `baseapp` comes with a built-in implementation of the interface. Let us go through the main ABCI messages that `baseapp` implements: [`CheckTx`](#checktx) and [`DeliverTx`](#delivertx) @@ -204,43 +258,43 @@ Developers building on top of the Cosmos SDK need not implement the ABCI themsel 1. Extract the `message`s from the transaction. 2. Perform *stateless* checks by calling `ValidateBasic()` on each of the `messages`. This is done first, as *stateless* checks are less computationally expensive than *stateful* checks. If `ValidateBasic()` fail, `CheckTx` returns before running *stateful* checks, which saves resources. -3. Perform non-module related *stateful* checks on the account. This step is mainly about checking that the `message` signatures are valid, that enough fees are provided and that the sending account has enough funds to pay for said fees. Note that no precise [`gas`](./accounts-fees-gas.md#gas) counting occurs here, as `message`s are not processed. Usually, the [`anteHandler`](./accounts-fees-gas.md#antehandler) will check that the `gas` provided with the transaction is superior to a minimum reference gas amount based on the raw transaction size, in order to avoid spam with transactions that provide 0 gas. -4. Ensure that a [`Route`](#message-routing) exists for each `message`, but do **not** actually process `message`s. `Message`s only need to be processed when the canonical state need to be updated, which happens during `DeliverTx`. +3. Perform non-module related *stateful* checks on the account. This step is mainly about checking that the `message` signatures are valid, that enough fees are provided and that the sending account has enough funds to pay for said fees. Note that no precise [`gas`](./accounts-fees.md#gas) counting occurs here, as `message`s are not processed. Usually, the [`anteHandler`](./accounts-fees.md#antehandler) will check that the `gas` provided with the transaction is superior to a minimum reference gas amount based on the raw transaction size, in order to avoid spam with transactions that provide 0 gas. +4. Ensure that a [`Route`](#message-routing) exists for each `message`, but do **not** actually process `message`s. `Message`s only need to be processed when the canonical state need to be updated, which happens during `DeliverTx`. -Steps 2. and 3. are performed by the [`anteHandler`](./accounts-fees-gas.md#antehandler) in the [`RunTx`](#runtx-antehandler-and-runmsgs) function, which `CheckTx` calls with the `runTxModeCheck` mode. During each step of `CheckTx`, a special [volatile state](#volatile-states) called `checkState` is updated. This state is used to keep track of the temporary changes triggered by the `CheckTx` calls of each transaction without modifying the [main canonical state](#main-state) . For example, when a transaction goes through `CheckTx`, the transaction's fees are deducted from the sender's account in `checkState`. If a second transaction is received from the same account before the first is processed, and the account has consumed all its funds in `checkState` during the first transaction, the second transaction will fail `CheckTx` and be rejected. In any case, the sender's account will not actually pay the fees until the transaction is actually included in a block, because `checkState` never gets committed to the main state. `checkState` is reset to the latest state of the main state each time a blocks gets [committed](#commit). +Steps 2. and 3. are performed by the [`anteHandler`](./accounts-fees.md#antehandler) in the [`RunTx`](#runtx-,antehandler-and-runmsgs) function, which `CheckTx` calls with the `runTxModeCheck` mode. During each step of `CheckTx`, a special [volatile state](#volatile-states) called `checkState` is updated. This state is used to keep track of the temporary changes triggered by the `CheckTx` calls of each transaction without modifying the [main canonical state](#main-state) . For example, when a transaction goes through `CheckTx`, the transaction's fees are deducted from the sender's account in `checkState`. If a second transaction is received from the same account before the first is processed, and the account has consumed all its funds in `checkState` during the first transaction, the second transaction will fail `CheckTx` and be rejected. In any case, the sender's account will not actually pay the fees until the transaction is actually included in a block, because `checkState` never gets committed to the main state. `checkState` is reset to the latest state of the main state each time a blocks gets [committed](#commit). `CheckTx` returns a response to the underlying consensus engine of type [`abci.ResponseCheckTx`](https://tendermint.com/docs/spec/abci/abci.html#messages). The response contains: -- `Code (uint32)`: Response Code. `0` if successful. +- `Code (uint32)`: Response Code. `0` if successful. - `Data ([]byte)`: Result bytes, if any. - `Log (string):` The output of the application's logger. May be non-deterministic. - `Info (string):` Additional information. May be non-deterministic. -- `GasWanted (int64)`: Amount of gas requested for transaction. It is provided by users when they generate the transaction. -- `GasUsed (int64)`: Amount of gas consumed by transaction. During `CheckTx`, this value is computed by multiplying the standard cost of a transaction byte by the size of the raw transaction (click [here](https://github.com/cosmos/cosmos-sdk/blob/master/x/auth/ante.go#L101) for an example). +- `GasWanted (int64)`: Amount of gas requested for transaction. It is provided by users when they generate the transaction. +- `GasUsed (int64)`: Amount of gas consumed by transaction. During `CheckTx`, this value is computed by multiplying the standard cost of a transaction byte by the size of the raw transaction (click [here](https://github.com/cosmos/cosmos-sdk/blob/master/x/auth/ante.go#L101) for an example). - `Tags ([]cmn.KVPair)`: Key-Value tags for filtering and indexing transactions (eg. by account). - `Codespace (string)`: Namespace for the Code. ### DeliverTx -When the underlying consensus engine receives a block proposal, each transaction in the block needs to be processed by the application. To that end, the underlying consensus engine sends a `DeliverTx` message to the application for each transaction in a sequential order. +When the underlying consensus engine receives a block proposal, each transaction in the block needs to be processed by the application. To that end, the underlying consensus engine sends a `DeliverTx` message to the application for each transaction in a sequential order. -Before the first transaction of a given block is processed, a [volatile state](#volatile-states) called `deliverState` is intialized during [`BeginBlock`](#beginblock). This state is updated each time a transaction is processed via `DeliverTx`, and committed to the [main state](#main-state) when the block is [committed](#commit), after what is is set to `nil`. +Before the first transaction of a given block is processed, a [volatile state](#volatile-states) called `deliverState` is intialized during [`BeginBlock`](#beginblock). This state is updated each time a transaction is processed via `DeliverTx`, and committed to the [main state](#main-state) when the block is [committed](#commit), after what is is set to `nil`. `DeliverTx` performs the **exact same steps as `CheckTx`**, with a little caveat at step 3 and the addition of a fifth step: -3. The `anteHandler` does **not** check that the transaction's `gas-prices` is sufficient. That is because the `min-gas-prices` value `gas-prices` is checked against is local to the node, and therefore what is enough for one full-node might not be for another. This means that the proposer can potentially include transactions for free, although they are not incentivised to do so, as they earn a bonus on the total fee of the block they propose. -5. For each `message` in the transaction, route to the appropriate module's [`handler`](../building-modules/handler.md). Additional *stateful* checks are performed, and the cache-wrapped multistore held in `deliverState`'s `context` is updated by the module's `keeper`. If the `handler` returns successfully, the cache-wrapped multistore held in `context` is written to `deliverState` `CacheMultiStore`. +3. The `anteHandler` does **not** check that the transaction's `gas-prices` is sufficient. That is because the `min-gas-prices` value `gas-prices` is checked against is local to the node, and therefore what is enough for one full-node might not be for another. This means that the proposer can potentially include transactions for free, although they are not incentivised to do so, as they earn a bonus on the total fee of the block they propose. +5. For each `message` in the transaction, route to the appropriate module's [`handler`](../building-modules/handler.md). Additional *stateful* checks are performed, and the cache-wrapped multistore held in `deliverState`'s `context` is updated by the module's `keeper`. If the `handler` returns successfully, the cache-wrapped multistore held in `context` is written to `deliverState` `CacheMultiStore`. -During step 5., each read/write to the store increases the value of `GasConsumed`. You can find the default cost of each operation [here](https://github.com/cosmos/cosmos-sdk/blob/master/store/types/gas.go#L142-L150). At any point, if `GasConsumed > GasWanted`, the function returns with `Code != 0` and `DeliverTx` fails. +During step 5., each read/write to the store increases the value of `GasConsumed`. You can find the default cost of each operation [here](https://github.com/cosmos/cosmos-sdk/blob/master/store/types/gas.go#L142-L150). At any point, if `GasConsumed > GasWanted`, the function returns with `Code != 0` and `DeliverTx` fails. `DeliverTx` returns a response to the underlying consensus engine of type [`abci.ResponseCheckTx`](https://tendermint.com/docs/spec/abci/abci.html#messages). The response contains: -- `Code (uint32)`: Response Code. `0` if successful. +- `Code (uint32)`: Response Code. `0` if successful. - `Data ([]byte)`: Result bytes, if any. - `Log (string):` The output of the application's logger. May be non-deterministic. - `Info (string):` Additional information. May be non-deterministic. -- `GasWanted (int64)`: Amount of gas requested for transaction. It is provided by users when they generate the transaction. -- `GasUsed (int64)`: Amount of gas consumed by transaction. During `DeliverTx`, this value is computed by multiplying the standard cost of a transaction byte by the size of the raw transaction (click [here](https://github.com/cosmos/cosmos-sdk/blob/master/x/auth/ante.go#L101) for an example), and by adding gas each time a read/write to the store occurs. +- `GasWanted (int64)`: Amount of gas requested for transaction. It is provided by users when they generate the transaction. +- `GasUsed (int64)`: Amount of gas consumed by transaction. During `DeliverTx`, this value is computed by multiplying the standard cost of a transaction byte by the size of the raw transaction (click [here](https://github.com/cosmos/cosmos-sdk/blob/master/x/auth/ante.go#L101) for an example), and by adding gas each time a read/write to the store occurs. - `Tags ([]cmn.KVPair)`: Key-Value tags for filtering and indexing transactions (eg. by account). - `Codespace (string)`: Namespace for the Code. @@ -248,13 +302,13 @@ During step 5., each read/write to the store increases the value of `GasConsumed ### RunTx -`RunTx` is called from `CheckTx`/`DeliverTx` to handle the transaction, with `runTxModeCheck` or `runTxModeDeliver` as parameter to differentiate between the two modes of execution. Note that when `RunTx` receives a transaction, it has already been decoded. +`RunTx` is called from `CheckTx`/`DeliverTx` to handle the transaction, with `runTxModeCheck` or `runTxModeDeliver` as parameter to differentiate between the two modes of execution. Note that when `RunTx` receives a transaction, it has already been decoded. -The first thing `RunTx` does upon being called is to retrieve the `context`'s `CacheMultiStore` by calling the `getContextForTx()` function with the appropriate mode (either `runTxModeCheck` or `runTxModeDeliver`). This `CacheMultiStore` is a cached version of the main store instantiated during `BeginBlock` for `DeliverTx` and during the `Commit` of the previous block for `CheckTx`. After that, two `defer func()` are called for [`gas`](./accounts-fees-gas.md#gas) management. They are executed when `runTx` returns and make sure `gas` is actually consumed, and will throw errors, if any. +The first thing `RunTx` does upon being called is to retrieve the `context`'s `CacheMultiStore` by calling the `getContextForTx()` function with the appropriate mode (either `runTxModeCheck` or `runTxModeDeliver`). This `CacheMultiStore` is a cached version of the main store instantiated during `BeginBlock` for `DeliverTx` and during the `Commit` of the previous block for `CheckTx`. After that, two `defer func()` are called for [`gas`](./accounts-fees.md#gas) management. They are executed when `runTx` returns and make sure `gas` is actually consumed, and will throw errors, if any. -After that, `RunTx` calls `ValidateBasic()` on each `message`in the `Tx`, which runs prelimary *stateless* validity checks. If any `message` fails to pass `ValidateBasic()`, `RunTx` returns with an error. +After that, `RunTx` calls `ValidateBasic()` on each `message`in the `Tx`, which runs prelimary *stateless* validity checks. If any `message` fails to pass `ValidateBasic()`, `RunTx` returns with an error. -Then, the [`anteHandler`](#antehandler) of the application is run (if it exists). In preparation of this step, both the `checkState`/`deliverState`'s `context` and `context`'s `CacheMultiStore` are cached-wrapped using the [`cacheTxContext()`](https://github.com/cosmos/cosmos-sdk/blob/master/baseapp/baseapp.go#L781-L798) function. This allows `RunTx` not to commit the changes made to the state during the execution of `anteHandler` if it ends up failing. It also prevents the module implementing the `anteHandler` from writing to state, which is an important part of the [object-capabilities](./ocap.md) of the Cosmos SDK. +Then, the [`anteHandler`](#antehandler) of the application is run (if it exists). In preparation of this step, both the `checkState`/`deliverState`'s `context` and `context`'s `CacheMultiStore` are cached-wrapped using the [`cacheTxContext()`](https://github.com/cosmos/cosmos-sdk/blob/master/baseapp/baseapp.go#L781-L798) function. This allows `RunTx` not to commit the changes made to the state during the execution of `anteHandler` if it ends up failing. It also prevents the module implementing the `anteHandler` from writing to state, which is an important part of the [object-capabilities](./ocap.md) of the Cosmos SDK. Finally, the [`RunMsgs`](#runmsgs) function is called to process the `messages`s in the `Tx`. In preparation of this step, just like with the `anteHandler`, both the `checkState`/`deliverState`'s `context` and `context`'s `CacheMultiStore` are cached-wrapped using the `cacheTxContext()` function. @@ -264,66 +318,36 @@ The `AnteHandler` is a special handler that implements the [`anteHandler` interf The `AnteHandler` is theoretically optional, but still a very important component of public blockchain networks. It serves 3 primary purposes: -- Be a primary line of defense against spam and second line of defense (the first one being the mempool) against transaction replay with fees deduction and [`sequence`](./tx-msgs.md#sequence) checking. -- Perform preliminary *stateful* validity checks like ensuring signatures are valid or that the sender has enough funds to pay for fees. -- Play a role in the incentivisation of stakeholders via the collection of transaction fees. +- Be a primary line of defense against spam and second line of defense (the first one being the mempool) against transaction replay with fees deduction and [`sequence`](./tx-msgs.md#sequence) checking. +- Perform preliminary *stateful* validity checks like ensuring signatures are valid or that the sender has enough funds to pay for fees. +- Play a role in the incentivisation of stakeholders via the collection of transaction fees. `baseapp` holds an `anteHandler` as paraemter, which is initialized in the [application's constructor](../basics/app-anatomy.md#application-constructor). The most widely used `anteHandler` today is that of the [`auth` module](https://github.com/cosmos/cosmos-sdk/blob/master/x/auth/ante.go). ### RunMsgs -`RunMsgs` is called from `RunTx` with `runTxModeCheck` as parameter to check the existence of a route for each message the transaction, and with `runTxModeDeliver` to actually process the `message`s. +`RunMsgs` is called from `RunTx` with `runTxModeCheck` as parameter to check the existence of a route for each message the transaction, and with `runTxModeDeliver` to actually process the `message`s. -First, it retreives the `message`'s `route` using the `Msg.Route()` method. Then, using the application's [`router`](#routing) and the `route`, it checks for the existence of a `handler`. At this point, if `mode == runTxModeCheck`, `RunMsgs` returns. If instead `mode == runTxModeDeliver`, the [`handler`](../building-modules/handler.md) function for the message is executed, before `RunMsgs` returns. +First, it retreives the `message`'s `route` using the `Msg.Route()` method. Then, using the application's [`router`](#routing) and the `route`, it checks for the existence of a `handler`. At this point, if `mode == runTxModeCheck`, `RunMsgs` returns. If instead `mode == runTxModeDeliver`, the [`handler`](../building-modules.md#handler) function for the message is executed, before `RunMsgs` returns. ## Other ABCI Messages ### InitChain -The [`InitChain` ABCI message](https://tendermint.com/docs/app-dev/abci-spec.html#initchain) is sent from the underlying Tendermint engine when the chain is first started. It is mainly used to **initialize** parameters and state like: - -- [Consensus Parameters](https://tendermint.com/docs/spec/abci/apps.html#consensus-parameters) via `setConsensusParams`. -- [`checkState` and `deliverState`](#volatile-states) via `setCheckState` and `setDeliverState`. -- The [block gas meter](../basics/accounts-fees-gas.md#block-gas-meter), with infinite gas to process genesis transactions. - -Finally, the `InitChain(req abci.RequestInitChain)` method of `baseapp` calls the [`initChainer()`](../basics/app-anatomy.md#initchainer) of the application in order to initialize the main state of the application from the [`genesis file`](./genesis.md) and, if defined, call the `InitGenesis` function of each of the application's modules. +The `InitChain` ABCI message is sent from the underlying Tendermint engine when the chain is first started. ### BeginBlock -The [`BeginBlock` ABCI message](#https://tendermint.com/docs/app-dev/abci-spec.html#beginblock) is sent from the underlying Tendermint engine when a block proposal created by the correct proposer is received, before [`DeliverTx`](#delivertx) is run for each transaction in the block. It allows developers to have logic be executed at the beginning of each block. In the Cosmos SDK, the `BeginBlock(req abci.RequestBeginBlock)` method does the following: - -- Initialize [`deliverState`](#volatile-states) with the latest header using the `req abci.RequestBeginBlock` passed as parameter via the [`setDeliverState`](https://github.com/cosmos/cosmos-sdk/blob/master/baseapp/baseapp.go#L283-L289) function. -- Initialize the [block gas meter](../basics/accounts-fees-gas.md#block-gas-meter) with the `maxGas` limit. The `gas` consumed within the block cannot go above `maxGas`. This parameter is defined in the application's consensus parameters. -- Run the application's [`begingBlocker()`](../basics/app-anatomy.md#beginblocker-and-endblock), which mainly runs the `BeginBlocker()` method of each of the application's modules. -- Set the [`VoteInfos`](https://tendermint.com/docs/app-dev/abci-spec.html#voteinfo) of the application, i.e. the list of validators whose *precommit* for the previous block was included by the proposer of the current block. This information is carried into the [`Context`](./context.md) so that it can be used during `DeliverTx` and `EndBlock`. - ### EndBlock -The [`EndBlock` ABCI message](#https://tendermint.com/docs/app-dev/abci-spec.html#endblock) is sent from the underlying Tendermint engine after [`DeliverTx`](#delivertx) as been run for each transactioni n the block. It allows developers to have logic be executed at the end of each block. In the Cosmos SDK, the bulk `EndBlock(req abci.RequestEndBlock)` method is to run the application's [`endBlocker()`](../basics/app-anatomy.md#beginblocker-and-endblock), which mainly runs the `EndBlocker()` method of each of the application's modules. - ### Commit -The [`Commit` ABCI message](https://tendermint.com/docs/app-dev/abci-spec.html#commit) is sent from the underlying Tendermint engine after the full-node has received *precommits* from 2/3+ of validators (weighted by voting power). On the `baseapp` end, the `Commit(res abci.ResponseCommit)` function is implemented to commit all the valid state transitions that occured during `BeginBlock`, `DeliverTx` and `EndBlock` and to reset state for the next block. +The [`Commit` ABCI message](https://tendermint.com/docs/app-dev/abci-spec.html#commit) is sent from the underlying Tendermint engine after the full-node has received *precommits* from 2/3+ of validators (weighted by voting power). On the `baseapp` end, the `Commit(res abci.ResponseCommit)` function is implemented to commit all the valid state transitions that occured during `BeginBlock()`, `DeliverTx()` and `EndBlock()` and to reset state for the next block. To commit state-transitions, the `Commit` function calls the `Write()` function on `deliverState.ms`, where `deliverState.ms` is a cached multistore of the main store `app.cms`. Then, the `Commit` function sets `checkState` to the latest header (obtbained from `deliverState.ctx.BlockHeader`) and `deliverState` to `nil`. -Finally, `Commit` returns the hash of the commitment of `app.cms` back to the underlying consensus engine. This hash is used as a reference in the header of the next block. +Finally, `Commit` returns the hash of the commitment of `app.cms` back to the underlying consensus engine. This hash is used as a reference in the header of the next block. ### Info -The [`Info` ABCI message](https://tendermint.com/docs/app-dev/abci-spec.html#info) is a simple query from the underlying consensus engine, notably used to sync the latter with the application during a handshake that happens on startup. When called, the `Info(res abci.ResponseInfo)` function from `baseapp` will return the application's name, version and the hash of the last commit of `app.cms`. - -### Query - -The [`Query` ABCI message](https://tendermint.com/docs/app-dev/abci-spec.html#query) is used to serve queries received from the underlying consensus engine, including queries received via RPC like Tendermint RPC. It is the main entrypoint to build interfaces with the application. The application must respect a few rules when implementing the `Query` method, which are outlined [here](https://tendermint.com/docs/app-dev/abci-spec.html#query). - -The `baseapp` implementation of the `Query(req abci.RequestQuery)` method is a simple dispatcher serving 4 main categories of queries: - -- Application-related queries like querying the application's version, which are served via the `handleQueryApp` method. -- Direct queries to the multistore, which are served by the `handlerQueryStore` method. These direct queryeis are different from custom queries which go through `app.queryRouter`, and are mainly used by third-party service provider like block explorers. -- P2P queries, which are served via the `handleQueryP2P` method. These queries return either `app.addrPeerFilter` or `app.ipPeerFilter` that contain the list of peers filtered by address or IP respectively. These lists are first initialized via `options` in `baseapp`'s [constructor](#constructor). -- Custom queries, which encompass most queries, are served via the `handleQueryCustom` method. The `handleQueryCustom` cache-wraps the multistore before using the `queryRoute` obtained from [`app.queryRouter`](#query-routing) to map the query to the appropriate module's [`querier`](../building-modules/querier.md). - -## Next - -Learn more about [stores](./store.md). +### Query diff --git a/docs/modules/handler.md b/docs/modules/handler.md deleted file mode 100644 index f8fc820df8de..000000000000 --- a/docs/modules/handler.md +++ /dev/null @@ -1 +0,0 @@ -# Handlers \ No newline at end of file diff --git a/docs/modules/invariants.md b/docs/modules/invariants.md deleted file mode 100644 index 18cd9ad6224f..000000000000 --- a/docs/modules/invariants.md +++ /dev/null @@ -1,5 +0,0 @@ -# Invariants - -## What is an invariant - -## Invariant Registry \ No newline at end of file diff --git a/docs/modules/keeper.md b/docs/modules/keeper.md deleted file mode 100644 index e69de29bb2d1..000000000000 diff --git a/docs/modules/module-interfaces.md b/docs/modules/module-interfaces.md deleted file mode 100644 index 0cd27c895326..000000000000 --- a/docs/modules/module-interfaces.md +++ /dev/null @@ -1,5 +0,0 @@ -# Module Interfaces - -## CLI - -## REST \ No newline at end of file diff --git a/docs/modules/modules.md b/docs/modules/modules.md deleted file mode 100644 index 5c65c4d89f92..000000000000 --- a/docs/modules/modules.md +++ /dev/null @@ -1,8 +0,0 @@ -# SDK Modules - -Todo: Intro concept docs on modules - -## Application Module Interface - -## Module Manager - diff --git a/docs/modules/querier.md b/docs/modules/querier.md deleted file mode 100644 index 3afa9f0cc308..000000000000 --- a/docs/modules/querier.md +++ /dev/null @@ -1,3 +0,0 @@ -# Queriers - -TODO \ No newline at end of file From 653ada24d54e8d82db40fe0e3032cb0e7376e708 Mon Sep 17 00:00:00 2001 From: gamarin Date: Fri, 5 Jul 2019 19:53:40 +0200 Subject: [PATCH 044/196] finish first draft --- docs/basics/accounts-fees.md | 11 ------- docs/basics/app-anatomy.md | 4 +-- docs/core/baseapp.md | 63 ++++++++++++++++++++++++------------ 3 files changed, 45 insertions(+), 33 deletions(-) delete mode 100644 docs/basics/accounts-fees.md diff --git a/docs/basics/accounts-fees.md b/docs/basics/accounts-fees.md deleted file mode 100644 index 20fe1fb2dac8..000000000000 --- a/docs/basics/accounts-fees.md +++ /dev/null @@ -1,11 +0,0 @@ -# Accounts, Fees and Gas - -## Accounts - -## AnteHandler - -## Signatures - -## Fees - -## Gas \ No newline at end of file diff --git a/docs/basics/app-anatomy.md b/docs/basics/app-anatomy.md index bca2c0c2774f..af206c06cf6a 100644 --- a/docs/basics/app-anatomy.md +++ b/docs/basics/app-anatomy.md @@ -117,7 +117,7 @@ The SDK offers developers the possibility to implement automatic execution of co In general, the `BeginBlocker` and `EndBlocker` functions are mostly composed of the `BeginBlock` and `EndBlock` functions of each of the application's modules. This is done by calling the `BeginBlock` and `EndBlock` functions of the module manager, which in turn will call the `BeginBLock` and `EndBlock` functions of each of the modules it contains. Note that the order in which the modules' `BegingBlock` and `EndBlock` functions must be called has to be set in the module manager using the `SetOrderBeginBlock` and `SetOrderEndBlock` methods respectively. This is done in the [application's constructor](#application-constructor), and the `SetOrderBeginBlock` and `SetOrderEndBlock` methods have to be called before the `SetBeginBlocker` and `SetEndBlocker` functions. -As a sidenote, it is important to remember that application-specific blockchains are deterministic. Developers must be careful not to introduce non-determinism in `BeginBlocker` or `EndBlocker`, and must also be careful not to make them too computationally expensive, as [gas](./accounts-fees.md/gas) does not constrain the cost of `BeginBlocker` and `EndBlocker` execution. +As a sidenote, it is important to remember that application-specific blockchains are deterministic. Developers must be careful not to introduce non-determinism in `BeginBlocker` or `EndBlocker`, and must also be careful not to make them too computationally expensive, as [gas](./accounts-fees-gas.md/gas) does not constrain the cost of `BeginBlocker` and `EndBlocker` execution. You can see an example of `BeginBlocker` and `EndBlocker` functions [here](https://github.com/cosmos/gaia/blob/master/app/app.go#L224-L232). @@ -155,7 +155,7 @@ To learn more about the application module interface, [click here](../building-m A message is a custom type defined by each module that implements the [`message`](../building-modules/messages-and-queries.md#messages) interface. Each [`transaction`](../core/transaction.md) contains one or multiple `messages`. When a valid block of transactions is received by the full-node, Tendermint relays each one to the application via [`DeliverTx`](https://tendermint.com/docs/app-dev/abci-spec.html#delivertx). Then, the application handles the transaction: 1. Upon receiving the transaction, the application first unmarshalls it from `[]bytes`. -2. Then, it verifies a few things about the transaction like [fee payment and signatures](#accounts-fees.md) before extracting the message(s) contained in the transaction. +2. Then, it verifies a few things about the transaction like [fee payment and signatures](#accounts-fees-gas.md) before extracting the message(s) contained in the transaction. 3. With the [`Type()`](https://github.com/cosmos/cosmos-sdk/blob/master/types/tx_msg.go#L16) method, `baseapp` is able to know which modules defines the message. It is then able to route it to the appropriate module's [handler](#handler) in order for the message to be processed. 4. If the message is successfully processed, the state is updated. diff --git a/docs/core/baseapp.md b/docs/core/baseapp.md index 7f8214b34e4c..b0b889f7812d 100644 --- a/docs/core/baseapp.md +++ b/docs/core/baseapp.md @@ -29,9 +29,6 @@ This document describes `baseapp`, the abstraction that implements most of the c + [Info](#info) + [Query](#query) - - - ## Introduction `baseapp` is an abstraction that implements the core of an SDK application, namely: @@ -67,12 +64,12 @@ First, the important parameters that are initialized during the initialization o - A [`CommitMultiStore`](./store.md#commit-multi-store). This is the main store of the application, which holds the canonical state that is committed at the [end of each block](#commit). This store is **not** cached, meaning it is not used to update the application's intermediate (un-committed) states. The `CommitMultiStore` is a multi-store, meaning a store of stores. Each module of the application uses one or multiple `KVStores` in the multi-store to persist their subset of the state. - A [database](./store.md#database) `db`, which is used by the `CommitMultiStore` to handle data storage. -- A [router](#messages). The `router` facilitates the routing of [messages](./tx-msgs.md) to the appropriate module for it to be processed. -- A [query router](#queries). The `query router` facilitates the routing of [queries](./querier.md) to the appropriate module for it to be processed. +- A [router](#message-routing). The `router` facilitates the routing of [messages](./tx-msgs.md) to the appropriate module for it to be processed. +- A [query router](#query-routing). The `query router` facilitates the routing of [queries](./querier.md) to the appropriate module for it to be processed. - A [`txDecoder`](https://godoc.org/github.com/cosmos/cosmos-sdk/types#TxDecoder), used to decode transaction `[]byte` relayed by the underlying Tendermint engine. - A [`baseKey`], to access the [main store](./store.md#main-store) in the `CommitMultiStore`. The main store is used to persist data related to the core of the application, like consensus parameters. - A [`anteHandler`](#antehandler), to handle signature verification and fee paiement when a transaction is received. -- An [`initChainer`](./app-anatomy.md#initchainer), [`beginBlocker` and `endBlocker`](./app-anatomy.md#beginblocker-and-endblocker), which are the functions executed when the application received the [InitChain], [BeginBlock] and [EndBlock] messages from the underlying Tendermint engine. +- An [`initChainer`](../basics/app-anatomy.md#initchainer), [`beginBlocker` and `endBlocker`](../basics/app-anatomy.md#beginblocker-and-endblocker), which are the functions executed when the application received the [InitChain], [BeginBlock] and [EndBlock] messages from the underlying Tendermint engine. Then, parameters used to define [volatile states](#volatile-states) (i.e. cached states): @@ -89,13 +86,9 @@ Finally, a few more important parameterd: `NewBaseApp(name string, logger log.Logger, db dbm.DB, txDecoder sdk.TxDecoder, options ...func(*BaseApp),)` is the constructor function for `baseapp`. It is called from the [application's constructor function](../basics/app-anatomy.md#constructor-function) each time the full-node is started. -`baseapp`'s constructor function is pretty straightforward. The only thing worth noting is the possibility to add additional [`options`](https://github.com/cosmos/cosmos-sdk/blob/master/baseapp/options.go) to `baseapp` by passing `options functions` to the constructor function, which will execute them in order. `options` are generally `setter` functions for important parameters, like `SetPruning()` to active pruning or `SetMinGasPrices()` to set the node's `min-gas-prices`. - -A list of `options` examples can be found [here](https://github.com/cosmos/cosmos-sdk/blob/master/baseapp/options.go). Naturally, developers can add additional `options` based on their application's needs. - -## Constructor - +`baseapp`'s constructor function is pretty straightforward. The only thing worth noting is the possibility to add additional [`options`](https://github.com/cosmos/cosmos-sdk/blob/master/baseapp/options.go) to `baseapp` by passing `options functions` to the constructor function, which will execute them in order. `options` are generally `setters` function for important parameters, like `SetPruning()` to active pruning or `SetMinGasPrices()` to set the node's `min-gas-prices`. +A list of `options` example can be found [here](https://github.com/cosmos/cosmos-sdk/blob/master/baseapp/options.go). Naturally, developers can add additional `options` based on their application's needs. ## States @@ -149,8 +142,8 @@ Commit() | | ``` ``` - To perform stateful checks To execute state To answer queries - on received transactions transitions during DeliverTx about last-committed state + To perform stateful checks To execute state To serve queries + on received transactions transitions during DeliverTx on last-committed state +----------------------+ +----------------------+ +----------------------+ | CheckState(t)(0) | | DeliverState(t)(0) | | QueryState(t) | +----------------------+ | | | | @@ -246,7 +239,7 @@ The consensus engine handles two main tasks: - The networking logic, which mainly consists in gossiping block parts, transactions and consensus votes. - The consensus logic, which results in the deterministic ordering of transactions in the form of blocks. -It is **not** the role of the consensus engine to define the state or the validity of transactions. Generally, transactions are handled by the consensus engine in the form of `[]bytes`, and relayed to the application via the ABCI to be decoded and processed. At keys moments in the networking and consensus processes (e.g. beginning of a block, commit of a block, reception of an unconfirmed transaction, ...), the consensus engine emits ABCI messages for the state-machine to act on. +It is **not** the role of the consensus engine to define the state or the validity of transactions. Generally, transactions are handled by the consensus engine in the form of `[]bytes`, and relayed to the application via the ABCI to be decoded and processed. At keys moments in the networking and consensus processes (e.g. beginning of a block, commit of a block, reception of an unconfirmed transaction, ...), the consensus engine emits ABCI messages for the state-machine to act on. Developers building on top of the Cosmos SDK need not implement the ABCI themselves, as `baseapp` comes with a built-in implementation of the interface. Let us go through the main ABCI messages that `baseapp` implements: [`CheckTx`](#checktx) and [`DeliverTx`](#delivertx) @@ -258,10 +251,10 @@ Developers building on top of the Cosmos SDK need not implement the ABCI themsel 1. Extract the `message`s from the transaction. 2. Perform *stateless* checks by calling `ValidateBasic()` on each of the `messages`. This is done first, as *stateless* checks are less computationally expensive than *stateful* checks. If `ValidateBasic()` fail, `CheckTx` returns before running *stateful* checks, which saves resources. -3. Perform non-module related *stateful* checks on the account. This step is mainly about checking that the `message` signatures are valid, that enough fees are provided and that the sending account has enough funds to pay for said fees. Note that no precise [`gas`](./accounts-fees.md#gas) counting occurs here, as `message`s are not processed. Usually, the [`anteHandler`](./accounts-fees.md#antehandler) will check that the `gas` provided with the transaction is superior to a minimum reference gas amount based on the raw transaction size, in order to avoid spam with transactions that provide 0 gas. +3. Perform non-module related *stateful* checks on the account. This step is mainly about checking that the `message` signatures are valid, that enough fees are provided and that the sending account has enough funds to pay for said fees. Note that no precise [`gas`](./accounts-fees-gas.md#gas) counting occurs here, as `message`s are not processed. Usually, the [`anteHandler`](./accounts-fees-gas.md#antehandler) will check that the `gas` provided with the transaction is superior to a minimum reference gas amount based on the raw transaction size, in order to avoid spam with transactions that provide 0 gas. 4. Ensure that a [`Route`](#message-routing) exists for each `message`, but do **not** actually process `message`s. `Message`s only need to be processed when the canonical state need to be updated, which happens during `DeliverTx`. -Steps 2. and 3. are performed by the [`anteHandler`](./accounts-fees.md#antehandler) in the [`RunTx`](#runtx-,antehandler-and-runmsgs) function, which `CheckTx` calls with the `runTxModeCheck` mode. During each step of `CheckTx`, a special [volatile state](#volatile-states) called `checkState` is updated. This state is used to keep track of the temporary changes triggered by the `CheckTx` calls of each transaction without modifying the [main canonical state](#main-state) . For example, when a transaction goes through `CheckTx`, the transaction's fees are deducted from the sender's account in `checkState`. If a second transaction is received from the same account before the first is processed, and the account has consumed all its funds in `checkState` during the first transaction, the second transaction will fail `CheckTx` and be rejected. In any case, the sender's account will not actually pay the fees until the transaction is actually included in a block, because `checkState` never gets committed to the main state. `checkState` is reset to the latest state of the main state each time a blocks gets [committed](#commit). +Steps 2. and 3. are performed by the [`anteHandler`](./accounts-fees-gas.md#antehandler) in the [`RunTx`](#runtx-,antehandler-and-runmsgs) function, which `CheckTx` calls with the `runTxModeCheck` mode. During each step of `CheckTx`, a special [volatile state](#volatile-states) called `checkState` is updated. This state is used to keep track of the temporary changes triggered by the `CheckTx` calls of each transaction without modifying the [main canonical state](#main-state) . For example, when a transaction goes through `CheckTx`, the transaction's fees are deducted from the sender's account in `checkState`. If a second transaction is received from the same account before the first is processed, and the account has consumed all its funds in `checkState` during the first transaction, the second transaction will fail `CheckTx` and be rejected. In any case, the sender's account will not actually pay the fees until the transaction is actually included in a block, because `checkState` never gets committed to the main state. `checkState` is reset to the latest state of the main state each time a blocks gets [committed](#commit). `CheckTx` returns a response to the underlying consensus engine of type [`abci.ResponseCheckTx`](https://tendermint.com/docs/spec/abci/abci.html#messages). The response contains: @@ -304,7 +297,7 @@ During step 5., each read/write to the store increases the value of `GasConsumed `RunTx` is called from `CheckTx`/`DeliverTx` to handle the transaction, with `runTxModeCheck` or `runTxModeDeliver` as parameter to differentiate between the two modes of execution. Note that when `RunTx` receives a transaction, it has already been decoded. -The first thing `RunTx` does upon being called is to retrieve the `context`'s `CacheMultiStore` by calling the `getContextForTx()` function with the appropriate mode (either `runTxModeCheck` or `runTxModeDeliver`). This `CacheMultiStore` is a cached version of the main store instantiated during `BeginBlock` for `DeliverTx` and during the `Commit` of the previous block for `CheckTx`. After that, two `defer func()` are called for [`gas`](./accounts-fees.md#gas) management. They are executed when `runTx` returns and make sure `gas` is actually consumed, and will throw errors, if any. +The first thing `RunTx` does upon being called is to retrieve the `context`'s `CacheMultiStore` by calling the `getContextForTx()` function with the appropriate mode (either `runTxModeCheck` or `runTxModeDeliver`). This `CacheMultiStore` is a cached version of the main store instantiated during `BeginBlock` for `DeliverTx` and during the `Commit` of the previous block for `CheckTx`. After that, two `defer func()` are called for [`gas`](./accounts-fees-gas.md#gas) management. They are executed when `runTx` returns and make sure `gas` is actually consumed, and will throw errors, if any. After that, `RunTx` calls `ValidateBasic()` on each `message`in the `Tx`, which runs prelimary *stateless* validity checks. If any `message` fails to pass `ValidateBasic()`, `RunTx` returns with an error. @@ -334,15 +327,30 @@ First, it retreives the `message`'s `route` using the `Msg.Route()` method. Then ### InitChain -The `InitChain` ABCI message is sent from the underlying Tendermint engine when the chain is first started. +The [`InitChain` ABCI message](https://tendermint.com/docs/app-dev/abci-spec.html#initchain) is sent from the underlying Tendermint engine when the chain is first started. It is mainly used to **initialize** parameters and state like: + +- [Consensus Parameters](https://tendermint.com/docs/spec/abci/apps.html#consensus-parameters) via `setConsensusParams`. +- [`checkState` and `deliverState`](#volatile-states) via `setCheckState` and `setDeliverState`. +- The [block gas meter](../basics/accounts-fees-gas.md#block-gas-meter), with infinite gas to process genesis transactions. + +Finally, the `InitChain(req abci.RequestInitChain)` method of `baseapp` calls the [`initChainer()`](../basics/app-anatomy.md#initchainer) of the application in order to initialize the main state of the application from the [`genesis file`](./genesis.md) and, if defined, call the `InitGenesis` function of each of the application's modules. ### BeginBlock +The [`BeginBlock` ABCI message](#https://tendermint.com/docs/app-dev/abci-spec.html#beginblock) is sent from the underlying Tendermint engine when a block proposal created by the correct proposer is received, before [`DeliverTx`](#delivertx) is run for each transaction in the block. It allows developers to have logic be executed at the beginning of each block. In the Cosmos SDK, the `BeginBlock(req abci.RequestBeginBlock)` method does the following: + +- Initialize [`deliverState`](#volatile-states) with the latest header using the `req abci.RequestBeginBlock` passed as parameter via the [`setDeliverState`](https://github.com/cosmos/cosmos-sdk/blob/master/baseapp/baseapp.go#L283-L289) function. +- Initialize the [block gas meter](../basics/accounts-fees-gas.md#block-gas-meter) with the `maxGas` limit. The `gas` consumed within the block cannot go above `maxGas`. This parameter is defined in the application's consensus parameters. +- Run the application's [`begingBlocker()`](../basics/app-anatomy.md#beginblocker-and-endblock), which mainly runs the `BeginBlocker()` method of each of the application's modules. +- Set the [`VoteInfos`](https://tendermint.com/docs/app-dev/abci-spec.html#voteinfo) of the application, i.e. the list of validators whose *precommit* for the previous block was included by the proposer of the current block. This information is carried into the [`Context`](./context.md) so that it can be used during `DeliverTx` and `EndBlock`. + ### EndBlock +The [`EndBlock` ABCI message](#https://tendermint.com/docs/app-dev/abci-spec.html#endblock) is sent from the underlying Tendermint engine after [`DeliverTx`](#delivertx) as been run for each transactioni n the block. It allows developers to have logic be executed at the end of each block. In the Cosmos SDK, the bulk `EndBlock(req abci.RequestEndBlock)` method is to run the application's [`endBlocker()`](../basics/app-anatomy.md#beginblocker-and-endblock), which mainly runs the `EndBlocker()` method of each of the application's modules. + ### Commit -The [`Commit` ABCI message](https://tendermint.com/docs/app-dev/abci-spec.html#commit) is sent from the underlying Tendermint engine after the full-node has received *precommits* from 2/3+ of validators (weighted by voting power). On the `baseapp` end, the `Commit(res abci.ResponseCommit)` function is implemented to commit all the valid state transitions that occured during `BeginBlock()`, `DeliverTx()` and `EndBlock()` and to reset state for the next block. +The [`Commit` ABCI message](https://tendermint.com/docs/app-dev/abci-spec.html#commit) is sent from the underlying Tendermint engine after the full-node has received *precommits* from 2/3+ of validators (weighted by voting power). On the `baseapp` end, the `Commit(res abci.ResponseCommit)` function is implemented to commit all the valid state transitions that occured during `BeginBlock`, `DeliverTx` and `EndBlock` and to reset state for the next block. To commit state-transitions, the `Commit` function calls the `Write()` function on `deliverState.ms`, where `deliverState.ms` is a cached multistore of the main store `app.cms`. Then, the `Commit` function sets `checkState` to the latest header (obtbained from `deliverState.ctx.BlockHeader`) and `deliverState` to `nil`. @@ -350,4 +358,19 @@ Finally, `Commit` returns the hash of the commitment of `app.cms` back to the un ### Info +The [`Info` ABCI message](https://tendermint.com/docs/app-dev/abci-spec.html#info) is a simple query from the underlying consensus engine, notably used to sync the latter with the application during a handshake that happens on startup. When called, the `Info(res abci.ResponseInfo)` function from `baseapp` will return the application's name, version and the hash of the last commit of `app.cms`. + ### Query + +The [`Query` ABCI message](https://tendermint.com/docs/app-dev/abci-spec.html#query) is used to serve queries received from the underlying consensus engine, including queries received via RPC like Tendermint RPC. It is the main entrypoint to build interfaces with the application. The application must respect a few rules when implementing the `Query` method, which are outlined [here](https://tendermint.com/docs/app-dev/abci-spec.html#query). + +The `baseapp` implementation of the `Query(req abci.RequestQuery)` method is a simple dispatcher serving 4 main categories of queries: + +- Application-related queries like querying the application's version, which are served via the `handleQueryApp` method. +- Direct queries to the multistore, which are served by the `handlerQueryStore` method. These direct queryeis are different from custom queries which go through `app.queryRouter`, and are mainly used by third-party service provider like block explorers. +- P2P queries, which are served via the `handleQueryP2P` method. These queries return either `app.addrPeerFilter` or `app.ipPeerFilter` that contain the list of peers filtered by address or IP respectively. These lists are first initialized via `options` in `baseapp`'s [constructor](#constructor). +- Custom queries, which encompass most queries, are served via the `handleQueryCustom` method. The `handleQueryCustom` cache-wraps the multistore before using the `queryRoute` obtained from [`app.queryRouter`](#query-routing) to map the query to the appropriate module's [`querier`](../building-modules/querier.md). + +## Next + +Learn more about [stores](./store.md). From 0fc3c9a3c130520447f3075ce12e60c9fb9dabb4 Mon Sep 17 00:00:00 2001 From: gamarin Date: Fri, 5 Jul 2019 19:59:09 +0200 Subject: [PATCH 045/196] remove old files --- docs/core/baseapp_old.md | 128 +++++++++++++++++++++++++++++++++++++++ 1 file changed, 128 insertions(+) create mode 100644 docs/core/baseapp_old.md diff --git a/docs/core/baseapp_old.md b/docs/core/baseapp_old.md new file mode 100644 index 000000000000..c4f71f33f696 --- /dev/null +++ b/docs/core/baseapp_old.md @@ -0,0 +1,128 @@ +# BaseApp + +The BaseApp defines the foundational implementation for a basic ABCI application +so that your Cosmos-SDK application can communicate with an underlying +Tendermint node. + +The BaseApp is composed of many internal components. Some of the most important +include the `CommitMultiStore` and its internal state. The internal state is +essentially two sub-states, both of which are used for transaction execution +during different phases, `CheckTx` and `DeliverTx` respectively. During block +commitment, only the `DeliverTx` is persisted. + +The BaseApp requires stores to be mounted via capabilities keys - handlers can +only access stores they're given the key to. The `baseApp` ensures all stores are +properly loaded, cached, and committed. One mounted store is considered the +"main" (`baseApp.MainStoreKey`) - it holds the latest block header, from which we can find and load the +most recent state. + +The BaseApp distinguishes between two handler types - the `AnteHandler` and the +`MsgHandler`. The former is a global validity check (checking nonces, sigs and +sufficient balances to pay fees, e.g. things that apply to all transaction from +all modules), the later is the full state transition function. + +During `CheckTx` the state transition function is only applied to the `checkTxState` +and should return before any expensive state transitions are run +(this is up to each developer). It also needs to return the estimated gas cost. + +During `DeliverTx` the state transition function is applied to the blockchain +state and the transactions need to be fully executed. + +The BaseApp is responsible for managing the context passed into handlers - +it makes the block header available and provides the right stores for `CheckTx` +and `DeliverTx`. BaseApp is completely agnostic to serialization formats. + +## Routing + +TODO + +## Transaction Life Cycle + +During the execution of a transaction, it may pass through both `CheckTx` and +`DeliverTx` as defined in the ABCI specification. `CheckTx` is executed by the +proposing validator and is used for the Tendermint mempool for all full nodes. + +Both `CheckTx` and `DeliverTx` execute the application's AnteHandler (if +defined), where the AnteHandler is responsible for pre-message validation +checks such as account and signature validation, fee deduction and collection, +and incrementing sequence numbers. + +### CheckTx + +During the execution of `CheckTx`, only the AnteHandler is executed. + +State transitions due to the AnteHandler are persisted between subsequent calls +of `CheckTx` in the check-tx state, unless the AnteHandler fails and aborts. + +### DeliverTx + +During the execution of `DeliverTx`, the AnteHandler and Handler is executed. + +The transaction execution during `DeliverTx` operates in a similar fashion to +`CheckTx`. However, state transitions that occur during the AnteHandler are +persisted even when the following Handler processing logic fails. + +It is possible that a malicious proposer may include a transaction in a block +that fails the AnteHandler. In this case, all state transitions for the +offending transaction are discarded. + + +## Other ABCI Messages + +Besides `CheckTx` and `DeliverTx`, BaseApp handles the following ABCI messages. + +### Info +TODO complete description + +### SetOption +TODO complete description + +### Query +TODO complete description + +### InitChain +TODO complete description + +During chain initialization InitChain runs the initialization logic directly on +the CommitMultiStore. The deliver and check states are initialized with the +ChainID. + +Note that we do not commit after InitChain, so BeginBlock for block 1 starts +from the deliver state as initialized by InitChain. + +### BeginBlock +TODO complete description + +### EndBlock +TODO complete description + +### Commit +TODO complete description + + +## Gas Management + +### Gas: InitChain + +During InitChain, the block gas meter is initialized with an infinite amount of +gas to run any genesis transactions. + +Additionally, the InitChain request message includes ConsensusParams as +declared in the genesis.json file. + +### Gas: BeginBlock + +The block gas meter is reset during BeginBlock for the deliver state. If no +maximum block gas is set within baseapp then an infinite gas meter is set, +otherwise a gas meter with `ConsensusParam.BlockSize.MaxGas` is initialized. + +### Gas: DeliverTx + +Before the transaction logic is run, the `BlockGasMeter` is first checked to +see if any gas remains. If no gas remains, then `DeliverTx` immediately returns +an error. + +After the transaction has been processed, the used gas (up to the transaction +gas limit) is deducted from the BlockGasMeter. If the remaining gas exceeds the +meter's limits, then DeliverTx returns an error and the transaction is not +committed. From 7b1f376b3dc395885d4166505ebd171b31d3c3c0 Mon Sep 17 00:00:00 2001 From: gamarin Date: Thu, 11 Jul 2019 18:43:04 +0200 Subject: [PATCH 046/196] finish intro --- docs/building-modules/README.md | 78 ++++++++++++++++++++++ docs/building-modules/intro.md | 29 ++++---- docs/building-modules/module-interfaces.md | 8 +++ docs/building-modules/modules-manager.md | 6 ++ docs/core/baseapp.md | 6 +- 5 files changed, 109 insertions(+), 18 deletions(-) create mode 100644 docs/building-modules/README.md create mode 100644 docs/building-modules/modules-manager.md diff --git a/docs/building-modules/README.md b/docs/building-modules/README.md new file mode 100644 index 000000000000..5b5743671751 --- /dev/null +++ b/docs/building-modules/README.md @@ -0,0 +1,78 @@ +# Auth + +The `x/auth` modules is used for accounts + +See the [API docs](https://godoc.org/github.com/cosmos/cosmos-sdk/x/auth) + +See the [specification](https://github.com/cosmos/cosmos-sdk/tree/master/docs/spec/auth) + +# Bank + +The `x/bank` module is for transferring coins between accounts. + +See the [API docs](https://godoc.org/github.com/cosmos/cosmos-sdk/x/bank). + +See the [specification](https://github.com/cosmos/cosmos-sdk/tree/master/docs/spec/bank) + +# Stake + +The `x/staking` module is for Cosmos Delegated-Proof-of-Stake. + +See the [API docs](https://godoc.org/github.com/cosmos/cosmos-sdk/x/staking). + +See the +[specification](https://github.com/cosmos/cosmos-sdk/tree/master/docs/spec/staking) + +# Slashing + +The `x/slashing` module is for Cosmos Delegated-Proof-of-Stake. + +See the [API docs](https://godoc.org/github.com/cosmos/cosmos-sdk/x/slashing) + +See the +[specification](https://github.com/cosmos/cosmos-sdk/tree/master/docs/spec/slashing) + +# Distribution + +The `x/distribution` module is for distributing fees and inflation across bonded +stakeholders. + +See the [API docs](https://godoc.org/github.com/cosmos/cosmos-sdk/x/distribution) + +See the +[specification](https://github.com/cosmos/cosmos-sdk/tree/master/docs/spec/distribution) + +# Governance + +The `x/gov` module is for bonded stakeholders to make proposals and vote on them. + +See the [API docs](https://godoc.org/github.com/cosmos/cosmos-sdk/x/gov) + +See the +[specification](https://github.com/cosmos/cosmos-sdk/tree/master/docs/spec/governance) + +To keep up with the current status of IBC, follow and contribute to [ICS](https://github.com/cosmos/ics) + +# Crisis + +The `x/crisis` module is for halting the blockchain under certain circumstances. + +See the [API Docs](https://godoc.org/github.com/cosmos/cosmos-sdk/x/crisis) + +See the [specification](https://github.com/cosmos/cosmos-sdk/blob/master/docs/spec/crisis) + +# Mint + +The `x/mint` module is for flexible inflation rates and effect a balance between market liquidity and staked supply. + +See the [API Docs](https://godoc.org/github.com/cosmos/cosmos-sdk/x/mint) + +See the [specification](https://github.com/cosmos/cosmos-sdk/blob/master/docs/spec/mint) + +# Params + +The `x/params` module provides a globally available parameter store. + +See the [API Docs](https://godoc.org/github.com/cosmos/cosmos-sdk/x/params) + +See the [specification](https://github.com/cosmos/cosmos-sdk/blob/master/docs/spec/params) diff --git a/docs/building-modules/intro.md b/docs/building-modules/intro.md index 403eb755a2a2..d3e8440992d5 100644 --- a/docs/building-modules/intro.md +++ b/docs/building-modules/intro.md @@ -7,7 +7,7 @@ ## Synopsis -Modules define most of the logic of any SDK application. Developers compose module together to build their custom application-specific blockchains. This document outlines the basic concepts behind SDK modules and how to approach module management. +Modules define most of the logic of any SDK application. Developers compose module together to build their custom application-specific blockchains. This document outlines the basic concepts behind SDK modules and how to approach module management. - [Role of Modules in an SDK application](#role-of-modules-in-an-sdk-application) - [How to Approach Building Modules as a Developer](#how-to-approach-building-modules-as-a-developer) @@ -18,14 +18,14 @@ Modules define most of the logic of any SDK application. Developers compose modu The Cosmos SDK can be thought as the Ruby-on-Rails of blockchain development. It comes with a core that provides the basic functionalities every blockchain application need, like a boilerplate implementation of the ABCI to communicate with the underlying consensus engine, a multistore to persist state, a server to form a full-node and interfaces to handle queries. -On top of this core, the SDK enables developers to build modules that implement the business logic of their application. In other words, SDK modules implement the bulk of the logic of applications, while the core does the wiring and enables modules to be composed together. The end goal is to build a robust ecosystem of open-source SDK modules, making it increasingly easier to build complex blockchain applications. +On top of this core, the SDK enables developers to build modules that implement the business logic of their application. In other words, SDK modules implement the bulk of the logic of applications, while the core does the wiring and enables modules to be composed together. The end goal is to build a robust ecosystem of open-source SDK modules, making it increasingly easier to build complex blockchain applications. -SDK Modules can be seen as little state-machines within the state-machine. They generally define a subset of the state using one ore multiple `KVStore` in the [main multistore](../core/store.md), as well as a subset of [`message` types](./message.md). These `message`s are routed by one of the main component of SDK core, [`baseapp`](../core/baseapp.md), to the [`handler`](./handler.md) of the module that define them. +SDK Modules can be seen as little state-machines within the state-machine. They generally define a subset of the state using one ore multiple `KVStore` in the [main multistore](../core/store.md), as well as a subset of [`message` types](./message.md). These `message`s are routed by one of the main component of SDK core, [`baseapp`](../core/baseapp.md), to the [`handler`](./handler.md) of the module that define them. ``` + | - | Transaction relayed from the full-node's consensus engine + | Transaction relayed from the full-node's consensus engine | to the node's application via DeliverTx | | @@ -67,29 +67,28 @@ SDK Modules can be seen as little state-machines within the state-machine. They v ``` -As a result of this architecture, building an SDK application usually revolves around writing modules to implement the specialized logic of the application, and composing them with existing modules to complete the application. Developers will generally work on modules that implement logic needed for their specific use case that do not exist yet, and will use existing modules for more generic functionalities like staking, accounts or token management. +As a result of this architecture, building an SDK application usually revolves around writing modules to implement the specialized logic of the application, and composing them with existing modules to complete the application. Developers will generally work on modules that implement logic needed for their specific use case that do not exist yet, and will use existing modules for more generic functionalities like staking, accounts or token management. ## How to Approach Building Modules as a Developer While there is no definitive guidelines for writing modules, here are some important design principles developers should keep in mind when building them: -- **Composability**: SDK applications are almost always composed of multiple modules. This means developers need to carefully consider the integration of their module not only with the core of the Cosmos SDK, but also with other modules. The former is achieved by following standard design patterns outlined [here](#main-components-of-sdk-modules), while the latter is achieved by properly exposing the store(s) of the module via the [`keeper`](./keeper.md). -- **Specialization**: A direct consequence of the **composability** feature is that modules should be **specialized**. Developers should carefully establish the scope of their module and not batch multiple functionalities into the same module. This separation of concern enables modules to be re-used in other projects and improves the upgradability of the application. **Specialization** also plays an important role in the [object-capabilities model](../core/ocap.md) of the Cosmos SDK. -- **Capabilities**: Most modules need to read and/or write to the store(s) of other modules. However, in an open-source environment, it is possible for some module to be malicious. That is why module developers need to carefully think not only about how their module interracts with other modules, and how to give access to the module's store(s). The Cosmos SDK takes a capabilities-oriented approach to inter-module security. This means that each store defined by a module is accessed by a `key`, which is held by the module's [`keeper`](./keeper.md). This `keeper` defines how to access the store(s) and under what conditions. Access to the module's store(s) is done by passing a reference to the module's `keeper`. +- **Composability**: SDK applications are almost always composed of multiple modules. This means developers need to carefully consider the integration of their module not only with the core of the Cosmos SDK, but also with other modules. The former is achieved by following standard design patterns outlined [here](#main-components-of-sdk-modules), while the latter is achieved by properly exposing the store(s) of the module via the [`keeper`](./keeper.md). +- **Specialization**: A direct consequence of the **composability** feature is that modules should be **specialized**. Developers should carefully establish the scope of their module and not batch multiple functionalities into the same module. This separation of concern enables modules to be re-used in other projects and improves the upgradability of the application. **Specialization** also plays an important role in the [object-capabilities model](../core/ocap.md) of the Cosmos SDK. +- **Capabilities**: Most modules need to read and/or write to the store(s) of other modules. However, in an open-source environment, it is possible for some module to be malicious. That is why module developers need to carefully think not only about how their module interracts with other modules, and how to give access to the module's store(s). The Cosmos SDK takes a capabilities-oriented approach to inter-module security. This means that each store defined by a module is accessed by a `key`, which is held by the module's [`keeper`](./keeper.md). This `keeper` defines how to access the store(s) and under what conditions. Access to the module's store(s) is done by passing a reference to the module's `keeper`. ## Main Components of SDK Module -Modules are by convention defined in the `.x/` subfolder (e.g. the `bank` module will be defined in the `./x/bank` folder). They generally share the same core components: +Modules generally share the same core components: -- Custom [`message` types](./message.md) to trigger state-transitions. -- A [`handler`](./handler.md) used to process messages when they are routed to the module by [`baseapp`](../core/baseapp.md#message-routing). -- A [`keeper`](./keeper.md), used to access the module's store(s) and update the state. +- Custom [`message` types](./message.md) to trigger state-transitions. +- A [`handler`](./handler.md) used to process messages when they are routed to the module by [`baseapp`](../core/baseapp.md#message-routing). +- A [`keeper`](./keeper.md), used to access the module's store(s) and update the state. - A [`querier`](./querier.md), used to process user queries when they are routed to the module by [`baseapp`](../core/baseapp.md#query-routing). - Interfaces, for end users to query the subset of the state defined by the module and create `message`s of the custom types defined in the module. -In addition to these components, modules implement the `AppModule` interface in order to be managed by the [`module manager`](./module-manager.md). +In addition to these components, modules implement the `module` interface in order to be managed by the [`module manager`](./module-manager.md). ## Next -Read more on the [`AppModule` interface and the `module manager`](./module-manager.md) - +Read more on the [`module interface` and the `module manager`](./module-manager.md) diff --git a/docs/building-modules/module-interfaces.md b/docs/building-modules/module-interfaces.md index c3ddea3298aa..377e9ed56f98 100644 --- a/docs/building-modules/module-interfaces.md +++ b/docs/building-modules/module-interfaces.md @@ -1,3 +1,4 @@ +<<<<<<< HEAD # Module Interfaces ## Prerequisites @@ -281,3 +282,10 @@ A few things to note: ## Next Read about the next topic in building modules. +======= +# Module Manager + +## Application Module Interface + +## Module Manager +>>>>>>> finish intro diff --git a/docs/building-modules/modules-manager.md b/docs/building-modules/modules-manager.md new file mode 100644 index 000000000000..c10974af7609 --- /dev/null +++ b/docs/building-modules/modules-manager.md @@ -0,0 +1,6 @@ +# Module Manager + +## Application Module Interface + +## Module Manager + diff --git a/docs/core/baseapp.md b/docs/core/baseapp.md index b0b889f7812d..d34db4912444 100644 --- a/docs/core/baseapp.md +++ b/docs/core/baseapp.md @@ -34,7 +34,7 @@ This document describes `baseapp`, the abstraction that implements most of the c `baseapp` is an abstraction that implements the core of an SDK application, namely: - The [Application-Blockchain Interface](#abci), for the state-machine to communicate with the underlying consensus engine (e.g. Tendermint). -- A [Router](#routing), to route [messages](./tx-msgs.md) and [queries](./querier.md) to the appropriate [module](../building-modules/modules.md). +- A [Router](#routing), to route [messages](./tx-msgs.md) and [queries](./querier.md) to the appropriate [module](../building-modules/intro.md). - Different [states](#states), as the state-machine can have different parallel states updated based on the ABCI message received. The goal of `baseapp` is to provide a boilerplate SDK application that developers can easily extend to build their own custom application. Usually, developers will create a custom type for their application, like so: @@ -222,7 +222,7 @@ When messages and queries are received by the application, they must be routed t [`Message`s](#../building-modules/messages-and-queries.md#messages) need to be routed after they are extracted from transactions, which are sent from the underlying Tendermint engine via the [`CheckTx`](#checktx) and [`DeliverTx`](#delivertx) ABCI messages. To do so, `baseapp` holds a [`router`](https://github.com/cosmos/cosmos-sdk/blob/master/baseapp/router.go) which maps `paths` (`string`) to the appropriate module [`handler`](./handler.md). Usually, the `path` is the name of the module. -The application's `router` is initilalized with all the routes using the application's [module manager](./modules.md#module-manager), which itself is initialized with all the application's modules in the application's [constructor](../basics/app-anatomy.md#app-constructor). +The application's `router` is initilalized with all the routes using the application's [module manager](../building-modules/module-manager.md), which itself is initialized with all the application's modules in the application's [constructor](../basics/app-anatomy.md#app-constructor). ### Query Routing @@ -321,7 +321,7 @@ The `AnteHandler` is theoretically optional, but still a very important componen `RunMsgs` is called from `RunTx` with `runTxModeCheck` as parameter to check the existence of a route for each message the transaction, and with `runTxModeDeliver` to actually process the `message`s. -First, it retreives the `message`'s `route` using the `Msg.Route()` method. Then, using the application's [`router`](#routing) and the `route`, it checks for the existence of a `handler`. At this point, if `mode == runTxModeCheck`, `RunMsgs` returns. If instead `mode == runTxModeDeliver`, the [`handler`](../building-modules.md#handler) function for the message is executed, before `RunMsgs` returns. +First, it retreives the `message`'s `route` using the `Msg.Route()` method. Then, using the application's [`router`](#routing) and the `route`, it checks for the existence of a `handler`. At this point, if `mode == runTxModeCheck`, `RunMsgs` returns. If instead `mode == runTxModeDeliver`, the [`handler`](../building-modules/handler.md) function for the message is executed, before `RunMsgs` returns. ## Other ABCI Messages From 023c31e1886dbd6226a6330f483801e1fd38ee4e Mon Sep 17 00:00:00 2001 From: gamarin Date: Thu, 18 Jul 2019 17:20:03 +0200 Subject: [PATCH 047/196] workinnn --- docs/basics/app-anatomy.md | 44 +++---- docs/building-modules/module-interfaces.md | 9 +- docs/building-modules/modules-manager.md | 145 ++++++++++++++++++++- docs/core/baseapp.md | 6 +- 4 files changed, 168 insertions(+), 36 deletions(-) diff --git a/docs/basics/app-anatomy.md b/docs/basics/app-anatomy.md index af206c06cf6a..2e4613c5e8b6 100644 --- a/docs/basics/app-anatomy.md +++ b/docs/basics/app-anatomy.md @@ -65,6 +65,8 @@ The `start` command function primarily does three things: 2. Initialize the state-machine with the latest known state, extracted from the `db` stored in the `~/.appd/data` folder. At this point, the state-machine is at height `appBlockHeight`. 3. Create and start a new Tendermint instance. Among other things, the node will perform a handshake with its peers. It will get the latest `blockHeight` from them, and replay blocks to sync to this height if it is greater than the local `appBlockHeight`. If `appBlockHeight` is `0`, the node is starting from genesis and Tendermint sends an `InitChain` message via the ABCI to the `app`, which triggers the [`InitChainer`](#initchainer). +To learn more about the `start` command, [click here](../core/node.md#start-command). + ## Core Application File In general, the core of the state-machine is defined in a file called `app.go`. It mainly contains the **type definition of the application** and functions to **create and initialize it**. @@ -73,11 +75,11 @@ In general, the core of the state-machine is defined in a file called `app.go`. The first thing defined in `app.go` is the `type` of the application. It is generally comprised of the following parts: -- **A reference to [`baseapp`](./baseapp.md).** The custom application defined in `app.go` is an extension of the `baseapp` type. `baseapp` implements most of the core logic for the application, including all the [ABCI methods](https://tendermint.com/docs/spec/abci/abci.html#overview) and the routing logic. When a transaction is relayed by Tendermint to the application, the latter uses `baseapp`'s methods to route them to the appropriate module. -- **A list of store keys**. The [store](./store.md), which contains the entire state, is implemented as a multistore (i.e. a store of stores) in the Cosmos SDK. Each module uses one or multiple stores in the multistore to persist their part of the state. These stores can be accessed with specific keys that are declared in the `app` type. These keys, along with the `keepers`, are at the heart of the [object-capabilities model](../intro/ocap.md) of the Cosmos SDK. -- **A list of module's `keepers`.** Each module defines an abstraction called `keeper`, which handles reads and writes for this module's store(s). The `keeper`'s methods of one module can be called from other modules (if authorized), which is why they are declared in the application's type and exported as interfaces to other modules so that they are only allowed to access the authorized functions. -- **A reference to a `codec`.** The Cosmos SDK gives developers the freedom to choose the encoding framework for their application. The application's `codec` is used to serialize and deserialize data structures in order to store them, as stores can only persist `[]bytes`. The `codec` must be deterministic. The default codec is [amino](./amino.md). -- **A reference to a [module manager](./modules.md#module-manager)**. The module manager is an object that contains a list of the application's module. It facilitates operations related to these modules, like registering [`routes`](./baseapp.md#routing), [query routes](#./baseapp.md#query-routing) or setting the order of execution between modules for various functions like [`InitChainer`](#initchainer), [`BeginBlocker` and `EndBlocker`](#beginblocker-and-endblocker). +- **A reference to [`baseapp`](../core/baseapp.md).** The custom application defined in `app.go` is an extension of the `baseapp` type. `baseapp` implements most of the core logic for the application, including all the [ABCI methods](https://tendermint.com/docs/spec/abci/abci.html#overview) and the routing logic. When a transaction is relayed by Tendermint to the application, the latter uses `baseapp`'s methods to route them to the appropriate module. +- **A list of store keys**. The [store](../core/store.md), which contains the entire state, is implemented as a multistore (i.e. a store of stores) in the Cosmos SDK. Each module uses one or multiple stores in the multistore to persist their part of the state. These stores can be accessed with specific keys that are declared in the `app` type. These keys, along with the `keepers`, are at the heart of the [object-capabilities model](../intro/ocap.md) of the Cosmos SDK. +- **A list of module's `keepers`.** Each module defines an abstraction called [`keeper`](../building-modules/keeper.md), which handles reads and writes for this module's store(s). The `keeper`'s methods of one module can be called from other modules (if authorized), which is why they are declared in the application's type and exported as interfaces to other modules so that they are only allowed to access the authorized functions. +- **A reference to a [`codec`](../core/encoding.md).** The Cosmos SDK gives developers the freedom to choose the encoding framework for their application. The application's `codec` is used to serialize and deserialize data structures in order to store them, as stores can only persist `[]bytes`. The `codec` must be deterministic. The default codec is [amino](./amino.md). +- **A reference to a [module manager](../building-modules/module-manager.md#manager)** and a [basic module manager](../building-modules/module-manager.md#basicmanager). The module manager is an object that contains a list of the application's module. It facilitates operations related to these modules, like registering [`routes`](./baseapp.md#routing), [query routes](#./baseapp.md#query-routing) or setting the order of execution between modules for various functions like [`InitChainer`](#initchainer), [`BeginBlocker` and `EndBlocker`](#beginblocker-and-endblocker). You can see an example of application type definition [here](https://github.com/cosmos/gaia/blob/master/app/app.go#L73-L107). @@ -88,14 +90,14 @@ This function constructs a new application of the type defined above. It is call - Instantiate a new [`codec`](../core/encoding.md) and initialize the `codec` of each of the application's module using the [basic manager](../building-modules/module-manager.md#basicmanager) - Instantiate a new application with a reference to a `baseapp` instance, a codec and all the appropriate store keys. - Instantiate all the [`keeper`s](#keeper) defined in the application's `type` using the `NewKeeper` function of each of the application's modules. Note that `keepers` must be instantiated in the correct order, as the `NewKeeper` of one module might require a reference to another module's `keeper`. -- Instantiate the application's [module manager](./module-manager.md) with the [`AppModule`](#application-module-interface) object of each of the application's modules. -- With the module manager, initialize the application's [`routes`](./baseapp.md#routing) and [query routes](./baseapp.md#query-routing). When a transaction is relayed to the application by Tendermint via the ABCI, it is routed to the appropriate module's [`handler`](#handler) using the routes defined here. Likewise, when a query is received by the application, it is routed to the appropriate module's [`querier`](#querier) using the query routes defined here. -- With the module manager, register the [application's modules' invariants](./invariants.md). Invariants are variables (e.g. total supply of a token) that are evaluated at the end of each block. The process of checking invariants is done via a special module called the [`InvariantsRegistry`](./invariants.md#invariant-registry). The value of the invariant should be equal to a predicted value defined in the module. Should the value be different than the predicted one, special logic defined in the invariant registry will be triggered (usually the chain is halted). This is useful to make sure no critical bug goes unnoticed and produces long-lasting effects that would be hard to fix. +- Instantiate the application's [module manager](../building-modules/module-manager.md#manager) with the [`AppModule`](#application-module-interface) object of each of the application's modules. +- With the module manager, initialize the application's [`routes`](../core/baseapp.md#routing) and [query routes](../core/baseapp.md#query-routing). When a transaction is relayed to the application by Tendermint via the ABCI, it is routed to the appropriate module's [`handler`](#handler) using the routes defined here. Likewise, when a query is received by the application, it is routed to the appropriate module's [`querier`](#querier) using the query routes defined here. +- With the module manager, register the [application's modules' invariants](./invariants.md). Invariants are variables (e.g. total supply of a token) that are evaluated at the end of each block. The process of checking invariants is done via a special module called the [`InvariantsRegistry`](../building-modules/invariants.md#invariant-registry). The value of the invariant should be equal to a predicted value defined in the module. Should the value be different than the predicted one, special logic defined in the invariant registry will be triggered (usually the chain is halted). This is useful to make sure no critical bug goes unnoticed and produces long-lasting effects that would be hard to fix. - With the module manager, set the order of execution between the `InitGenesis`, `BegingBlocker` and `EndBlocker` functions of each of the [application's modules](#application-module-interface). Note that not all modules implement these functions. - Set the remainer of application's parameters: + [`InitChainer`](#initchainer): used to initialize the application when it is first started. + [`BeginBlocker`, `EndBlocker`](#beginblocker-and-endlbocker): called at the beginning and the end of every block). - + [`anteHandler`](#baseapp.md#antehandler): used to handle fees and signature verification. + + [`anteHandler`](../core/baseapp.md#antehandler): used to handle fees and signature verification. - Mount the stores. - Return the application. @@ -105,7 +107,7 @@ You can see an example of application constructor [here](https://github.com/cosm ### InitChainer -The `InitChainer` is a function that initializes the state of the application from a [genesis file](./genesis.md) (i.e. token balances of genesis accounts). It is called when the application receives the `InitChain` message from the Tendermint engine, which happens when the node is started at `appBlockHeight == 0` (i.e. on genesis). The application must set the `InitChainer` in its constructor via the [`SetInitChainer`](https://godoc.org/github.com/cosmos/cosmos-sdk/baseapp#BaseApp.SetInitChainer) method. +The `InitChainer` is a function that initializes the state of the application from a [genesis file](../core/genesis.md) (i.e. token balances of genesis accounts). It is called when the application receives the `InitChain` message from the Tendermint engine, which happens when the node is started at `appBlockHeight == 0` (i.e. on genesis). The application must set the `InitChainer` in its constructor via the [`SetInitChainer`](https://godoc.org/github.com/cosmos/cosmos-sdk/baseapp#BaseApp.SetInitChainer) method. In general, the `InitChainer` is mostly composed of the `InitGenesis` function of each of the application's modules. This is done by calling the `InitGenesis` function of the module manager, which in turn will call the `InitGenesis` function of each of the modules it contains. Note that the order in which the modules' `InitGenesis` functions must be called has to be set in the module manager using the `SetOrderInitGenesis` method. This is done in the [application's constructor](#application-constructor), and the `SetOrderInitGenesis` has to be called before the `SetInitChainer`. @@ -131,24 +133,20 @@ You can see an example of a `MakeCodec` [here](https://github.com/cosmos/gaia/bl ## Modules -Modules are the heart and soul of an SDK application. They can be considered as state-machines within the state-machine. When a transaction is relayed from the underlying Tendermint engine via the ABCI to the application, it is routed by `baseapp` to the appropriate module in order to be processed. This paradigm enables developers to easily build complex state-machines, as most of the modules they need often already exist. For developers, most of the work involved in building an SDK application revolves around building custom modules required by their application that do not exist, and integrating them with modules that do already exist into one coherent application. In the application directory, the standard practice is to store modules in the `x/` folder (not to be confused with the SDK's `x/` folder, which contains already-built modules). +Modules are the heart and soul of an SDK application. They can be considered as state-machines within the state-machine. When a transaction is relayed from the underlying Tendermint engine via the ABCI to the application, it is routed by [`baseapp`](../core/baseapp.md) to the appropriate module in order to be processed. This paradigm enables developers to easily build complex state-machines, as most of the modules they need often already exist. For developers, most of the work involved in building an SDK application revolves around building custom modules required by their application that do not exist, and integrating them with modules that do already exist into one coherent application. In the application directory, the standard practice is to store modules in the `x/` folder (not to be confused with the SDK's `x/` folder, which contains already-built modules). To learn more about modules, [click here](./modules.md) ### Application Module Interface -Modules implement two interfaces defined in the Cosmos SDK, [`AppModuleBasic`](https://github.com/cosmos/cosmos-sdk/blob/master/types/module/module.go#L44-L57) and [`AppModule`](https://github.com/cosmos/cosmos-sdk/blob/master/types/module/module.go#L44-L57). The former implements basic non-dependant elements of the module, such as the `codec`, while the latter handles the bulk of the module methods (including methods that require references to other modules' `keeper`s). Both the `AppModule` and `AppModuleBasic` types are defined in a file called `./module.go`. - -`AppModule` exposes a collection of useful methods on the module that facilitates the composition of modules into a coherent application. Important methods include: - -- `Route()` and `QueryRoute()`: These methods the name of the route and querier route for the module, for [messages](#message-types) to be routed to the module's [`handler`](#handler) and queries to be routes to the module's [`querier`](#querier). -- `NewHandler()` and `NewQuerierHandler()`: These methods return a `handler` and `querierHandler` respectively, in order to process a message or a query once they are routed. -- `BeginBlock()`, `EndBlock()` and `InitGenesis()`: These methods are executed respectively at the beginning of each block, at the end of each block and at the start of the chain. They implement special logic the module requires to be triggered during those events. For example, the `EndBlock` function is frequently used by modules where voting occurs to tally the result of the votes. -- `RegisterInvariants()`: This method registers the [invariants](./invariants.md) for the module. Invariants are checked at the end of every block to make sure no unpredicted behaviour is occuring. +Modules implement two interfaces defined in the Cosmos SDK, [`AppModuleBasic`](../building-modules/module-manager.md#appmodulebasic) and [`AppModule`](../building-modules/module-manager.md#appmodule). The former implements basic non-dependant elements of the module, such as the `codec`, while the latter handles the bulk of the module methods (including methods that require references to other modules' `keeper`s). Both the `AppModule` and `AppModuleBasic` types are defined in a file called `./module.go`. -`AppModule`'s methods are called from the `module manager`(./modules.md#module-manager), which manages the application's collection of modules. +`AppModule` exposes a collection of useful methods on the module that facilitates the composition of modules into a coherent application. These methods are are called from the `module manager`(../building-modules/module-manager.md#manager), which manages the application's collection of modules. +To learn more about the application module interface, [click here](./modules.md#application-module-interface). +======= To learn more about the application module interface, [click here](../building-modules/module-manager.md#application-module-interfaces). +>>>>>>> workinnn ### Message Types @@ -171,7 +169,7 @@ The [`handler`](../building-modules/handler.md) refers to the part of the module The handler of a module is generally defined in a file called `handler.go` and consists of: -- A **switch function** `NewHandler` to route the message to the appropriate handler function. This function returns a `handler` function, and is registered in the [`AppModule`](#application-module-interface) to be used in the application's module manager to initialize the [application's router](./baseapp.md#routing). See an example of such a switch [here](https://github.com/cosmos/sdk-application-tutorial/blob/master/x/nameservice/handler.go#L10-L22). +- A **switch function** `NewHandler` to route the message to the appropriate handler function. This function returns a `handler` function, and is registered in the [`AppModule`](#application-module-interface) to be used in the application's module manager to initialize the [application's router](../core/baseapp.md#routing). See an example of such a switch [here](https://github.com/cosmos/sdk-application-tutorial/blob/master/x/nameservice/handler.go#L10-L22). - **One handler function for each message type defined by the module**. Developers write the message processing logic in these functions. This generally involves doing stateful checks to ensure the message is valid and calling [`keeper`](#keeper)'s methods to update the state. Handler functions return a result of type [`sdk.Result`](https://github.com/cosmos/cosmos-sdk/blob/master/types/result.go#L14-L37), which informs the application on whether the message was successfully processed. @@ -198,7 +196,7 @@ To learn more about `keepers`, [click here](../building-modules/keeper.md). ### Querier -`Queriers` are very similar to `handlers`, except they serve user queries to the state as opposed to processing transactions. A query is initiated from an [interface](#intefaces) by an end-user who provides a `queryRoute` and some `data`. The query is then routed to the correct application's `querier` by `baseapp`'s [`handleQueryCustom`](https://github.com/cosmos/cosmos-sdk/blob/master/baseapp/baseapp.go#L519-L556) method using `queryRoute`. +[`Queriers`](../building-modules/querier.md) are very similar to `handlers`, except they serve user queries to the state as opposed to processing transactions. A [query](../building-modules/messages-and-queries.md#queries) is initiated from an [interface](#interfaces) by an end-user who provides a `queryRoute` and some `data`. The query is then routed to the correct application's `querier` by `baseapp`'s [`handleQueryCustom`](https://github.com/cosmos/cosmos-sdk/blob/master/baseapp/baseapp.go#L519-L556) method using `queryRoute`. The `Querier` of a module is defined in a file called `querier.go`, and consists of: @@ -241,7 +239,7 @@ The main interface is the [Command-Line Interface](../interfaces/cli.md). The CL - **A `main()` function**, which is executed to build the `appcli` interface client. This function prepares each command and adds them to the `rootCmd` before building them. At the root of `appCli`, the function adds generic commands like `status`, `keys` and `config`, query commands, tx commands and `rest-server`. - **Query commands** are added by calling the `queryCmd` function, also defined in `appcli/main.go`. This function returns a Cobra command that contains the query commands defined in each of the application's modules (passed as an array of `sdk.ModuleClients` from the `main()` function), as well as some other lower level query commands such as block or validator queries. Query command are called by using the command `appcli query [query]` of the CLI. - **Transaction commands** are added by calling the `txCmd` function. Similar to `queryCmd`, the function returns a Cobra command that contains the tx commands defined in each of the application's modules, as well as lower level tx commands like transaction signing or broadcasting. Tx commands are called by using the command `appcli tx [tx]` of the CLI. -- **A `registerRoutes` function**, which is called from the `main()` function when initializing the [application's light-client daemon (LCD)](./node.md#lcd) (i.e. `rest-server`). `registerRoutes` calls the `RegisterRoutes` function of each of the application's module, thereby registering the routes of the module to the lcd's router. The LCD can be started by running the following command `appcli rest-server`. +- **A `registerRoutes` function**, which is called from the `main()` function when initializing the [application's light-client daemon (LCD)](../core/node.md#lcd) (i.e. `rest-server`). `registerRoutes` calls the `RegisterRoutes` function of each of the application's module, thereby registering the routes of the module to the lcd's router. The LCD can be started by running the following command `appcli rest-server`. See an example of an application's main command-line file [here](https://github.com/cosmos/sdk-application-tutorial/blob/master/cmd/nscli/main.go). diff --git a/docs/building-modules/module-interfaces.md b/docs/building-modules/module-interfaces.md index 377e9ed56f98..01b20e6bff15 100644 --- a/docs/building-modules/module-interfaces.md +++ b/docs/building-modules/module-interfaces.md @@ -1,4 +1,3 @@ -<<<<<<< HEAD # Module Interfaces ## Prerequisites @@ -19,6 +18,7 @@ This document details how to build CLI and REST interfaces for a module. Example ## CLI +<<<<<<< HEAD One of the main interfaces for an application is the [command-line interface](../interfaces/cli.md). This entrypoint created by the application developer will add commands from the application's modules to let end-users create [**messages**](./messages-and-queries.md) and [**queries**](./messages-and-queries.md). The CLI files are typically found in the `./x/moduleName/client/cli` folder. ### Transaction Commands @@ -282,10 +282,3 @@ A few things to note: ## Next Read about the next topic in building modules. -======= -# Module Manager - -## Application Module Interface - -## Module Manager ->>>>>>> finish intro diff --git a/docs/building-modules/modules-manager.md b/docs/building-modules/modules-manager.md index c10974af7609..bfe4c9d2d297 100644 --- a/docs/building-modules/modules-manager.md +++ b/docs/building-modules/modules-manager.md @@ -1,6 +1,147 @@ # Module Manager -## Application Module Interface +## Pre-requisite Reading -## Module Manager +- [Introduction to SDK Modules](./intro.md) +## Synopsis + +Cosmos SDK modules need to implement the [`AppModule` interfaces](#application-module-interfaces), in order to be managed by the application's [module manager](#module-manager). The module manager plays an important role in [`message` and `query` routing](../core/baseapp.md#routing), and allows the application developer to set the order of execution of a variety of functions like [`BeginBlocker` and `EndBlocker`](../basics/app-anatomy.md#begingblocker-and-endblocker). + +## Application Module Interfaces + +[Application module interfaces](https://github.com/cosmos/cosmos-sdk/blob/master/types/module/module.go) exist to facilitate the composition of modules together to form a functional SDK application. There are 3 main application module interfaces: + +- [`AppModuleBasic`](#appmodulebasic) for independent module functionalities. +- [`AppModule`](#appmodule) for inter-dependent module functionalities (except genesis-related functionalities). +- [`AppModuleGenesis`](#appmodulegenesis) for inter-dependent genesis-related module functionalities. + +The `AppModuleBasic` interface exists to define independent methods of the module, i.e. those that do not depend on other modules in the application. This allows for the construction of the basic application structure early in the application definition, generally in the `init()` function of the [main application file](../basics/app-antomy.md#core-application-file). + +The `AppModule` interface exists to define inter-dependent module methods. Many modules need to interract with other modules, typically through [`keeper`s](./keeper.md), which means there is a need for an interface where modules list their `keeper`s and other methods that require a reference to another module's object. `AppModule` interface also enables the module manager to set the order of execution between module's methods like `BeginBlock` and `EndBlock`, which is important in cases where the order of execution between modules matters in the context of the application. + +Lastly the interface for genesis functionality `AppModuleGenesis` is separated out from full module functionality `AppModule` so that modules which +are only used for genesis can take advantage of the `Module` patterns without having to define many placeholder functions. + +### `AppModuleBasic` + +The [`AppModuleBasic`](https://github.com/cosmos/cosmos-sdk/blob/master/types/module/module.go#L45-L57) interface defines the independent methods modules need to implement. + +```go +type AppModuleBasic interface { + Name() string + RegisterCodec(*codec.Codec) + + // genesis + DefaultGenesis() json.RawMessage + ValidateGenesis(json.RawMessage) error + + // client functionality + RegisterRESTRoutes(context.CLIContext, *mux.Router) + GetTxCmd(*codec.Codec) *cobra.Command + GetQueryCmd(*codec.Codec) *cobra.Command +} +``` + +Let us go through the methods: + +- `Name()`: Returns the name of the module as a `string`. +- `RegisterCodec(*codec.Codec)`: Registers the `codec` for the module, which is used to marhsal and unmarshal structs to/from `[]byte` in order to persist them in the moduel's `KVStore`. +- `DefaultGenesis()`: Returns a default [`GenesisState`](./genesis.md#genesisstate) for the module, marshalled to `json.RawMessage`. The default `GenesisState` need to be defined by the module developer and is primarily used for testing. +- `ValidateGenesis(json.RawMessage)`: Used to validate the `GenesisState` defined by a module, given in its `json.RawMessage` form. It will usually unmarshall the `json` before running a custom [`ValidateGenesis`](./genesis.md#validategenesis) function defined by the module developer. +- `RegisterRESTRoutes(context.CLIContext, *mux.Router)`: Registers the REST routes for the module. These routes will be used to map REST request to the module in order to process them. See [../interfaces/rest.md] for more. +- `GetTxCmd(*codec.Codec)`: Returns the root [`Tx` command](./module-interfaces.md#tx) for the module. The subcommands of this root command are used by end-users to generate new transactions containing [`message`s](./messages-and-queries.md#queries) defined in the module. +- `GetQueryCmd(*codec.Codec)`: Return the root [`query` command](./module-intefaces.md#query) for the module. The subcommands of this root command are used by end-users to generate new queries to the subset of the state defined by the module. + +All the `AppModuleBasic` of an application are managed by the [`BasicManager`](#basicmanager). + +### `AppModuleGenesis` + +The [`AppModuleGenesis`](https://github.com/cosmos/cosmos-sdk/blob/master/types/module/module.go#L123-L127) interface is a simple embedding of the `AppModuleBasic` interface with two added methods. + +```go +type AppModuleGenesis interface { + AppModuleBasic + InitGenesis(sdk.Context, json.RawMessage) []abci.ValidatorUpdate + ExportGenesis(sdk.Context) json.RawMessage +} +``` + +Let us go through the two added methods: + +- `InitGenesis(sdk.Context, json.RawMessage)`: Initializes the subset of the state managed by the module. It is called at genesis (i.e. when the chain is first started). +- `ExportGenesis(sdk.Context)`: Exports the latest subset of the state managed by the module to be used in a new genesis file. `ExportGenesis` is called for each module when a new chain is started from the state of an existing chain. + +It does not have its own manager, and exists separately from [`AppModule`](#appmodule) only for modules that exist only to implement genesis functionalities, so that they can be managed without having to implement all of `AppModule`'s methods. If the module is not only used during genesis, `InitGenesis(sdk.Context, json.RawMessage)` and `ExportGenesis(sdk.Context)` will generally be defined as methods of the concrete type implementing hte `AppModule` interface. + +### `AppModule` + +The [`AppModule`](https://github.com/cosmos/cosmos-sdk/blob/master/types/module/module.go#L130-L144) interface defines the inter-dependent methods modules need to implement. + +```go +type AppModule interface { + AppModuleGenesis + + // registers + RegisterInvariants(sdk.InvariantRegistry) + + // routes + Route() string + NewHandler() sdk.Handler + QuerierRoute() string + NewQuerierHandler() sdk.Querier + + BeginBlock(sdk.Context, abci.RequestBeginBlock) + EndBlock(sdk.Context, abci.RequestEndBlock) []abci.ValidatorUpdate +} +``` + +`AppModule`s are managed by the [module manager](#manager). This interface embeds the `AppModuleGenesis` interface so that the manager can access all the independent and genesis inter-dependent methods of the module. This means that a concrete type implementing the `AppModule` interface must either implement all the methods of `AppModuleGenesis` (and by extension `AppModuleBasic`), or include a concrete type that does as parameter. + +Let us go through the methods of `AppModule`: + +- `RegisterInvariants(sdk.InvariantRegistry)`: Registers the [`invariants`](./invariants.md) of the module. If the invariants deviates from its predicted value, the [`InvariantRegistry`](./invariants.md#registry) triggers appropriate logic (most often the chain will be halted). +- `Route()`: Returns the name of the module's route, for [`message`s](./messages-and-queries.md#messages) to be routed to the module by [`baseapp`](../core/baseapp.md#message-routing). +- `NewHandler()`: Returns a [`handler`](./handler.md) given the `Type()` of the `message`, in order to process the `message`. +- `QuerierRoute()`: Returns the name of the module's query route, for [`queries`](./messages-and-queries.md#queries) to be routes to the module by [`baseapp`](../core/baseapp.md#query-routing). +- `NewQuerierHandler()`: Returns a [`querier`](./querier.md) given the query `path`, in order to process the `query`. +- `BeginBlock(sdk.Context, abci.RequestBeginBlock)`: This method gives module developers the option to implement logic that is automatically triggered at the beginning of each block. Implement empty if no logic needs to be triggered at the beginning of each block for this module. +- `EndBlock(sdk.Context, abci.RequestEndBlock)`: This method gives module developers the option to implement logic that is automatically triggered at the beginning of each block. This is also where the module can inform the underlying consensus engine of validator set changes (e.g. the `staking` module). Implement empty if no logic needs to be triggered at the beginning of each block for this module. + +### Implementing the Application Module Interfaces + +Typically, the various application module interfaces are implemented in a file called `module.go`, located in the module's folder (e.g. `./x/module/module.go`). + +Almost every module need to implement the `AppModuleBasic` and `AppModule` interfaces. If the module is only used for genesis, it will implement `AppModuleGenesis` instead of `AppModule`. The concrete type that implements the interface can add parameters that are required for the implementation of the various methods of the interface. For example, the `NewHandler()` function often calls a `NewHandler(k keeper)` function defined in [`handler.go`](./handler.md) and therefore needs to pass the module's [`keeper`](./keeper.md) as parameter. + +```go +// example +type AppModule struct { + AppModuleBasic + keeper Keeper +} +``` + +In the example above, you can see that the `AppModule` concrete type references an `AppModuleBasic`, and not an `AppModuleGenesis`. That is because `AppModuleGenesis` only needs to be implemented in modules that focus on genesis-related functionalities. In most modules, the concrete `AppModule` type will have a reference to an `AppModuleBasic` and implement the two added methods of `AppModuleGenesis` directly in the `AppModule` type. + +If no parameter is required (which is often the case for `AppModuleBasic`), just declare an empty concrete type like so: + +```go +type AppModuleBasic struct{} +``` + +## Module Managers + +Module managers are used to manage collections of `AppModuleBasic` and `AppModule`. + +### `BasicManager` + +The `BasicManager` is a structure that lists all the `AppModuleBasic` of an application: + +```go +type BasicManager map[string]AppModuleBasic +``` + + + +### `Manager` diff --git a/docs/core/baseapp.md b/docs/core/baseapp.md index d34db4912444..44c46f26f489 100644 --- a/docs/core/baseapp.md +++ b/docs/core/baseapp.md @@ -64,8 +64,8 @@ First, the important parameters that are initialized during the initialization o - A [`CommitMultiStore`](./store.md#commit-multi-store). This is the main store of the application, which holds the canonical state that is committed at the [end of each block](#commit). This store is **not** cached, meaning it is not used to update the application's intermediate (un-committed) states. The `CommitMultiStore` is a multi-store, meaning a store of stores. Each module of the application uses one or multiple `KVStores` in the multi-store to persist their subset of the state. - A [database](./store.md#database) `db`, which is used by the `CommitMultiStore` to handle data storage. -- A [router](#message-routing). The `router` facilitates the routing of [messages](./tx-msgs.md) to the appropriate module for it to be processed. -- A [query router](#query-routing). The `query router` facilitates the routing of [queries](./querier.md) to the appropriate module for it to be processed. +- A [router](#message-routing). The `router` facilitates the routing of [messages](../building-modules/messages-and-queries.md#messages) to the appropriate module for it to be processed. +- A [query router](#query-routing). The `query router` facilitates the routing of [queries](../building-modules/messages-and-queries.md#queries) to the appropriate module for it to be processed. - A [`txDecoder`](https://godoc.org/github.com/cosmos/cosmos-sdk/types#TxDecoder), used to decode transaction `[]byte` relayed by the underlying Tendermint engine. - A [`baseKey`], to access the [main store](./store.md#main-store) in the `CommitMultiStore`. The main store is used to persist data related to the core of the application, like consensus parameters. - A [`anteHandler`](#antehandler), to handle signature verification and fee paiement when a transaction is received. @@ -226,7 +226,7 @@ The application's `router` is initilalized with all the routes using the applica ### Query Routing -Similar to messages, queries need to be routed to the appropriate module's [querier](./querier.md). To do so, `baseapp` holds a [`query router`](https://github.com/cosmos/cosmos-sdk/blob/master/baseapp/queryrouter.go), which maps `paths` (`string`) to the appropriate module [`querier`](./querier.md). Usually, the `path` is the name of the module. +Similar to `message`s, [`queries`](../building-modules/messages-and-queries.md#queries) need to be routed to the appropriate module's [querier](../building-modules/querier.md). To do so, `baseapp` holds a [`query router`](https://github.com/cosmos/cosmos-sdk/blob/master/baseapp/queryrouter.go), which maps `paths` (`string`) to the appropriate module `querier`. Usually, the `path` is the name of the module. Just like the `router`, the `query router` is initilalized with all the query routes using the application's [module manager](../building-modules/module-manager.md), which itself is initialized with all the application's modules in the application's [constructor](../basics/app-anatomy.md#app-constructor). From 033af57324ae5139aceb6aff947c487bbf06659c Mon Sep 17 00:00:00 2001 From: Gloria Zhao Date: Sat, 20 Jul 2019 11:10:20 -0700 Subject: [PATCH 048/196] initial commit after rebase --- docs/interfaces/cli.md | 145 ++++++++++++++++++++++++++++- docs/interfaces/query-lifecycle.md | 33 +++++++ 2 files changed, 176 insertions(+), 2 deletions(-) create mode 100644 docs/interfaces/query-lifecycle.md diff --git a/docs/interfaces/cli.md b/docs/interfaces/cli.md index fda1ef60b91e..b09d4581cbdf 100644 --- a/docs/interfaces/cli.md +++ b/docs/interfaces/cli.md @@ -1,3 +1,144 @@ -# CLI +# Command-Line Interface -> TODO: Rewrite this section to explain how CLI works for a generic SDK app. +## Prerequisites + +* [Anatomy of an SDK App](./app-anatomy.md) + +## Synopsis + +This document describes how to create a commmand-line interface for an SDK application. A separate document for creating module interfaces can be found [here](#./module-interfaces.md). + +1. [Application CLI](#Application-cli) +2. [Commands](#commands) +3. [Flags](#flags) +4. [Initialization and Configurations](#initialization-and-configurations) + +## Application CLI + +One of the main entrypoints of an application is the command-line interface. This entrypoint is created as a `main.go` file which compiles to a binary, conventionally placed in the application's `app/cmd/cli` folder. + +### Cobra + +There is no set way to create a CLI, but SDK modules all use the [Cobra Library](https://github.com/spf13/cobra). Building a CLI with Cobra entails defining commands, arguments, and flags. [**Commands**](#commands) represent the action users wish to take, such as `tx` for creating a transaction and `query` for querying the application. Each command can also have nested subcommands, necessary for naming the specific transaction type. Users also supply **Arguments**, such as account numbers to send coins to, and [**Flags**](#flags) to modify various aspects of the commands, such as gas prices or which node to broadcast to. + +### Main Function + +The `main.go` file needs to have a `main()` function that does the following to run the command-line interface: + +* **Instantiate the `codec`** by calling the application's `MakeCodec()` function. The `codec` is used to code and encode data structures for the application - stores can only persist `[]byte`s so the developer must define a serialization format for their data structures or use the default, [Amino](./amino.md). +* **Configurations** are set by reading in configuration files (e.g. the sdk config file). +* **Create the root command** to which all the application commands will be added as subcommands and add any required flags to it, such as `--chain-id`. +* **Add subcommands** for all the possible user interactions, including [transaction commands](#transaction-commands) and [query commands](#query-commands). +* **Create an Executor** and execute the root command. + +The rest of the document will detail what needs to be implemented for each step. + +## Commands + +Every application CLI first constructs a root command, then adds functionality by aggregating subcommands (often with further nested subcommands) using `AddCommand()`. The bulk of an application's unique capabilities lies in its transaction and query commands, called `TxCmd` and `QueryCmd` respectively. + +### Root Command + +The root command (also called `rootCmd`) is what the user first types into the command line to indicate which application they wish to interact with. The string used to invoke the command (the "Use" field) is typically the name of the application suffixed with `-cli`, e.g. `appcli`. The root command must include the following commands to support basic functionality in the application. + +* **Status** command from the SDK rpc client tools, which prints information about the status of the connected `Node`. +* **Config** command from the SDK client tools, which allows the user to edit a `config.toml` file that sets values for [flags](#flags) such as `--chain-id` and which `--node` they wish to connect to. +* **Keys** commands from the SDK client tools, which includes a collection of subcommands for using the key functions in the SDK crypto tools, including adding a new key and saving it to disk, listing all public keys stored in the key manager, and deleting a key. +* [**Transaction**](#transaction-commands) commands. +* [**Query**](#query-commands) commands. + +### Transaction Commands + +Application [transactions](#./transactions.md) are objects that trigger state changes. To enable the creation of transactions using the CLI interface, `TxCmd` should add the following commands: + +* **Sign** command from the [`auth`](https://github.com/cosmos/cosmos-sdk/tree/67f6b021180c7ef0bcf25b6597a629aca27766b8/docs/spec/auth) module, which signs messages in a transaction. To enable multisig, it should also add the `auth` module MultiSign command. Since every transaction requires some sort of signature in order to be valid, this command is necessary for every application. +* **Broadcast** command from the SDK client tools, which broadcasts transactions. +* **Send** command from the [`bank`](https://github.com/cosmos/cosmos-sdk/tree/67f6b021180c7ef0bcf25b6597a629aca27766b8/docs/spec/bank) module, which is a transaction that allows accounts to send coins to one another, including gas and fees for transactions. +* Any application-specific transaction commands defined by the application developer. +* All commands in each module the application is dependent on, retrieved by calling `GetTxCmd()` on all the modules or using the Module Manager's `AddTxCommands()` function. + +### Query Commands + +Application queries are objects that allow users to retrieve information about the application's state. To enable basic queries, `QueryCmd` should add the following commands: + +* **QueryTx** and/or other transaction query commands from the `auth` module which allow the user to search for a transaction by inputting its hash, a list of tags, or a block height. These various queries allow users to see if transactions have been included in a block. +* **Account** command from the `auth` module, which displays the state (e.g. account balance) of an account given an address. +* **Validator** command from the SDK rpc client tools, which displays the validator set of a given height. +* **Block** command from the SDK rpc client tools, which displays the block data for a given height. +* Any application-specific query commands defined by the application developer. +* All commands in each module the application is dependent on, retrieved by calling `GetQueryCmd()` on all the modules or using the Module Manager's `AddQueryCommands()` function. + +## Flags + +Flags are used to modify commands. Users can explicitly include them in commands or pre-configure them by entering a command in the format `appcli config ` into their command line. Commonly pre-configured flags include the `--node` to connect to and `--chain-id` of the blockchain the user wishes to interact with. + +A _persistent_ flag (as opposed to a _local_ flag) added to a command transcends all of its children. Additionally, all flags have default values when they are added to commands; some toggle an option off but others are empty values that the user needs to override to create valid commands. A flag can be explicitly marked as _required_ so that an error is automatically thrown if the user does not provide a value, but it is also acceptable to handle unexpected missing flags differently. + +### Root Command Flags + +It is common to add a _persistent_ flag for `--chain-id`, the unique identifier of the blockchain the application pertains to, to the root command. Adding this flag makes sense as the chain ID should not be changing across commands in this application CLI. + +### Transaction Flags + +To **create** a transaction, the user enters a `tx` command and provides several flags. + +* `--from` indicates which account the transaction originates from. This account is used to sign the transaction. +* `--gas` refers to how much gas, which represents computational resources, Tx consumes. Gas is dependent on the transaction and is not precisely calculated until execution, but can be estimated by providing auto as the value for --gas. +* `--gas-adjustment` (optional) can be used to scale gas up in order to avoid underestimating. For example, users can specify their gas adjustment as 1.5 to use 1.5 times the estimated gas. +* `--gas-prices` specifies how much the user is willing pay per unit of gas, which can be one or multiple denominations of tokens. For example, --gas-prices=0.025uatom, 0.025upho means the user is willing to pay 0.025uatom AND 0.025upho per unit of gas. +* `--fees` specifies how much in fees the user is willing to pay in total. Note that the user only needs to provide either `gas-prices` or `fees`, but not both, because they can be derived from each other. +* `--generate-only` (optional) instructs the application to simply generate the unsigned transaction and output or write to a file. Without this flag, the transaction is created, signed, and broadcasted all in one command. +* `--dry-run` (optional), similar to `--generate-only`, instructs the application to ignore the `--gas` flag and simulate the transaction running without broadcasting. +* `--indent` (optional) adds an indent to the JSON response. +* `--memo` sends a memo along with the transaction. + +For example, the following command creates a transaction to send 1000uatom from `sender-address` to `recipient-address`. The user is willing to pay 0.025uatom per unit gas but wants the transaction to be only generated offline (i.e. not broadcasted) and written, in JSON format, to the file `myUnsignedTx.json`. + +```bash +appcli tx send 1000uatom --from --gas auto -gas-prices 0.025uatom --generate-only > myUnsignedTx.json +``` + +To **sign** a transaction generated offline using the `--generate-only` flag, the user enters a `tx sign` command (by default, the transaction is automatically signed upon creation). There are four values for flags that must be provided if a transaction is expected to be signed: + +* `--from` specifies an address; the corresponding private key is used to sign the transaction. +* `--chain-id` specifies the unique identifier of the blockchain the transaction pertains to. +* `--sequence` is the value of a counter measuring how many transactions have been sent from the account. It is used to prevent replay attacks. +* `--account-number` is an identifier for the account. +* `--validate-signatures` (optional) instructs the process to sign the transaction and verify that all signatures have been provided. +* `--ledger` (optional) lets the user perform the action using a Ledger Nano S, which needs to be plugged in and unlocked. + +For example, the following command signs the inputted transaction, `myUnsignedTx.json`, and writes the signed transaction to the file `mySignedTx.json`. + +```bash +appcli tx sign myUnsignedTx.json --from --chain-id --sequence --account-number > mySignedTx.json +``` + +To **broadcast** a signed transaction generated offline, the user enters a `tx broadcast` command. Only one flag is required here: + +* `--node` specifies which node to broadcast to. +* `--trust-node` (optional) indicates whether or not the node and its response proofs can be trusted. +* `--broadcast-mode` (optional) specifies when the process should return. Options include asynchronous (return immediately), synchronous (return after `CheckTx` passes), or block (return after block commit). + +For example, the following command broadcasts the signed transaction, `mySignedTx.json` to a particular node. + +```bash +appcli tx broadcast mySignedTx.json --node +``` +### Query Flags + +Queries also have flags. + +* `--node` indicates which full-node to connect to. +* `--trust-node` (optional) represents whether or not the connected node is trusted. If the node is not trusted, all proofs in the responses are verified. +* `--indent` (optional) adds an indent to the JSON response. +* `--height` (optional) can be provided to query the blockchain at a specific height. +* `--ledger` (optional) lets the user perform the action using a Ledger Nano S. + + +## Initialization and Configurations + +TODO + +## Next + +Read about how to build a CLI for your module [here](./module-interfaces#cli) diff --git a/docs/interfaces/query-lifecycle.md b/docs/interfaces/query-lifecycle.md new file mode 100644 index 000000000000..895c83af4abc --- /dev/null +++ b/docs/interfaces/query-lifecycle.md @@ -0,0 +1,33 @@ +# Query Lifecycle + +## Prerequisites + +## Synopsis + +This document describes SDK interfaces through the lifecycle of a query, from the user interface to application stores and back. The query will be referred to as `query`. + +1. [Interfaces](#interfaces) +2. [CLIContext](#clicontext) +3. [Tendermint and ABCI](#tendermint-and-abci) +4. [Application Query Handling](#application-query-handling) +5. [Response](#response) + +## Interfaces + +### CLI + +### REST + +## CLIContext + +## Tendermint and ABCI + +## Application Query Handling + +### Baseapp + +## Response + +## Next + +Read about how to build a [Command-Line Interface](./cli.md). From f342f3a99019849945f84c98b22a93da4efd7a48 Mon Sep 17 00:00:00 2001 From: Gloria Zhao Date: Sat, 20 Jul 2019 16:19:39 -0700 Subject: [PATCH 049/196] query-lifecycle and started modules-interfaces --- docs/building-modules/module-interfaces.md | 1 - docs/interfaces/cli.md | 16 ++++-- .../{interfaces.md => interfaces-intro.md} | 2 +- docs/interfaces/query-lifecycle.md | 57 +++++++++++++++++-- docs/interfaces/rest.md | 1 + 5 files changed, 64 insertions(+), 13 deletions(-) rename docs/interfaces/{interfaces.md => interfaces-intro.md} (73%) create mode 100644 docs/interfaces/rest.md diff --git a/docs/building-modules/module-interfaces.md b/docs/building-modules/module-interfaces.md index 01b20e6bff15..c3ddea3298aa 100644 --- a/docs/building-modules/module-interfaces.md +++ b/docs/building-modules/module-interfaces.md @@ -18,7 +18,6 @@ This document details how to build CLI and REST interfaces for a module. Example ## CLI -<<<<<<< HEAD One of the main interfaces for an application is the [command-line interface](../interfaces/cli.md). This entrypoint created by the application developer will add commands from the application's modules to let end-users create [**messages**](./messages-and-queries.md) and [**queries**](./messages-and-queries.md). The CLI files are typically found in the `./x/moduleName/client/cli` folder. ### Transaction Commands diff --git a/docs/interfaces/cli.md b/docs/interfaces/cli.md index b09d4581cbdf..58f9b9422887 100644 --- a/docs/interfaces/cli.md +++ b/docs/interfaces/cli.md @@ -2,20 +2,20 @@ ## Prerequisites -* [Anatomy of an SDK App](./app-anatomy.md) +* [Query Lifecycle](./query-lifecycle.md) ## Synopsis This document describes how to create a commmand-line interface for an SDK application. A separate document for creating module interfaces can be found [here](#./module-interfaces.md). -1. [Application CLI](#Application-cli) +1. [Application CLI](#application-cli) 2. [Commands](#commands) 3. [Flags](#flags) 4. [Initialization and Configurations](#initialization-and-configurations) ## Application CLI -One of the main entrypoints of an application is the command-line interface. This entrypoint is created as a `main.go` file which compiles to a binary, conventionally placed in the application's `app/cmd/cli` folder. +One of the main entrypoints of an application is the command-line interface. This entrypoint is created as a `main.go` file which compiles to a binary, conventionally placed in the application's `app/cmd/cli` folder. The CLI for an application will typically be referred to as the name of the application suffixed with `-cli`, e.g. `appcli`. ### Cobra @@ -135,10 +135,14 @@ Queries also have flags. * `--ledger` (optional) lets the user perform the action using a Ledger Nano S. -## Initialization and Configurations +## Configurations -TODO +The last function to define is, `initConfig`, which should do exactly what it sounds like - initial configurations. To call this function, set it as a `PersistentPreRunE` function for the root command, so that it always executes before the main execution of the root command and any of its subcommands. `initConfig` should do the following: + +1. Read in the `config.toml` file. This same file is edited through `config` commands. +2. Use the [Viper](https://github.com/spf13/viper) to read in configurations from the file and set them. +3. Set any persistent flags defined by the user: `--chain-id`, `--encoding`, `--output`, etc. ## Next -Read about how to build a CLI for your module [here](./module-interfaces#cli) +Read about how to build a module CLI [here](./module-interfaces#cli) diff --git a/docs/interfaces/interfaces.md b/docs/interfaces/interfaces-intro.md similarity index 73% rename from docs/interfaces/interfaces.md rename to docs/interfaces/interfaces-intro.md index bb580a5cf171..43ae0f9a0a6e 100644 --- a/docs/interfaces/interfaces.md +++ b/docs/interfaces/interfaces-intro.md @@ -1,3 +1,3 @@ # Interfaces -TODO \ No newline at end of file +TODO diff --git a/docs/interfaces/query-lifecycle.md b/docs/interfaces/query-lifecycle.md index 895c83af4abc..08662b041c25 100644 --- a/docs/interfaces/query-lifecycle.md +++ b/docs/interfaces/query-lifecycle.md @@ -14,20 +14,67 @@ This document describes SDK interfaces through the lifecycle of a query, from th ## Interfaces -### CLI +A **query** is a request for information made by users of applications. They can query information about the network, the application itself, and application state directly from the application's stores or modules. There are a few ways `query` can be made. + +## CLI + +The main interface for an application is the command-line interface. Users run the CLI directly from their machines and type commands to create queries. For the purpose of explaining a query lifecycle, let's say `query` is requesting a list of delegations made by a certain delegator address in the application called `app`. To create this query from the command-line, users would type the following command: + +``` +appcli query staking delegations +``` + +### CLIContext + +The first thing that is created in the execution of a CLI command is a `CLIContext`. A [Context](../core/context.md) is an immutable object that stores all the data needed to process a request. In particular, a `CLIContext` stores the following: + +* **Codec**: The encoder/decoder used by the application, used to marshal the parameters and query before making the Tendermint RPC request and unmarshal the returned response into a JSON object. +* **Account Decoder**: The account decoder from the [`auth`](https://github.com/cosmos/cosmos-sdk/tree/67f6b021180c7ef0bcf25b6597a629aca27766b8/docs/spec/auth) module, which translates `[]byte`s into accounts. +* **RPC Client**: The [Tendermint RPC Client](https://github.com/tendermint/tendermint/blob/master/rpc/client/interface.go). +* **Keybase**: A [Key Manager](.//core/accounts-keys.md) used to sign transactions and handle other operations with keys. +* **Output Writer**: A [Writer](https://golang.org/pkg/io/#Writer) used to output the response. +* **Configurations**: The flags configured by the user for this command, including `--height`, specifying the height of the blockchain to query and `--indent`, which indicates to add an indent to the JSON response. + +For full specification of the `CLIContext` type, click [here](https://github.com/cosmos/cosmos-sdk/blob/73e5ef7c13c420f9ee879fdf1b60cf0bdc8f325e/client/context/context.go#L36-L59). + +### Parameters and Route Creation + +After a `CLIContext` is created for the CLI command, the command is parsed to create a query route and arguments. + +The command contains arguments; in this case, `query` contains a `delegatorAddress`. Since requests can only contain `[]byte`s, the `CLIContext` `codec` is used to marshal the address as the type `QueryDelegatorParams`. All query arguments (e.g. the `staking` module also has `QueryValidatorParams` and `QueryBondsParams`) have their own types that the application `codec` understands how to encode. All of this logic is specified in the module [`querier`](.//building-modules/querier.md). + +A `route` is also created for `query` so that the application will understand how to route it. Baseapp will understand this query to be a `custom` query in the module `staking` with the type `QueryDelegatorDelegations`. Thus, the route will be `"custom/staking/delegatorDelegations"`. + +### ABCI Query + +The `CLIContext`'s main `query` function takes the `route`, which is now called `path`, and arguments, now called `key`. It first retrieves the RPC Client (called the **node**) configured by the user to relay this query to, and creates the `ABCIQueryOptions` (parameters formatted for the ABCI call). The node is used to make the ABCI call, `ABCIQueryWithOptions`. + +From here, continue reading about how the CLI command is handled by skipping to the [Tendermint and ABCI](#tendermint-and-abci) section, or first read about how to make the same `query` using the [REST Interface](#rest). + +## REST + +Another interface through which users can make queries is a REST interface. -### REST -## CLIContext ## Tendermint and ABCI +Nodes running the consensus engine (e.g. Tendermint Core) make ABCI calls to interact with the application. At this point, `query` exists as an ABCI `RequestQuery` and the [ABCI Client](https://github.com/tendermint/tendermint/blob/51b3428f5c0f4fdd2e469147cd90353faa4bd704/abci/client/client.go#L16-L50) calls the ABCI method [`Query()`](https://tendermint.com/docs/spec/abci/abci.html#query) on the application. + +Read more about ABCI Clients and Tendermint RPC in the Tendermint documentation [here](https://tendermint.com/rpc). + ## Application Query Handling -### Baseapp +[Baseapp](../core/baseapp.md) implements the ABCI [`Query()`](../core/baseapp.md#query) function and handles four different types of queries: `app`, `store`, `p2p`, and `custom`. The `queryRoute` is parsed such that the first string must be one of the four options, then the rest of the path is parsed within the subroutines handling each type of query. The first three types are application-level and thus directly handled by Baseapp or the stores, but the `custom` query type requires Baseapp to route the query to a module's [querier](../building-modules/querier.md). + +Since `query` is a custom query type, Baseapp first parses the path to retrieve the name of the path. retrieves the querier using its `QueryRouter`. ## Response +The ABCI `Query()` function returns an ABCI Response of type `ResponseQuery`. + +The `CLIContext` `query` routine receives the response and, if `--trust-node` is toggled to `false` and a proof needs to be verified, the response is verified with the `CLIContext` `verifyProof` function before the response is returned. + ## Next -Read about how to build a [Command-Line Interface](./cli.md). +Read about how to build a [Command-Line Interface](./cli.md), or a [REST Interface](./rest.md). diff --git a/docs/interfaces/rest.md b/docs/interfaces/rest.md new file mode 100644 index 000000000000..9133e5ce9e2f --- /dev/null +++ b/docs/interfaces/rest.md @@ -0,0 +1 @@ +# REST Interface From f766dc2e5e1c45b5ba3f1d62cd4903830c1cfdfe Mon Sep 17 00:00:00 2001 From: Gloria Zhao Date: Sun, 21 Jul 2019 14:16:18 -0700 Subject: [PATCH 050/196] query-lifecycle first draft done --- docs/interfaces/query-lifecycle.md | 62 ++++++++++++++++++++---------- 1 file changed, 42 insertions(+), 20 deletions(-) diff --git a/docs/interfaces/query-lifecycle.md b/docs/interfaces/query-lifecycle.md index 08662b041c25..9635afa59743 100644 --- a/docs/interfaces/query-lifecycle.md +++ b/docs/interfaces/query-lifecycle.md @@ -4,7 +4,7 @@ ## Synopsis -This document describes SDK interfaces through the lifecycle of a query, from the user interface to application stores and back. The query will be referred to as `query`. +This document describes SDK interfaces in detail through the lifecycle of a query, from the user interface to application stores and back. The query will be referred to as `query`. 1. [Interfaces](#interfaces) 2. [CLIContext](#clicontext) @@ -14,19 +14,43 @@ This document describes SDK interfaces through the lifecycle of a query, from th ## Interfaces -A **query** is a request for information made by users of applications. They can query information about the network, the application itself, and application state directly from the application's stores or modules. There are a few ways `query` can be made. +A **query** is a request for information made by users of applications. They can query information about the network, the application itself, and application state directly from the application's stores or modules. -## CLI +For the purpose of explaining a query lifecycle, let's say `query` is requesting a list of delegations made by a certain delegator address in the application called `app`. There are a few ways `query` can be made on the user side. -The main interface for an application is the command-line interface. Users run the CLI directly from their machines and type commands to create queries. For the purpose of explaining a query lifecycle, let's say `query` is requesting a list of delegations made by a certain delegator address in the application called `app`. To create this query from the command-line, users would type the following command: +### CLI + +The main interface for an application is the command-line interface. Users run the CLI directly from their machines and type commands to create queries. To create this query from the command-line, users would type the following command: ``` appcli query staking delegations ``` +To provide values such as `--chain-id`, the ID of the blockchain to make the query to, the user must use the `config` command to set them or provide them as flags. + +This query command is defined by the module developer and added to the list of subcommands by the application developer when creating the CLI. To see the command itself, click [here](). + +### REST + +Another interface through which users can make queries is through HTTP Requests to a REST server. The REST server contains, among other things, a [`CLIContext`](#clicontext) and [mux](./rest.md)(#gorilla-mux) router. The request looks like this: + +```bash +http://localhost:{PORT}/staking/delegators/{delegatorAddr}/delegations +``` + +To provide values such as `--chain-id`, the ID of the blockchain to make the query to, the user must configure their REST server with the values or provide them in the request body. + +The router automatically routes the `query` HTTP request to the staking module `delegatorDelegationsHandlerFn()` function (to see the handler itself, click [here]()). Since this function is defined within the module and thus has no inherent knowledge of the application `query` belongs to, it takes in the application `codec` and `CLIContext` as parameters. + +To read about how the router is used, click [here](./rest.md). + +## Request and Command Handling + +The user interactions are somewhat similar, but the underlying functions are almost identical. This section describes how the CLI command or HTTP request is processed, up until the ABCI request is sent. This step of processing heavily involves a `CLIContext`. + ### CLIContext -The first thing that is created in the execution of a CLI command is a `CLIContext`. A [Context](../core/context.md) is an immutable object that stores all the data needed to process a request. In particular, a `CLIContext` stores the following: +The first thing that is created in the execution of a CLI command is a `CLIContext`, while the REST Server directly provides a `CLIContext` for the REST Request handler. A [Context](../core/context.md) is an immutable object that stores all the data needed to process a request. In particular, a `CLIContext` stores the following: * **Codec**: The encoder/decoder used by the application, used to marshal the parameters and query before making the Tendermint RPC request and unmarshal the returned response into a JSON object. * **Account Decoder**: The account decoder from the [`auth`](https://github.com/cosmos/cosmos-sdk/tree/67f6b021180c7ef0bcf25b6597a629aca27766b8/docs/spec/auth) module, which translates `[]byte`s into accounts. @@ -39,27 +63,19 @@ For full specification of the `CLIContext` type, click [here](https://github.com ### Parameters and Route Creation -After a `CLIContext` is created for the CLI command, the command is parsed to create a query route and arguments. +The next step is to parse the command or request, extract the arguments, create a `queryRoute`, and encode everything. -The command contains arguments; in this case, `query` contains a `delegatorAddress`. Since requests can only contain `[]byte`s, the `CLIContext` `codec` is used to marshal the address as the type `QueryDelegatorParams`. All query arguments (e.g. the `staking` module also has `QueryValidatorParams` and `QueryBondsParams`) have their own types that the application `codec` understands how to encode. All of this logic is specified in the module [`querier`](.//building-modules/querier.md). +In this case, `query` contains a `delegatorAddress` as its only argument. Since requests can only contain `[]byte`s, the `CLIContext` `codec` is used to marshal the address as the type `QueryDelegatorParams`. All query arguments (e.g. the `staking` module also has `QueryValidatorParams` and `QueryBondsParams`) have their own types that the application `codec` understands how to encode and decode. All of this logic is specified in the module [`querier`](.//building-modules/querier.md). -A `route` is also created for `query` so that the application will understand how to route it. Baseapp will understand this query to be a `custom` query in the module `staking` with the type `QueryDelegatorDelegations`. Thus, the route will be `"custom/staking/delegatorDelegations"`. +A `route` is also created for `query` so that the application will understand which module to route the query to. Baseapp will understand this query to be a `custom` query in the module `staking` with the type `QueryDelegatorDelegations`. Thus, the route will be `"custom/staking/delegatorDelegations"`. ### ABCI Query -The `CLIContext`'s main `query` function takes the `route`, which is now called `path`, and arguments, now called `key`. It first retrieves the RPC Client (called the **node**) configured by the user to relay this query to, and creates the `ABCIQueryOptions` (parameters formatted for the ABCI call). The node is used to make the ABCI call, `ABCIQueryWithOptions`. - -From here, continue reading about how the CLI command is handled by skipping to the [Tendermint and ABCI](#tendermint-and-abci) section, or first read about how to make the same `query` using the [REST Interface](#rest). - -## REST - -Another interface through which users can make queries is a REST interface. - - +The `CLIContext`'s main `query` function takes the `route`, which is now called `path`, and arguments, now called `key`. It first retrieves the RPC Client (called the **node**) configured by the user to relay this query to, and creates the `ABCIQueryOptions` (parameters formatted for the ABCI call). The node is then used to make the ABCI call, `ABCIQueryWithOptions`. ## Tendermint and ABCI -Nodes running the consensus engine (e.g. Tendermint Core) make ABCI calls to interact with the application. At this point, `query` exists as an ABCI `RequestQuery` and the [ABCI Client](https://github.com/tendermint/tendermint/blob/51b3428f5c0f4fdd2e469147cd90353faa4bd704/abci/client/client.go#L16-L50) calls the ABCI method [`Query()`](https://tendermint.com/docs/spec/abci/abci.html#query) on the application. +With a call to `ABCIQueryWithOptions()`, `query` arrives at the consensus engine portion of its lifecycle. Nodes running the consensus engine (e.g. Tendermint Core) make ABCI calls to interact with the application. At this point, `query` exists as an ABCI `RequestQuery` and the [ABCI Client](https://github.com/tendermint/tendermint/blob/51b3428f5c0f4fdd2e469147cd90353faa4bd704/abci/client/client.go#L16-L50) calls the ABCI method [`Query()`](https://tendermint.com/docs/spec/abci/abci.html#query) on the application. Read more about ABCI Clients and Tendermint RPC in the Tendermint documentation [here](https://tendermint.com/rpc). @@ -71,9 +87,15 @@ Since `query` is a custom query type, Baseapp first parses the path to retrieve ## Response -The ABCI `Query()` function returns an ABCI Response of type `ResponseQuery`. +Since `Query()` is an ABCI function, Baseapp returns the `query` response as an `abci.ResponseQuery`. The `CLIContext` `query` routine receives the response and, if `--trust-node` is toggled to `false` and a proof needs to be verified, the response is verified with the `CLIContext` `verifyProof` function before the response is returned. + +### CLI Response + +The application `codec` is used to unmarshal the response to a JSON and the `CLIContext` prints the output to the command line, applying any configurations such as `--indent`. + +### REST Response -The `CLIContext` `query` routine receives the response and, if `--trust-node` is toggled to `false` and a proof needs to be verified, the response is verified with the `CLIContext` `verifyProof` function before the response is returned. +The REST server uses the `CLIContext` to format the response properly, then uses the HTTP package to write the appropriate response or error. ## Next From 45fb5f1330cb7adaecf1afd35d6f6a764274e1e1 Mon Sep 17 00:00:00 2001 From: Gloria Zhao Date: Tue, 23 Jul 2019 09:33:59 -0700 Subject: [PATCH 051/196] module interfaces first draft --- docs/interfaces/query-lifecycle.md | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/docs/interfaces/query-lifecycle.md b/docs/interfaces/query-lifecycle.md index 9635afa59743..6c60c92fe3b7 100644 --- a/docs/interfaces/query-lifecycle.md +++ b/docs/interfaces/query-lifecycle.md @@ -32,7 +32,7 @@ This query command is defined by the module developer and added to the list of s ### REST -Another interface through which users can make queries is through HTTP Requests to a REST server. The REST server contains, among other things, a [`CLIContext`](#clicontext) and [mux](./rest.md)(#gorilla-mux) router. The request looks like this: +Another interface through which users can make queries is through HTTP Requests to a REST server. The REST server contains, among other things, a [`CLIContext`](#clicontext) and [mux](./rest.md#gorilla-mux) router. The request looks like this: ```bash http://localhost:{PORT}/staking/delegators/{delegatorAddr}/delegations @@ -46,7 +46,7 @@ To read about how the router is used, click [here](./rest.md). ## Request and Command Handling -The user interactions are somewhat similar, but the underlying functions are almost identical. This section describes how the CLI command or HTTP request is processed, up until the ABCI request is sent. This step of processing heavily involves a `CLIContext`. +The interactions from the users' perspective are a bit different, but the underlying functions are almost identical. This section describes how the CLI command or HTTP request is processed, up until the ABCI request is sent. This step of processing heavily involves a `CLIContext`. ### CLIContext @@ -65,7 +65,7 @@ For full specification of the `CLIContext` type, click [here](https://github.com The next step is to parse the command or request, extract the arguments, create a `queryRoute`, and encode everything. -In this case, `query` contains a `delegatorAddress` as its only argument. Since requests can only contain `[]byte`s, the `CLIContext` `codec` is used to marshal the address as the type `QueryDelegatorParams`. All query arguments (e.g. the `staking` module also has `QueryValidatorParams` and `QueryBondsParams`) have their own types that the application `codec` understands how to encode and decode. All of this logic is specified in the module [`querier`](.//building-modules/querier.md). +In this case, `query` contains a `delegatorAddress` as its only argument. However, the request can only contain `[]byte`s, as it will be relayed to a consensus engine node that has no inherent knowledge of the application types. Thus, the `CLIContext` `codec` is used to marshal the address as the type `QueryDelegatorParams`. All query arguments (e.g. the `staking` module also has `QueryValidatorParams` and `QueryBondsParams`) have their own types that the application `codec` understands how to encode and decode. The module [`querier`](.//building-modules/querier.md) declares these types and the application registers the `codec`s. A `route` is also created for `query` so that the application will understand which module to route the query to. Baseapp will understand this query to be a `custom` query in the module `staking` with the type `QueryDelegatorDelegations`. Thus, the route will be `"custom/staking/delegatorDelegations"`. @@ -83,7 +83,7 @@ Read more about ABCI Clients and Tendermint RPC in the Tendermint documentation [Baseapp](../core/baseapp.md) implements the ABCI [`Query()`](../core/baseapp.md#query) function and handles four different types of queries: `app`, `store`, `p2p`, and `custom`. The `queryRoute` is parsed such that the first string must be one of the four options, then the rest of the path is parsed within the subroutines handling each type of query. The first three types are application-level and thus directly handled by Baseapp or the stores, but the `custom` query type requires Baseapp to route the query to a module's [querier](../building-modules/querier.md). -Since `query` is a custom query type, Baseapp first parses the path to retrieve the name of the path. retrieves the querier using its `QueryRouter`. +Since `query` is a custom query type, Baseapp first parses the path, then uses the `QueryRouter` to retrieve the corresponding querier. ## Response @@ -95,7 +95,7 @@ The application `codec` is used to unmarshal the response to a JSON and the `CLI ### REST Response -The REST server uses the `CLIContext` to format the response properly, then uses the HTTP package to write the appropriate response or error. +The REST server uses the `CLIContext` to format the response properly, then uses the HTTP package to write the appropriate response or error. ## Next From a77f6070f7568b5cc2883697980ba92cbbf4fc35 Mon Sep 17 00:00:00 2001 From: Gloria Zhao Date: Thu, 25 Jul 2019 19:31:35 -0700 Subject: [PATCH 052/196] rest and intro skeletons --- docs/interfaces/cli.md | 12 ++++++------ docs/interfaces/interfaces-intro.md | 2 +- docs/interfaces/query-lifecycle.md | 10 +++++----- docs/interfaces/rest.md | 29 +++++++++++++++++++++++++++++ 4 files changed, 41 insertions(+), 12 deletions(-) diff --git a/docs/interfaces/cli.md b/docs/interfaces/cli.md index 58f9b9422887..94fca6537b06 100644 --- a/docs/interfaces/cli.md +++ b/docs/interfaces/cli.md @@ -6,12 +6,12 @@ ## Synopsis -This document describes how to create a commmand-line interface for an SDK application. A separate document for creating module interfaces can be found [here](#./module-interfaces.md). +This document describes how to create a commmand-line interface for an SDK application. A separate document for creating a module CLI can be found [here](#../module-interfaces.md#cli). -1. [Application CLI](#application-cli) -2. [Commands](#commands) -3. [Flags](#flags) -4. [Initialization and Configurations](#initialization-and-configurations) +- [Application CLI](#application-cli) +- [Commands](#commands) +- [Flags](#flags) +- [Initialization and Configurations](#initialization-and-configurations) ## Application CLI @@ -19,7 +19,7 @@ One of the main entrypoints of an application is the command-line interface. Thi ### Cobra -There is no set way to create a CLI, but SDK modules all use the [Cobra Library](https://github.com/spf13/cobra). Building a CLI with Cobra entails defining commands, arguments, and flags. [**Commands**](#commands) represent the action users wish to take, such as `tx` for creating a transaction and `query` for querying the application. Each command can also have nested subcommands, necessary for naming the specific transaction type. Users also supply **Arguments**, such as account numbers to send coins to, and [**Flags**](#flags) to modify various aspects of the commands, such as gas prices or which node to broadcast to. +There is no set way to create a CLI, but SDK modules all use the [Cobra Library](https://github.com/spf13/cobra) in order to implement the [`AppModuleBasic`]() interface. Building a CLI with Cobra entails defining commands, arguments, and flags. [**Commands**](#commands) represent the action users wish to take, such as `tx` for creating a transaction and `query` for querying the application. Each command can also have nested subcommands, necessary for naming the specific transaction type. Users also supply **Arguments**, such as account numbers to send coins to, and [**Flags**](#flags) to modify various aspects of the commands, such as gas prices or which node to broadcast to. ### Main Function diff --git a/docs/interfaces/interfaces-intro.md b/docs/interfaces/interfaces-intro.md index 43ae0f9a0a6e..09466179cc60 100644 --- a/docs/interfaces/interfaces-intro.md +++ b/docs/interfaces/interfaces-intro.md @@ -1,3 +1,3 @@ # Interfaces -TODO +This document introduces interfaces for SDK applications. The two main interfaces are the Command-Line Interface and REST Interface. diff --git a/docs/interfaces/query-lifecycle.md b/docs/interfaces/query-lifecycle.md index 6c60c92fe3b7..83fe119d1b7b 100644 --- a/docs/interfaces/query-lifecycle.md +++ b/docs/interfaces/query-lifecycle.md @@ -6,11 +6,11 @@ This document describes SDK interfaces in detail through the lifecycle of a query, from the user interface to application stores and back. The query will be referred to as `query`. -1. [Interfaces](#interfaces) -2. [CLIContext](#clicontext) -3. [Tendermint and ABCI](#tendermint-and-abci) -4. [Application Query Handling](#application-query-handling) -5. [Response](#response) +- [Interfaces](#interfaces) +- [CLIContext](#clicontext) +- [Tendermint and ABCI](#tendermint-and-abci) +- [Application Query Handling](#application-query-handling) +- [Response](#response) ## Interfaces diff --git a/docs/interfaces/rest.md b/docs/interfaces/rest.md index 9133e5ce9e2f..ba22e264ab2b 100644 --- a/docs/interfaces/rest.md +++ b/docs/interfaces/rest.md @@ -1 +1,30 @@ # REST Interface + +## Prerequisites + +* [Query Lifecycle](./query-lifecycle.md) + +## Synopsis + +This document describes how to create a REST interface for an SDK application. A separate document for creating module REST Routes can be found [here](#../module-interfaces.md#rest). + +- [Application REST Interface](#application-rest-interface) +- [REST Server](#rest-server) +- [Router](#router) +- [Registering Routes](#registering-routes) + +## Application REST Interface + +## REST Server + +The SDK REST Server has the following: + +* **Mux Router** +* **CLIContext** +* **Keybase** +* **Logger** +* **Listener** + +## Registering Routes + +For information about how to define REST Routes for modules, click [here](../building-modules.md#rest) From 02843324938f29de64fa89585f74e17ca2a03de0 Mon Sep 17 00:00:00 2001 From: Gloria Zhao Date: Fri, 26 Jul 2019 10:34:32 -0700 Subject: [PATCH 053/196] rest and intro done --- docs/interfaces/cli.md | 6 ++-- docs/interfaces/interfaces-intro.md | 44 ++++++++++++++++++++++++++++- docs/interfaces/query-lifecycle.md | 2 ++ docs/interfaces/rest.md | 41 +++++++++++++++++++++------ 4 files changed, 81 insertions(+), 12 deletions(-) diff --git a/docs/interfaces/cli.md b/docs/interfaces/cli.md index 94fca6537b06..75c36f6b3079 100644 --- a/docs/interfaces/cli.md +++ b/docs/interfaces/cli.md @@ -8,18 +8,18 @@ This document describes how to create a commmand-line interface for an SDK application. A separate document for creating a module CLI can be found [here](#../module-interfaces.md#cli). -- [Application CLI](#application-cli) +- [Application CLI Components](#application-cli-components) - [Commands](#commands) - [Flags](#flags) - [Initialization and Configurations](#initialization-and-configurations) -## Application CLI +## Application CLI Components One of the main entrypoints of an application is the command-line interface. This entrypoint is created as a `main.go` file which compiles to a binary, conventionally placed in the application's `app/cmd/cli` folder. The CLI for an application will typically be referred to as the name of the application suffixed with `-cli`, e.g. `appcli`. ### Cobra -There is no set way to create a CLI, but SDK modules all use the [Cobra Library](https://github.com/spf13/cobra) in order to implement the [`AppModuleBasic`]() interface. Building a CLI with Cobra entails defining commands, arguments, and flags. [**Commands**](#commands) represent the action users wish to take, such as `tx` for creating a transaction and `query` for querying the application. Each command can also have nested subcommands, necessary for naming the specific transaction type. Users also supply **Arguments**, such as account numbers to send coins to, and [**Flags**](#flags) to modify various aspects of the commands, such as gas prices or which node to broadcast to. +There is no set way to create a CLI, but SDK modules all use the [Cobra Library](https://github.com/spf13/cobra) in order to implement the [`AppModuleBasic`](../building-modules) interface. Building a CLI with Cobra entails defining commands, arguments, and flags. [**Commands**](#commands) represent the action users wish to take, such as `tx` for creating a transaction and `query` for querying the application. Each command can also have nested subcommands, necessary for naming the specific transaction type. Users also supply **Arguments**, such as account numbers to send coins to, and [**Flags**](#flags) to modify various aspects of the commands, such as gas prices or which node to broadcast to. ### Main Function diff --git a/docs/interfaces/interfaces-intro.md b/docs/interfaces/interfaces-intro.md index 09466179cc60..6e6d91d3f6ec 100644 --- a/docs/interfaces/interfaces-intro.md +++ b/docs/interfaces/interfaces-intro.md @@ -1,3 +1,45 @@ # Interfaces -This document introduces interfaces for SDK applications. The two main interfaces are the Command-Line Interface and REST Interface. +## Prerequisites + +* [Anatomy of an SDK Application](../basics/app-anatomy.md) +* [Lifecycle of a Transaction](../basics/tx-lifecycle.md) + + +## Synopsis + +Every application must include some interface users can use to interact with the defined functionalities. This document introduces user interfaces for SDK applications. + +- [Types of Application Interfaces](#types-of-application-interfaces) +- [Module vs Application Interfaces](#module-vs-application-interfaces) + + [Module Developer Responsibilities](#module-developer-responsibilities) + + [Application Developer Responsibilities](#application-developer-responsibilities) + + +## Types of Application Interfaces + +SDK applications should have a Command-Line Interface (CLI) and REST Interface to support HTTP requests. The SDK is opinionated about how to create these two interfaces; all modules specify [Cobra commands](https://github.com/spf13/cobra) and register routes using [Gorilla Mux routers](https://github.com/gorilla/mux). + + +## Module vs Application Interfaces + +The CLI and REST Interface are conventionally defined in the application `/cmd/cli` folder. The process of creating an application interface is vastly different from a module interface, though the components are closely intertwined. As expected, the module interface handles the bulk of the underlying logic, unpacking user requests into arguments and routes, and neatly marshaling everything into ABCI requests to be handled by Baseapp. On the other hand, the application interface handles the user configurations and customizations, instantiates the application-specific values and objects, and passes everything to module interface functions. + +### Module Developer Responsibilities + +In regards to interfaces, the module developers' responsibilities include: + +* **CLI commands:** Specifically, [Transaction commands](../building-modules/interfaces.md#transaction-commands) and [Query commands](../building-modules/interfaces.md#query-commands). These are commands that users will invoke when interacting with the application. For example, if an application enables sending coins through the [`auth`](https://github.com/cosmos/cosmos-sdk/tree/67f6b021180c7ef0bcf25b6597a629aca27766b8/docs/spec/auth) module, users will create `auth send` transactions. +* **Request Handlers:** Also categorized into Transaction and Query requests. Transactions will require HTTP [Request Types](../building-modules/interfaces.md#request-types) in addition to [Request Handlers](../building-modules/interfaces.md#request-handlers) in order to encapsulate all of the user's options (e.g. gas prices). +* **REST Routes:** Given a router, the module interface registers paths with the aforementioned [Request Handlers](../building-modules/interfaces.md#request-handlers) for each type of request. + +Module interfaces are designed to be generic. Both commands and request types will include required user input (through flags or request body) which will be different for each application. This section of documents will only detail application interfaces; to read about how to build module interfaces, click [here](../building-modules/interfaces.md). + +### Application Developer Responsibilities + +In regards to interfaces, the application developers' responsibilities include: + +* **CLI Root Command:** The root command adds subcommands to include all of the functionality for the application, mainly module transaction and query commands. +* **App Configurations:** All application-specific values are the responsibility of the application developer, including the `codec` used to marshal requests before relaying them to a node. +* **User Configurations:** Some values are specific to the user, such as the user's address and which node they are connected to. +* **RegisterRoutes Function:** To be passed to an instantiated REST Server so that it knows how to route requests for this particular application. diff --git a/docs/interfaces/query-lifecycle.md b/docs/interfaces/query-lifecycle.md index 83fe119d1b7b..78a7ca4e2035 100644 --- a/docs/interfaces/query-lifecycle.md +++ b/docs/interfaces/query-lifecycle.md @@ -2,6 +2,8 @@ ## Prerequisites +[Introduction to Interfaces](./interfaces-intro.md) + ## Synopsis This document describes SDK interfaces in detail through the lifecycle of a query, from the user interface to application stores and back. The query will be referred to as `query`. diff --git a/docs/interfaces/rest.md b/docs/interfaces/rest.md index ba22e264ab2b..9297de98d58b 100644 --- a/docs/interfaces/rest.md +++ b/docs/interfaces/rest.md @@ -3,6 +3,7 @@ ## Prerequisites * [Query Lifecycle](./query-lifecycle.md) +* [Application CLI](./cli.md) ## Synopsis @@ -10,21 +11,45 @@ This document describes how to create a REST interface for an SDK application. A - [Application REST Interface](#application-rest-interface) - [REST Server](#rest-server) -- [Router](#router) - [Registering Routes](#registering-routes) ## Application REST Interface +Building a REST Interface for an application involves creating a REST server to route requests and output responses. The SDK has its own REST Server type used for LCDs (light-client daemons). It has a `ServeCommand` that takes in an application's `codec` and `RegisterRoutes` function, starts up a new SDK REST Server, and registers routes using function provided from the application. To enable this command, it should be added as a subcommand of the root command `RootCmd` in the `main()` function of the CLI interface. + +Users can use the application CLI to start a new LCD, a local server through which they can securely interact with the application without downloading the entire state. The command entered by users would look something like this: + +```bash +appcli rest-server --chain-id --trust-node +``` + ## REST Server -The SDK REST Server has the following: +A REST Server is used to receive and route HTTP Requests, obtain the results from the application, and return the response to the user. The REST Server defined by the SDK LCD package contains the following: + +* **Router:** A router for HTTP requests. A new router can be instantiated for an application and used to match routes based on path, request method, headers, etc. The SDK uses the [Gorilla Mux Router](https://github.com/gorilla/mux). +* **CLIContext:** A [`CLIContext`](./query-lifecycle.md#clicontext) created for a user interaction. +* **Keybase:** A [Keybase](../core/keys-accounts.md) is a key manager. +* **Logger:** A logger from Tendermint `Log`, a log package structured around key-value pairs that allows logging level to be set differently for different keys. The logger takes `Debug()`, `Info()`, and `Error()`s. +* **Listener:** A [listener](https://golang.org/pkg/net/#Listener) from the net package. -* **Mux Router** -* **CLIContext** -* **Keybase** -* **Logger** -* **Listener** +Of the five, the only attribute that developers will need to configure is the router. ## Registering Routes -For information about how to define REST Routes for modules, click [here](../building-modules.md#rest) +To include routes for each module in an application, the CLI must have some kind of function to Register Routes in its REST Server. This `RegisterRoutes` function is utilized by the `ServeCommand` and must include routes for each of the application's modules. Since each module used by an SDK application implements a [`RegisterRESTRoutes`](../building-modules.md#rest) function, application developers simply use the Module Manager to call this function for each module. + +At the bare minimum, a `RegisterRoutes` function should use the SDK client package `RegisterRoutes` function to be able to route RPC calls, and instruct the application Module Manager to call `RegisterRESTRoutes` for all of its modules: + +```go +func registerRoutes(rs *lcd.RestServer) { + client.RegisterRoutes(rs.CliCtx, rs.Mux) + app.ModuleBasics.RegisterRESTRoutes(rs.CliCtx, rs.Mux) +} +``` + +This function is specific to the application and passed in to the `ServeCommand`, which should be added to the `rootCmd` as such: + +```go +rootCmd.AddCommand(lcd.ServeCommand(cdc, registerRoutes)) +``` From 54ced8626a496df18d1b74bc9f5e7a8d68b607dd Mon Sep 17 00:00:00 2001 From: Gloria Zhao Date: Fri, 26 Jul 2019 15:38:50 -0700 Subject: [PATCH 054/196] small edits and links --- docs/interfaces/cli.md | 14 +++++----- docs/interfaces/interfaces-intro.md | 13 +++++++--- docs/interfaces/query-lifecycle.md | 40 ++++++++++++++--------------- docs/interfaces/rest.md | 24 ++++++++++++++++- 4 files changed, 57 insertions(+), 34 deletions(-) diff --git a/docs/interfaces/cli.md b/docs/interfaces/cli.md index 75c36f6b3079..5c8d9b9f4811 100644 --- a/docs/interfaces/cli.md +++ b/docs/interfaces/cli.md @@ -2,7 +2,7 @@ ## Prerequisites -* [Query Lifecycle](./query-lifecycle.md) +* [Lifecycle of a Query](./query-lifecycle.md) ## Synopsis @@ -19,7 +19,7 @@ One of the main entrypoints of an application is the command-line interface. Thi ### Cobra -There is no set way to create a CLI, but SDK modules all use the [Cobra Library](https://github.com/spf13/cobra) in order to implement the [`AppModuleBasic`](../building-modules) interface. Building a CLI with Cobra entails defining commands, arguments, and flags. [**Commands**](#commands) represent the action users wish to take, such as `tx` for creating a transaction and `query` for querying the application. Each command can also have nested subcommands, necessary for naming the specific transaction type. Users also supply **Arguments**, such as account numbers to send coins to, and [**Flags**](#flags) to modify various aspects of the commands, such as gas prices or which node to broadcast to. +There is no set way to create a CLI, but SDK modules all use the [Cobra Library](https://github.com/spf13/cobra) in order to implement the [`AppModuleBasic`](../building-modules/modules-manager.md) interface. Building a CLI with Cobra entails defining commands, arguments, and flags. [**Commands**](#commands) represent the action users wish to take, such as `tx` for creating a transaction and `query` for querying the application. Each command can also have nested subcommands, necessary for naming the specific transaction type. Users also supply **Arguments**, such as account numbers to send coins to, and [**Flags**](#flags) to modify various aspects of the commands, such as gas prices or which node to broadcast to. ### Main Function @@ -49,23 +49,21 @@ The root command (also called `rootCmd`) is what the user first types into the c ### Transaction Commands -Application [transactions](#./transactions.md) are objects that trigger state changes. To enable the creation of transactions using the CLI interface, `TxCmd` should add the following commands: +[Transactions](#./transactions.md) are objects wrapping messages that trigger state changes within modules. To enable the creation of transactions using the CLI interface, `TxCmd` should add the following commands: -* **Sign** command from the [`auth`](https://github.com/cosmos/cosmos-sdk/tree/67f6b021180c7ef0bcf25b6597a629aca27766b8/docs/spec/auth) module, which signs messages in a transaction. To enable multisig, it should also add the `auth` module MultiSign command. Since every transaction requires some sort of signature in order to be valid, this command is necessary for every application. +* **Sign** command from the [`auth`](https://github.com/cosmos/cosmos-sdk/blob/master/docs/spec/auth) module, which signs messages in a transaction. To enable multisig, it should also add the `auth` module MultiSign command. Since every transaction requires some sort of signature in order to be valid, this command is necessary for every application. * **Broadcast** command from the SDK client tools, which broadcasts transactions. -* **Send** command from the [`bank`](https://github.com/cosmos/cosmos-sdk/tree/67f6b021180c7ef0bcf25b6597a629aca27766b8/docs/spec/bank) module, which is a transaction that allows accounts to send coins to one another, including gas and fees for transactions. -* Any application-specific transaction commands defined by the application developer. +* **Send** command from the [`bank`](https://github.com/cosmos/cosmos-sdk/blob/master/docs/spec/bank) module, which is a transaction that allows accounts to send coins to one another, including gas and fees for transactions. * All commands in each module the application is dependent on, retrieved by calling `GetTxCmd()` on all the modules or using the Module Manager's `AddTxCommands()` function. ### Query Commands -Application queries are objects that allow users to retrieve information about the application's state. To enable basic queries, `QueryCmd` should add the following commands: +[**Queries**](../building-modules/messages-and-queries.md#queries) are objects that allow users to retrieve information about the application's state. To enable basic queries, `QueryCmd` should add the following commands: * **QueryTx** and/or other transaction query commands from the `auth` module which allow the user to search for a transaction by inputting its hash, a list of tags, or a block height. These various queries allow users to see if transactions have been included in a block. * **Account** command from the `auth` module, which displays the state (e.g. account balance) of an account given an address. * **Validator** command from the SDK rpc client tools, which displays the validator set of a given height. * **Block** command from the SDK rpc client tools, which displays the block data for a given height. -* Any application-specific query commands defined by the application developer. * All commands in each module the application is dependent on, retrieved by calling `GetQueryCmd()` on all the modules or using the Module Manager's `AddQueryCommands()` function. ## Flags diff --git a/docs/interfaces/interfaces-intro.md b/docs/interfaces/interfaces-intro.md index 6e6d91d3f6ec..9e68ee971027 100644 --- a/docs/interfaces/interfaces-intro.md +++ b/docs/interfaces/interfaces-intro.md @@ -18,18 +18,18 @@ Every application must include some interface users can use to interact with the ## Types of Application Interfaces -SDK applications should have a Command-Line Interface (CLI) and REST Interface to support HTTP requests. The SDK is opinionated about how to create these two interfaces; all modules specify [Cobra commands](https://github.com/spf13/cobra) and register routes using [Gorilla Mux routers](https://github.com/gorilla/mux). +SDK applications should have a Command-Line Interface (CLI) and REST Interface to support HTTP requests. The SDK is opinionated about how to create these two interfaces; all modules specify [Cobra commands](https://github.com/spf13/cobra) and register routes using [Gorilla Mux routers](https://github.com/gorilla/mux). The CLI and REST Interface are conventionally defined in the application `/cmd/cli` folder. ## Module vs Application Interfaces -The CLI and REST Interface are conventionally defined in the application `/cmd/cli` folder. The process of creating an application interface is vastly different from a module interface, though the components are closely intertwined. As expected, the module interface handles the bulk of the underlying logic, unpacking user requests into arguments and routes, and neatly marshaling everything into ABCI requests to be handled by Baseapp. On the other hand, the application interface handles the user configurations and customizations, instantiates the application-specific values and objects, and passes everything to module interface functions. +The process of creating an application interface is very different from creating a module interface, though the components are closely intertwined. As expected, the module interface handles the bulk of the underlying logic, unpacking user requests into arguments and routes, and neatly marshaling everything into ABCI requests to be handled by Baseapp. On the other hand, the application interface handles the user configurations and customizations, instantiates the application-specific values and objects, and passes everything to module interface functions. ### Module Developer Responsibilities In regards to interfaces, the module developers' responsibilities include: -* **CLI commands:** Specifically, [Transaction commands](../building-modules/interfaces.md#transaction-commands) and [Query commands](../building-modules/interfaces.md#query-commands). These are commands that users will invoke when interacting with the application. For example, if an application enables sending coins through the [`auth`](https://github.com/cosmos/cosmos-sdk/tree/67f6b021180c7ef0bcf25b6597a629aca27766b8/docs/spec/auth) module, users will create `auth send` transactions. +* **CLI commands:** Specifically, [Transaction commands](../building-modules/interfaces.md#transaction-commands) and [Query commands](../building-modules/interfaces.md#query-commands). These are commands that users will invoke when interacting with the application to create transactions and queries. For example, if an application enables sending coins through the [`auth`](https://github.com/cosmos/cosmos-sdk/tree/67f6b021180c7ef0bcf25b6597a629aca27766b8/docs/spec/auth) module, users will create `tx auth send` transactions. * **Request Handlers:** Also categorized into Transaction and Query requests. Transactions will require HTTP [Request Types](../building-modules/interfaces.md#request-types) in addition to [Request Handlers](../building-modules/interfaces.md#request-handlers) in order to encapsulate all of the user's options (e.g. gas prices). * **REST Routes:** Given a router, the module interface registers paths with the aforementioned [Request Handlers](../building-modules/interfaces.md#request-handlers) for each type of request. @@ -41,5 +41,10 @@ In regards to interfaces, the application developers' responsibilities include: * **CLI Root Command:** The root command adds subcommands to include all of the functionality for the application, mainly module transaction and query commands. * **App Configurations:** All application-specific values are the responsibility of the application developer, including the `codec` used to marshal requests before relaying them to a node. -* **User Configurations:** Some values are specific to the user, such as the user's address and which node they are connected to. +* **User Configurations:** Some values are specific to the user, such as the user's address and which node they are connected to. * **RegisterRoutes Function:** To be passed to an instantiated REST Server so that it knows how to route requests for this particular application. + + +## Next + +Read about the [Lifecycle of a Query](./query-lifecycle.md). diff --git a/docs/interfaces/query-lifecycle.md b/docs/interfaces/query-lifecycle.md index 78a7ca4e2035..b95d6980fae0 100644 --- a/docs/interfaces/query-lifecycle.md +++ b/docs/interfaces/query-lifecycle.md @@ -2,11 +2,11 @@ ## Prerequisites -[Introduction to Interfaces](./interfaces-intro.md) +* [Introduction to Interfaces](./interfaces-intro.md) ## Synopsis -This document describes SDK interfaces in detail through the lifecycle of a query, from the user interface to application stores and back. The query will be referred to as `query`. +This document describes SDK interfaces in detail through the lifecycle of a query, from the user interface to application stores and back. The query will be referred to as `Query`. - [Interfaces](#interfaces) - [CLIContext](#clicontext) @@ -16,35 +16,33 @@ This document describes SDK interfaces in detail through the lifecycle of a quer ## Interfaces -A **query** is a request for information made by users of applications. They can query information about the network, the application itself, and application state directly from the application's stores or modules. +A [**query**](../building-modules/messages-and-queries.md#queries) is a request for information made by users of applications. Users can query information about the network, the application itself, and application state directly from the application's stores or modules. -For the purpose of explaining a query lifecycle, let's say `query` is requesting a list of delegations made by a certain delegator address in the application called `app`. There are a few ways `query` can be made on the user side. +For the purpose of explaining a query lifecycle, let's say `Query` is requesting a list of delegations made by a certain delegator address in the application called `app`. There are a few ways `Query` can be made on the user side. ### CLI -The main interface for an application is the command-line interface. Users run the CLI directly from their machines and type commands to create queries. To create this query from the command-line, users would type the following command: +The main interface for an application is the command-line interface. Users run the CLI directly from their machines and type commands to create queries. To create this query from their terminal, users would type the following command: ``` appcli query staking delegations ``` -To provide values such as `--chain-id`, the ID of the blockchain to make the query to, the user must use the `config` command to set them or provide them as flags. +To provide values such as `--chain-id` (the ID of the blockchain to make the query to), the user must use the `config` command to set them or provide them as flags. -This query command is defined by the module developer and added to the list of subcommands by the application developer when creating the CLI. To see the command itself, click [here](). +This query command is defined by the module developer and added to the list of subcommands by the application developer when creating the CLI. ### REST Another interface through which users can make queries is through HTTP Requests to a REST server. The REST server contains, among other things, a [`CLIContext`](#clicontext) and [mux](./rest.md#gorilla-mux) router. The request looks like this: ```bash -http://localhost:{PORT}/staking/delegators/{delegatorAddr}/delegations +GET http://localhost:{PORT}/staking/delegators/{delegatorAddr}/delegations ``` -To provide values such as `--chain-id`, the ID of the blockchain to make the query to, the user must configure their REST server with the values or provide them in the request body. +To provide values such as `--chain-id` (the ID of the blockchain to make the query to), the user must configure their local REST server with the values or provide them in the request body. -The router automatically routes the `query` HTTP request to the staking module `delegatorDelegationsHandlerFn()` function (to see the handler itself, click [here]()). Since this function is defined within the module and thus has no inherent knowledge of the application `query` belongs to, it takes in the application `codec` and `CLIContext` as parameters. - -To read about how the router is used, click [here](./rest.md). +The router automatically routes the `Query` HTTP request to the staking module `delegatorDelegationsHandlerFn()` function (to see the handler itself, click [here]()). Since this function is defined within the module and thus has no inherent knowledge of the application `Query` belongs to, it takes in the application `codec` and `CLIContext` as parameters. ## Request and Command Handling @@ -55,29 +53,29 @@ The interactions from the users' perspective are a bit different, but the underl The first thing that is created in the execution of a CLI command is a `CLIContext`, while the REST Server directly provides a `CLIContext` for the REST Request handler. A [Context](../core/context.md) is an immutable object that stores all the data needed to process a request. In particular, a `CLIContext` stores the following: * **Codec**: The encoder/decoder used by the application, used to marshal the parameters and query before making the Tendermint RPC request and unmarshal the returned response into a JSON object. -* **Account Decoder**: The account decoder from the [`auth`](https://github.com/cosmos/cosmos-sdk/tree/67f6b021180c7ef0bcf25b6597a629aca27766b8/docs/spec/auth) module, which translates `[]byte`s into accounts. -* **RPC Client**: The [Tendermint RPC Client](https://github.com/tendermint/tendermint/blob/master/rpc/client/interface.go). +* **Account Decoder**: The account decoder from the [`auth`](.../spec/auth) module, which translates `[]byte`s into accounts. +* **RPC Client**: The [Tendermint RPC Client](https://github.com/tendermint/tendermint/blob/master/rpc/client/interface.go), or node, to which the request will be relayed to. * **Keybase**: A [Key Manager](.//core/accounts-keys.md) used to sign transactions and handle other operations with keys. * **Output Writer**: A [Writer](https://golang.org/pkg/io/#Writer) used to output the response. * **Configurations**: The flags configured by the user for this command, including `--height`, specifying the height of the blockchain to query and `--indent`, which indicates to add an indent to the JSON response. -For full specification of the `CLIContext` type, click [here](https://github.com/cosmos/cosmos-sdk/blob/73e5ef7c13c420f9ee879fdf1b60cf0bdc8f325e/client/context/context.go#L36-L59). +For full specification of the `CLIContext` type, click [here](https://github.com/cosmos/cosmos-sdk/blob/master/client/context/context.go#L36-L59). ### Parameters and Route Creation The next step is to parse the command or request, extract the arguments, create a `queryRoute`, and encode everything. -In this case, `query` contains a `delegatorAddress` as its only argument. However, the request can only contain `[]byte`s, as it will be relayed to a consensus engine node that has no inherent knowledge of the application types. Thus, the `CLIContext` `codec` is used to marshal the address as the type `QueryDelegatorParams`. All query arguments (e.g. the `staking` module also has `QueryValidatorParams` and `QueryBondsParams`) have their own types that the application `codec` understands how to encode and decode. The module [`querier`](.//building-modules/querier.md) declares these types and the application registers the `codec`s. +In this case, `Query` contains a `delegatorAddress` as its only argument. However, the request can only contain `[]byte`s, as it will be relayed to a consensus engine node that has no inherent knowledge of the application types. Thus, the `CLIContext` `codec` is used to marshal the address as the type `QueryDelegatorParams`. All query arguments (e.g. the `staking` module also has `QueryValidatorParams` and `QueryBondsParams`) have their own types that the application `codec` understands how to encode and decode. The module [`querier`](.//building-modules/querier.md) declares these types and the application registers the `codec`s. -A `route` is also created for `query` so that the application will understand which module to route the query to. Baseapp will understand this query to be a `custom` query in the module `staking` with the type `QueryDelegatorDelegations`. Thus, the route will be `"custom/staking/delegatorDelegations"`. +A `route` is also created for `Query` so that the application will understand which module to route the query to. Baseapp will understand this query to be a `custom` query in the module `staking` with the type `QueryDelegatorDelegations`. Thus, the route will be `"custom/staking/delegatorDelegations"`. ### ABCI Query -The `CLIContext`'s main `query` function takes the `route`, which is now called `path`, and arguments, now called `key`. It first retrieves the RPC Client (called the **node**) configured by the user to relay this query to, and creates the `ABCIQueryOptions` (parameters formatted for the ABCI call). The node is then used to make the ABCI call, `ABCIQueryWithOptions`. +The `CLIContext`'s main `Query` function takes the `route`, which is now called `path`, and arguments, now called `key`. It first retrieves the RPC Client (called the **node**) configured by the user to relay this query to, and creates the `ABCIQueryOptions` (parameters formatted for the ABCI call). The node is then used to make the ABCI call, `ABCIQueryWithOptions`. ## Tendermint and ABCI -With a call to `ABCIQueryWithOptions()`, `query` arrives at the consensus engine portion of its lifecycle. Nodes running the consensus engine (e.g. Tendermint Core) make ABCI calls to interact with the application. At this point, `query` exists as an ABCI `RequestQuery` and the [ABCI Client](https://github.com/tendermint/tendermint/blob/51b3428f5c0f4fdd2e469147cd90353faa4bd704/abci/client/client.go#L16-L50) calls the ABCI method [`Query()`](https://tendermint.com/docs/spec/abci/abci.html#query) on the application. +With a call to `ABCIQueryWithOptions()`, `Query` arrives at the consensus engine portion of its lifecycle. Nodes running the consensus engine (e.g. Tendermint Core) make ABCI calls to interact with the application. At this point, `Query` exists as an ABCI `RequestQuery` and the [ABCI Client](https://github.com/tendermint/tendermint/blob/51b3428f5c0f4fdd2e469147cd90353faa4bd704/abci/client/client.go#L16-L50) calls the ABCI method [`Query()`](https://tendermint.com/docs/spec/abci/abci.html#query) on the application. Read more about ABCI Clients and Tendermint RPC in the Tendermint documentation [here](https://tendermint.com/rpc). @@ -85,11 +83,11 @@ Read more about ABCI Clients and Tendermint RPC in the Tendermint documentation [Baseapp](../core/baseapp.md) implements the ABCI [`Query()`](../core/baseapp.md#query) function and handles four different types of queries: `app`, `store`, `p2p`, and `custom`. The `queryRoute` is parsed such that the first string must be one of the four options, then the rest of the path is parsed within the subroutines handling each type of query. The first three types are application-level and thus directly handled by Baseapp or the stores, but the `custom` query type requires Baseapp to route the query to a module's [querier](../building-modules/querier.md). -Since `query` is a custom query type, Baseapp first parses the path, then uses the `QueryRouter` to retrieve the corresponding querier. +Since `Query` is a custom query type, Baseapp first parses the path, then uses the `QueryRouter` to retrieve the corresponding querier. The querier is responsible for recognizing this query, retrieving the appropriate values from the application's stores, and returning a response. ## Response -Since `Query()` is an ABCI function, Baseapp returns the `query` response as an `abci.ResponseQuery`. The `CLIContext` `query` routine receives the response and, if `--trust-node` is toggled to `false` and a proof needs to be verified, the response is verified with the `CLIContext` `verifyProof` function before the response is returned. +Since `Query()` is an ABCI function, Baseapp returns the `Query` response as an `abci.ResponseQuery`. The `CLIContext` `Query` routine receives the response and, if `--trust-node` is toggled to `false` and a proof needs to be verified, the response is verified with the `CLIContext` `verifyProof` function before the response is returned. ### CLI Response diff --git a/docs/interfaces/rest.md b/docs/interfaces/rest.md index 9297de98d58b..ce3b8db10b42 100644 --- a/docs/interfaces/rest.md +++ b/docs/interfaces/rest.md @@ -10,12 +10,13 @@ This document describes how to create a REST interface for an SDK application. A separate document for creating module REST Routes can be found [here](#../module-interfaces.md#rest). - [Application REST Interface](#application-rest-interface) +- [Request Types](#request-types) - [REST Server](#rest-server) - [Registering Routes](#registering-routes) ## Application REST Interface -Building a REST Interface for an application involves creating a REST server to route requests and output responses. The SDK has its own REST Server type used for LCDs (light-client daemons). It has a `ServeCommand` that takes in an application's `codec` and `RegisterRoutes` function, starts up a new SDK REST Server, and registers routes using function provided from the application. To enable this command, it should be added as a subcommand of the root command `RootCmd` in the `main()` function of the CLI interface. +Building the REST Interface for an application involves creating a REST server to route requests and output responses. The SDK has its own REST Server type used for LCDs (light-client daemons). It has a `ServeCommand` that takes in an application's `codec` and `RegisterRoutes` function, starts up a new SDK REST Server, and registers routes using function provided from the application. To enable this command, it should be added as a subcommand of the root command `RootCmd` in the `main()` function of the CLI interface. Users can use the application CLI to start a new LCD, a local server through which they can securely interact with the application without downloading the entire state. The command entered by users would look something like this: @@ -23,6 +24,27 @@ Users can use the application CLI to start a new LCD, a local server through whi appcli rest-server --chain-id --trust-node ``` +## Request Types + +HTTP Request types are defined by the module interfaces for every type of transaction. The structs all include a base request `baseReq`, the name of the request, and any arguments for the transaction. + +### BaseReq + +`BaseReq` is a type defined in the SDK that encapsulates much of the transaction configurations similar to CLI command flags. Users must provide the information in the body of their requests. + +* `From` indicates which account the transaction originates from. This account is used to sign the transaction. +* `Memo` sends a memo along with the transaction. +* `ChainID` specifies the unique identifier of the blockchain the transaction pertains to. +* `AccountNumber` is an identifier for the account. +* `Sequence`is the value of a counter measuring how many transactions have been sent from the account. It is used to prevent replay attacks. +* `Gas` refers to how much gas, which represents computational resources, Tx consumes. Gas is dependent on the transaction and is not precisely calculated until execution, but can be estimated by providing auto as the value for `Gas`. +* `GasAdjustment` can be used to scale gas up in order to avoid underestimating. For example, users can specify their gas adjustment as 1.5 to use 1.5 times the estimated gas. +* `GasPrices` specifies how much the user is willing pay per unit of gas, which can be one or multiple denominations of tokens. For example, --gas-prices=0.025uatom, 0.025upho means the user is willing to pay 0.025uatom AND 0.025upho per unit of gas. +* `Fees` specifies how much in fees the user is willing to pay in total. Note that the user only needs to provide either `gas-prices` or `fees`, but not both, because they can be derived from each other. +* `Simulate` instructs the application to ignore gas and simulate the transaction running without broadcasting. + +Additionally, each request may contain arguments such as a specific address pertaining to the request. + ## REST Server A REST Server is used to receive and route HTTP Requests, obtain the results from the application, and return the response to the user. The REST Server defined by the SDK LCD package contains the following: From e3d819ee096ff8a66eed5b1cc14ad75ac65cf06d Mon Sep 17 00:00:00 2001 From: Gloria Zhao Date: Tue, 30 Jul 2019 20:35:21 -0700 Subject: [PATCH 055/196] comments --- docs/building-modules/module-interfaces.md | 34 +++++++++------------- docs/interfaces/cli.md | 4 +-- 2 files changed, 16 insertions(+), 22 deletions(-) diff --git a/docs/building-modules/module-interfaces.md b/docs/building-modules/module-interfaces.md index c3ddea3298aa..a75b5b0d169a 100644 --- a/docs/building-modules/module-interfaces.md +++ b/docs/building-modules/module-interfaces.md @@ -145,11 +145,11 @@ Finally, the module also needs a `GetQueryCmd`, which aggregates all of the quer [Flags](../interfaces/cli.md#flags) are entered by the user and allow for command customizations. Examples include the [fees](../core/accounts-fees.md) or gas prices users are willing to pay for their transactions. -The flags for a module are typically found in a `flags.go` file in the `./x/moduleName/client/cli` folder. Module developers can create a list of possible flags including the value type, default value, and a description displayed if the user uses a `help` command. In each transaction getter function, they can add flags to the commands and, optionally, mark flags as *required* so that an error is thrown if the user does not provide values for them. +The flags for a module are typically found in the `flags.go` file in the `./x/moduleName/client/cli` folder. Module developers can create a list of possible flags including the value type, default value, and a description displayed if the user uses a `help` command. In each transaction getter function, they can add flags to the commands and, optionally, mark flags as *required* so that an error is thrown if the user does not provide values for them. For full details on flags, visit the [Cobra Documentation](https://github.com/spf13/cobra). -For example, the SDK `./client/flags` package includes a [`PostCommands()`](https://github.com/cosmos/cosmos-sdk/blob/master/client/flags/flags.go#L85-L116) function that adds necessary flags to transaction commands, such as the `from` flag to indicate which address the transaction originates from. Here is an example of how to add a flag using the `from` flag from this function. +For example, the SDK `./client/flags` package includes a [`PostCommands`](https://github.com/cosmos/cosmos-sdk/blob/master/client/flags/flags.go#L85-L116) function that adds necessary flags to transaction commands, such as the `from` flag to indicate which address the transaction originates from. Here is an example of how to add a flag using the `from` flag from this function. ```go cmd.Flags().String(FlagFrom, "", "Name or address of private key with which to sign") @@ -163,11 +163,11 @@ A flag can be marked as *required* so that an error is automatically thrown if t cmd.MarkFlagRequired(FlagFrom) ``` -Since `PostCommands()` includes all of the basic flags required for a transaction command, module developers may choose not to add any of their own (specifying arguments instead may often be more appropriate). For a full list of what flags are included in the `PostCommands()` function, including which are required inputs from users, see the CLI documentation [here](../interfaces/cli.md#transaction-flags). +For a full list of what flags are in `PostCommands`, including which are required inputs from users, see the CLI documentation [here](../interfaces/cli.md#transaction-flags). ## REST -Applications are typically required to support web services that use HTTP requests (e.g. a web wallet like [Lunie.io](lunie.io)). Thus, application developers will also use REST Routes to route HTTP requests to the application's modules; these routes will be used by service providers. The module developer's responsibility is to define the REST client by defining [routes](#register-routes) for all possible [requests](#request-types) and [handlers](#request-handlers) for each of them. It's up to the module developer how to organize the REST interface files; there is typically a `rest.go` file found in the module's `./x/moduleName/client/rest` folder. +Applications are typically required to support web services that use HTTP requests (e.g. a web wallet like [Lunie.io](lunie.io)). Thus, application developers will also use REST Routes to route HTTP requests to the application's modules; these routes will be used by service providers. The module developer's responsibility is to define the REST client by defining routes for all possible requests and handlers for each of them. The REST interface file `rest.go` is typically found in the module's `./x/moduleName/client/rest` folder. ### Request Types @@ -183,24 +183,8 @@ type buyNameReq struct { Buyer string `json:"buyer"` } ``` - The `BaseReq` includes basic information that every request needs to have, similar to required flags in a CLI. All of these values, including `GasPrices` and `AccountNumber`, will be provided in the request body. The user will also need to specify the arguments `Name` and `Amount` fields in the body and `Buyer` will be provided by the user's address. -#### BaseReq - -`BaseReq` is a type defined in the SDK that encapsulates much of the transaction configurations similar to CLI command flags. Users must provide the information in the body of their requests. - -* `From` indicates which [account](../core/accounts-fees.md) the transaction originates from. This account is used to sign the transaction. -* `Memo` sends a memo along with the transaction. -* `ChainID` specifies the unique identifier of the blockchain the transaction pertains to. -* `AccountNumber` is an identifier for the account. -* `Sequence`is the value of a counter measuring how many transactions have been sent from the account. It is used to prevent replay attacks. -* `Gas` refers to how much [gas](../core/gas.md), which represents computational resources, Tx consumes. Gas is dependent on the transaction and is not precisely calculated until execution, but can be estimated by providing auto as the value for `Gas`. -* `GasAdjustment` can be used to scale gas up in order to avoid underestimating. For example, users can specify their gas adjustment as 1.5 to use 1.5 times the estimated gas. -* `GasPrices` specifies how much the user is willing pay per unit of gas, which can be one or multiple denominations of tokens. For example, --gas-prices=0.025uatom, 0.025upho means the user is willing to pay 0.025uatom AND 0.025upho per unit of gas. -* `Fees` specifies how much in [fees](../core/accounts-fees.md) the user is willing to pay in total. Note that the user only needs to provide either `gas-prices` or `fees`, but not both, because they can be derived from each other. -* `Simulate` instructs the application to ignore gas and simulate the transaction running without broadcasting. - ### Request Handlers Request handlers must be defined for both transaction and query requests. Handlers' arguments include a reference to the application's `codec` and the [`CLIContext`](../interfaces/query-lifecycle.md#clicontext) created in the user interaction. @@ -257,6 +241,16 @@ To read more about how a transaction is generated, visit the transactions docume ### Register Routes +The request handler can be broken down as follows: + +* **Parse Request:** The request handler first attempts to parse the request, and then run `Sanitize` and `ValidateBasic` on the underlying `BaseReq` to check the validity of the request. Next, it attempts to parse the arguments `Buyer` and `Amount` to the types `AccountAddress` and `Coins` respectively. +* **Message:** Then, a [message](./messages-and-queries.md) of the type `MsgBuyName` (defined by the module developer to trigger the state changes for this transaction) is created from the values and another sanity check, `ValidateBasic` is run on it. +* **Generate Transaction:** Finally, the HTTP `ResponseWriter`, application [`codec`](../core/encoding.md), [`CLIContext`](../interfaces/query-lifecycle.md#clicontext), request [`BaseReq`](../interfaces/rest.md#basereq), and message is passed to `WriteGenerateStdTxResponse` to further process the request. + +To read more about how a transaction is generated, visit the transactions documentation [here](../core/transactions.md#transaction-generation). + +### Register Routes + The application CLI entrypoint will have a `RegisterRoutes` function in its `main.go` file, which calls the `registerRoutes` functions of each module utilized by the application. Module developers need to implement `registerRoutes` for their modules so that applications are able to route messages and queries to their corresponding handlers and queriers. The router used by the SDK is [Gorilla Mux](https://github.com/gorilla/mux). The router is initialized with the Gorilla Mux `NewRouter()` function. Then, the router's `HandleFunc` function can then be used to route urls with the defined request handlers and the HTTP method (e.g. "POST", "GET") as a route matcher. It is recommended to prefix every route with the name of the module to avoid collisions with other modules that have the same query or transaction names. diff --git a/docs/interfaces/cli.md b/docs/interfaces/cli.md index 5c8d9b9f4811..974ca5384e33 100644 --- a/docs/interfaces/cli.md +++ b/docs/interfaces/cli.md @@ -78,7 +78,7 @@ It is common to add a _persistent_ flag for `--chain-id`, the unique identifier ### Transaction Flags -To **create** a transaction, the user enters a `tx` command and provides several flags. +To **create** a transaction, the user enters a `tx` command and provides several flags. These are the basic flags added to every command using the SDK `./client/flags` package [`PostCommands`](https://github.com/cosmos/cosmos-sdk/blob/master/client/flags/flags.go#L85-L116) function: * `--from` indicates which account the transaction originates from. This account is used to sign the transaction. * `--gas` refers to how much gas, which represents computational resources, Tx consumes. Gas is dependent on the transaction and is not precisely calculated until execution, but can be estimated by providing auto as the value for --gas. @@ -124,7 +124,7 @@ appcli tx broadcast mySignedTx.json --node ``` ### Query Flags -Queries also have flags. +Queries also have flags. These are the basic flags added to every command using the SDK `./client/flags` package [`GetCommand`](https://github.com/cosmos/cosmos-sdk/blob/master/client/flags/flags.go#L67-L82) function: * `--node` indicates which full-node to connect to. * `--trust-node` (optional) represents whether or not the connected node is trusted. If the node is not trusted, all proofs in the responses are verified. From 4f040c42186643749d6d5a32b57409beb6935253 Mon Sep 17 00:00:00 2001 From: Gloria Zhao Date: Fri, 2 Aug 2019 15:31:21 -0700 Subject: [PATCH 056/196] revisions --- docs/building-modules/module-interfaces.md | 17 +-- docs/interfaces/cli.md | 149 +++++++++++++++++++-- docs/interfaces/interfaces-intro.md | 20 +-- docs/interfaces/query-lifecycle.md | 34 ++--- docs/interfaces/rest.md | 12 +- 5 files changed, 173 insertions(+), 59 deletions(-) diff --git a/docs/building-modules/module-interfaces.md b/docs/building-modules/module-interfaces.md index a75b5b0d169a..e4a1ff940713 100644 --- a/docs/building-modules/module-interfaces.md +++ b/docs/building-modules/module-interfaces.md @@ -145,11 +145,11 @@ Finally, the module also needs a `GetQueryCmd`, which aggregates all of the quer [Flags](../interfaces/cli.md#flags) are entered by the user and allow for command customizations. Examples include the [fees](../core/accounts-fees.md) or gas prices users are willing to pay for their transactions. -The flags for a module are typically found in the `flags.go` file in the `./x/moduleName/client/cli` folder. Module developers can create a list of possible flags including the value type, default value, and a description displayed if the user uses a `help` command. In each transaction getter function, they can add flags to the commands and, optionally, mark flags as *required* so that an error is thrown if the user does not provide values for them. +The flags for a module are typically found in a `flags.go` file in the `./x/moduleName/client/cli` folder. Module developers can create a list of possible flags including the value type, default value, and a description displayed if the user uses a `help` command. In each transaction getter function, they can add flags to the commands and, optionally, mark flags as *required* so that an error is thrown if the user does not provide values for them. For full details on flags, visit the [Cobra Documentation](https://github.com/spf13/cobra). -For example, the SDK `./client/flags` package includes a [`PostCommands`](https://github.com/cosmos/cosmos-sdk/blob/master/client/flags/flags.go#L85-L116) function that adds necessary flags to transaction commands, such as the `from` flag to indicate which address the transaction originates from. Here is an example of how to add a flag using the `from` flag from this function. +For example, the SDK `./client/flags` package includes a [`PostCommands()`](https://github.com/cosmos/cosmos-sdk/blob/master/client/flags/flags.go#L85-L116) function that adds necessary flags to transaction commands, such as the `from` flag to indicate which address the transaction originates from. Here is an example of how to add a flag using the `from` flag from this function. ```go cmd.Flags().String(FlagFrom, "", "Name or address of private key with which to sign") @@ -163,11 +163,11 @@ A flag can be marked as *required* so that an error is automatically thrown if t cmd.MarkFlagRequired(FlagFrom) ``` -For a full list of what flags are in `PostCommands`, including which are required inputs from users, see the CLI documentation [here](../interfaces/cli.md#transaction-flags). +Since `PostCommands()` includes all of the basic flags required for a transaction command, module developers may choose not to add any of their own (specifying arguments instead may often be more appropriate). For a full list of what flags are included in the `PostCommands()` function, including which are required inputs from users, see the CLI documentation [here](../interfaces/cli.md#transaction-flags). ## REST -Applications are typically required to support web services that use HTTP requests (e.g. a web wallet like [Lunie.io](lunie.io)). Thus, application developers will also use REST Routes to route HTTP requests to the application's modules; these routes will be used by service providers. The module developer's responsibility is to define the REST client by defining routes for all possible requests and handlers for each of them. The REST interface file `rest.go` is typically found in the module's `./x/moduleName/client/rest` folder. +Applications are typically required to support web services that use HTTP requests (e.g. a web wallet like [Lunie.io](lunie.io)). Thus, application developers will also use REST Routes to route HTTP requests to the application's modules; these routes will be used by service providers. The module developer's responsibility is to define the REST client by defining [routes](#register-routes) for all possible [requests](#request-types) and [handlers](#request-handlers) for each of them. It's up to the module developer how to organize the REST interface files; there is typically a `rest.go` file found in the module's `./x/moduleName/client/rest` folder. ### Request Types @@ -239,15 +239,6 @@ The request handler can be broken down as follows: To read more about how a transaction is generated, visit the transactions documentation [here](../core/transactions.md#transaction-generation). -### Register Routes - -The request handler can be broken down as follows: - -* **Parse Request:** The request handler first attempts to parse the request, and then run `Sanitize` and `ValidateBasic` on the underlying `BaseReq` to check the validity of the request. Next, it attempts to parse the arguments `Buyer` and `Amount` to the types `AccountAddress` and `Coins` respectively. -* **Message:** Then, a [message](./messages-and-queries.md) of the type `MsgBuyName` (defined by the module developer to trigger the state changes for this transaction) is created from the values and another sanity check, `ValidateBasic` is run on it. -* **Generate Transaction:** Finally, the HTTP `ResponseWriter`, application [`codec`](../core/encoding.md), [`CLIContext`](../interfaces/query-lifecycle.md#clicontext), request [`BaseReq`](../interfaces/rest.md#basereq), and message is passed to `WriteGenerateStdTxResponse` to further process the request. - -To read more about how a transaction is generated, visit the transactions documentation [here](../core/transactions.md#transaction-generation). ### Register Routes diff --git a/docs/interfaces/cli.md b/docs/interfaces/cli.md index 974ca5384e33..6287c0d24026 100644 --- a/docs/interfaces/cli.md +++ b/docs/interfaces/cli.md @@ -11,7 +11,7 @@ This document describes how to create a commmand-line interface for an SDK appli - [Application CLI Components](#application-cli-components) - [Commands](#commands) - [Flags](#flags) -- [Initialization and Configurations](#initialization-and-configurations) +- [Configurations](#configurations) ## Application CLI Components @@ -19,19 +19,19 @@ One of the main entrypoints of an application is the command-line interface. Thi ### Cobra -There is no set way to create a CLI, but SDK modules all use the [Cobra Library](https://github.com/spf13/cobra) in order to implement the [`AppModuleBasic`](../building-modules/modules-manager.md) interface. Building a CLI with Cobra entails defining commands, arguments, and flags. [**Commands**](#commands) represent the action users wish to take, such as `tx` for creating a transaction and `query` for querying the application. Each command can also have nested subcommands, necessary for naming the specific transaction type. Users also supply **Arguments**, such as account numbers to send coins to, and [**Flags**](#flags) to modify various aspects of the commands, such as gas prices or which node to broadcast to. +There is no set way to create a CLI, but SDK modules all use the [Cobra Library](https://github.com/spf13/cobra) in order to implement the [`AppModuleBasic`](../building-modules/modules-manager.md) interface. Building a CLI with Cobra entails defining commands, arguments, and flags. [**Commands**](#commands) understand the actions users wish to take, such as `tx` for creating a transaction and `query` for querying the application. Each command can also have nested subcommands, necessary for naming the specific transaction type. Users also supply **Arguments**, such as account numbers to send coins to, and [**Flags**](#flags) to modify various aspects of the commands, such as gas prices or which node to broadcast to. ### Main Function The `main.go` file needs to have a `main()` function that does the following to run the command-line interface: -* **Instantiate the `codec`** by calling the application's `MakeCodec()` function. The `codec` is used to code and encode data structures for the application - stores can only persist `[]byte`s so the developer must define a serialization format for their data structures or use the default, [Amino](./amino.md). +* **Instantiate the `codec`** by calling the application's `MakeCodec()` function. The [`codec`](../core/encoding.md) is used to code and encode data structures for the application - stores can only persist `[]byte`s so the developer must define a serialization format for their data structures or use the default, [Amino](../core/amino.md). * **Configurations** are set by reading in configuration files (e.g. the sdk config file). * **Create the root command** to which all the application commands will be added as subcommands and add any required flags to it, such as `--chain-id`. * **Add subcommands** for all the possible user interactions, including [transaction commands](#transaction-commands) and [query commands](#query-commands). * **Create an Executor** and execute the root command. -The rest of the document will detail what needs to be implemented for each step. +An example of the `main()` function for the [nameservice tutorial](https://cosmos.network/docs/tutorial) CLI can be found [here](https://github.com/cosmos/sdk-application-tutorial/blob/master/cmd/nscli/main.go#L26-L67). The rest of the document will detail what needs to be implemented for each step and include smaller portions of code from the nameservice CLI `main.go` file. ## Commands @@ -41,20 +41,74 @@ Every application CLI first constructs a root command, then adds functionality b The root command (also called `rootCmd`) is what the user first types into the command line to indicate which application they wish to interact with. The string used to invoke the command (the "Use" field) is typically the name of the application suffixed with `-cli`, e.g. `appcli`. The root command must include the following commands to support basic functionality in the application. -* **Status** command from the SDK rpc client tools, which prints information about the status of the connected `Node`. +* **Status** command from the SDK rpc client tools, which prints information about the status of the connected [`Node`](,,/core/node.md). * **Config** command from the SDK client tools, which allows the user to edit a `config.toml` file that sets values for [flags](#flags) such as `--chain-id` and which `--node` they wish to connect to. * **Keys** commands from the SDK client tools, which includes a collection of subcommands for using the key functions in the SDK crypto tools, including adding a new key and saving it to disk, listing all public keys stored in the key manager, and deleting a key. * [**Transaction**](#transaction-commands) commands. * [**Query**](#query-commands) commands. +Here is an example from the [nameservice tutorial](https://cosmos.network/docs/tutorial) CLI's `main()` function. It instantiates the root command, adds a [*persistent* flag](#flags) and `PreRun` function to be run before every execution, and adds all of the necessary subcommands. + + +```go +rootCmd := &cobra.Command{ + Use: "nscli", + Short: "nameservice Client", +} +rootCmd.AddCommand( + rpc.StatusCommand(), + client.ConfigCmd(defaultCLIHome), + queryCmd(cdc, mc), + txCmd(cdc, mc), + client.LineBreak, + lcd.ServeCommand(cdc, registerRoutes), + client.LineBreak, + keys.Commands(), + client.LineBreak, +) +``` + +All of these things are done within the `main()` function. At the end of the `main()` function, it is necessary to create an `executor` and `Execute()` the root command in the `main()` function: + +```go +executor := cli.PrepareMainCmd(rootCmd, "NS", defaultCLIHome) +err := executor.Execute() +``` + ### Transaction Commands -[Transactions](#./transactions.md) are objects wrapping messages that trigger state changes within modules. To enable the creation of transactions using the CLI interface, `TxCmd` should add the following commands: +[Transactions](#./transactions.md) are objects wrapping [messages](../building-modules/messages-and-queries.md) that trigger state changes within modules. To enable the creation of transactions using the CLI interface, `TxCmd` should add the following commands: -* **Sign** command from the [`auth`](https://github.com/cosmos/cosmos-sdk/blob/master/docs/spec/auth) module, which signs messages in a transaction. To enable multisig, it should also add the `auth` module MultiSign command. Since every transaction requires some sort of signature in order to be valid, this command is necessary for every application. +* **Sign** command from the [`auth`](https://github.com/cosmos/cosmos-sdk/blob/master/docs/spec/auth) module, which signs messages in a transaction. To enable multisig, it should also add the `auth` module `MultiSign` command. Since every transaction requires some sort of signature in order to be valid, this command is necessary for every application. * **Broadcast** command from the SDK client tools, which broadcasts transactions. * **Send** command from the [`bank`](https://github.com/cosmos/cosmos-sdk/blob/master/docs/spec/bank) module, which is a transaction that allows accounts to send coins to one another, including gas and fees for transactions. -* All commands in each module the application is dependent on, retrieved by calling `GetTxCmd()` on all the modules or using the Module Manager's `AddTxCommands()` function. +* All commands in each module the application is dependent on, retrieved by calling [`GetTxCmd()`](../building-modules/interfaces.md#GetTxCmd) on all the modules or using the Module Manager's [`AddTxCommands()`](../building-modules/module-manager.md) function. + +Here is an example of a `TxCmd` aggregating these subcommands from the [nameservice tutorial](https://cosmos.network/docs/tutorial). + +```go +func txCmd(cdc *amino.Codec, mc []sdk.ModuleClients) *cobra.Command { + txCmd := &cobra.Command{ + Use: "tx", + Short: "Transactions subcommands", + } + + txCmd.AddCommand( + bankcmd.SendTxCmd(cdc), + client.LineBreak, + authcmd.GetSignCommand(cdc), + tx.GetBroadcastCommand(cdc), + client.LineBreak, + ) + + for _, m := range mc { + txCmd.AddCommand(m.GetTxCmd()) + } + + return txCmd +} +``` + ### Query Commands @@ -64,24 +118,55 @@ The root command (also called `rootCmd`) is what the user first types into the c * **Account** command from the `auth` module, which displays the state (e.g. account balance) of an account given an address. * **Validator** command from the SDK rpc client tools, which displays the validator set of a given height. * **Block** command from the SDK rpc client tools, which displays the block data for a given height. -* All commands in each module the application is dependent on, retrieved by calling `GetQueryCmd()` on all the modules or using the Module Manager's `AddQueryCommands()` function. +* All commands in each module the application is dependent on, retrieved by calling [`GetQueryCmd()`](../building-modules/interfaces.md#GetqueryCmd) on all the modules or using the Module Manager's `AddQueryCommands()` function. + +Here is an example of a `QueryCmd` aggregating subcommands, also from the nameservice tutorial (it is structurally identical to `TxCmd`): + +```go +func queryCmd(cdc *amino.Codec, mc []sdk.ModuleClients) *cobra.Command { + queryCmd := &cobra.Command{ + Use: "query", + Aliases: []string{"q"}, + Short: "Querying subcommands", + } + + queryCmd.AddCommand( + rpc.ValidatorCommand(cdc), + rpc.BlockCommand(), + tx.SearchTxCmd(cdc), + tx.QueryTxCmd(cdc), + client.LineBreak, + authcmd.GetAccountCmd(storeAcc, cdc), + ) + + for _, m := range mc { + queryCmd.AddCommand(m.GetQueryCmd()) + } + + return queryCmd +} +``` ## Flags Flags are used to modify commands. Users can explicitly include them in commands or pre-configure them by entering a command in the format `appcli config ` into their command line. Commonly pre-configured flags include the `--node` to connect to and `--chain-id` of the blockchain the user wishes to interact with. -A _persistent_ flag (as opposed to a _local_ flag) added to a command transcends all of its children. Additionally, all flags have default values when they are added to commands; some toggle an option off but others are empty values that the user needs to override to create valid commands. A flag can be explicitly marked as _required_ so that an error is automatically thrown if the user does not provide a value, but it is also acceptable to handle unexpected missing flags differently. +A *persistent* flag (as opposed to a _local_ flag) added to a command transcends all of its children: subcommands will inherit the configured values for these flags. Additionally, all flags have default values when they are added to commands; some toggle an option off but others are empty values that the user needs to override to create valid commands. A flag can be explicitly marked as _required_ so that an error is automatically thrown if the user does not provide a value, but it is also acceptable to handle unexpected missing flags differently. ### Root Command Flags -It is common to add a _persistent_ flag for `--chain-id`, the unique identifier of the blockchain the application pertains to, to the root command. Adding this flag makes sense as the chain ID should not be changing across commands in this application CLI. +It is common to add a _persistent_ flag for `--chain-id`, the unique identifier of the blockchain the application pertains to, to the root command. Adding this flag makes sense as the chain ID should not be changing across commands in this application CLI. Here is what that looks like: + +```go +rootCmd.PersistentFlags().String(client.FlagChainID, "", "Chain ID of tendermint node") +``` ### Transaction Flags To **create** a transaction, the user enters a `tx` command and provides several flags. These are the basic flags added to every command using the SDK `./client/flags` package [`PostCommands`](https://github.com/cosmos/cosmos-sdk/blob/master/client/flags/flags.go#L85-L116) function: -* `--from` indicates which account the transaction originates from. This account is used to sign the transaction. -* `--gas` refers to how much gas, which represents computational resources, Tx consumes. Gas is dependent on the transaction and is not precisely calculated until execution, but can be estimated by providing auto as the value for --gas. +* `--from` indicates which [account](../core/accounts-fees.md) the transaction originates from. This account is used to sign the transaction. +* `--gas` refers to how much [gas](../core/gas.md), which represents computational resources, Tx consumes. Gas is dependent on the computational needs of the transaction and is not precisely calculated until execution, but can be estimated by providing auto as the value for --gas. * `--gas-adjustment` (optional) can be used to scale gas up in order to avoid underestimating. For example, users can specify their gas adjustment as 1.5 to use 1.5 times the estimated gas. * `--gas-prices` specifies how much the user is willing pay per unit of gas, which can be one or multiple denominations of tokens. For example, --gas-prices=0.025uatom, 0.025upho means the user is willing to pay 0.025uatom AND 0.025upho per unit of gas. * `--fees` specifies how much in fees the user is willing to pay in total. Note that the user only needs to provide either `gas-prices` or `fees`, but not both, because they can be derived from each other. @@ -122,6 +207,7 @@ For example, the following command broadcasts the signed transaction, `mySignedT ```bash appcli tx broadcast mySignedTx.json --node ``` + ### Query Flags Queries also have flags. These are the basic flags added to every command using the SDK `./client/flags` package [`GetCommand`](https://github.com/cosmos/cosmos-sdk/blob/master/client/flags/flags.go#L67-L82) function: @@ -135,12 +221,47 @@ Queries also have flags. These are the basic flags added to every command using ## Configurations -The last function to define is, `initConfig`, which should do exactly what it sounds like - initial configurations. To call this function, set it as a `PersistentPreRunE` function for the root command, so that it always executes before the main execution of the root command and any of its subcommands. `initConfig` should do the following: +The last function to define is, `initConfig`, which should do exactly what it sounds like - initial configurations. To call this function, set it as a `PersistentPreRunE` function for the root command, so that it always executes before the main execution of the root command and any of its subcommands. `initConfig()` should do the following: 1. Read in the `config.toml` file. This same file is edited through `config` commands. 2. Use the [Viper](https://github.com/spf13/viper) to read in configurations from the file and set them. 3. Set any persistent flags defined by the user: `--chain-id`, `--encoding`, `--output`, etc. +Here is an example of an `initConfig()` function from the nameservice tutorial CLI: + +```go +func initConfig(cmd *cobra.Command) error { + home, err := cmd.PersistentFlags().GetString(cli.HomeFlag) + if err != nil { + return err + } + + cfgFile := path.Join(home, "config", "config.toml") + if _, err := os.Stat(cfgFile); err == nil { + viper.SetConfigFile(cfgFile) + + if err := viper.ReadInConfig(); err != nil { + return err + } + } + if err := viper.BindPFlag(client.FlagChainID, cmd.PersistentFlags().Lookup(client.FlagChainID)); err != nil { + return err + } + if err := viper.BindPFlag(cli.EncodingFlag, cmd.PersistentFlags().Lookup(cli.EncodingFlag)); err != nil { + return err + } + return viper.BindPFlag(cli.OutputFlag, cmd.PersistentFlags().Lookup(cli.OutputFlag)) +} +``` + +Here is an example of how to add `initConfig` as a `PersistentPreRunE` to the root command: + +```go +rootCmd.PersistentPreRunE = func(_ *cobra.Command, _ []string) error { + return initConfig(rootCmd) +} +``` + ## Next Read about how to build a module CLI [here](./module-interfaces#cli) diff --git a/docs/interfaces/interfaces-intro.md b/docs/interfaces/interfaces-intro.md index 9e68ee971027..e457925acaad 100644 --- a/docs/interfaces/interfaces-intro.md +++ b/docs/interfaces/interfaces-intro.md @@ -8,7 +8,7 @@ ## Synopsis -Every application must include some interface users can use to interact with the defined functionalities. This document introduces user interfaces for SDK applications. +Typically, SDK applications include some type of interface that users interact with to utilize the application's functionalities. This document introduces user command-line and REST interfaces. - [Types of Application Interfaces](#types-of-application-interfaces) - [Module vs Application Interfaces](#module-vs-application-interfaces) @@ -18,31 +18,31 @@ Every application must include some interface users can use to interact with the ## Types of Application Interfaces -SDK applications should have a Command-Line Interface (CLI) and REST Interface to support HTTP requests. The SDK is opinionated about how to create these two interfaces; all modules specify [Cobra commands](https://github.com/spf13/cobra) and register routes using [Gorilla Mux routers](https://github.com/gorilla/mux). The CLI and REST Interface are conventionally defined in the application `/cmd/cli` folder. +SDK applications generally have a Command-Line Interface (CLI) and REST Interface to support interactions with a [full-node](../core/node.md). The SDK is opinionated about how to create these two interfaces; all modules specify [Cobra commands](https://github.com/spf13/cobra) and register routes using [Gorilla Mux routers](https://github.com/gorilla/mux). The CLI and REST Interface are conventionally defined in the application `app/cmd/cli` folder. ## Module vs Application Interfaces -The process of creating an application interface is very different from creating a module interface, though the components are closely intertwined. As expected, the module interface handles the bulk of the underlying logic, unpacking user requests into arguments and routes, and neatly marshaling everything into ABCI requests to be handled by Baseapp. On the other hand, the application interface handles the user configurations and customizations, instantiates the application-specific values and objects, and passes everything to module interface functions. +The process of creating an application interface is distinct from creating a [module interface](../building-modules/interfaces.md), though the components are closely intertwined. As expected, the module interface handles the bulk of the underlying logic, defining ways for end-users to create [messages](../building-modules/messages-and-queries.md#messages) handled by the module and [queries](../building-modules/messages-and-queries.md#queries) to the subset of application state within the scope of the module. On the other hand, the application interfaces aggregate module-level interfaces in order to route messages and queries to the appropriate modules. Application interfaces also handle root-level responsibilities such as signing and broadcasting [transactions](../core/transactions.md) that wrap messages. ### Module Developer Responsibilities -In regards to interfaces, the module developers' responsibilities include: +In regards to interfaces, module developers include the following definitions: * **CLI commands:** Specifically, [Transaction commands](../building-modules/interfaces.md#transaction-commands) and [Query commands](../building-modules/interfaces.md#query-commands). These are commands that users will invoke when interacting with the application to create transactions and queries. For example, if an application enables sending coins through the [`auth`](https://github.com/cosmos/cosmos-sdk/tree/67f6b021180c7ef0bcf25b6597a629aca27766b8/docs/spec/auth) module, users will create `tx auth send` transactions. * **Request Handlers:** Also categorized into Transaction and Query requests. Transactions will require HTTP [Request Types](../building-modules/interfaces.md#request-types) in addition to [Request Handlers](../building-modules/interfaces.md#request-handlers) in order to encapsulate all of the user's options (e.g. gas prices). * **REST Routes:** Given a router, the module interface registers paths with the aforementioned [Request Handlers](../building-modules/interfaces.md#request-handlers) for each type of request. -Module interfaces are designed to be generic. Both commands and request types will include required user input (through flags or request body) which will be different for each application. This section of documents will only detail application interfaces; to read about how to build module interfaces, click [here](../building-modules/interfaces.md). +Module interfaces are designed to be generic. Both commands and request types include required user input (through flags or request body) which are different for each application. This section of documents will only detail application interfaces; to read about how to build module interfaces, click [here](../building-modules/interfaces.md). ### Application Developer Responsibilities -In regards to interfaces, the application developers' responsibilities include: +In regards to interfaces, application developers include: -* **CLI Root Command:** The root command adds subcommands to include all of the functionality for the application, mainly module transaction and query commands. -* **App Configurations:** All application-specific values are the responsibility of the application developer, including the `codec` used to marshal requests before relaying them to a node. -* **User Configurations:** Some values are specific to the user, such as the user's address and which node they are connected to. -* **RegisterRoutes Function:** To be passed to an instantiated REST Server so that it knows how to route requests for this particular application. +* **CLI Root Command:** The [root command](./cli.md#root-command) adds subcommands to include all of the functionality for the application, mainly module [transaction](./cli.md#transaction-commands) and [query](./cli.md#query-commands) commands from the application's module(s). +* **App Configurations:** All application-specific values are the responsibility of the application developer, including the [`codec`](../core/encoding.md) used to marshal requests before relaying them to a node. +* **User Configurations:** Some values are specific to the user, such as the user's address and which node they are connected to. The CLI has a [configurations](./cli.md#configurations) function to set these values. +* **RegisterRoutes Function:** [Routes](./rest.md#registerroutes) must be registered and passed to an instantiated [REST server](./rest.md#rest-server) so that it knows how to route requests for this particular application. ## Next diff --git a/docs/interfaces/query-lifecycle.md b/docs/interfaces/query-lifecycle.md index b95d6980fae0..44026d16bc2d 100644 --- a/docs/interfaces/query-lifecycle.md +++ b/docs/interfaces/query-lifecycle.md @@ -9,7 +9,7 @@ This document describes SDK interfaces in detail through the lifecycle of a query, from the user interface to application stores and back. The query will be referred to as `Query`. - [Interfaces](#interfaces) -- [CLIContext](#clicontext) +- [Request and Command Handling](#request-and-command-handling) - [Tendermint and ABCI](#tendermint-and-abci) - [Application Query Handling](#application-query-handling) - [Response](#response) @@ -18,11 +18,11 @@ This document describes SDK interfaces in detail through the lifecycle of a quer A [**query**](../building-modules/messages-and-queries.md#queries) is a request for information made by users of applications. Users can query information about the network, the application itself, and application state directly from the application's stores or modules. -For the purpose of explaining a query lifecycle, let's say `Query` is requesting a list of delegations made by a certain delegator address in the application called `app`. There are a few ways `Query` can be made on the user side. +For the purpose of explaining a query lifecycle, let's say `Query` is requesting a list of delegations made by a certain delegator address in the application called `app`. As to be expected, the [`staking`](https://github.com/cosmos/cosmos-sdk/blob/master/docs/spec/staking) module handles this query. But first, there are a few ways `Query` can be created by users. ### CLI -The main interface for an application is the command-line interface. Users run the CLI directly from their machines and type commands to create queries. To create this query from their terminal, users would type the following command: +The main interface for an application is the command-line interface. Users connect to a full node and run the CLI directly from their machines. To create `Query` from their terminal, users type the following command: ``` appcli query staking delegations @@ -30,20 +30,22 @@ appcli query staking delegations To provide values such as `--chain-id` (the ID of the blockchain to make the query to), the user must use the `config` command to set them or provide them as flags. -This query command is defined by the module developer and added to the list of subcommands by the application developer when creating the CLI. +This query command was defined by the [`staking`](https://github.com/cosmos/cosmos-sdk/blob/master/docs/spec/staking) module developer and added to the list of subcommands by the application developer when creating the CLI. The code for this particular command can be found [here](https://github.com/cosmos/cosmos-sdk/blob/master/x/staking/client/cli/query.go#L253-L294). ### REST -Another interface through which users can make queries is through HTTP Requests to a REST server. The REST server contains, among other things, a [`CLIContext`](#clicontext) and [mux](./rest.md#gorilla-mux) router. The request looks like this: +Another interface through which users can make queries is through HTTP Requests to a [REST server](./rest.md#rest-server). The REST server contains, among other things, a [`CLIContext`](#clicontext) and [mux](./rest.md#gorilla-mux) router. The request looks like this: ```bash GET http://localhost:{PORT}/staking/delegators/{delegatorAddr}/delegations ``` -To provide values such as `--chain-id` (the ID of the blockchain to make the query to), the user must configure their local REST server with the values or provide them in the request body. +To provide values such as `--chain-id` (the ID of the blockchain to make the query to) that are required by [`baseReq`](./rest.md#basereq), the user must configure their local REST server with the values or provide them in the request body. The router automatically routes the `Query` HTTP request to the staking module `delegatorDelegationsHandlerFn()` function (to see the handler itself, click [here]()). Since this function is defined within the module and thus has no inherent knowledge of the application `Query` belongs to, it takes in the application `codec` and `CLIContext` as parameters. +When users interact with the interfaces, the result is a CLI command or HTTP request. `Query` is then created when the command is executed or request handled. + ## Request and Command Handling The interactions from the users' perspective are a bit different, but the underlying functions are almost identical. This section describes how the CLI command or HTTP request is processed, up until the ABCI request is sent. This step of processing heavily involves a `CLIContext`. @@ -52,7 +54,7 @@ The interactions from the users' perspective are a bit different, but the underl The first thing that is created in the execution of a CLI command is a `CLIContext`, while the REST Server directly provides a `CLIContext` for the REST Request handler. A [Context](../core/context.md) is an immutable object that stores all the data needed to process a request. In particular, a `CLIContext` stores the following: -* **Codec**: The encoder/decoder used by the application, used to marshal the parameters and query before making the Tendermint RPC request and unmarshal the returned response into a JSON object. +* **Codec**: The [encoder/decoder](,./core/encoding.md) used by the application, used to marshal the parameters and query before making the Tendermint RPC request and unmarshal the returned response into a JSON object. * **Account Decoder**: The account decoder from the [`auth`](.../spec/auth) module, which translates `[]byte`s into accounts. * **RPC Client**: The [Tendermint RPC Client](https://github.com/tendermint/tendermint/blob/master/rpc/client/interface.go), or node, to which the request will be relayed to. * **Keybase**: A [Key Manager](.//core/accounts-keys.md) used to sign transactions and handle other operations with keys. @@ -65,37 +67,37 @@ For full specification of the `CLIContext` type, click [here](https://github.com The next step is to parse the command or request, extract the arguments, create a `queryRoute`, and encode everything. -In this case, `Query` contains a `delegatorAddress` as its only argument. However, the request can only contain `[]byte`s, as it will be relayed to a consensus engine node that has no inherent knowledge of the application types. Thus, the `CLIContext` `codec` is used to marshal the address as the type `QueryDelegatorParams`. All query arguments (e.g. the `staking` module also has `QueryValidatorParams` and `QueryBondsParams`) have their own types that the application `codec` understands how to encode and decode. The module [`querier`](.//building-modules/querier.md) declares these types and the application registers the `codec`s. +In this case, `Query` contains an [address](../core/accounts-fees.md) `delegatorAddress` as its only argument. However, the request can only contain `[]byte`s, as it will be relayed to a consensus engine node that has no inherent knowledge of the application types. Thus, the `CLIContext` `codec` is used to marshal the address as the type [`QueryDelegatorParams`](https://github.com/cosmos/cosmos-sdk/blob/master/x/staking/types/querier.go#L30-L38). All query arguments (e.g. the [`staking`](https://github.com/cosmos/cosmos-sdk/blob/master/docs/spec/staking) module also has [`QueryValidatorParams`](https://github.com/cosmos/cosmos-sdk/blob/master/x/staking/types/querier.go#L45-L53) and [`QueryBondsParams`](https://github.com/cosmos/cosmos-sdk/blob/master/x/staking/types/querier.go#L59-L69)) have their own types that the application `codec` understands how to encode and decode. The module [`querier`](.//building-modules/querier.md) declares these types and the application registers the `codec`s. -A `route` is also created for `Query` so that the application will understand which module to route the query to. Baseapp will understand this query to be a `custom` query in the module `staking` with the type `QueryDelegatorDelegations`. Thus, the route will be `"custom/staking/delegatorDelegations"`. +A `route` is also created for `Query` so that the application will understand which module to route the query to. [Baseapp](../core/baseapp.md#query-routing) will understand this query to be a `custom` query in the module `staking` with the type `QueryDelegatorDelegations`. Thus, the route will be `"custom/staking/delegatorDelegations"`. ### ABCI Query -The `CLIContext`'s main `Query` function takes the `route`, which is now called `path`, and arguments, now called `key`. It first retrieves the RPC Client (called the **node**) configured by the user to relay this query to, and creates the `ABCIQueryOptions` (parameters formatted for the ABCI call). The node is then used to make the ABCI call, `ABCIQueryWithOptions`. +The `CLIContext`'s main `Query` function takes the `route`, which is now called `path`, and arguments, now called `key`. It first retrieves the RPC Client (called the [**node**](../core/node.md)) configured by the user to relay this query to, and creates the `ABCIQueryOptions` (parameters formatted for the ABCI call). The node is then used to make the ABCI call, `ABCIQueryWithOptions()`. ## Tendermint and ABCI -With a call to `ABCIQueryWithOptions()`, `Query` arrives at the consensus engine portion of its lifecycle. Nodes running the consensus engine (e.g. Tendermint Core) make ABCI calls to interact with the application. At this point, `Query` exists as an ABCI `RequestQuery` and the [ABCI Client](https://github.com/tendermint/tendermint/blob/51b3428f5c0f4fdd2e469147cd90353faa4bd704/abci/client/client.go#L16-L50) calls the ABCI method [`Query()`](https://tendermint.com/docs/spec/abci/abci.html#query) on the application. +With a call to `ABCIQueryWithOptions()`, `Query` arrives at the consensus engine portion of its lifecycle. Nodes running the consensus engine (e.g. Tendermint Core) make ABCI calls to interact with the application. At this point, `Query` exists as an ABCI `RequestQuery` and the [ABCI Client](https://github.com/tendermint/tendermint/blob/master/abci/client/client.go#L16-L50) calls the ABCI method [`Query()`](https://tendermint.com/docs/spec/abci/abci.html#query) on the application. Read more about ABCI Clients and Tendermint RPC in the Tendermint documentation [here](https://tendermint.com/rpc). ## Application Query Handling -[Baseapp](../core/baseapp.md) implements the ABCI [`Query()`](../core/baseapp.md#query) function and handles four different types of queries: `app`, `store`, `p2p`, and `custom`. The `queryRoute` is parsed such that the first string must be one of the four options, then the rest of the path is parsed within the subroutines handling each type of query. The first three types are application-level and thus directly handled by Baseapp or the stores, but the `custom` query type requires Baseapp to route the query to a module's [querier](../building-modules/querier.md). +[Baseapp](../core/baseapp.md) implements the ABCI [`Query()`](../core/baseapp.md#query) function and handles four different types of queries: `app`, `store`, `p2p`, and `custom`. The `queryRoute` is parsed such that the first string must be one of the four options, then the rest of the path is parsed within the subroutines handling each type of query. The first three types (`app`, `store`, `p2p`) are purely application-level and thus directly handled by Baseapp or the stores, but the `custom` query type requires Baseapp to route the query to a module's [querier](../building-modules/querier.md). -Since `Query` is a custom query type, Baseapp first parses the path, then uses the `QueryRouter` to retrieve the corresponding querier. The querier is responsible for recognizing this query, retrieving the appropriate values from the application's stores, and returning a response. +Since `Query` is a custom query type from the `staking` module, Baseapp first parses the path, then uses the `QueryRouter` to retrieve the corresponding querier. The querier is responsible for recognizing this query, retrieving the appropriate values from the application's stores, and returning a response. ## Response -Since `Query()` is an ABCI function, Baseapp returns the `Query` response as an `abci.ResponseQuery`. The `CLIContext` `Query` routine receives the response and, if `--trust-node` is toggled to `false` and a proof needs to be verified, the response is verified with the `CLIContext` `verifyProof` function before the response is returned. +Since `Query()` is an ABCI function, Baseapp returns the response as an [`abci.ResponseQuery`](https://tendermint.com/docs/spec/abci/abci.html#messages) type. The `CLIContext` `Query()` routine receives the response and, if `--trust-node` is toggled to `false` and a proof needs to be verified, the response is verified with the `CLIContext` [`verifyProof()`](https://github.com/cosmos/cosmos-sdk/blob/master/client/context/query.go#L136-L173) function before the response is returned. ### CLI Response -The application `codec` is used to unmarshal the response to a JSON and the `CLIContext` prints the output to the command line, applying any configurations such as `--indent`. +The application [`codec`](../core/encoding.md) is used to unmarshal the response to a JSON and the `CLIContext` prints the output to the command line, applying any configurations such as `--indent`. ### REST Response -The REST server uses the `CLIContext` to format the response properly, then uses the HTTP package to write the appropriate response or error. +The [REST server](./rest.md#rest-server) uses the `CLIContext` to format the response properly, then uses the HTTP package to write the appropriate response or error. ## Next diff --git a/docs/interfaces/rest.md b/docs/interfaces/rest.md index ce3b8db10b42..858c4b9420a4 100644 --- a/docs/interfaces/rest.md +++ b/docs/interfaces/rest.md @@ -16,7 +16,7 @@ This document describes how to create a REST interface for an SDK application. A ## Application REST Interface -Building the REST Interface for an application involves creating a REST server to route requests and output responses. The SDK has its own REST Server type used for LCDs (light-client daemons). It has a `ServeCommand` that takes in an application's `codec` and `RegisterRoutes` function, starts up a new SDK REST Server, and registers routes using function provided from the application. To enable this command, it should be added as a subcommand of the root command `RootCmd` in the `main()` function of the CLI interface. +Building the REST Interface for an application involves creating a [REST server](./rest.md#rest-server) to route requests and output responses. The SDK has its own REST Server type used for [LCDs](../core/node.md) (light-client daemons). It has a `ServeCommand` that takes in an application's `codec` and `RegisterRoutes()` function, starts up a new REST Server, and registers routes using function provided from the application. To enable this command, it should be added as a subcommand of the root command `RootCmd` in the `main()` function of the CLI interface. Users can use the application CLI to start a new LCD, a local server through which they can securely interact with the application without downloading the entire state. The command entered by users would look something like this: @@ -32,15 +32,15 @@ HTTP Request types are defined by the module interfaces for every type of transa `BaseReq` is a type defined in the SDK that encapsulates much of the transaction configurations similar to CLI command flags. Users must provide the information in the body of their requests. -* `From` indicates which account the transaction originates from. This account is used to sign the transaction. +* `From` indicates which [account](../core/accounts-fees.md) the transaction originates from. This account is used to sign the transaction. * `Memo` sends a memo along with the transaction. * `ChainID` specifies the unique identifier of the blockchain the transaction pertains to. * `AccountNumber` is an identifier for the account. * `Sequence`is the value of a counter measuring how many transactions have been sent from the account. It is used to prevent replay attacks. -* `Gas` refers to how much gas, which represents computational resources, Tx consumes. Gas is dependent on the transaction and is not precisely calculated until execution, but can be estimated by providing auto as the value for `Gas`. +* `Gas` refers to how much [gas](../core/gas.md), which represents computational resources, Tx consumes. Gas is dependent on the transaction and is not precisely calculated until execution, but can be estimated by providing auto as the value for `Gas`. * `GasAdjustment` can be used to scale gas up in order to avoid underestimating. For example, users can specify their gas adjustment as 1.5 to use 1.5 times the estimated gas. * `GasPrices` specifies how much the user is willing pay per unit of gas, which can be one or multiple denominations of tokens. For example, --gas-prices=0.025uatom, 0.025upho means the user is willing to pay 0.025uatom AND 0.025upho per unit of gas. -* `Fees` specifies how much in fees the user is willing to pay in total. Note that the user only needs to provide either `gas-prices` or `fees`, but not both, because they can be derived from each other. +* `Fees` specifies how much in [fees](../core/accounts-fees.md) the user is willing to pay in total. Note that the user only needs to provide either `gas-prices` or `fees`, but not both, because they can be derived from each other. * `Simulate` instructs the application to ignore gas and simulate the transaction running without broadcasting. Additionally, each request may contain arguments such as a specific address pertaining to the request. @@ -59,9 +59,9 @@ Of the five, the only attribute that developers will need to configure is the ro ## Registering Routes -To include routes for each module in an application, the CLI must have some kind of function to Register Routes in its REST Server. This `RegisterRoutes` function is utilized by the `ServeCommand` and must include routes for each of the application's modules. Since each module used by an SDK application implements a [`RegisterRESTRoutes`](../building-modules.md#rest) function, application developers simply use the Module Manager to call this function for each module. +To include routes for each module in an application, the CLI must have some kind of function to Register Routes in its REST Server. This `RegisterRoutes()` function is utilized by the `ServeCommand` and must include routes for each of the application's modules. Since each module used by an SDK application implements a [`RegisterRESTRoutes`](../building-modules.md#rest) function, application developers simply use the Module Manager to call this function for each module. -At the bare minimum, a `RegisterRoutes` function should use the SDK client package `RegisterRoutes` function to be able to route RPC calls, and instruct the application Module Manager to call `RegisterRESTRoutes` for all of its modules: +At the bare minimum, a `RegisterRoutes()` function should use the SDK client package `RegisterRoutes()` function to be able to route RPC calls, and instruct the application Module Manager to call `RegisterRESTRoutes()` for all of its modules: ```go func registerRoutes(rs *lcd.RestServer) { From 0be941032b720329f18f11041103a930925910e6 Mon Sep 17 00:00:00 2001 From: Gloria Zhao Date: Mon, 12 Aug 2019 11:35:39 -0400 Subject: [PATCH 057/196] cli.md comments --- docs/interfaces/cli.md | 155 ++++++++++++++++++++++++----------------- 1 file changed, 90 insertions(+), 65 deletions(-) diff --git a/docs/interfaces/cli.md b/docs/interfaces/cli.md index 6287c0d24026..f1864a2593cb 100644 --- a/docs/interfaces/cli.md +++ b/docs/interfaces/cli.md @@ -6,7 +6,7 @@ ## Synopsis -This document describes how to create a commmand-line interface for an SDK application. A separate document for creating a module CLI can be found [here](#../module-interfaces.md#cli). +This document describes how to create a commmand-line interface (CLI) for an application. A separate document for implementing a CLI for an SDK module can be found [here](#../building-modules/interfaces.md#cli). - [Application CLI Components](#application-cli-components) - [Commands](#commands) @@ -15,11 +15,20 @@ This document describes how to create a commmand-line interface for an SDK appli ## Application CLI Components -One of the main entrypoints of an application is the command-line interface. This entrypoint is created as a `main.go` file which compiles to a binary, conventionally placed in the application's `app/cmd/cli` folder. The CLI for an application will typically be referred to as the name of the application suffixed with `-cli`, e.g. `appcli`. +One of the main entrypoints of an application is the command-line interface. This entrypoint is created as a `main.go` file which compiles to a binary, conventionally placed in the application's `./cmd/cli` folder. The CLI for an application is typically be referred to as the name of the application suffixed with `-cli`, e.g. `appcli`. Here is where the interfaces docs lie in the directory from the [nameservice tutorial](https://cosmos.network/docs/tutorial) ### Cobra -There is no set way to create a CLI, but SDK modules all use the [Cobra Library](https://github.com/spf13/cobra) in order to implement the [`AppModuleBasic`](../building-modules/modules-manager.md) interface. Building a CLI with Cobra entails defining commands, arguments, and flags. [**Commands**](#commands) understand the actions users wish to take, such as `tx` for creating a transaction and `query` for querying the application. Each command can also have nested subcommands, necessary for naming the specific transaction type. Users also supply **Arguments**, such as account numbers to send coins to, and [**Flags**](#flags) to modify various aspects of the commands, such as gas prices or which node to broadcast to. +There is no set way to create a CLI, but SDK modules all use the [Cobra Library](https://github.com/spf13/cobra). Building a CLI with Cobra entails defining commands, arguments, and flags. [**Commands**](#commands) understand the actions users wish to take, such as `tx` for creating a transaction and `query` for querying the application. Each command can also have nested subcommands, necessary for naming the specific transaction type. Users also supply **Arguments**, such as account numbers to send coins to, and [**Flags**](#flags) to modify various aspects of the commands, such as gas prices or which node to broadcast to. + +Here is an example of a command a user might enter to interact with the nameservice CLI `nscli` in order to buy a name: + +```bash +nscli tx nameservice buy-name --gas auto --gas-prices +``` +The first four strings specify the command: the root command for the entire application `nscli`, the subcommand `tx`, the subcommand `nameservice` to indicate which module to route the command to, and the type of transaction `buy-name`. The next two strings are arguments: the `name` the user wishes to buy and the `amount` they want to pay for it. Finally, the last few strings of the command are flags to indicate how much the user is willing to pay in fees (calculated using the amount of gas used to execute the transaction and the gas prices provided by the user). + +The CLI interacts with a node (running `nsd`) to handle this command. ### Main Function @@ -39,11 +48,53 @@ Every application CLI first constructs a root command, then adds functionality b ### Root Command -The root command (also called `rootCmd`) is what the user first types into the command line to indicate which application they wish to interact with. The string used to invoke the command (the "Use" field) is typically the name of the application suffixed with `-cli`, e.g. `appcli`. The root command must include the following commands to support basic functionality in the application. - -* **Status** command from the SDK rpc client tools, which prints information about the status of the connected [`Node`](,,/core/node.md). -* **Config** command from the SDK client tools, which allows the user to edit a `config.toml` file that sets values for [flags](#flags) such as `--chain-id` and which `--node` they wish to connect to. -* **Keys** commands from the SDK client tools, which includes a collection of subcommands for using the key functions in the SDK crypto tools, including adding a new key and saving it to disk, listing all public keys stored in the key manager, and deleting a key. +The root command (called `rootCmd`) is what the user first types into the command line to indicate which application they wish to interact with. The string used to invoke the command (the "Use" field) is typically the name of the application suffixed with `-cli`, e.g. `appcli`. The root command must include the following commands to support basic functionality in the application. + +* **Status** command from the SDK rpc client tools, which prints information about the status of the connected [`Node`](,,/core/node.md). The Status of a node includes [`NodeInfo`](https://github.com/tendermint/tendermint/blob/master/p2p/node_info.go#L75-L92), `SyncInfo` and `ValidatorInfo`: this information includes the node ID, latest block hash, and the validator public key and voting power. Here is an example of what the `status command` outputs: +```json +{ + "jsonrpc": "2.0", + "id": "", + "result": { + "node_info": { + "protocol_version": { + "p2p": "4", + "block": "7", + "app": "0" + }, + "id": "53729852020041b956e86685e24394e0bee4373f", + "listen_addr": "10.0.2.15:26656", + "network": "test-chain-Y1OHx6", + "version": "0.24.0-2ce1abc2", + "channels": "4020212223303800", + "moniker": "ubuntu-xenial", + "other": { + "tx_index": "on", + "rpc_addr": "tcp://0.0.0.0:26657" + } + }, + "sync_info": { + "latest_block_hash": "F51538DA498299F4C57AC8162AAFA0254CE08286", + "latest_app_hash": "0000000000000000", + "latest_block_height": "18", + "latest_block_time": "2018-09-17T11:42:19.149920551Z", + "catching_up": false + }, + "validator_info": { + "address": "D9F56456D7C5793815D0E9AF07C3A355D0FC64FD", + "pub_key": { + "type": "tendermint/PubKeyEd25519", + "value": "wVxKNtEsJmR4vvh651LrVoRguPs+6yJJ9Bz174gw9DM=" + }, + "voting_power": "10" + } + } +} +``` +* **Config** [command](https://github.com/cosmos/cosmos-sdk/blob/master/client/config.go) from the SDK client tools, which allows the user to edit a `config.toml` file that sets values for [flags](#flags) such as `--chain-id` and which `--node` they wish to connect to. +The `config` command can be invoked by typing `appcli config` with optional arguments ` [value]` and a `--get` flag to query configurations or `--home` flag to create a new configuration. +* **Keys** [commands](https://github.com/cosmos/cosmos-sdk/blob/master/client/keys) from the SDK client tools, which includes a collection of subcommands for using the key functions in the SDK crypto tools, including adding a new key and saving it to disk, listing all public keys stored in the key manager, and deleting a key. +For example, users can type `appcli keys add ` to add a new key and save an encrypted copy to disk, using the flag `--recover` to recover a private key from a seed phrase or the flag `--multisig` to group multiple keys together to create a multisig key. For full details on the `add` key command, see the code [here](https://github.com/cosmos/cosmos-sdk/blob/master/client/keys/add.go). * [**Transaction**](#transaction-commands) commands. * [**Query**](#query-commands) commands. @@ -77,12 +128,12 @@ err := executor.Execute() ### Transaction Commands -[Transactions](#./transactions.md) are objects wrapping [messages](../building-modules/messages-and-queries.md) that trigger state changes within modules. To enable the creation of transactions using the CLI interface, `TxCmd` should add the following commands: +[Transactions](#./transactions.md) are objects wrapping [messages](../building-modules/messages-and-queries.md) that trigger state changes. To enable the creation of transactions using the CLI interface, `TxCmd` needs to add the following commands: -* **Sign** command from the [`auth`](https://github.com/cosmos/cosmos-sdk/blob/master/docs/spec/auth) module, which signs messages in a transaction. To enable multisig, it should also add the `auth` module `MultiSign` command. Since every transaction requires some sort of signature in order to be valid, this command is necessary for every application. -* **Broadcast** command from the SDK client tools, which broadcasts transactions. -* **Send** command from the [`bank`](https://github.com/cosmos/cosmos-sdk/blob/master/docs/spec/bank) module, which is a transaction that allows accounts to send coins to one another, including gas and fees for transactions. -* All commands in each module the application is dependent on, retrieved by calling [`GetTxCmd()`](../building-modules/interfaces.md#GetTxCmd) on all the modules or using the Module Manager's [`AddTxCommands()`](../building-modules/module-manager.md) function. +* **Sign** [command](https://github.com/cosmos/cosmos-sdk/blob/master/x/auth/client/cli/tx_sign.go#L30-L83) from the [`auth`](https://github.com/cosmos/cosmos-sdk/blob/master/docs/spec/auth) module, the command that signs messages in a transaction. To enable multisig, add the `auth` module [`MultiSign`](https://github.com/cosmos/cosmos-sdk/blob/master/x/auth/client/cli/tx_multisign.go#L26-L151) command. Since every transaction requires some sort of signature in order to be valid, this command is necessary for every application. +* **Broadcast** [command](https://github.com/cosmos/cosmos-sdk/blob/master/client/context/broadcast.go) from the SDK client tools, which broadcasts transactions. +* **Send** [command](https://github.com/cosmos/cosmos-sdk/blob/master/x/bank/client/cli/tx.go#L31-L60) from the [`bank`](https://github.com/cosmos/cosmos-sdk/blob/master/docs/spec/bank) module, which is a transaction that allows accounts to send coins to one another, including gas and fees for transactions. +* All [module transaction commands](../building-modules/interfaces.md) the application is dependent on, retrieved by calling [`GetTxCmd()`](../building-modules/interfaces.md#GetTxCmd) on all the modules or using the Module Manager's [`AddTxCommands()`](../building-modules/module-manager.md) function. Here is an example of a `TxCmd` aggregating these subcommands from the [nameservice tutorial](https://cosmos.network/docs/tutorial). @@ -112,13 +163,13 @@ func txCmd(cdc *amino.Codec, mc []sdk.ModuleClients) *cobra.Command { ### Query Commands -[**Queries**](../building-modules/messages-and-queries.md#queries) are objects that allow users to retrieve information about the application's state. To enable basic queries, `QueryCmd` should add the following commands: +[**Queries**](../building-modules/messages-and-queries.md#queries) are objects that allow users to retrieve information about the application's state. To enable basic queries, `QueryCmd` needs to add the following commands: -* **QueryTx** and/or other transaction query commands from the `auth` module which allow the user to search for a transaction by inputting its hash, a list of tags, or a block height. These various queries allow users to see if transactions have been included in a block. -* **Account** command from the `auth` module, which displays the state (e.g. account balance) of an account given an address. -* **Validator** command from the SDK rpc client tools, which displays the validator set of a given height. -* **Block** command from the SDK rpc client tools, which displays the block data for a given height. -* All commands in each module the application is dependent on, retrieved by calling [`GetQueryCmd()`](../building-modules/interfaces.md#GetqueryCmd) on all the modules or using the Module Manager's `AddQueryCommands()` function. +* **QueryTx** and/or other transaction [query commands](https://github.com/cosmos/cosmos-sdk/blob/master/x/auth/client/cli/query.go) from the `auth` module which allow the user to search for a transaction by inputting its hash, a list of tags, or a block height. These queries allow users to see if transactions have been included in a block. +* **Account** [command](https://github.com/cosmos/cosmos-sdk/blob/master/x/auth/client/cli/query.go#L45-L73) from the `auth` module, which displays the state (e.g. account balance) of an account given an address. +* **Validator** [command](https://github.com/cosmos/cosmos-sdk/blob/master/client/rpc/validators.go) from the SDK rpc client tools, which displays the validator set of a given height. +* **Block** [command](https://github.com/cosmos/cosmos-sdk/blob/master/client/rpc/block.go) from the SDK rpc client tools, which displays the block data for a given height. +* All [module query commands](../building-modules/interfaces.md) the application is dependent on, retrieved by calling [`GetQueryCmd()`](../building-modules/interfaces.md#GetqueryCmd) on all the modules or using the Module Manager's `AddQueryCommands()` function. Here is an example of a `QueryCmd` aggregating subcommands, also from the nameservice tutorial (it is structurally identical to `TxCmd`): @@ -153,75 +204,49 @@ Flags are used to modify commands. Users can explicitly include them in commands A *persistent* flag (as opposed to a _local_ flag) added to a command transcends all of its children: subcommands will inherit the configured values for these flags. Additionally, all flags have default values when they are added to commands; some toggle an option off but others are empty values that the user needs to override to create valid commands. A flag can be explicitly marked as _required_ so that an error is automatically thrown if the user does not provide a value, but it is also acceptable to handle unexpected missing flags differently. -### Root Command Flags - -It is common to add a _persistent_ flag for `--chain-id`, the unique identifier of the blockchain the application pertains to, to the root command. Adding this flag makes sense as the chain ID should not be changing across commands in this application CLI. Here is what that looks like: +Every flag has a name the user types to use the flag. For example, the commonly used `--from` flag is declared as a constant in the SDK [flags](https://github.com/cosmos/cosmos-sdk/blob/master/client/flags/flags.go) file: ```go -rootCmd.PersistentFlags().String(client.FlagChainID, "", "Chain ID of tendermint node") +const FlagFrom = "from" ``` -### Transaction Flags - -To **create** a transaction, the user enters a `tx` command and provides several flags. These are the basic flags added to every command using the SDK `./client/flags` package [`PostCommands`](https://github.com/cosmos/cosmos-sdk/blob/master/client/flags/flags.go#L85-L116) function: - -* `--from` indicates which [account](../core/accounts-fees.md) the transaction originates from. This account is used to sign the transaction. -* `--gas` refers to how much [gas](../core/gas.md), which represents computational resources, Tx consumes. Gas is dependent on the computational needs of the transaction and is not precisely calculated until execution, but can be estimated by providing auto as the value for --gas. -* `--gas-adjustment` (optional) can be used to scale gas up in order to avoid underestimating. For example, users can specify their gas adjustment as 1.5 to use 1.5 times the estimated gas. -* `--gas-prices` specifies how much the user is willing pay per unit of gas, which can be one or multiple denominations of tokens. For example, --gas-prices=0.025uatom, 0.025upho means the user is willing to pay 0.025uatom AND 0.025upho per unit of gas. -* `--fees` specifies how much in fees the user is willing to pay in total. Note that the user only needs to provide either `gas-prices` or `fees`, but not both, because they can be derived from each other. -* `--generate-only` (optional) instructs the application to simply generate the unsigned transaction and output or write to a file. Without this flag, the transaction is created, signed, and broadcasted all in one command. -* `--dry-run` (optional), similar to `--generate-only`, instructs the application to ignore the `--gas` flag and simulate the transaction running without broadcasting. -* `--indent` (optional) adds an indent to the JSON response. -* `--memo` sends a memo along with the transaction. +The flag can be added to a command `cmd`, adding a default value and description: -For example, the following command creates a transaction to send 1000uatom from `sender-address` to `recipient-address`. The user is willing to pay 0.025uatom per unit gas but wants the transaction to be only generated offline (i.e. not broadcasted) and written, in JSON format, to the file `myUnsignedTx.json`. - -```bash -appcli tx send 1000uatom --from --gas auto -gas-prices 0.025uatom --generate-only > myUnsignedTx.json +```go +cmd.Flags().String(FlagFrom, "", "Name or address of private key with which to sign") ``` -To **sign** a transaction generated offline using the `--generate-only` flag, the user enters a `tx sign` command (by default, the transaction is automatically signed upon creation). There are four values for flags that must be provided if a transaction is expected to be signed: +The SDK client package includes a list of [flags](https://github.com/cosmos/cosmos-sdk/blob/master/client/flags/flags.go) that are commonly used across existing commands. -* `--from` specifies an address; the corresponding private key is used to sign the transaction. -* `--chain-id` specifies the unique identifier of the blockchain the transaction pertains to. -* `--sequence` is the value of a counter measuring how many transactions have been sent from the account. It is used to prevent replay attacks. -* `--account-number` is an identifier for the account. -* `--validate-signatures` (optional) instructs the process to sign the transaction and verify that all signatures have been provided. -* `--ledger` (optional) lets the user perform the action using a Ledger Nano S, which needs to be plugged in and unlocked. +### Root Command Flags -For example, the following command signs the inputted transaction, `myUnsignedTx.json`, and writes the signed transaction to the file `mySignedTx.json`. +It is common to add a _persistent_ flag for `--chain-id`, the unique identifier of the blockchain the application pertains to, to the root command. Adding this flag makes sense as the chain ID should not be changing across commands in this application CLI. Here is what that looks like: -```bash -appcli tx sign myUnsignedTx.json --from --chain-id --sequence --account-number > mySignedTx.json +```go +rootCmd.PersistentFlags().String(client.FlagChainID, "", "Chain ID of tendermint node") ``` -To **broadcast** a signed transaction generated offline, the user enters a `tx broadcast` command. Only one flag is required here: +### Transaction and Query Flags -* `--node` specifies which node to broadcast to. -* `--trust-node` (optional) indicates whether or not the node and its response proofs can be trusted. -* `--broadcast-mode` (optional) specifies when the process should return. Options include asynchronous (return immediately), synchronous (return after `CheckTx` passes), or block (return after block commit). +To create a transaction, users enter a `tx` command and provide several flags. The SDK `./client/flags` package [`PostCommands()`](https://github.com/cosmos/cosmos-sdk/blob/master/client/flags/flags.go#L85-L116) function adds a set of basic flags to every transaction command. For queries, the [`GetCommand()`](https://github.com/cosmos/cosmos-sdk/blob/master/client/flags/flags.go#L67-L82) function adds basic flags to query commands, such as the block `--height` to query from. -For example, the following command broadcasts the signed transaction, `mySignedTx.json` to a particular node. +For example, the following command creates a transaction to send 1000uatom from `sender-address` to `recipient-address`. The user is willing to pay 0.025uatom per unit gas but wants the transaction to be only generated offline (i.e. not broadcasted) and written, in JSON format, to the file `myUnsignedTx.json`. ```bash -appcli tx broadcast mySignedTx.json --node +appcli tx send 1000uatom --from --gas auto -gas-prices 0.025uatom --generate-only > myUnsignedTx.json ``` -### Query Flags - -Queries also have flags. These are the basic flags added to every command using the SDK `./client/flags` package [`GetCommand`](https://github.com/cosmos/cosmos-sdk/blob/master/client/flags/flags.go#L67-L82) function: +Here are the flags used: -* `--node` indicates which full-node to connect to. -* `--trust-node` (optional) represents whether or not the connected node is trusted. If the node is not trusted, all proofs in the responses are verified. -* `--indent` (optional) adds an indent to the JSON response. -* `--height` (optional) can be provided to query the blockchain at a specific height. -* `--ledger` (optional) lets the user perform the action using a Ledger Nano S. +* `--from` indicates which [account](../core/accounts-fees.md) the transaction originates from. This account is used to sign the transaction. +* `--gas` refers to how much [gas](../core/gas.md), which represents computational resources, Tx consumes. Gas is dependent on the computational needs of the transaction and is not precisely calculated until execution, but can be estimated by providing auto as the value for --gas. +* `--gas-prices` specifies how much the user is willing pay per unit of gas, which can be one or multiple denominations of tokens. For example, --gas-prices=0.025uatom, 0.025upho means the user is willing to pay 0.025uatom AND 0.025upho per unit of gas. +* `--generate-only` (optional) instructs the application to simply generate the unsigned transaction and output or write to a file. Without this flag, the transaction is created, signed, and broadcasted all in one command. ## Configurations -The last function to define is, `initConfig`, which should do exactly what it sounds like - initial configurations. To call this function, set it as a `PersistentPreRunE` function for the root command, so that it always executes before the main execution of the root command and any of its subcommands. `initConfig()` should do the following: +The last function to define is, `initConfig`, which does exactly what it sounds like - initial configurations. To call this function, set it as a `PersistentPreRunE` function for the root command, so that it always executes before the main execution of the root command and any of its subcommands. `initConfig()` does the following: 1. Read in the `config.toml` file. This same file is edited through `config` commands. 2. Use the [Viper](https://github.com/spf13/viper) to read in configurations from the file and set them. From 62e1da25b5836aed612272e4973b30bc02b34da1 Mon Sep 17 00:00:00 2001 From: Gloria Zhao Date: Tue, 13 Aug 2019 23:53:19 -0400 Subject: [PATCH 058/196] comments --- docs/building-modules/module-interfaces.md | 16 +++++++++ docs/interfaces/query-lifecycle.md | 38 +++++++++++++--------- docs/interfaces/rest.md | 35 ++++++++------------ 3 files changed, 52 insertions(+), 37 deletions(-) diff --git a/docs/building-modules/module-interfaces.md b/docs/building-modules/module-interfaces.md index e4a1ff940713..f1136e63d72c 100644 --- a/docs/building-modules/module-interfaces.md +++ b/docs/building-modules/module-interfaces.md @@ -183,8 +183,24 @@ type buyNameReq struct { Buyer string `json:"buyer"` } ``` + The `BaseReq` includes basic information that every request needs to have, similar to required flags in a CLI. All of these values, including `GasPrices` and `AccountNumber`, will be provided in the request body. The user will also need to specify the arguments `Name` and `Amount` fields in the body and `Buyer` will be provided by the user's address. +#### BaseReq + +`BaseReq` is a type defined in the SDK that encapsulates much of the transaction configurations similar to CLI command flags. Users must provide the information in the body of their requests. + +* `From` indicates which [account](../core/accounts-fees.md) the transaction originates from. This account is used to sign the transaction. +* `Memo` sends a memo along with the transaction. +* `ChainID` specifies the unique identifier of the blockchain the transaction pertains to. +* `AccountNumber` is an identifier for the account. +* `Sequence`is the value of a counter measuring how many transactions have been sent from the account. It is used to prevent replay attacks. +* `Gas` refers to how much [gas](../core/gas.md), which represents computational resources, Tx consumes. Gas is dependent on the transaction and is not precisely calculated until execution, but can be estimated by providing auto as the value for `Gas`. +* `GasAdjustment` can be used to scale gas up in order to avoid underestimating. For example, users can specify their gas adjustment as 1.5 to use 1.5 times the estimated gas. +* `GasPrices` specifies how much the user is willing pay per unit of gas, which can be one or multiple denominations of tokens. For example, --gas-prices=0.025uatom, 0.025upho means the user is willing to pay 0.025uatom AND 0.025upho per unit of gas. +* `Fees` specifies how much in [fees](../core/accounts-fees.md) the user is willing to pay in total. Note that the user only needs to provide either `gas-prices` or `fees`, but not both, because they can be derived from each other. +* `Simulate` instructs the application to ignore gas and simulate the transaction running without broadcasting. + ### Request Handlers Request handlers must be defined for both transaction and query requests. Handlers' arguments include a reference to the application's `codec` and the [`CLIContext`](../interfaces/query-lifecycle.md#clicontext) created in the user interaction. diff --git a/docs/interfaces/query-lifecycle.md b/docs/interfaces/query-lifecycle.md index 44026d16bc2d..7771e4398456 100644 --- a/docs/interfaces/query-lifecycle.md +++ b/docs/interfaces/query-lifecycle.md @@ -16,22 +16,30 @@ This document describes SDK interfaces in detail through the lifecycle of a quer ## Interfaces -A [**query**](../building-modules/messages-and-queries.md#queries) is a request for information made by users of applications. Users can query information about the network, the application itself, and application state directly from the application's stores or modules. +A [**query**](../building-modules/messages-and-queries.md#queries) is a request for information made by end-users of applications through an interface and processed by a full-node. Users can query information about the network, the application itself, and application state directly from the application's stores or modules. Note that queries are different from [transactions](../core/transactions.md) (view the lifecycle [here](../basics/tx-lifecycle.md)), particularly in that they do not require consensus to be processed; they can be fully handled by one full-node. For the purpose of explaining a query lifecycle, let's say `Query` is requesting a list of delegations made by a certain delegator address in the application called `app`. As to be expected, the [`staking`](https://github.com/cosmos/cosmos-sdk/blob/master/docs/spec/staking) module handles this query. But first, there are a few ways `Query` can be created by users. ### CLI -The main interface for an application is the command-line interface. Users connect to a full node and run the CLI directly from their machines. To create `Query` from their terminal, users type the following command: +The main interface for an application is the command-line interface. Users connect to a full-node and run the CLI directly from their machines - the CLI interacts directly with the full-node. To create `Query` from their terminal, users type the following command: -``` +```bash appcli query staking delegations ``` -To provide values such as `--chain-id` (the ID of the blockchain to make the query to), the user must use the `config` command to set them or provide them as flags. +Note that the general format is as follows: + +```bash +appcli query [moduleName] [command] --flag +``` + +To provide values such as `--node` (the full-node the CLI connects to), the user must use the `config` command to set them or provide them as flags. This query command was defined by the [`staking`](https://github.com/cosmos/cosmos-sdk/blob/master/docs/spec/staking) module developer and added to the list of subcommands by the application developer when creating the CLI. The code for this particular command can be found [here](https://github.com/cosmos/cosmos-sdk/blob/master/x/staking/client/cli/query.go#L253-L294). +The CLI understands a specific set of commands, defined in a hierarchical structure by the application developer: from the [root command](./cli.md#root-command) (`appcli`), the type of command (`query`), the module that contains the command (`staking`), and command itself (`delegations`). Thus, the CLI knows exactly which module handles this command and directly passes the call there. + ### REST Another interface through which users can make queries is through HTTP Requests to a [REST server](./rest.md#rest-server). The REST server contains, among other things, a [`CLIContext`](#clicontext) and [mux](./rest.md#gorilla-mux) router. The request looks like this: @@ -40,15 +48,15 @@ Another interface through which users can make queries is through HTTP Requests GET http://localhost:{PORT}/staking/delegators/{delegatorAddr}/delegations ``` -To provide values such as `--chain-id` (the ID of the blockchain to make the query to) that are required by [`baseReq`](./rest.md#basereq), the user must configure their local REST server with the values or provide them in the request body. +To provide values such as `--node` (the full-node the CLI connects to) that are required by [`baseReq`](./rest.md#basereq), the user must configure their local REST server with the values or provide them in the request body. -The router automatically routes the `Query` HTTP request to the staking module `delegatorDelegationsHandlerFn()` function (to see the handler itself, click [here]()). Since this function is defined within the module and thus has no inherent knowledge of the application `Query` belongs to, it takes in the application `codec` and `CLIContext` as parameters. +The router automatically routes the `Query` HTTP request to the staking module `delegatorDelegationsHandlerFn()` function (to see the handler itself, click [here](https://github.com/cosmos/cosmos-sdk/blob/master/x/staking/client/rest/query.go#L103-L106)). Since this function is defined within the module and thus has no inherent knowledge of the application `Query` belongs to, it takes in the application `codec` and `CLIContext` as parameters. -When users interact with the interfaces, the result is a CLI command or HTTP request. `Query` is then created when the command is executed or request handled. +To summarize, when users interact with the interfaces, they create a CLI command or HTTP request. `Query` is then created when the command is executed or HTTP request is handled. ## Request and Command Handling -The interactions from the users' perspective are a bit different, but the underlying functions are almost identical. This section describes how the CLI command or HTTP request is processed, up until the ABCI request is sent. This step of processing heavily involves a `CLIContext`. +The interactions from the users' perspective are a bit different, but the underlying functions are almost identical because they are implementations of the same command defined by the module developer. This step of processing heavily involves a `CLIContext`. ### CLIContext @@ -65,27 +73,27 @@ For full specification of the `CLIContext` type, click [here](https://github.com ### Parameters and Route Creation -The next step is to parse the command or request, extract the arguments, create a `queryRoute`, and encode everything. +The first step is to parse the command or request, extract the arguments, create a `queryRoute`, and encode everything. -In this case, `Query` contains an [address](../core/accounts-fees.md) `delegatorAddress` as its only argument. However, the request can only contain `[]byte`s, as it will be relayed to a consensus engine node that has no inherent knowledge of the application types. Thus, the `CLIContext` `codec` is used to marshal the address as the type [`QueryDelegatorParams`](https://github.com/cosmos/cosmos-sdk/blob/master/x/staking/types/querier.go#L30-L38). All query arguments (e.g. the [`staking`](https://github.com/cosmos/cosmos-sdk/blob/master/docs/spec/staking) module also has [`QueryValidatorParams`](https://github.com/cosmos/cosmos-sdk/blob/master/x/staking/types/querier.go#L45-L53) and [`QueryBondsParams`](https://github.com/cosmos/cosmos-sdk/blob/master/x/staking/types/querier.go#L59-L69)) have their own types that the application `codec` understands how to encode and decode. The module [`querier`](.//building-modules/querier.md) declares these types and the application registers the `codec`s. +**Arguments:** In this case, `Query` contains an [address](../core/accounts-fees.md) `delegatorAddress` as its only argument. However, the request can only contain `[]byte`s, as it will be relayed to a consensus engine node that has no inherent knowledge of the application types. Thus, the `CLIContext` `codec` is used to marshal the address as the type [`QueryDelegatorParams`](https://github.com/cosmos/cosmos-sdk/blob/master/x/staking/types/querier.go#L30-L38). All query arguments (e.g. the [`staking`](https://github.com/cosmos/cosmos-sdk/blob/master/docs/spec/staking) module also has [`QueryValidatorParams`](https://github.com/cosmos/cosmos-sdk/blob/master/x/staking/types/querier.go#L45-L53) and [`QueryBondsParams`](https://github.com/cosmos/cosmos-sdk/blob/master/x/staking/types/querier.go#L59-L69)) have their own types that the application `codec` understands how to encode and decode. The module [`querier`](.//building-modules/querier.md) declares these types and the application registers the `codec`s. -A `route` is also created for `Query` so that the application will understand which module to route the query to. [Baseapp](../core/baseapp.md#query-routing) will understand this query to be a `custom` query in the module `staking` with the type `QueryDelegatorDelegations`. Thus, the route will be `"custom/staking/delegatorDelegations"`. +**Route:** A `route` is also created for `Query` so that the application will understand which module to route the query to. [Baseapp](../core/baseapp.md#query-routing) will understand this query to be a `custom` query in the module `staking` with the type `QueryDelegatorDelegations`. Thus, the route will be `"custom/staking/delegatorDelegations"`. ### ABCI Query -The `CLIContext`'s main `Query` function takes the `route`, which is now called `path`, and arguments, now called `key`. It first retrieves the RPC Client (called the [**node**](../core/node.md)) configured by the user to relay this query to, and creates the `ABCIQueryOptions` (parameters formatted for the ABCI call). The node is then used to make the ABCI call, `ABCIQueryWithOptions()`. +The `CLIContext`'s main `Query` function takes the `route` and arguments. It first retrieves the RPC Client (called the [**node**](../core/node.md)) configured by the user to relay this query to, and creates the `ABCIQueryOptions` (parameters formatted for the ABCI call). The node is then used to make the ABCI call, `ABCIQueryWithOptions()`. ## Tendermint and ABCI -With a call to `ABCIQueryWithOptions()`, `Query` arrives at the consensus engine portion of its lifecycle. Nodes running the consensus engine (e.g. Tendermint Core) make ABCI calls to interact with the application. At this point, `Query` exists as an ABCI `RequestQuery` and the [ABCI Client](https://github.com/tendermint/tendermint/blob/master/abci/client/client.go#L16-L50) calls the ABCI method [`Query()`](https://tendermint.com/docs/spec/abci/abci.html#query) on the application. +With a call to `ABCIQueryWithOptions()`, `Query` is received by a full-node which will then process the request. Note that, while the RPC is made to the consensus engine (e.g. Tendermint Core) of a full-node, queries are not part of consensus and will not be broadcasted to the rest of the network, as they do not require anything the network needs to agree upon. Read more about ABCI Clients and Tendermint RPC in the Tendermint documentation [here](https://tendermint.com/rpc). ## Application Query Handling -[Baseapp](../core/baseapp.md) implements the ABCI [`Query()`](../core/baseapp.md#query) function and handles four different types of queries: `app`, `store`, `p2p`, and `custom`. The `queryRoute` is parsed such that the first string must be one of the four options, then the rest of the path is parsed within the subroutines handling each type of query. The first three types (`app`, `store`, `p2p`) are purely application-level and thus directly handled by Baseapp or the stores, but the `custom` query type requires Baseapp to route the query to a module's [querier](../building-modules/querier.md). +[baseapp](../core/baseapp.md) implements the ABCI [`Query()`](../core/baseapp.md#query) function and handles four different types of queries: `app`, `store`, `p2p`, and `custom`. The `queryRoute` is parsed such that the first string must be one of the four options, then the rest of the path is parsed within the subroutines handling each type of query. The first three types (`app`, `store`, `p2p`) are purely application-level and thus directly handled by Baseapp or the stores, but the `custom` query type requires Baseapp to route the query to a module's [querier](../building-modules/querier.md). -Since `Query` is a custom query type from the `staking` module, Baseapp first parses the path, then uses the `QueryRouter` to retrieve the corresponding querier. The querier is responsible for recognizing this query, retrieving the appropriate values from the application's stores, and returning a response. +Since `Query` is a custom query type from the `staking` module, Baseapp first parses the path, then uses the `QueryRouter` to retrieve the corresponding querier. The querier is responsible for recognizing this query, retrieving the appropriate values from the application's stores, and returning a response. Read more about queriers [here](../building-modules/querier.md). ## Response diff --git a/docs/interfaces/rest.md b/docs/interfaces/rest.md index 858c4b9420a4..5f187d01ea8c 100644 --- a/docs/interfaces/rest.md +++ b/docs/interfaces/rest.md @@ -7,16 +7,20 @@ ## Synopsis -This document describes how to create a REST interface for an SDK application. A separate document for creating module REST Routes can be found [here](#../module-interfaces.md#rest). +This document describes how to create a REST interface for an SDK application. A separate document for creating a module REST interface can be found [here](#../module-interfaces.md#rest). - [Application REST Interface](#application-rest-interface) -- [Request Types](#request-types) - [REST Server](#rest-server) - [Registering Routes](#registering-routes) +- [Request Types](#request-types) ## Application REST Interface -Building the REST Interface for an application involves creating a [REST server](./rest.md#rest-server) to route requests and output responses. The SDK has its own REST Server type used for [LCDs](../core/node.md) (light-client daemons). It has a `ServeCommand` that takes in an application's `codec` and `RegisterRoutes()` function, starts up a new REST Server, and registers routes using function provided from the application. To enable this command, it should be added as a subcommand of the root command `RootCmd` in the `main()` function of the CLI interface. +Building the REST Interface for an application involves creating a [REST server](./rest.md#rest-server) to route requests and output responses. The SDK has its own REST Server type used for [LCDs](../core/node.md) (light-client daemons). It has a `ServeCommand` that takes in an application's `codec` and `RegisterRoutes()` function, starts up a new REST Server, and registers routes using function provided from the application. To enable this command, it should be added as a subcommand of the root command in the `main()` function of the CLI interface: + +```go +rootCmd.AddCommand(lcd.ServeCommand(cdc, registerRoutes)) +``` Users can use the application CLI to start a new LCD, a local server through which they can securely interact with the application without downloading the entire state. The command entered by users would look something like this: @@ -24,26 +28,7 @@ Users can use the application CLI to start a new LCD, a local server through whi appcli rest-server --chain-id --trust-node ``` -## Request Types - -HTTP Request types are defined by the module interfaces for every type of transaction. The structs all include a base request `baseReq`, the name of the request, and any arguments for the transaction. - -### BaseReq -`BaseReq` is a type defined in the SDK that encapsulates much of the transaction configurations similar to CLI command flags. Users must provide the information in the body of their requests. - -* `From` indicates which [account](../core/accounts-fees.md) the transaction originates from. This account is used to sign the transaction. -* `Memo` sends a memo along with the transaction. -* `ChainID` specifies the unique identifier of the blockchain the transaction pertains to. -* `AccountNumber` is an identifier for the account. -* `Sequence`is the value of a counter measuring how many transactions have been sent from the account. It is used to prevent replay attacks. -* `Gas` refers to how much [gas](../core/gas.md), which represents computational resources, Tx consumes. Gas is dependent on the transaction and is not precisely calculated until execution, but can be estimated by providing auto as the value for `Gas`. -* `GasAdjustment` can be used to scale gas up in order to avoid underestimating. For example, users can specify their gas adjustment as 1.5 to use 1.5 times the estimated gas. -* `GasPrices` specifies how much the user is willing pay per unit of gas, which can be one or multiple denominations of tokens. For example, --gas-prices=0.025uatom, 0.025upho means the user is willing to pay 0.025uatom AND 0.025upho per unit of gas. -* `Fees` specifies how much in [fees](../core/accounts-fees.md) the user is willing to pay in total. Note that the user only needs to provide either `gas-prices` or `fees`, but not both, because they can be derived from each other. -* `Simulate` instructs the application to ignore gas and simulate the transaction running without broadcasting. - -Additionally, each request may contain arguments such as a specific address pertaining to the request. ## REST Server @@ -75,3 +60,9 @@ This function is specific to the application and passed in to the `ServeCommand` ```go rootCmd.AddCommand(lcd.ServeCommand(cdc, registerRoutes)) ``` + +## Request Types + +HTTP Request types are defined by the module interfaces for every type of transaction. The structs all include a base request [`baseReq`](../building-modules/module-interfaces.md#basereq), the name of the request, and any arguments for the transaction. + +Additionally, each request may contain arguments such as a specific address pertaining to the request. From 8faeacb95e30297fdfe8fa567cf1598d6af4ad33 Mon Sep 17 00:00:00 2001 From: Gloria Zhao Date: Tue, 13 Aug 2019 23:54:43 -0400 Subject: [PATCH 059/196] minor edits --- docs/interfaces/query-lifecycle.md | 2 +- docs/interfaces/rest.md | 8 -------- 2 files changed, 1 insertion(+), 9 deletions(-) diff --git a/docs/interfaces/query-lifecycle.md b/docs/interfaces/query-lifecycle.md index 7771e4398456..e6a0fa9f4ff4 100644 --- a/docs/interfaces/query-lifecycle.md +++ b/docs/interfaces/query-lifecycle.md @@ -48,7 +48,7 @@ Another interface through which users can make queries is through HTTP Requests GET http://localhost:{PORT}/staking/delegators/{delegatorAddr}/delegations ``` -To provide values such as `--node` (the full-node the CLI connects to) that are required by [`baseReq`](./rest.md#basereq), the user must configure their local REST server with the values or provide them in the request body. +To provide values such as `--node` (the full-node the CLI connects to) that are required by [`baseReq`](../building-modules/module-interfaces.md#basereq), the user must configure their local REST server with the values or provide them in the request body. The router automatically routes the `Query` HTTP request to the staking module `delegatorDelegationsHandlerFn()` function (to see the handler itself, click [here](https://github.com/cosmos/cosmos-sdk/blob/master/x/staking/client/rest/query.go#L103-L106)). Since this function is defined within the module and thus has no inherent knowledge of the application `Query` belongs to, it takes in the application `codec` and `CLIContext` as parameters. diff --git a/docs/interfaces/rest.md b/docs/interfaces/rest.md index 5f187d01ea8c..bf4a010d0fa8 100644 --- a/docs/interfaces/rest.md +++ b/docs/interfaces/rest.md @@ -12,7 +12,6 @@ This document describes how to create a REST interface for an SDK application. A - [Application REST Interface](#application-rest-interface) - [REST Server](#rest-server) - [Registering Routes](#registering-routes) -- [Request Types](#request-types) ## Application REST Interface @@ -29,7 +28,6 @@ appcli rest-server --chain-id --trust-node ``` - ## REST Server A REST Server is used to receive and route HTTP Requests, obtain the results from the application, and return the response to the user. The REST Server defined by the SDK LCD package contains the following: @@ -60,9 +58,3 @@ This function is specific to the application and passed in to the `ServeCommand` ```go rootCmd.AddCommand(lcd.ServeCommand(cdc, registerRoutes)) ``` - -## Request Types - -HTTP Request types are defined by the module interfaces for every type of transaction. The structs all include a base request [`baseReq`](../building-modules/module-interfaces.md#basereq), the name of the request, and any arguments for the transaction. - -Additionally, each request may contain arguments such as a specific address pertaining to the request. From 936afccb11128a6514203ee4de119f24834a0511 Mon Sep 17 00:00:00 2001 From: Gloria Zhao Date: Mon, 19 Aug 2019 19:31:02 -0700 Subject: [PATCH 060/196] better flow for query lifecycle --- docs/interfaces/query-lifecycle.md | 101 ++++++++++++++++++++++++----- 1 file changed, 85 insertions(+), 16 deletions(-) diff --git a/docs/interfaces/query-lifecycle.md b/docs/interfaces/query-lifecycle.md index e6a0fa9f4ff4..6c69aa454e68 100644 --- a/docs/interfaces/query-lifecycle.md +++ b/docs/interfaces/query-lifecycle.md @@ -8,13 +8,13 @@ This document describes SDK interfaces in detail through the lifecycle of a query, from the user interface to application stores and back. The query will be referred to as `Query`. -- [Interfaces](#interfaces) -- [Request and Command Handling](#request-and-command-handling) -- [Tendermint and ABCI](#tendermint-and-abci) +- [Query Creation](#query-creation) +- [Query Preparation](#query-preparation) +- [RPC](#rpc) - [Application Query Handling](#application-query-handling) - [Response](#response) -## Interfaces +## Query Creation A [**query**](../building-modules/messages-and-queries.md#queries) is a request for information made by end-users of applications through an interface and processed by a full-node. Users can query information about the network, the application itself, and application state directly from the application's stores or modules. Note that queries are different from [transactions](../core/transactions.md) (view the lifecycle [here](../basics/tx-lifecycle.md)), particularly in that they do not require consensus to be processed; they can be fully handled by one full-node. @@ -52,11 +52,11 @@ To provide values such as `--node` (the full-node the CLI connects to) that are The router automatically routes the `Query` HTTP request to the staking module `delegatorDelegationsHandlerFn()` function (to see the handler itself, click [here](https://github.com/cosmos/cosmos-sdk/blob/master/x/staking/client/rest/query.go#L103-L106)). Since this function is defined within the module and thus has no inherent knowledge of the application `Query` belongs to, it takes in the application `codec` and `CLIContext` as parameters. -To summarize, when users interact with the interfaces, they create a CLI command or HTTP request. `Query` is then created when the command is executed or HTTP request is handled. +To summarize, when users interact with the interfaces, they create a CLI command or HTTP request. `Query` now exists in one of these two forms, but needs to be transformed into an object understood by a full-node. -## Request and Command Handling +## Query Preparation -The interactions from the users' perspective are a bit different, but the underlying functions are almost identical because they are implementations of the same command defined by the module developer. This step of processing heavily involves a `CLIContext`. +The interactions from the users' perspective are a bit different, but the underlying functions are almost identical because they are implementations of the same command defined by the module developer. This step of processing happens within the CLI or REST server and heavily involves a `CLIContext`. ### CLIContext @@ -69,23 +69,69 @@ The first thing that is created in the execution of a CLI command is a `CLIConte * **Output Writer**: A [Writer](https://golang.org/pkg/io/#Writer) used to output the response. * **Configurations**: The flags configured by the user for this command, including `--height`, specifying the height of the blockchain to query and `--indent`, which indicates to add an indent to the JSON response. -For full specification of the `CLIContext` type, click [here](https://github.com/cosmos/cosmos-sdk/blob/master/client/context/context.go#L36-L59). +The `CLIContext` also contains various functions such as `Query()` which retrieves the RPC Client and makes an ABCI call to relay a query to a full-node. For full specification of the `CLIContext` type, click [here](https://github.com/cosmos/cosmos-sdk/blob/master/client/context/context.go#L36-L59). -### Parameters and Route Creation -The first step is to parse the command or request, extract the arguments, create a `queryRoute`, and encode everything. +The `CLIContext`'s primary role is to store data used during interactions with the end-user and provide methods to interact with this data - it is used before and after the query is processed by the full-node. Specifically, in handling `Query`, the `CLIContext` is utilized to encode the query parameters, retrieve the full-node, and write the output. Prior to being relayed to a full-node, the query needs to be encoded into a `[]byte` form, as full-nodes are application-agnostic and do not understand specific types. The full-node (RPC Client) itself is retrieved using the `CLIContext`, which knows which node the user CLI is connected to. The query is relayed to this full-node to be processed. Finally, the `CLIContext` contains a `Writer` to write output when the response is returned. These steps are further described in later sections. -**Arguments:** In this case, `Query` contains an [address](../core/accounts-fees.md) `delegatorAddress` as its only argument. However, the request can only contain `[]byte`s, as it will be relayed to a consensus engine node that has no inherent knowledge of the application types. Thus, the `CLIContext` `codec` is used to marshal the address as the type [`QueryDelegatorParams`](https://github.com/cosmos/cosmos-sdk/blob/master/x/staking/types/querier.go#L30-L38). All query arguments (e.g. the [`staking`](https://github.com/cosmos/cosmos-sdk/blob/master/docs/spec/staking) module also has [`QueryValidatorParams`](https://github.com/cosmos/cosmos-sdk/blob/master/x/staking/types/querier.go#L45-L53) and [`QueryBondsParams`](https://github.com/cosmos/cosmos-sdk/blob/master/x/staking/types/querier.go#L59-L69)) have their own types that the application `codec` understands how to encode and decode. The module [`querier`](.//building-modules/querier.md) declares these types and the application registers the `codec`s. +### Arguments and Route Creation -**Route:** A `route` is also created for `Query` so that the application will understand which module to route the query to. [Baseapp](../core/baseapp.md#query-routing) will understand this query to be a `custom` query in the module `staking` with the type `QueryDelegatorDelegations`. Thus, the route will be `"custom/staking/delegatorDelegations"`. +At this point in the lifecycle, the user has created a CLI command or HTTP Request with all of the data they wish to include in their `Query`. A `CLIContext` exists to assist in the rest of the `Query`'s journey. Now, the next step is to parse the command or request, extract the arguments, create a `queryRoute`, and encode everything. -### ABCI Query +#### Parse Arguments -The `CLIContext`'s main `Query` function takes the `route` and arguments. It first retrieves the RPC Client (called the [**node**](../core/node.md)) configured by the user to relay this query to, and creates the `ABCIQueryOptions` (parameters formatted for the ABCI call). The node is then used to make the ABCI call, `ABCIQueryWithOptions()`. +In this case, `Query` contains an [address](../core/accounts-fees.md) `delegatorAddress` as its only argument. However, the request can only contain `[]byte`s, as it will be relayed to a consensus engine node that has no inherent knowledge of the application types. Thus, the `CLIContext` `codec` is used to marshal the address as the type [`QueryDelegatorParams`](https://github.com/cosmos/cosmos-sdk/blob/master/x/staking/types/querier.go#L30-L38). All query arguments (e.g. the [`staking`](https://github.com/cosmos/cosmos-sdk/blob/master/docs/spec/staking) module also has [`QueryValidatorParams`](https://github.com/cosmos/cosmos-sdk/blob/master/x/staking/types/querier.go#L45-L53) and [`QueryBondsParams`](https://github.com/cosmos/cosmos-sdk/blob/master/x/staking/types/querier.go#L59-L69)) have their own types that the application `codec` understands how to encode and decode. The module [`querier`](.//building-modules/querier.md) declares these types and the application registers the `codec`s. -## Tendermint and ABCI +Here is what the code looks like for the CLI command: -With a call to `ABCIQueryWithOptions()`, `Query` is received by a full-node which will then process the request. Note that, while the RPC is made to the consensus engine (e.g. Tendermint Core) of a full-node, queries are not part of consensus and will not be broadcasted to the rest of the network, as they do not require anything the network needs to agree upon. +```go +delAddr, err := sdk.AccAddressFromBech32(args[0]) +bz, err := cdc.MarshalJSON(types.NewQueryDelegatorParams(delAddr)) +``` + +Here is what the code looks like for the HTTP Request: + +```go +vars := mux.Vars(r) +bech32delegator := vars["delegatorAddr"] +delegatorAddr, err := sdk.AccAddressFromBech32(bech32delegator) +cliCtx, ok := rest.ParseQueryHeightOrReturnBadRequest(w, cliCtx, r) +if !ok { + return +} +params := types.NewQueryDelegatorParams(delegatorAddr) +``` + +#### Query Route Creation + +Important to note is that there will never be a "query" object created for `Query`; the SDK actually takes a simpler approach. Instead of an object, all the full-node needs to process a query is its `route` which specifies exactly which module to route the query to and the name of this query type. The `route` will be passed to the application baseapp, then module, then [querier](../building-modules/querier.md), and each will understand the `route` and pass it to the appropriate next step. [baseapp](../core/baseapp.md#query-routing) will understand this query to be a `custom` query in the module `staking`, and the `staking` module querier supports the type `QueryDelegatorDelegations`. Thus, the route will be `"custom/staking/delegatorDelegations"`. + +Here is what the code looks like: + +```go +route := fmt.Sprintf("custom/%s/%s", queryRoute, types.QueryDelegatorDelegations) +``` + +Now, `Query` exists as a set of encoded arguments and a route to a specific module and its query type. It is ready to be relayed to a full-node. + +#### ABCI Query Call + +The `CLIContext` has a `Query()` function used to retrieve the pre-configured node and relay a query to it; the function takes the query `route` and arguments as parameters. It first retrieves the RPC Client (called the [**node**](../core/node.md)) configured by the user to relay this query to, and creates the `ABCIQueryOptions` (parameters formatted for the ABCI call). The node is then used to make the ABCI call, `ABCIQueryWithOptions()`. + +Here is what the code looks like (for full specification of all `CLIContext` query functionality, click [here](https://github.com/cosmos/cosmos-sdk/blob/master/client/context/query.go)): + +```go +node, err := ctx.GetNode() +opts := rpcclient.ABCIQueryOptions{ + Height: ctx.Height, + Prove: !ctx.TrustNode, +} +result, err := node.ABCIQueryWithOptions(path, key, opts) +``` + +## RPC + +With a call to `ABCIQueryWithOptions()`, `Query` is received by a [full-node](../core/encoding.md) which will then process the request. Note that, while the RPC is made to the consensus engine (e.g. Tendermint Core) of a full-node, queries are not part of consensus and will not be broadcasted to the rest of the network, as they do not require anything the network needs to agree upon. Read more about ABCI Clients and Tendermint RPC in the Tendermint documentation [here](https://tendermint.com/rpc). @@ -103,10 +149,33 @@ Since `Query()` is an ABCI function, Baseapp returns the response as an [`abci.R The application [`codec`](../core/encoding.md) is used to unmarshal the response to a JSON and the `CLIContext` prints the output to the command line, applying any configurations such as `--indent`. +Here is what the code looks like: + +```go +res, _, err := cliCtx.QueryWithData(route, bz) +var resp types.DelegationResponses +if err := cdc.UnmarshalJSON(res, &resp); err != nil { + return err +} +return cliCtx.PrintOutput(resp) +``` + ### REST Response The [REST server](./rest.md#rest-server) uses the `CLIContext` to format the response properly, then uses the HTTP package to write the appropriate response or error. +Here is what the code looks like: + +```go +res, height, err := cliCtx.QueryWithData(endpoint, bz) +if err != nil { + rest.WriteErrorResponse(w, http.StatusInternalServerError, err.Error()) + return +} +cliCtx = cliCtx.WithHeight(height) +rest.PostProcessResponse(w, cliCtx, res) +``` + ## Next Read about how to build a [Command-Line Interface](./cli.md), or a [REST Interface](./rest.md). From 93a9fab1aa0b35b4168c6aeb5e5bc250b6c63052 Mon Sep 17 00:00:00 2001 From: Gloria Zhao Date: Thu, 18 Jul 2019 10:23:21 -0700 Subject: [PATCH 061/196] add transactions into core --- docs/core/transactions.md | 84 +++++++++++++++++++++++++++++++++++++++ 1 file changed, 84 insertions(+) create mode 100644 docs/core/transactions.md diff --git a/docs/core/transactions.md b/docs/core/transactions.md new file mode 100644 index 000000000000..69a260d3edce --- /dev/null +++ b/docs/core/transactions.md @@ -0,0 +1,84 @@ +# Transactions + +## Prerequisites + +* [Anatomy of an SDK Application](./app-anatomy.md) + +## Synopsis + +This document describes how various components are defined to enable transactions. It also describes how transactions are generated. + +1. [Transactions](#transactions) +2. [Transaction Definition](#transaction-definition) +3. [CLI and REST Interfaces](#cli-and-rest-interfaces) +4. [Messages](#messages) +5. [Transaction Generation](#transaction-generation) +6. [Handlers](#handlers) + + +## Transactions + +[**Transactions**](https://github.com/cosmos/cosmos-sdk/blob/97d10210beb55ad4bd6722f7186a80bf7cb140e2/types/tx_msg.go#L36-L43) are objects that wrap messages and transaction data, created to enable a user interact with an application. Specifically, they are comprised of metadata held in [contexts](./contexts) and [messages](../modules.md#messages) that trigger state changes within a module and are handled by the module's Handler. + +When users want to interact with an application and make state changes (e.g. sending coins), they create transactions. Each of a transaction's messages must be signed using the private key associated with the appropriate account(s), and then the transaction broadcasted to the network. A transaction must then be included in a block, validated, and approved by the network through the consensus process. To read more about the lifecycle of a transaction, click [here](../basics/tx-lifecycle.md). + +## Transaction Definition + +Transactions are defined by module developers. They must implement the [`Tx`](https://github.com/cosmos/cosmos-sdk/blob/73700df8c39d1fe6c3d3a1a635ac03d4bacecf55/types/tx_msg.go#L34-L41) interface and include an encoder and decoder: + +* **GetMsgs:** unwraps the transaction and returns a list of its message(s) - one transaction may have one or multiple messages. +* **ValidateBasic:** includes lightweight, [*stateless*](../basics/tx-lifecycle.md#types-of-checks) checks used by ABCI messages [`CheckTx`](../basics/baseapp.md#checktx) and [`DeliverTx`](../basics/baseapp.md#delivertx) to validate transactions. The `StdTx` `ValidateBasic` function checks that its transactions are signed by the correct number of signers and that the fees do not exceed what the user's maximum. Note that this function is distinct from the `ValidateBasic` functions for *messages*, which are also for transaction validation but only check messages. For example, when [`runTx`](../basics/baseapp.md#runtx-and-runmsgs) is checking a transaction created from the [`auth`](https://github.com/cosmos/cosmos-sdk/tree/67f6b021180c7ef0bcf25b6597a629aca27766b8/docs/spec/auth) module, it first runs `ValidateBasic` on each message, then runs the `auth` module AnteHandler which calls `ValidateBasic` for the transaction itself. +* **TxEncoder:** Nodes running the consensus engine (e.g. Tendermint Core) are responsible for gossiping transactions and ordering them into blocks, but only handle them in the generic `[]byte` form. Transactions are always marshaled (encoded) before they are relayed to nodes, which compacts them to facilitate gossiping and helps maintain the consensus engine's agnosticism with applications. The Cosmos SDK allows developers to specify any deterministic encoding format for their applications; the default is [`Amino`](./amino.md). +* **TxDecoder:** [ABCI](https://tendermint.com/docs/spec/abci/) calls from the consensus engine to the application, such as `CheckTx` and `DeliverTx`, are used to process transaction data to determine validity and state changes. Since transactions are passed in as `txBytes []byte`, they need to first be unmarshaled (decoded) using `TxDecoder` before any logic is applied. + +A transaction is created through one of the possible [interfaces](#interfaces). In the process, two contexts and an array of [messages](#messages) are created, which are then used to [generate](#transaction-generation) the transaction itself. The actual state changes triggered by transactions are enabled by the [handlers](#handlers). The rest of the document will describe each of these components, in this order. + +## CLI and REST Interfaces + +The SDK uses several tools for building [interfaces](./interfaces.md) through which users can create transactions. Application developers create entrypoints to the application by creating a [command-line interface](./interfaces.md#cli) or [REST interface](./interfaces.md#rest), typically found in the application's `/cmd` folder. These interfaces allow users to interact with the application through command-line or through HTTP requests. + +In order for module messages to be utilized in transactions created through these interfaces, module developers must also specify possible user [interactions](../modules/interfaces.md), typically in the module's `/client` folder. For the [command-line interface](../modules/interfaces.md#cli), module developers create subcommands that will be added to the application `tx` command. For [HTTP requests](../modules/interfaces.md#rest), module developers specify acceptable request types, register REST routes, and create HTTP Request Handlers. + +When users interact with the application's interfaces, they invoke the underlying modules' handlers or command functions, directly creating messages. + +## Messages + +**Messages** are module-specific objects that trigger state transitions within the scope of the module they belong to. Module developers define the messages for their module by implementing the [`Msg`](https://github.com/cosmos/cosmos-sdk/blob/97d10210beb55ad4bd6722f7186a80bf7cb140e2/types/tx_msg.go#L10-L31) interface, and also define a [`Handler`](../building-modules/handler.md) to process them. Messages in a module are typically defined in a `msgs.go` file (though not always), and one handler with multiple functions to handle each of the module's messages is defined in a `handler.go` file. + +Note: module messages are not to be confused with [ABCI Messages](https://tendermint.com/docs/spec/abci/abci.html#messages) which define interactions between the Tendermint and application layers. + +The [`Msg`](https://github.com/cosmos/cosmos-sdk/blob/97d10210beb55ad4bd6722f7186a80bf7cb140e2/types/tx_msg.go#L10-L31) interface has five required functions. + +* **Route** returns a string that specifies which module this message is a part of and, thus, which module contains the handler used to implement the actions of this message. [Baseapp](./baseapp.md) uses this function to deliver transactions by invoking the correct handler(s). For example, `MsgSend` is defined in and handled by the `bank` module; its `Route` function returns the name of the `bank` module so `Baseapp` understands to use that module's handler. +* **Type** returns a short, human-readable string that describes what the message does. For example, `MsgSend`'s type is `"send"`. +* **ValidateBasic** implements a set of stateless sanity checks for the message and returns an `Error`. For example, the `validateBasic` method for `MsgSend`, the message which sends coins from one account to another, checks that both sender and recipient addresses are valid and the amount is nonnegative. +* **GetSignBytes** returns a `[]byte` representation of the message which is used by the signer to sign it. +* **GetSigners** returns a list of addresses whose corresponding signatures are required for the message to be valid. For example, `MsgSend` requires a signature from the sender of the coins. + +While messages contain the information for state transition logic, a transaction's other metadata and relevant information are stored in the `TxBuilder` and `CLIContext`. + +## Transaction Generation + +[`Contexts`](https://godoc.org/context) are immutable objects that contain all the information needed to process a request. In the process of creating a transaction, two contexts are created: the [`CLIContext`](../interfaces/query-lifecycle.md#clicontext) and `TxBuilder`. Both are automatically generated and do not need to be defined by application developers, but do require input from the transaction creator (e.g. using flags through the CLI). + +The [`TxBuilder`](https://github.com/cosmos/cosmos-sdk/blob/73700df8c39d1fe6c3d3a1a635ac03d4bacecf55/x/auth/types/txbuilder.go) contains data closely related with the processing of transactions: + +* `TxEncoder` defined by the developer for this type of transaction. Used to encode messages before being processed by nodes running Tendermint. +* `Keybase` that manages the user's keys and is used to perform signing operations. +* `AccountNumber` from which this transaction originated. +* `Sequence`, the number of transactions that the user has sent out, used to prevent replay attacks. +* `Gas` option chosen by the users for how to calculate how much gas they will need to pay. A common option is "auto" which generates an automatic estimate. +* `GasAdjustment` to adjust the estimate of gas by a scalar value, used to avoid underestimating the amount of gas required. +* `SimulateAndExecute` option to simply simulate the transaction execution without broadcasting. +* `ChainID` representing which blockchain this transaction pertains to. +* `Memo` to send with the transaction. +* `Fees`, the maximum amount the user is willing to pay in fees. Alternative to specifying gas prices. +* `GasPrices`, the amount per unit of gas the user is willing to pay in fees. Alternative to specifying fees. + +The `CLIContext` is initialized using the application's `codec` and data more closely related to the user interaction with the interface, holding data such as the output to the user and the broadcast mode. Read more about `CLIContext` [here](../interfaces/query-lifecycle.md#clicontext). + +Every message in a transaction must be signed by the addresses specified by `GetSigners`. The signing process must be handled by a module, and the most widely used one is the [`auth`](https://github.com/cosmos/cosmos-sdk/tree/67f6b021180c7ef0bcf25b6597a629aca27766b8/docs/spec/auth) module. Signing is automatically performed when the transaction is created, unless the user choses to generate and sign separately. The `TxBuilder` (namely, the `KeyBase`) is used to perform the signing operations, and the `CLIContext` is used to broadcast transactions. + +## Handlers + +The final components developers must implement to enable transactions are handlers and keeprs. Each module has a [`Handler`](../building-modules/handler.md) to process all of the module's message types. From 54ee0673bf7d575b4dac4fca2eb0b1debfaaa03c Mon Sep 17 00:00:00 2001 From: Gloria Zhao Date: Wed, 24 Jul 2019 20:16:22 -0700 Subject: [PATCH 062/196] hans comments --- docs/core/transactions.md | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/docs/core/transactions.md b/docs/core/transactions.md index 69a260d3edce..60c2c9f9ac20 100644 --- a/docs/core/transactions.md +++ b/docs/core/transactions.md @@ -18,26 +18,26 @@ This document describes how various components are defined to enable transaction ## Transactions -[**Transactions**](https://github.com/cosmos/cosmos-sdk/blob/97d10210beb55ad4bd6722f7186a80bf7cb140e2/types/tx_msg.go#L36-L43) are objects that wrap messages and transaction data, created to enable a user interact with an application. Specifically, they are comprised of metadata held in [contexts](./contexts) and [messages](../modules.md#messages) that trigger state changes within a module and are handled by the module's Handler. +[**Transactions**](https://github.com/cosmos/cosmos-sdk/blob/97d10210beb55ad4bd6722f7186a80bf7cb140e2/types/tx_msg.go#L36-L43) are objects that wrap messages and transaction data, created to enable a user to interact with an application. Specifically, they are comprised of metadata held in [contexts](./contexts) and [messages](../modules.md#messages) that trigger state changes within a module and are handled by the module's Handler. -When users want to interact with an application and make state changes (e.g. sending coins), they create transactions. Each of a transaction's messages must be signed using the private key associated with the appropriate account(s), and then the transaction broadcasted to the network. A transaction must then be included in a block, validated, and approved by the network through the consensus process. To read more about the lifecycle of a transaction, click [here](../basics/tx-lifecycle.md). +When users want to interact with an application and make state changes (e.g. sending coins), they create transactions. Each of a transaction's messages must be signed using the private key associated with the appropriate account(s), and then the transaction is broadcasted to the network. A transaction must then be included in a block, validated, and approved by the network through the consensus process. To read more about the lifecycle of a transaction, click [here](../basics/tx-lifecycle.md). ## Transaction Definition -Transactions are defined by module developers. They must implement the [`Tx`](https://github.com/cosmos/cosmos-sdk/blob/73700df8c39d1fe6c3d3a1a635ac03d4bacecf55/types/tx_msg.go#L34-L41) interface and include an encoder and decoder: +Transactions messages are defined by module developers. The transaction objects themselves are SDK types that implement the [`Tx`](https://github.com/cosmos/cosmos-sdk/blob/73700df8c39d1fe6c3d3a1a635ac03d4bacecf55/types/tx_msg.go#L34-L41) interface and include an encoder and decoder: * **GetMsgs:** unwraps the transaction and returns a list of its message(s) - one transaction may have one or multiple messages. * **ValidateBasic:** includes lightweight, [*stateless*](../basics/tx-lifecycle.md#types-of-checks) checks used by ABCI messages [`CheckTx`](../basics/baseapp.md#checktx) and [`DeliverTx`](../basics/baseapp.md#delivertx) to validate transactions. The `StdTx` `ValidateBasic` function checks that its transactions are signed by the correct number of signers and that the fees do not exceed what the user's maximum. Note that this function is distinct from the `ValidateBasic` functions for *messages*, which are also for transaction validation but only check messages. For example, when [`runTx`](../basics/baseapp.md#runtx-and-runmsgs) is checking a transaction created from the [`auth`](https://github.com/cosmos/cosmos-sdk/tree/67f6b021180c7ef0bcf25b6597a629aca27766b8/docs/spec/auth) module, it first runs `ValidateBasic` on each message, then runs the `auth` module AnteHandler which calls `ValidateBasic` for the transaction itself. -* **TxEncoder:** Nodes running the consensus engine (e.g. Tendermint Core) are responsible for gossiping transactions and ordering them into blocks, but only handle them in the generic `[]byte` form. Transactions are always marshaled (encoded) before they are relayed to nodes, which compacts them to facilitate gossiping and helps maintain the consensus engine's agnosticism with applications. The Cosmos SDK allows developers to specify any deterministic encoding format for their applications; the default is [`Amino`](./amino.md). +* **TxEncoder:** Nodes running the consensus engine (e.g. Tendermint Core) are responsible for gossiping transactions and ordering them into blocks, but only handle them in the generic `[]byte` form. Transactions are always marshaled (encoded) before they are relayed to nodes, which compacts them to facilitate gossiping and helps maintain the consensus engine's separation from from application logic. The Cosmos SDK allows developers to specify any deterministic encoding format for their applications; the default is [`Amino`](./amino.md). * **TxDecoder:** [ABCI](https://tendermint.com/docs/spec/abci/) calls from the consensus engine to the application, such as `CheckTx` and `DeliverTx`, are used to process transaction data to determine validity and state changes. Since transactions are passed in as `txBytes []byte`, they need to first be unmarshaled (decoded) using `TxDecoder` before any logic is applied. A transaction is created through one of the possible [interfaces](#interfaces). In the process, two contexts and an array of [messages](#messages) are created, which are then used to [generate](#transaction-generation) the transaction itself. The actual state changes triggered by transactions are enabled by the [handlers](#handlers). The rest of the document will describe each of these components, in this order. ## CLI and REST Interfaces -The SDK uses several tools for building [interfaces](./interfaces.md) through which users can create transactions. Application developers create entrypoints to the application by creating a [command-line interface](./interfaces.md#cli) or [REST interface](./interfaces.md#rest), typically found in the application's `/cmd` folder. These interfaces allow users to interact with the application through command-line or through HTTP requests. +The SDK uses several tools for building [interfaces](./interfaces.md) through which users can create transactions through the command-line or HTTP Requests. Application developers create entrypoints to the application by creating a [command-line interface](./interfaces.md#cli) or [REST interface](./interfaces.md#rest), typically found in the application's `/cmd` folder. These interfaces allow users to interact with the application through command-line or through HTTP requests. -In order for module messages to be utilized in transactions created through these interfaces, module developers must also specify possible user [interactions](../modules/interfaces.md), typically in the module's `/client` folder. For the [command-line interface](../modules/interfaces.md#cli), module developers create subcommands that will be added to the application `tx` command. For [HTTP requests](../modules/interfaces.md#rest), module developers specify acceptable request types, register REST routes, and create HTTP Request Handlers. +In order for module messages to be utilized in transactions created through these interfaces, module developers must also specify possible user [interactions](../modules/interfaces.md), typically in the module's `/client` folder. For the [command-line interface](../modules/interfaces.md#cli), module developers create subcommands to add as children to the application top-level transaction command `TxCmd`. For [HTTP requests](../modules/interfaces.md#rest), module developers specify acceptable request types, register REST routes, and create HTTP Request Handlers. When users interact with the application's interfaces, they invoke the underlying modules' handlers or command functions, directly creating messages. @@ -45,7 +45,7 @@ When users interact with the application's interfaces, they invoke the underlyin **Messages** are module-specific objects that trigger state transitions within the scope of the module they belong to. Module developers define the messages for their module by implementing the [`Msg`](https://github.com/cosmos/cosmos-sdk/blob/97d10210beb55ad4bd6722f7186a80bf7cb140e2/types/tx_msg.go#L10-L31) interface, and also define a [`Handler`](../building-modules/handler.md) to process them. Messages in a module are typically defined in a `msgs.go` file (though not always), and one handler with multiple functions to handle each of the module's messages is defined in a `handler.go` file. -Note: module messages are not to be confused with [ABCI Messages](https://tendermint.com/docs/spec/abci/abci.html#messages) which define interactions between the Tendermint and application layers. +Note: module messages are not to be confused with [ABCI Messages](https://tendermint.com/docs/spec/abci/abci.html#messages) which define interactions between the Tendermint and application layers. While ABCI messages such as CheckTx and DeliverTx contain Transactions, which contain module Messages, they are not to be confused with the module level messages themselves The [`Msg`](https://github.com/cosmos/cosmos-sdk/blob/97d10210beb55ad4bd6722f7186a80bf7cb140e2/types/tx_msg.go#L10-L31) interface has five required functions. @@ -81,4 +81,4 @@ Every message in a transaction must be signed by the addresses specified by `Get ## Handlers -The final components developers must implement to enable transactions are handlers and keeprs. Each module has a [`Handler`](../building-modules/handler.md) to process all of the module's message types. +The final components developers must implement to enable transactions are handlers and keeprs. Each module has a Handler to process all of the module's message types. To read more about handlers, visit the documentation for building modules [here](../building-modules/handler.md). From de0aebf7c9353de77654917dcd28f09121b0ec21 Mon Sep 17 00:00:00 2001 From: Gloria Zhao Date: Thu, 18 Jul 2019 10:23:21 -0700 Subject: [PATCH 063/196] add transactions into core --- docs/core/transactions.md | 34 +++++++++++++++------------------- 1 file changed, 15 insertions(+), 19 deletions(-) diff --git a/docs/core/transactions.md b/docs/core/transactions.md index 60c2c9f9ac20..a2cd7bb494ee 100644 --- a/docs/core/transactions.md +++ b/docs/core/transactions.md @@ -18,50 +18,46 @@ This document describes how various components are defined to enable transaction ## Transactions -[**Transactions**](https://github.com/cosmos/cosmos-sdk/blob/97d10210beb55ad4bd6722f7186a80bf7cb140e2/types/tx_msg.go#L36-L43) are objects that wrap messages and transaction data, created to enable a user to interact with an application. Specifically, they are comprised of metadata held in [contexts](./contexts) and [messages](../modules.md#messages) that trigger state changes within a module and are handled by the module's Handler. +[**Transactions**](https://github.com/cosmos/cosmos-sdk/blob/master/types/tx_msg.go#L36-L43) are objects created by end-users to trigger state changes in the application. Specifically, they are comprised of metadata held in [contexts](./context.md) and [messages](../building-modules/messages-and-queries.md) that trigger state changes within a module through the module's Handler. When users want to interact with an application and make state changes (e.g. sending coins), they create transactions. Each of a transaction's messages must be signed using the private key associated with the appropriate account(s), and then the transaction is broadcasted to the network. A transaction must then be included in a block, validated, and approved by the network through the consensus process. To read more about the lifecycle of a transaction, click [here](../basics/tx-lifecycle.md). ## Transaction Definition -Transactions messages are defined by module developers. The transaction objects themselves are SDK types that implement the [`Tx`](https://github.com/cosmos/cosmos-sdk/blob/73700df8c39d1fe6c3d3a1a635ac03d4bacecf55/types/tx_msg.go#L34-L41) interface and include an encoder and decoder: +The transaction objects themselves are SDK types that implement the [`Tx`](https://github.com/cosmos/cosmos-sdk/blob/master/types/tx_msg.go#L34-L41) interface and include an encoder and decoder: -* **GetMsgs:** unwraps the transaction and returns a list of its message(s) - one transaction may have one or multiple messages. -* **ValidateBasic:** includes lightweight, [*stateless*](../basics/tx-lifecycle.md#types-of-checks) checks used by ABCI messages [`CheckTx`](../basics/baseapp.md#checktx) and [`DeliverTx`](../basics/baseapp.md#delivertx) to validate transactions. The `StdTx` `ValidateBasic` function checks that its transactions are signed by the correct number of signers and that the fees do not exceed what the user's maximum. Note that this function is distinct from the `ValidateBasic` functions for *messages*, which are also for transaction validation but only check messages. For example, when [`runTx`](../basics/baseapp.md#runtx-and-runmsgs) is checking a transaction created from the [`auth`](https://github.com/cosmos/cosmos-sdk/tree/67f6b021180c7ef0bcf25b6597a629aca27766b8/docs/spec/auth) module, it first runs `ValidateBasic` on each message, then runs the `auth` module AnteHandler which calls `ValidateBasic` for the transaction itself. -* **TxEncoder:** Nodes running the consensus engine (e.g. Tendermint Core) are responsible for gossiping transactions and ordering them into blocks, but only handle them in the generic `[]byte` form. Transactions are always marshaled (encoded) before they are relayed to nodes, which compacts them to facilitate gossiping and helps maintain the consensus engine's separation from from application logic. The Cosmos SDK allows developers to specify any deterministic encoding format for their applications; the default is [`Amino`](./amino.md). +* **GetMsgs:** unwraps the transaction and returns a list of its message(s) - one transaction may have one or multiple [messages](../building-modules/messages-and-queries.md#messages), which are defined by module developers. +* **ValidateBasic:** includes lightweight, [*stateless*](../basics/tx-lifecycle.md#types-of-checks) checks used by ABCI messages [`CheckTx`](../basics/baseapp.md#checktx) and [`DeliverTx`](../basics/baseapp.md#delivertx) to make sure transactions are not invalid. The `StdTx` `ValidateBasic` function checks that its transactions are signed by the correct number of signers and that the fees do not exceed what the user's maximum. Note that this function is distinct from the `ValidateBasic` functions for *messages*, which perform basic validity checks on messages only. For example, when [`runTx`](../basics/baseapp.md#runtx-and-runmsgs) is checking a transaction created from the [`auth`](https://github.com/cosmos/cosmos-sdk/blob/master/docs/spec/auth) module, it first runs `ValidateBasic` on each message, then runs the `auth` module AnteHandler which calls `ValidateBasic` for the transaction itself. +* **TxEncoder:** Nodes running the consensus engine (e.g. Tendermint Core) are responsible for gossiping transactions and ordering them into blocks, but only handle them in the generic `[]byte` form. Transactions are always [marshaled](./encoding.md) (encoded) before they are relayed to nodes, which compacts them to facilitate gossiping and helps maintain the consensus engine's separation from from application logic. The Cosmos SDK allows developers to specify any deterministic encoding format for their applications; the default is Amino. * **TxDecoder:** [ABCI](https://tendermint.com/docs/spec/abci/) calls from the consensus engine to the application, such as `CheckTx` and `DeliverTx`, are used to process transaction data to determine validity and state changes. Since transactions are passed in as `txBytes []byte`, they need to first be unmarshaled (decoded) using `TxDecoder` before any logic is applied. A transaction is created through one of the possible [interfaces](#interfaces). In the process, two contexts and an array of [messages](#messages) are created, which are then used to [generate](#transaction-generation) the transaction itself. The actual state changes triggered by transactions are enabled by the [handlers](#handlers). The rest of the document will describe each of these components, in this order. ## CLI and REST Interfaces -The SDK uses several tools for building [interfaces](./interfaces.md) through which users can create transactions through the command-line or HTTP Requests. Application developers create entrypoints to the application by creating a [command-line interface](./interfaces.md#cli) or [REST interface](./interfaces.md#rest), typically found in the application's `/cmd` folder. These interfaces allow users to interact with the application through command-line or through HTTP requests. +Application developers create entrypoints to the application by creating a [command-line interface](../interfaces/cli.md) or [REST interface](../interfaces/rest.md), typically found in the application's `/cmd` folder. These interfaces allow users to interact with the application through command-line or through HTTP requests. -In order for module messages to be utilized in transactions created through these interfaces, module developers must also specify possible user [interactions](../modules/interfaces.md), typically in the module's `/client` folder. For the [command-line interface](../modules/interfaces.md#cli), module developers create subcommands to add as children to the application top-level transaction command `TxCmd`. For [HTTP requests](../modules/interfaces.md#rest), module developers specify acceptable request types, register REST routes, and create HTTP Request Handlers. +In order for module messages to be utilized in transactions created through these interfaces, module developers must also specify possible user [interactions](../building-modules/interfaces.md), typically in the module's `/client` folder. For the [command-line interface](../building-modules/interfaces.md#cli), module developers create subcommands to add as children to the application top-level transaction command `TxCmd`. For [HTTP requests](../building-modules/interfaces.md#rest), module developers specify acceptable request types, register REST routes, and create HTTP Request Handlers. When users interact with the application's interfaces, they invoke the underlying modules' handlers or command functions, directly creating messages. ## Messages -**Messages** are module-specific objects that trigger state transitions within the scope of the module they belong to. Module developers define the messages for their module by implementing the [`Msg`](https://github.com/cosmos/cosmos-sdk/blob/97d10210beb55ad4bd6722f7186a80bf7cb140e2/types/tx_msg.go#L10-L31) interface, and also define a [`Handler`](../building-modules/handler.md) to process them. Messages in a module are typically defined in a `msgs.go` file (though not always), and one handler with multiple functions to handle each of the module's messages is defined in a `handler.go` file. +**Messages** are module-specific objects that trigger state transitions within the scope of the module they belong to. Module developers define the messages for their module by implementing the [`Msg`](https://github.com/cosmos/cosmos-sdk/blob/master/types/tx_msg.go#L10-L31) interface, and also define a [`Handler`](../building-modules/handler.md) to process them. Messages in a module are typically defined in a `msgs.go` file (though not always), and one handler with multiple functions to handle each of the module's messages is defined in a `handler.go` file. Note: module messages are not to be confused with [ABCI Messages](https://tendermint.com/docs/spec/abci/abci.html#messages) which define interactions between the Tendermint and application layers. While ABCI messages such as CheckTx and DeliverTx contain Transactions, which contain module Messages, they are not to be confused with the module level messages themselves -The [`Msg`](https://github.com/cosmos/cosmos-sdk/blob/97d10210beb55ad4bd6722f7186a80bf7cb140e2/types/tx_msg.go#L10-L31) interface has five required functions. - -* **Route** returns a string that specifies which module this message is a part of and, thus, which module contains the handler used to implement the actions of this message. [Baseapp](./baseapp.md) uses this function to deliver transactions by invoking the correct handler(s). For example, `MsgSend` is defined in and handled by the `bank` module; its `Route` function returns the name of the `bank` module so `Baseapp` understands to use that module's handler. -* **Type** returns a short, human-readable string that describes what the message does. For example, `MsgSend`'s type is `"send"`. -* **ValidateBasic** implements a set of stateless sanity checks for the message and returns an `Error`. For example, the `validateBasic` method for `MsgSend`, the message which sends coins from one account to another, checks that both sender and recipient addresses are valid and the amount is nonnegative. -* **GetSignBytes** returns a `[]byte` representation of the message which is used by the signer to sign it. -* **GetSigners** returns a list of addresses whose corresponding signatures are required for the message to be valid. For example, `MsgSend` requires a signature from the sender of the coins. +To learn more about messages, click [here](../building-modules/messages-and-queries.md#messages). While messages contain the information for state transition logic, a transaction's other metadata and relevant information are stored in the `TxBuilder` and `CLIContext`. ## Transaction Generation -[`Contexts`](https://godoc.org/context) are immutable objects that contain all the information needed to process a request. In the process of creating a transaction, two contexts are created: the [`CLIContext`](../interfaces/query-lifecycle.md#clicontext) and `TxBuilder`. Both are automatically generated and do not need to be defined by application developers, but do require input from the transaction creator (e.g. using flags through the CLI). +Transactions are first created by end-users through an `appcli tx` command through the command-line or a POST request to an HTTPS server. For details about transaction creation, click [here](../basics/tx-lifecycle.md#transaction-creation). + +[`Contexts`](https://godoc.org/context) are immutable objects that contain all the information needed to process a request. In the process of creating a transaction through the `auth` module (though it is not mandatory to create transactions this way), two contexts are created: the [`CLIContext`](../interfaces/query-lifecycle.md#clicontext) and `TxBuilder`. Both are automatically generated and do not need to be defined by application developers, but do require input from the transaction creator (e.g. using flags through the CLI). -The [`TxBuilder`](https://github.com/cosmos/cosmos-sdk/blob/73700df8c39d1fe6c3d3a1a635ac03d4bacecf55/x/auth/types/txbuilder.go) contains data closely related with the processing of transactions: +The [`TxBuilder`](https://github.com/cosmos/cosmos-sdk/blob/master/x/auth/types/txbuilder.go) contains data closely related with the processing of transactions: * `TxEncoder` defined by the developer for this type of transaction. Used to encode messages before being processed by nodes running Tendermint. * `Keybase` that manages the user's keys and is used to perform signing operations. @@ -77,8 +73,8 @@ The [`TxBuilder`](https://github.com/cosmos/cosmos-sdk/blob/73700df8c39d1fe6c3d3 The `CLIContext` is initialized using the application's `codec` and data more closely related to the user interaction with the interface, holding data such as the output to the user and the broadcast mode. Read more about `CLIContext` [here](../interfaces/query-lifecycle.md#clicontext). -Every message in a transaction must be signed by the addresses specified by `GetSigners`. The signing process must be handled by a module, and the most widely used one is the [`auth`](https://github.com/cosmos/cosmos-sdk/tree/67f6b021180c7ef0bcf25b6597a629aca27766b8/docs/spec/auth) module. Signing is automatically performed when the transaction is created, unless the user choses to generate and sign separately. The `TxBuilder` (namely, the `KeyBase`) is used to perform the signing operations, and the `CLIContext` is used to broadcast transactions. +Every message in a transaction must be signed by the addresses specified by `GetSigners`. The signing process must be handled by a module, and the most widely used one is the [`auth`](https://github.com/cosmos/cosmos-sdk/blob/master/docs/spec/auth) module. Signing is automatically performed when the transaction is created, unless the user choses to generate and sign separately. The `TxBuilder` (namely, the `KeyBase`) is used to perform the signing operations, and the `CLIContext` is used to broadcast transactions. ## Handlers -The final components developers must implement to enable transactions are handlers and keeprs. Each module has a Handler to process all of the module's message types. To read more about handlers, visit the documentation for building modules [here](../building-modules/handler.md). +The final components developers must implement to enable transactions are handlers and keepers. Since messages are module types, each module needs a Handler to process all of its message types and enact the state changes within the module's scope. This design puts more responsibility in module developers, allowing application developers to reuse common functionalities without having to implement state transition logic repetitively. To read more about handlers, visit the documentation for building modules [here](../building-modules/handler.md). From 207132cef08703e69bc8a5c5d5b188eaf22b229f Mon Sep 17 00:00:00 2001 From: Gloria Zhao Date: Wed, 21 Aug 2019 14:28:34 -0700 Subject: [PATCH 064/196] checkout master-docs files --- docs/.vuepress/config.js | 3 +- docs/basics/app-anatomy.md | 94 +++++++--------- docs/building-modules/intro.md | 29 ++--- docs/core/baseapp.md | 165 +++++++++++------------------ docs/core/node.md | 2 +- docs/intro/README.md | 15 +-- docs/intro/sdk-app-architecture.md | 26 ++--- docs/intro/why-app-specific.md | 39 +++---- 8 files changed, 155 insertions(+), 218 deletions(-) diff --git a/docs/.vuepress/config.js b/docs/.vuepress/config.js index 602d20781420..9ee6a31059c5 100644 --- a/docs/.vuepress/config.js +++ b/docs/.vuepress/config.js @@ -31,8 +31,7 @@ module.exports = { "/intro/", "/intro/why-app-specific", "/intro/sdk-app-architecture", - "/intro/sdk-design", - "/intro/ocap" + "/intro/sdk-design" ] }, { diff --git a/docs/basics/app-anatomy.md b/docs/basics/app-anatomy.md index 2e4613c5e8b6..dc58e389342a 100644 --- a/docs/basics/app-anatomy.md +++ b/docs/basics/app-anatomy.md @@ -55,9 +55,9 @@ Blockchain Node | | Consensus | | The blockchain full-node presents itself as a binary, generally suffixed by `-d` for "daemon" (e.g. `appd` for `app` or `gaiad` for `gaia`). This binary is built by running a simple `main.go` function placed in `cmd/appd/`. This operation usually happens through the [Makefile](#dependencies-and-makefile). -To learn more about the `main.go` function, [click here](../core/node.md#main-function). +To learn more about the `main.go` function, [click here](./node.md#main-function). -Once the main binary is built, the node can be started by running the `start` command. The core logic behind the `start` command is implemented in the SDK itself in the [`/server/start.go`](https://github.com/cosmos/cosmos-sdk/blob/master/server/start.go) file. The main [`start` command function](https://github.com/cosmos/cosmos-sdk/blob/master/server/start.go#L31) takes a [`context`](https://godoc.org/github.com/cosmos/cosmos-sdk/client/context) and [`appCreator`](#constructor-function-(`appCreator`)) as arguments. The `appCreator` is a constructor function for the SDK application, and is used in the starting process of the full-node. +Once the main binary is built, the node can be started by running the `start` command. The core logic behind the `start` command is implemented in the SDK itself in the [`/server/start.go`](https://github.com/cosmos/cosmos-sdk/blob/master/server/start.go) file. The main [`start` command function](https://github.com/cosmos/cosmos-sdk/blob/master/server/start.go#L31) takes a [`context`](https://godoc.org/github.com/cosmos/cosmos-sdk/client/context) and [`appCreator`](<#constructor-function-(`appCreator`)>) as arguments. The `appCreator` is a constructor function for the SDK application, and is used in the starting process of the full-node. The `start` command function primarily does three things: @@ -65,8 +65,6 @@ The `start` command function primarily does three things: 2. Initialize the state-machine with the latest known state, extracted from the `db` stored in the `~/.appd/data` folder. At this point, the state-machine is at height `appBlockHeight`. 3. Create and start a new Tendermint instance. Among other things, the node will perform a handshake with its peers. It will get the latest `blockHeight` from them, and replay blocks to sync to this height if it is greater than the local `appBlockHeight`. If `appBlockHeight` is `0`, the node is starting from genesis and Tendermint sends an `InitChain` message via the ABCI to the `app`, which triggers the [`InitChainer`](#initchainer). -To learn more about the `start` command, [click here](../core/node.md#start-command). - ## Core Application File In general, the core of the state-machine is defined in a file called `app.go`. It mainly contains the **type definition of the application** and functions to **create and initialize it**. @@ -75,11 +73,11 @@ In general, the core of the state-machine is defined in a file called `app.go`. The first thing defined in `app.go` is the `type` of the application. It is generally comprised of the following parts: -- **A reference to [`baseapp`](../core/baseapp.md).** The custom application defined in `app.go` is an extension of the `baseapp` type. `baseapp` implements most of the core logic for the application, including all the [ABCI methods](https://tendermint.com/docs/spec/abci/abci.html#overview) and the routing logic. When a transaction is relayed by Tendermint to the application, the latter uses `baseapp`'s methods to route them to the appropriate module. -- **A list of store keys**. The [store](../core/store.md), which contains the entire state, is implemented as a multistore (i.e. a store of stores) in the Cosmos SDK. Each module uses one or multiple stores in the multistore to persist their part of the state. These stores can be accessed with specific keys that are declared in the `app` type. These keys, along with the `keepers`, are at the heart of the [object-capabilities model](../intro/ocap.md) of the Cosmos SDK. -- **A list of module's `keepers`.** Each module defines an abstraction called [`keeper`](../building-modules/keeper.md), which handles reads and writes for this module's store(s). The `keeper`'s methods of one module can be called from other modules (if authorized), which is why they are declared in the application's type and exported as interfaces to other modules so that they are only allowed to access the authorized functions. -- **A reference to a [`codec`](../core/encoding.md).** The Cosmos SDK gives developers the freedom to choose the encoding framework for their application. The application's `codec` is used to serialize and deserialize data structures in order to store them, as stores can only persist `[]bytes`. The `codec` must be deterministic. The default codec is [amino](./amino.md). -- **A reference to a [module manager](../building-modules/module-manager.md#manager)** and a [basic module manager](../building-modules/module-manager.md#basicmanager). The module manager is an object that contains a list of the application's module. It facilitates operations related to these modules, like registering [`routes`](./baseapp.md#routing), [query routes](#./baseapp.md#query-routing) or setting the order of execution between modules for various functions like [`InitChainer`](#initchainer), [`BeginBlocker` and `EndBlocker`](#beginblocker-and-endblocker). +- **A reference to [`baseapp`](./baseapp.md).** The custom application defined in `app.go` is an extension of the `baseapp` type. `baseapp` implements most of the core logic for the application, including all the [ABCI methods](https://tendermint.com/docs/spec/abci/abci.html#overview) and the routing logic. When a transaction is relayed by Tendermint to the application, the latter uses `baseapp`'s methods to route them to the appropriate module. +- **A list of store keys**. The [store](./store.md), which contains the entire state, is implemented as a multistore (i.e. a store of stores) in the Cosmos SDK. Each module uses one or multiple stores in the multistore to persist their part of the state. These stores can be accessed with specific keys that are declared in the `app` type. These keys, along with the `keepers`, are at the heart of the [object-capabilities model](../intro/ocap.md) of the Cosmos SDK. +- **A list of module's `keepers`.** Each module defines an abstraction called `keeper`, which handles reads and writes for this module's store(s). The `keeper`'s methods of one module can be called from other modules (if authorized), which is why they are declared in the application's type and exported as interfaces to other modules so that they are only allowed to access the authorized functions. +- **A reference to a `codec`.** The Cosmos SDK gives developers the freedom to choose the encoding framework for their application. The application's `codec` is used to serialize and deserialize data structures in order to store them, as stores can only persist `[]bytes`. The `codec` must be deterministic. The default codec is [amino](./amino.md). +- **A reference to a [module manager](./modules.md#module-manager)**. The module manager is an object that contains a list of the application's module. It facilitates operations related to these modules, like registering [`routes`](./baseapp.md#routing), [query routes](#./baseapp.md#query-routing) or setting the order of execution between modules for various functions like [`InitChainer`](#initchainer), [`BeginBlocker` and `EndBlocker`](#beginblocker-and-endblocker). You can see an example of application type definition [here](https://github.com/cosmos/gaia/blob/master/app/app.go#L73-L107). @@ -87,17 +85,16 @@ You can see an example of application type definition [here](https://github.com/ This function constructs a new application of the type defined above. It is called every time the full-node is started with the [`start`](https://github.com/cosmos/cosmos-sdk/blob/master/server/start.go#L117) command. Here are the main actions performed by this function: -- Instantiate a new [`codec`](../core/encoding.md) and initialize the `codec` of each of the application's module using the [basic manager](../building-modules/module-manager.md#basicmanager) - Instantiate a new application with a reference to a `baseapp` instance, a codec and all the appropriate store keys. - Instantiate all the [`keeper`s](#keeper) defined in the application's `type` using the `NewKeeper` function of each of the application's modules. Note that `keepers` must be instantiated in the correct order, as the `NewKeeper` of one module might require a reference to another module's `keeper`. -- Instantiate the application's [module manager](../building-modules/module-manager.md#manager) with the [`AppModule`](#application-module-interface) object of each of the application's modules. -- With the module manager, initialize the application's [`routes`](../core/baseapp.md#routing) and [query routes](../core/baseapp.md#query-routing). When a transaction is relayed to the application by Tendermint via the ABCI, it is routed to the appropriate module's [`handler`](#handler) using the routes defined here. Likewise, when a query is received by the application, it is routed to the appropriate module's [`querier`](#querier) using the query routes defined here. -- With the module manager, register the [application's modules' invariants](./invariants.md). Invariants are variables (e.g. total supply of a token) that are evaluated at the end of each block. The process of checking invariants is done via a special module called the [`InvariantsRegistry`](../building-modules/invariants.md#invariant-registry). The value of the invariant should be equal to a predicted value defined in the module. Should the value be different than the predicted one, special logic defined in the invariant registry will be triggered (usually the chain is halted). This is useful to make sure no critical bug goes unnoticed and produces long-lasting effects that would be hard to fix. -- With the module manager, set the order of execution between the `InitGenesis`, `BegingBlocker` and `EndBlocker` functions of each of the [application's modules](#application-module-interface). Note that not all modules implement these functions. +- Instantiate the application's [module manager](./module-manager.md) with the [`AppModule`](#application-module-interface) object of each of the application's modules. +- With the module manager, initialize the application's [`routes`](./baseapp.md#routing) and [query routes](./baseapp.md#query-routing). When a transaction is relayed to the application by Tendermint via the ABCI, it is routed to the appropriate module's [`handler`](#handler) using the routes defined here. Likewise, when a query is received by the application, it is routed to the appropriate module's [`querier`](#querier) using the query routes defined here. +- With the module manager, register the [application's modules' invariants](./invariants.md). Invariants are variables (e.g. total supply of a token) that are evaluated at the end of each block. The process of checking invariants is done via a special module called the [`InvariantsRegistry`](./invariants.md#invariant-registry). The value of the invariant should be equal to a predicted value defined in the module. Should the value be different than the predicted one, special logic defined in the invariant registry will be triggered (usually the chain is halted). This is useful to make sure no critical bug goes unnoticed and produces long-lasting effects that would be hard to fix. +- With the module manager, set the order of execution between the `InitGenesis`, `BegingBlocker` and `EndBlocker` functions of each of the [application's modules](#application-module-interface). Note that not all modules implement these functions. - Set the remainer of application's parameters: - + [`InitChainer`](#initchainer): used to initialize the application when it is first started. - + [`BeginBlocker`, `EndBlocker`](#beginblocker-and-endlbocker): called at the beginning and the end of every block). - + [`anteHandler`](../core/baseapp.md#antehandler): used to handle fees and signature verification. + - [`InitChainer`](#initchainer): used to initialize the application when it is first started. + - [`BeginBlocker`, `EndBlocker`](#beginblocker-and-endlbocker): called at the beginning and the end of every block). + - [`anteHandler`](#baseapp.md#antehandler): used to handle fees and signature verification. - Mount the stores. - Return the application. @@ -107,7 +104,7 @@ You can see an example of application constructor [here](https://github.com/cosm ### InitChainer -The `InitChainer` is a function that initializes the state of the application from a [genesis file](../core/genesis.md) (i.e. token balances of genesis accounts). It is called when the application receives the `InitChain` message from the Tendermint engine, which happens when the node is started at `appBlockHeight == 0` (i.e. on genesis). The application must set the `InitChainer` in its constructor via the [`SetInitChainer`](https://godoc.org/github.com/cosmos/cosmos-sdk/baseapp#BaseApp.SetInitChainer) method. +The `InitChainer` is a function that initializes the state of the application from a [genesis file](./genesis.md) (i.e. token balances of genesis accounts). It is called when the application receives the `InitChain` message from the Tendermint engine, which happens when the node is started at `appBlockHeight == 0` (i.e. on genesis). The application must set the `InitChainer` in its constructor via the [`SetInitChainer`](https://godoc.org/github.com/cosmos/cosmos-sdk/baseapp#BaseApp.SetInitChainer) method. In general, the `InitChainer` is mostly composed of the `InitGenesis` function of each of the application's modules. This is done by calling the `InitGenesis` function of the module manager, which in turn will call the `InitGenesis` function of each of the modules it contains. Note that the order in which the modules' `InitGenesis` functions must be called has to be set in the module manager using the `SetOrderInitGenesis` method. This is done in the [application's constructor](#application-constructor), and the `SetOrderInitGenesis` has to be called before the `SetInitChainer`. @@ -119,40 +116,39 @@ The SDK offers developers the possibility to implement automatic execution of co In general, the `BeginBlocker` and `EndBlocker` functions are mostly composed of the `BeginBlock` and `EndBlock` functions of each of the application's modules. This is done by calling the `BeginBlock` and `EndBlock` functions of the module manager, which in turn will call the `BeginBLock` and `EndBlock` functions of each of the modules it contains. Note that the order in which the modules' `BegingBlock` and `EndBlock` functions must be called has to be set in the module manager using the `SetOrderBeginBlock` and `SetOrderEndBlock` methods respectively. This is done in the [application's constructor](#application-constructor), and the `SetOrderBeginBlock` and `SetOrderEndBlock` methods have to be called before the `SetBeginBlocker` and `SetEndBlocker` functions. -As a sidenote, it is important to remember that application-specific blockchains are deterministic. Developers must be careful not to introduce non-determinism in `BeginBlocker` or `EndBlocker`, and must also be careful not to make them too computationally expensive, as [gas](./accounts-fees-gas.md/gas) does not constrain the cost of `BeginBlocker` and `EndBlocker` execution. +As a sidenote, it is important to remember that application-specific blockchains are deterministic. Developers must be careful not to introduce non-determinism in `BeginBlocker` or `EndBlocker`, and must also be careful not to make them too computationally expensive, as gas does not constrain the cost of `BeginBlocker` and `EndBlocker` execution. You can see an example of `BeginBlocker` and `EndBlocker` functions [here](https://github.com/cosmos/gaia/blob/master/app/app.go#L224-L232). ### Register Codec -The `MakeCodec` function is the last important function of the `app.go` file. The goal of this function is to instantiate a codec `cdc` (e.g. [amino](./amino.md)) initiliaze the codec of the SDK and each of the application's modules using the `RegisterCodec` function. +The `MakeCodec` function is the last important function of the `app.go` file. The goal of this function is to instantiate a codec `cdc` (e.g. amino) initialize the codec of the SDK and each of the application's modules using the `RegisterCodec` function. -To register the application's modules, the `MakeCodec` function calls `RegisterCodec` on `ModuleBasics`. `ModuleBasics` is a [basic manager](../building-modules/module-manager.md#basicmanager) which lists all of the application's modules. It is instanciated in the `init()` function, and only serves to easily register non-dependant elements of application's modules (such as codec). To learn more about the basic module manager, click [here](../building-modules/module-manager.md#basicmanager). +To register the application's modules, the `MakeCodec` function calls `RegisterCodec` on `ModuleBasics`. `ModuleBasics` is a basic manager which lists all of the application's modules. It is instantiated in the `init()` function, and only serves to easily register non-dependent elements of application's modules (such as codec). To learn more about the basic module manager,. You can see an example of a `MakeCodec` [here](https://github.com/cosmos/gaia/blob/master/app/app.go#L64-L70) ## Modules -Modules are the heart and soul of an SDK application. They can be considered as state-machines within the state-machine. When a transaction is relayed from the underlying Tendermint engine via the ABCI to the application, it is routed by [`baseapp`](../core/baseapp.md) to the appropriate module in order to be processed. This paradigm enables developers to easily build complex state-machines, as most of the modules they need often already exist. For developers, most of the work involved in building an SDK application revolves around building custom modules required by their application that do not exist, and integrating them with modules that do already exist into one coherent application. In the application directory, the standard practice is to store modules in the `x/` folder (not to be confused with the SDK's `x/` folder, which contains already-built modules). - -To learn more about modules, [click here](./modules.md) +Modules are the heart and soul of an SDK application. They can be considered as state-machines within the state-machine. When a transaction is relayed from the underlying Tendermint engine via the ABCI to the application, it is routed by `baseapp` to the appropriate module in order to be processed. This paradigm enables developers to easily build complex state-machines, as most of the modules they need often already exist. For developers, most of the work involved in building an SDK application revolves around building custom modules required by their application that do not exist, and integrating them with modules that do already exist into one coherent application. In the application directory, the standard practice is to store modules in the `x/` folder (not to be confused with the SDK's `x/` folder, which contains already-built modules). ### Application Module Interface -Modules implement two interfaces defined in the Cosmos SDK, [`AppModuleBasic`](../building-modules/module-manager.md#appmodulebasic) and [`AppModule`](../building-modules/module-manager.md#appmodule). The former implements basic non-dependant elements of the module, such as the `codec`, while the latter handles the bulk of the module methods (including methods that require references to other modules' `keeper`s). Both the `AppModule` and `AppModuleBasic` types are defined in a file called `./module.go`. +Modules implement two interfaces defined in the Cosmos SDK, [`AppModuleBasic`](https://github.com/cosmos/cosmos-sdk/blob/master/types/module/module.go#L44-L57) and [`AppModule`](https://github.com/cosmos/cosmos-sdk/blob/master/types/module/module.go#L44-L57). The former implements basic non-dependant elements of the module, such as the `codec`, while the latter handles the bulk of the module methods (including methods that require references to other modules' `keeper`s). Both the `AppModule` and `AppModuleBasic` types are defined in a file called `./module.go`. -`AppModule` exposes a collection of useful methods on the module that facilitates the composition of modules into a coherent application. These methods are are called from the `module manager`(../building-modules/module-manager.md#manager), which manages the application's collection of modules. +`AppModule` exposes a collection of useful methods on the module that facilitates the composition of modules into a coherent application. Important methods include: -To learn more about the application module interface, [click here](./modules.md#application-module-interface). -======= -To learn more about the application module interface, [click here](../building-modules/module-manager.md#application-module-interfaces). ->>>>>>> workinnn +- `Route()` and `QueryRoute()`: These methods the name of the route and querier route for the module, for [messages](#message-types) to be routed to the module's [`handler`](#handler) and queries to be routes to the module's [`querier`](#querier). +- `NewHandler()` and `NewQuerierHandler()`: These methods return a `handler` and `querierHandler` respectively, in order to process a message or a query once they are routed. +- `BeginBlock()`, `EndBlock()` and `InitGenesis()`: These methods are executed respectively at the beginning of each block, at the end of each block and at the start of the chain. They implement special logic the module requires to be triggered during those events. For example, the `EndBlock` function is frequently used by modules where voting occurs to tally the result of the votes. +- `RegisterInvariants()`: This method registers the [invariants](./invariants.md) for the module. Invariants are checked at the end of every block to make sure no unpredicted behaviour is occuring. +- `AppModule`'s methods are called from the `module manager`, which manages the application's collection of modules. ### Message Types -A message is a custom type defined by each module that implements the [`message`](../building-modules/messages-and-queries.md#messages) interface. Each [`transaction`](../core/transaction.md) contains one or multiple `messages`. When a valid block of transactions is received by the full-node, Tendermint relays each one to the application via [`DeliverTx`](https://tendermint.com/docs/app-dev/abci-spec.html#delivertx). Then, the application handles the transaction: +A message is a custom type defined by each module that implements the [`message`](https://github.com/cosmos/cosmos-sdk/blob/master/types/tx_msg.go#L8-L29) interface. Each `transaction` contains one or multiple `messages`. When a valid block of transactions is received by the full-node, Tendermint relays each one to the application via [`DeliverTx`](https://tendermint.com/docs/app-dev/abci-spec.html#delivertx). Then, the application handles the transaction: -1. Upon receiving the transaction, the application first unmarshalls it from `[]bytes`. +1. Upon receiving the transaction, the application first unmarshals it from `[]bytes`. 2. Then, it verifies a few things about the transaction like [fee payment and signatures](#accounts-fees-gas.md) before extracting the message(s) contained in the transaction. 3. With the [`Type()`](https://github.com/cosmos/cosmos-sdk/blob/master/types/tx_msg.go#L16) method, `baseapp` is able to know which modules defines the message. It is then able to route it to the appropriate module's [handler](#handler) in order for the message to be processed. 4. If the message is successfully processed, the state is updated. @@ -161,24 +157,20 @@ For a more detailed look at a transaction lifecycle, click [here](./tx-lifecycle Module developers create custom message types when they build their own module. The general practice is to prefix the type declaration of the message with `Msg`. For example, the message type [`MsgSend`](https://github.com/cosmos/cosmos-sdk/blob/master/x/bank/types/msgs.go#L10-L15) allows users to transfer tokens. It is processed by the handler of the `bank` module, which ultimately calls the `keeper` of the `auth` module in order to update the state. -To learn more about messages, [click here](../building-modules/messages-and-queries.md#messages). - ### Handler -The [`handler`](../building-modules/handler.md) refers to the part of the module responsible for processing the message after it is routed by `baseapp`. `handler` functions of modules (except those of the `auth` module) are only executed if the transaction is relayed from Tendermint by the `DeliverTx` ABCI message. If the transaction is relayed by `CheckTx`, only stateless checks and fee-related (i.e. `auth` module-related) stateful checks are performed. To better understand the difference between `DeliverTx`and `CheckTx`, as well as the difference between stateful and stateless checks, click [here](./tx-lifecycle.md). +The `handler` refers to the part of the module responsible for processing the message after it is routed by `baseapp`. `handler` functions of modules (except those of the `auth` module) are only executed if the transaction is relayed from Tendermint by the `DeliverTx` ABCI message. If the transaction is relayed by `CheckTx`, only stateless checks and fee-related (i.e. `auth` module-related) stateful checks are performed. To better understand the difference between `DeliverTx`and `CheckTx`, as well as the difference between stateful and stateless checks, click [here](./tx-lifecycle.md). The handler of a module is generally defined in a file called `handler.go` and consists of: -- A **switch function** `NewHandler` to route the message to the appropriate handler function. This function returns a `handler` function, and is registered in the [`AppModule`](#application-module-interface) to be used in the application's module manager to initialize the [application's router](../core/baseapp.md#routing). See an example of such a switch [here](https://github.com/cosmos/sdk-application-tutorial/blob/master/x/nameservice/handler.go#L10-L22). +- A **switch function** `NewHandler` to route the message to the appropriate handler function. This function returns a `handler` function, and is registered in the [`AppModule`](#application-module-interface) to be used in the application's module manager to initialize the application's router. See an example of such a switch [here](https://github.com/cosmos/sdk-application-tutorial/blob/master/x/nameservice/handler.go#L10-L22). - **One handler function for each message type defined by the module**. Developers write the message processing logic in these functions. This generally involves doing stateful checks to ensure the message is valid and calling [`keeper`](#keeper)'s methods to update the state. Handler functions return a result of type [`sdk.Result`](https://github.com/cosmos/cosmos-sdk/blob/master/types/result.go#L14-L37), which informs the application on whether the message was successfully processed. -To learn more about handlers, [click here](../building-modules/handler.md). - ### Keeper -[`Keepers`](../building-module/keeper.md) are the gatekeepers of their module's store(s). To read or write in a module's store, it is mandatory to go through one of its `keeper`'s methods. This is ensured by the [object-capabilities](../core/ocap.md) model of the Cosmos SDK. Only objects that hold the key to a store can access it, and only the module's `keeper` should hold the key(s) to the module's store(s). +`Keepers` are the gatekeepers of their module's store(s). To read or write in a module's store, it is mandatory to go through one of its `keeper`'s methods. This is ensured by the [object-capabilities](./ocap.md) model of the Cosmos SDK. Only objects that hold the key to a store can access it, and only the module's `keeper` should hold the key(s) to the module's store(s). `Keepers` are generally defined in a file called `keeper.go`. It contains the `keeper`'s type definition and methods. @@ -192,18 +184,14 @@ Along with the type definition, the next important component of the `keeper.go` The rest of the file defines the `keeper`'s methods, primarily getters and setters. You can check an example of a `keeper` implementation [here](https://github.com/cosmos/sdk-application-tutorial/blob/master/x/nameservice/keeper.go). -To learn more about `keepers`, [click here](../building-modules/keeper.md). - ### Querier -[`Queriers`](../building-modules/querier.md) are very similar to `handlers`, except they serve user queries to the state as opposed to processing transactions. A [query](../building-modules/messages-and-queries.md#queries) is initiated from an [interface](#interfaces) by an end-user who provides a `queryRoute` and some `data`. The query is then routed to the correct application's `querier` by `baseapp`'s [`handleQueryCustom`](https://github.com/cosmos/cosmos-sdk/blob/master/baseapp/baseapp.go#L519-L556) method using `queryRoute`. +`Queriers` are very similar to `handlers`, except they serve user queries to the state as opposed to processing transactions. A query is initiated from an [interface](#intefaces) by an end-user who provides a `queryRoute` and some `data`. The query is then routed to the correct application's `querier` by `baseapp`'s [`handleQueryCustom`](https://github.com/cosmos/cosmos-sdk/blob/master/baseapp/baseapp.go#L519-L556) method using `queryRoute`. The `Querier` of a module is defined in a file called `querier.go`, and consists of: -- A **switch function** `NewQuerier` to route the query to the appropriate `querier` function. This function returns a `querier` function, and is is registered in the [`AppModule`](#application-module-interface) to be used in the application's module manager to initialize the [application's query router](../core/baseapp.md#query-routing). See an example of such a switch [here](https://github.com/cosmos/sdk-application-tutorial/blob/master/x/nameservice/querier.go#L21-L34). -- - **One querier function for each data type defined by the module that needs to be queryable**. Developers write the query processing logic in these functions. This generally involves calling [`keeper`](#keeper)'s methods to query the state and marshalling it to JSON. See an example of `querier` functions [here](https://github.com/cosmos/sdk-application-tutorial/blob/master/x/nameservice/querier.go#L37-L101). - -To learn more about `queriers`, [click here](../building-modules/querier.md). +- A **switch function** `NewQuerier` to route the query to the appropriate `querier` function. This function returns a `querier` function, and is is registered in the [`AppModule`](#application-module-interface) to be used in the application's module manager to initialize the application's query router. See an example of such a switch [here](https://github.com/cosmos/sdk-application-tutorial/blob/master/x/nameservice/querier.go#L21-L34). +- - **One querier function for each data type defined by the module that needs to be queryable**. Developers write the query processing logic in these functions. This generally involves calling [`keeper`](#keeper)'s methods to query the state and marshaling it to JSON. See an example of `querier` functions [here](https://github.com/cosmos/sdk-application-tutorial/blob/master/x/nameservice/querier.go#L37-L101). ### Command-Line and REST Interfaces @@ -216,11 +204,9 @@ Generally, the commands related to a module are defined in a folder called `clie - Transactions commands let users generate new transactions so that they can be included in a block and eventually update the state. One command should be created for each [message type](#message-types) defined in the module. The command calls the constructor of the message with the parameters provided by the end-user, and wraps it into a transaction. The SDK handles signing and the addition of other transaction metadata. See examples of transactions commands [here](https://github.com/cosmos/sdk-application-tutorial/blob/master/x/nameservice/client/cli/tx.go). - Queries let users query the subset of the state defined by the module. Query commands forward queries to the [application's query router](./baseapp.md#query-routing), which routes them to the appropriate [querier](#querier) the `queryRoute` parameter supplied. See examples of query commands [here](https://github.com/cosmos/sdk-application-tutorial/blob/master/x/nameservice/client/cli/query.go). -To learn more about modules CLI, [click here](../building-modules/module-interfaces.md#cli). - #### REST -The module's REST interface lets users generate transactions and query the state through REST calls to the application's [light client daemon](../core/node.md#lcd) (LCD). REST routes are defined in a file `client/rest/rest.go`, which is composed of: +The module's REST interface lets users generate transactions and query the state through REST calls to the application's light client daemon (LCD). REST routes are defined in a file `client/rest/rest.go`, which is composed of: - A `RegisterRoutes` function, which registers each route defined in the file. This function is called from the [main application's interface](#application-interfaces) for each module used within the application. The router used in the SDK is [Gorilla's mux](https://github.com/gorilla/mux). - Custom request type definitions for each query or transaction creation function that needs to be exposed. These custom request types build on the [base `request` type](https://github.com/cosmos/cosmos-sdk/blob/master/types/rest/rest.go#L32-L43) of the Cosmos SDK. @@ -228,23 +214,19 @@ The module's REST interface lets users generate transactions and query the state See an example of a module's `rest.go` file [here](https://github.com/cosmos/sdk-application-tutorial/blob/master/x/nameservice/client/rest/rest.go). -To learn more about modules REST interface, [click here](../building-modules/module-interfaces.md#rest). - ## Application Interface Interfaces let end-users interact with full-node clients. This means querying data from the full-node or creating and sending new transactions to be relayed by the full-node and eventually included in a block. -The main interface is the [Command-Line Interface](../interfaces/cli.md). The CLI of an SDK application is built by aggregating [CLI commands](#cli) defined in each of the modules used by the application. The CLI of an application generally has the `-cli` suffix (e.g. `appcli`), and defined in a file called `cmd/appcli/main.go`. The file contains: +The main interface is the Command-Line Interface. The CLI of an SDK application is built by aggregating [CLI commands](#cli) defined in each of the modules used by the application. The CLI of an application generally has the `-cli` suffix (e.g. `appcli`), and defined in a file called `cmd/appcli/main.go`. The file contains: - **A `main()` function**, which is executed to build the `appcli` interface client. This function prepares each command and adds them to the `rootCmd` before building them. At the root of `appCli`, the function adds generic commands like `status`, `keys` and `config`, query commands, tx commands and `rest-server`. - **Query commands** are added by calling the `queryCmd` function, also defined in `appcli/main.go`. This function returns a Cobra command that contains the query commands defined in each of the application's modules (passed as an array of `sdk.ModuleClients` from the `main()` function), as well as some other lower level query commands such as block or validator queries. Query command are called by using the command `appcli query [query]` of the CLI. -- **Transaction commands** are added by calling the `txCmd` function. Similar to `queryCmd`, the function returns a Cobra command that contains the tx commands defined in each of the application's modules, as well as lower level tx commands like transaction signing or broadcasting. Tx commands are called by using the command `appcli tx [tx]` of the CLI. -- **A `registerRoutes` function**, which is called from the `main()` function when initializing the [application's light-client daemon (LCD)](../core/node.md#lcd) (i.e. `rest-server`). `registerRoutes` calls the `RegisterRoutes` function of each of the application's module, thereby registering the routes of the module to the lcd's router. The LCD can be started by running the following command `appcli rest-server`. +- **Transaction commands** are added by calling the `txCmd` function. Similar to `queryCmd`, the function returns a Cobra command that contains the tx commands defined in each of the application's modules, as well as lower level tx commands like transaction signing or broadcasting. Tx commands are called by using the command `appcli tx [tx]` of the CLI. +- **A `registerRoutes` function**, which is called from the `main()` function when initializing the [application's light-client daemon (LCD)](./node.md#lcd) (i.e. `rest-server`). `registerRoutes` calls the `RegisterRoutes` function of each of the application's module, thereby registering the routes of the module to the lcd's router. The LCD can be started by running the following command `appcli rest-server`. See an example of an application's main command-line file [here](https://github.com/cosmos/sdk-application-tutorial/blob/master/cmd/nscli/main.go). -To learn more about interfaces, [click here](../interfaces/intro.md). - ## Dependencies and Makefile This section is optional, as developers are free to choose their depencency manager and project building method. That said, the current most used framework for versioning control is [`go.mod`](https://github.com/golang/go/wiki/Modules). It ensures each of the libraries used throughout the application are imported with the correct version. An example can be found [here](https://github.com/cosmos/sdk-application-tutorial/blob/master/go.mod). diff --git a/docs/building-modules/intro.md b/docs/building-modules/intro.md index d3e8440992d5..403eb755a2a2 100644 --- a/docs/building-modules/intro.md +++ b/docs/building-modules/intro.md @@ -7,7 +7,7 @@ ## Synopsis -Modules define most of the logic of any SDK application. Developers compose module together to build their custom application-specific blockchains. This document outlines the basic concepts behind SDK modules and how to approach module management. +Modules define most of the logic of any SDK application. Developers compose module together to build their custom application-specific blockchains. This document outlines the basic concepts behind SDK modules and how to approach module management. - [Role of Modules in an SDK application](#role-of-modules-in-an-sdk-application) - [How to Approach Building Modules as a Developer](#how-to-approach-building-modules-as-a-developer) @@ -18,14 +18,14 @@ Modules define most of the logic of any SDK application. Developers compose modu The Cosmos SDK can be thought as the Ruby-on-Rails of blockchain development. It comes with a core that provides the basic functionalities every blockchain application need, like a boilerplate implementation of the ABCI to communicate with the underlying consensus engine, a multistore to persist state, a server to form a full-node and interfaces to handle queries. -On top of this core, the SDK enables developers to build modules that implement the business logic of their application. In other words, SDK modules implement the bulk of the logic of applications, while the core does the wiring and enables modules to be composed together. The end goal is to build a robust ecosystem of open-source SDK modules, making it increasingly easier to build complex blockchain applications. +On top of this core, the SDK enables developers to build modules that implement the business logic of their application. In other words, SDK modules implement the bulk of the logic of applications, while the core does the wiring and enables modules to be composed together. The end goal is to build a robust ecosystem of open-source SDK modules, making it increasingly easier to build complex blockchain applications. -SDK Modules can be seen as little state-machines within the state-machine. They generally define a subset of the state using one ore multiple `KVStore` in the [main multistore](../core/store.md), as well as a subset of [`message` types](./message.md). These `message`s are routed by one of the main component of SDK core, [`baseapp`](../core/baseapp.md), to the [`handler`](./handler.md) of the module that define them. +SDK Modules can be seen as little state-machines within the state-machine. They generally define a subset of the state using one ore multiple `KVStore` in the [main multistore](../core/store.md), as well as a subset of [`message` types](./message.md). These `message`s are routed by one of the main component of SDK core, [`baseapp`](../core/baseapp.md), to the [`handler`](./handler.md) of the module that define them. ``` + | - | Transaction relayed from the full-node's consensus engine + | Transaction relayed from the full-node's consensus engine | to the node's application via DeliverTx | | @@ -67,28 +67,29 @@ SDK Modules can be seen as little state-machines within the state-machine. They v ``` -As a result of this architecture, building an SDK application usually revolves around writing modules to implement the specialized logic of the application, and composing them with existing modules to complete the application. Developers will generally work on modules that implement logic needed for their specific use case that do not exist yet, and will use existing modules for more generic functionalities like staking, accounts or token management. +As a result of this architecture, building an SDK application usually revolves around writing modules to implement the specialized logic of the application, and composing them with existing modules to complete the application. Developers will generally work on modules that implement logic needed for their specific use case that do not exist yet, and will use existing modules for more generic functionalities like staking, accounts or token management. ## How to Approach Building Modules as a Developer While there is no definitive guidelines for writing modules, here are some important design principles developers should keep in mind when building them: -- **Composability**: SDK applications are almost always composed of multiple modules. This means developers need to carefully consider the integration of their module not only with the core of the Cosmos SDK, but also with other modules. The former is achieved by following standard design patterns outlined [here](#main-components-of-sdk-modules), while the latter is achieved by properly exposing the store(s) of the module via the [`keeper`](./keeper.md). -- **Specialization**: A direct consequence of the **composability** feature is that modules should be **specialized**. Developers should carefully establish the scope of their module and not batch multiple functionalities into the same module. This separation of concern enables modules to be re-used in other projects and improves the upgradability of the application. **Specialization** also plays an important role in the [object-capabilities model](../core/ocap.md) of the Cosmos SDK. -- **Capabilities**: Most modules need to read and/or write to the store(s) of other modules. However, in an open-source environment, it is possible for some module to be malicious. That is why module developers need to carefully think not only about how their module interracts with other modules, and how to give access to the module's store(s). The Cosmos SDK takes a capabilities-oriented approach to inter-module security. This means that each store defined by a module is accessed by a `key`, which is held by the module's [`keeper`](./keeper.md). This `keeper` defines how to access the store(s) and under what conditions. Access to the module's store(s) is done by passing a reference to the module's `keeper`. +- **Composability**: SDK applications are almost always composed of multiple modules. This means developers need to carefully consider the integration of their module not only with the core of the Cosmos SDK, but also with other modules. The former is achieved by following standard design patterns outlined [here](#main-components-of-sdk-modules), while the latter is achieved by properly exposing the store(s) of the module via the [`keeper`](./keeper.md). +- **Specialization**: A direct consequence of the **composability** feature is that modules should be **specialized**. Developers should carefully establish the scope of their module and not batch multiple functionalities into the same module. This separation of concern enables modules to be re-used in other projects and improves the upgradability of the application. **Specialization** also plays an important role in the [object-capabilities model](../core/ocap.md) of the Cosmos SDK. +- **Capabilities**: Most modules need to read and/or write to the store(s) of other modules. However, in an open-source environment, it is possible for some module to be malicious. That is why module developers need to carefully think not only about how their module interracts with other modules, and how to give access to the module's store(s). The Cosmos SDK takes a capabilities-oriented approach to inter-module security. This means that each store defined by a module is accessed by a `key`, which is held by the module's [`keeper`](./keeper.md). This `keeper` defines how to access the store(s) and under what conditions. Access to the module's store(s) is done by passing a reference to the module's `keeper`. ## Main Components of SDK Module -Modules generally share the same core components: +Modules are by convention defined in the `.x/` subfolder (e.g. the `bank` module will be defined in the `./x/bank` folder). They generally share the same core components: -- Custom [`message` types](./message.md) to trigger state-transitions. -- A [`handler`](./handler.md) used to process messages when they are routed to the module by [`baseapp`](../core/baseapp.md#message-routing). -- A [`keeper`](./keeper.md), used to access the module's store(s) and update the state. +- Custom [`message` types](./message.md) to trigger state-transitions. +- A [`handler`](./handler.md) used to process messages when they are routed to the module by [`baseapp`](../core/baseapp.md#message-routing). +- A [`keeper`](./keeper.md), used to access the module's store(s) and update the state. - A [`querier`](./querier.md), used to process user queries when they are routed to the module by [`baseapp`](../core/baseapp.md#query-routing). - Interfaces, for end users to query the subset of the state defined by the module and create `message`s of the custom types defined in the module. -In addition to these components, modules implement the `module` interface in order to be managed by the [`module manager`](./module-manager.md). +In addition to these components, modules implement the `AppModule` interface in order to be managed by the [`module manager`](./module-manager.md). ## Next -Read more on the [`module interface` and the `module manager`](./module-manager.md) +Read more on the [`AppModule` interface and the `module manager`](./module-manager.md) + diff --git a/docs/core/baseapp.md b/docs/core/baseapp.md index 44c46f26f489..6c3d2dd9e506 100644 --- a/docs/core/baseapp.md +++ b/docs/core/baseapp.md @@ -7,7 +7,7 @@ ## Synopsis -This document describes `baseapp`, the abstraction that implements most of the common functionalities of an SDK application. +This document describes `baseapp`, the abstraction that implements most of the common functionalities of an SDK application. - [Introduction](#introduction) - [Type Definition](#type-definition) @@ -17,7 +17,7 @@ This document describes `baseapp`, the abstraction that implements most of the c - [Main ABCI Messages](#abci) + [CheckTx](#checktx) + [DeliverTx](#delivertx) -- [RunTx, AnteHandler and RunMsgs](#runtx-,antehandler-and-runmsgs) +- [RunTx, AnteHandler and RunMsgs](#runtx-antehandler-and-runmsgs) + [RunTx](#runtx) + [AnteHandler](#antehandler) + [RunMsgs](#runmsgs) @@ -28,18 +28,18 @@ This document describes `baseapp`, the abstraction that implements most of the c + [Commit](#commit) + [Info](#info) + [Query](#query) - + ## Introduction `baseapp` is an abstraction that implements the core of an SDK application, namely: -- The [Application-Blockchain Interface](#abci), for the state-machine to communicate with the underlying consensus engine (e.g. Tendermint). +- The [Application-Blockchain Interface](#abci), for the state-machine to communicate with the underlying consensus engine (e.g. Tendermint). - A [Router](#routing), to route [messages](./tx-msgs.md) and [queries](./querier.md) to the appropriate [module](../building-modules/intro.md). -- Different [states](#states), as the state-machine can have different parallel states updated based on the ABCI message received. +- Different [states](#states), as the state-machine can have different parallel states updated based on the ABCI message received. The goal of `baseapp` is to provide a boilerplate SDK application that developers can easily extend to build their own custom application. Usually, developers will create a custom type for their application, like so: -```go +```go type app struct { *bam.BaseApp // reference to baseapp cdc *codec.Codec @@ -52,24 +52,24 @@ type app struct { } ``` -Extending the application with `baseapp` gives the former access to all of `baseapp`'s methods. This allows developers to compose their custom application with the modules they want, while not having to concern themselves with the hard work of implementing the ABCI, the routing and state management logic. +Extending the application with `baseapp` gives the former access to all of `baseapp`'s methods. This allows developers to compose their custom application with the modules they want, while not having to concern themselves with the hard work of implementing the ABCI, the routing and state management logic. ## Type Definition The [`baseapp` type](https://github.com/cosmos/cosmos-sdk/blob/master/baseapp/baseapp.go#L45-L91) holds many important parameters for any Cosmos SDK based application. Let us go through the most important components. -*Note: Not all parameters are described, only the most important ones. Refer to the [type definition](https://github.com/cosmos/cosmos-sdk/blob/master/baseapp/baseapp.go#L45-L91) for the full list* +*Note: Not all parameters are described, only the most important ones. Refer to the [type definition](https://github.com/cosmos/cosmos-sdk/blob/master/baseapp/baseapp.go#L45-L91) for the full list* First, the important parameters that are initialized during the initialization of the application: -- A [`CommitMultiStore`](./store.md#commit-multi-store). This is the main store of the application, which holds the canonical state that is committed at the [end of each block](#commit). This store is **not** cached, meaning it is not used to update the application's intermediate (un-committed) states. The `CommitMultiStore` is a multi-store, meaning a store of stores. Each module of the application uses one or multiple `KVStores` in the multi-store to persist their subset of the state. +- A [`CommitMultiStore`](./store.md#commit-multi-store). This is the main store of the application, which holds the canonical state that is committed at the [end of each block](#commit). This store is **not** cached, meaning it is not used to update the application's intermediate (un-committed) states. The `CommitMultiStore` is a multi-store, meaning a store of stores. Each module of the application uses one or multiple `KVStores` in the multi-store to persist their subset of the state. - A [database](./store.md#database) `db`, which is used by the `CommitMultiStore` to handle data storage. - A [router](#message-routing). The `router` facilitates the routing of [messages](../building-modules/messages-and-queries.md#messages) to the appropriate module for it to be processed. - A [query router](#query-routing). The `query router` facilitates the routing of [queries](../building-modules/messages-and-queries.md#queries) to the appropriate module for it to be processed. - A [`txDecoder`](https://godoc.org/github.com/cosmos/cosmos-sdk/types#TxDecoder), used to decode transaction `[]byte` relayed by the underlying Tendermint engine. - A [`baseKey`], to access the [main store](./store.md#main-store) in the `CommitMultiStore`. The main store is used to persist data related to the core of the application, like consensus parameters. - A [`anteHandler`](#antehandler), to handle signature verification and fee paiement when a transaction is received. -- An [`initChainer`](../basics/app-anatomy.md#initchainer), [`beginBlocker` and `endBlocker`](../basics/app-anatomy.md#beginblocker-and-endblocker), which are the functions executed when the application received the [InitChain], [BeginBlock] and [EndBlock] messages from the underlying Tendermint engine. +- An [`initChainer`](../basics/app-anatomy.md#initchainer), [`beginBlocker` and `endBlocker`](../basics/app-anatomy.md#beginblocker-and-endblocker), which are the functions executed when the application received the [InitChain], [BeginBlock] and [EndBlock] messages from the underlying Tendermint engine. Then, parameters used to define [volatile states](#volatile-states) (i.e. cached states): @@ -84,13 +84,13 @@ Finally, a few more important parameterd: ## Constructor -`NewBaseApp(name string, logger log.Logger, db dbm.DB, txDecoder sdk.TxDecoder, options ...func(*BaseApp),)` is the constructor function for `baseapp`. It is called from the [application's constructor function](../basics/app-anatomy.md#constructor-function) each time the full-node is started. +`NewBaseApp(name string, logger log.Logger, db dbm.DB, txDecoder sdk.TxDecoder, options ...func(*BaseApp),)` is the constructor function for `baseapp`. It is called from the [application's constructor function](../basics/app-anatomy.md#constructor-function) each time the full-node is started. -`baseapp`'s constructor function is pretty straightforward. The only thing worth noting is the possibility to add additional [`options`](https://github.com/cosmos/cosmos-sdk/blob/master/baseapp/options.go) to `baseapp` by passing `options functions` to the constructor function, which will execute them in order. `options` are generally `setters` function for important parameters, like `SetPruning()` to active pruning or `SetMinGasPrices()` to set the node's `min-gas-prices`. +`baseapp`'s constructor function is pretty straightforward. The only thing worth noting is the possibility to add additional [`options`](https://github.com/cosmos/cosmos-sdk/blob/master/baseapp/options.go) to `baseapp` by passing `options functions` to the constructor function, which will execute them in order. `options` are generally `setters` function for important parameters, like `SetPruning()` to active pruning or `SetMinGasPrices()` to set the node's `min-gas-prices`. -A list of `options` example can be found [here](https://github.com/cosmos/cosmos-sdk/blob/master/baseapp/options.go). Naturally, developers can add additional `options` based on their application's needs. +A list of `options` example can be found [here](https://github.com/cosmos/cosmos-sdk/blob/master/baseapp/options.go). Naturally, developers can add additional `options` based on their application's needs. -## States +## States `baseapp` handles various parallel states for different purposes. There is the [main state](#main-state), which is the canonical state of the application, and volatile states like [`checkState`](#checkState) and [`deliverState`](#deliverstate), which are used to handle temporary states inbetween updates of the main state. @@ -120,54 +120,7 @@ DeliverTx(tx1) | | | +----------------------+ +----------------------+ | | | | | DeliverState(t)(1) | | | | | +----------------------+ | | -DeliverTx(tx2) | | | | | - | | v | | - | | +----------------------+ | | - | | | DeliverState(t)(2) | | | - | | +----------------------+ | | -DeliverTx(tx3) | | | | | - | | v | | - | | +----------------------+ | | - | | | DeliverState(t)(3) | | | - +----------------------+ +----------------------+ +----------------------+ -Commit() | | | - v v v - +----------------------+ +----------------------+ +----------------------+ - | CheckState(t+1)(0) | | DeliverState(t+1)(0) | | QueryState(t+1) | - +----------------------+ | | | | - . . . - . . . - . . . - -``` - -``` - To perform stateful checks To execute state To serve queries - on received transactions transitions during DeliverTx on last-committed state - +----------------------+ +----------------------+ +----------------------+ - | CheckState(t)(0) | | DeliverState(t)(0) | | QueryState(t) | - +----------------------+ | | | | -CheckTx(tx1) | | | | | - v | | | | - +----------------------+ | | | | - | CheckState(t)(1) | | | | | - +----------------------+ | | | | -CheckTx(tx2) | | | | | - v | | | | - +----------------------+ | | | | - | CheckState(t)(2) | | | | | - +----------------------+ | | | | -CheckTx(tx3) | | | | | - v | | | | - +----------------------+ | | | | - | CheckState(t)(3) | | | | | - +----------------------+ +----------------------+ | | -DeliverTx(tx1) | | | | - v v | | - +----------------------+ +----------------------+ | | - | | | DeliverState(t)(1) | | | - | | +----------------------+ | | -DeliverTx(tx2) | | | | | +DeliverTx(tx2) | | | | | | | v | | | | +----------------------+ | | | | | DeliverState(t)(2) | | | @@ -185,12 +138,12 @@ Commit() | | . . . . . . . . . - + ``` ### Main State -The main state is the canonical state of the application. It is initialized on [`InitChain`](#initchain and updated on [`Commit`](#abci-commit) at the end of each block. +The main state is the canonical state of the application. It is initialized on [`InitChain`](#initchain and updated on [`Commit`](#abci-commit) at the end of each block. ``` +--------+ +--------+ @@ -206,13 +159,13 @@ The main state is held by `baseapp` in a structure called the [`CommitMultiStore Volatile - or cached - states are used in between [`Commit`s](#commit) to manage temporary states. They are reset to the latest version of the main state after it is committed. There are two main volatile states: -- `checkState`: This cached state is initialized during [`InitChain`](#initchain), updated during [`CheckTx`](#abci-checktx) when an unconfirmed transaction is received, and reset to the [main state](#main-state) on [`Commit`](#abci-commit). +- `checkState`: This cached state is initialized during [`InitChain`](#initchain), updated during [`CheckTx`](#abci-checktx) when an unconfirmed transaction is received, and reset to the [main state](#main-state) on [`Commit`](#abci-commit). - `deliverState`: This cached state is initialized during [`BeginBlock`](#beginblock), updated during [`DeliverTx`](#abci-delivertx) when a transaction included in a block is processed, and reset to the [main state](#main-state) on [`Commit`](#abci-commit). Both `checkState` and `deliverState` are of type [`state`](https://github.com/cosmos/cosmos-sdk/blob/master/baseapp/baseapp.go#L973-L976), which includes: -- A [`CacheMultiStore`](https://github.com/cosmos/cosmos-sdk/blob/master/store/cachemulti/store.go), which is a cached version of the main `CommitMultiStore`. A new version of this store is committed at the end of each successful `CheckTx`/`DeliverTx` execution. -- A [`Context`](./context.md), which carries general information (like raw transaction size, block height, ...) that might be needed in order to process the transaction during `CheckTx` and `DeliverTx`. The `context` also holds a cache-wrapped version of the `CacheMultiStore`, so that the `CacheMultiStore` can maintain the correct version even if an internal step of `CheckTx` or `DeliverTx` fails. +- A [`CacheMultiStore`](https://github.com/cosmos/cosmos-sdk/blob/master/store/cachemulti/store.go), which is a cached version of the main `CommitMultiStore`. A new version of this store is committed at the end of each successful `CheckTx`/`DeliverTx` execution. +- A [`Context`](./context.md), which carries general information (like raw transaction size, block height, ...) that might be needed in order to process the transaction during `CheckTx` and `DeliverTx`. The `context` also holds a cache-wrapped version of the `CacheMultiStore`, so that the `CacheMultiStore` can maintain the correct version even if an internal step of `CheckTx` or `DeliverTx` fails. ## Routing @@ -222,24 +175,24 @@ When messages and queries are received by the application, they must be routed t [`Message`s](#../building-modules/messages-and-queries.md#messages) need to be routed after they are extracted from transactions, which are sent from the underlying Tendermint engine via the [`CheckTx`](#checktx) and [`DeliverTx`](#delivertx) ABCI messages. To do so, `baseapp` holds a [`router`](https://github.com/cosmos/cosmos-sdk/blob/master/baseapp/router.go) which maps `paths` (`string`) to the appropriate module [`handler`](./handler.md). Usually, the `path` is the name of the module. -The application's `router` is initilalized with all the routes using the application's [module manager](../building-modules/module-manager.md), which itself is initialized with all the application's modules in the application's [constructor](../basics/app-anatomy.md#app-constructor). +The application's `router` is initilalized with all the routes using the application's [module manager](../building-modules/module-manager.md), which itself is initialized with all the application's modules in the application's [constructor](../basics/app-anatomy.md#app-constructor). ### Query Routing -Similar to `message`s, [`queries`](../building-modules/messages-and-queries.md#queries) need to be routed to the appropriate module's [querier](../building-modules/querier.md). To do so, `baseapp` holds a [`query router`](https://github.com/cosmos/cosmos-sdk/blob/master/baseapp/queryrouter.go), which maps `paths` (`string`) to the appropriate module `querier`. Usually, the `path` is the name of the module. +Similar to `message`s, [`queries`](../building-modules/messages-and-queries.md#queries) need to be routed to the appropriate module's [querier](../building-modules/querier.md). To do so, `baseapp` holds a [`query router`](https://github.com/cosmos/cosmos-sdk/blob/master/baseapp/queryrouter.go), which maps `paths` (`string`) to the appropriate module `querier`. Usually, the `path` is the name of the module. Just like the `router`, the `query router` is initilalized with all the query routes using the application's [module manager](../building-modules/module-manager.md), which itself is initialized with all the application's modules in the application's [constructor](../basics/app-anatomy.md#app-constructor). ## Main ABCI Messages -The [Application-Blockchain Interface](https://tendermint.com/docs/spec/abci/) (ABCI) is a generic interface that connects a state-machine with a consensus engine to form a functional full-node. It can be wrapped in any language, and needs to be implemented by each application-specific blockchain built on top of an ABCI-compatible consensus engine like Tendermint. +The [Application-Blockchain Interface](https://tendermint.com/docs/spec/abci/) (ABCI) is a generic interface that connects a state-machine with a consensus engine to form a functional full-node. It can be wrapped in any language, and needs to be implemented by each application-specific blockchain built on top of an ABCI-compatible consensus engine like Tendermint. The consensus engine handles two main tasks: - The networking logic, which mainly consists in gossiping block parts, transactions and consensus votes. -- The consensus logic, which results in the deterministic ordering of transactions in the form of blocks. +- The consensus logic, which results in the deterministic ordering of transactions in the form of blocks. -It is **not** the role of the consensus engine to define the state or the validity of transactions. Generally, transactions are handled by the consensus engine in the form of `[]bytes`, and relayed to the application via the ABCI to be decoded and processed. At keys moments in the networking and consensus processes (e.g. beginning of a block, commit of a block, reception of an unconfirmed transaction, ...), the consensus engine emits ABCI messages for the state-machine to act on. +It is **not** the role of the consensus engine to define the state or the validity of transactions. Generally, transactions are handled by the consensus engine in the form of `[]bytes`, and relayed to the application via the ABCI to be decoded and processed. At keys moments in the networking and consensus processes (e.g. beginning of a block, commit of a block, reception of an unconfirmed transaction, ...), the consensus engine emits ABCI messages for the state-machine to act on. Developers building on top of the Cosmos SDK need not implement the ABCI themselves, as `baseapp` comes with a built-in implementation of the interface. Let us go through the main ABCI messages that `baseapp` implements: [`CheckTx`](#checktx) and [`DeliverTx`](#delivertx) @@ -251,43 +204,43 @@ Developers building on top of the Cosmos SDK need not implement the ABCI themsel 1. Extract the `message`s from the transaction. 2. Perform *stateless* checks by calling `ValidateBasic()` on each of the `messages`. This is done first, as *stateless* checks are less computationally expensive than *stateful* checks. If `ValidateBasic()` fail, `CheckTx` returns before running *stateful* checks, which saves resources. -3. Perform non-module related *stateful* checks on the account. This step is mainly about checking that the `message` signatures are valid, that enough fees are provided and that the sending account has enough funds to pay for said fees. Note that no precise [`gas`](./accounts-fees-gas.md#gas) counting occurs here, as `message`s are not processed. Usually, the [`anteHandler`](./accounts-fees-gas.md#antehandler) will check that the `gas` provided with the transaction is superior to a minimum reference gas amount based on the raw transaction size, in order to avoid spam with transactions that provide 0 gas. -4. Ensure that a [`Route`](#message-routing) exists for each `message`, but do **not** actually process `message`s. `Message`s only need to be processed when the canonical state need to be updated, which happens during `DeliverTx`. +3. Perform non-module related *stateful* checks on the account. This step is mainly about checking that the `message` signatures are valid, that enough fees are provided and that the sending account has enough funds to pay for said fees. Note that no precise [`gas`](./accounts-fees-gas.md#gas) counting occurs here, as `message`s are not processed. Usually, the [`anteHandler`](./accounts-fees-gas.md#antehandler) will check that the `gas` provided with the transaction is superior to a minimum reference gas amount based on the raw transaction size, in order to avoid spam with transactions that provide 0 gas. +4. Ensure that a [`Route`](#message-routing) exists for each `message`, but do **not** actually process `message`s. `Message`s only need to be processed when the canonical state need to be updated, which happens during `DeliverTx`. -Steps 2. and 3. are performed by the [`anteHandler`](./accounts-fees-gas.md#antehandler) in the [`RunTx`](#runtx-,antehandler-and-runmsgs) function, which `CheckTx` calls with the `runTxModeCheck` mode. During each step of `CheckTx`, a special [volatile state](#volatile-states) called `checkState` is updated. This state is used to keep track of the temporary changes triggered by the `CheckTx` calls of each transaction without modifying the [main canonical state](#main-state) . For example, when a transaction goes through `CheckTx`, the transaction's fees are deducted from the sender's account in `checkState`. If a second transaction is received from the same account before the first is processed, and the account has consumed all its funds in `checkState` during the first transaction, the second transaction will fail `CheckTx` and be rejected. In any case, the sender's account will not actually pay the fees until the transaction is actually included in a block, because `checkState` never gets committed to the main state. `checkState` is reset to the latest state of the main state each time a blocks gets [committed](#commit). +Steps 2. and 3. are performed by the [`anteHandler`](./accounts-fees-gas.md#antehandler) in the [`RunTx`](#runtx-antehandler-and-runmsgs) function, which `CheckTx` calls with the `runTxModeCheck` mode. During each step of `CheckTx`, a special [volatile state](#volatile-states) called `checkState` is updated. This state is used to keep track of the temporary changes triggered by the `CheckTx` calls of each transaction without modifying the [main canonical state](#main-state) . For example, when a transaction goes through `CheckTx`, the transaction's fees are deducted from the sender's account in `checkState`. If a second transaction is received from the same account before the first is processed, and the account has consumed all its funds in `checkState` during the first transaction, the second transaction will fail `CheckTx` and be rejected. In any case, the sender's account will not actually pay the fees until the transaction is actually included in a block, because `checkState` never gets committed to the main state. `checkState` is reset to the latest state of the main state each time a blocks gets [committed](#commit). `CheckTx` returns a response to the underlying consensus engine of type [`abci.ResponseCheckTx`](https://tendermint.com/docs/spec/abci/abci.html#messages). The response contains: -- `Code (uint32)`: Response Code. `0` if successful. +- `Code (uint32)`: Response Code. `0` if successful. - `Data ([]byte)`: Result bytes, if any. - `Log (string):` The output of the application's logger. May be non-deterministic. - `Info (string):` Additional information. May be non-deterministic. -- `GasWanted (int64)`: Amount of gas requested for transaction. It is provided by users when they generate the transaction. -- `GasUsed (int64)`: Amount of gas consumed by transaction. During `CheckTx`, this value is computed by multiplying the standard cost of a transaction byte by the size of the raw transaction (click [here](https://github.com/cosmos/cosmos-sdk/blob/master/x/auth/ante.go#L101) for an example). +- `GasWanted (int64)`: Amount of gas requested for transaction. It is provided by users when they generate the transaction. +- `GasUsed (int64)`: Amount of gas consumed by transaction. During `CheckTx`, this value is computed by multiplying the standard cost of a transaction byte by the size of the raw transaction (click [here](https://github.com/cosmos/cosmos-sdk/blob/master/x/auth/ante.go#L101) for an example). - `Tags ([]cmn.KVPair)`: Key-Value tags for filtering and indexing transactions (eg. by account). - `Codespace (string)`: Namespace for the Code. ### DeliverTx -When the underlying consensus engine receives a block proposal, each transaction in the block needs to be processed by the application. To that end, the underlying consensus engine sends a `DeliverTx` message to the application for each transaction in a sequential order. +When the underlying consensus engine receives a block proposal, each transaction in the block needs to be processed by the application. To that end, the underlying consensus engine sends a `DeliverTx` message to the application for each transaction in a sequential order. -Before the first transaction of a given block is processed, a [volatile state](#volatile-states) called `deliverState` is intialized during [`BeginBlock`](#beginblock). This state is updated each time a transaction is processed via `DeliverTx`, and committed to the [main state](#main-state) when the block is [committed](#commit), after what is is set to `nil`. +Before the first transaction of a given block is processed, a [volatile state](#volatile-states) called `deliverState` is intialized during [`BeginBlock`](#beginblock). This state is updated each time a transaction is processed via `DeliverTx`, and committed to the [main state](#main-state) when the block is [committed](#commit), after what is is set to `nil`. `DeliverTx` performs the **exact same steps as `CheckTx`**, with a little caveat at step 3 and the addition of a fifth step: -3. The `anteHandler` does **not** check that the transaction's `gas-prices` is sufficient. That is because the `min-gas-prices` value `gas-prices` is checked against is local to the node, and therefore what is enough for one full-node might not be for another. This means that the proposer can potentially include transactions for free, although they are not incentivised to do so, as they earn a bonus on the total fee of the block they propose. -5. For each `message` in the transaction, route to the appropriate module's [`handler`](../building-modules/handler.md). Additional *stateful* checks are performed, and the cache-wrapped multistore held in `deliverState`'s `context` is updated by the module's `keeper`. If the `handler` returns successfully, the cache-wrapped multistore held in `context` is written to `deliverState` `CacheMultiStore`. +3. The `anteHandler` does **not** check that the transaction's `gas-prices` is sufficient. That is because the `min-gas-prices` value `gas-prices` is checked against is local to the node, and therefore what is enough for one full-node might not be for another. This means that the proposer can potentially include transactions for free, although they are not incentivised to do so, as they earn a bonus on the total fee of the block they propose. +5. For each `message` in the transaction, route to the appropriate module's [`handler`](../building-modules/handler.md). Additional *stateful* checks are performed, and the cache-wrapped multistore held in `deliverState`'s `context` is updated by the module's `keeper`. If the `handler` returns successfully, the cache-wrapped multistore held in `context` is written to `deliverState` `CacheMultiStore`. -During step 5., each read/write to the store increases the value of `GasConsumed`. You can find the default cost of each operation [here](https://github.com/cosmos/cosmos-sdk/blob/master/store/types/gas.go#L142-L150). At any point, if `GasConsumed > GasWanted`, the function returns with `Code != 0` and `DeliverTx` fails. +During step 5., each read/write to the store increases the value of `GasConsumed`. You can find the default cost of each operation [here](https://github.com/cosmos/cosmos-sdk/blob/master/store/types/gas.go#L142-L150). At any point, if `GasConsumed > GasWanted`, the function returns with `Code != 0` and `DeliverTx` fails. `DeliverTx` returns a response to the underlying consensus engine of type [`abci.ResponseCheckTx`](https://tendermint.com/docs/spec/abci/abci.html#messages). The response contains: -- `Code (uint32)`: Response Code. `0` if successful. +- `Code (uint32)`: Response Code. `0` if successful. - `Data ([]byte)`: Result bytes, if any. - `Log (string):` The output of the application's logger. May be non-deterministic. - `Info (string):` Additional information. May be non-deterministic. -- `GasWanted (int64)`: Amount of gas requested for transaction. It is provided by users when they generate the transaction. -- `GasUsed (int64)`: Amount of gas consumed by transaction. During `DeliverTx`, this value is computed by multiplying the standard cost of a transaction byte by the size of the raw transaction (click [here](https://github.com/cosmos/cosmos-sdk/blob/master/x/auth/ante.go#L101) for an example), and by adding gas each time a read/write to the store occurs. +- `GasWanted (int64)`: Amount of gas requested for transaction. It is provided by users when they generate the transaction. +- `GasUsed (int64)`: Amount of gas consumed by transaction. During `DeliverTx`, this value is computed by multiplying the standard cost of a transaction byte by the size of the raw transaction (click [here](https://github.com/cosmos/cosmos-sdk/blob/master/x/auth/ante.go#L101) for an example), and by adding gas each time a read/write to the store occurs. - `Tags ([]cmn.KVPair)`: Key-Value tags for filtering and indexing transactions (eg. by account). - `Codespace (string)`: Namespace for the Code. @@ -295,13 +248,13 @@ During step 5., each read/write to the store increases the value of `GasConsumed ### RunTx -`RunTx` is called from `CheckTx`/`DeliverTx` to handle the transaction, with `runTxModeCheck` or `runTxModeDeliver` as parameter to differentiate between the two modes of execution. Note that when `RunTx` receives a transaction, it has already been decoded. +`RunTx` is called from `CheckTx`/`DeliverTx` to handle the transaction, with `runTxModeCheck` or `runTxModeDeliver` as parameter to differentiate between the two modes of execution. Note that when `RunTx` receives a transaction, it has already been decoded. The first thing `RunTx` does upon being called is to retrieve the `context`'s `CacheMultiStore` by calling the `getContextForTx()` function with the appropriate mode (either `runTxModeCheck` or `runTxModeDeliver`). This `CacheMultiStore` is a cached version of the main store instantiated during `BeginBlock` for `DeliverTx` and during the `Commit` of the previous block for `CheckTx`. After that, two `defer func()` are called for [`gas`](./accounts-fees-gas.md#gas) management. They are executed when `runTx` returns and make sure `gas` is actually consumed, and will throw errors, if any. -After that, `RunTx` calls `ValidateBasic()` on each `message`in the `Tx`, which runs prelimary *stateless* validity checks. If any `message` fails to pass `ValidateBasic()`, `RunTx` returns with an error. +After that, `RunTx` calls `ValidateBasic()` on each `message`in the `Tx`, which runs prelimary *stateless* validity checks. If any `message` fails to pass `ValidateBasic()`, `RunTx` returns with an error. -Then, the [`anteHandler`](#antehandler) of the application is run (if it exists). In preparation of this step, both the `checkState`/`deliverState`'s `context` and `context`'s `CacheMultiStore` are cached-wrapped using the [`cacheTxContext()`](https://github.com/cosmos/cosmos-sdk/blob/master/baseapp/baseapp.go#L781-L798) function. This allows `RunTx` not to commit the changes made to the state during the execution of `anteHandler` if it ends up failing. It also prevents the module implementing the `anteHandler` from writing to state, which is an important part of the [object-capabilities](./ocap.md) of the Cosmos SDK. +Then, the [`anteHandler`](#antehandler) of the application is run (if it exists). In preparation of this step, both the `checkState`/`deliverState`'s `context` and `context`'s `CacheMultiStore` are cached-wrapped using the [`cacheTxContext()`](https://github.com/cosmos/cosmos-sdk/blob/master/baseapp/baseapp.go#L781-L798) function. This allows `RunTx` not to commit the changes made to the state during the execution of `anteHandler` if it ends up failing. It also prevents the module implementing the `anteHandler` from writing to state, which is an important part of the [object-capabilities](./ocap.md) of the Cosmos SDK. Finally, the [`RunMsgs`](#runmsgs) function is called to process the `messages`s in the `Tx`. In preparation of this step, just like with the `anteHandler`, both the `checkState`/`deliverState`'s `context` and `context`'s `CacheMultiStore` are cached-wrapped using the `cacheTxContext()` function. @@ -311,17 +264,17 @@ The `AnteHandler` is a special handler that implements the [`anteHandler` interf The `AnteHandler` is theoretically optional, but still a very important component of public blockchain networks. It serves 3 primary purposes: -- Be a primary line of defense against spam and second line of defense (the first one being the mempool) against transaction replay with fees deduction and [`sequence`](./tx-msgs.md#sequence) checking. -- Perform preliminary *stateful* validity checks like ensuring signatures are valid or that the sender has enough funds to pay for fees. -- Play a role in the incentivisation of stakeholders via the collection of transaction fees. +- Be a primary line of defense against spam and second line of defense (the first one being the mempool) against transaction replay with fees deduction and [`sequence`](./tx-msgs.md#sequence) checking. +- Perform preliminary *stateful* validity checks like ensuring signatures are valid or that the sender has enough funds to pay for fees. +- Play a role in the incentivisation of stakeholders via the collection of transaction fees. `baseapp` holds an `anteHandler` as paraemter, which is initialized in the [application's constructor](../basics/app-anatomy.md#application-constructor). The most widely used `anteHandler` today is that of the [`auth` module](https://github.com/cosmos/cosmos-sdk/blob/master/x/auth/ante.go). ### RunMsgs -`RunMsgs` is called from `RunTx` with `runTxModeCheck` as parameter to check the existence of a route for each message the transaction, and with `runTxModeDeliver` to actually process the `message`s. +`RunMsgs` is called from `RunTx` with `runTxModeCheck` as parameter to check the existence of a route for each message the transaction, and with `runTxModeDeliver` to actually process the `message`s. -First, it retreives the `message`'s `route` using the `Msg.Route()` method. Then, using the application's [`router`](#routing) and the `route`, it checks for the existence of a `handler`. At this point, if `mode == runTxModeCheck`, `RunMsgs` returns. If instead `mode == runTxModeDeliver`, the [`handler`](../building-modules/handler.md) function for the message is executed, before `RunMsgs` returns. +First, it retreives the `message`'s `route` using the `Msg.Route()` method. Then, using the application's [`router`](#routing) and the `route`, it checks for the existence of a `handler`. At this point, if `mode == runTxModeCheck`, `RunMsgs` returns. If instead `mode == runTxModeDeliver`, the [`handler`](../building-modules/handler.md) function for the message is executed, before `RunMsgs` returns. ## Other ABCI Messages @@ -329,9 +282,9 @@ First, it retreives the `message`'s `route` using the `Msg.Route()` method. Then The [`InitChain` ABCI message](https://tendermint.com/docs/app-dev/abci-spec.html#initchain) is sent from the underlying Tendermint engine when the chain is first started. It is mainly used to **initialize** parameters and state like: -- [Consensus Parameters](https://tendermint.com/docs/spec/abci/apps.html#consensus-parameters) via `setConsensusParams`. +- [Consensus Parameters](https://tendermint.com/docs/spec/abci/apps.html#consensus-parameters) via `setConsensusParams`. - [`checkState` and `deliverState`](#volatile-states) via `setCheckState` and `setDeliverState`. -- The [block gas meter](../basics/accounts-fees-gas.md#block-gas-meter), with infinite gas to process genesis transactions. +- The [block gas meter](../basics/accounts-fees-gas.md#block-gas-meter), with infinite gas to process genesis transactions. Finally, the `InitChain(req abci.RequestInitChain)` method of `baseapp` calls the [`initChainer()`](../basics/app-anatomy.md#initchainer) of the application in order to initialize the main state of the application from the [`genesis file`](./genesis.md) and, if defined, call the `InitGenesis` function of each of the application's modules. @@ -339,37 +292,37 @@ Finally, the `InitChain(req abci.RequestInitChain)` method of `baseapp` calls th The [`BeginBlock` ABCI message](#https://tendermint.com/docs/app-dev/abci-spec.html#beginblock) is sent from the underlying Tendermint engine when a block proposal created by the correct proposer is received, before [`DeliverTx`](#delivertx) is run for each transaction in the block. It allows developers to have logic be executed at the beginning of each block. In the Cosmos SDK, the `BeginBlock(req abci.RequestBeginBlock)` method does the following: -- Initialize [`deliverState`](#volatile-states) with the latest header using the `req abci.RequestBeginBlock` passed as parameter via the [`setDeliverState`](https://github.com/cosmos/cosmos-sdk/blob/master/baseapp/baseapp.go#L283-L289) function. -- Initialize the [block gas meter](../basics/accounts-fees-gas.md#block-gas-meter) with the `maxGas` limit. The `gas` consumed within the block cannot go above `maxGas`. This parameter is defined in the application's consensus parameters. +- Initialize [`deliverState`](#volatile-states) with the latest header using the `req abci.RequestBeginBlock` passed as parameter via the [`setDeliverState`](https://github.com/cosmos/cosmos-sdk/blob/master/baseapp/baseapp.go#L283-L289) function. +- Initialize the [block gas meter](../basics/accounts-fees-gas.md#block-gas-meter) with the `maxGas` limit. The `gas` consumed within the block cannot go above `maxGas`. This parameter is defined in the application's consensus parameters. - Run the application's [`begingBlocker()`](../basics/app-anatomy.md#beginblocker-and-endblock), which mainly runs the `BeginBlocker()` method of each of the application's modules. - Set the [`VoteInfos`](https://tendermint.com/docs/app-dev/abci-spec.html#voteinfo) of the application, i.e. the list of validators whose *precommit* for the previous block was included by the proposer of the current block. This information is carried into the [`Context`](./context.md) so that it can be used during `DeliverTx` and `EndBlock`. ### EndBlock -The [`EndBlock` ABCI message](#https://tendermint.com/docs/app-dev/abci-spec.html#endblock) is sent from the underlying Tendermint engine after [`DeliverTx`](#delivertx) as been run for each transactioni n the block. It allows developers to have logic be executed at the end of each block. In the Cosmos SDK, the bulk `EndBlock(req abci.RequestEndBlock)` method is to run the application's [`endBlocker()`](../basics/app-anatomy.md#beginblocker-and-endblock), which mainly runs the `EndBlocker()` method of each of the application's modules. +The [`EndBlock` ABCI message](#https://tendermint.com/docs/app-dev/abci-spec.html#endblock) is sent from the underlying Tendermint engine after [`DeliverTx`](#delivertx) as been run for each transactioni n the block. It allows developers to have logic be executed at the end of each block. In the Cosmos SDK, the bulk `EndBlock(req abci.RequestEndBlock)` method is to run the application's [`endBlocker()`](../basics/app-anatomy.md#beginblocker-and-endblock), which mainly runs the `EndBlocker()` method of each of the application's modules. ### Commit -The [`Commit` ABCI message](https://tendermint.com/docs/app-dev/abci-spec.html#commit) is sent from the underlying Tendermint engine after the full-node has received *precommits* from 2/3+ of validators (weighted by voting power). On the `baseapp` end, the `Commit(res abci.ResponseCommit)` function is implemented to commit all the valid state transitions that occured during `BeginBlock`, `DeliverTx` and `EndBlock` and to reset state for the next block. +The [`Commit` ABCI message](https://tendermint.com/docs/app-dev/abci-spec.html#commit) is sent from the underlying Tendermint engine after the full-node has received *precommits* from 2/3+ of validators (weighted by voting power). On the `baseapp` end, the `Commit(res abci.ResponseCommit)` function is implemented to commit all the valid state transitions that occured during `BeginBlock`, `DeliverTx` and `EndBlock` and to reset state for the next block. To commit state-transitions, the `Commit` function calls the `Write()` function on `deliverState.ms`, where `deliverState.ms` is a cached multistore of the main store `app.cms`. Then, the `Commit` function sets `checkState` to the latest header (obtbained from `deliverState.ctx.BlockHeader`) and `deliverState` to `nil`. -Finally, `Commit` returns the hash of the commitment of `app.cms` back to the underlying consensus engine. This hash is used as a reference in the header of the next block. +Finally, `Commit` returns the hash of the commitment of `app.cms` back to the underlying consensus engine. This hash is used as a reference in the header of the next block. ### Info -The [`Info` ABCI message](https://tendermint.com/docs/app-dev/abci-spec.html#info) is a simple query from the underlying consensus engine, notably used to sync the latter with the application during a handshake that happens on startup. When called, the `Info(res abci.ResponseInfo)` function from `baseapp` will return the application's name, version and the hash of the last commit of `app.cms`. +The [`Info` ABCI message](https://tendermint.com/docs/app-dev/abci-spec.html#info) is a simple query from the underlying consensus engine, notably used to sync the latter with the application during a handshake that happens on startup. When called, the `Info(res abci.ResponseInfo)` function from `baseapp` will return the application's name, version and the hash of the last commit of `app.cms`. -### Query +### Query -The [`Query` ABCI message](https://tendermint.com/docs/app-dev/abci-spec.html#query) is used to serve queries received from the underlying consensus engine, including queries received via RPC like Tendermint RPC. It is the main entrypoint to build interfaces with the application. The application must respect a few rules when implementing the `Query` method, which are outlined [here](https://tendermint.com/docs/app-dev/abci-spec.html#query). +The [`Query` ABCI message](https://tendermint.com/docs/app-dev/abci-spec.html#query) is used to serve queries received from the underlying consensus engine, including queries received via RPC like Tendermint RPC. It is the main entrypoint to build interfaces with the application. The application must respect a few rules when implementing the `Query` method, which are outlined [here](https://tendermint.com/docs/app-dev/abci-spec.html#query). The `baseapp` implementation of the `Query(req abci.RequestQuery)` method is a simple dispatcher serving 4 main categories of queries: - Application-related queries like querying the application's version, which are served via the `handleQueryApp` method. -- Direct queries to the multistore, which are served by the `handlerQueryStore` method. These direct queryeis are different from custom queries which go through `app.queryRouter`, and are mainly used by third-party service provider like block explorers. +- Direct queries to the multistore, which are served by the `handlerQueryStore` method. These direct queryeis are different from custom queries which go through `app.queryRouter`, and are mainly used by third-party service provider like block explorers. - P2P queries, which are served via the `handleQueryP2P` method. These queries return either `app.addrPeerFilter` or `app.ipPeerFilter` that contain the list of peers filtered by address or IP respectively. These lists are first initialized via `options` in `baseapp`'s [constructor](#constructor). -- Custom queries, which encompass most queries, are served via the `handleQueryCustom` method. The `handleQueryCustom` cache-wraps the multistore before using the `queryRoute` obtained from [`app.queryRouter`](#query-routing) to map the query to the appropriate module's [`querier`](../building-modules/querier.md). +- Custom queries, which encompass most queries, are served via the `handleQueryCustom` method. The `handleQueryCustom` cache-wraps the multistore before using the `queryRoute` obtained from [`app.queryRouter`](#query-routing) to map the query to the appropriate module's [`querier`](../building-modules/querier.md). ## Next diff --git a/docs/core/node.md b/docs/core/node.md index 36fe12602d0d..85c6152542ad 100644 --- a/docs/core/node.md +++ b/docs/core/node.md @@ -2,7 +2,7 @@ ## Pre-Requisite Reading -## main function +## `main` function TODO diff --git a/docs/intro/README.md b/docs/intro/README.md index e676fd179b16..9df4e13e443c 100644 --- a/docs/intro/README.md +++ b/docs/intro/README.md @@ -2,15 +2,15 @@ ## What is the SDK? -The [Cosmos-SDK](https://github.com/cosmos/cosmos-sdk) is an open-source framework for building multi-asset public Proof-of-Stake (PoS) blockchains, like the Cosmos Hub, as well as permissionned Proof-Of-Authority (PoA) blockchains. Blockchains built with the Cosmos SDK are generally referred to as **application-specific blockchains**. +The [Cosmos-SDK](https://github.com/cosmos/cosmos-sdk) is an open-source framework for building multi-asset public Proof-of-Stake (PoS) blockchains, like the Cosmos Hub, as well as permissioned Proof-Of-Authority (PoA) blockchains. Blockchains built with the Cosmos SDK are generally referred to as **application-specific blockchains**. -The goal of the Cosmos SDK is to allow developers to easily create custom blockchains from scratch that can natively interoperate with other blockchains. We envision the SDK as the npm-like framework to build secure blockchain applications on top of [Tendermint](https://github.com/tendermint/tendermint). SDK-based blockchains are built out of composable modules, most of which are open source and readily available for any developers to use. Anyone can create a module for the Cosmos-SDK, and integrating already-built modules is as simple as importing them into your blockchain application. What's more, the Cosmos SDK is a capabilities-based system, which allows developer to better reason about the security of interactions between modules. For a deeper look at capabilities, jump to [this section](./ocap.md). +The goal of the Cosmos SDK is to allow developers to easily create custom blockchains from scratch that can natively interoperate with other blockchains. We envision the SDK as the npm-like framework to build secure blockchain applications on top of [Tendermint](https://github.com/tendermint/tendermint). SDK-based blockchains are built out of composable modules, most of which are open source and readily available for any developers to use. Anyone can create a module for the Cosmos-SDK, and integrating already-built modules is as simple as importing them into your blockchain application. What's more, the Cosmos SDK is a capabilities-based system, which allows developers to better reason about the security of interactions between modules. For a deeper look at capabilities, jump to [this section](./ocap.md). ## What are Application-Specific Blockchains? One development paradigm in the blockchain world today is that of virtual-machine blockchains like Ethereum, where development generally revolves around building a decentralised applications on top of an existing blockchain as a set of smart contracts. While smart contracts can be very good for some use cases like single-use applications (e.g. ICOs), they often fall short for building complex decentralised platforms. More generally, smart contracts can be limiting in terms of flexibility, sovereignty and performance. -Application-specific blockchains offer a radically different development paradigm than virtual-machine blockchains. An application-specific blockchain is a blockchain customized to operate a single application: developers have all the freedom to make the design decisions required for the application to run optimally. They can also provide better sovereignty, security and performance. +Application-specific blockchains offer a radically different development paradigm than virtual-machine blockchains. An application-specific blockchain is a blockchain customized to operate a single application: developers have all the freedom to make the design decisions required for the application to run optimally. They can also provide better sovereignty, security and performance. To learn more about application-specific blockchains, [click here](./why-app-specific.md). @@ -18,12 +18,13 @@ To learn more about application-specific blockchains, [click here](./why-app-spe The Cosmos SDK is the most advanced framework for building custom application-specific blockchains today. Here are a few reasons why you might want to consider building your decentralised application with the Cosmos SDK: -- The default consensus engine available within the SDK is [Tendermint Core](https://github.com/tendermint/tendermint). Tendermint is the most (and only) mature BFT consensus engine in existence. It is widely used accross the industry and is considered the gold standard consensus engine for building Proof-of-Stake systems. -- The SDK is open source and designed to make it easy to build blockchains out of composable modules. As the ecosystem of open source SDK modules grow, it will become increasingly easier to build complex decentralised platforms with it. -- The SDK is inspired by capabilities-based security, and informed by years of wrestling with blockchain state-machines. This makes the Cosmos SDK a very secure environment to build blockchains. -- Most importantly, the Cosmos SDK has already been used to build many application-specific blockchains that are already in production. Among others, we can cite [Cosmos Hub](https://hub.cosmos.network), [Iris](https://irisnet.org), [Binance Chain](https://docs.binance.org/), [Terra](https://terra.money/) or [Lino](https://lino.network/). Many more are building on the Cosmos SDK. You can get a view of the ecosystem [here](https://cosmos.network/ecosystem). +- The default consensus engine available within the SDK is [Tendermint Core](https://github.com/tendermint/tendermint). Tendermint is the most (and only) mature BFT consensus engine in existence. It is widely used across the industry and is considered the gold standard consensus engine for building Proof-of-Stake systems. +- The SDK is open source and designed to make it easy to build blockchains out of composable modules. As the ecosystem of open source SDK modules grow, it will become increasingly easier to build complex decentralised platforms with it. +- The SDK is inspired by capabilities-based security, and informed by years of wrestling with blockchain state-machines. This makes the Cosmos SDK a very secure environment to build blockchains. +- Most importantly, the Cosmos SDK has already been used to build many application-specific blockchains that are already in production. Among others, we can cite [Cosmos Hub](https://hub.cosmos.network), [IRIS Hub](https://irisnet.org), [Binance Chain](https://docs.binance.org/), [Terra](https://terra.money/) or [Lino](https://lino.network/). Many more are building on the Cosmos SDK. You can get a view of the ecosystem [here](https://cosmos.network/ecosystem). ## Getting started with the Cosmos SDK - Learn more about the [architecture of an SDK application](./sdk-app-architecture.md) - Learn how to build an application-specific blockchain from scratch with the [SDK Tutorial](https://cosmos.network/docs/tutorial) + diff --git a/docs/intro/sdk-app-architecture.md b/docs/intro/sdk-app-architecture.md index a420fe627c33..94007a2742dc 100644 --- a/docs/intro/sdk-app-architecture.md +++ b/docs/intro/sdk-app-architecture.md @@ -1,12 +1,12 @@ # SDK Application Architecture -## State machine +## State machine -At its core, a blockchain is a [replicated deterministic state machine](https://en.wikipedia.org/wiki/State_machine_replication). +At its core, a blockchain is a [replicated deterministic state machine](https://en.wikipedia.org/wiki/State_machine_replication). -A state machine is a computer science concept whereby a machine can have multiple states, but only one at any given time. There is a `state`, which describes the current state of the system, and `transactions`, that trigger state transitions. +A state machine is a computer science concept whereby a machine can have multiple states, but only one at any given time. There is a `state`, which describes the current state of the system, and `transactions`, that trigger state transitions. -Given a state S and a transaction T, the state machine will return a new state S'. +Given a state S and a transaction T, the state machine will return a new state S'. ``` +--------+ +--------+ @@ -26,9 +26,9 @@ In practice, the transactions are bundled in blocks to make the process more eff +--------+ +--------+ ``` -In a blockchain context, the state machine is deterministic. This means that if you start at a given state and replay the same sequence of transactions, you will always end up with the same final state. +In a blockchain context, the state machine is deterministic. This means that if you start at a given state and replay the same sequence of transactions, you will always end up with the same final state. -The Cosmos SDK gives you maximum flexibility to define the state of your application, transaction types and state transition functions. The process of building the state-machine with the SDK will be described more in depth in the following sections. But first, let us see how it is replicated using **Tendermint**. +The Cosmos SDK gives you maximum flexibility to define the state of your application, transaction types and state transition functions. The process of building the state-machine with the SDK will be described more in depth in the following sections. But first, let us see how it is replicated using **Tendermint**. ### Tendermint @@ -54,14 +54,14 @@ Blockchain node | | Consensus | | Tendermint is an application-agnostic engine that is responsible for handling the *networking* and *consensus* layers of your blockchain. In practice, this means that Tendermint is responsible for propagating and ordering transaction bytes. Tendermint Core relies on an eponymous Byzantine-Fault-Tolerant (BFT) algorithm to reach consensus on the order of transactions. For more on Tendermint, click [here](https://tendermint.com/docs/introduction/what-is-tendermint.html). -Tendermint consensus algorithm works with a set of special nodes called *Validators*. Validators are responsible for adding blocks of transactions to the blockchain. At any given block, there is a validator set V. A validator in V is chosen by the algorithm to be the proposer of the next block. This block is considered valid if more than two thirds of V signed a *[prevote](https://tendermint.com/docs/spec/consensus/consensus.html#prevote-step-height-h-round-r)* and a *[precommit](https://tendermint.com/docs/spec/consensus/consensus.html#precommit-step-height-h-round-r)* on it, and if all the transactions that it contains are valid. The validator set can be changed by rules written in the state-machine. For a deeper look at the algorithm, click [here](https://tendermint.com/docs/introduction/what-is-tendermint.html#consensus-overview). +The Tendermint consensus algorithm works with a set of special nodes called *Validators*. Validators are responsible for adding blocks of transactions to the blockchain. At any given block, there is a validator set V. A validator in V is chosen by the algorithm to be the proposer of the next block. This block is considered valid if more than two thirds of V signed a *[prevote](https://tendermint.com/docs/spec/consensus/consensus.html#prevote-step-height-h-round-r)* and a *[precommit](https://tendermint.com/docs/spec/consensus/consensus.html#precommit-step-height-h-round-r)* on it, and if all the transactions that it contains are valid. The validator set can be changed by rules written in the state-machine. For a deeper look at the algorithm, click [here](https://tendermint.com/docs/introduction/what-is-tendermint.html#consensus-overview). -The main part of a Cosmos SDK application is a blockchain daemon that is run by each node in the network locally. If less than one third of the *validator set* is byzantine (i.e. malicious), then each node should obtain the same result when querying the state at the same time. +The main part of a Cosmos SDK application is a blockchain daemon that is run by each node in the network locally. If less than one third of the *validator set* is byzantine (i.e. malicious), then each node should obtain the same result when querying the state at the same time. ## ABCI -Tendermint passes transactions from the network to the application through an interface called the [ABCI](https://github.com/tendermint/tendermint/tree/master/abci), which the application must implement. +Tendermint passes transactions from the network to the application through an interface called the [ABCI](https://github.com/tendermint/tendermint/tree/master/abci), which the application must implement. ``` +---------------------+ @@ -81,16 +81,16 @@ Tendermint passes transactions from the network to the application through an in +---------------------+ ``` -Note that **Tendermint only handles transaction bytes**. It has no knowledge of what these bytes mean. All Tendermint does is order these transaction bytes deterministically. Tendermint passes the bytes to the application via the ABCI, and expects a return code to inform it if the messages contained in the transactions were successfully processed or not. +Note that **Tendermint only handles transaction bytes**. It has no knowledge of what these bytes mean. All Tendermint does is order these transaction bytes deterministically. Tendermint passes the bytes to the application via the ABCI, and expects a return code to inform it if the messages contained in the transactions were successfully processed or not. Here are the most important messages of the ABCI: -- `CheckTx`: When a transaction is received by Tendermint Core, it is passed to the application to check if a few basic requirements are met. `CheckTx` is used to protect the mempool of full-nodes against spam. A special handler called the "Ante Handler" is used to execute a series of validation steps such as checking for sufficient fees and validating the signatures. If the check is valid, the transaction is added to the [mempool](https://tendermint.com/docs/spec/reactors/mempool/functionality.html#mempool-functionality) and relayed to peer nodes. Note that transactions are not processed (i.e. no modification of the state occurs) with `CheckTx` since they have not been included in a block yet. +- `CheckTx`: When a transaction is received by Tendermint Core, it is passed to the application to check if a few basic requirements are met. `CheckTx` is used to protect the mempool of full-nodes against spam. A special handler called the "Ante Handler" is used to execute a series of validation steps such as checking for sufficient fees and validating the signatures. If the check is valid, the transaction is added to the [mempool](https://tendermint.com/docs/spec/reactors/mempool/functionality.html#mempool-functionality) and relayed to peer nodes. Note that transactions are not processed (i.e. no modification of the state occurs) with `CheckTx` since they have not been included in a block yet. - `DeliverTx`: When a [valid block](https://tendermint.com/docs/spec/blockchain/blockchain.html#validation) is received by Tendermint Core, each transaction in the given block is passed to the application via `DeliverTx` to be processed. It is during this stage that the state transitions occur. The "Ante Handler" executes again along with the actual handlers for each message in the transaction. - - `BeginBlock`/`EndBlock`: These messages are executed at the beginning and the end of each block, whether the block contains transaction or not. It is useful to trigger automatic execution of logic. Proceed with caution though, as computationally expensive loops could slow down your blockchain, or even freeze it if the loop is infinite. + - `BeginBlock`/`EndBlock`: These messages are executed at the beginning and the end of each block, whether the block contains transaction or not. It is useful to trigger automatic execution of logic. Proceed with caution though, as computationally expensive loops could slow down your blockchain, or even freeze it if the loop is infinite. For a more detailed view of the ABCI methods and types, click [here](https://tendermint.com/docs/spec/abci/abci.html#overview). Any application built on Tendermint needs to implement the ABCI interface in order to communicate with the underlying local Tendermint engine. Fortunately, you do not have to implement the ABCI interface. The Cosmos SDK provides a boilerplate implementation of it in the form of [baseapp](./sdk-design.md#baseapp). -### Next, let us go into the [high-level design principles of the SDK](./sdk-design.md) +### Next, let us go into the [high-level design principles of the SDK](./sdk-design.md) \ No newline at end of file diff --git a/docs/intro/why-app-specific.md b/docs/intro/why-app-specific.md index 0873f87d0e4a..1b160429f6eb 100644 --- a/docs/intro/why-app-specific.md +++ b/docs/intro/why-app-specific.md @@ -4,7 +4,7 @@ This document explains what application-specific blockchains are, and why develo ## What are application-specific blockchains? -Application-specific blockchains are blockchains customized to operate a single application. Instead of building a decentralised application on top of an underlying blockchain like Ethereum, developers build their own blockchain from the ground up. This means building a full-node client, a light-client, and all the necessary interfaces (CLI, REST, ...) to interract with the nodes. +Application-specific blockchains are blockchains customized to operate a single application. Instead of building a decentralised application on top of an underlying blockchain like Ethereum, developers build their own blockchain from the ground up. This means building a full-node client, a light-client, and all the necessary interfaces (CLI, REST, ...) to interract with the nodes. ``` ^ +-------------------------------+ ^ @@ -24,13 +24,13 @@ Blockchain node | | Consensus | | ## What are the shortcomings of Smart Contracts? -Virtual-machine blockchains like Ethereum addressed the demand for more programmability back in 2014. At the time, the options available for building decentralised applications were quite limited. Most developers would build on top of the complex and limited Bitcoin scripting language, or fork the Bitcoin codebase which was hard to work with and customize. +Virtual-machine blockchains like Ethereum addressed the demand for more programmability back in 2014. At the time, the options available for building decentralised applications were quite limited. Most developers would build on top of the complex and limited Bitcoin scripting language, or fork the Bitcoin codebase which was hard to work with and customize. Virtual-machine blockchains came in with a new value proposition. Their state-machine incorporates a virtual-machine that is able to interpret turing-complete programs called Smart Contracts. These Smart Contracts are very good for use cases like one-time events (e.g. ICOs), but they can fall short for building complex decentralised platforms: -- Smart Contracts are generally developed with specific programming languages that can be interpreted by the underlying virtual-machine. These programming languages are often immature and inherently limited by the constraints of the virtual-machine. For example, the Ethereum Virtual Machine does not allow developers to implement automatic execution of code. Developers are also limited to the account-based system of the EVM, and they can only choose from a limited set of functions for their cryptographic operations. These are examples, but they hint at the lack of **flexibility** a smart contract environment often entails. +- Smart Contracts are generally developed with specific programming languages that can be interpreted by the underlying virtual-machine. These programming languages are often immature and inherently limited by the constraints of the virtual-machine. For example, the Ethereum Virtual Machine does not allow developers to implement automatic execution of code. Developers are also limited to the account-based system of the EVM, and they can only choose from a limited set of functions for their cryptographic operations. These are examples, but they hint at the lack of **flexibility** a smart contract environment often entails. - Smart Contracts are all run by the same virtual machine. This means that they compete for resources, which can severly restrain **performance**. And even if the state-machine were to be split in multiple subsets (e.g. via sharding), Smart Contracts would still need to be interpeted by a virtual machine, which would limit performance compared to a native application implemented at state-machine level (our benchmarks show an improvement on the order of x10 in performance when the virtual-machine is removed). -- Another issue with the fact that Smart Contracts share the same underlying environment is the resulting limitation in **sovereignty**. A decentralised application is an ecosystem that involves multiple players. If the application is built on a general-purpose virtual-machine blockchain, these players have very limited sovereignty over it, and are ultimately superseded by the governance of the underlying blockchain. If there is a bug in the application, very little can be done about it. +- Another issue with the fact that Smart Contracts share the same underlying environment is the resulting limitation in **sovereignty**. A decentralised application is an ecosystem that involves multiple players. If the application is built on a general-purpose virtual-machine blockchain, these players have very limited sovereignty over it, and are ultimately superseded by the governance of the underlying blockchain. If there is a bug in the application, very little can be done about it. Application-Specific Blockchains are designed to address these shortcomings. @@ -40,35 +40,36 @@ Application-Specific Blockchains are designed to address these shortcomings. Application-specific blockchains give maximum flexibility to developers: -- Developers can choose among multiple frameworks to build their state-machine. The most widely used today is the Cosmos SDK, but others exist (e.g. Lotion, Weave, ...). The choice will most of the time be done based on the programming language they want to use (Cosmos SDK and Weave are in Golang, Lotion is in Javascript, ...). -- Developers can swap consensus engine. Today, only Tendermint is production-ready, but in the future other engines are expected to emerge. -- Even when they settle for a framework and consensus engine, developers still have the freedom to tweak them if they don't perfectly match their requirements in their pristine forms. -- Developers are free to explore the full spectrum of tradeoffs (e.g. number of validators vs transaction throughput, safety vs availability in asynchrony, ...) and design choices (DB or IAVL tree for storage, UTXO or account model, ...). -- Developers can implement automatic execution of code. In the Cosmos SDK, logic can be automatically triggered at the beginning and the end of each block. They are also free to choose the cryptographic library used in their application, as opposed to being constrained by what is made available by the underlying environment in the case of virtual-machine blockchains. +- In Cosmos blockchains, the state-machine is typically connected to the underlying consensus engine via an interface called the [ABCI](https://tendermint.com/docs/spec/abci/). This interface can be wrapped in any programming language, meaning developers can build their state-machine in the programming language of their choice. +- Developers can choose among multiple frameworks to build their state-machine. The most widely used today is the Cosmos SDK, but others exist (e.g. [Lotion](https://github.com/nomic-io/lotion), [Weave](https://github.com/iov-one/weave), ...). The choice will most of the time be done based on the programming language they want to use (Cosmos SDK and Weave are in Golang, Lotion is in Javascript, ...). +- The ABCI also allows developers to swap the consensus engine of their application-specific blockchain. Today, only Tendermint is production-ready, but in the future other engines are expected to emerge. +- Even when they settle for a framework and consensus engine, developers still have the freedom to tweak them if they don't perfectly match their requirements in their pristine forms. +- Developers are free to explore the full spectrum of tradeoffs (e.g. number of validators vs transaction throughput, safety vs availability in asynchrony, ...) and design choices (DB or IAVL tree for storage, UTXO or account model, ...). +- Developers can implement automatic execution of code. In the Cosmos SDK, logic can be automatically triggered at the beginning and the end of each block. They are also free to choose the cryptographic library used in their application, as opposed to being constrained by what is made available by the underlying environment in the case of virtual-machine blockchains. -The list above contains a few examples that show how much flexibility application-specific blockchains give to developers. The goal of Cosmos and the Cosmos SDK is to make developer tooling as generic and composable as possible, so that each part of the stack can be forked, tweaked and improved without losing compatibility. As the community grows, more alternative for each of the core building blocks will emerge, giving more options to developers. +The list above contains a few examples that show how much flexibility application-specific blockchains give to developers. The goal of Cosmos and the Cosmos SDK is to make developer tooling as generic and composable as possible, so that each part of the stack can be forked, tweaked and improved without losing compatibility. As the community grows, more alternative for each of the core building blocks will emerge, giving more options to developers. ### Performance Decentralised applications built with Smart Contracts are inherently capped in performance by the underlying environment. For a decentralised application to optimise performance, it needs to be built as an application-specific blockchains. Here are the benefits of an application-specific blockchains with regards to performance: -- Developers of application-specific blockchains can choose to operate with novel consensus engine such as Tendermint BFT. Compared to Proof-of-Work (used by most virtual-machine blockchains today), it offers significant gains in throuhgput. -- An application-specific blockchain only operates a single application, so that the application does not compete with others for computation. This is the opposite of most non-sharded virtual-machine blockchains today, where smart contracts all compete for computation. -- Even if a virtual-machine blockchain offered application-based sharding coupled with an efficient consensus algorithm, performance would still be limited by the virtual-machine itself. The real throughput bottleneck is the state-machine, and requiring transactions to be interpreted by a virtual-machine significantly increases the computational complexity of processing them. +- Developers of application-specific blockchains can choose to operate with novel consensus engine such as Tendermint BFT. Compared to Proof-of-Work (used by most virtual-machine blockchains today), it offers significant gains in throuhgput. +- An application-specific blockchain only operates a single application, so that the application does not compete with others for computation and storage. This is the opposite of most non-sharded virtual-machine blockchains today, where smart contracts all compete for computation and storage. +- Even if a virtual-machine blockchain offered application-based sharding coupled with an efficient consensus algorithm, performance would still be limited by the virtual-machine itself. The real throughput bottleneck is the state-machine, and requiring transactions to be interpreted by a virtual-machine significantly increases the computational complexity of processing them. -### Security +### Security Security is hard to quantify, and greatly varies from platform to platform. That said here are some important benefits an application-specific blockchain can bring in terms of security: -- Developers can choose proven programming language like Golang when building their application-specific blockchains, as opposed to smart contract programming languages that are often more immature. -- Developers are not constrained by the cryptographic functions made available by the underlying virtual-machines. They can use their own custom cryptography, and rely on well-audited crypto libraries. -- Developers do not have to worry about potential bugs or exploitable mechanisms in the underlying virtual-machine, making it easier to reason about the security of the application. +- Developers can choose proven programming languages like Golang when building their application-specific blockchains, as opposed to smart contract programming languages that are often more immature. +- Developers are not constrained by the cryptographic functions made available by the underlying virtual-machines. They can use their own custom cryptography, and rely on well-audited crypto libraries. +- Developers do not have to worry about potential bugs or exploitable mechanisms in the underlying virtual-machine, making it easier to reason about the security of the application. ### Sovereignty -One of the major benefits of application-specific blockchains is sovereignty. A decentralised application is an ecosystem that involves many actors: users, developers, third-party services, and more. When developers build on virtual-machine blockchain where many decentralised applications coexist, the community of the application is different than the community of the underlying blockchain, and the latter supersedes the former. If there is a bug or if a new feature is needed, the community of the application has very little sovereignty to upgrade the code. If the community of the underlying blockchain refuses to act, nothing can happen. +One of the major benefits of application-specific blockchains is sovereignty. A decentralised application is an ecosystem that involves many actors: users, developers, third-party services, and more. When developers build on virtual-machine blockchain where many decentralised applications coexist, the community of the application is different than the community of the underlying blockchain, and the latter supersedes the former. If there is a bug or if a new feature is needed, the community of the application has very little sovereignty to upgrade the code. If the community of the underlying blockchain refuses to act, nothing can happen. -The fundamental issue here is that the governance of the application and the governance of the network are not aligned. This issue is solved by application-specific blockchains. Because application-specific blockchains specialize to operate a single application, the community of the application has full control over the entire chain. This ensures the community will not be stuck if a bug is discovered, and that it has the entire freedom to choose how it is going to evolve. +The fundamental issue here is that the governance of the application and the governance of the network are not aligned. This issue is solved by application-specific blockchains. Because application-specific blockchains specialize to operate a single application, the community of the application has full control over the entire chain. This ensures the community will not be stuck if a bug is discovered, and that it has the entire freedom to choose how it is going to evolve. ## Start Building Your Application-Specific Blockchain Today From cf60c92b6b1536c1f39b1feeb9c4ac19b8eb678c Mon Sep 17 00:00:00 2001 From: Gloria Zhao Date: Wed, 21 Aug 2019 14:32:01 -0700 Subject: [PATCH 065/196] deleted some --- docs/basics/app-anatomy.md | 103 +++++++++------- docs/building-modules/modules-manager.md | 147 ----------------------- docs/concepts/encoding.md | 3 - docs/concepts/tx-msgs.md | 5 - 4 files changed, 58 insertions(+), 200 deletions(-) delete mode 100644 docs/building-modules/modules-manager.md delete mode 100644 docs/concepts/encoding.md delete mode 100644 docs/concepts/tx-msgs.md diff --git a/docs/basics/app-anatomy.md b/docs/basics/app-anatomy.md index dc58e389342a..15e1c9fc1e22 100644 --- a/docs/basics/app-anatomy.md +++ b/docs/basics/app-anatomy.md @@ -55,7 +55,7 @@ Blockchain Node | | Consensus | | The blockchain full-node presents itself as a binary, generally suffixed by `-d` for "daemon" (e.g. `appd` for `app` or `gaiad` for `gaia`). This binary is built by running a simple `main.go` function placed in `cmd/appd/`. This operation usually happens through the [Makefile](#dependencies-and-makefile). -To learn more about the `main.go` function, [click here](./node.md#main-function). +To learn more about the `main.go` function, [click here](../core/node.md#main-function). Once the main binary is built, the node can be started by running the `start` command. The core logic behind the `start` command is implemented in the SDK itself in the [`/server/start.go`](https://github.com/cosmos/cosmos-sdk/blob/master/server/start.go) file. The main [`start` command function](https://github.com/cosmos/cosmos-sdk/blob/master/server/start.go#L31) takes a [`context`](https://godoc.org/github.com/cosmos/cosmos-sdk/client/context) and [`appCreator`](<#constructor-function-(`appCreator`)>) as arguments. The `appCreator` is a constructor function for the SDK application, and is used in the starting process of the full-node. @@ -73,11 +73,11 @@ In general, the core of the state-machine is defined in a file called `app.go`. The first thing defined in `app.go` is the `type` of the application. It is generally comprised of the following parts: -- **A reference to [`baseapp`](./baseapp.md).** The custom application defined in `app.go` is an extension of the `baseapp` type. `baseapp` implements most of the core logic for the application, including all the [ABCI methods](https://tendermint.com/docs/spec/abci/abci.html#overview) and the routing logic. When a transaction is relayed by Tendermint to the application, the latter uses `baseapp`'s methods to route them to the appropriate module. -- **A list of store keys**. The [store](./store.md), which contains the entire state, is implemented as a multistore (i.e. a store of stores) in the Cosmos SDK. Each module uses one or multiple stores in the multistore to persist their part of the state. These stores can be accessed with specific keys that are declared in the `app` type. These keys, along with the `keepers`, are at the heart of the [object-capabilities model](../intro/ocap.md) of the Cosmos SDK. -- **A list of module's `keepers`.** Each module defines an abstraction called `keeper`, which handles reads and writes for this module's store(s). The `keeper`'s methods of one module can be called from other modules (if authorized), which is why they are declared in the application's type and exported as interfaces to other modules so that they are only allowed to access the authorized functions. -- **A reference to a `codec`.** The Cosmos SDK gives developers the freedom to choose the encoding framework for their application. The application's `codec` is used to serialize and deserialize data structures in order to store them, as stores can only persist `[]bytes`. The `codec` must be deterministic. The default codec is [amino](./amino.md). -- **A reference to a [module manager](./modules.md#module-manager)**. The module manager is an object that contains a list of the application's module. It facilitates operations related to these modules, like registering [`routes`](./baseapp.md#routing), [query routes](#./baseapp.md#query-routing) or setting the order of execution between modules for various functions like [`InitChainer`](#initchainer), [`BeginBlocker` and `EndBlocker`](#beginblocker-and-endblocker). +- **A reference to [`baseapp`](../core/baseapp.md).** The custom application defined in `app.go` is an extension of the `baseapp` type. `baseapp` implements most of the core logic for the application, including all the [ABCI methods](https://tendermint.com/docs/spec/abci/abci.html#overview) and the routing logic. When a transaction is relayed by Tendermint to the application, the latter uses `baseapp`'s methods to route them to the appropriate module. +- **A list of store keys**. The [store](../core/store.md), which contains the entire state, is implemented as a multistore (i.e. a store of stores) in the Cosmos SDK. Each module uses one or multiple stores in the multistore to persist their part of the state. These stores can be accessed with specific keys that are declared in the `app` type. These keys, along with the `keepers`, are at the heart of the [object-capabilities model](../intro/ocap.md) of the Cosmos SDK. +- **A list of module's `keepers`.** Each module defines an abstraction called [`keeper`](../building-modules/keeper.md), which handles reads and writes for this module's store(s). The `keeper`'s methods of one module can be called from other modules (if authorized), which is why they are declared in the application's type and exported as interfaces to other modules so that they are only allowed to access the authorized functions. +- **A reference to a [`codec`](../core/encoding.md).** The Cosmos SDK gives developers the freedom to choose the encoding framework for their application. The application's `codec` is used to serialize and deserialize data structures in order to store them, as stores can only persist `[]bytes`. The `codec` must be deterministic. The default codec is [amino](./amino.md). +- **A reference to a [module manager](../building-modules/module-manager.md#manager)** and a [basic module manager](../building-modules/module-manager.md#basicmanager). The module manager is an object that contains a list of the application's module. It facilitates operations related to these modules, like registering [`routes`](./baseapp.md#routing), [query routes](#./baseapp.md#query-routing) or setting the order of execution between modules for various functions like [`InitChainer`](#initchainer), [`BeginBlocker` and `EndBlocker`](#beginblocker-and-endblocker). You can see an example of application type definition [here](https://github.com/cosmos/gaia/blob/master/app/app.go#L73-L107). @@ -85,18 +85,19 @@ You can see an example of application type definition [here](https://github.com/ This function constructs a new application of the type defined above. It is called every time the full-node is started with the [`start`](https://github.com/cosmos/cosmos-sdk/blob/master/server/start.go#L117) command. Here are the main actions performed by this function: +- Instantiate a new [`codec`](../core/encoding.md) and initialize the `codec` of each of the application's module using the [basic manager](../building-modules/module-manager.md#basicmanager) - Instantiate a new application with a reference to a `baseapp` instance, a codec and all the appropriate store keys. -- Instantiate all the [`keeper`s](#keeper) defined in the application's `type` using the `NewKeeper` function of each of the application's modules. Note that `keepers` must be instantiated in the correct order, as the `NewKeeper` of one module might require a reference to another module's `keeper`. -- Instantiate the application's [module manager](./module-manager.md) with the [`AppModule`](#application-module-interface) object of each of the application's modules. -- With the module manager, initialize the application's [`routes`](./baseapp.md#routing) and [query routes](./baseapp.md#query-routing). When a transaction is relayed to the application by Tendermint via the ABCI, it is routed to the appropriate module's [`handler`](#handler) using the routes defined here. Likewise, when a query is received by the application, it is routed to the appropriate module's [`querier`](#querier) using the query routes defined here. -- With the module manager, register the [application's modules' invariants](./invariants.md). Invariants are variables (e.g. total supply of a token) that are evaluated at the end of each block. The process of checking invariants is done via a special module called the [`InvariantsRegistry`](./invariants.md#invariant-registry). The value of the invariant should be equal to a predicted value defined in the module. Should the value be different than the predicted one, special logic defined in the invariant registry will be triggered (usually the chain is halted). This is useful to make sure no critical bug goes unnoticed and produces long-lasting effects that would be hard to fix. -- With the module manager, set the order of execution between the `InitGenesis`, `BegingBlocker` and `EndBlocker` functions of each of the [application's modules](#application-module-interface). Note that not all modules implement these functions. +- Instantiate all the [`keeper`s](#keeper) defined in the application's `type` using the `NewKeeper` function of each of the application's modules. Note that `keepers` must be instantiated in the correct order, as the `NewKeeper` of one module might require a reference to another module's `keeper`. +- Instantiate the application's [module manager](../building-modules/module-manager.md#manager) with the [`AppModule`](#application-module-interface) object of each of the application's modules. +- With the module manager, initialize the application's [`routes`](../core/baseapp.md#routing) and [query routes](../core/baseapp.md#query-routing). When a transaction is relayed to the application by Tendermint via the ABCI, it is routed to the appropriate module's [`handler`](#handler) using the routes defined here. Likewise, when a query is received by the application, it is routed to the appropriate module's [`querier`](#querier) using the query routes defined here. +- With the module manager, register the [application's modules' invariants](./invariants.md). Invariants are variables (e.g. total supply of a token) that are evaluated at the end of each block. The process of checking invariants is done via a special module called the [`InvariantsRegistry`](../building-modules/invariants.md#invariant-registry). The value of the invariant should be equal to a predicted value defined in the module. Should the value be different than the predicted one, special logic defined in the invariant registry will be triggered (usually the chain is halted). This is useful to make sure no critical bug goes unnoticed and produces long-lasting effects that would be hard to fix. +- With the module manager, set the order of execution between the `InitGenesis`, `BegingBlocker` and `EndBlocker` functions of each of the [application's modules](#application-module-interface). Note that not all modules implement these functions. - Set the remainer of application's parameters: - - [`InitChainer`](#initchainer): used to initialize the application when it is first started. - - [`BeginBlocker`, `EndBlocker`](#beginblocker-and-endlbocker): called at the beginning and the end of every block). - - [`anteHandler`](#baseapp.md#antehandler): used to handle fees and signature verification. -- Mount the stores. -- Return the application. + + [`InitChainer`](#initchainer): used to initialize the application when it is first started. + + [`BeginBlocker`, `EndBlocker`](#beginblocker-and-endlbocker): called at the beginning and the end of every block). + + [`anteHandler`](../core/baseapp.md#antehandler): used to handle fees and signature verification. +- Mount the stores. +- Return the application. Note that this function only creates an instance of the app, while the actual state is either carried over from the `~/.appd/data` folder if the node is restarted, or generated from the genesis file if the node is started for the first time. @@ -104,7 +105,7 @@ You can see an example of application constructor [here](https://github.com/cosm ### InitChainer -The `InitChainer` is a function that initializes the state of the application from a [genesis file](./genesis.md) (i.e. token balances of genesis accounts). It is called when the application receives the `InitChain` message from the Tendermint engine, which happens when the node is started at `appBlockHeight == 0` (i.e. on genesis). The application must set the `InitChainer` in its constructor via the [`SetInitChainer`](https://godoc.org/github.com/cosmos/cosmos-sdk/baseapp#BaseApp.SetInitChainer) method. +The `InitChainer` is a function that initializes the state of the application from a [genesis file](../core/genesis.md) (i.e. token balances of genesis accounts). It is called when the application receives the `InitChain` message from the Tendermint engine, which happens when the node is started at `appBlockHeight == 0` (i.e. on genesis). The application must set the `InitChainer` in its constructor via the [`SetInitChainer`](https://godoc.org/github.com/cosmos/cosmos-sdk/baseapp#BaseApp.SetInitChainer) method. In general, the `InitChainer` is mostly composed of the `InitGenesis` function of each of the application's modules. This is done by calling the `InitGenesis` function of the module manager, which in turn will call the `InitGenesis` function of each of the modules it contains. Note that the order in which the modules' `InitGenesis` functions must be called has to be set in the module manager using the `SetOrderInitGenesis` method. This is done in the [application's constructor](#application-constructor), and the `SetOrderInitGenesis` has to be called before the `SetInitChainer`. @@ -116,7 +117,7 @@ The SDK offers developers the possibility to implement automatic execution of co In general, the `BeginBlocker` and `EndBlocker` functions are mostly composed of the `BeginBlock` and `EndBlock` functions of each of the application's modules. This is done by calling the `BeginBlock` and `EndBlock` functions of the module manager, which in turn will call the `BeginBLock` and `EndBlock` functions of each of the modules it contains. Note that the order in which the modules' `BegingBlock` and `EndBlock` functions must be called has to be set in the module manager using the `SetOrderBeginBlock` and `SetOrderEndBlock` methods respectively. This is done in the [application's constructor](#application-constructor), and the `SetOrderBeginBlock` and `SetOrderEndBlock` methods have to be called before the `SetBeginBlocker` and `SetEndBlocker` functions. -As a sidenote, it is important to remember that application-specific blockchains are deterministic. Developers must be careful not to introduce non-determinism in `BeginBlocker` or `EndBlocker`, and must also be careful not to make them too computationally expensive, as gas does not constrain the cost of `BeginBlocker` and `EndBlocker` execution. +As a sidenote, it is important to remember that application-specific blockchains are deterministic. Developers must be careful not to introduce non-determinism in `BeginBlocker` or `EndBlocker`, and must also be careful not to make them too computationally expensive, as [gas](./accounts-fees-gas.md/gas) does not constrain the cost of `BeginBlocker` and `EndBlocker` execution. You can see an example of `BeginBlocker` and `EndBlocker` functions [here](https://github.com/cosmos/gaia/blob/master/app/app.go#L224-L232). @@ -124,53 +125,55 @@ You can see an example of `BeginBlocker` and `EndBlocker` functions [here](https The `MakeCodec` function is the last important function of the `app.go` file. The goal of this function is to instantiate a codec `cdc` (e.g. amino) initialize the codec of the SDK and each of the application's modules using the `RegisterCodec` function. -To register the application's modules, the `MakeCodec` function calls `RegisterCodec` on `ModuleBasics`. `ModuleBasics` is a basic manager which lists all of the application's modules. It is instantiated in the `init()` function, and only serves to easily register non-dependent elements of application's modules (such as codec). To learn more about the basic module manager,. +To register the application's modules, the `MakeCodec` function calls `RegisterCodec` on `ModuleBasics`. `ModuleBasics` is a [basic manager](../building-modules/module-manager.md#basicmanager) which lists all of the application's modules. It is instanciated in the `init()` function, and only serves to easily register non-dependant elements of application's modules (such as codec). To learn more about the basic module manager, click [here](../building-modules/module-manager.md#basicmanager). You can see an example of a `MakeCodec` [here](https://github.com/cosmos/gaia/blob/master/app/app.go#L64-L70) ## Modules -Modules are the heart and soul of an SDK application. They can be considered as state-machines within the state-machine. When a transaction is relayed from the underlying Tendermint engine via the ABCI to the application, it is routed by `baseapp` to the appropriate module in order to be processed. This paradigm enables developers to easily build complex state-machines, as most of the modules they need often already exist. For developers, most of the work involved in building an SDK application revolves around building custom modules required by their application that do not exist, and integrating them with modules that do already exist into one coherent application. In the application directory, the standard practice is to store modules in the `x/` folder (not to be confused with the SDK's `x/` folder, which contains already-built modules). +Modules are the heart and soul of an SDK application. They can be considered as state-machines within the state-machine. When a transaction is relayed from the underlying Tendermint engine via the ABCI to the application, it is routed by [`baseapp`](../core/baseapp.md) to the appropriate module in order to be processed. This paradigm enables developers to easily build complex state-machines, as most of the modules they need often already exist. For developers, most of the work involved in building an SDK application revolves around building custom modules required by their application that do not exist, and integrating them with modules that do already exist into one coherent application. In the application directory, the standard practice is to store modules in the `x/` folder (not to be confused with the SDK's `x/` folder, which contains already-built modules). + +To learn more about modules, [click here](./modules.md) ### Application Module Interface -Modules implement two interfaces defined in the Cosmos SDK, [`AppModuleBasic`](https://github.com/cosmos/cosmos-sdk/blob/master/types/module/module.go#L44-L57) and [`AppModule`](https://github.com/cosmos/cosmos-sdk/blob/master/types/module/module.go#L44-L57). The former implements basic non-dependant elements of the module, such as the `codec`, while the latter handles the bulk of the module methods (including methods that require references to other modules' `keeper`s). Both the `AppModule` and `AppModuleBasic` types are defined in a file called `./module.go`. +Modules implement two interfaces defined in the Cosmos SDK, [`AppModuleBasic`](../building-modules/module-manager.md#appmodulebasic) and [`AppModule`](../building-modules/module-manager.md#appmodule). The former implements basic non-dependant elements of the module, such as the `codec`, while the latter handles the bulk of the module methods (including methods that require references to other modules' `keeper`s). Both the `AppModule` and `AppModuleBasic` types are defined in a file called `./module.go`. -`AppModule` exposes a collection of useful methods on the module that facilitates the composition of modules into a coherent application. Important methods include: +`AppModule` exposes a collection of useful methods on the module that facilitates the composition of modules into a coherent application. These methods are are called from the `module manager`(../building-modules/module-manager.md#manager), which manages the application's collection of modules. -- `Route()` and `QueryRoute()`: These methods the name of the route and querier route for the module, for [messages](#message-types) to be routed to the module's [`handler`](#handler) and queries to be routes to the module's [`querier`](#querier). -- `NewHandler()` and `NewQuerierHandler()`: These methods return a `handler` and `querierHandler` respectively, in order to process a message or a query once they are routed. -- `BeginBlock()`, `EndBlock()` and `InitGenesis()`: These methods are executed respectively at the beginning of each block, at the end of each block and at the start of the chain. They implement special logic the module requires to be triggered during those events. For example, the `EndBlock` function is frequently used by modules where voting occurs to tally the result of the votes. -- `RegisterInvariants()`: This method registers the [invariants](./invariants.md) for the module. Invariants are checked at the end of every block to make sure no unpredicted behaviour is occuring. -- `AppModule`'s methods are called from the `module manager`, which manages the application's collection of modules. +To learn more about the application module interface, [click here](../building-modules/module-manager.md#application-module-interfaces). ### Message Types -A message is a custom type defined by each module that implements the [`message`](https://github.com/cosmos/cosmos-sdk/blob/master/types/tx_msg.go#L8-L29) interface. Each `transaction` contains one or multiple `messages`. When a valid block of transactions is received by the full-node, Tendermint relays each one to the application via [`DeliverTx`](https://tendermint.com/docs/app-dev/abci-spec.html#delivertx). Then, the application handles the transaction: +A message is a custom type defined by each module that implements the [`message`](../building-modules/messages-and-queries.md#messages) interface. Each [`transaction`](../core/transaction.md) contains one or multiple `messages`. When a valid block of transactions is received by the full-node, Tendermint relays each one to the application via [`DeliverTx`](https://tendermint.com/docs/app-dev/abci-spec.html#delivertx). Then, the application handles the transaction: -1. Upon receiving the transaction, the application first unmarshals it from `[]bytes`. -2. Then, it verifies a few things about the transaction like [fee payment and signatures](#accounts-fees-gas.md) before extracting the message(s) contained in the transaction. -3. With the [`Type()`](https://github.com/cosmos/cosmos-sdk/blob/master/types/tx_msg.go#L16) method, `baseapp` is able to know which modules defines the message. It is then able to route it to the appropriate module's [handler](#handler) in order for the message to be processed. -4. If the message is successfully processed, the state is updated. +1. Upon receiving the transaction, the application first unmarshalls it from `[]bytes`. +2. Then, it verifies a few things about the transaction like [fee payment and signatures](#accounts-fees-gas.md) before extracting the message(s) contained in the transaction. +3. With the [`Type()`](https://github.com/cosmos/cosmos-sdk/blob/master/types/tx_msg.go#L16) method, `baseapp` is able to know which modules defines the message. It is then able to route it to the appropriate module's [handler](#handler) in order for the message to be processed. +4. If the message is successfully processed, the state is updated. For a more detailed look at a transaction lifecycle, click [here](./tx-lifecycle.md). Module developers create custom message types when they build their own module. The general practice is to prefix the type declaration of the message with `Msg`. For example, the message type [`MsgSend`](https://github.com/cosmos/cosmos-sdk/blob/master/x/bank/types/msgs.go#L10-L15) allows users to transfer tokens. It is processed by the handler of the `bank` module, which ultimately calls the `keeper` of the `auth` module in order to update the state. +To learn more about messages, [click here](../building-modules/messages-and-queries.md#messages). + ### Handler -The `handler` refers to the part of the module responsible for processing the message after it is routed by `baseapp`. `handler` functions of modules (except those of the `auth` module) are only executed if the transaction is relayed from Tendermint by the `DeliverTx` ABCI message. If the transaction is relayed by `CheckTx`, only stateless checks and fee-related (i.e. `auth` module-related) stateful checks are performed. To better understand the difference between `DeliverTx`and `CheckTx`, as well as the difference between stateful and stateless checks, click [here](./tx-lifecycle.md). +The [`handler`](../building-modules/handler.md) refers to the part of the module responsible for processing the message after it is routed by `baseapp`. `handler` functions of modules (except those of the `auth` module) are only executed if the transaction is relayed from Tendermint by the `DeliverTx` ABCI message. If the transaction is relayed by `CheckTx`, only stateless checks and fee-related (i.e. `auth` module-related) stateful checks are performed. To better understand the difference between `DeliverTx`and `CheckTx`, as well as the difference between stateful and stateless checks, click [here](./tx-lifecycle.md). The handler of a module is generally defined in a file called `handler.go` and consists of: -- A **switch function** `NewHandler` to route the message to the appropriate handler function. This function returns a `handler` function, and is registered in the [`AppModule`](#application-module-interface) to be used in the application's module manager to initialize the application's router. See an example of such a switch [here](https://github.com/cosmos/sdk-application-tutorial/blob/master/x/nameservice/handler.go#L10-L22). -- **One handler function for each message type defined by the module**. Developers write the message processing logic in these functions. This generally involves doing stateful checks to ensure the message is valid and calling [`keeper`](#keeper)'s methods to update the state. +- A **switch function** `NewHandler` to route the message to the appropriate handler function. This function returns a `handler` function, and is registered in the [`AppModule`](#application-module-interface) to be used in the application's module manager to initialize the [application's router](../core/baseapp.md#routing). See an example of such a switch [here](https://github.com/cosmos/sdk-application-tutorial/blob/master/x/nameservice/handler.go#L10-L22). +- **One handler function for each message type defined by the module**. Developers write the message processing logic in these functions. This generally involves doing stateful checks to ensure the message is valid and calling [`keeper`](#keeper)'s methods to update the state. Handler functions return a result of type [`sdk.Result`](https://github.com/cosmos/cosmos-sdk/blob/master/types/result.go#L14-L37), which informs the application on whether the message was successfully processed. +To learn more about handlers, [click here](../building-modules/handler.md). + ### Keeper -`Keepers` are the gatekeepers of their module's store(s). To read or write in a module's store, it is mandatory to go through one of its `keeper`'s methods. This is ensured by the [object-capabilities](./ocap.md) model of the Cosmos SDK. Only objects that hold the key to a store can access it, and only the module's `keeper` should hold the key(s) to the module's store(s). +[`Keepers`](../building-module/keeper.md) are the gatekeepers of their module's store(s). To read or write in a module's store, it is mandatory to go through one of its `keeper`'s methods. This is ensured by the [object-capabilities](../core/ocap.md) model of the Cosmos SDK. Only objects that hold the key to a store can access it, and only the module's `keeper` should hold the key(s) to the module's store(s). `Keepers` are generally defined in a file called `keeper.go`. It contains the `keeper`'s type definition and methods. @@ -184,14 +187,18 @@ Along with the type definition, the next important component of the `keeper.go` The rest of the file defines the `keeper`'s methods, primarily getters and setters. You can check an example of a `keeper` implementation [here](https://github.com/cosmos/sdk-application-tutorial/blob/master/x/nameservice/keeper.go). -### Querier +To learn more about `keepers`, [click here](../building-modules/keeper.md). + +### Querier -`Queriers` are very similar to `handlers`, except they serve user queries to the state as opposed to processing transactions. A query is initiated from an [interface](#intefaces) by an end-user who provides a `queryRoute` and some `data`. The query is then routed to the correct application's `querier` by `baseapp`'s [`handleQueryCustom`](https://github.com/cosmos/cosmos-sdk/blob/master/baseapp/baseapp.go#L519-L556) method using `queryRoute`. +[`Queriers`](../building-modules/querier.md) are very similar to `handlers`, except they serve user queries to the state as opposed to processing transactions. A [query](../building-modules/messages-and-queries.md#queries) is initiated from an [interface](#interfaces) by an end-user who provides a `queryRoute` and some `data`. The query is then routed to the correct application's `querier` by `baseapp`'s [`handleQueryCustom`](https://github.com/cosmos/cosmos-sdk/blob/master/baseapp/baseapp.go#L519-L556) method using `queryRoute`. The `Querier` of a module is defined in a file called `querier.go`, and consists of: -- A **switch function** `NewQuerier` to route the query to the appropriate `querier` function. This function returns a `querier` function, and is is registered in the [`AppModule`](#application-module-interface) to be used in the application's module manager to initialize the application's query router. See an example of such a switch [here](https://github.com/cosmos/sdk-application-tutorial/blob/master/x/nameservice/querier.go#L21-L34). -- - **One querier function for each data type defined by the module that needs to be queryable**. Developers write the query processing logic in these functions. This generally involves calling [`keeper`](#keeper)'s methods to query the state and marshaling it to JSON. See an example of `querier` functions [here](https://github.com/cosmos/sdk-application-tutorial/blob/master/x/nameservice/querier.go#L37-L101). +- A **switch function** `NewQuerier` to route the query to the appropriate `querier` function. This function returns a `querier` function, and is is registered in the [`AppModule`](#application-module-interface) to be used in the application's module manager to initialize the [application's query router](../core/baseapp.md#query-routing). See an example of such a switch [here](https://github.com/cosmos/sdk-application-tutorial/blob/master/x/nameservice/querier.go#L21-L34). +- - **One querier function for each data type defined by the module that needs to be queryable**. Developers write the query processing logic in these functions. This generally involves calling [`keeper`](#keeper)'s methods to query the state and marshalling it to JSON. See an example of `querier` functions [here](https://github.com/cosmos/sdk-application-tutorial/blob/master/x/nameservice/querier.go#L37-L101). + +To learn more about `queriers`, [click here](../building-modules/querier.md). ### Command-Line and REST Interfaces @@ -204,9 +211,11 @@ Generally, the commands related to a module are defined in a folder called `clie - Transactions commands let users generate new transactions so that they can be included in a block and eventually update the state. One command should be created for each [message type](#message-types) defined in the module. The command calls the constructor of the message with the parameters provided by the end-user, and wraps it into a transaction. The SDK handles signing and the addition of other transaction metadata. See examples of transactions commands [here](https://github.com/cosmos/sdk-application-tutorial/blob/master/x/nameservice/client/cli/tx.go). - Queries let users query the subset of the state defined by the module. Query commands forward queries to the [application's query router](./baseapp.md#query-routing), which routes them to the appropriate [querier](#querier) the `queryRoute` parameter supplied. See examples of query commands [here](https://github.com/cosmos/sdk-application-tutorial/blob/master/x/nameservice/client/cli/query.go). +To learn more about modules CLI, [click here](../building-modules/module-interfaces.md#cli). + #### REST -The module's REST interface lets users generate transactions and query the state through REST calls to the application's light client daemon (LCD). REST routes are defined in a file `client/rest/rest.go`, which is composed of: +The module's REST interface lets users generate transactions and query the state through REST calls to the application's [light client daemon](../core/node.md#lcd) (LCD). REST routes are defined in a file `client/rest/rest.go`, which is composed of: - A `RegisterRoutes` function, which registers each route defined in the file. This function is called from the [main application's interface](#application-interfaces) for each module used within the application. The router used in the SDK is [Gorilla's mux](https://github.com/gorilla/mux). - Custom request type definitions for each query or transaction creation function that needs to be exposed. These custom request types build on the [base `request` type](https://github.com/cosmos/cosmos-sdk/blob/master/types/rest/rest.go#L32-L43) of the Cosmos SDK. @@ -214,19 +223,23 @@ The module's REST interface lets users generate transactions and query the state See an example of a module's `rest.go` file [here](https://github.com/cosmos/sdk-application-tutorial/blob/master/x/nameservice/client/rest/rest.go). +To learn more about modules REST interface, [click here](../building-modules/module-interfaces.md#rest). + ## Application Interface Interfaces let end-users interact with full-node clients. This means querying data from the full-node or creating and sending new transactions to be relayed by the full-node and eventually included in a block. -The main interface is the Command-Line Interface. The CLI of an SDK application is built by aggregating [CLI commands](#cli) defined in each of the modules used by the application. The CLI of an application generally has the `-cli` suffix (e.g. `appcli`), and defined in a file called `cmd/appcli/main.go`. The file contains: +The main interface is the [Command-Line Interface](../interfaces/cli.md). The CLI of an SDK application is built by aggregating [CLI commands](#cli) defined in each of the modules used by the application. The CLI of an application generally has the `-cli` suffix (e.g. `appcli`), and defined in a file called `cmd/appcli/main.go`. The file contains: - **A `main()` function**, which is executed to build the `appcli` interface client. This function prepares each command and adds them to the `rootCmd` before building them. At the root of `appCli`, the function adds generic commands like `status`, `keys` and `config`, query commands, tx commands and `rest-server`. -- **Query commands** are added by calling the `queryCmd` function, also defined in `appcli/main.go`. This function returns a Cobra command that contains the query commands defined in each of the application's modules (passed as an array of `sdk.ModuleClients` from the `main()` function), as well as some other lower level query commands such as block or validator queries. Query command are called by using the command `appcli query [query]` of the CLI. -- **Transaction commands** are added by calling the `txCmd` function. Similar to `queryCmd`, the function returns a Cobra command that contains the tx commands defined in each of the application's modules, as well as lower level tx commands like transaction signing or broadcasting. Tx commands are called by using the command `appcli tx [tx]` of the CLI. -- **A `registerRoutes` function**, which is called from the `main()` function when initializing the [application's light-client daemon (LCD)](./node.md#lcd) (i.e. `rest-server`). `registerRoutes` calls the `RegisterRoutes` function of each of the application's module, thereby registering the routes of the module to the lcd's router. The LCD can be started by running the following command `appcli rest-server`. +- **Query commands** are added by calling the `queryCmd` function, also defined in `appcli/main.go`. This function returns a Cobra command that contains the query commands defined in each of the application's modules (passed as an array of `sdk.ModuleClients` from the `main()` function), as well as some other lower level query commands such as block or validator queries. Query command are called by using the command `appcli query [query]` of the CLI. +- **Transaction commands** are added by calling the `txCmd` function. Similar to `queryCmd`, the function returns a Cobra command that contains the tx commands defined in each of the application's modules, as well as lower level tx commands like transaction signing or broadcasting. Tx commands are called by using the command `appcli tx [tx]` of the CLI. +- **A `registerRoutes` function**, which is called from the `main()` function when initializing the [application's light-client daemon (LCD)](../core/node.md#lcd) (i.e. `rest-server`). `registerRoutes` calls the `RegisterRoutes` function of each of the application's module, thereby registering the routes of the module to the lcd's router. The LCD can be started by running the following command `appcli rest-server`. See an example of an application's main command-line file [here](https://github.com/cosmos/sdk-application-tutorial/blob/master/cmd/nscli/main.go). +To learn more about interfaces, [click here](../interfaces/intro.md). + ## Dependencies and Makefile This section is optional, as developers are free to choose their depencency manager and project building method. That said, the current most used framework for versioning control is [`go.mod`](https://github.com/golang/go/wiki/Modules). It ensures each of the libraries used throughout the application are imported with the correct version. An example can be found [here](https://github.com/cosmos/sdk-application-tutorial/blob/master/go.mod). diff --git a/docs/building-modules/modules-manager.md b/docs/building-modules/modules-manager.md deleted file mode 100644 index bfe4c9d2d297..000000000000 --- a/docs/building-modules/modules-manager.md +++ /dev/null @@ -1,147 +0,0 @@ -# Module Manager - -## Pre-requisite Reading - -- [Introduction to SDK Modules](./intro.md) - -## Synopsis - -Cosmos SDK modules need to implement the [`AppModule` interfaces](#application-module-interfaces), in order to be managed by the application's [module manager](#module-manager). The module manager plays an important role in [`message` and `query` routing](../core/baseapp.md#routing), and allows the application developer to set the order of execution of a variety of functions like [`BeginBlocker` and `EndBlocker`](../basics/app-anatomy.md#begingblocker-and-endblocker). - -## Application Module Interfaces - -[Application module interfaces](https://github.com/cosmos/cosmos-sdk/blob/master/types/module/module.go) exist to facilitate the composition of modules together to form a functional SDK application. There are 3 main application module interfaces: - -- [`AppModuleBasic`](#appmodulebasic) for independent module functionalities. -- [`AppModule`](#appmodule) for inter-dependent module functionalities (except genesis-related functionalities). -- [`AppModuleGenesis`](#appmodulegenesis) for inter-dependent genesis-related module functionalities. - -The `AppModuleBasic` interface exists to define independent methods of the module, i.e. those that do not depend on other modules in the application. This allows for the construction of the basic application structure early in the application definition, generally in the `init()` function of the [main application file](../basics/app-antomy.md#core-application-file). - -The `AppModule` interface exists to define inter-dependent module methods. Many modules need to interract with other modules, typically through [`keeper`s](./keeper.md), which means there is a need for an interface where modules list their `keeper`s and other methods that require a reference to another module's object. `AppModule` interface also enables the module manager to set the order of execution between module's methods like `BeginBlock` and `EndBlock`, which is important in cases where the order of execution between modules matters in the context of the application. - -Lastly the interface for genesis functionality `AppModuleGenesis` is separated out from full module functionality `AppModule` so that modules which -are only used for genesis can take advantage of the `Module` patterns without having to define many placeholder functions. - -### `AppModuleBasic` - -The [`AppModuleBasic`](https://github.com/cosmos/cosmos-sdk/blob/master/types/module/module.go#L45-L57) interface defines the independent methods modules need to implement. - -```go -type AppModuleBasic interface { - Name() string - RegisterCodec(*codec.Codec) - - // genesis - DefaultGenesis() json.RawMessage - ValidateGenesis(json.RawMessage) error - - // client functionality - RegisterRESTRoutes(context.CLIContext, *mux.Router) - GetTxCmd(*codec.Codec) *cobra.Command - GetQueryCmd(*codec.Codec) *cobra.Command -} -``` - -Let us go through the methods: - -- `Name()`: Returns the name of the module as a `string`. -- `RegisterCodec(*codec.Codec)`: Registers the `codec` for the module, which is used to marhsal and unmarshal structs to/from `[]byte` in order to persist them in the moduel's `KVStore`. -- `DefaultGenesis()`: Returns a default [`GenesisState`](./genesis.md#genesisstate) for the module, marshalled to `json.RawMessage`. The default `GenesisState` need to be defined by the module developer and is primarily used for testing. -- `ValidateGenesis(json.RawMessage)`: Used to validate the `GenesisState` defined by a module, given in its `json.RawMessage` form. It will usually unmarshall the `json` before running a custom [`ValidateGenesis`](./genesis.md#validategenesis) function defined by the module developer. -- `RegisterRESTRoutes(context.CLIContext, *mux.Router)`: Registers the REST routes for the module. These routes will be used to map REST request to the module in order to process them. See [../interfaces/rest.md] for more. -- `GetTxCmd(*codec.Codec)`: Returns the root [`Tx` command](./module-interfaces.md#tx) for the module. The subcommands of this root command are used by end-users to generate new transactions containing [`message`s](./messages-and-queries.md#queries) defined in the module. -- `GetQueryCmd(*codec.Codec)`: Return the root [`query` command](./module-intefaces.md#query) for the module. The subcommands of this root command are used by end-users to generate new queries to the subset of the state defined by the module. - -All the `AppModuleBasic` of an application are managed by the [`BasicManager`](#basicmanager). - -### `AppModuleGenesis` - -The [`AppModuleGenesis`](https://github.com/cosmos/cosmos-sdk/blob/master/types/module/module.go#L123-L127) interface is a simple embedding of the `AppModuleBasic` interface with two added methods. - -```go -type AppModuleGenesis interface { - AppModuleBasic - InitGenesis(sdk.Context, json.RawMessage) []abci.ValidatorUpdate - ExportGenesis(sdk.Context) json.RawMessage -} -``` - -Let us go through the two added methods: - -- `InitGenesis(sdk.Context, json.RawMessage)`: Initializes the subset of the state managed by the module. It is called at genesis (i.e. when the chain is first started). -- `ExportGenesis(sdk.Context)`: Exports the latest subset of the state managed by the module to be used in a new genesis file. `ExportGenesis` is called for each module when a new chain is started from the state of an existing chain. - -It does not have its own manager, and exists separately from [`AppModule`](#appmodule) only for modules that exist only to implement genesis functionalities, so that they can be managed without having to implement all of `AppModule`'s methods. If the module is not only used during genesis, `InitGenesis(sdk.Context, json.RawMessage)` and `ExportGenesis(sdk.Context)` will generally be defined as methods of the concrete type implementing hte `AppModule` interface. - -### `AppModule` - -The [`AppModule`](https://github.com/cosmos/cosmos-sdk/blob/master/types/module/module.go#L130-L144) interface defines the inter-dependent methods modules need to implement. - -```go -type AppModule interface { - AppModuleGenesis - - // registers - RegisterInvariants(sdk.InvariantRegistry) - - // routes - Route() string - NewHandler() sdk.Handler - QuerierRoute() string - NewQuerierHandler() sdk.Querier - - BeginBlock(sdk.Context, abci.RequestBeginBlock) - EndBlock(sdk.Context, abci.RequestEndBlock) []abci.ValidatorUpdate -} -``` - -`AppModule`s are managed by the [module manager](#manager). This interface embeds the `AppModuleGenesis` interface so that the manager can access all the independent and genesis inter-dependent methods of the module. This means that a concrete type implementing the `AppModule` interface must either implement all the methods of `AppModuleGenesis` (and by extension `AppModuleBasic`), or include a concrete type that does as parameter. - -Let us go through the methods of `AppModule`: - -- `RegisterInvariants(sdk.InvariantRegistry)`: Registers the [`invariants`](./invariants.md) of the module. If the invariants deviates from its predicted value, the [`InvariantRegistry`](./invariants.md#registry) triggers appropriate logic (most often the chain will be halted). -- `Route()`: Returns the name of the module's route, for [`message`s](./messages-and-queries.md#messages) to be routed to the module by [`baseapp`](../core/baseapp.md#message-routing). -- `NewHandler()`: Returns a [`handler`](./handler.md) given the `Type()` of the `message`, in order to process the `message`. -- `QuerierRoute()`: Returns the name of the module's query route, for [`queries`](./messages-and-queries.md#queries) to be routes to the module by [`baseapp`](../core/baseapp.md#query-routing). -- `NewQuerierHandler()`: Returns a [`querier`](./querier.md) given the query `path`, in order to process the `query`. -- `BeginBlock(sdk.Context, abci.RequestBeginBlock)`: This method gives module developers the option to implement logic that is automatically triggered at the beginning of each block. Implement empty if no logic needs to be triggered at the beginning of each block for this module. -- `EndBlock(sdk.Context, abci.RequestEndBlock)`: This method gives module developers the option to implement logic that is automatically triggered at the beginning of each block. This is also where the module can inform the underlying consensus engine of validator set changes (e.g. the `staking` module). Implement empty if no logic needs to be triggered at the beginning of each block for this module. - -### Implementing the Application Module Interfaces - -Typically, the various application module interfaces are implemented in a file called `module.go`, located in the module's folder (e.g. `./x/module/module.go`). - -Almost every module need to implement the `AppModuleBasic` and `AppModule` interfaces. If the module is only used for genesis, it will implement `AppModuleGenesis` instead of `AppModule`. The concrete type that implements the interface can add parameters that are required for the implementation of the various methods of the interface. For example, the `NewHandler()` function often calls a `NewHandler(k keeper)` function defined in [`handler.go`](./handler.md) and therefore needs to pass the module's [`keeper`](./keeper.md) as parameter. - -```go -// example -type AppModule struct { - AppModuleBasic - keeper Keeper -} -``` - -In the example above, you can see that the `AppModule` concrete type references an `AppModuleBasic`, and not an `AppModuleGenesis`. That is because `AppModuleGenesis` only needs to be implemented in modules that focus on genesis-related functionalities. In most modules, the concrete `AppModule` type will have a reference to an `AppModuleBasic` and implement the two added methods of `AppModuleGenesis` directly in the `AppModule` type. - -If no parameter is required (which is often the case for `AppModuleBasic`), just declare an empty concrete type like so: - -```go -type AppModuleBasic struct{} -``` - -## Module Managers - -Module managers are used to manage collections of `AppModuleBasic` and `AppModule`. - -### `BasicManager` - -The `BasicManager` is a structure that lists all the `AppModuleBasic` of an application: - -```go -type BasicManager map[string]AppModuleBasic -``` - - - -### `Manager` diff --git a/docs/concepts/encoding.md b/docs/concepts/encoding.md deleted file mode 100644 index 8113f63e9630..000000000000 --- a/docs/concepts/encoding.md +++ /dev/null @@ -1,3 +0,0 @@ -# Amnio Encoding - -TODO \ No newline at end of file diff --git a/docs/concepts/tx-msgs.md b/docs/concepts/tx-msgs.md deleted file mode 100644 index fde1963e3c2a..000000000000 --- a/docs/concepts/tx-msgs.md +++ /dev/null @@ -1,5 +0,0 @@ -# Transactions and Messages - -## Transactions - -## Messages From 8f9c36c250d2f0893e270943f10d3daaa9ab8d91 Mon Sep 17 00:00:00 2001 From: Gloria Zhao Date: Wed, 21 Aug 2019 14:33:26 -0700 Subject: [PATCH 066/196] remove modules readme --- docs/building-modules/README.md | 78 --------------------------------- 1 file changed, 78 deletions(-) delete mode 100644 docs/building-modules/README.md diff --git a/docs/building-modules/README.md b/docs/building-modules/README.md deleted file mode 100644 index 5b5743671751..000000000000 --- a/docs/building-modules/README.md +++ /dev/null @@ -1,78 +0,0 @@ -# Auth - -The `x/auth` modules is used for accounts - -See the [API docs](https://godoc.org/github.com/cosmos/cosmos-sdk/x/auth) - -See the [specification](https://github.com/cosmos/cosmos-sdk/tree/master/docs/spec/auth) - -# Bank - -The `x/bank` module is for transferring coins between accounts. - -See the [API docs](https://godoc.org/github.com/cosmos/cosmos-sdk/x/bank). - -See the [specification](https://github.com/cosmos/cosmos-sdk/tree/master/docs/spec/bank) - -# Stake - -The `x/staking` module is for Cosmos Delegated-Proof-of-Stake. - -See the [API docs](https://godoc.org/github.com/cosmos/cosmos-sdk/x/staking). - -See the -[specification](https://github.com/cosmos/cosmos-sdk/tree/master/docs/spec/staking) - -# Slashing - -The `x/slashing` module is for Cosmos Delegated-Proof-of-Stake. - -See the [API docs](https://godoc.org/github.com/cosmos/cosmos-sdk/x/slashing) - -See the -[specification](https://github.com/cosmos/cosmos-sdk/tree/master/docs/spec/slashing) - -# Distribution - -The `x/distribution` module is for distributing fees and inflation across bonded -stakeholders. - -See the [API docs](https://godoc.org/github.com/cosmos/cosmos-sdk/x/distribution) - -See the -[specification](https://github.com/cosmos/cosmos-sdk/tree/master/docs/spec/distribution) - -# Governance - -The `x/gov` module is for bonded stakeholders to make proposals and vote on them. - -See the [API docs](https://godoc.org/github.com/cosmos/cosmos-sdk/x/gov) - -See the -[specification](https://github.com/cosmos/cosmos-sdk/tree/master/docs/spec/governance) - -To keep up with the current status of IBC, follow and contribute to [ICS](https://github.com/cosmos/ics) - -# Crisis - -The `x/crisis` module is for halting the blockchain under certain circumstances. - -See the [API Docs](https://godoc.org/github.com/cosmos/cosmos-sdk/x/crisis) - -See the [specification](https://github.com/cosmos/cosmos-sdk/blob/master/docs/spec/crisis) - -# Mint - -The `x/mint` module is for flexible inflation rates and effect a balance between market liquidity and staked supply. - -See the [API Docs](https://godoc.org/github.com/cosmos/cosmos-sdk/x/mint) - -See the [specification](https://github.com/cosmos/cosmos-sdk/blob/master/docs/spec/mint) - -# Params - -The `x/params` module provides a globally available parameter store. - -See the [API Docs](https://godoc.org/github.com/cosmos/cosmos-sdk/x/params) - -See the [specification](https://github.com/cosmos/cosmos-sdk/blob/master/docs/spec/params) From 38c9ab9860350e819d095a62ea2b92a3e4188427 Mon Sep 17 00:00:00 2001 From: Gloria Zhao Date: Tue, 27 Aug 2019 19:44:42 -0700 Subject: [PATCH 067/196] cli.md comments --- docs/interfaces/cli.md | 36 ++++++++++++++++++++---------------- 1 file changed, 20 insertions(+), 16 deletions(-) diff --git a/docs/interfaces/cli.md b/docs/interfaces/cli.md index f1864a2593cb..ed15192968c5 100644 --- a/docs/interfaces/cli.md +++ b/docs/interfaces/cli.md @@ -6,7 +6,7 @@ ## Synopsis -This document describes how to create a commmand-line interface (CLI) for an application. A separate document for implementing a CLI for an SDK module can be found [here](#../building-modules/interfaces.md#cli). +This document describes how to create a commmand-line interface (CLI) for an [**application**](../basics/app-anatomy.md). A separate document for implementing a CLI for an SDK [**module**](../building-modules/intro.md) can be found [here](#../building-modules/interfaces.md#cli). - [Application CLI Components](#application-cli-components) - [Commands](#commands) @@ -19,7 +19,7 @@ One of the main entrypoints of an application is the command-line interface. Thi ### Cobra -There is no set way to create a CLI, but SDK modules all use the [Cobra Library](https://github.com/spf13/cobra). Building a CLI with Cobra entails defining commands, arguments, and flags. [**Commands**](#commands) understand the actions users wish to take, such as `tx` for creating a transaction and `query` for querying the application. Each command can also have nested subcommands, necessary for naming the specific transaction type. Users also supply **Arguments**, such as account numbers to send coins to, and [**Flags**](#flags) to modify various aspects of the commands, such as gas prices or which node to broadcast to. +There is no set way to create a CLI, but SDK modules typically use the [Cobra Library](https://github.com/spf13/cobra). Building a CLI with Cobra entails defining commands, arguments, and flags. [**Commands**](#commands) understand the actions users wish to take, such as `tx` for creating a transaction and `query` for querying the application. Each command can also have nested subcommands, necessary for naming the specific transaction type. Users also supply **Arguments**, such as account numbers to send coins to, and [**Flags**](#flags) to modify various aspects of the commands, such as gas prices or which node to broadcast to. Here is an example of a command a user might enter to interact with the nameservice CLI `nscli` in order to buy a name: @@ -28,17 +28,17 @@ nscli tx nameservice buy-name --gas auto --gas-prices ` into their command line. Commonly pre-configured flags include the `--node` to connect to and `--chain-id` of the blockchain the user wishes to interact with. +Flags are used to modify commands; developers can include them in a `flags.go` file with their CLI. Users can explicitly include them in commands or pre-configure them by entering a command in the format `appcli config ` into their command line. Commonly pre-configured flags include the `--node` to connect to and `--chain-id` of the blockchain the user wishes to interact with. A *persistent* flag (as opposed to a _local_ flag) added to a command transcends all of its children: subcommands will inherit the configured values for these flags. Additionally, all flags have default values when they are added to commands; some toggle an option off but others are empty values that the user needs to override to create valid commands. A flag can be explicitly marked as _required_ so that an error is automatically thrown if the user does not provide a value, but it is also acceptable to handle unexpected missing flags differently. -Every flag has a name the user types to use the flag. For example, the commonly used `--from` flag is declared as a constant in the SDK [flags](https://github.com/cosmos/cosmos-sdk/blob/master/client/flags/flags.go) file: +### Creating Flags + +Every flag has a name the user types to include the flag. For example, the commonly used `--from` flag is declared as a constant in the SDK [flags](https://github.com/cosmos/cosmos-sdk/blob/master/client/flags/flags.go) file: ```go const FlagFrom = "from" ``` -The flag can be added to a command `cmd`, adding a default value and description: +The flag can be added to a command `cmd` right after the command is created, adding a default value and description: ```go cmd.Flags().String(FlagFrom, "", "Name or address of private key with which to sign") ``` -The SDK client package includes a list of [flags](https://github.com/cosmos/cosmos-sdk/blob/master/client/flags/flags.go) that are commonly used across existing commands. +The SDK client package includes a list of [flags](https://github.com/cosmos/cosmos-sdk/blob/master/client/flags/flags.go) that are commonly used across existing commands. Developers are free to create their own custom flags, following this format. ### Root Command Flags -It is common to add a _persistent_ flag for `--chain-id`, the unique identifier of the blockchain the application pertains to, to the root command. Adding this flag makes sense as the chain ID should not be changing across commands in this application CLI. Here is what that looks like: +It is common to add a _persistent_ flag for `--chain-id`, the unique identifier of the blockchain the application pertains to, to the root command. Adding this flag can be done in the `main()` function. Adding this flag makes sense as the chain ID should not be changing across commands in this application CLI. Here is what that looks like: ```go rootCmd.PersistentFlags().String(client.FlagChainID, "", "Chain ID of tendermint node") @@ -228,7 +232,7 @@ rootCmd.PersistentFlags().String(client.FlagChainID, "", "Chain ID of tendermint ### Transaction and Query Flags -To create a transaction, users enter a `tx` command and provide several flags. The SDK `./client/flags` package [`PostCommands()`](https://github.com/cosmos/cosmos-sdk/blob/master/client/flags/flags.go#L85-L116) function adds a set of basic flags to every transaction command. For queries, the [`GetCommand()`](https://github.com/cosmos/cosmos-sdk/blob/master/client/flags/flags.go#L67-L82) function adds basic flags to query commands, such as the block `--height` to query from. +To create a transaction, users enter a `tx` command and provide several flags. The SDK `./client/flags` package [`PostCommands()`](https://github.com/cosmos/cosmos-sdk/blob/master/client/flags/flags.go#L85-L116) function adds a set of basic flags to every transaction command. For queries, the [`GetCommand()`](https://github.com/cosmos/cosmos-sdk/blob/master/client/flags/flags.go#L67-L82) function adds basic flags to query commands, such as the block `--height` to query from. For example, the following command creates a transaction to send 1000uatom from `sender-address` to `recipient-address`. The user is willing to pay 0.025uatom per unit gas but wants the transaction to be only generated offline (i.e. not broadcasted) and written, in JSON format, to the file `myUnsignedTx.json`. @@ -246,13 +250,13 @@ Here are the flags used: ## Configurations -The last function to define is, `initConfig`, which does exactly what it sounds like - initial configurations. To call this function, set it as a `PersistentPreRunE` function for the root command, so that it always executes before the main execution of the root command and any of its subcommands. `initConfig()` does the following: +The last function to define in `main.go` is `initConfig`, which does exactly what it sounds like - initialize configurations. To call this function, set it as a `PersistentPreRunE` function for the root command, so that it always executes before the main execution of the root command and any of its subcommands. `initConfig()` does the following: 1. Read in the `config.toml` file. This same file is edited through `config` commands. 2. Use the [Viper](https://github.com/spf13/viper) to read in configurations from the file and set them. 3. Set any persistent flags defined by the user: `--chain-id`, `--encoding`, `--output`, etc. -Here is an example of an `initConfig()` function from the nameservice tutorial CLI: +Here is an example of an `initConfig()` function from the [nameservice tutorial CLI](https://cosmos.network/docs/tutorial/entrypoint.html#nscli): ```go func initConfig(cmd *cobra.Command) error { From 19fee8127d6391e7fed91cfe1718ea44d7135fa1 Mon Sep 17 00:00:00 2001 From: Gloria Zhao Date: Tue, 27 Aug 2019 20:05:43 -0700 Subject: [PATCH 068/196] comments --- docs/interfaces/query-lifecycle.md | 43 ++++++++---------------------- docs/interfaces/rest.md | 4 +-- 2 files changed, 13 insertions(+), 34 deletions(-) diff --git a/docs/interfaces/query-lifecycle.md b/docs/interfaces/query-lifecycle.md index 6c69aa454e68..6c8a5b842620 100644 --- a/docs/interfaces/query-lifecycle.md +++ b/docs/interfaces/query-lifecycle.md @@ -60,7 +60,7 @@ The interactions from the users' perspective are a bit different, but the underl ### CLIContext -The first thing that is created in the execution of a CLI command is a `CLIContext`, while the REST Server directly provides a `CLIContext` for the REST Request handler. A [Context](../core/context.md) is an immutable object that stores all the data needed to process a request. In particular, a `CLIContext` stores the following: +The first thing that is created in the execution of a CLI command is a `CLIContext`, while the REST Server directly provides a `CLIContext` for the REST Request handler. A [Context](../core/context.md) is an immutable object that stores all the data needed to process a request on the user side. In particular, a `CLIContext` stores the following: * **Codec**: The [encoder/decoder](,./core/encoding.md) used by the application, used to marshal the parameters and query before making the Tendermint RPC request and unmarshal the returned response into a JSON object. * **Account Decoder**: The account decoder from the [`auth`](.../spec/auth) module, which translates `[]byte`s into accounts. @@ -76,11 +76,11 @@ The `CLIContext`'s primary role is to store data used during interactions with t ### Arguments and Route Creation -At this point in the lifecycle, the user has created a CLI command or HTTP Request with all of the data they wish to include in their `Query`. A `CLIContext` exists to assist in the rest of the `Query`'s journey. Now, the next step is to parse the command or request, extract the arguments, create a `queryRoute`, and encode everything. +At this point in the lifecycle, the user has created a CLI command or HTTP Request with all of the data they wish to include in their `Query`. A `CLIContext` exists to assist in the rest of the `Query`'s journey. Now, the next step is to parse the command or request, extract the arguments, create a `queryRoute`, and encode everything. These steps all happen on the user side within the interface they are interacting with. #### Parse Arguments -In this case, `Query` contains an [address](../core/accounts-fees.md) `delegatorAddress` as its only argument. However, the request can only contain `[]byte`s, as it will be relayed to a consensus engine node that has no inherent knowledge of the application types. Thus, the `CLIContext` `codec` is used to marshal the address as the type [`QueryDelegatorParams`](https://github.com/cosmos/cosmos-sdk/blob/master/x/staking/types/querier.go#L30-L38). All query arguments (e.g. the [`staking`](https://github.com/cosmos/cosmos-sdk/blob/master/docs/spec/staking) module also has [`QueryValidatorParams`](https://github.com/cosmos/cosmos-sdk/blob/master/x/staking/types/querier.go#L45-L53) and [`QueryBondsParams`](https://github.com/cosmos/cosmos-sdk/blob/master/x/staking/types/querier.go#L59-L69)) have their own types that the application `codec` understands how to encode and decode. The module [`querier`](.//building-modules/querier.md) declares these types and the application registers the `codec`s. +In this case, `Query` contains an [address](../core/accounts-fees.md) `delegatorAddress` as its only argument. However, the request can only contain `[]byte`s, as it will be relayed to a consensus engine (e.g. Tendermint Core) of a full-node that has no inherent knowledge of the application types. Thus, the `codec` of `CLIContext` is used to marshal the address as the type [`QueryDelegatorParams`](https://github.com/cosmos/cosmos-sdk/blob/master/x/staking/types/querier.go#L30-L38). All query arguments have their own types that the application `codec` understands how to encode and decode. For example, the [`staking`](https://github.com/cosmos/cosmos-sdk/blob/master/docs/spec/staking) module also has [`QueryValidatorParams`](https://github.com/cosmos/cosmos-sdk/blob/master/x/staking/types/querier.go#L45-L53) and [`QueryBondsParams`](https://github.com/cosmos/cosmos-sdk/blob/master/x/staking/types/querier.go#L59-L69). The module [`querier`](.//building-modules/querier.md) declares these types and the application registers the `codec`s. Here is what the code looks like for the CLI command: @@ -104,7 +104,7 @@ params := types.NewQueryDelegatorParams(delegatorAddr) #### Query Route Creation -Important to note is that there will never be a "query" object created for `Query`; the SDK actually takes a simpler approach. Instead of an object, all the full-node needs to process a query is its `route` which specifies exactly which module to route the query to and the name of this query type. The `route` will be passed to the application baseapp, then module, then [querier](../building-modules/querier.md), and each will understand the `route` and pass it to the appropriate next step. [baseapp](../core/baseapp.md#query-routing) will understand this query to be a `custom` query in the module `staking`, and the `staking` module querier supports the type `QueryDelegatorDelegations`. Thus, the route will be `"custom/staking/delegatorDelegations"`. +Important to note is that there will never be a "query" object created for `Query`; the SDK actually takes a simpler approach. Instead of an object, all the full-node needs to process a query is its `route` which specifies exactly which module to route the query to and the name of this query type. The `route` will be passed to the application `baseapp`, then module, then [querier](../building-modules/querier.md), and each will understand the `route` and pass it to the appropriate next step. [`baseapp`](../core/baseapp.md#query-routing) will understand this query to be a `custom` query in the module `staking`, and the `staking` module querier supports the type `QueryDelegatorDelegations`. Thus, the route will be `"custom/staking/delegatorDelegations"`. Here is what the code looks like: @@ -137,44 +137,23 @@ Read more about ABCI Clients and Tendermint RPC in the Tendermint documentation ## Application Query Handling -[baseapp](../core/baseapp.md) implements the ABCI [`Query()`](../core/baseapp.md#query) function and handles four different types of queries: `app`, `store`, `p2p`, and `custom`. The `queryRoute` is parsed such that the first string must be one of the four options, then the rest of the path is parsed within the subroutines handling each type of query. The first three types (`app`, `store`, `p2p`) are purely application-level and thus directly handled by Baseapp or the stores, but the `custom` query type requires Baseapp to route the query to a module's [querier](../building-modules/querier.md). +When a query is received by the full-node after it has been relayed from the underlying consensus engine, it is now being handled within an environment that understands application-specific types and has a copy of the state. [`baseapp`](../core/baseapp.md) implements the ABCI [`Query()`](../core/baseapp.md#query) function and handles four different types of queries: `app`, `store`, `p2p`, and `custom`. The `queryRoute` is parsed such that the first string must be one of the four options, then the rest of the path is parsed within the subroutines handling each type of query. The first three types (`app`, `store`, `p2p`) are purely application-level and thus directly handled by `baseapp` or the stores, but the `custom` query type requires `baseapp` to route the query to a module's [querier](../building-modules/querier.md). -Since `Query` is a custom query type from the `staking` module, Baseapp first parses the path, then uses the `QueryRouter` to retrieve the corresponding querier. The querier is responsible for recognizing this query, retrieving the appropriate values from the application's stores, and returning a response. Read more about queriers [here](../building-modules/querier.md). +Since `Query` is a custom query type from the `staking` module, `baseapp` first parses the path, then uses the `QueryRouter` to retrieve the corresponding querier, and routes the query to the module. The querier is responsible for recognizing this query, retrieving the appropriate values from the application's stores, and returning a response. Read more about queriers [here](../building-modules/querier.md). + +Once a result is received from the querier, `baseapp` begins the process of returning a response to the user. ## Response -Since `Query()` is an ABCI function, Baseapp returns the response as an [`abci.ResponseQuery`](https://tendermint.com/docs/spec/abci/abci.html#messages) type. The `CLIContext` `Query()` routine receives the response and, if `--trust-node` is toggled to `false` and a proof needs to be verified, the response is verified with the `CLIContext` [`verifyProof()`](https://github.com/cosmos/cosmos-sdk/blob/master/client/context/query.go#L136-L173) function before the response is returned. +Since `Query()` is an ABCI function, `baseapp` returns the response as an [`abci.ResponseQuery`](https://tendermint.com/docs/spec/abci/abci.html#messages) type. The `CLIContext` `Query()` routine receives the response and, if `--trust-node` is toggled to `false` and a proof needs to be verified, the response is verified with the `CLIContext` [`verifyProof()`](https://github.com/cosmos/cosmos-sdk/blob/master/client/context/query.go#L136-L173) function before the response is returned. ### CLI Response -The application [`codec`](../core/encoding.md) is used to unmarshal the response to a JSON and the `CLIContext` prints the output to the command line, applying any configurations such as `--indent`. - -Here is what the code looks like: - -```go -res, _, err := cliCtx.QueryWithData(route, bz) -var resp types.DelegationResponses -if err := cdc.UnmarshalJSON(res, &resp); err != nil { - return err -} -return cliCtx.PrintOutput(resp) -``` +The application [`codec`](../core/encoding.md) is used to unmarshal the response to a JSON and the `CLIContext` prints the output to the command line, applying any configurations such as `--indent`. To see the code, click [here](https://github.com/cosmos/cosmos-sdk/blob/master/x/staking/client/cli/query.go#L252-L293). ### REST Response -The [REST server](./rest.md#rest-server) uses the `CLIContext` to format the response properly, then uses the HTTP package to write the appropriate response or error. - -Here is what the code looks like: - -```go -res, height, err := cliCtx.QueryWithData(endpoint, bz) -if err != nil { - rest.WriteErrorResponse(w, http.StatusInternalServerError, err.Error()) - return -} -cliCtx = cliCtx.WithHeight(height) -rest.PostProcessResponse(w, cliCtx, res) -``` +The [REST server](./rest.md#rest-server) uses the `CLIContext` to format the response properly, then uses the HTTP package to write the appropriate response or error. To see the code, click [here](https://github.com/cosmos/cosmos-sdk/blob/master/x/staking/client/rest/utils.go#L115-L148). ## Next diff --git a/docs/interfaces/rest.md b/docs/interfaces/rest.md index bf4a010d0fa8..2b0e3ba2b633 100644 --- a/docs/interfaces/rest.md +++ b/docs/interfaces/rest.md @@ -7,7 +7,7 @@ ## Synopsis -This document describes how to create a REST interface for an SDK application. A separate document for creating a module REST interface can be found [here](#../module-interfaces.md#rest). +This document describes how to create a REST interface for an SDK **application**. A separate document for creating a [**module**](../building-modules/intro.md) REST interface can be found [here](#../module-interfaces.md#rest). - [Application REST Interface](#application-rest-interface) - [REST Server](#rest-server) @@ -42,7 +42,7 @@ Of the five, the only attribute that developers will need to configure is the ro ## Registering Routes -To include routes for each module in an application, the CLI must have some kind of function to Register Routes in its REST Server. This `RegisterRoutes()` function is utilized by the `ServeCommand` and must include routes for each of the application's modules. Since each module used by an SDK application implements a [`RegisterRESTRoutes`](../building-modules.md#rest) function, application developers simply use the Module Manager to call this function for each module. +To include routes for each module in an application, the CLI must have some kind of function to Register Routes in its REST Server. This `RegisterRoutes()` function is utilized by the `ServeCommand` and must include routes for each of the application's modules. Since each module used by an SDK application implements a [`RegisterRESTRoutes`](../building-modules.md/module-interfaces.md#rest) function, application developers simply use the Module Manager to call this function for each module. At the bare minimum, a `RegisterRoutes()` function should use the SDK client package `RegisterRoutes()` function to be able to route RPC calls, and instruct the application Module Manager to call `RegisterRESTRoutes()` for all of its modules: From c685c3467960045a6d93d6ef8d7c45243cbac929 Mon Sep 17 00:00:00 2001 From: Gloria Zhao Date: Tue, 27 Aug 2019 20:15:45 -0700 Subject: [PATCH 069/196] module-interfaces comments --- docs/building-modules/module-interfaces.md | 18 ++++++++---------- 1 file changed, 8 insertions(+), 10 deletions(-) diff --git a/docs/building-modules/module-interfaces.md b/docs/building-modules/module-interfaces.md index f1136e63d72c..300bd6b0817c 100644 --- a/docs/building-modules/module-interfaces.md +++ b/docs/building-modules/module-interfaces.md @@ -18,11 +18,11 @@ This document details how to build CLI and REST interfaces for a module. Example ## CLI -One of the main interfaces for an application is the [command-line interface](../interfaces/cli.md). This entrypoint created by the application developer will add commands from the application's modules to let end-users create [**messages**](./messages-and-queries.md) and [**queries**](./messages-and-queries.md). The CLI files are typically found in the `./x/moduleName/client/cli` folder. +One of the main interfaces for an application is the [command-line interface](../interfaces/cli.md). This entrypoint created by the application developer will add commands from the application's modules to let end-users create [**messages**](./messages-and-queries.md#messages) and [**queries**](./messages-and-queries.md#queries). The CLI files are typically found in the `./x/moduleName/client/cli` folder. ### Transaction Commands -[Transactions](../core/transactions.md) are created by users to wrap messages that trigger state changes when they get included in a valid block. Transaction commands typically have their own `tx.go` file in the module `./x/moduleName/client/cli` folder. The commands are specified in getter functions prefixed with `GetCmd` and include the name of the command. Here is an example from the nameservice tutorial: +[Transactions](../core/transactions.md) are created by users to wrap messages that trigger state changes when they get included in a valid block. Transaction commands typically have their own `tx.go` file in the module `./x/moduleName/client/cli` folder. The commands are specified in getter functions prefixed with `GetCmd` and include the name of the command. Here is an example from the [nameservice tutorial](https://cosmos.network/docs/tutorial/cli.html#transactions): ```go func GetCmdBuyName(cdc *codec.Codec) *cobra.Command { @@ -74,9 +74,6 @@ This getter function creates the command for the Buy Name transaction. It does t + Depending on what the user wants, the transaction is either generated offline or signed and broadcasted to the preconfigured node using `GenerateOrBroadcastMsgs()`. - **Flags.** Add any [flags](#flags) to the command. No flags were specified here, but all transaction commands have flags to provide additional information from the user (e.g. amount of fees they are willing to pay). These *persistent* [transaction flags](../interfaces/cli.md#flags) can be added to a higher-level command so that they apply to all transaction commands. - -#### GetTxCmd - Finally, the module needs to have a `GetTxCmd()`, which aggregates all of the transaction commands of the module. Often, each command getter function has its own file in the module's `cli` folder, and a separate `tx.go` file contains `GetTxCmd()`. Application developers wishing to include the module's transactions will call this function to add them as subcommands in their CLI. Here is the [`auth`](https://github.com/cosmos/cosmos-sdk/tree/67f6b021180c7ef0bcf25b6597a629aca27766b8/docs/spec/auth) `GetTxCmd()` function, which adds the `Sign` and `MultiSign` commands. An application using this module likely adds `auth` module commands to its root `TxCmd` command by calling `txCmd.AddCommand(authModuleClient.GetTxCmd())`. ```go @@ -98,7 +95,7 @@ func GetTxCmd(cdc *codec.Codec) *cobra.Command { ### Query Commands -[Queries](./messages-and-queries.md) allow users to gather information about the application or network state; they are routed by the application and processed by the module in which they are defined. Query commands typically have their own `query.go` file in the module `x/moduleName/client/cli` folder. Like transaction commands, they are specified in getter functions and have the prefix `GetCmdQuery`. Here is an example of a query command from the nameservice module: +[Queries](./messages-and-queries.md#queries) allow users to gather information about the application or network state; they are routed by the application and processed by the module in which they are defined. Query commands typically have their own `query.go` file in the module `x/moduleName/client/cli` folder. Like transaction commands, they are specified in getter functions and have the prefix `GetCmdQuery`. Here is an example of a query command from the [nameservice module CLI](https://cosmos.network/docs/tutorial/cli.html#queries): ```go func GetCmdWhois(queryRoute string, cdc *codec.Codec) *cobra.Command { @@ -137,9 +134,8 @@ This query returns the address that owns a particular name. The getter function + The `codec` is used to nmarshal the response and the `CLIContext` is used to print the output back to the user. - **Flags.** Add any [flags](#flags) to the command. -#### GetQueryCmd -Finally, the module also needs a `GetQueryCmd`, which aggregates all of the query commands of the module. Application developers wishing to include the module's queries will call this function to add them as subcommands in their CLI. Its structure is identical to the [`GetTxCmd`](#gettxcmd) command. +Finally, the module also needs a `GetQueryCmd`, which aggregates all of the query commands of the module. Application developers wishing to include the module's queries will call this function to add them as subcommands in their CLI. Its structure is identical to the `GetTxCmd` command shown above. ### Flags @@ -167,11 +163,13 @@ Since `PostCommands()` includes all of the basic flags required for a transactio ## REST -Applications are typically required to support web services that use HTTP requests (e.g. a web wallet like [Lunie.io](lunie.io)). Thus, application developers will also use REST Routes to route HTTP requests to the application's modules; these routes will be used by service providers. The module developer's responsibility is to define the REST client by defining [routes](#register-routes) for all possible [requests](#request-types) and [handlers](#request-handlers) for each of them. It's up to the module developer how to organize the REST interface files; there is typically a `rest.go` file found in the module's `./x/moduleName/client/rest` folder. +Applications typically support web services that use HTTP requests (e.g. a web wallet like [Lunie.io](lunie.io)). Thus, application developers will also use REST Routes to route HTTP requests to the application's modules; these routes will be used by service providers. The module developer's responsibility is to define the REST client by defining [routes](#register-routes) for all possible [requests](#request-types) and [handlers](#request-handlers) for each of them. It's up to the module developer how to organize the REST interface files; there is typically a `rest.go` file found in the module's `./x/moduleName/client/rest` folder. + +To support HTTP requests, the module developer needs to define possible request types, how to handle them, and provide a way to register them with a provided router. ### Request Types -Request types must be defined for all *transaction* requests. Conventionally, each request is named with the suffix `Req`, e.g. `SendReq` for a Send transaction. Each struct should include a base request [`baseReq`](../interfaces/rest.md#basereq), the name of the transaction, and all the arguments the user must provide for the transaction. +Request types, which define structured interactions from users, must be defined for all *transaction* requests. Users using this method to interact with an application will send HTTP Requests with the required fields in order to trigger state changes in the application. Conventionally, each request is named with the suffix `Req`, e.g. `SendReq` for a Send transaction. Each struct should include a base request [`baseReq`](../interfaces/rest.md#basereq), the name of the transaction, and all the arguments the user must provide for the transaction. Here is an example of a request to buy a name from the [nameservice](https://cosmos.network/docs/tutorial/rest.html) module: From cef7b4cdabbe0925d1bc97fca7138387289502e5 Mon Sep 17 00:00:00 2001 From: Gloria Zhao Date: Wed, 28 Aug 2019 09:06:33 -0700 Subject: [PATCH 070/196] Merge PR #4857: Add Context concept doc --- docs/core/context.md | 132 +++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 132 insertions(+) diff --git a/docs/core/context.md b/docs/core/context.md index e69de29bb2d1..64d9eb704276 100644 --- a/docs/core/context.md +++ b/docs/core/context.md @@ -0,0 +1,132 @@ +# Context + +## Synopsis + +This document details the SDK `Context` type. + +- [Context](#context) + - [Synopsis](#synopsis) + - [Prerequisites](#prerequisites) + - [Context Definition](#context-definition) + - [Go Context Package](#go-context-package) + - [Cache Wrapping](#cache-wrapping) + - [Next](#next) + +## Prerequisites + +- [Anatomy of an SDK Application](../basics/app-anatomy.md) +- [Lifecycle of a Transaction](../basics/tx-lifecycle.md) + +## Context Definition + +The SDK `Context` is a custom data structure that contains Go's stdlib [`context`](https://golang.org/pkg/context) +as its base, and has many additional types within its definition that are specific to the Cosmos SDK +and Tendermint. The `Context` is directly passed between methods and functions as an argument. +The `Context` is integral to tx processing in that it allows modules to easily access their respective +[state](./multistore.md) and retrieve transactional context such as the block header and gas meter. + +```go +type Context struct { + ctx context.Context + ms MultiStore + header abci.Header + chainID string + txBytes []byte + logger log.Logger + voteInfo []abci.VoteInfo + gasMeter GasMeter + blockGasMeter GasMeter + checkTx bool + minGasPrice DecCoins + consParams *abci.ConsensusParams + eventManager *EventManager +} +``` + +- **Context:** The base type is a Go [Context](https://golang.org/pkg/context), which is explained further in the [Go Context Package](#go-context-package) section below. +- **Multistore:** Every application's `BaseApp` contains a [`CommitMultiStore`](./multistore.md) which is provided when a `Context` is created. Calling the `KVStore()` and `TransientStore()` methods allows modules to fetch their +respective `KVStore` using their unique `StoreKey`. +- **ABCI Header:** The [header](https://tendermint.com/docs/spec/abci/abci.html#header) is an ABCI type. It carries important information about the state of the blockchain, such as block height and proposer of the current block. +- **Chain ID:** The unique identification number of the blockchain a block pertains to. +- **Transaction Bytes:** The `[]byte` representation of a transaction being processed using the context. Every transaction is processed by various parts of the SDK and consensus engine (e.g. Tendermint) throughout its [lifecycle](../basics/tx-lifecycle.md), some of which to not have any understanding of transaction types. Thus, transactions are marshaled into the generic `[]byte` type using some kind of [encoding format](./encoding.md) such as [Amino](./amino.md). +- **Logger:** A [Logger](https://github.com/tendermint/tendermint/blob/master/libs/log/logger.go) from the Tendermint libraries. Learn more about logs [here](https://tendermint.com/docs/tendermint-core/how-to-read-logs.html#how-to-read-logs). Modules call this method to create their own unique module-specific logger. +- **VoteInfo:** A list of the ABCI type [`VoteInfo`](https://tendermint.com/docs/spec/abci/abci.html#voteinfo), which includes the name of a validator and a boolean indicating whether they have signed the block. +- **Gas Meters:** Specifically, a `gasMeter` for the transaction currently being processed using the context and a `blockGasMeter` for the entire block it belongs to. Users specify how much in fees they wish to pay for the execution of their transaction; these gas meters keep track of how much [gas](../basics/accounts-fees-gas.md) has been used in the transaction or block so far. If the gas meter runs out, execution halts. +- **CheckTx Mode:** A boolean value indicating whether a transaction should be processed in `CheckTx` or `DeliverTx` mode. +- **Min Gas Price:** The minimum [gas](../basics/accounts-fees-gas.md) price a node is willing to take in order to include a transaction in its block. This price is a local value configured by each node individually. +- **Consensus Params:** The ABCI type [Consensus Parameters](https://tendermint.com/docs/spec/abci/apps.html#consensus-parameters), which enforce certain limits for the blockchain, such as maximum gas for a block. +- **Event Manager:** The event manager allows any caller with access to a `Context` to emit [`Events`](https://github.com/cosmos/cosmos-sdk/blob/master/types/events.go). Modules may define module specific +`Events` by defining various `Types` and `Attributes` or use the common definitions found in `types/`. Clients +can subscribe or query for these `Events`. These `Events` are collected throughout `DeliverTx`, `BeginBlock`, +and `EndBlock` and are returned to Tendermint for indexing. For example: + +```go +ctx.EventManager().EmitEvent(sdk.NewEvent( + sdk.EventTypeMessage, + sdk.NewAttribute(sdk.AttributeKeyModule, types.AttributeValueCategory)), +) +``` + +## Go Context Package + +A basic `Context` is defined in the [Golang Context Package](https://golang.org/pkg/context). A `Context` +is an immutable data structure that carries request-scoped data across APIs and processes. Contexts +are also designed to enable concurrency and to be used in goroutines. + +Contexts are intended to be **immutable**; they should never be edited. Instead, the convention is +to create a child context from its parent using a `With` function. For example: + +``` go +childCtx = parentCtx.WithBlockHeader(header) +``` + +The [Golang Context Package](https://golang.org/pkg/context) documentation instructs developers to +explicitly pass a context `ctx` as the first argument of a process. + +## Cache Wrapping + +The `Context` contains a `MultiStore`, which allows for cache-wrapping functionality: a `CacheMultiStore` +where each `KVStore` is is wrapped with an ephemeral cache. Processes are free to write changes to +the `CacheMultiStore`, then write the changes back to the original state or disregard them if something +goes wrong. The pattern of usage for a Context is as follows: + +1. A process receives a Context `ctx` from its parent process, which provides information needed to + perform the process. +2. The `ctx.ms` is [**cache wrapped**](./multistore.md), i.e. a cached copy of the [multistore](./multistore.md) +is made so that the process can make changes to the state as it executes, without changing the original`ctx.ms` state. +3. The process may read and write from `ctx` as it is executing. It may call a subprocess and pass +`ctx` to it as needed. +4. When a subprocess returns, it checks if the result is a success or failure. If a failure, nothing +needs to be done - the cache wrapped `ctx` is simply discarded. If successful, the changes made to +the cache-wrapped `MultiStore` can be committed to the original `ctx.ms` via `Write()`. + +For example, here is a snippet from the [`runTx`](./baseapp.md#runtx-and-runmsgs) function in +[`baseapp`](./baseapp.md): + +```go +runMsgCtx, msCache := app.cacheTxContext(ctx, txBytes) +result = app.runMsgs(runMsgCtx, msgs, mode) +result.GasWanted = gasWanted + +if mode != runTxModeDeliver { + return result +} + +if result.IsOK() { + msCache.Write() +} +``` + +Here is the process: + +1. Prior to calling `runMsgs` on the message(s) in the transaction, it uses `app.cacheTxContext()` +to cache-wrap the context and multistore. +2. The cache-wrapped context, `runMsgCtx`, is used in `runMsgs` to return a result. +3. If the process is running in [`checkTxMode`](./baseapp.md#checktx), there is no need to write the +changes - the result is returned immediately. +4. If the process is running in [`deliverTxMode`](./baseapp.md#delivertx) and the result indicates +a successful run over all the messages, the cached multistore is written back to the original. + +## Next + +Read about the next core concept. From d96abfd6d3839992424439032b5a9386cd452fee Mon Sep 17 00:00:00 2001 From: gamarin Date: Mon, 9 Sep 2019 14:08:01 +0200 Subject: [PATCH 071/196] working --- docs/building-modules/genesis.md | 4 ++ docs/building-modules/intro.md | 5 +-- docs/building-modules/messages-and-queries.md | 13 ++++++ docs/building-modules/module-manager.md | 45 ++++++++++++++++++- 4 files changed, 63 insertions(+), 4 deletions(-) diff --git a/docs/building-modules/genesis.md b/docs/building-modules/genesis.md index 2667616ff802..c877e33debff 100644 --- a/docs/building-modules/genesis.md +++ b/docs/building-modules/genesis.md @@ -2,4 +2,8 @@ ## `GenesisState` +## `DefaultGenesis` + +## `InitGenesis` + ## `ValidateGenesis` \ No newline at end of file diff --git a/docs/building-modules/intro.md b/docs/building-modules/intro.md index 403eb755a2a2..7eefb949160c 100644 --- a/docs/building-modules/intro.md +++ b/docs/building-modules/intro.md @@ -11,8 +11,7 @@ Modules define most of the logic of any SDK application. Developers compose modu - [Role of Modules in an SDK application](#role-of-modules-in-an-sdk-application) - [How to Approach Building Modules as a Developer](#how-to-approach-building-modules-as-a-developer) -- [Application Module Interface](#application-module-interface) -- [Module Manager](#module-manager) +- [Main Components of SDK Modules](#main-components-of-sdk-modules) ## Role of Modules in an SDK Application @@ -77,7 +76,7 @@ While there is no definitive guidelines for writing modules, here are some impor - **Specialization**: A direct consequence of the **composability** feature is that modules should be **specialized**. Developers should carefully establish the scope of their module and not batch multiple functionalities into the same module. This separation of concern enables modules to be re-used in other projects and improves the upgradability of the application. **Specialization** also plays an important role in the [object-capabilities model](../core/ocap.md) of the Cosmos SDK. - **Capabilities**: Most modules need to read and/or write to the store(s) of other modules. However, in an open-source environment, it is possible for some module to be malicious. That is why module developers need to carefully think not only about how their module interracts with other modules, and how to give access to the module's store(s). The Cosmos SDK takes a capabilities-oriented approach to inter-module security. This means that each store defined by a module is accessed by a `key`, which is held by the module's [`keeper`](./keeper.md). This `keeper` defines how to access the store(s) and under what conditions. Access to the module's store(s) is done by passing a reference to the module's `keeper`. -## Main Components of SDK Module +## Main Components of SDK Modules Modules are by convention defined in the `.x/` subfolder (e.g. the `bank` module will be defined in the `./x/bank` folder). They generally share the same core components: diff --git a/docs/building-modules/messages-and-queries.md b/docs/building-modules/messages-and-queries.md index 55c14281b99a..211c09527098 100644 --- a/docs/building-modules/messages-and-queries.md +++ b/docs/building-modules/messages-and-queries.md @@ -1,5 +1,18 @@ # Messages and Queries +## Pre-requisite Reading + +- [Introduction to SDK Modules](./intro.md) + +## Synopsis + +`Message`s and `Queries` are the two primary objects handled by modules. Most of the core components defined in a module, like `handler`s, `keeper`s and `querier`s, exist to process `message`s and `queries`. + +- [Messages](#messages) +- [Queries](#queries) + ## Messages +`Message`s are objects defined by modules, instantiated by end-users and included in [transactions](../core/transactions.md) in order to modify the state. + ## Queries \ No newline at end of file diff --git a/docs/building-modules/module-manager.md b/docs/building-modules/module-manager.md index d96760f69429..6aefacc0d71c 100644 --- a/docs/building-modules/module-manager.md +++ b/docs/building-modules/module-manager.md @@ -8,6 +8,15 @@ Cosmos SDK modules need to implement the [`AppModule` interfaces](#application-module-interfaces), in order to be managed by the application's [module manager](#module-manager). The module manager plays an important role in [`message` and `query` routing](../core/baseapp.md#routing), and allows the application developer to set the order of execution of a variety of functions like [`BeginBlocker` and `EndBlocker`](../basics/app-anatomy.md#begingblocker-and-endblocker). +- [Application Module Interfaces](#application-module-interfaces) + + [`AppModuleBasic`](#appmodulebasic) + + [`AppModuleGenesis`](#appmodulegenesis) + + [`AppModule`](#appmodule) + + [Implementing the Application Module Interfaces](#implementing-the-application-module-interfaces) +- [Module Managers](#module-managers) + + [`BasicManager`](#basicmanager) + + [`Manager`](#manager) + ## Application Module Interfaces [Application module interfaces](https://github.com/cosmos/cosmos-sdk/blob/master/types/module/module.go) exist to facilitate the composition of modules together to form a functional SDK application. There are 3 main application module interfaces: @@ -145,8 +154,42 @@ type BasicManager map[string]AppModuleBasic It implements the following methods: - `NewBasicManager(modules ...AppModuleBasic)`: Constructor function. It takes a list of the application's `AppModuleBasic` and builds a new `BasicManager`. This function is generally called in the `init()` function of [`app.go`](../basics/app-anatomy.md#core-application-file) to quickly initialize the independent elements of the application's modules (click [here](https://github.com/cosmos/gaia/blob/master/app/app.go#L59-L74) to see an example). -- `RegisterCodec(cdc *codec.Codec)`: Registers the [`codec`s](../core/encoding.md) of each of the application's `AppModuleBasic`. This function is usually early on in the [application's construction](../basics/app-anatomy.md#constructor) +- `RegisterCodec(cdc *codec.Codec)`: Registers the [`codec`s](../core/encoding.md) of each of the application's `AppModuleBasic`. This function is usually called early on in the [application's construction](../basics/app-anatomy.md#constructor). +- `DefaultGenesis()`: Provides default genesis information for modules in the application by calling the [`DefaultGenesis()`](./genesis.md#defaultgenesis) function of each module. It is used to construct a default genesis file for the application. +- `ValidateGenesis(genesis map[string]json.RawMessage)`: Validates the genesis information modules by calling the [`ValidateGenesis()`](./genesis.md#validategenesis) function of each module. +- `RegisterRESTRoutes(ctx context.CLIContext, rtr *mux.Router)`: Registers REST routes for modules by calling the [`RegisterRESTRoutes`](./module-interfaces.md#register-routes) function of each module. This function is usually called function from the `main.go` function of the [application's command-line interface](../interfaces/cli.md). +- `AddTxCommands(rootTxCmd *cobra.Command, cdc *codec.Codec)`: Adds modules' transaction commands to the application's [`rootTxCommand`](../interfaces/cli.md#transaction-commands). This function is usually called function from the `main.go` function of the [application's command-line interface](../interfaces/cli.md). +- `AddQueryCommands(rootQueryCmd *cobra.Command, cdc *codec.Codec)`: Adds modules' query commands to the application's [`rootQueryCommand`](../interfaces/cli.md#query-commands). This function is usually called function from the `main.go` function of the [application's command-line interface](../interfaces/cli.md). ### `Manager` +The [`Manager`](https://github.com/cosmos/cosmos-sdk/blob/master/types/module/module.go#L203-L209) is a structure that lists all the `AppModule` of an application, and defines the order of execution between several key components of these modules: + +```go +type Manager struct { + Modules map[string]AppModule + OrderInitGenesis []string + OrderExportGenesis []string + OrderBeginBlockers []string + OrderEndBlockers []string +} +``` + +The module manager is used throughout the application whenever an action on a collection of module is required. It implements the following methods: + +- `NewManager(modules ...AppModule)`: Constructor function. It takes a list of the application's `AppModule`s and builds a new `Manager`. It is generally called from the application's main [constructor function](../basics/app-anatomy.md#constructor-function). +- `SetOrderInitGenesis(moduleNames ...string)`: Sets the order in which the [`InitGenesis`](./genesis.md#initgenesis) function of each module will be called when the application is first started. This function is generally called from the application's main [constructor function](../basics/app-anatomy.md#constructor-function). +- `SetOrderExportGenesis(moduleNames ...string)`: Sets the order in which the [`ExportGenesis`](./genesis.md#exportgenesis) function of each module will be called in case of an export. This function is generally called from the application's main [constructor function](../basics/app-anatomy.md#constructor-function). +- `SetOrderBeginBlockers(moduleNames ...string)`: Sets the order in which the `BeginBlock()` function of each module will be called at the beginning of each block. This function is generally called from the application's main [constructor function](../basics/app-anatomy.md#constructor-function). +- `SetOrderEndBlockers(moduleNames ...string)`: Sets the order in which the `EndBlock()` function of each module will be called at the beginning of each block. This function is generally called from the application's main [constructor function](../basics/app-anatomy.md#constructor-function). +- `RegisterInvariants(ir sdk.InvariantRegistry)`: Registers the [invariants](./invariants.md) of each module. +- `RegisterRoutes(router sdk.Router, queryRouter sdk.QueryRouter)`: Registers module routes to the application's `router`, in order to route [`message`s](./messages-and-queries.md#messages) to the appropriate [`handler`](./handler.md), and module query routes to the application's `queryRouter`, in order to route [`queries`](./messages-and-queries.md#queries) to the appropriate [`querier`](./querier.md). +- `InitGenesis(ctx sdk.Context, genesisData map[string]json.RawMessage)`: Calls the [`InitGenesis`](./genesis.md#initgenesis) function of each module when the application is first started, in the order defined in `OrderInitGenesis`. Returns an `abci.ResponseInitChain` to the underlying consensus engine, which can contain validator updates. +- `ExportGenesis(ctx sdk.Context)`: Calls the [`ExportGenesis`](./genesis.md#exportgenesis) function of each module, in the order defined in `OrderExportGenesis`. The export constructs a genesis file from a previously existing state, and is mainly used when a hard-fork upgrade of the chain is required. +- `BeginBlock(ctx sdk.Context, req abci.RequestBeginBlock)`: At the beginning of each block, this function calls the [`BeginBlock`] function of each module, in the order defined in `OrderBeginBlockers`. It creates a child [context](../core/context.md) with an event manager to aggregate [events](./events.md) emitted from all modules. The function returns an `abci.ResponseBeginBlock` which contains the aforementioned events. +- `EndBlock(ctx sdk.Context, req abci.RequestEndBlock)`: At the end of each block, this function calls the [`EndBlock`] function of each module, in the order defined in `OrderEndBlockers`. It creates a child [context](../core/context.md) with an event manager to aggregate [events](./events.md) emitted from all modules. The function returns an `abci.ResponseEndBlock` which contains the aforementioned events, as well as validator set updates (if any). + +## Next + +Learn more about [`message`s and `queries`](./messages-and-queries.md). \ No newline at end of file From f38fd487976768e7b2e92ad180c7be358135ef0d Mon Sep 17 00:00:00 2001 From: gamarin Date: Mon, 9 Sep 2019 18:35:48 +0200 Subject: [PATCH 072/196] working --- docs/building-modules/messages-and-queries.md | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/docs/building-modules/messages-and-queries.md b/docs/building-modules/messages-and-queries.md index 211c09527098..f61e71a796a8 100644 --- a/docs/building-modules/messages-and-queries.md +++ b/docs/building-modules/messages-and-queries.md @@ -13,6 +13,14 @@ ## Messages -`Message`s are objects defined by modules, instantiated by end-users and included in [transactions](../core/transactions.md) in order to modify the state. +`Message`s are objects whose end-goal is to trigger state-transitions. They are wrapped in [transactions], which may contain one or multiple of them. + +When a transaction is relayed from the underlying consensus engine to the SDK application, it is first decoded by [`baseapp`](../basics/baseapp.md). Then, each `message` contained in the transaction is extracted and routed to the appropriate module so that it can be processed by the module's [`handler`](./handler.md). For a more detailed explanation of the lifecycle of a transaction, click [here](../basics/tx-lifecycle.md). + +Defining `message`s is the responsibility of module developers. Typically, they are defined in a `types/msgs.go` file inside the module's folder. `message`s need to implement the [`Msg`](https://github.com/cosmos/cosmos-sdk/blob/master/types/tx_msg.go#L7-L29) interface, which contains the following methods: + +- `Route() string`: Name of the route for this message. Typically all `message`s in a module have the same route, which is most often the module's name. +- `Type() string`: Type of the message, used primarly in [events](./events.md). This should return a message-specific `string`, typically the denomination of the message itself. +- `ValidateBasic() Error`: ## Queries \ No newline at end of file From c7ddc7065013e00af14224ada434f30f0e9d867c Mon Sep 17 00:00:00 2001 From: gamarin Date: Tue, 10 Sep 2019 14:56:46 +0200 Subject: [PATCH 073/196] finish messages and queries --- docs/building-modules/messages-and-queries.md | 49 +++++++++++++++++-- docs/core/baseapp.md | 6 +-- 2 files changed, 48 insertions(+), 7 deletions(-) diff --git a/docs/building-modules/messages-and-queries.md b/docs/building-modules/messages-and-queries.md index f61e71a796a8..83c448263901 100644 --- a/docs/building-modules/messages-and-queries.md +++ b/docs/building-modules/messages-and-queries.md @@ -15,12 +15,53 @@ `Message`s are objects whose end-goal is to trigger state-transitions. They are wrapped in [transactions], which may contain one or multiple of them. -When a transaction is relayed from the underlying consensus engine to the SDK application, it is first decoded by [`baseapp`](../basics/baseapp.md). Then, each `message` contained in the transaction is extracted and routed to the appropriate module so that it can be processed by the module's [`handler`](./handler.md). For a more detailed explanation of the lifecycle of a transaction, click [here](../basics/tx-lifecycle.md). +When a transaction is relayed from the underlying consensus engine to the SDK application, it is first decoded by [`baseapp`](../basics/baseapp.md). Then, each `message` contained in the transaction is extracted and routed to the appropriate module via `baseapp`'s `router` so that it can be processed by the module's [`handler`](./handler.md). For a more detailed explanation of the lifecycle of a transaction, click [here](../basics/tx-lifecycle.md). -Defining `message`s is the responsibility of module developers. Typically, they are defined in a `types/msgs.go` file inside the module's folder. `message`s need to implement the [`Msg`](https://github.com/cosmos/cosmos-sdk/blob/master/types/tx_msg.go#L7-L29) interface, which contains the following methods: +Defining `message`s is the responsibility of module developers. Typically, they are defined in a `types/msgs.go` file inside the module's folder. The `message`'s type definition usually includes a list of parameters needed to process the message that will be provided by end-users when they want to create a new transaction containing said `message`. + +```go +// Example of a message type definition + +type MsgSubmitProposal struct { + Content Content `json:"content" yaml:"content"` + InitialDeposit sdk.Coins `json:"initial_deposit" yaml:"initial_deposit"` + Proposer sdk.AccAddress `json:"proposer" yaml:"proposer"` +} +``` + +The `Msg` is typically accompagnied by a standard constructor function, that is called from one of the [module's interface](./module-interface). `message`s also need to implement the [`Msg`](https://github.com/cosmos/cosmos-sdk/blob/master/types/tx_msg.go#L7-L29) interface, which contains the following methods: - `Route() string`: Name of the route for this message. Typically all `message`s in a module have the same route, which is most often the module's name. - `Type() string`: Type of the message, used primarly in [events](./events.md). This should return a message-specific `string`, typically the denomination of the message itself. -- `ValidateBasic() Error`: +- `ValidateBasic() Error`: This method is called by `baseapp` very early in the processing of the `message`, in order to discard obviously invalid messages. `ValidateBasic` should only include *stateless* checks, i.e. checks that do not require access to the state. This usually consists in checking that the message's parameters are correctly formatted and valid (i.e. that the `amount` is strictly positive for a transfer). +- `GetSignBytes() []byte`: Return the canonical byte representation of the message. Used to generate a signature. +- `GetSigners() []AccAddress`: Return the list of signers. The SDK will make sure that each `message` contained in a transaction is signed by all the signers listed in the list returned by this method. + +You can see an example implementation of a `message` from the *nameservice tutorial* [here](https://github.com/cosmos/cosmos-sdk/blob/master/types/tx_msg.go). + +## Queries + +A `query` is a request for information made by end-users of applications through an interface and processed by a full-node. A `query` is received by a full-node through its consensus engine and relayed to the application via the ABCI. It is then routed to the appropriate module via `baseapp`'s `queryrouter` so that it can be processed by the module's [`querier`](./querier.md). For a deeper look at the lifecycle of a `query`, click [here](../interfaces/query-lifecycle.md). + +Contrary to `message`s, there is usually no specific `query` object defined by module developers. Instead, the SDK takes the simpler approach of using a simple `path` to define each `query`. The `path` contains the `query` type and all the arguments needed in order to process it. For most module queries, the `path` should look like the following: + +``` +queryCategory/queryRoute/queryType/arg1/arg2/... +``` + +where: + +- `queryCategory` is the category of the `query`, typically `custom` for module queries. It is used to differentiate between different kinds of queries within `baseapp`'s [`Query` method](../core/baseapp.md#query). +- `queryRoute` is used by `baseapp`'s [`queryRouter`](../core/baseapp.md#query-routing) to map the `query` to its module. Usually, `queryRoute` should be the name of the module. +- `queryType` is used by the module's [`querier`](./querier.md) to map the `query` to the appropriate `querier function` within the module. +- `args` are the actual arguments needed to process the `query`. They are filled out by the end-user. + +The `path` for each `query` must be defined by the module developer in the module's [command-line interface file](./module-interfaces.md#query-commands).Overall, there are 3 mains components module developers need to implement in order to make the subset of the state defined by their module queryable: + +- A [`querier`](./querier.md), to process the `query` once it has been [routed to the module](../core/baseapp.md#query-routing). +- [Query commands](./module-interfaces.md#query-commands) in the module's CLI file, where the `path` for each `query` is specified. +- `query` return types. Typically defined in a file `types/querier.go`, they specify the result type of each of the module's `queries`. These custom types must implement the `String()` method of [`fmt.Stringer`](https://golang.org/pkg/fmt/#Stringer). See an example of `query` return types from the [nameservice tutorial](https://github.com/cosmos/sdk-application-tutorial/blob/master/x/nameservice/internal/types/querier.go). + +## Next -## Queries \ No newline at end of file +Learn about [`handler`s](./handler.go). \ No newline at end of file diff --git a/docs/core/baseapp.md b/docs/core/baseapp.md index 6c3d2dd9e506..42d0ae99000e 100644 --- a/docs/core/baseapp.md +++ b/docs/core/baseapp.md @@ -179,7 +179,7 @@ The application's `router` is initilalized with all the routes using the applica ### Query Routing -Similar to `message`s, [`queries`](../building-modules/messages-and-queries.md#queries) need to be routed to the appropriate module's [querier](../building-modules/querier.md). To do so, `baseapp` holds a [`query router`](https://github.com/cosmos/cosmos-sdk/blob/master/baseapp/queryrouter.go), which maps `paths` (`string`) to the appropriate module `querier`. Usually, the `path` is the name of the module. +Similar to `message`s, [`queries`](../building-modules/messages-and-queries.md#queries) need to be routed to the appropriate module's [querier](../building-modules/querier.md). To do so, `baseapp` holds a [`query router`](https://github.com/cosmos/cosmos-sdk/blob/master/baseapp/queryrouter.go), which maps module names to module `querier`s. The `queryRouter` is called during the initial stages of `query` processing, which is done via the [`Query` ABCI message](#query). Just like the `router`, the `query router` is initilalized with all the query routes using the application's [module manager](../building-modules/module-manager.md), which itself is initialized with all the application's modules in the application's [constructor](../basics/app-anatomy.md#app-constructor). @@ -317,12 +317,12 @@ The [`Info` ABCI message](https://tendermint.com/docs/app-dev/abci-spec.html#inf The [`Query` ABCI message](https://tendermint.com/docs/app-dev/abci-spec.html#query) is used to serve queries received from the underlying consensus engine, including queries received via RPC like Tendermint RPC. It is the main entrypoint to build interfaces with the application. The application must respect a few rules when implementing the `Query` method, which are outlined [here](https://tendermint.com/docs/app-dev/abci-spec.html#query). -The `baseapp` implementation of the `Query(req abci.RequestQuery)` method is a simple dispatcher serving 4 main categories of queries: +Each `query` comes with a `path`, which contains multiple `string`s. By convention, the first element of the `path` (`path[0]`) contains the category of `query` (`app`, `p2p`, `store` or `custom`). The `baseapp` implementation of the `Query(req abci.RequestQuery)` method is a simple dispatcher serving these 4 main categories of queries: - Application-related queries like querying the application's version, which are served via the `handleQueryApp` method. - Direct queries to the multistore, which are served by the `handlerQueryStore` method. These direct queryeis are different from custom queries which go through `app.queryRouter`, and are mainly used by third-party service provider like block explorers. - P2P queries, which are served via the `handleQueryP2P` method. These queries return either `app.addrPeerFilter` or `app.ipPeerFilter` that contain the list of peers filtered by address or IP respectively. These lists are first initialized via `options` in `baseapp`'s [constructor](#constructor). -- Custom queries, which encompass most queries, are served via the `handleQueryCustom` method. The `handleQueryCustom` cache-wraps the multistore before using the `queryRoute` obtained from [`app.queryRouter`](#query-routing) to map the query to the appropriate module's [`querier`](../building-modules/querier.md). +- Custom queries, which encompass most [module queries](../building-modules/messages-and-queries.md#queries), are served via the [`handleQueryCustom`](https://github.com/cosmos/cosmos-sdk/blob/master/baseapp/abci.go#L395-L453) method. The `handleQueryCustom` first cache-wraps the multistore. Then, it uses the second component of the path (`path[1]`) to retrieve the `queryRoute` from [`app.queryRouter`](#query-routing) to map the query to the appropriate module's [`querier`](../building-modules/querier.md). The following elements of the `path` (`path[2:]`) are passed to the `querier` to properly process the query. Finally, the result of the `querier`'s execution is returned via `abci.ResponseQuery`. ## Next From f7b6fc344a4ea9e25eac67de123cabb4d6c31cf2 Mon Sep 17 00:00:00 2001 From: gamarin Date: Tue, 10 Sep 2019 17:03:25 +0200 Subject: [PATCH 074/196] handler --- docs/building-modules/handler.md | 56 +++++++++++++++++++++++++++++++- docs/core/baseapp.md | 6 ++-- 2 files changed, 58 insertions(+), 4 deletions(-) diff --git a/docs/building-modules/handler.md b/docs/building-modules/handler.md index f8fc820df8de..77b2189f9fbb 100644 --- a/docs/building-modules/handler.md +++ b/docs/building-modules/handler.md @@ -1 +1,55 @@ -# Handlers \ No newline at end of file +# Handlers + +## Pre-requisite Reading + +- [Module Manager](./module-manager.md). +- [Messages and Queries](./messages-and-queries.md) + +## Synopsis + +A `Handler` designates a function that processes [`message`s](./messages-and-queries.md#messages). `handler`s are specific to the module in which they are defined, and only process `message`s defined within said module. They are called from `baseapp` during [`DeliverTx`](../core/baseapp.md#delivertx). + +## `handler` type + +The [`handler` type](https://github.com/cosmos/cosmos-sdk/blob/master/types/handler.go#L4) defined in the Cosmos SDK specifies the typical structure of a `handler` function: + +```go +type Handler func(ctx Context, msg Msg) Result +``` + +Let us break it down: + +- The [`msg`](./messages-and-queries.md#messages) is the actual object being processed. +- The [`Context`](../core/context.md) contains all the necessary information needed to process the `msg`, as well as a cache-wrapped copy of the latest state. If the `msg` is succesfully processed, the modified version of the temporary state contained in the `ctx` will be written to the main state. +- The [`Result`](https://github.com/cosmos/cosmos-sdk/blob/master/types/result.go#L14-L38) returned to `baseapp`, which contains (among other things) information on the execution of the `handler`, [`gas`](../basics/accounts-fees-gas.md#gas) consumption and [`events`](./events.md). + +## Implementation of a module's `handler`s + +Module `handler`s are typically implemented in a `handler.go` file inside the module's folder. The [module manager](./module-manager.md) is used to add the module's `handler`s to the [application's `router`](../core/baseapp.md#message-routing) via the `NewHandler()` method. Typically, the manager's `NewHandler` method simply calls a `NewHandler()` method defined in `handler.go`, which looks like the following: + +```go +func NewHandler(keeper Keeper) sdk.Handler { + return func(ctx sdk.Context, msg sdk.Msg) sdk.Result { + switch msg := msg.(type) { + case MsgType1: + return handleMsgType1(ctx, keeper, msg) + case MsgType2: + return handleMsgType2(ctx, keeper, msg) + default: + errMsg := fmt.Sprintf("Unrecognized nameservice Msg type: %v", msg.Type()) + return sdk.ErrUnknownRequest(errMsg).Result() + } + } +} +``` + +This simple switch returns a `handler` function specific to the type of the received `message`. These `handler` functions are the ones that actually process `message`s, and usually follow the following 2 steps: + +- First, they perform *stateful* checks to make sure the `message` is valid. At this stage, the `message`'s `ValidateBasic()` method has already been called, meaning *stateless* checks on the message (like making sure parameters are correctly formatted) have already been performed. Checks performed in the `handler` can be more expensive and require access to the state. For example, a `handler` for a `transfer` message might check that the sending account has enough funds to actually perform the transfer. To access the state, the `handler` needs to call the [`keeper`'s](./keeper.md) getter functions. +- Then, if the checks are successfull, the `handler` calls the [`keeper`'s](./keeper.md) setter functions to actually perform the state transition. + +For more information, see this [example implementation of a `handler` function](https://github.com/cosmos/sdk-application-tutorial/blob/master/x/nameservice/handler.go) from the nameservice tutorial. + +## Next + +Learn about [queriers](./querier.md). \ No newline at end of file diff --git a/docs/core/baseapp.md b/docs/core/baseapp.md index 42d0ae99000e..b0ef299e363b 100644 --- a/docs/core/baseapp.md +++ b/docs/core/baseapp.md @@ -175,7 +175,7 @@ When messages and queries are received by the application, they must be routed t [`Message`s](#../building-modules/messages-and-queries.md#messages) need to be routed after they are extracted from transactions, which are sent from the underlying Tendermint engine via the [`CheckTx`](#checktx) and [`DeliverTx`](#delivertx) ABCI messages. To do so, `baseapp` holds a [`router`](https://github.com/cosmos/cosmos-sdk/blob/master/baseapp/router.go) which maps `paths` (`string`) to the appropriate module [`handler`](./handler.md). Usually, the `path` is the name of the module. -The application's `router` is initilalized with all the routes using the application's [module manager](../building-modules/module-manager.md), which itself is initialized with all the application's modules in the application's [constructor](../basics/app-anatomy.md#app-constructor). +The application's `router` is initilalized with all the routes using the application's [module manager](../building-modules/module-manager.md#manager), which itself is initialized with all the application's modules in the application's [constructor](../basics/app-anatomy.md#app-constructor). ### Query Routing @@ -209,7 +209,7 @@ Developers building on top of the Cosmos SDK need not implement the ABCI themsel Steps 2. and 3. are performed by the [`anteHandler`](./accounts-fees-gas.md#antehandler) in the [`RunTx`](#runtx-antehandler-and-runmsgs) function, which `CheckTx` calls with the `runTxModeCheck` mode. During each step of `CheckTx`, a special [volatile state](#volatile-states) called `checkState` is updated. This state is used to keep track of the temporary changes triggered by the `CheckTx` calls of each transaction without modifying the [main canonical state](#main-state) . For example, when a transaction goes through `CheckTx`, the transaction's fees are deducted from the sender's account in `checkState`. If a second transaction is received from the same account before the first is processed, and the account has consumed all its funds in `checkState` during the first transaction, the second transaction will fail `CheckTx` and be rejected. In any case, the sender's account will not actually pay the fees until the transaction is actually included in a block, because `checkState` never gets committed to the main state. `checkState` is reset to the latest state of the main state each time a blocks gets [committed](#commit). -`CheckTx` returns a response to the underlying consensus engine of type [`abci.ResponseCheckTx`](https://tendermint.com/docs/spec/abci/abci.html#messages). The response contains: +`CheckTx` returns a response to the underlying consensus engine of type [`abci.ResponseCheckTx`](https://tendermint.com/docs/spec/abci/abci.html#checktx). The response contains: - `Code (uint32)`: Response Code. `0` if successful. - `Data ([]byte)`: Result bytes, if any. @@ -233,7 +233,7 @@ Before the first transaction of a given block is processed, a [volatile state](# During step 5., each read/write to the store increases the value of `GasConsumed`. You can find the default cost of each operation [here](https://github.com/cosmos/cosmos-sdk/blob/master/store/types/gas.go#L142-L150). At any point, if `GasConsumed > GasWanted`, the function returns with `Code != 0` and `DeliverTx` fails. -`DeliverTx` returns a response to the underlying consensus engine of type [`abci.ResponseCheckTx`](https://tendermint.com/docs/spec/abci/abci.html#messages). The response contains: +`DeliverTx` returns a response to the underlying consensus engine of type [`abci.ResponseDeliverTx`](https://tendermint.com/docs/spec/abci/abci.html#delivertx). The response contains: - `Code (uint32)`: Response Code. `0` if successful. - `Data ([]byte)`: Result bytes, if any. From 8b1ac7248f0010ed4ab81b2a1da6d662feda3a42 Mon Sep 17 00:00:00 2001 From: gamarin Date: Tue, 10 Sep 2019 18:43:04 +0200 Subject: [PATCH 075/196] querier --- docs/building-modules/handler.md | 9 ++- docs/building-modules/messages-and-queries.md | 2 +- docs/building-modules/querier.md | 56 ++++++++++++++++++- 3 files changed, 62 insertions(+), 5 deletions(-) diff --git a/docs/building-modules/handler.md b/docs/building-modules/handler.md index 77b2189f9fbb..5ecee9f5b98b 100644 --- a/docs/building-modules/handler.md +++ b/docs/building-modules/handler.md @@ -9,6 +9,9 @@ A `Handler` designates a function that processes [`message`s](./messages-and-queries.md#messages). `handler`s are specific to the module in which they are defined, and only process `message`s defined within said module. They are called from `baseapp` during [`DeliverTx`](../core/baseapp.md#delivertx). +- [`handler` type](#handler-type) +- [Implementation of a module `handler`s](#implementation-of-a-module-handlers) + ## `handler` type The [`handler` type](https://github.com/cosmos/cosmos-sdk/blob/master/types/handler.go#L4) defined in the Cosmos SDK specifies the typical structure of a `handler` function: @@ -23,9 +26,9 @@ Let us break it down: - The [`Context`](../core/context.md) contains all the necessary information needed to process the `msg`, as well as a cache-wrapped copy of the latest state. If the `msg` is succesfully processed, the modified version of the temporary state contained in the `ctx` will be written to the main state. - The [`Result`](https://github.com/cosmos/cosmos-sdk/blob/master/types/result.go#L14-L38) returned to `baseapp`, which contains (among other things) information on the execution of the `handler`, [`gas`](../basics/accounts-fees-gas.md#gas) consumption and [`events`](./events.md). -## Implementation of a module's `handler`s +## Implementation of a module `handler`s -Module `handler`s are typically implemented in a `handler.go` file inside the module's folder. The [module manager](./module-manager.md) is used to add the module's `handler`s to the [application's `router`](../core/baseapp.md#message-routing) via the `NewHandler()` method. Typically, the manager's `NewHandler` method simply calls a `NewHandler()` method defined in `handler.go`, which looks like the following: +Module `handler`s are typically implemented in a `handler.go` file inside the module's folder. The [module manager](./module-manager.md) is used to add the module's `handler`s to the [application's `router`](../core/baseapp.md#message-routing) via the `NewHandler()` method. Typically, the manager's `NewHandler()` method simply calls a `NewHandler()` method defined in `handler.go`, which looks like the following: ```go func NewHandler(keeper Keeper) sdk.Handler { @@ -48,7 +51,7 @@ This simple switch returns a `handler` function specific to the type of the rece - First, they perform *stateful* checks to make sure the `message` is valid. At this stage, the `message`'s `ValidateBasic()` method has already been called, meaning *stateless* checks on the message (like making sure parameters are correctly formatted) have already been performed. Checks performed in the `handler` can be more expensive and require access to the state. For example, a `handler` for a `transfer` message might check that the sending account has enough funds to actually perform the transfer. To access the state, the `handler` needs to call the [`keeper`'s](./keeper.md) getter functions. - Then, if the checks are successfull, the `handler` calls the [`keeper`'s](./keeper.md) setter functions to actually perform the state transition. -For more information, see this [example implementation of a `handler` function](https://github.com/cosmos/sdk-application-tutorial/blob/master/x/nameservice/handler.go) from the nameservice tutorial. +For a deeper look at `handler`s, see this [example implementation of a `handler` function](https://github.com/cosmos/sdk-application-tutorial/blob/master/x/nameservice/handler.go) from the nameservice tutorial. ## Next diff --git a/docs/building-modules/messages-and-queries.md b/docs/building-modules/messages-and-queries.md index 83c448263901..58beabb08c3a 100644 --- a/docs/building-modules/messages-and-queries.md +++ b/docs/building-modules/messages-and-queries.md @@ -54,7 +54,7 @@ where: - `queryCategory` is the category of the `query`, typically `custom` for module queries. It is used to differentiate between different kinds of queries within `baseapp`'s [`Query` method](../core/baseapp.md#query). - `queryRoute` is used by `baseapp`'s [`queryRouter`](../core/baseapp.md#query-routing) to map the `query` to its module. Usually, `queryRoute` should be the name of the module. - `queryType` is used by the module's [`querier`](./querier.md) to map the `query` to the appropriate `querier function` within the module. -- `args` are the actual arguments needed to process the `query`. They are filled out by the end-user. +- `args` are the actual arguments needed to process the `query`. They are filled out by the end-user. Note that for bigger queries, you might prefer passing arguments in the `Data` field of the request `req` instead of the `path`. The `path` for each `query` must be defined by the module developer in the module's [command-line interface file](./module-interfaces.md#query-commands).Overall, there are 3 mains components module developers need to implement in order to make the subset of the state defined by their module queryable: diff --git a/docs/building-modules/querier.md b/docs/building-modules/querier.md index 3afa9f0cc308..fb018f7b57b8 100644 --- a/docs/building-modules/querier.md +++ b/docs/building-modules/querier.md @@ -1,3 +1,57 @@ # Queriers -TODO \ No newline at end of file +## Pre-requisite Reading + +- [Module Manager](./module-manager.md). +- [Messages and Queries](./messages-and-queries.md) + +## Synopsis + +A `Querier` designates a function that processes [`queries`](./messages-and-queries.md#queries). `querier`s are specific to the module in which they are defined, and only process `queries` defined within said module. They are called from `baseapp`'s [`Query` method](../core/baseapp.md#query). + +- [`querier` type](#querier-type) +- [Implementation of a module `queriers`](#implementation-of-a-module-queriers) + +## `querier` type + +The [`querier` type](https://github.com/cosmos/cosmos-sdk/blob/master/types/queryable.go#L6) defined in the Cosmos SDK specifies the typical structure of a `querier` function: + +```go +type Querier = func(ctx Context, path []string, req abci.RequestQuery) (res []byte, err Error) +``` + +Let us break it down: + +- The `path` is an array of `string`s that contains the type of the query, and that can also contain `query` arguments. See [`queries`](./messages-and-queries.md#queries) for more information. +- The `req` itself is primarily used to retrieve arguments if they are too large to fit in the `path`. This is done using the `Data` field of `req`. +- The [`Context`](../core/context.md) contains all the necessary information needed to process the `query`, as well as a cache-wrapped copy of the latest state. It is primarily used by the [`keeper`](./keeper.md) to access the state. +- The result `res` returned to `baseapp`, marhsalled using the application's [`codec`](../core/encoding.md). + +## Implementation of a module `querier`s + +Module `querier`s are typically implemented in a `querier.go` file inside the module's folder. The [module manager](./module-manager.md) is used to add the module's `querier`s to the [application's `queryRouter`](../core/baseapp.md#query-routing) via the `NewQuerier()` method. Typically, the manager's `NewQuerier()` method simply calls a `NewQuerier()` method defined in `querier.go`, which looks like the following: + +```go +func NewQuerier(keeper Keeper) sdk.Querier { + return func(ctx sdk.Context, path []string, req abci.RequestQuery) (res []byte, err sdk.Error) { + switch path[0] { + case QueryType1: + return queryType1(ctx, path[1:], req, keeper) + case QueryType2: + return queryType2(ctx, path[1:], req, keeper) + default: + return nil, sdk.ErrUnknownRequest("unknown nameservice query endpoint") + } + } +} +``` + +This simple switch returns a `querier` function specific to the type of the received `query`. At this point of the [query lifecycle](../interfaces/query-lifecycle.md), the first element of the `path` (`path[0]`) contains the type of the query. The following elements are either empty or contain arguments needed to process the query. + +The `querier` functions themselves are pretty straighforward. They generally fetch a value or values from the state using the [`keeper`](./keeper.md). Then, they marshall the value(s) using the [`codec`](../core/encoding.md) and return the `[]byte` obtained as result. + +For a deeper look at `querier`s, see this [example implementation of a `querier` function](https://github.com/cosmos/sdk-application-tutorial/blob/master/x/nameservice/querier.go) from the nameservice tutorial. + +## Next + +Learn about [`keeper`s](./keeper.md). From 6f39d98376c7f720103fe77d20ae4b94a3e5e3e9 Mon Sep 17 00:00:00 2001 From: Gloria Zhao Date: Tue, 10 Sep 2019 09:43:37 -0700 Subject: [PATCH 076/196] last comments! --- docs/core/transactions.md | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/docs/core/transactions.md b/docs/core/transactions.md index a2cd7bb494ee..c2ea9721e1b5 100644 --- a/docs/core/transactions.md +++ b/docs/core/transactions.md @@ -18,20 +18,20 @@ This document describes how various components are defined to enable transaction ## Transactions -[**Transactions**](https://github.com/cosmos/cosmos-sdk/blob/master/types/tx_msg.go#L36-L43) are objects created by end-users to trigger state changes in the application. Specifically, they are comprised of metadata held in [contexts](./context.md) and [messages](../building-modules/messages-and-queries.md) that trigger state changes within a module through the module's Handler. +[**Transactions**](https://github.com/cosmos/cosmos-sdk/blob/master/types/tx_msg.go#L36-L43) are objects created by end-users to trigger state changes in the application. Specifically, they are comprised of metadata held in [contexts](./context.md) and [messages](../building-modules/messages-and-queries.md) that trigger state changes within a module through the module's [Handler](../building-modules/handler.md). When users want to interact with an application and make state changes (e.g. sending coins), they create transactions. Each of a transaction's messages must be signed using the private key associated with the appropriate account(s), and then the transaction is broadcasted to the network. A transaction must then be included in a block, validated, and approved by the network through the consensus process. To read more about the lifecycle of a transaction, click [here](../basics/tx-lifecycle.md). ## Transaction Definition -The transaction objects themselves are SDK types that implement the [`Tx`](https://github.com/cosmos/cosmos-sdk/blob/master/types/tx_msg.go#L34-L41) interface and include an encoder and decoder: +The transaction objects themselves are SDK types that implement the [`Tx`](https://github.com/cosmos/cosmos-sdk/blob/master/types/tx_msg.go#L34-L41) interface, which contains the following methods:: * **GetMsgs:** unwraps the transaction and returns a list of its message(s) - one transaction may have one or multiple [messages](../building-modules/messages-and-queries.md#messages), which are defined by module developers. -* **ValidateBasic:** includes lightweight, [*stateless*](../basics/tx-lifecycle.md#types-of-checks) checks used by ABCI messages [`CheckTx`](../basics/baseapp.md#checktx) and [`DeliverTx`](../basics/baseapp.md#delivertx) to make sure transactions are not invalid. The `StdTx` `ValidateBasic` function checks that its transactions are signed by the correct number of signers and that the fees do not exceed what the user's maximum. Note that this function is distinct from the `ValidateBasic` functions for *messages*, which perform basic validity checks on messages only. For example, when [`runTx`](../basics/baseapp.md#runtx-and-runmsgs) is checking a transaction created from the [`auth`](https://github.com/cosmos/cosmos-sdk/blob/master/docs/spec/auth) module, it first runs `ValidateBasic` on each message, then runs the `auth` module AnteHandler which calls `ValidateBasic` for the transaction itself. +* **ValidateBasic:** includes lightweight, [*stateless*](../basics/tx-lifecycle.md#types-of-checks) checks used by ABCI messages [`CheckTx`](../basics/baseapp.md#checktx) and [`DeliverTx`](../basics/baseapp.md#delivertx) to make sure transactions are not invalid. For example, the [`auth`](https://github.com/cosmos/cosmos-sdk/tree/master/x/auth) module's `StdTx` `ValidateBasic` function checks that its transactions are signed by the correct number of signers and that the fees do not exceed what the user's maximum (see the full implementation of `StdTx` [here](https://github.com/cosmos/cosmos-sdk/blob/master/x/auth/types/stdtx.go)). Note that this function is to be distinct from the `ValidateBasic` functions for *messages*, which perform basic validity checks on messages only. For example, when [`runTx`](../basics/baseapp.md#runtx-and-runmsgs) is checking a transaction created from the [`auth`](https://github.com/cosmos/cosmos-sdk/blob/master/docs/spec/auth) module, it first runs `ValidateBasic` on each message, then runs the `auth` module AnteHandler which calls `ValidateBasic` for the transaction itself. * **TxEncoder:** Nodes running the consensus engine (e.g. Tendermint Core) are responsible for gossiping transactions and ordering them into blocks, but only handle them in the generic `[]byte` form. Transactions are always [marshaled](./encoding.md) (encoded) before they are relayed to nodes, which compacts them to facilitate gossiping and helps maintain the consensus engine's separation from from application logic. The Cosmos SDK allows developers to specify any deterministic encoding format for their applications; the default is Amino. * **TxDecoder:** [ABCI](https://tendermint.com/docs/spec/abci/) calls from the consensus engine to the application, such as `CheckTx` and `DeliverTx`, are used to process transaction data to determine validity and state changes. Since transactions are passed in as `txBytes []byte`, they need to first be unmarshaled (decoded) using `TxDecoder` before any logic is applied. -A transaction is created through one of the possible [interfaces](#interfaces). In the process, two contexts and an array of [messages](#messages) are created, which are then used to [generate](#transaction-generation) the transaction itself. The actual state changes triggered by transactions are enabled by the [handlers](#handlers). The rest of the document will describe each of these components, in this order. +A transaction is created by an end-user through one of the possible [interfaces](#interfaces). In the process, two contexts and an array of [messages](#messages) are created, which are then used to [generate](#transaction-generation) the transaction itself. The actual state changes triggered by transactions are enabled by the [handlers](#handlers). The rest of the document will describe each of these components, in this order. ## CLI and REST Interfaces From 02bfe222ac598feb7384ed208d71b0d94056c9da Mon Sep 17 00:00:00 2001 From: Gloria Zhao Date: Tue, 10 Sep 2019 09:44:12 -0700 Subject: [PATCH 077/196] punctuation --- docs/core/transactions.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/core/transactions.md b/docs/core/transactions.md index c2ea9721e1b5..4751be98836e 100644 --- a/docs/core/transactions.md +++ b/docs/core/transactions.md @@ -24,7 +24,7 @@ When users want to interact with an application and make state changes (e.g. sen ## Transaction Definition -The transaction objects themselves are SDK types that implement the [`Tx`](https://github.com/cosmos/cosmos-sdk/blob/master/types/tx_msg.go#L34-L41) interface, which contains the following methods:: +The transaction objects themselves are SDK types that implement the [`Tx`](https://github.com/cosmos/cosmos-sdk/blob/master/types/tx_msg.go#L34-L41) interface, which contains the following methods: * **GetMsgs:** unwraps the transaction and returns a list of its message(s) - one transaction may have one or multiple [messages](../building-modules/messages-and-queries.md#messages), which are defined by module developers. * **ValidateBasic:** includes lightweight, [*stateless*](../basics/tx-lifecycle.md#types-of-checks) checks used by ABCI messages [`CheckTx`](../basics/baseapp.md#checktx) and [`DeliverTx`](../basics/baseapp.md#delivertx) to make sure transactions are not invalid. For example, the [`auth`](https://github.com/cosmos/cosmos-sdk/tree/master/x/auth) module's `StdTx` `ValidateBasic` function checks that its transactions are signed by the correct number of signers and that the fees do not exceed what the user's maximum (see the full implementation of `StdTx` [here](https://github.com/cosmos/cosmos-sdk/blob/master/x/auth/types/stdtx.go)). Note that this function is to be distinct from the `ValidateBasic` functions for *messages*, which perform basic validity checks on messages only. For example, when [`runTx`](../basics/baseapp.md#runtx-and-runmsgs) is checking a transaction created from the [`auth`](https://github.com/cosmos/cosmos-sdk/blob/master/docs/spec/auth) module, it first runs `ValidateBasic` on each message, then runs the `auth` module AnteHandler which calls `ValidateBasic` for the transaction itself. From 5162d2e52ea1e887cf055c8bf8485f25b1fc3374 Mon Sep 17 00:00:00 2001 From: gamarin Date: Tue, 10 Sep 2019 18:49:34 +0200 Subject: [PATCH 078/196] querier2 --- docs/building-modules/querier.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/building-modules/querier.md b/docs/building-modules/querier.md index fb018f7b57b8..e865f82eccab 100644 --- a/docs/building-modules/querier.md +++ b/docs/building-modules/querier.md @@ -29,7 +29,7 @@ Let us break it down: ## Implementation of a module `querier`s -Module `querier`s are typically implemented in a `querier.go` file inside the module's folder. The [module manager](./module-manager.md) is used to add the module's `querier`s to the [application's `queryRouter`](../core/baseapp.md#query-routing) via the `NewQuerier()` method. Typically, the manager's `NewQuerier()` method simply calls a `NewQuerier()` method defined in `querier.go`, which looks like the following: +Module `querier`s are typically implemented in a `querier.go` file inside the module's folder. The [module manager](./module-manager.md) is used to add the module's `querier`s to the [application's `queryRouter`](../core/baseapp.md#query-routing) via the `NewQuerier()` method. Typically, the manager's `NewQuerier()` method simply calls a `NewQuerier()` method defined in `keeper/querier.go`, which looks like the following: ```go func NewQuerier(keeper Keeper) sdk.Querier { From 25fdbf274f7a76b861bd0fd43e3647bda3adccd5 Mon Sep 17 00:00:00 2001 From: gamarin Date: Mon, 20 May 2019 14:08:56 +0200 Subject: [PATCH 079/196] consolidate intro --- docs/intro/README.md | 15 +++++------ docs/intro/sdk-app-architecture.md | 26 +++++++++---------- docs/intro/why-app-specific.md | 41 +++++++++++++++--------------- 3 files changed, 40 insertions(+), 42 deletions(-) diff --git a/docs/intro/README.md b/docs/intro/README.md index 9df4e13e443c..e753330be21b 100644 --- a/docs/intro/README.md +++ b/docs/intro/README.md @@ -2,15 +2,15 @@ ## What is the SDK? -The [Cosmos-SDK](https://github.com/cosmos/cosmos-sdk) is an open-source framework for building multi-asset public Proof-of-Stake (PoS) blockchains, like the Cosmos Hub, as well as permissioned Proof-Of-Authority (PoA) blockchains. Blockchains built with the Cosmos SDK are generally referred to as **application-specific blockchains**. +The [Cosmos-SDK](https://github.com/cosmos/cosmos-sdk) is a framework for building multi-asset public Proof-of-Stake (PoS) blockchains, like the Cosmos Hub, as well as permissionned Proof-Of-Authority (PoA) blockchains. Blockchains built with the Cosmos SDK are generally referred to as **application-specific blockchains**. -The goal of the Cosmos SDK is to allow developers to easily create custom blockchains from scratch that can natively interoperate with other blockchains. We envision the SDK as the npm-like framework to build secure blockchain applications on top of [Tendermint](https://github.com/tendermint/tendermint). SDK-based blockchains are built out of composable modules, most of which are open source and readily available for any developers to use. Anyone can create a module for the Cosmos-SDK, and integrating already-built modules is as simple as importing them into your blockchain application. What's more, the Cosmos SDK is a capabilities-based system, which allows developers to better reason about the security of interactions between modules. For a deeper look at capabilities, jump to [this section](./ocap.md). +The goal of the Cosmos SDK is to allow developers to easily create custom blockchains from scratch that can natively interoperate with other blockchains. We envision the SDK as the npm-like framework to build secure blockchain applications on top of [Tendermint](https://github.com/tendermint/tendermint). SDK-based blockchains are built out of composable modules, most of which are open source and readily available for any developers to use. Anyone can create a module for the Cosmos-SDK, and integrating already-built modules is as simple as importing them into your blockchain application. What's more, the Cosmos SDK is a capabilities-based system, which allows developer to better reason about the security of interactions between modules. For a deeper look at capabilities, jump to [this section](./ocap.md). ## What are Application-Specific Blockchains? One development paradigm in the blockchain world today is that of virtual-machine blockchains like Ethereum, where development generally revolves around building a decentralised applications on top of an existing blockchain as a set of smart contracts. While smart contracts can be very good for some use cases like single-use applications (e.g. ICOs), they often fall short for building complex decentralised platforms. More generally, smart contracts can be limiting in terms of flexibility, sovereignty and performance. -Application-specific blockchains offer a radically different development paradigm than virtual-machine blockchains. An application-specific blockchain is a blockchain customized to operate a single application: developers have all the freedom to make the design decisions required for the application to run optimally. They can also provide better sovereignty, security and performance. +Application-specific blockchains offer a radically different development paradigm than virtual-machine blockchains. An application-specific blockchain is a blockchain customized to operate a single application: developers have all the freedom to make the design decisions required for the application to run optimally. They can also provide better sovereignty, security and performance. To learn more about application-specific blockchains, [click here](./why-app-specific.md). @@ -18,13 +18,12 @@ To learn more about application-specific blockchains, [click here](./why-app-spe The Cosmos SDK is the most advanced framework for building custom application-specific blockchains today. Here are a few reasons why you might want to consider building your decentralised application with the Cosmos SDK: -- The default consensus engine available within the SDK is [Tendermint Core](https://github.com/tendermint/tendermint). Tendermint is the most (and only) mature BFT consensus engine in existence. It is widely used across the industry and is considered the gold standard consensus engine for building Proof-of-Stake systems. -- The SDK is open source and designed to make it easy to build blockchains out of composable modules. As the ecosystem of open source SDK modules grow, it will become increasingly easier to build complex decentralised platforms with it. -- The SDK is inspired by capabilities-based security, and informed by years of wrestling with blockchain state-machines. This makes the Cosmos SDK a very secure environment to build blockchains. -- Most importantly, the Cosmos SDK has already been used to build many application-specific blockchains that are already in production. Among others, we can cite [Cosmos Hub](https://hub.cosmos.network), [IRIS Hub](https://irisnet.org), [Binance Chain](https://docs.binance.org/), [Terra](https://terra.money/) or [Lino](https://lino.network/). Many more are building on the Cosmos SDK. You can get a view of the ecosystem [here](https://cosmos.network/ecosystem). +- The default consensus engine available within the SDK is [Tendermint Core](https://github.com/tendermint/tendermint). Tendermint is the most (and only) mature BFT consensus engine in existence. It is widely used accross the industry and is considered the gold standard consensus engine for building Proof-of-Stake systems. +- The SDK is open source and designed to make it easy to build blockchains out of composable modules. As the ecosystem of open source SDK modules grow, it will become increasingly easier to build complex decentralised platforms with it. +- The SDK is inspired by capabilities-based security, and informed by years of wrestling with blockchain state-machines. This makes the Cosmos SDK a very secure environment to build blockchains. +- Most importantly, the Cosmos SDK has already been used to build many application-specific blockchains that are already in production. Among others, we can cite [Cosmos Hub](https://hub.cosmos.network), [Iris](https://irisnet.org), [Binance Chain](https://docs.binance.org/), [Terra](https://terra.money/) or [Lino](https://lino.network/). Many more are building on the Cosmos SDK. You can get a view of the ecosystem [here](https://cosmos.network/ecosystem). ## Getting started with the Cosmos SDK - Learn more about the [architecture of an SDK application](./sdk-app-architecture.md) - Learn how to build an application-specific blockchain from scratch with the [SDK Tutorial](https://cosmos.network/docs/tutorial) - diff --git a/docs/intro/sdk-app-architecture.md b/docs/intro/sdk-app-architecture.md index 94007a2742dc..a420fe627c33 100644 --- a/docs/intro/sdk-app-architecture.md +++ b/docs/intro/sdk-app-architecture.md @@ -1,12 +1,12 @@ # SDK Application Architecture -## State machine +## State machine -At its core, a blockchain is a [replicated deterministic state machine](https://en.wikipedia.org/wiki/State_machine_replication). +At its core, a blockchain is a [replicated deterministic state machine](https://en.wikipedia.org/wiki/State_machine_replication). -A state machine is a computer science concept whereby a machine can have multiple states, but only one at any given time. There is a `state`, which describes the current state of the system, and `transactions`, that trigger state transitions. +A state machine is a computer science concept whereby a machine can have multiple states, but only one at any given time. There is a `state`, which describes the current state of the system, and `transactions`, that trigger state transitions. -Given a state S and a transaction T, the state machine will return a new state S'. +Given a state S and a transaction T, the state machine will return a new state S'. ``` +--------+ +--------+ @@ -26,9 +26,9 @@ In practice, the transactions are bundled in blocks to make the process more eff +--------+ +--------+ ``` -In a blockchain context, the state machine is deterministic. This means that if you start at a given state and replay the same sequence of transactions, you will always end up with the same final state. +In a blockchain context, the state machine is deterministic. This means that if you start at a given state and replay the same sequence of transactions, you will always end up with the same final state. -The Cosmos SDK gives you maximum flexibility to define the state of your application, transaction types and state transition functions. The process of building the state-machine with the SDK will be described more in depth in the following sections. But first, let us see how it is replicated using **Tendermint**. +The Cosmos SDK gives you maximum flexibility to define the state of your application, transaction types and state transition functions. The process of building the state-machine with the SDK will be described more in depth in the following sections. But first, let us see how it is replicated using **Tendermint**. ### Tendermint @@ -54,14 +54,14 @@ Blockchain node | | Consensus | | Tendermint is an application-agnostic engine that is responsible for handling the *networking* and *consensus* layers of your blockchain. In practice, this means that Tendermint is responsible for propagating and ordering transaction bytes. Tendermint Core relies on an eponymous Byzantine-Fault-Tolerant (BFT) algorithm to reach consensus on the order of transactions. For more on Tendermint, click [here](https://tendermint.com/docs/introduction/what-is-tendermint.html). -The Tendermint consensus algorithm works with a set of special nodes called *Validators*. Validators are responsible for adding blocks of transactions to the blockchain. At any given block, there is a validator set V. A validator in V is chosen by the algorithm to be the proposer of the next block. This block is considered valid if more than two thirds of V signed a *[prevote](https://tendermint.com/docs/spec/consensus/consensus.html#prevote-step-height-h-round-r)* and a *[precommit](https://tendermint.com/docs/spec/consensus/consensus.html#precommit-step-height-h-round-r)* on it, and if all the transactions that it contains are valid. The validator set can be changed by rules written in the state-machine. For a deeper look at the algorithm, click [here](https://tendermint.com/docs/introduction/what-is-tendermint.html#consensus-overview). +Tendermint consensus algorithm works with a set of special nodes called *Validators*. Validators are responsible for adding blocks of transactions to the blockchain. At any given block, there is a validator set V. A validator in V is chosen by the algorithm to be the proposer of the next block. This block is considered valid if more than two thirds of V signed a *[prevote](https://tendermint.com/docs/spec/consensus/consensus.html#prevote-step-height-h-round-r)* and a *[precommit](https://tendermint.com/docs/spec/consensus/consensus.html#precommit-step-height-h-round-r)* on it, and if all the transactions that it contains are valid. The validator set can be changed by rules written in the state-machine. For a deeper look at the algorithm, click [here](https://tendermint.com/docs/introduction/what-is-tendermint.html#consensus-overview). -The main part of a Cosmos SDK application is a blockchain daemon that is run by each node in the network locally. If less than one third of the *validator set* is byzantine (i.e. malicious), then each node should obtain the same result when querying the state at the same time. +The main part of a Cosmos SDK application is a blockchain daemon that is run by each node in the network locally. If less than one third of the *validator set* is byzantine (i.e. malicious), then each node should obtain the same result when querying the state at the same time. ## ABCI -Tendermint passes transactions from the network to the application through an interface called the [ABCI](https://github.com/tendermint/tendermint/tree/master/abci), which the application must implement. +Tendermint passes transactions from the network to the application through an interface called the [ABCI](https://github.com/tendermint/tendermint/tree/master/abci), which the application must implement. ``` +---------------------+ @@ -81,16 +81,16 @@ Tendermint passes transactions from the network to the application through an in +---------------------+ ``` -Note that **Tendermint only handles transaction bytes**. It has no knowledge of what these bytes mean. All Tendermint does is order these transaction bytes deterministically. Tendermint passes the bytes to the application via the ABCI, and expects a return code to inform it if the messages contained in the transactions were successfully processed or not. +Note that **Tendermint only handles transaction bytes**. It has no knowledge of what these bytes mean. All Tendermint does is order these transaction bytes deterministically. Tendermint passes the bytes to the application via the ABCI, and expects a return code to inform it if the messages contained in the transactions were successfully processed or not. Here are the most important messages of the ABCI: -- `CheckTx`: When a transaction is received by Tendermint Core, it is passed to the application to check if a few basic requirements are met. `CheckTx` is used to protect the mempool of full-nodes against spam. A special handler called the "Ante Handler" is used to execute a series of validation steps such as checking for sufficient fees and validating the signatures. If the check is valid, the transaction is added to the [mempool](https://tendermint.com/docs/spec/reactors/mempool/functionality.html#mempool-functionality) and relayed to peer nodes. Note that transactions are not processed (i.e. no modification of the state occurs) with `CheckTx` since they have not been included in a block yet. +- `CheckTx`: When a transaction is received by Tendermint Core, it is passed to the application to check if a few basic requirements are met. `CheckTx` is used to protect the mempool of full-nodes against spam. A special handler called the "Ante Handler" is used to execute a series of validation steps such as checking for sufficient fees and validating the signatures. If the check is valid, the transaction is added to the [mempool](https://tendermint.com/docs/spec/reactors/mempool/functionality.html#mempool-functionality) and relayed to peer nodes. Note that transactions are not processed (i.e. no modification of the state occurs) with `CheckTx` since they have not been included in a block yet. - `DeliverTx`: When a [valid block](https://tendermint.com/docs/spec/blockchain/blockchain.html#validation) is received by Tendermint Core, each transaction in the given block is passed to the application via `DeliverTx` to be processed. It is during this stage that the state transitions occur. The "Ante Handler" executes again along with the actual handlers for each message in the transaction. - - `BeginBlock`/`EndBlock`: These messages are executed at the beginning and the end of each block, whether the block contains transaction or not. It is useful to trigger automatic execution of logic. Proceed with caution though, as computationally expensive loops could slow down your blockchain, or even freeze it if the loop is infinite. + - `BeginBlock`/`EndBlock`: These messages are executed at the beginning and the end of each block, whether the block contains transaction or not. It is useful to trigger automatic execution of logic. Proceed with caution though, as computationally expensive loops could slow down your blockchain, or even freeze it if the loop is infinite. For a more detailed view of the ABCI methods and types, click [here](https://tendermint.com/docs/spec/abci/abci.html#overview). Any application built on Tendermint needs to implement the ABCI interface in order to communicate with the underlying local Tendermint engine. Fortunately, you do not have to implement the ABCI interface. The Cosmos SDK provides a boilerplate implementation of it in the form of [baseapp](./sdk-design.md#baseapp). -### Next, let us go into the [high-level design principles of the SDK](./sdk-design.md) \ No newline at end of file +### Next, let us go into the [high-level design principles of the SDK](./sdk-design.md) diff --git a/docs/intro/why-app-specific.md b/docs/intro/why-app-specific.md index 1b160429f6eb..ce454383711c 100644 --- a/docs/intro/why-app-specific.md +++ b/docs/intro/why-app-specific.md @@ -4,7 +4,7 @@ This document explains what application-specific blockchains are, and why develo ## What are application-specific blockchains? -Application-specific blockchains are blockchains customized to operate a single application. Instead of building a decentralised application on top of an underlying blockchain like Ethereum, developers build their own blockchain from the ground up. This means building a full-node client, a light-client, and all the necessary interfaces (CLI, REST, ...) to interract with the nodes. +Application-specific blockchains are blockchains customized to operate a single application. Instead of building a decentralised application on top of an underlying blockchain like Ethereum, developers build their own blockchain from the ground up. This means building a full-node client, a light-client, and all the necessary interfaces (CLI, REST, ...) to interract with the nodes. ``` ^ +-------------------------------+ ^ @@ -24,13 +24,13 @@ Blockchain node | | Consensus | | ## What are the shortcomings of Smart Contracts? -Virtual-machine blockchains like Ethereum addressed the demand for more programmability back in 2014. At the time, the options available for building decentralised applications were quite limited. Most developers would build on top of the complex and limited Bitcoin scripting language, or fork the Bitcoin codebase which was hard to work with and customize. +Virtual-machine blockchains like Ethereum addressed the demand for more programmability back in 2014. At the time, the options available for building decentralised applications were quite limited. Most developers would build on top of the complex and limited Bitcoin scripting language, or fork the Bitcoin codebase which was hard to work with and customize. Virtual-machine blockchains came in with a new value proposition. Their state-machine incorporates a virtual-machine that is able to interpret turing-complete programs called Smart Contracts. These Smart Contracts are very good for use cases like one-time events (e.g. ICOs), but they can fall short for building complex decentralised platforms: -- Smart Contracts are generally developed with specific programming languages that can be interpreted by the underlying virtual-machine. These programming languages are often immature and inherently limited by the constraints of the virtual-machine. For example, the Ethereum Virtual Machine does not allow developers to implement automatic execution of code. Developers are also limited to the account-based system of the EVM, and they can only choose from a limited set of functions for their cryptographic operations. These are examples, but they hint at the lack of **flexibility** a smart contract environment often entails. +- Smart Contracts are generally developed with specific programming languages that can be interpreted by the underlying virtual-machine. These programming languages are often immature and inherently limited by the constraints of the virtual-machine. For example, the Ethereum Virtual Machine does not allow developers to implement automatic execution of code. Developers are also limited to the account-based system of the EVM, and they can only choose from a limited set of functions for their cryptographic operations. These are examples, but they hint at the lack of **flexibility** a smart contract environment often entails. - Smart Contracts are all run by the same virtual machine. This means that they compete for resources, which can severly restrain **performance**. And even if the state-machine were to be split in multiple subsets (e.g. via sharding), Smart Contracts would still need to be interpeted by a virtual machine, which would limit performance compared to a native application implemented at state-machine level (our benchmarks show an improvement on the order of x10 in performance when the virtual-machine is removed). -- Another issue with the fact that Smart Contracts share the same underlying environment is the resulting limitation in **sovereignty**. A decentralised application is an ecosystem that involves multiple players. If the application is built on a general-purpose virtual-machine blockchain, these players have very limited sovereignty over it, and are ultimately superseded by the governance of the underlying blockchain. If there is a bug in the application, very little can be done about it. +- Another issue with the fact that Smart Contracts share the same underlying environment is the resulting limitation in **sovereignty**. A decentralised application is an ecosystem that involves multiple players. If the application is built on a general-purpose virtual-machine blockchain, these players have very limited sovereignty over it, and are ultimately superseded by the governance of the underlying blockchain. If there is a bug in the application, very little can be done about it. Application-Specific Blockchains are designed to address these shortcomings. @@ -40,40 +40,39 @@ Application-Specific Blockchains are designed to address these shortcomings. Application-specific blockchains give maximum flexibility to developers: -- In Cosmos blockchains, the state-machine is typically connected to the underlying consensus engine via an interface called the [ABCI](https://tendermint.com/docs/spec/abci/). This interface can be wrapped in any programming language, meaning developers can build their state-machine in the programming language of their choice. -- Developers can choose among multiple frameworks to build their state-machine. The most widely used today is the Cosmos SDK, but others exist (e.g. [Lotion](https://github.com/nomic-io/lotion), [Weave](https://github.com/iov-one/weave), ...). The choice will most of the time be done based on the programming language they want to use (Cosmos SDK and Weave are in Golang, Lotion is in Javascript, ...). -- The ABCI also allows developers to swap the consensus engine of their application-specific blockchain. Today, only Tendermint is production-ready, but in the future other engines are expected to emerge. -- Even when they settle for a framework and consensus engine, developers still have the freedom to tweak them if they don't perfectly match their requirements in their pristine forms. -- Developers are free to explore the full spectrum of tradeoffs (e.g. number of validators vs transaction throughput, safety vs availability in asynchrony, ...) and design choices (DB or IAVL tree for storage, UTXO or account model, ...). -- Developers can implement automatic execution of code. In the Cosmos SDK, logic can be automatically triggered at the beginning and the end of each block. They are also free to choose the cryptographic library used in their application, as opposed to being constrained by what is made available by the underlying environment in the case of virtual-machine blockchains. +- Developers can choose among multiple frameworks to build their state-machine. The most widely used today is the Cosmos SDK, but others exist (e.g. Lotion, Weave, ...). The choice will most of the time be done based on the programming language they want to use (Cosmos SDK and Weave are in Golang, Lotion is in Javascript, ...). +- Developers can swap consensus engine. Today, only Tendermint is production-ready, but in the future other engines are expected to emerge. +- Even when they settle for a framework and consensus engine, developers still have the freedom to tweak them if they don't perfectly match their requirements in their pristine forms. +- Developers are free to explore the full spectrum of tradeoffs (e.g. number of validators vs transaction throughput, safety vs availability in asynchrony, ...) and design choices (DB or IAVL tree for storage, UTXO or account model, ...). +- Developers can implement automatic execution of code. In the Cosmos SDK, logic can be automatically triggered at the beginning and the end of each block. They are also free to choose the cryptographic library used in their application, as opposed to being constrained by what is made available by the underlying environment in the case of virtual-machine blockchains. -The list above contains a few examples that show how much flexibility application-specific blockchains give to developers. The goal of Cosmos and the Cosmos SDK is to make developer tooling as generic and composable as possible, so that each part of the stack can be forked, tweaked and improved without losing compatibility. As the community grows, more alternative for each of the core building blocks will emerge, giving more options to developers. +The list above contains a few examples that show how much flexibility application-specific blockchains give to developers. The goal of Cosmos and the Cosmos SDK is to make developer tooling as generic and composable as possible, so that each part of the stack can be forked, tweaked and improved without losing compatibility. As the community grows, more alternative for each of the core building blocks will emerge, giving more options to developers. ### Performance Decentralised applications built with Smart Contracts are inherently capped in performance by the underlying environment. For a decentralised application to optimise performance, it needs to be built as an application-specific blockchains. Here are the benefits of an application-specific blockchains with regards to performance: -- Developers of application-specific blockchains can choose to operate with novel consensus engine such as Tendermint BFT. Compared to Proof-of-Work (used by most virtual-machine blockchains today), it offers significant gains in throuhgput. -- An application-specific blockchain only operates a single application, so that the application does not compete with others for computation and storage. This is the opposite of most non-sharded virtual-machine blockchains today, where smart contracts all compete for computation and storage. -- Even if a virtual-machine blockchain offered application-based sharding coupled with an efficient consensus algorithm, performance would still be limited by the virtual-machine itself. The real throughput bottleneck is the state-machine, and requiring transactions to be interpreted by a virtual-machine significantly increases the computational complexity of processing them. +- Developers of application-specific blockchains can choose to operate with novel consensus engine such as Tendermint BFT. Compared to Proof-of-Work (used by most virtual-machine blockchains today), it offers significant gains in throuhgput. +- An application-specific blockchain only operates a single application, so that the application does not compete with others for computation. This is the opposite of most non-sharded virtual-machine blockchains today, where smart contracts all compete for computation. +- Even if a virtual-machine blockchain offered application-based sharding coupled with an efficient consensus algorithm, performance would still be limited by the virtual-machine itself. The real throughput bottleneck is the state-machine, and requiring transactions to be interpreted by a virtual-machine significantly increases the computational complexity of processing them. -### Security +### Security Security is hard to quantify, and greatly varies from platform to platform. That said here are some important benefits an application-specific blockchain can bring in terms of security: -- Developers can choose proven programming languages like Golang when building their application-specific blockchains, as opposed to smart contract programming languages that are often more immature. -- Developers are not constrained by the cryptographic functions made available by the underlying virtual-machines. They can use their own custom cryptography, and rely on well-audited crypto libraries. -- Developers do not have to worry about potential bugs or exploitable mechanisms in the underlying virtual-machine, making it easier to reason about the security of the application. +- Developers can choose proven programming language like Golang when building their application-specific blockchains, as opposed to smart contract programming languages that are often more immature. +- Developers are not constrained by the cryptographic functions made available by the underlying virtual-machines. They can use their own custom cryptography, and rely on well-audited crypto libraries. +- Developers do not have to worry about potential bugs or exploitable mechanisms in the underlying virtual-machine, making it easier to reason about the security of the application. ### Sovereignty -One of the major benefits of application-specific blockchains is sovereignty. A decentralised application is an ecosystem that involves many actors: users, developers, third-party services, and more. When developers build on virtual-machine blockchain where many decentralised applications coexist, the community of the application is different than the community of the underlying blockchain, and the latter supersedes the former. If there is a bug or if a new feature is needed, the community of the application has very little sovereignty to upgrade the code. If the community of the underlying blockchain refuses to act, nothing can happen. +One of the major benefits of application-specific blockchains is sovereignty. A decentralised application is an ecosystem that involves many actors: users, developers, third-party services, and more. When developers build on virtual-machine blockchain where many decentralised applications coexist, the community of the application is different than the community of the underlying blockchain, and the latter supersedes the former. If there is a bug or if a new feature is needed, the community of the application has very little sovereignty to upgrade the code. If the community of the underlying blockchain refuses to act, nothing can happen. -The fundamental issue here is that the governance of the application and the governance of the network are not aligned. This issue is solved by application-specific blockchains. Because application-specific blockchains specialize to operate a single application, the community of the application has full control over the entire chain. This ensures the community will not be stuck if a bug is discovered, and that it has the entire freedom to choose how it is going to evolve. +The fundamental issue here is that the governance of the application and the governance of the network are not aligned. This issue is solved by application-specific blockchains. Because application-specific blockchains specialize to operate a single application, the community of the application has full control over the entire chain. This ensures the community will not be stuck if a bug is discovered, and that it has the entire freedom to choose how it is going to evolve. ## Start Building Your Application-Specific Blockchain Today Clearly, application-specific blockchains are awesome. The Cosmos SDK makes it easier than ever to build them. What are you waiting for? -- Learn more about the [high-level architecture](./sdk-app-architecture) of an SDK application. - Learn how to build an application-specific blockchain from scratch with the [SDK tutorial](https://cosmos.network/docs/tutorial) +- Learn more about the [high-level architecture](./sdk-app-architecture) of an SDK application. From a6bd71e8049c3a2c30085af7dd2cbb129c7c1c2a Mon Sep 17 00:00:00 2001 From: gamarin Date: Tue, 28 May 2019 17:32:29 +0200 Subject: [PATCH 080/196] querier --- docs/concepts/amino.md | 3 +++ docs/concepts/genesis.md | 3 +++ docs/concepts/handler.md | 1 + docs/concepts/keeper.md | 0 docs/concepts/modules.md | 3 +++ docs/concepts/querier.md | 3 +++ docs/core/node.md | 2 +- docs/intro/README.md | 2 +- 8 files changed, 15 insertions(+), 2 deletions(-) create mode 100644 docs/concepts/amino.md create mode 100644 docs/concepts/genesis.md create mode 100644 docs/concepts/handler.md create mode 100644 docs/concepts/keeper.md create mode 100644 docs/concepts/modules.md create mode 100644 docs/concepts/querier.md diff --git a/docs/concepts/amino.md b/docs/concepts/amino.md new file mode 100644 index 000000000000..8113f63e9630 --- /dev/null +++ b/docs/concepts/amino.md @@ -0,0 +1,3 @@ +# Amnio Encoding + +TODO \ No newline at end of file diff --git a/docs/concepts/genesis.md b/docs/concepts/genesis.md new file mode 100644 index 000000000000..5e3dbd31dcad --- /dev/null +++ b/docs/concepts/genesis.md @@ -0,0 +1,3 @@ +# Genesis File + +TODO \ No newline at end of file diff --git a/docs/concepts/handler.md b/docs/concepts/handler.md new file mode 100644 index 000000000000..f8fc820df8de --- /dev/null +++ b/docs/concepts/handler.md @@ -0,0 +1 @@ +# Handlers \ No newline at end of file diff --git a/docs/concepts/keeper.md b/docs/concepts/keeper.md new file mode 100644 index 000000000000..e69de29bb2d1 diff --git a/docs/concepts/modules.md b/docs/concepts/modules.md new file mode 100644 index 000000000000..cfd71f817963 --- /dev/null +++ b/docs/concepts/modules.md @@ -0,0 +1,3 @@ +# SDK Modules + +Todo: Intro concept docs on modules \ No newline at end of file diff --git a/docs/concepts/querier.md b/docs/concepts/querier.md new file mode 100644 index 000000000000..3afa9f0cc308 --- /dev/null +++ b/docs/concepts/querier.md @@ -0,0 +1,3 @@ +# Queriers + +TODO \ No newline at end of file diff --git a/docs/core/node.md b/docs/core/node.md index 85c6152542ad..36fe12602d0d 100644 --- a/docs/core/node.md +++ b/docs/core/node.md @@ -2,7 +2,7 @@ ## Pre-Requisite Reading -## `main` function +## main function TODO diff --git a/docs/intro/README.md b/docs/intro/README.md index e753330be21b..e676fd179b16 100644 --- a/docs/intro/README.md +++ b/docs/intro/README.md @@ -2,7 +2,7 @@ ## What is the SDK? -The [Cosmos-SDK](https://github.com/cosmos/cosmos-sdk) is a framework for building multi-asset public Proof-of-Stake (PoS) blockchains, like the Cosmos Hub, as well as permissionned Proof-Of-Authority (PoA) blockchains. Blockchains built with the Cosmos SDK are generally referred to as **application-specific blockchains**. +The [Cosmos-SDK](https://github.com/cosmos/cosmos-sdk) is an open-source framework for building multi-asset public Proof-of-Stake (PoS) blockchains, like the Cosmos Hub, as well as permissionned Proof-Of-Authority (PoA) blockchains. Blockchains built with the Cosmos SDK are generally referred to as **application-specific blockchains**. The goal of the Cosmos SDK is to allow developers to easily create custom blockchains from scratch that can natively interoperate with other blockchains. We envision the SDK as the npm-like framework to build secure blockchain applications on top of [Tendermint](https://github.com/tendermint/tendermint). SDK-based blockchains are built out of composable modules, most of which are open source and readily available for any developers to use. Anyone can create a module for the Cosmos-SDK, and integrating already-built modules is as simple as importing them into your blockchain application. What's more, the Cosmos SDK is a capabilities-based system, which allows developer to better reason about the security of interactions between modules. For a deeper look at capabilities, jump to [this section](./ocap.md). From 2101a755f30bcf088e72ac77b6583a641e36500a Mon Sep 17 00:00:00 2001 From: gamarin Date: Wed, 5 Jun 2019 17:10:54 +0200 Subject: [PATCH 081/196] workiiiing --- docs/.vuepress/config.js | 3 +- docs/concepts/app-anatomy.md | 212 +++++++++++++++++++++++++++++++++ docs/intro/why-app-specific.md | 2 +- 3 files changed, 215 insertions(+), 2 deletions(-) create mode 100644 docs/concepts/app-anatomy.md diff --git a/docs/.vuepress/config.js b/docs/.vuepress/config.js index 9ee6a31059c5..d8756aae2385 100644 --- a/docs/.vuepress/config.js +++ b/docs/.vuepress/config.js @@ -31,7 +31,8 @@ module.exports = { "/intro/", "/intro/why-app-specific", "/intro/sdk-app-architecture", - "/intro/sdk-design" + "/intro/sdk-design", + "intro/ocap" ] }, { diff --git a/docs/concepts/app-anatomy.md b/docs/concepts/app-anatomy.md new file mode 100644 index 000000000000..346b35abab80 --- /dev/null +++ b/docs/concepts/app-anatomy.md @@ -0,0 +1,212 @@ +# Anatomy of an SDK Application + +## Pre-requisite reading + +- [High-level overview of the architecture of an SDK application](../intro/sdk-app-architecture.md) +- [Cosmos SDK design overview](../intro/sdk-design.md) + +## Synopsis + +This document describes the core parts of a Cosmos SDK application. The placeholder name for this application will be `app`. + +- [Node Client](#node-client) +- [Core Application File](#core-application-file) +- [Modules](#modules) +- [Intefaces](#interfaces) +- [Dependencies and Makefile](#dependencies-and-makefile) + +The core parts listed above will generally translate to the following directory tree: + +``` +./app +├── cmd/ +│ ├── appd +│ └── appcli +├── app.go +├── x/ +│ ├── auth +│ └── bank +├── Gopkg.toml +└── Makefile +``` + +## Node Client (Daemon) + +The Daemon, or Full-Node Client, is the core process of an SDK-based blockchain. Participants in the network run this process to initialize their state-machine, connect with other full-nodes and update their state-machine as new blocks come in. + +``` + ^ +-------------------------------+ ^ + | | | | + | | State+machine = Application | | + | | | | Built with Cosmos SDK + | | ^ + | | + | +----------- | ABCI | ----------+ v + | | + v | ^ + | | | | +Blockchain Node | | Consensus | | + | | | | + | +-------------------------------+ | Tendermint Core + | | | | + | | Networking | | + | | | | + v +-------------------------------+ v +``` +The blockchain full-node presents itself as a binary, generally suffixed by `-d` (e.g. `appd` for `app` or `gaiad` for the `gaia`) for "daemon". This binary is built by running a simple `main.go` function placed in `cmd/appd/`. This operation usually happens through the [Makefil](#dependencies-and-makefile). + +To learn more about the `main.go` function, [click here](./node.md#main-function). + +Once the main binary is built, the node can be started by running the `start` command. The core logic behind the `start` command is implemented in the SDK itself in the [`/server/start.go`](https://github.com/cosmos/cosmos-sdk/blob/master/server/start.go) file. The main [`start` command function](https://github.com/cosmos/cosmos-sdk/blob/master/server/start.go#L31) takes a [`context`](https://godoc.org/github.com/cosmos/cosmos-sdk/client/context) and [`appCreator`](#constructor-function-(`appCreator`)) as arguments. The `appCreator` is a constructor function for the SDK application, and is used in the starting process of the full-node. + +The `start` command function primarily does three things: + +1- Create an instance of the state-machine defined in [`app.go`](#core-application-file) using the `appCreator`. +2- Initialize the state-machine with the latest known state, extracted from the `db` stored in the `~/.appd/data` folder. At this point, the state-machine is at height `appBlockHeight`. +3- Create and start a new Tendermint instance. Among other things, the node will perform a handshake with its peers. It will get the latest `blockHeight` from them, and replay blocks to sync to this height if it is greater than the local `appBlockHeight`. If `appBlockHeight` is `0`, the node is starting from genesis and Tendermint sends an `InitChain` message via the ABCI to the `app`, which triggers the [`InitChainer`](#initchainer). + +To learn more about the `start` command, [click here](./node.md#start-command). + +## Core Application File + +In general, the core of the state-machine is defined in a file called `app.go`. It mainly contains the **type definition of the application** and functions to **create and initialize it**. + +### Type Definition of the Application + +The first thing defined in `app.go` is the `type` of the application. It is generally comprised of the following parts: + +- **A reference to [`baseapp`](./baseapp.md).** The custom application defined in `app.go` is a golang embedding of the `baseapp` type. `baseapp` implements most of the core logic for the application, including all the [ABCI methods](https://tendermint.com/docs/spec/abci/abci.html#overview) and the routing logic. When a transaction is relayed by Tendermint to the application, the latter uses `baseapp`'s methods to route them to the appropriate module. +- **A list of store keys**. The [store](./store.md), which contains the entire state, is implemented as a multistore (i.e. a store of stores) in the Cosmos SDK. Each module uses one or multiple stores in the multistore to persist their part of the state. These stores can be accessed with specific keys that are declared in the `app` type. These keys, along with the `keepers`, are at the heart of the [object-capabilities model](../intro/ocap.md) of the Cosmos SDK. +- **A list of module's `keepers`.** Each module defines an abstraction called `keeper`, which handles reads and writes for this module's store(s). The `keeper`'s methods of one module can be called from other modules (if authorized), which is why they are declared in the application's type. +- **A reference to a `codec`.** The Cosmos SDK gives developers the freedom to choose the encoding framework for their application. The application's `codec` is used to serialize and deserialize data structures in order to store them, as stores can only persist `[]bytes`. The `codec` must be deterministic. Most SDK application use [amino](./amino.md) as their `codec`. + +You can see an example of application type definition [here](https://github.com/cosmos/sdk-application-tutorial/blob/master/app.go#L27-L43). + +### Constructor Function + +This function constructs a new application of the type defined above. It is [called](https://github.com/cosmos/cosmos-sdk/blob/master/server/start.go#L117) everytime the full-node is started with the `start` command. Here are the main actions performed by this function: + +- Instanciate a new application with a reference to a `baseapp` instance, a codec and all the appropriate store keys. +- Instanciate all the `keepers` defined in the application's `type`. +- Initialize the application's [`routes`](./baseapp.md#routing) with the [`handlers`](#handler) of each one of the application's modules. When a transaction is relayed to the application by Tendermint via the ABCI, it is routed to the appropriate module's handler using the routes defined here. +- Initialize the application's [query routes](./baseapp.md#query-routing) with the [`queriers`](#querier) of each of the application's modules. When a user query comes in, it is routed to the appropriate module using the query routes defined here. +- Set the application's [`initChainer`](#initchainer) and mount the stores. +- Return the application. + +Note that this function only creates an instance of the app, while the actual state is either carried over from the `~/.appd/data` folder if the node is restarted, or generated from the genesis file if the node is started for the first time. + +You can see an example of application constructor [here](https://github.com/cosmos/sdk-application-tutorial/blob/master/app.go#L46-L128). + +### InitChainer + +The `initChainer` is a function that initializes the state of the application from a [genesis file](./genesis.md) (i.e. token balances of genesis accounts). It is called when the application received the `InitChain` message from the Tendermint engine, which happens when the node is started at `appBlockHeight == 0` (i.e. on genesis). The application must set the `initChainer` in its constructor via the [`setInitChainer`](https://godoc.org/github.com/cosmos/cosmos-sdk/baseapp#BaseApp.SetInitChainer) method. + +You can see an example of an `initChainer` [here](https://github.com/cosmos/sdk-application-tutorial/blob/master/app.go#L137-L155). + +### Register Codec + +The `MakeCodec` function is the last important function of the `app.go` file. The goal of this function is to instanciate a codec `cdc` (e.g. [amino](./amino.md)) and calls the `RegisterCodec(*codec.Codec)` method of each module used within the application to register `cdc` to each module. + +In turn, the `RegisterCodec` function of each module register the custom interfaces and type structures of their respective module so that they can be marhsaled and unmarshaled. + +You can see an example of a `MakeCodec` [here](You can see an example of an `initChainer` [here](https://github.com/cosmos/sdk-application-tutorial/blob/master/app.go#L189-L198).). + +## Modules + +Modules are the heart and soul of an SDK application. They can be considered as state-machines within the state-machine. When a transaction is relayed from the underlying Tendermint engine via the ABCI to the application, it is routed by `baseapp` to the appropriate module in order to be processed. This paradigm enables developers to easily build complex state-machines, as most of the modules they need often already exist. For developers, most of the work involved in building an SDK application revolves around building custom modules required by their application that do not exist, and integrating them with modules that do already exist into one coherent application. In the application directory, the standard practice is to store modules in the `x/` folder. + +To learn more about modules, [click here](./modules.md) + +### Message Types + +A message is a custom type defined by each module that implements the [`message`](https://github.com/cosmos/cosmos-sdk/blob/master/types/tx_msg.go#L8-L29) interface. Each `transaction` contains one or multiple `messages`. When a valid block of transactions is received by the full-node, Tendermint relays each one to the application via [`DeliverTx`](https://tendermint.com/docs/app-dev/abci-spec.html#delivertx). Upon receiving the transaction, the application first unmarshalls it. Then, it extracts the message(s) contained in the application. With the [`Type()`](https://github.com/cosmos/cosmos-sdk/blob/master/types/tx_msg.go#L16) method, `baseapp` is able to know which modules defines the message. It is then able to route it to the appropriate module's [handler](#handler) in order for the message to be processed. If the message is succesfully processed, the state is updated. + +Module developers create custom message types when they build their own module. The general practice is to prefix the type declaration of the message with `Msg`. For example, the message type `MsgSend` allows users to transfer tokens. It is processed by the handler of the `bank` module, which ultimately calls the `keeper` of the `auth` module in order to update the state. + +To learn more about messages, [click here](./tx-msgs.md) + +### Handler + +The `handler` refers to the part of the module responsible for processing the message after it is routed by `baseapp`. `handler` functions of modules (except those of the `auth` module) are only executed if the transaction is relayed from Tendermint by the `DeliverTx` ABCI message. If the transaction is realyed by `CheckTx`, only stateless checks and fee-related (i.e. `auth` module-related) stateful checks are performed. To better understand the difference between `DeliverTx`and `CheckTx`, as well as the difference between stateful and stateless checks, click [here](./tx-lifecycle.md). + +The handler of a module is generally defined in a file called `handler.go` and consists of: + +- A **switch function** `NewHandler` to route the message to the appropriate handler function. This function returns a `handler` function, and is used in `app.go` to initialize the [application's router](./baseapp.md#routing). See an example of such a switch [here](https://github.com/cosmos/sdk-application-tutorial/blob/master/x/nameservice/handler.go#L10-L22). +- **One handler function for each message type defined by the module**. Developers write the message processing logic in these functions. This generally involves doing stateful checks to ensure the message is valid and calling [`keeper`](#keeper)'s methods to update the state. + +Handler functions return a result of type [`sdk.Result`](https://github.com/cosmos/cosmos-sdk/blob/master/types/result.go#L14-L37), which informs the application on wether the message was succesfully processed and. + +To learn more about handlers, [click here](./handler.md). + +### Keeper + +`Keepers` are the gatekeepers of their module's store(s). To read or write in a module's store, it is mandatory to go through one of its `keeper`'s methods. This is ensured by the [object-capabilities](./ocap.md) model of the Cosmos SDK. Only objects that hold the key to a store can access it, and only the module's `keeper` should hold the key(s) to the module's store(s). + +`Keepers` are generally defined in a file called `keeper.go`. It contains the `keeper`'s type definition and methods. + +The `keeper` type definition generally consists of: + +- **Key(s)** to the module's store(s) in the multistore. +- Reference to **other module's `keepers`**. Only needed if the `keeper` needs to access other module's store(s) (either to read or write from them). +- A reference to the application's **codec**. The `keeper` needs it to marshal structs before storing them, or to unmarhsal them when it retrieves them, because stores only accept `[]bytes` as value. + +The rest of the file defines the `keeper`'s methods, primarily getters and setters. You can check an example of a `keeper` implementation [here](https://github.com/cosmos/sdk-application-tutorial/blob/master/x/nameservice/keeper.go). + +To learn more about `keepers`, [click here](./keeper.md). + +### Querier + +`Queriers` are very similar to `handlers`, except they serve user queries to the state as opposed to processing transactions. A query is initiated from an [interface](#intefaces) by an end-user who provides a `queryRoute` and some `data`. The query is then routed to the correct application's `querier` by `baseapp`'s [`handleQueryCustom`](https://github.com/cosmos/cosmos-sdk/blob/master/baseapp/baseapp.go#L519-L556) method using `queryRoute`. + +The `Querier` of a module are defined in a file called `querier.go`, and consists of: + +- A **switch function** `NewQuerier` to route the query to the appropriate `querier` function. This function returns a `querier` function, and is used in `app.go` to initialize the [application's query router](./baseapp.md#query-routing). See an example of such a switch [here](https://github.com/cosmos/sdk-application-tutorial/blob/master/x/nameservice/querier.go#L21-L34). +- - **One querier function for each data type defined by the module that needs to be queryable**. Developers write the query processing logic in these functions. This generally involves calling [`keeper`](#keeper)'s methods to query the state and marshalling it to JSON. See an example of `querier` functions [here](https://github.com/cosmos/sdk-application-tutorial/blob/master/x/nameservice/querier.go#L37-L101). + +To learn more about `queriers`, [click here](./querier.md). + +### Command-Line and REST Interfaces + +Each module defines command-line commands and REST routes to be exposed to end-user via the [application's interfaces](#application-interfaces). This enables end-users to create messages of the types defined in the module, or to query the subset of the state managed by the module. + +#### CLI + +Generally, the commands related to a module are defined in a folder called `client/cli` in the module's folder. The CLI divides commands in two category, transactions and queries, defined in `client/cli/tx.go` and `client/cli/query.go` respectively. Both build commands on top of the [Cobra Library](https://github.com/spf13/cobra): + +- Transactions commands let users generate new transactions so that they can be included in a block and eventually update the state. One command should be created for each [message type](#message-types) defined in the module. The command calls the constructor of the message with the parameters provided by the end-user, and wraps it into a transaction. The SDK handles signing and the addition of other transaction metadata. See examples of transactions commands [here](https://github.com/cosmos/sdk-application-tutorial/blob/master/x/nameservice/client/cli/tx.go). +- Queries let users query the subset of the state defined by the module. Query commands forward queries to the [application's query router](./baseapp.md#query-routing), which routes them to the appropriate [querier](#querier) the `queryRoute` parameter supplied. See examples of query commands [here](https://github.com/cosmos/sdk-application-tutorial/blob/master/x/nameservice/client/cli/query.go). + +To learn more about modules CLI, [click here](./module-interfaces.md#cli). + +#### REST + +The module's REST interface lets users generate transactions and query the state through REST calls to the application's [light-client daemon](./node.md#lcd). REST routes are defined in a file `client/rest/rest.go`, which is composed of: + +- A `RegisterRoutes` function, which registers each route defined in the file. This function is called from the [main application's interface](#application-interfaces) for each module used within the application. The router used in the SDK is [Gorilla's mux](https://github.com/gorilla/mux). +- Custom request type definitions for each query or transaction creation function that needs to be exposed. These custom request types build on the [base `request` type](https://github.com/cosmos/cosmos-sdk/blob/master/types/rest/rest.go#L32-L43) of the Cosmos SDK. +- One handler function for each request that can be routed to the given module. These functions implement the core logic necessary to serve the request. + +See an example of a module's `rest.go` file [here](https://github.com/cosmos/sdk-application-tutorial/blob/master/x/nameservice/client/rest/rest.go). + +To learn more about modules REST interface, [click here](./module-interfaces.md#rest). + +## Application Interface + +Interfaces let end-users interract with full-node clients. This means querying data from the full-node or creating and sending new transactions to be relayed by the full-node and eventually included in a block. + +The main interface is the [Command-Line Interface](./interfaces.md#cli). The CLI of an SDK application is built by aggregating [CLI commands](#cli) defined in each of the modules used by the application. The CLI of an application generally has the `-cli` suffix (e.g. `appcli`), and defined in a file called `cmd/appcli/main.go`. The file contains: + +- **A `main()` function**, which is executed to build the `appcli` interface client. This function prepares each command and adds them to the `rootCmd` before building them. At the root of `appCli`, the function adds generic commands like `status`, `keys` and `config`, query commands, tx commands and `rest-server`. +- **Query commands** are added by calling the `queryCmd` function, also defined in `appcli/main.go`. This function returns a Cobra command that contains the query commands defined in each of the application's modules (passed as an array of `sdk.ModuleClients` from the `main()` function), as well as some other lower level query commands such as block or validator queries. Query command are called by using the command `appcli query [query]` of the CLI. +- **Transaction commands** are added by calling the `txCmd` function. Similar to `queryCmd`, the function returns a Cobra command that contains the tx commands defined in each of the application's modules, as well as lower level tx commands like transaction signing or broadcasting. Tx commands are called by using the command `appcli tx [tx]` of the CLI. +- **A `registerRoutes` function**, which is called from the `main()` function when initializing the [application's light-client daemon (LCD)](./node.md#lcd) (i.e. `rest-server`). `registerRoutes` calls the `RegisterRoutes` function of each of the application's module, thereby registering the routes of the module to the lcd's router. The LCD can be started by running the following command `appcli rest-server`. + +See an example of an application's main command-line file [here](https://github.com/cosmos/sdk-application-tutorial/blob/master/cmd/nscli/main.go). + +To learn more about interfaces, [click here](./interfaces.md) + +## Dependencies and Makefile + + + +## Next + +Learn more about the [Lifecycle of a transaction](./tx-lifecycle.md). \ No newline at end of file diff --git a/docs/intro/why-app-specific.md b/docs/intro/why-app-specific.md index ce454383711c..0873f87d0e4a 100644 --- a/docs/intro/why-app-specific.md +++ b/docs/intro/why-app-specific.md @@ -74,5 +74,5 @@ The fundamental issue here is that the governance of the application and the gov Clearly, application-specific blockchains are awesome. The Cosmos SDK makes it easier than ever to build them. What are you waiting for? -- Learn how to build an application-specific blockchain from scratch with the [SDK tutorial](https://cosmos.network/docs/tutorial) - Learn more about the [high-level architecture](./sdk-app-architecture) of an SDK application. +- Learn how to build an application-specific blockchain from scratch with the [SDK tutorial](https://cosmos.network/docs/tutorial) From 8ee9c4a4cf437d917825ee3f0d62b58192ebb681 Mon Sep 17 00:00:00 2001 From: gamarin Date: Mon, 10 Jun 2019 15:13:41 +0200 Subject: [PATCH 082/196] refactor for new module interface --- docs/.vuepress/config.js | 2 +- docs/concepts/app-anatomy.md | 132 +++++++++++++++--------- docs/concepts/{amino.md => encoding.md} | 0 docs/concepts/fees-signature.md | 7 ++ docs/concepts/invariants.md | 5 + docs/concepts/modules.md | 7 +- 6 files changed, 105 insertions(+), 48 deletions(-) rename docs/concepts/{amino.md => encoding.md} (100%) create mode 100644 docs/concepts/fees-signature.md create mode 100644 docs/concepts/invariants.md diff --git a/docs/.vuepress/config.js b/docs/.vuepress/config.js index d8756aae2385..602d20781420 100644 --- a/docs/.vuepress/config.js +++ b/docs/.vuepress/config.js @@ -32,7 +32,7 @@ module.exports = { "/intro/why-app-specific", "/intro/sdk-app-architecture", "/intro/sdk-design", - "intro/ocap" + "/intro/ocap" ] }, { diff --git a/docs/concepts/app-anatomy.md b/docs/concepts/app-anatomy.md index 346b35abab80..1646e0f39e8a 100644 --- a/docs/concepts/app-anatomy.md +++ b/docs/concepts/app-anatomy.md @@ -28,16 +28,16 @@ The core parts listed above will generally translate to the following directory │ └── bank ├── Gopkg.toml └── Makefile -``` +``` -## Node Client (Daemon) +## Node Client -The Daemon, or Full-Node Client, is the core process of an SDK-based blockchain. Participants in the network run this process to initialize their state-machine, connect with other full-nodes and update their state-machine as new blocks come in. +The Daemon, or Full-Node Client, is the core process of an SDK-based blockchain. Participants in the network run this process to initialize their state-machine, connect with other full-nodes and update their state-machine as new blocks come in. ``` ^ +-------------------------------+ ^ | | | | - | | State+machine = Application | | + | | State-machine = Application | | | | | | Built with Cosmos SDK | | ^ + | | | +----------- | ABCI | ----------+ v @@ -55,73 +55,111 @@ The blockchain full-node presents itself as a binary, generally suffixed by `-d` To learn more about the `main.go` function, [click here](./node.md#main-function). -Once the main binary is built, the node can be started by running the `start` command. The core logic behind the `start` command is implemented in the SDK itself in the [`/server/start.go`](https://github.com/cosmos/cosmos-sdk/blob/master/server/start.go) file. The main [`start` command function](https://github.com/cosmos/cosmos-sdk/blob/master/server/start.go#L31) takes a [`context`](https://godoc.org/github.com/cosmos/cosmos-sdk/client/context) and [`appCreator`](#constructor-function-(`appCreator`)) as arguments. The `appCreator` is a constructor function for the SDK application, and is used in the starting process of the full-node. +Once the main binary is built, the node can be started by running the `start` command. The core logic behind the `start` command is implemented in the SDK itself in the [`/server/start.go`](https://github.com/cosmos/cosmos-sdk/blob/master/server/start.go) file. The main [`start` command function](https://github.com/cosmos/cosmos-sdk/blob/master/server/start.go#L31) takes a [`context`](https://godoc.org/github.com/cosmos/cosmos-sdk/client/context) and [`appCreator`](#constructor-function-(`appCreator`)) as arguments. The `appCreator` is a constructor function for the SDK application, and is used in the starting process of the full-node. The `start` command function primarily does three things: -1- Create an instance of the state-machine defined in [`app.go`](#core-application-file) using the `appCreator`. -2- Initialize the state-machine with the latest known state, extracted from the `db` stored in the `~/.appd/data` folder. At this point, the state-machine is at height `appBlockHeight`. -3- Create and start a new Tendermint instance. Among other things, the node will perform a handshake with its peers. It will get the latest `blockHeight` from them, and replay blocks to sync to this height if it is greater than the local `appBlockHeight`. If `appBlockHeight` is `0`, the node is starting from genesis and Tendermint sends an `InitChain` message via the ABCI to the `app`, which triggers the [`InitChainer`](#initchainer). +1. Create an instance of the state-machine defined in [`app.go`](#core-application-file) using the `appCreator`. +2. Initialize the state-machine with the latest known state, extracted from the `db` stored in the `~/.appd/data` folder. At this point, the state-machine is at height `appBlockHeight`. +3. Create and start a new Tendermint instance. Among other things, the node will perform a handshake with its peers. It will get the latest `blockHeight` from them, and replay blocks to sync to this height if it is greater than the local `appBlockHeight`. If `appBlockHeight` is `0`, the node is starting from genesis and Tendermint sends an `InitChain` message via the ABCI to the `app`, which triggers the [`InitChainer`](#initchainer). To learn more about the `start` command, [click here](./node.md#start-command). ## Core Application File -In general, the core of the state-machine is defined in a file called `app.go`. It mainly contains the **type definition of the application** and functions to **create and initialize it**. +In general, the core of the state-machine is defined in a file called `app.go`. It mainly contains the **type definition of the application** and functions to **create and initialize it**. ### Type Definition of the Application The first thing defined in `app.go` is the `type` of the application. It is generally comprised of the following parts: -- **A reference to [`baseapp`](./baseapp.md).** The custom application defined in `app.go` is a golang embedding of the `baseapp` type. `baseapp` implements most of the core logic for the application, including all the [ABCI methods](https://tendermint.com/docs/spec/abci/abci.html#overview) and the routing logic. When a transaction is relayed by Tendermint to the application, the latter uses `baseapp`'s methods to route them to the appropriate module. +- **A reference to [`baseapp`](./baseapp.md).** The custom application defined in `app.go` is an extension of the `baseapp` type. `baseapp` implements most of the core logic for the application, including all the [ABCI methods](https://tendermint.com/docs/spec/abci/abci.html#overview) and the routing logic. When a transaction is relayed by Tendermint to the application, the latter uses `baseapp`'s methods to route them to the appropriate module. - **A list of store keys**. The [store](./store.md), which contains the entire state, is implemented as a multistore (i.e. a store of stores) in the Cosmos SDK. Each module uses one or multiple stores in the multistore to persist their part of the state. These stores can be accessed with specific keys that are declared in the `app` type. These keys, along with the `keepers`, are at the heart of the [object-capabilities model](../intro/ocap.md) of the Cosmos SDK. -- **A list of module's `keepers`.** Each module defines an abstraction called `keeper`, which handles reads and writes for this module's store(s). The `keeper`'s methods of one module can be called from other modules (if authorized), which is why they are declared in the application's type. -- **A reference to a `codec`.** The Cosmos SDK gives developers the freedom to choose the encoding framework for their application. The application's `codec` is used to serialize and deserialize data structures in order to store them, as stores can only persist `[]bytes`. The `codec` must be deterministic. Most SDK application use [amino](./amino.md) as their `codec`. +- **A list of module's [`keepers`](#keeper).** Each module defines an abstraction called `keeper`, which handles reads and writes for this module's store(s). The `keeper`'s methods of one module can be called from other modules (if authorized), which is why they are declared in the application's type. +- **A reference to a `codec`.** The Cosmos SDK gives developers the freedom to choose the encoding framework for their application. The application's `codec` is used to serialize and deserialize data structures in order to store them, as stores can only persist `[]bytes`. The `codec` must be deterministic. Most SDK application use [amino](./amino.md) as their `codec`. +- **A reference to a [module manager](./modules.md#module-manager)**. The module manager is an object that contains a list of the application's module. It facilitates operations related to these modules, like registering [`routes`](./baseapp.md#routing), [query routes](#./baseapp.md#query-routing) or setting the order of execution between modules for various functions like [`InitChainer`](#initchainer), [`BeginBlocker` and `EndBlocker`](#beginblocker-and-endblocker). -You can see an example of application type definition [here](https://github.com/cosmos/sdk-application-tutorial/blob/master/app.go#L27-L43). +You can see an example of application type definition [here](https://github.com/cosmos/gaia/blob/master/app/app.go#L73-L107). ### Constructor Function This function constructs a new application of the type defined above. It is [called](https://github.com/cosmos/cosmos-sdk/blob/master/server/start.go#L117) everytime the full-node is started with the `start` command. Here are the main actions performed by this function: -- Instanciate a new application with a reference to a `baseapp` instance, a codec and all the appropriate store keys. -- Instanciate all the `keepers` defined in the application's `type`. -- Initialize the application's [`routes`](./baseapp.md#routing) with the [`handlers`](#handler) of each one of the application's modules. When a transaction is relayed to the application by Tendermint via the ABCI, it is routed to the appropriate module's handler using the routes defined here. -- Initialize the application's [query routes](./baseapp.md#query-routing) with the [`queriers`](#querier) of each of the application's modules. When a user query comes in, it is routed to the appropriate module using the query routes defined here. -- Set the application's [`initChainer`](#initchainer) and mount the stores. -- Return the application. +- Instantiate a new application with a reference to a `baseapp` instance, a codec and all the appropriate store keys. +- Instantiate all the [`keeper`s](#keeper) defined in the application's `type` using the `NewKeeper` function of each of the application's modules. Note that `keepers` must be instantiated in the correct order, as the `NewKeeper` of one module might require a reference to another module's `keeper`. +- Instantiate the application's [module manager](./module-manager.md) with the [`AppModule`](#application-module-interface) object of each of the application's modules. +- With the module manager, initialize the application's [`routes`](./baseapp.md#routing) and [query routes](./baseapp.md#query-routing). When a transaction is relayed to the application by Tendermint via the ABCI, it is routed to the appropriate module's [`handler`](#handler) using the routes defined here. Likewise, when a query is received by the application, it is routed to the appropriate module's [`querier`](#querier) using the query routes defined here. +- With the module manager, register the [application's modules' invariants](./invariants.md). Invariants are variables (e.g. total supply of a token) that are evaluated at the end of each block. The process of checking invariants is done via a special module called the [`InvariantsRegistry`](./invariants.md#invariant-registry). The value of the ivnariant should be equal to a predicted value defined in the module. Should the value be different than the predicted one, special logic defined in the invariant registry will be triggered (usually the chain is halted). This is useful to make sure no critical bug goes unoticed and produces long-lasting effects that would be hard to fix. +- With the module manager, set the order of execution between the `InitGenesis`, `BegingBlocker` and `EndBlocker` functions of each of the [application's modules](#application-module-interface). Note that not all modules implement these functions. +- Set the application's [`InitChainer`](#initchainer) (used to initialize the application when it is first started), [`BeginBlocker`, `EndBlocker`](#beginblocker-and-endlbocker) (called at the beginning and the end of every block) and [`anteHandler`](#baseapp.md#antehandler) (used to handle fees and signature verification). +- Mount the stores. +- Return the application. -Note that this function only creates an instance of the app, while the actual state is either carried over from the `~/.appd/data` folder if the node is restarted, or generated from the genesis file if the node is started for the first time. +Note that this function only creates an instance of the app, while the actual state is either carried over from the `~/.appd/data` folder if the node is restarted, or generated from the genesis file if the node is started for the first time. -You can see an example of application constructor [here](https://github.com/cosmos/sdk-application-tutorial/blob/master/app.go#L46-L128). +You can see an example of application constructor [here](https://github.com/cosmos/gaia/blob/master/app/app.go#L110-L222). ### InitChainer -The `initChainer` is a function that initializes the state of the application from a [genesis file](./genesis.md) (i.e. token balances of genesis accounts). It is called when the application received the `InitChain` message from the Tendermint engine, which happens when the node is started at `appBlockHeight == 0` (i.e. on genesis). The application must set the `initChainer` in its constructor via the [`setInitChainer`](https://godoc.org/github.com/cosmos/cosmos-sdk/baseapp#BaseApp.SetInitChainer) method. +The `InitChainer` is a function that initializes the state of the application from a [genesis file](./genesis.md) (i.e. token balances of genesis accounts). It is called when the application receives the `InitChain` message from the Tendermint engine, which happens when the node is started at `appBlockHeight == 0` (i.e. on genesis). The application must set the `InitChainer` in its constructor via the [`SetInitChainer`](https://godoc.org/github.com/cosmos/cosmos-sdk/baseapp#BaseApp.SetInitChainer) method. + +In general, the `InitChainer` is mostly composed of the `InitGenesis` function of each of the application's modules. This is done by calling the `InitGenesis` function of the module manager, which in turn will call the `InitGenesis` function of each of the modules it contains. Note that the order in which the modules' `InitGenesis` functions must be called has to be set in the module manager using the `SetOrderInitGenesis` method. This is done in the [application's constructor](#application-constructor), and the `SetOrderInitGenesis` has to be called before the `SetInitChainer`. + +You can see an example of an `InitChainer` [here](https://github.com/cosmos/gaia/blob/master/app/app.go#L235-L239). + +### BeginBlocker and EndBlocker -You can see an example of an `initChainer` [here](https://github.com/cosmos/sdk-application-tutorial/blob/master/app.go#L137-L155). +The SDK offers developers the possibility to implement automatic execution of code as part of their application. This is implemented through two function called `BeginBlocker` and `EndBlocker`. They are called when the application receives respectively the `BeginBlock` and `EndBlock` messages from the Tendermint engine, which happens at the beginning and at the end of each block. The application must set the `BeginBlocker` and `EndBlocker` in its constructor via the [`SetBeginBlocker`](https://godoc.org/github.com/cosmos/cosmos-sdk/baseapp#BaseApp.SetBeginBlocker) and [`SetEndBlocker`](https://godoc.org/github.com/cosmos/cosmos-sdk/baseapp#BaseApp.SetEndBlocker) methods. + +In general, the `BeginBlocker` and `EndBlocker` functions are mostly composed of the `BeginBlock` and `EndBlock` functions of each of the application's modules. This is done by calling the `BeginBlock` and `EndBlock` functions of the module manager, which in turn will call the `BeginBLock` and `EndBlock` functions of each of the modules it contains. Note that the order in which the modules' `BegingBlock` and `EndBlock` functions must be called has to be set in the module manager using the `SetOrderBeginBlock` and `SetOrderEndBlock` methods respectively. This is done in the [application's constructor](#application-constructor), and the `SetOrderBeginBlock` and `SetOrderEndBlock` methods have to be called before the `SetBeginBlocker` and `SetEndBlocker` functions. + +As a sidenote, it is important to remember that application-specific blockchains are deterministic. Developers must be careful not to introduce non-determinism in `BeginBlocker` or `EndBlocker`, and must also be careful not to make them too computationally expensive, as [gas](./fees-signature.md/gas) does not constrain the cost of `BeginBlocker` and `EndBlocker` execution. + +You can see an example of `BeginBlocker` and `EndBlocker` functions [here](https://github.com/cosmos/gaia/blob/master/app/app.go#L224-L232). ### Register Codec -The `MakeCodec` function is the last important function of the `app.go` file. The goal of this function is to instanciate a codec `cdc` (e.g. [amino](./amino.md)) and calls the `RegisterCodec(*codec.Codec)` method of each module used within the application to register `cdc` to each module. +The `MakeCodec` function is the last important function of the `app.go` file. The goal of this function is to instantiate a codec `cdc` (e.g. [amino](./amino.md)) initiliaze the codec of the SDK and each of the application's modules using the `RegisterCodec` function. -In turn, the `RegisterCodec` function of each module register the custom interfaces and type structures of their respective module so that they can be marhsaled and unmarshaled. +To register the application's modules, the `MakeCodec` function calls `RegisterCodec` on `ModuleBasics`. `ModuleBasics` is a [basic manager](./modules.md#basic-manager) which lists all of the application's modules. It is instanciated in the `init()` function, and only serves to easily register non-dependant elements of application's modules (such as codec). To learn more about the basic module manager, click [here](./modules.md#basic-manager). -You can see an example of a `MakeCodec` [here](You can see an example of an `initChainer` [here](https://github.com/cosmos/sdk-application-tutorial/blob/master/app.go#L189-L198).). +You can see an example of a `MakeCodec` [here](https://github.com/cosmos/gaia/blob/master/app/app.go#L64-L70) ## Modules -Modules are the heart and soul of an SDK application. They can be considered as state-machines within the state-machine. When a transaction is relayed from the underlying Tendermint engine via the ABCI to the application, it is routed by `baseapp` to the appropriate module in order to be processed. This paradigm enables developers to easily build complex state-machines, as most of the modules they need often already exist. For developers, most of the work involved in building an SDK application revolves around building custom modules required by their application that do not exist, and integrating them with modules that do already exist into one coherent application. In the application directory, the standard practice is to store modules in the `x/` folder. +Modules are the heart and soul of an SDK application. They can be considered as state-machines within the state-machine. When a transaction is relayed from the underlying Tendermint engine via the ABCI to the application, it is routed by `baseapp` to the appropriate module in order to be processed. This paradigm enables developers to easily build complex state-machines, as most of the modules they need often already exist. For developers, most of the work involved in building an SDK application revolves around building custom modules required by their application that do not exist, and integrating them with modules that do already exist into one coherent application. In the application directory, the standard practice is to store modules in the `x/` folder (not to be confused with the SDK's `x/` folder, which contains already-built modules). To learn more about modules, [click here](./modules.md) +### Application Module Interface + +Modules implement two interfaces defined in the Cosmos SDK, [`AppModuleBasic`](https://github.com/cosmos/cosmos-sdk/blob/master/types/module/module.go#L44-L57) and [`AppModule`](https://github.com/cosmos/cosmos-sdk/blob/master/types/module/module.go#L44-L57). The former implements basic non-dependant elements of the module, such as the `codec`, while the latter handles the bulk of the module methods (including methods that require references to other modules' `keeper`s). Both the `AppModule` and `AppModuleBasic` types are defined in a file called `./module.go`. + +`AppModule` exposes a collection of useful methods on the module that facilitates the composition of modules into a coherent application. Important methods include: + +- `Route()` and `QueryRoute()`: These methods the name of the route and querier route for the module, for [messages](#message-types) to be routed to the module's [`handler`](#handler) and queries to be routes to the module's [`querier`](#querier). +- `NewHandler()` and `NewQuerierHandler()`: These methods return a `handler` and `querierHandler` respectively, in order to process a message or a query once they are routed. +- `BeginBlock()`, `EndBlock()` and `InitGenesis()`: These methods are executed respectively at the beginning of each block, at the end of each block and at the start of the chain. They implement special logic the module requires to be triggered during those events. For example, the `EndBlock` function is frequently used by modules where voting occurs to tally the result of the votes. +- `RegisterInvariants()`: This method registers the [invariants](./invariants.md) for the module. Invariants are checked at the end of every block to make sure no unpredicted behaviour is occuring. + +`AppModule`'s methods are called from the `module manager`(./modules.md#module-manager), which manages the application's collection of modules. + +To learn more about the application module interface, [click here](./modules.md#application-module-interface). + ### Message Types -A message is a custom type defined by each module that implements the [`message`](https://github.com/cosmos/cosmos-sdk/blob/master/types/tx_msg.go#L8-L29) interface. Each `transaction` contains one or multiple `messages`. When a valid block of transactions is received by the full-node, Tendermint relays each one to the application via [`DeliverTx`](https://tendermint.com/docs/app-dev/abci-spec.html#delivertx). Upon receiving the transaction, the application first unmarshalls it. Then, it extracts the message(s) contained in the application. With the [`Type()`](https://github.com/cosmos/cosmos-sdk/blob/master/types/tx_msg.go#L16) method, `baseapp` is able to know which modules defines the message. It is then able to route it to the appropriate module's [handler](#handler) in order for the message to be processed. If the message is succesfully processed, the state is updated. +A message is a custom type defined by each module that implements the [`message`](https://github.com/cosmos/cosmos-sdk/blob/master/types/tx_msg.go#L8-L29) interface. Each `transaction` contains one or multiple `messages`. When a valid block of transactions is received by the full-node, Tendermint relays each one to the application via [`DeliverTx`](https://tendermint.com/docs/app-dev/abci-spec.html#delivertx). Then, the application handles the transaction: + +1. Upon receiving the transaction, the application first unmarshalls it from `[]bytes`. +2. Then, it verifies a few things about the transaction like [fee payment and signatures](#fees-signature.md) before extracting the message(s) contained in the transaction. +3. With the [`Type()`](https://github.com/cosmos/cosmos-sdk/blob/master/types/tx_msg.go#L16) method, `baseapp` is able to know which modules defines the message. It is then able to route it to the appropriate module's [handler](#handler) in order for the message to be processed. +4. If the message is successfully processed, the state is updated. -Module developers create custom message types when they build their own module. The general practice is to prefix the type declaration of the message with `Msg`. For example, the message type `MsgSend` allows users to transfer tokens. It is processed by the handler of the `bank` module, which ultimately calls the `keeper` of the `auth` module in order to update the state. +For a more detailed look at a transaction lifecycle, click [here](./tx-lifecycle.md). -To learn more about messages, [click here](./tx-msgs.md) +Module developers create custom message types when they build their own module. The general practice is to prefix the type declaration of the message with `Msg`. For example, the message type [`MsgSend`](https://github.com/cosmos/cosmos-sdk/blob/master/x/bank/types/msgs.go#L10-L15) allows users to transfer tokens. It is processed by the handler of the `bank` module, which ultimately calls the `keeper` of the `auth` module in order to update the state. + +To learn more about messages, [click here](./tx-msgs.md). ### Handler @@ -129,8 +167,8 @@ The `handler` refers to the part of the module responsible for processing the me The handler of a module is generally defined in a file called `handler.go` and consists of: -- A **switch function** `NewHandler` to route the message to the appropriate handler function. This function returns a `handler` function, and is used in `app.go` to initialize the [application's router](./baseapp.md#routing). See an example of such a switch [here](https://github.com/cosmos/sdk-application-tutorial/blob/master/x/nameservice/handler.go#L10-L22). -- **One handler function for each message type defined by the module**. Developers write the message processing logic in these functions. This generally involves doing stateful checks to ensure the message is valid and calling [`keeper`](#keeper)'s methods to update the state. +- A **switch function** `NewHandler` to route the message to the appropriate handler function. This function returns a `handler` function, and is registered in the [`AppModule`](#application-module-interface) to be used in the application's module manager to initialize the [application's router](./baseapp.md#routing). See an example of such a switch [here](https://github.com/cosmos/sdk-application-tutorial/blob/master/x/nameservice/handler.go#L10-L22). +- **One handler function for each message type defined by the module**. Developers write the message processing logic in these functions. This generally involves doing stateful checks to ensure the message is valid and calling [`keeper`](#keeper)'s methods to update the state. Handler functions return a result of type [`sdk.Result`](https://github.com/cosmos/cosmos-sdk/blob/master/types/result.go#L14-L37), which informs the application on wether the message was succesfully processed and. @@ -140,36 +178,38 @@ To learn more about handlers, [click here](./handler.md). `Keepers` are the gatekeepers of their module's store(s). To read or write in a module's store, it is mandatory to go through one of its `keeper`'s methods. This is ensured by the [object-capabilities](./ocap.md) model of the Cosmos SDK. Only objects that hold the key to a store can access it, and only the module's `keeper` should hold the key(s) to the module's store(s). -`Keepers` are generally defined in a file called `keeper.go`. It contains the `keeper`'s type definition and methods. +`Keepers` are generally defined in a file called `keeper.go`. It contains the `keeper`'s type definition and methods. The `keeper` type definition generally consists of: -- **Key(s)** to the module's store(s) in the multistore. +- **Key(s)** to the module's store(s) in the multistore. - Reference to **other module's `keepers`**. Only needed if the `keeper` needs to access other module's store(s) (either to read or write from them). -- A reference to the application's **codec**. The `keeper` needs it to marshal structs before storing them, or to unmarhsal them when it retrieves them, because stores only accept `[]bytes` as value. +- A reference to the application's **codec**. The `keeper` needs it to marshal structs before storing them, or to unmarshal them when it retrieves them, because stores only accept `[]bytes` as value. + +Along with the type definition, the next important component of the `keeper.go` file is the `keeper`'s constructor function, `NewKeeper`. This function instantiates a new `keeper` of the type defined above, with a `codec`, store `keys` and potentially references to other modules' `keeper`s as parameters. The `NewKeeper` function is called from the [application's constructor](#constructor-function). The rest of the file defines the `keeper`'s methods, primarily getters and setters. You can check an example of a `keeper` implementation [here](https://github.com/cosmos/sdk-application-tutorial/blob/master/x/nameservice/keeper.go). To learn more about `keepers`, [click here](./keeper.md). -### Querier +### Querier -`Queriers` are very similar to `handlers`, except they serve user queries to the state as opposed to processing transactions. A query is initiated from an [interface](#intefaces) by an end-user who provides a `queryRoute` and some `data`. The query is then routed to the correct application's `querier` by `baseapp`'s [`handleQueryCustom`](https://github.com/cosmos/cosmos-sdk/blob/master/baseapp/baseapp.go#L519-L556) method using `queryRoute`. +`Queriers` are very similar to `handlers`, except they serve user queries to the state as opposed to processing transactions. A query is initiated from an [interface](#intefaces) by an end-user who provides a `queryRoute` and some `data`. The query is then routed to the correct application's `querier` by `baseapp`'s [`handleQueryCustom`](https://github.com/cosmos/cosmos-sdk/blob/master/baseapp/baseapp.go#L519-L556) method using `queryRoute`. The `Querier` of a module are defined in a file called `querier.go`, and consists of: -- A **switch function** `NewQuerier` to route the query to the appropriate `querier` function. This function returns a `querier` function, and is used in `app.go` to initialize the [application's query router](./baseapp.md#query-routing). See an example of such a switch [here](https://github.com/cosmos/sdk-application-tutorial/blob/master/x/nameservice/querier.go#L21-L34). +- A **switch function** `NewQuerier` to route the query to the appropriate `querier` function. This function returns a `querier` function, and is is registered in the [`AppModule`](#application-module-interface) to be used in the application's module manager to initialize the [application's query router](./baseapp.md#query-routing). See an example of such a switch [here](https://github.com/cosmos/sdk-application-tutorial/blob/master/x/nameservice/querier.go#L21-L34). - - **One querier function for each data type defined by the module that needs to be queryable**. Developers write the query processing logic in these functions. This generally involves calling [`keeper`](#keeper)'s methods to query the state and marshalling it to JSON. See an example of `querier` functions [here](https://github.com/cosmos/sdk-application-tutorial/blob/master/x/nameservice/querier.go#L37-L101). To learn more about `queriers`, [click here](./querier.md). ### Command-Line and REST Interfaces -Each module defines command-line commands and REST routes to be exposed to end-user via the [application's interfaces](#application-interfaces). This enables end-users to create messages of the types defined in the module, or to query the subset of the state managed by the module. +Each module defines command-line commands and REST routes to be exposed to end-user via the [application's interfaces](#application-interfaces). This enables end-users to create messages of the types defined in the module, or to query the subset of the state managed by the module. #### CLI -Generally, the commands related to a module are defined in a folder called `client/cli` in the module's folder. The CLI divides commands in two category, transactions and queries, defined in `client/cli/tx.go` and `client/cli/query.go` respectively. Both build commands on top of the [Cobra Library](https://github.com/spf13/cobra): +Generally, the commands related to a module are defined in a folder called `client/cli` in the module's folder. The CLI divides commands in two category, transactions and queries, defined in `client/cli/tx.go` and `client/cli/query.go` respectively. Both commands are built on top of the [Cobra Library](https://github.com/spf13/cobra): - Transactions commands let users generate new transactions so that they can be included in a block and eventually update the state. One command should be created for each [message type](#message-types) defined in the module. The command calls the constructor of the message with the parameters provided by the end-user, and wraps it into a transaction. The SDK handles signing and the addition of other transaction metadata. See examples of transactions commands [here](https://github.com/cosmos/sdk-application-tutorial/blob/master/x/nameservice/client/cli/tx.go). - Queries let users query the subset of the state defined by the module. Query commands forward queries to the [application's query router](./baseapp.md#query-routing), which routes them to the appropriate [querier](#querier) the `queryRoute` parameter supplied. See examples of query commands [here](https://github.com/cosmos/sdk-application-tutorial/blob/master/x/nameservice/client/cli/query.go). @@ -181,7 +221,7 @@ To learn more about modules CLI, [click here](./module-interfaces.md#cli). The module's REST interface lets users generate transactions and query the state through REST calls to the application's [light-client daemon](./node.md#lcd). REST routes are defined in a file `client/rest/rest.go`, which is composed of: - A `RegisterRoutes` function, which registers each route defined in the file. This function is called from the [main application's interface](#application-interfaces) for each module used within the application. The router used in the SDK is [Gorilla's mux](https://github.com/gorilla/mux). -- Custom request type definitions for each query or transaction creation function that needs to be exposed. These custom request types build on the [base `request` type](https://github.com/cosmos/cosmos-sdk/blob/master/types/rest/rest.go#L32-L43) of the Cosmos SDK. +- Custom request type definitions for each query or transaction creation function that needs to be exposed. These custom request types build on the [base `request` type](https://github.com/cosmos/cosmos-sdk/blob/master/types/rest/rest.go#L32-L43) of the Cosmos SDK. - One handler function for each request that can be routed to the given module. These functions implement the core logic necessary to serve the request. See an example of a module's `rest.go` file [here](https://github.com/cosmos/sdk-application-tutorial/blob/master/x/nameservice/client/rest/rest.go). @@ -190,23 +230,23 @@ To learn more about modules REST interface, [click here](./module-interfaces.md# ## Application Interface -Interfaces let end-users interract with full-node clients. This means querying data from the full-node or creating and sending new transactions to be relayed by the full-node and eventually included in a block. +Interfaces let end-users interact with full-node clients. This means querying data from the full-node or creating and sending new transactions to be relayed by the full-node and eventually included in a block. The main interface is the [Command-Line Interface](./interfaces.md#cli). The CLI of an SDK application is built by aggregating [CLI commands](#cli) defined in each of the modules used by the application. The CLI of an application generally has the `-cli` suffix (e.g. `appcli`), and defined in a file called `cmd/appcli/main.go`. The file contains: - **A `main()` function**, which is executed to build the `appcli` interface client. This function prepares each command and adds them to the `rootCmd` before building them. At the root of `appCli`, the function adds generic commands like `status`, `keys` and `config`, query commands, tx commands and `rest-server`. -- **Query commands** are added by calling the `queryCmd` function, also defined in `appcli/main.go`. This function returns a Cobra command that contains the query commands defined in each of the application's modules (passed as an array of `sdk.ModuleClients` from the `main()` function), as well as some other lower level query commands such as block or validator queries. Query command are called by using the command `appcli query [query]` of the CLI. +- **Query commands** are added by calling the `queryCmd` function, also defined in `appcli/main.go`. This function returns a Cobra command that contains the query commands defined in each of the application's modules (passed as an array of `sdk.ModuleClients` from the `main()` function), as well as some other lower level query commands such as block or validator queries. Query command are called by using the command `appcli query [query]` of the CLI. - **Transaction commands** are added by calling the `txCmd` function. Similar to `queryCmd`, the function returns a Cobra command that contains the tx commands defined in each of the application's modules, as well as lower level tx commands like transaction signing or broadcasting. Tx commands are called by using the command `appcli tx [tx]` of the CLI. -- **A `registerRoutes` function**, which is called from the `main()` function when initializing the [application's light-client daemon (LCD)](./node.md#lcd) (i.e. `rest-server`). `registerRoutes` calls the `RegisterRoutes` function of each of the application's module, thereby registering the routes of the module to the lcd's router. The LCD can be started by running the following command `appcli rest-server`. +- **A `registerRoutes` function**, which is called from the `main()` function when initializing the [application's light-client daemon (LCD)](./node.md#lcd) (i.e. `rest-server`). `registerRoutes` calls the `RegisterRoutes` function of each of the application's module, thereby registering the routes of the module to the lcd's router. The LCD can be started by running the following command `appcli rest-server`. See an example of an application's main command-line file [here](https://github.com/cosmos/sdk-application-tutorial/blob/master/cmd/nscli/main.go). To learn more about interfaces, [click here](./interfaces.md) -## Dependencies and Makefile +## Dependencies and Makefile ## Next -Learn more about the [Lifecycle of a transaction](./tx-lifecycle.md). \ No newline at end of file +Learn more about the [Lifecycle of a transaction](./tx-lifecycle.md). diff --git a/docs/concepts/amino.md b/docs/concepts/encoding.md similarity index 100% rename from docs/concepts/amino.md rename to docs/concepts/encoding.md diff --git a/docs/concepts/fees-signature.md b/docs/concepts/fees-signature.md new file mode 100644 index 000000000000..36982a97b5d8 --- /dev/null +++ b/docs/concepts/fees-signature.md @@ -0,0 +1,7 @@ +# Fees and Signatures + +## Signatures + +## Fees + +## Gas \ No newline at end of file diff --git a/docs/concepts/invariants.md b/docs/concepts/invariants.md new file mode 100644 index 000000000000..18cd9ad6224f --- /dev/null +++ b/docs/concepts/invariants.md @@ -0,0 +1,5 @@ +# Invariants + +## What is an invariant + +## Invariant Registry \ No newline at end of file diff --git a/docs/concepts/modules.md b/docs/concepts/modules.md index cfd71f817963..5c65c4d89f92 100644 --- a/docs/concepts/modules.md +++ b/docs/concepts/modules.md @@ -1,3 +1,8 @@ # SDK Modules -Todo: Intro concept docs on modules \ No newline at end of file +Todo: Intro concept docs on modules + +## Application Module Interface + +## Module Manager + From cefe24d7d008f8069440a45666b78b6980281e77 Mon Sep 17 00:00:00 2001 From: gamarin Date: Tue, 11 Jun 2019 16:09:21 +0200 Subject: [PATCH 083/196] karoly review --- docs/concepts/app-anatomy.md | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/docs/concepts/app-anatomy.md b/docs/concepts/app-anatomy.md index 1646e0f39e8a..78d7b1eda675 100644 --- a/docs/concepts/app-anatomy.md +++ b/docs/concepts/app-anatomy.md @@ -75,8 +75,8 @@ The first thing defined in `app.go` is the `type` of the application. It is gene - **A reference to [`baseapp`](./baseapp.md).** The custom application defined in `app.go` is an extension of the `baseapp` type. `baseapp` implements most of the core logic for the application, including all the [ABCI methods](https://tendermint.com/docs/spec/abci/abci.html#overview) and the routing logic. When a transaction is relayed by Tendermint to the application, the latter uses `baseapp`'s methods to route them to the appropriate module. - **A list of store keys**. The [store](./store.md), which contains the entire state, is implemented as a multistore (i.e. a store of stores) in the Cosmos SDK. Each module uses one or multiple stores in the multistore to persist their part of the state. These stores can be accessed with specific keys that are declared in the `app` type. These keys, along with the `keepers`, are at the heart of the [object-capabilities model](../intro/ocap.md) of the Cosmos SDK. -- **A list of module's [`keepers`](#keeper).** Each module defines an abstraction called `keeper`, which handles reads and writes for this module's store(s). The `keeper`'s methods of one module can be called from other modules (if authorized), which is why they are declared in the application's type. -- **A reference to a `codec`.** The Cosmos SDK gives developers the freedom to choose the encoding framework for their application. The application's `codec` is used to serialize and deserialize data structures in order to store them, as stores can only persist `[]bytes`. The `codec` must be deterministic. Most SDK application use [amino](./amino.md) as their `codec`. +- **A list of module's `keepers`.** Each module defines an abstraction called `keeper`, which handles reads and writes for this module's store(s). The `keeper`'s methods of one module can be called from other modules (if authorized), which is why they are declared in the application's type and exported as interfaces to other modules so that they are only allowed to access the authorized functions. +- **A reference to a `codec`.** The Cosmos SDK gives developers the freedom to choose the encoding framework for their application. The application's `codec` is used to serialize and deserialize data structures in order to store them, as stores can only persist `[]bytes`. The `codec` must be deterministic. The default codec is [amino](./amino.md). - **A reference to a [module manager](./modules.md#module-manager)**. The module manager is an object that contains a list of the application's module. It facilitates operations related to these modules, like registering [`routes`](./baseapp.md#routing), [query routes](#./baseapp.md#query-routing) or setting the order of execution between modules for various functions like [`InitChainer`](#initchainer), [`BeginBlocker` and `EndBlocker`](#beginblocker-and-endblocker). You can see an example of application type definition [here](https://github.com/cosmos/gaia/blob/master/app/app.go#L73-L107). @@ -91,7 +91,10 @@ This function constructs a new application of the type defined above. It is [cal - With the module manager, initialize the application's [`routes`](./baseapp.md#routing) and [query routes](./baseapp.md#query-routing). When a transaction is relayed to the application by Tendermint via the ABCI, it is routed to the appropriate module's [`handler`](#handler) using the routes defined here. Likewise, when a query is received by the application, it is routed to the appropriate module's [`querier`](#querier) using the query routes defined here. - With the module manager, register the [application's modules' invariants](./invariants.md). Invariants are variables (e.g. total supply of a token) that are evaluated at the end of each block. The process of checking invariants is done via a special module called the [`InvariantsRegistry`](./invariants.md#invariant-registry). The value of the ivnariant should be equal to a predicted value defined in the module. Should the value be different than the predicted one, special logic defined in the invariant registry will be triggered (usually the chain is halted). This is useful to make sure no critical bug goes unoticed and produces long-lasting effects that would be hard to fix. - With the module manager, set the order of execution between the `InitGenesis`, `BegingBlocker` and `EndBlocker` functions of each of the [application's modules](#application-module-interface). Note that not all modules implement these functions. -- Set the application's [`InitChainer`](#initchainer) (used to initialize the application when it is first started), [`BeginBlocker`, `EndBlocker`](#beginblocker-and-endlbocker) (called at the beginning and the end of every block) and [`anteHandler`](#baseapp.md#antehandler) (used to handle fees and signature verification). +- Set the remainer of application's parameters: + + [`InitChainer`](#initchainer): used to initialize the application when it is first started. + + [`BeginBlocker`, `EndBlocker`](#beginblocker-and-endlbocker): called at the beginning and the end of every block). + + [`anteHandler`](#baseapp.md#antehandler): used to handle fees and signature verification. - Mount the stores. - Return the application. From c3bdae6866f03bfa8e78501dd4515ab61426e1bf Mon Sep 17 00:00:00 2001 From: gamarin Date: Mon, 17 Jun 2019 16:55:53 +0200 Subject: [PATCH 084/196] working on baseapp doc --- docs/concepts/baseapp_old.md | 128 +++++++++++++++++++++++++++++ docs/concepts/store.md | 8 ++ docs/core/baseapp_old.md | 151 +++++++++++++---------------------- 3 files changed, 192 insertions(+), 95 deletions(-) create mode 100644 docs/concepts/baseapp_old.md create mode 100644 docs/concepts/store.md diff --git a/docs/concepts/baseapp_old.md b/docs/concepts/baseapp_old.md new file mode 100644 index 000000000000..c4f71f33f696 --- /dev/null +++ b/docs/concepts/baseapp_old.md @@ -0,0 +1,128 @@ +# BaseApp + +The BaseApp defines the foundational implementation for a basic ABCI application +so that your Cosmos-SDK application can communicate with an underlying +Tendermint node. + +The BaseApp is composed of many internal components. Some of the most important +include the `CommitMultiStore` and its internal state. The internal state is +essentially two sub-states, both of which are used for transaction execution +during different phases, `CheckTx` and `DeliverTx` respectively. During block +commitment, only the `DeliverTx` is persisted. + +The BaseApp requires stores to be mounted via capabilities keys - handlers can +only access stores they're given the key to. The `baseApp` ensures all stores are +properly loaded, cached, and committed. One mounted store is considered the +"main" (`baseApp.MainStoreKey`) - it holds the latest block header, from which we can find and load the +most recent state. + +The BaseApp distinguishes between two handler types - the `AnteHandler` and the +`MsgHandler`. The former is a global validity check (checking nonces, sigs and +sufficient balances to pay fees, e.g. things that apply to all transaction from +all modules), the later is the full state transition function. + +During `CheckTx` the state transition function is only applied to the `checkTxState` +and should return before any expensive state transitions are run +(this is up to each developer). It also needs to return the estimated gas cost. + +During `DeliverTx` the state transition function is applied to the blockchain +state and the transactions need to be fully executed. + +The BaseApp is responsible for managing the context passed into handlers - +it makes the block header available and provides the right stores for `CheckTx` +and `DeliverTx`. BaseApp is completely agnostic to serialization formats. + +## Routing + +TODO + +## Transaction Life Cycle + +During the execution of a transaction, it may pass through both `CheckTx` and +`DeliverTx` as defined in the ABCI specification. `CheckTx` is executed by the +proposing validator and is used for the Tendermint mempool for all full nodes. + +Both `CheckTx` and `DeliverTx` execute the application's AnteHandler (if +defined), where the AnteHandler is responsible for pre-message validation +checks such as account and signature validation, fee deduction and collection, +and incrementing sequence numbers. + +### CheckTx + +During the execution of `CheckTx`, only the AnteHandler is executed. + +State transitions due to the AnteHandler are persisted between subsequent calls +of `CheckTx` in the check-tx state, unless the AnteHandler fails and aborts. + +### DeliverTx + +During the execution of `DeliverTx`, the AnteHandler and Handler is executed. + +The transaction execution during `DeliverTx` operates in a similar fashion to +`CheckTx`. However, state transitions that occur during the AnteHandler are +persisted even when the following Handler processing logic fails. + +It is possible that a malicious proposer may include a transaction in a block +that fails the AnteHandler. In this case, all state transitions for the +offending transaction are discarded. + + +## Other ABCI Messages + +Besides `CheckTx` and `DeliverTx`, BaseApp handles the following ABCI messages. + +### Info +TODO complete description + +### SetOption +TODO complete description + +### Query +TODO complete description + +### InitChain +TODO complete description + +During chain initialization InitChain runs the initialization logic directly on +the CommitMultiStore. The deliver and check states are initialized with the +ChainID. + +Note that we do not commit after InitChain, so BeginBlock for block 1 starts +from the deliver state as initialized by InitChain. + +### BeginBlock +TODO complete description + +### EndBlock +TODO complete description + +### Commit +TODO complete description + + +## Gas Management + +### Gas: InitChain + +During InitChain, the block gas meter is initialized with an infinite amount of +gas to run any genesis transactions. + +Additionally, the InitChain request message includes ConsensusParams as +declared in the genesis.json file. + +### Gas: BeginBlock + +The block gas meter is reset during BeginBlock for the deliver state. If no +maximum block gas is set within baseapp then an infinite gas meter is set, +otherwise a gas meter with `ConsensusParam.BlockSize.MaxGas` is initialized. + +### Gas: DeliverTx + +Before the transaction logic is run, the `BlockGasMeter` is first checked to +see if any gas remains. If no gas remains, then `DeliverTx` immediately returns +an error. + +After the transaction has been processed, the used gas (up to the transaction +gas limit) is deducted from the BlockGasMeter. If the remaining gas exceeds the +meter's limits, then DeliverTx returns an error and the transaction is not +committed. diff --git a/docs/concepts/store.md b/docs/concepts/store.md new file mode 100644 index 000000000000..067eea3b79bd --- /dev/null +++ b/docs/concepts/store.md @@ -0,0 +1,8 @@ +# Store + +## Commit Multi Store + +## Database + +## Main Store + diff --git a/docs/core/baseapp_old.md b/docs/core/baseapp_old.md index c4f71f33f696..855b03cf1b55 100644 --- a/docs/core/baseapp_old.md +++ b/docs/core/baseapp_old.md @@ -1,128 +1,89 @@ # BaseApp -The BaseApp defines the foundational implementation for a basic ABCI application -so that your Cosmos-SDK application can communicate with an underlying -Tendermint node. - -The BaseApp is composed of many internal components. Some of the most important -include the `CommitMultiStore` and its internal state. The internal state is -essentially two sub-states, both of which are used for transaction execution -during different phases, `CheckTx` and `DeliverTx` respectively. During block -commitment, only the `DeliverTx` is persisted. - -The BaseApp requires stores to be mounted via capabilities keys - handlers can -only access stores they're given the key to. The `baseApp` ensures all stores are -properly loaded, cached, and committed. One mounted store is considered the -"main" (`baseApp.MainStoreKey`) - it holds the latest block header, from which we can find and load the -most recent state. - -The BaseApp distinguishes between two handler types - the `AnteHandler` and the -`MsgHandler`. The former is a global validity check (checking nonces, sigs and -sufficient balances to pay fees, e.g. things that apply to all transaction from -all modules), the later is the full state transition function. - -During `CheckTx` the state transition function is only applied to the `checkTxState` -and should return before any expensive state transitions are run -(this is up to each developer). It also needs to return the estimated gas cost. - -During `DeliverTx` the state transition function is applied to the blockchain -state and the transactions need to be fully executed. - -The BaseApp is responsible for managing the context passed into handlers - -it makes the block header available and provides the right stores for `CheckTx` -and `DeliverTx`. BaseApp is completely agnostic to serialization formats. +## Pre-requisite Reading -## Routing +- [Anatomy of an SDK application](./app-anatomy.md) +- [Lifecycle of an SDK transaction](./tx-lifecycle.md) -TODO +## Synopsis -## Transaction Life Cycle +This document describes `baseapp`, the abstraction that implements most of the common functionalities of an SDK application. -During the execution of a transaction, it may pass through both `CheckTx` and -`DeliverTx` as defined in the ABCI specification. `CheckTx` is executed by the -proposing validator and is used for the Tendermint mempool for all full nodes. +- [Introduction](#introduction) +- [Type Definition](#type-definition) +- [States and Modes](#states-and-modes) +- [Routing](#routing) +- [ABCI](#abci) +- [CheckTx](#abci-checktx) +- [DeliverTx](#abci-delivertx) +- [Commit](#abbci-commit) +- [Other ABCI Message](#other-abci-message) + + [Info](#info) + + [SetOption](#setoption) + + [Query](#query) + + [InitChain](#initchain) + + [BeginBlock](#beginblock) + + [EndBlock](#endblock) +- [Gas](#gas) -Both `CheckTx` and `DeliverTx` execute the application's AnteHandler (if -defined), where the AnteHandler is responsible for pre-message validation -checks such as account and signature validation, fee deduction and collection, -and incrementing sequence numbers. -### CheckTx +## Introduction -During the execution of `CheckTx`, only the AnteHandler is executed. +`baseapp` is an abstraction that implements the core of an SDK application, namely: -State transitions due to the AnteHandler are persisted between subsequent calls -of `CheckTx` in the check-tx state, unless the AnteHandler fails and aborts. +- The [Application-Blockchain Interface](#abci), for the state-machine to communicate with the underlying consensus engine (e.g. Tendermint). +- A [Router](#routing), to route [messages](./tx-msgs.md) and [queries](./querier.md) to the appropriate [module](./modules.md). +- Different [states and modes](#states-and-modes), as the state-machine can be in different modes depending on the ABCI message it processes. -### DeliverTx +The goal of `baseapp` is to provide a boilerplate SDK application that developers can easily extend to build their own custom application. Usually, developers will create a custom type for their application, like so: -During the execution of `DeliverTx`, the AnteHandler and Handler is executed. +```go +type app struct { + *bam.BaseApp // reference to baseapp + cdc *codec.Codec -The transaction execution during `DeliverTx` operates in a similar fashion to -`CheckTx`. However, state transitions that occur during the AnteHandler are -persisted even when the following Handler processing logic fails. + // list of application store keys -It is possible that a malicious proposer may include a transaction in a block -that fails the AnteHandler. In this case, all state transitions for the -offending transaction are discarded. + // list of application keepers + // module manager +} +``` -## Other ABCI Messages +Extending the application with `baseapp` gives the former access to all of `baseapp`'s methods. This allows developers to compose their custom application with the modules they want, while not having to concern themselves with the hard work of implementing the ABCI, the routing and state management logic. -Besides `CheckTx` and `DeliverTx`, BaseApp handles the following ABCI messages. +## Type Definition -### Info -TODO complete description +The [`baseapp` type](https://github.com/cosmos/cosmos-sdk/blob/master/baseapp/baseapp.go#L45-L91) holds many important parameters for any Cosmos SDK based application. Let us go through the most important components: -### SetOption -TODO complete description +- A [`CommitMultiStore`](./store.md#commit-multi-store). This is the main store of the application, which holds the canonical state that is committed at the [end of each block](#endblock). This store is **not** cached, meaning it is not used to update the application's intermediate (un-committed) states. The `CommitMultiStore` is a multi-store, meaning a store of stores. Each module of the application uses one or multiple `KVStores` in the multi-store to persist their subset of the state. +- A [database](./store.md#database) `db`, which is used by the `CommitMultiStore` to handle data storage. +- -### Query -TODO complete description +## States and Modes -### InitChain -TODO complete description - -During chain initialization InitChain runs the initialization logic directly on -the CommitMultiStore. The deliver and check states are initialized with the -ChainID. - -Note that we do not commit after InitChain, so BeginBlock for block 1 starts -from the deliver state as initialized by InitChain. - -### BeginBlock -TODO complete description +## Routing -### EndBlock -TODO complete description +## ABCI -### Commit -TODO complete description +## ABCI - CheckTx +## ABCI - DeliverTx -## Gas Management +## ABCI - Commit -### Gas: InitChain +## Other ABCI Messages -During InitChain, the block gas meter is initialized with an infinite amount of -gas to run any genesis transactions. +### Info -Additionally, the InitChain request message includes ConsensusParams as -declared in the genesis.json file. +### SetOption -### Gas: BeginBlock +### Query -The block gas meter is reset during BeginBlock for the deliver state. If no -maximum block gas is set within baseapp then an infinite gas meter is set, -otherwise a gas meter with `ConsensusParam.BlockSize.MaxGas` is initialized. +### InitChain -### Gas: DeliverTx +### BeginBlock -Before the transaction logic is run, the `BlockGasMeter` is first checked to -see if any gas remains. If no gas remains, then `DeliverTx` immediately returns -an error. +### EndBlock -After the transaction has been processed, the used gas (up to the transaction -gas limit) is deducted from the BlockGasMeter. If the remaining gas exceeds the -meter's limits, then DeliverTx returns an error and the transaction is not -committed. +## Gas \ No newline at end of file From 919ced40ce578c3bc86014cdcc962a7b194b181c Mon Sep 17 00:00:00 2001 From: gamarin Date: Thu, 27 Jun 2019 11:47:33 +0200 Subject: [PATCH 085/196] baseapp work --- docs/concepts/accounts-fees.md | 11 +++++ docs/concepts/app-anatomy.md | 4 +- docs/concepts/fees-signature.md | 7 --- docs/core/baseapp_old.md | 85 ++++++++++++++++++++++++++++----- 4 files changed, 85 insertions(+), 22 deletions(-) create mode 100644 docs/concepts/accounts-fees.md delete mode 100644 docs/concepts/fees-signature.md diff --git a/docs/concepts/accounts-fees.md b/docs/concepts/accounts-fees.md new file mode 100644 index 000000000000..9f03e0eb033d --- /dev/null +++ b/docs/concepts/accounts-fees.md @@ -0,0 +1,11 @@ +# Accounts, Fees and Signatures + +## Accounts + +## AnteHandler + +## Signatures + +## Fees + +## Gas \ No newline at end of file diff --git a/docs/concepts/app-anatomy.md b/docs/concepts/app-anatomy.md index 78d7b1eda675..177a84f19c7e 100644 --- a/docs/concepts/app-anatomy.md +++ b/docs/concepts/app-anatomy.md @@ -116,7 +116,7 @@ The SDK offers developers the possibility to implement automatic execution of co In general, the `BeginBlocker` and `EndBlocker` functions are mostly composed of the `BeginBlock` and `EndBlock` functions of each of the application's modules. This is done by calling the `BeginBlock` and `EndBlock` functions of the module manager, which in turn will call the `BeginBLock` and `EndBlock` functions of each of the modules it contains. Note that the order in which the modules' `BegingBlock` and `EndBlock` functions must be called has to be set in the module manager using the `SetOrderBeginBlock` and `SetOrderEndBlock` methods respectively. This is done in the [application's constructor](#application-constructor), and the `SetOrderBeginBlock` and `SetOrderEndBlock` methods have to be called before the `SetBeginBlocker` and `SetEndBlocker` functions. -As a sidenote, it is important to remember that application-specific blockchains are deterministic. Developers must be careful not to introduce non-determinism in `BeginBlocker` or `EndBlocker`, and must also be careful not to make them too computationally expensive, as [gas](./fees-signature.md/gas) does not constrain the cost of `BeginBlocker` and `EndBlocker` execution. +As a sidenote, it is important to remember that application-specific blockchains are deterministic. Developers must be careful not to introduce non-determinism in `BeginBlocker` or `EndBlocker`, and must also be careful not to make them too computationally expensive, as [gas](./accounts-fees.md/gas) does not constrain the cost of `BeginBlocker` and `EndBlocker` execution. You can see an example of `BeginBlocker` and `EndBlocker` functions [here](https://github.com/cosmos/gaia/blob/master/app/app.go#L224-L232). @@ -154,7 +154,7 @@ To learn more about the application module interface, [click here](./modules.md# A message is a custom type defined by each module that implements the [`message`](https://github.com/cosmos/cosmos-sdk/blob/master/types/tx_msg.go#L8-L29) interface. Each `transaction` contains one or multiple `messages`. When a valid block of transactions is received by the full-node, Tendermint relays each one to the application via [`DeliverTx`](https://tendermint.com/docs/app-dev/abci-spec.html#delivertx). Then, the application handles the transaction: 1. Upon receiving the transaction, the application first unmarshalls it from `[]bytes`. -2. Then, it verifies a few things about the transaction like [fee payment and signatures](#fees-signature.md) before extracting the message(s) contained in the transaction. +2. Then, it verifies a few things about the transaction like [fee payment and signatures](#accounts-fees.md) before extracting the message(s) contained in the transaction. 3. With the [`Type()`](https://github.com/cosmos/cosmos-sdk/blob/master/types/tx_msg.go#L16) method, `baseapp` is able to know which modules defines the message. It is then able to route it to the appropriate module's [handler](#handler) in order for the message to be processed. 4. If the message is successfully processed, the state is updated. diff --git a/docs/concepts/fees-signature.md b/docs/concepts/fees-signature.md deleted file mode 100644 index 36982a97b5d8..000000000000 --- a/docs/concepts/fees-signature.md +++ /dev/null @@ -1,7 +0,0 @@ -# Fees and Signatures - -## Signatures - -## Fees - -## Gas \ No newline at end of file diff --git a/docs/core/baseapp_old.md b/docs/core/baseapp_old.md index 855b03cf1b55..c239272fcba3 100644 --- a/docs/core/baseapp_old.md +++ b/docs/core/baseapp_old.md @@ -11,7 +11,7 @@ This document describes `baseapp`, the abstraction that implements most of the c - [Introduction](#introduction) - [Type Definition](#type-definition) -- [States and Modes](#states-and-modes) +- [States](#states) - [Routing](#routing) - [ABCI](#abci) - [CheckTx](#abci-checktx) @@ -33,7 +33,7 @@ This document describes `baseapp`, the abstraction that implements most of the c - The [Application-Blockchain Interface](#abci), for the state-machine to communicate with the underlying consensus engine (e.g. Tendermint). - A [Router](#routing), to route [messages](./tx-msgs.md) and [queries](./querier.md) to the appropriate [module](./modules.md). -- Different [states and modes](#states-and-modes), as the state-machine can be in different modes depending on the ABCI message it processes. +- Different [states](#states), as the state-machine can have different parallel states updated based on the ABCI message received. The goal of `baseapp` is to provide a boilerplate SDK application that developers can easily extend to build their own custom application. Usually, developers will create a custom type for their application, like so: @@ -54,26 +54,87 @@ Extending the application with `baseapp` gives the former access to all of `base ## Type Definition -The [`baseapp` type](https://github.com/cosmos/cosmos-sdk/blob/master/baseapp/baseapp.go#L45-L91) holds many important parameters for any Cosmos SDK based application. Let us go through the most important components: +The [`baseapp` type](https://github.com/cosmos/cosmos-sdk/blob/master/baseapp/baseapp.go#L45-L91) holds many important parameters for any Cosmos SDK based application. Let us go through the most important components. -- A [`CommitMultiStore`](./store.md#commit-multi-store). This is the main store of the application, which holds the canonical state that is committed at the [end of each block](#endblock). This store is **not** cached, meaning it is not used to update the application's intermediate (un-committed) states. The `CommitMultiStore` is a multi-store, meaning a store of stores. Each module of the application uses one or multiple `KVStores` in the multi-store to persist their subset of the state. +*Note: Not all parameters are described, only the most important ones. Refer to the [type definition](https://github.com/cosmos/cosmos-sdk/blob/master/baseapp/baseapp.go#L45-L91) for the full list* + +First, the important parameters that are initialized during the initialization of the application: + +- A [`CommitMultiStore`](./store.md#commit-multi-store). This is the main store of the application, which holds the canonical state that is committed at the [end of each block](#commit). This store is **not** cached, meaning it is not used to update the application's intermediate (un-committed) states. The `CommitMultiStore` is a multi-store, meaning a store of stores. Each module of the application uses one or multiple `KVStores` in the multi-store to persist their subset of the state. - A [database](./store.md#database) `db`, which is used by the `CommitMultiStore` to handle data storage. -- +- A [router](#messages). The `router` facilitates the routing of [messages](./tx-msgs.md) to the appropriate module for it to be processed. +- A [query router](#queries). The `query router` facilitates the routing of [queries](./querier.md) to the appropriate module for it to be processed. +- A [`txDecoder`](https://godoc.org/github.com/cosmos/cosmos-sdk/types#TxDecoder), used to decode transaction `[]byte` relayed by the underlying Tendermint engine. +- A [`baseKey`], to access the [main store](./store.md#main-store) in the `CommitMultiStore`. The main store is used to persist data related to the core of the application, like consensus parameters. +- A [`anteHandler`](./accounts-fees.md#antehandler), to handle signature verification and fee paiement when a transaction is received. +- An [`initChainer`](./app-anatomy.md#initchainer), [`beginBlocker` and `endBlocker`](./app-anatomy.md#beginblocker-and-endblocker), which are the functions executed when the application received the [InitChain], [BeginBlock] and [EndBlock] messages from the underlying Tendermint engine. + +Then, parameters used to define [volatile states](#volatile-states) (i.e. cached states): + +- `checkState`: This state is updated during [`CheckTx`](#checktx), and reset on [`Commit`](#commit). +- `deliverState`: This state is updated during [`DeliverTx`](#delivertx), and reset on [`Commit`](#commit). + +Finally, a few more important parameterd: + +- `voteInfos`: This parameter carries the list of validators whose precommit is missing, either because they did not vote or because the proposer did not include their vote. This information is carried by the [context](#context) and can be used by the application for various things like punishing absent validators. +- `minGasPrices`: This parameter defines the minimum [gas prices](./accounts-fees.md#gas) accepted by the node. This is a local parameter, meaning each full-node can set a different `minGasPrices`. It is run by the [`anteHandler`](./accounts-fees.md#antehandler) during `CheckTx`, mainly as a spam protection mechanism. The transaction enters the [mempool](https://tendermint.com/docs/tendermint-core/mempool.html#transaction-ordering) only if the gas price of the transaction is superior to one of the minimum gas price in `minGasPrices` (i.e. if `minGasPrices == 1uatom, 1upho`, the `gas-price` of the transaction must be superior to `1uatom` OR `1upho`). +- `appVersion`: Version of the application. It is set in the [application's constructor function](./baseapp.md#constructor-function). + +## States + +`baseapp` handles various parallel states for different purposes. There is the [main state](#main-state), which is the canonical state of the application, and volatile states like [`checkState`](#checkState) and [`deliverState`](#deliverstate), which are used to handle temporary states inbetween updates of the main state. + +### Main State + +The main state is the canonical state of the application. It is initialized on [`InitChain`](#initchain and updated on [`Commit`](#abci-commit) at the end of each block. + +``` ++--------+ +--------+ +| | | | +| S +----------------------------> | S' | +| | For each T in B: apply(T) | | ++--------+ +--------+ +``` + +The main state is held by `baseapp` in a structure called the [`CommitMultiStore`](./store.md#commit-multi-store). This multi-store is used by developers to instantiate all the stores they need for each of their application's modules. -## States and Modes +### Volatile States + +Volatile - or cached - states are used in between [`Commit`s](#commit) to manage temporary states. They are reset to the latest version of the main state after it is committed. There are two main volatile states: + +- `checkState`: This cached state is initialized during [`InitChain`](#initchain), updated during [`CheckTx`](#abci-checktx) when an unconfirmed transaction is received, and reset to the [main state](#main-state) on [`Commit`](#abci-commit). +- `deliverState`: This cached state is initialized during [`BeginBlock`](#beginblock), updated during [`DeliverTx`](#abci-delivertx) when a transaction included in a block is processed, and reset to the [main state](#main-state) on [`Commit`](#abci-commit). ## Routing -## ABCI +When messages and queries are received by the application, they must be routed to the appropriate module in order to be processed. Routing is done via `baseapp`, which holds a `router` for messages, and a `query router` for queries. + +### Message Routing + +Messages need to be routed after they are extracted from transactions, which are sent from the underlying Tendermint engine via the [`CheckTx`](#checktx) and [`DeliverTx`](#delivertx) ABCI messages. To do so, `baseapp` holds a [`router`](https://github.com/cosmos/cosmos-sdk/blob/master/baseapp/router.go) which maps `paths` (`string`) to the appropriate module [`handler`](./handler.md). Usually, the `path` is the name of the module. + +The application's `router` is initilalized with all the routes using the application's [module manager](./modules.md#module-manager), which itself is initialized with all the application's modules in the application's [constructor](./app-anatomy.md#app-constructor). + +### Query Routing + +Similar to messages, queries need to be routed to the appropriate module's [querier](./querier.md). To do so, `baseapp` holds a [`query router`](https://github.com/cosmos/cosmos-sdk/blob/master/baseapp/queryrouter.go), which maps `paths` (`string`) to the appropriate module [`querier`](./querier.md). Usually, the `path` is the name of the module. -## ABCI - CheckTx +Just like the `router`, the `query router` is initilalized with all the query routes using the application's [module manager](./modules.md#module-manager), which itself is initialized with all the application's modules in the application's [constructor](./app-anatomy.md#app-constructor). -## ABCI - DeliverTx +## Main ABCI Messages -## ABCI - Commit + + +### CheckTx + +### DeliverTx + +## RunTx and RunMsg ## Other ABCI Messages +### Commit + ### Info ### SetOption @@ -84,6 +145,4 @@ The [`baseapp` type](https://github.com/cosmos/cosmos-sdk/blob/master/baseapp/ba ### BeginBlock -### EndBlock - -## Gas \ No newline at end of file +### EndBlock \ No newline at end of file From a8a06b13642ff3ef8481d1abc347cb127e355ad2 Mon Sep 17 00:00:00 2001 From: gamarin Date: Thu, 27 Jun 2019 11:59:31 +0200 Subject: [PATCH 086/196] reorg --- docs/{concepts => basics}/accounts-fees.md | 0 docs/basics/app-anatomy.md | 63 ++--- docs/building-modules/module-interfaces.md | 280 ++++++++++++++++++++- docs/concepts/app-anatomy.md | 4 +- docs/concepts/baseapp_old.md | 128 ---------- docs/concepts/genesis.md | 3 - docs/concepts/store.md | 8 - docs/core/baseapp_old.md | 148 ----------- docs/{concepts => modules}/handler.md | 0 docs/{concepts => modules}/invariants.md | 0 docs/{concepts => modules}/keeper.md | 0 docs/modules/module-interfaces.md | 5 + docs/{concepts => modules}/modules.md | 0 docs/{concepts => modules}/querier.md | 0 14 files changed, 319 insertions(+), 320 deletions(-) rename docs/{concepts => basics}/accounts-fees.md (100%) delete mode 100644 docs/concepts/baseapp_old.md delete mode 100644 docs/concepts/genesis.md delete mode 100644 docs/concepts/store.md delete mode 100644 docs/core/baseapp_old.md rename docs/{concepts => modules}/handler.md (100%) rename docs/{concepts => modules}/invariants.md (100%) rename docs/{concepts => modules}/keeper.md (100%) create mode 100644 docs/modules/module-interfaces.md rename docs/{concepts => modules}/modules.md (100%) rename docs/{concepts => modules}/querier.md (100%) diff --git a/docs/concepts/accounts-fees.md b/docs/basics/accounts-fees.md similarity index 100% rename from docs/concepts/accounts-fees.md rename to docs/basics/accounts-fees.md diff --git a/docs/basics/app-anatomy.md b/docs/basics/app-anatomy.md index 15e1c9fc1e22..bca2c0c2774f 100644 --- a/docs/basics/app-anatomy.md +++ b/docs/basics/app-anatomy.md @@ -57,7 +57,7 @@ The blockchain full-node presents itself as a binary, generally suffixed by `-d` To learn more about the `main.go` function, [click here](../core/node.md#main-function). -Once the main binary is built, the node can be started by running the `start` command. The core logic behind the `start` command is implemented in the SDK itself in the [`/server/start.go`](https://github.com/cosmos/cosmos-sdk/blob/master/server/start.go) file. The main [`start` command function](https://github.com/cosmos/cosmos-sdk/blob/master/server/start.go#L31) takes a [`context`](https://godoc.org/github.com/cosmos/cosmos-sdk/client/context) and [`appCreator`](<#constructor-function-(`appCreator`)>) as arguments. The `appCreator` is a constructor function for the SDK application, and is used in the starting process of the full-node. +Once the main binary is built, the node can be started by running the `start` command. The core logic behind the `start` command is implemented in the SDK itself in the [`/server/start.go`](https://github.com/cosmos/cosmos-sdk/blob/master/server/start.go) file. The main [`start` command function](https://github.com/cosmos/cosmos-sdk/blob/master/server/start.go#L31) takes a [`context`](https://godoc.org/github.com/cosmos/cosmos-sdk/client/context) and [`appCreator`](#constructor-function-(`appCreator`)) as arguments. The `appCreator` is a constructor function for the SDK application, and is used in the starting process of the full-node. The `start` command function primarily does three things: @@ -73,11 +73,11 @@ In general, the core of the state-machine is defined in a file called `app.go`. The first thing defined in `app.go` is the `type` of the application. It is generally comprised of the following parts: -- **A reference to [`baseapp`](../core/baseapp.md).** The custom application defined in `app.go` is an extension of the `baseapp` type. `baseapp` implements most of the core logic for the application, including all the [ABCI methods](https://tendermint.com/docs/spec/abci/abci.html#overview) and the routing logic. When a transaction is relayed by Tendermint to the application, the latter uses `baseapp`'s methods to route them to the appropriate module. -- **A list of store keys**. The [store](../core/store.md), which contains the entire state, is implemented as a multistore (i.e. a store of stores) in the Cosmos SDK. Each module uses one or multiple stores in the multistore to persist their part of the state. These stores can be accessed with specific keys that are declared in the `app` type. These keys, along with the `keepers`, are at the heart of the [object-capabilities model](../intro/ocap.md) of the Cosmos SDK. -- **A list of module's `keepers`.** Each module defines an abstraction called [`keeper`](../building-modules/keeper.md), which handles reads and writes for this module's store(s). The `keeper`'s methods of one module can be called from other modules (if authorized), which is why they are declared in the application's type and exported as interfaces to other modules so that they are only allowed to access the authorized functions. -- **A reference to a [`codec`](../core/encoding.md).** The Cosmos SDK gives developers the freedom to choose the encoding framework for their application. The application's `codec` is used to serialize and deserialize data structures in order to store them, as stores can only persist `[]bytes`. The `codec` must be deterministic. The default codec is [amino](./amino.md). -- **A reference to a [module manager](../building-modules/module-manager.md#manager)** and a [basic module manager](../building-modules/module-manager.md#basicmanager). The module manager is an object that contains a list of the application's module. It facilitates operations related to these modules, like registering [`routes`](./baseapp.md#routing), [query routes](#./baseapp.md#query-routing) or setting the order of execution between modules for various functions like [`InitChainer`](#initchainer), [`BeginBlocker` and `EndBlocker`](#beginblocker-and-endblocker). +- **A reference to [`baseapp`](./baseapp.md).** The custom application defined in `app.go` is an extension of the `baseapp` type. `baseapp` implements most of the core logic for the application, including all the [ABCI methods](https://tendermint.com/docs/spec/abci/abci.html#overview) and the routing logic. When a transaction is relayed by Tendermint to the application, the latter uses `baseapp`'s methods to route them to the appropriate module. +- **A list of store keys**. The [store](./store.md), which contains the entire state, is implemented as a multistore (i.e. a store of stores) in the Cosmos SDK. Each module uses one or multiple stores in the multistore to persist their part of the state. These stores can be accessed with specific keys that are declared in the `app` type. These keys, along with the `keepers`, are at the heart of the [object-capabilities model](../intro/ocap.md) of the Cosmos SDK. +- **A list of module's `keepers`.** Each module defines an abstraction called `keeper`, which handles reads and writes for this module's store(s). The `keeper`'s methods of one module can be called from other modules (if authorized), which is why they are declared in the application's type and exported as interfaces to other modules so that they are only allowed to access the authorized functions. +- **A reference to a `codec`.** The Cosmos SDK gives developers the freedom to choose the encoding framework for their application. The application's `codec` is used to serialize and deserialize data structures in order to store them, as stores can only persist `[]bytes`. The `codec` must be deterministic. The default codec is [amino](./amino.md). +- **A reference to a [module manager](./modules.md#module-manager)**. The module manager is an object that contains a list of the application's module. It facilitates operations related to these modules, like registering [`routes`](./baseapp.md#routing), [query routes](#./baseapp.md#query-routing) or setting the order of execution between modules for various functions like [`InitChainer`](#initchainer), [`BeginBlocker` and `EndBlocker`](#beginblocker-and-endblocker). You can see an example of application type definition [here](https://github.com/cosmos/gaia/blob/master/app/app.go#L73-L107). @@ -87,17 +87,17 @@ This function constructs a new application of the type defined above. It is call - Instantiate a new [`codec`](../core/encoding.md) and initialize the `codec` of each of the application's module using the [basic manager](../building-modules/module-manager.md#basicmanager) - Instantiate a new application with a reference to a `baseapp` instance, a codec and all the appropriate store keys. -- Instantiate all the [`keeper`s](#keeper) defined in the application's `type` using the `NewKeeper` function of each of the application's modules. Note that `keepers` must be instantiated in the correct order, as the `NewKeeper` of one module might require a reference to another module's `keeper`. -- Instantiate the application's [module manager](../building-modules/module-manager.md#manager) with the [`AppModule`](#application-module-interface) object of each of the application's modules. -- With the module manager, initialize the application's [`routes`](../core/baseapp.md#routing) and [query routes](../core/baseapp.md#query-routing). When a transaction is relayed to the application by Tendermint via the ABCI, it is routed to the appropriate module's [`handler`](#handler) using the routes defined here. Likewise, when a query is received by the application, it is routed to the appropriate module's [`querier`](#querier) using the query routes defined here. -- With the module manager, register the [application's modules' invariants](./invariants.md). Invariants are variables (e.g. total supply of a token) that are evaluated at the end of each block. The process of checking invariants is done via a special module called the [`InvariantsRegistry`](../building-modules/invariants.md#invariant-registry). The value of the invariant should be equal to a predicted value defined in the module. Should the value be different than the predicted one, special logic defined in the invariant registry will be triggered (usually the chain is halted). This is useful to make sure no critical bug goes unnoticed and produces long-lasting effects that would be hard to fix. +- Instantiate all the [`keeper`s](#keeper) defined in the application's `type` using the `NewKeeper` function of each of the application's modules. Note that `keepers` must be instantiated in the correct order, as the `NewKeeper` of one module might require a reference to another module's `keeper`. +- Instantiate the application's [module manager](./module-manager.md) with the [`AppModule`](#application-module-interface) object of each of the application's modules. +- With the module manager, initialize the application's [`routes`](./baseapp.md#routing) and [query routes](./baseapp.md#query-routing). When a transaction is relayed to the application by Tendermint via the ABCI, it is routed to the appropriate module's [`handler`](#handler) using the routes defined here. Likewise, when a query is received by the application, it is routed to the appropriate module's [`querier`](#querier) using the query routes defined here. +- With the module manager, register the [application's modules' invariants](./invariants.md). Invariants are variables (e.g. total supply of a token) that are evaluated at the end of each block. The process of checking invariants is done via a special module called the [`InvariantsRegistry`](./invariants.md#invariant-registry). The value of the invariant should be equal to a predicted value defined in the module. Should the value be different than the predicted one, special logic defined in the invariant registry will be triggered (usually the chain is halted). This is useful to make sure no critical bug goes unnoticed and produces long-lasting effects that would be hard to fix. - With the module manager, set the order of execution between the `InitGenesis`, `BegingBlocker` and `EndBlocker` functions of each of the [application's modules](#application-module-interface). Note that not all modules implement these functions. - Set the remainer of application's parameters: + [`InitChainer`](#initchainer): used to initialize the application when it is first started. + [`BeginBlocker`, `EndBlocker`](#beginblocker-and-endlbocker): called at the beginning and the end of every block). - + [`anteHandler`](../core/baseapp.md#antehandler): used to handle fees and signature verification. -- Mount the stores. -- Return the application. + + [`anteHandler`](#baseapp.md#antehandler): used to handle fees and signature verification. +- Mount the stores. +- Return the application. Note that this function only creates an instance of the app, while the actual state is either carried over from the `~/.appd/data` folder if the node is restarted, or generated from the genesis file if the node is started for the first time. @@ -105,7 +105,7 @@ You can see an example of application constructor [here](https://github.com/cosm ### InitChainer -The `InitChainer` is a function that initializes the state of the application from a [genesis file](../core/genesis.md) (i.e. token balances of genesis accounts). It is called when the application receives the `InitChain` message from the Tendermint engine, which happens when the node is started at `appBlockHeight == 0` (i.e. on genesis). The application must set the `InitChainer` in its constructor via the [`SetInitChainer`](https://godoc.org/github.com/cosmos/cosmos-sdk/baseapp#BaseApp.SetInitChainer) method. +The `InitChainer` is a function that initializes the state of the application from a [genesis file](./genesis.md) (i.e. token balances of genesis accounts). It is called when the application receives the `InitChain` message from the Tendermint engine, which happens when the node is started at `appBlockHeight == 0` (i.e. on genesis). The application must set the `InitChainer` in its constructor via the [`SetInitChainer`](https://godoc.org/github.com/cosmos/cosmos-sdk/baseapp#BaseApp.SetInitChainer) method. In general, the `InitChainer` is mostly composed of the `InitGenesis` function of each of the application's modules. This is done by calling the `InitGenesis` function of the module manager, which in turn will call the `InitGenesis` function of each of the modules it contains. Note that the order in which the modules' `InitGenesis` functions must be called has to be set in the module manager using the `SetOrderInitGenesis` method. This is done in the [application's constructor](#application-constructor), and the `SetOrderInitGenesis` has to be called before the `SetInitChainer`. @@ -117,13 +117,13 @@ The SDK offers developers the possibility to implement automatic execution of co In general, the `BeginBlocker` and `EndBlocker` functions are mostly composed of the `BeginBlock` and `EndBlock` functions of each of the application's modules. This is done by calling the `BeginBlock` and `EndBlock` functions of the module manager, which in turn will call the `BeginBLock` and `EndBlock` functions of each of the modules it contains. Note that the order in which the modules' `BegingBlock` and `EndBlock` functions must be called has to be set in the module manager using the `SetOrderBeginBlock` and `SetOrderEndBlock` methods respectively. This is done in the [application's constructor](#application-constructor), and the `SetOrderBeginBlock` and `SetOrderEndBlock` methods have to be called before the `SetBeginBlocker` and `SetEndBlocker` functions. -As a sidenote, it is important to remember that application-specific blockchains are deterministic. Developers must be careful not to introduce non-determinism in `BeginBlocker` or `EndBlocker`, and must also be careful not to make them too computationally expensive, as [gas](./accounts-fees-gas.md/gas) does not constrain the cost of `BeginBlocker` and `EndBlocker` execution. +As a sidenote, it is important to remember that application-specific blockchains are deterministic. Developers must be careful not to introduce non-determinism in `BeginBlocker` or `EndBlocker`, and must also be careful not to make them too computationally expensive, as [gas](./accounts-fees.md/gas) does not constrain the cost of `BeginBlocker` and `EndBlocker` execution. You can see an example of `BeginBlocker` and `EndBlocker` functions [here](https://github.com/cosmos/gaia/blob/master/app/app.go#L224-L232). ### Register Codec -The `MakeCodec` function is the last important function of the `app.go` file. The goal of this function is to instantiate a codec `cdc` (e.g. amino) initialize the codec of the SDK and each of the application's modules using the `RegisterCodec` function. +The `MakeCodec` function is the last important function of the `app.go` file. The goal of this function is to instantiate a codec `cdc` (e.g. [amino](./amino.md)) initiliaze the codec of the SDK and each of the application's modules using the `RegisterCodec` function. To register the application's modules, the `MakeCodec` function calls `RegisterCodec` on `ModuleBasics`. `ModuleBasics` is a [basic manager](../building-modules/module-manager.md#basicmanager) which lists all of the application's modules. It is instanciated in the `init()` function, and only serves to easily register non-dependant elements of application's modules (such as codec). To learn more about the basic module manager, click [here](../building-modules/module-manager.md#basicmanager). @@ -131,15 +131,22 @@ You can see an example of a `MakeCodec` [here](https://github.com/cosmos/gaia/bl ## Modules -Modules are the heart and soul of an SDK application. They can be considered as state-machines within the state-machine. When a transaction is relayed from the underlying Tendermint engine via the ABCI to the application, it is routed by [`baseapp`](../core/baseapp.md) to the appropriate module in order to be processed. This paradigm enables developers to easily build complex state-machines, as most of the modules they need often already exist. For developers, most of the work involved in building an SDK application revolves around building custom modules required by their application that do not exist, and integrating them with modules that do already exist into one coherent application. In the application directory, the standard practice is to store modules in the `x/` folder (not to be confused with the SDK's `x/` folder, which contains already-built modules). +Modules are the heart and soul of an SDK application. They can be considered as state-machines within the state-machine. When a transaction is relayed from the underlying Tendermint engine via the ABCI to the application, it is routed by `baseapp` to the appropriate module in order to be processed. This paradigm enables developers to easily build complex state-machines, as most of the modules they need often already exist. For developers, most of the work involved in building an SDK application revolves around building custom modules required by their application that do not exist, and integrating them with modules that do already exist into one coherent application. In the application directory, the standard practice is to store modules in the `x/` folder (not to be confused with the SDK's `x/` folder, which contains already-built modules). To learn more about modules, [click here](./modules.md) ### Application Module Interface -Modules implement two interfaces defined in the Cosmos SDK, [`AppModuleBasic`](../building-modules/module-manager.md#appmodulebasic) and [`AppModule`](../building-modules/module-manager.md#appmodule). The former implements basic non-dependant elements of the module, such as the `codec`, while the latter handles the bulk of the module methods (including methods that require references to other modules' `keeper`s). Both the `AppModule` and `AppModuleBasic` types are defined in a file called `./module.go`. +Modules implement two interfaces defined in the Cosmos SDK, [`AppModuleBasic`](https://github.com/cosmos/cosmos-sdk/blob/master/types/module/module.go#L44-L57) and [`AppModule`](https://github.com/cosmos/cosmos-sdk/blob/master/types/module/module.go#L44-L57). The former implements basic non-dependant elements of the module, such as the `codec`, while the latter handles the bulk of the module methods (including methods that require references to other modules' `keeper`s). Both the `AppModule` and `AppModuleBasic` types are defined in a file called `./module.go`. -`AppModule` exposes a collection of useful methods on the module that facilitates the composition of modules into a coherent application. These methods are are called from the `module manager`(../building-modules/module-manager.md#manager), which manages the application's collection of modules. +`AppModule` exposes a collection of useful methods on the module that facilitates the composition of modules into a coherent application. Important methods include: + +- `Route()` and `QueryRoute()`: These methods the name of the route and querier route for the module, for [messages](#message-types) to be routed to the module's [`handler`](#handler) and queries to be routes to the module's [`querier`](#querier). +- `NewHandler()` and `NewQuerierHandler()`: These methods return a `handler` and `querierHandler` respectively, in order to process a message or a query once they are routed. +- `BeginBlock()`, `EndBlock()` and `InitGenesis()`: These methods are executed respectively at the beginning of each block, at the end of each block and at the start of the chain. They implement special logic the module requires to be triggered during those events. For example, the `EndBlock` function is frequently used by modules where voting occurs to tally the result of the votes. +- `RegisterInvariants()`: This method registers the [invariants](./invariants.md) for the module. Invariants are checked at the end of every block to make sure no unpredicted behaviour is occuring. + +`AppModule`'s methods are called from the `module manager`(./modules.md#module-manager), which manages the application's collection of modules. To learn more about the application module interface, [click here](../building-modules/module-manager.md#application-module-interfaces). @@ -148,9 +155,9 @@ To learn more about the application module interface, [click here](../building-m A message is a custom type defined by each module that implements the [`message`](../building-modules/messages-and-queries.md#messages) interface. Each [`transaction`](../core/transaction.md) contains one or multiple `messages`. When a valid block of transactions is received by the full-node, Tendermint relays each one to the application via [`DeliverTx`](https://tendermint.com/docs/app-dev/abci-spec.html#delivertx). Then, the application handles the transaction: 1. Upon receiving the transaction, the application first unmarshalls it from `[]bytes`. -2. Then, it verifies a few things about the transaction like [fee payment and signatures](#accounts-fees-gas.md) before extracting the message(s) contained in the transaction. -3. With the [`Type()`](https://github.com/cosmos/cosmos-sdk/blob/master/types/tx_msg.go#L16) method, `baseapp` is able to know which modules defines the message. It is then able to route it to the appropriate module's [handler](#handler) in order for the message to be processed. -4. If the message is successfully processed, the state is updated. +2. Then, it verifies a few things about the transaction like [fee payment and signatures](#accounts-fees.md) before extracting the message(s) contained in the transaction. +3. With the [`Type()`](https://github.com/cosmos/cosmos-sdk/blob/master/types/tx_msg.go#L16) method, `baseapp` is able to know which modules defines the message. It is then able to route it to the appropriate module's [handler](#handler) in order for the message to be processed. +4. If the message is successfully processed, the state is updated. For a more detailed look at a transaction lifecycle, click [here](./tx-lifecycle.md). @@ -164,8 +171,8 @@ The [`handler`](../building-modules/handler.md) refers to the part of the module The handler of a module is generally defined in a file called `handler.go` and consists of: -- A **switch function** `NewHandler` to route the message to the appropriate handler function. This function returns a `handler` function, and is registered in the [`AppModule`](#application-module-interface) to be used in the application's module manager to initialize the [application's router](../core/baseapp.md#routing). See an example of such a switch [here](https://github.com/cosmos/sdk-application-tutorial/blob/master/x/nameservice/handler.go#L10-L22). -- **One handler function for each message type defined by the module**. Developers write the message processing logic in these functions. This generally involves doing stateful checks to ensure the message is valid and calling [`keeper`](#keeper)'s methods to update the state. +- A **switch function** `NewHandler` to route the message to the appropriate handler function. This function returns a `handler` function, and is registered in the [`AppModule`](#application-module-interface) to be used in the application's module manager to initialize the [application's router](./baseapp.md#routing). See an example of such a switch [here](https://github.com/cosmos/sdk-application-tutorial/blob/master/x/nameservice/handler.go#L10-L22). +- **One handler function for each message type defined by the module**. Developers write the message processing logic in these functions. This generally involves doing stateful checks to ensure the message is valid and calling [`keeper`](#keeper)'s methods to update the state. Handler functions return a result of type [`sdk.Result`](https://github.com/cosmos/cosmos-sdk/blob/master/types/result.go#L14-L37), which informs the application on whether the message was successfully processed. @@ -189,9 +196,9 @@ The rest of the file defines the `keeper`'s methods, primarily getters and sette To learn more about `keepers`, [click here](../building-modules/keeper.md). -### Querier +### Querier -[`Queriers`](../building-modules/querier.md) are very similar to `handlers`, except they serve user queries to the state as opposed to processing transactions. A [query](../building-modules/messages-and-queries.md#queries) is initiated from an [interface](#interfaces) by an end-user who provides a `queryRoute` and some `data`. The query is then routed to the correct application's `querier` by `baseapp`'s [`handleQueryCustom`](https://github.com/cosmos/cosmos-sdk/blob/master/baseapp/baseapp.go#L519-L556) method using `queryRoute`. +`Queriers` are very similar to `handlers`, except they serve user queries to the state as opposed to processing transactions. A query is initiated from an [interface](#intefaces) by an end-user who provides a `queryRoute` and some `data`. The query is then routed to the correct application's `querier` by `baseapp`'s [`handleQueryCustom`](https://github.com/cosmos/cosmos-sdk/blob/master/baseapp/baseapp.go#L519-L556) method using `queryRoute`. The `Querier` of a module is defined in a file called `querier.go`, and consists of: @@ -232,9 +239,9 @@ Interfaces let end-users interact with full-node clients. This means querying da The main interface is the [Command-Line Interface](../interfaces/cli.md). The CLI of an SDK application is built by aggregating [CLI commands](#cli) defined in each of the modules used by the application. The CLI of an application generally has the `-cli` suffix (e.g. `appcli`), and defined in a file called `cmd/appcli/main.go`. The file contains: - **A `main()` function**, which is executed to build the `appcli` interface client. This function prepares each command and adds them to the `rootCmd` before building them. At the root of `appCli`, the function adds generic commands like `status`, `keys` and `config`, query commands, tx commands and `rest-server`. -- **Query commands** are added by calling the `queryCmd` function, also defined in `appcli/main.go`. This function returns a Cobra command that contains the query commands defined in each of the application's modules (passed as an array of `sdk.ModuleClients` from the `main()` function), as well as some other lower level query commands such as block or validator queries. Query command are called by using the command `appcli query [query]` of the CLI. +- **Query commands** are added by calling the `queryCmd` function, also defined in `appcli/main.go`. This function returns a Cobra command that contains the query commands defined in each of the application's modules (passed as an array of `sdk.ModuleClients` from the `main()` function), as well as some other lower level query commands such as block or validator queries. Query command are called by using the command `appcli query [query]` of the CLI. - **Transaction commands** are added by calling the `txCmd` function. Similar to `queryCmd`, the function returns a Cobra command that contains the tx commands defined in each of the application's modules, as well as lower level tx commands like transaction signing or broadcasting. Tx commands are called by using the command `appcli tx [tx]` of the CLI. -- **A `registerRoutes` function**, which is called from the `main()` function when initializing the [application's light-client daemon (LCD)](../core/node.md#lcd) (i.e. `rest-server`). `registerRoutes` calls the `RegisterRoutes` function of each of the application's module, thereby registering the routes of the module to the lcd's router. The LCD can be started by running the following command `appcli rest-server`. +- **A `registerRoutes` function**, which is called from the `main()` function when initializing the [application's light-client daemon (LCD)](./node.md#lcd) (i.e. `rest-server`). `registerRoutes` calls the `RegisterRoutes` function of each of the application's module, thereby registering the routes of the module to the lcd's router. The LCD can be started by running the following command `appcli rest-server`. See an example of an application's main command-line file [here](https://github.com/cosmos/sdk-application-tutorial/blob/master/cmd/nscli/main.go). diff --git a/docs/building-modules/module-interfaces.md b/docs/building-modules/module-interfaces.md index 744c439c67f2..c3ddea3298aa 100644 --- a/docs/building-modules/module-interfaces.md +++ b/docs/building-modules/module-interfaces.md @@ -1,9 +1,283 @@ # Module Interfaces +## Prerequisites + +* [Building Modules Intro](./intro.md) + +## Synopsis + +This document details how to build CLI and REST interfaces for a module. Examples from various SDK modules will be included. + +- [CLI](#cli) + + [Transaction Commands](#tx-commands) + + [Query Commands](#query-commands) +- [REST](#rest) + + [Request Types](#request-types) + + [Request Handlers](#request-handlers) + + [Register Routes](#register-routes) + ## CLI -### Tx +One of the main interfaces for an application is the [command-line interface](../interfaces/cli.md). This entrypoint created by the application developer will add commands from the application's modules to let end-users create [**messages**](./messages-and-queries.md) and [**queries**](./messages-and-queries.md). The CLI files are typically found in the `./x/moduleName/client/cli` folder. + +### Transaction Commands + +[Transactions](../core/transactions.md) are created by users to wrap messages that trigger state changes when they get included in a valid block. Transaction commands typically have their own `tx.go` file in the module `./x/moduleName/client/cli` folder. The commands are specified in getter functions prefixed with `GetCmd` and include the name of the command. Here is an example from the nameservice tutorial: + +```go +func GetCmdBuyName(cdc *codec.Codec) *cobra.Command { + return &cobra.Command{ + Use: "buy-name [name] [amount]", + Short: "bid for existing name or claim new name", + Args: cobra.ExactArgs(2), + RunE: func(cmd *cobra.Command, args []string) error { + cliCtx := context.NewCLIContext().WithCodec(cdc).WithAccountDecoder(cdc) + + txBldr := authtxb.NewTxBuilderFromCLI().WithTxEncoder(utils.GetTxEncoder(cdc)) + + if err := cliCtx.EnsureAccountExists(); err != nil { + return err + } + + coins, err := sdk.ParseCoins(args[1]) + if err != nil { + return err + } + + msg := nameservice.NewMsgBuyName(args[0], coins, cliCtx.GetFromAddress()) + err = msg.ValidateBasic() + if err != nil { + return err + } + + cliCtx.PrintResponse = true + + return utils.GenerateOrBroadcastMsgs(cliCtx, txBldr, []sdk.Msg{msg}, false) + }, + } +} +``` + +This getter function creates the command for the Buy Name transaction. It does the following: + +- **`codec`**. The getter function takes in an application [`codec`](../core/encoding.md) as an argument and returns a reference to the `cobra.command`. Since a module is intended to be used by any application, the `codec` must be provided. +- **Construct the command:** Read the [Cobra Documentation](https://github.com/spf13/cobra) for details on how to create commands. + + **Use:** Specifies the format of a command-line entry users should type in order to invoke this command. In this case, the user uses `buy-name` as the name of the transaction command and provides the `name` the user wishes to buy and the `amount` the user is willing to pay. + + **Args:** The number of arguments the user provides, in this case exactly two: `name` and `amount`. + + **Short and Long:** A description for the function is provided here. A `Short` description is expected, and `Long` can be used to provide a more detailed description when a user uses the `--help` flag to ask for more information. + + **RunE:** Defines a function that can return an error, called when the command is executed. Using `Run` would do the same thing, but would not allow for errors to be returned. +- **`RunE` Function Body:** The function should be specified as a `RunE` to allow for errors to be returned. This function encapsulates all of the logic to create a new transaction that is ready to be relayed to nodes. + + The function should first initialize a [`TxBuilder`](../core/transactions.md#txbuilder) with the application `codec`'s `TxEncoder`, as well as a new [`CLIContext`](./query-lifecycle.md#clicontext) with the `codec` and `AccountDecoder`. These contexts contain all the information provided by the user and will be used to transfer this user-specific information between processes. To learn more about how contexts are used in a transaction, click [here](../core/transactions.md#transaction-generation). + + If applicable, the command's arguments are parsed. Here, the `amount` given by the user is parsed into a denomination of `coins`. + + If applicable, the `CLIContext` is used to retrieve any parameters such as the transaction originator's address to be used in the transaction. Here, the `from` address is retrieved by calling `cliCtx.getFromAddress()`. + + A [message](./messages-and-queries.md) is created using all parameters parsed from the command arguments and `CLIContext`. The constructor function of the specific message type is called directly. It is good practice to call `ValidateBasic()` on the newly created message to run a sanity check and check for invalid arguments. + + Depending on what the user wants, the transaction is either generated offline or signed and broadcasted to the preconfigured node using `GenerateOrBroadcastMsgs()`. +- **Flags.** Add any [flags](#flags) to the command. No flags were specified here, but all transaction commands have flags to provide additional information from the user (e.g. amount of fees they are willing to pay). These *persistent* [transaction flags](../interfaces/cli.md#flags) can be added to a higher-level command so that they apply to all transaction commands. + + +#### GetTxCmd + +Finally, the module needs to have a `GetTxCmd()`, which aggregates all of the transaction commands of the module. Often, each command getter function has its own file in the module's `cli` folder, and a separate `tx.go` file contains `GetTxCmd()`. Application developers wishing to include the module's transactions will call this function to add them as subcommands in their CLI. Here is the [`auth`](https://github.com/cosmos/cosmos-sdk/tree/67f6b021180c7ef0bcf25b6597a629aca27766b8/docs/spec/auth) `GetTxCmd()` function, which adds the `Sign` and `MultiSign` commands. An application using this module likely adds `auth` module commands to its root `TxCmd` command by calling `txCmd.AddCommand(authModuleClient.GetTxCmd())`. + +```go +func GetTxCmd(cdc *codec.Codec) *cobra.Command { + txCmd := &cobra.Command{ + Use: types.ModuleName, + Short: "Auth transaction subcommands", + DisableFlagParsing: true, + SuggestionsMinimumDistance: 2, + RunE: client.ValidateCmd, + } + txCmd.AddCommand( + GetMultiSignCommand(cdc), + GetSignCommand(cdc), + ) + return txCmd +} +``` + +### Query Commands + +[Queries](./messages-and-queries.md) allow users to gather information about the application or network state; they are routed by the application and processed by the module in which they are defined. Query commands typically have their own `query.go` file in the module `x/moduleName/client/cli` folder. Like transaction commands, they are specified in getter functions and have the prefix `GetCmdQuery`. Here is an example of a query command from the nameservice module: + +```go +func GetCmdWhois(queryRoute string, cdc *codec.Codec) *cobra.Command { + return &cobra.Command{ + Use: "whois [name]", + Short: "Query whois info of name", + Args: cobra.ExactArgs(1), + RunE: func(cmd *cobra.Command, args []string) error { + cliCtx := context.NewCLIContext().WithCodec(cdc) + name := args[0] + + res, err := cliCtx.QueryWithData(fmt.Sprintf("custom/%s/whois/%s", queryRoute, name), nil) + if err != nil { + fmt.Printf("could not resolve whois - %s \n", string(name)) + return nil + } + + var out nameservice.Whois + cdc.MustUnmarshalJSON(res, &out) + return cliCtx.PrintOutput(out) + }, + } +} + +``` + +This query returns the address that owns a particular name. The getter function does the following: + +- **`codec` and `queryRoute`.** In addition to taking in the application `codec`, query command getters also take a `queryRoute` used to construct a path [Baseapp](../core/baseapp.md#query-routing) uses to route the query in the application. +- **Construct the command.** Read the [Cobra Documentation](https://github.com/spf13/cobra) and the [transaction command](#transaction-commands) example above for more information. The user must type `whois` and provide the `name` they are querying for as the only argument. +- **`RunE`.** The function should be specified as a `RunE` to allow for errors to be returned. This function encapsulates all of the logic to create a new query that is ready to be relayed to nodes. + + The function should first initialize a new [`CLIContext`](./query-lifecycle.md#clicontext) with the application `codec`. + + If applicable, the `CLIContext` is used to retrieve any parameters (e.g. the query originator's address to be used in the query) and marshal them with the query parameter type, in preparation to be relayed to a node. There are no `CLIContext` parameters in this case because the query does not involve any information about the user. + + The `queryRoute` is used to construct a route Baseapp will use to route the query to the appropriate [querier](./querier.md). Module queries are `custom` type queries (some SDK modules have exceptions, such as `auth` and `gov` module queries). + + The `CLIContext` query function relays the query to a node and retrieves the response. + + The `codec` is used to nmarshal the response and the `CLIContext` is used to print the output back to the user. +- **Flags.** Add any [flags](#flags) to the command. + +#### GetQueryCmd + +Finally, the module also needs a `GetQueryCmd`, which aggregates all of the query commands of the module. Application developers wishing to include the module's queries will call this function to add them as subcommands in their CLI. Its structure is identical to the [`GetTxCmd`](#gettxcmd) command. + +### Flags + +[Flags](../interfaces/cli.md#flags) are entered by the user and allow for command customizations. Examples include the [fees](../core/accounts-fees.md) or gas prices users are willing to pay for their transactions. + +The flags for a module are typically found in a `flags.go` file in the `./x/moduleName/client/cli` folder. Module developers can create a list of possible flags including the value type, default value, and a description displayed if the user uses a `help` command. In each transaction getter function, they can add flags to the commands and, optionally, mark flags as *required* so that an error is thrown if the user does not provide values for them. + +For full details on flags, visit the [Cobra Documentation](https://github.com/spf13/cobra). + +For example, the SDK `./client/flags` package includes a [`PostCommands()`](https://github.com/cosmos/cosmos-sdk/blob/master/client/flags/flags.go#L85-L116) function that adds necessary flags to transaction commands, such as the `from` flag to indicate which address the transaction originates from. Here is an example of how to add a flag using the `from` flag from this function. + +```go +cmd.Flags().String(FlagFrom, "", "Name or address of private key with which to sign") +``` + +The input provided for this flag - called `FlagFrom` is a string with the default value of `""` if none is provided. If the user asks for a description of this flag, the description will be printed. + +A flag can be marked as *required* so that an error is automatically thrown if the user does not provide a value: + +```go +cmd.MarkFlagRequired(FlagFrom) +``` + +Since `PostCommands()` includes all of the basic flags required for a transaction command, module developers may choose not to add any of their own (specifying arguments instead may often be more appropriate). For a full list of what flags are included in the `PostCommands()` function, including which are required inputs from users, see the CLI documentation [here](../interfaces/cli.md#transaction-flags). + +## REST + +Applications are typically required to support web services that use HTTP requests (e.g. a web wallet like [Lunie.io](lunie.io)). Thus, application developers will also use REST Routes to route HTTP requests to the application's modules; these routes will be used by service providers. The module developer's responsibility is to define the REST client by defining [routes](#register-routes) for all possible [requests](#request-types) and [handlers](#request-handlers) for each of them. It's up to the module developer how to organize the REST interface files; there is typically a `rest.go` file found in the module's `./x/moduleName/client/rest` folder. + +### Request Types + +Request types must be defined for all *transaction* requests. Conventionally, each request is named with the suffix `Req`, e.g. `SendReq` for a Send transaction. Each struct should include a base request [`baseReq`](../interfaces/rest.md#basereq), the name of the transaction, and all the arguments the user must provide for the transaction. + +Here is an example of a request to buy a name from the [nameservice](https://cosmos.network/docs/tutorial/rest.html) module: + +```go +type buyNameReq struct { + BaseReq rest.BaseReq `json:"base_req"` + Name string `json:"name"` + Amount string `json:"amount"` + Buyer string `json:"buyer"` +} +``` + +The `BaseReq` includes basic information that every request needs to have, similar to required flags in a CLI. All of these values, including `GasPrices` and `AccountNumber`, will be provided in the request body. The user will also need to specify the arguments `Name` and `Amount` fields in the body and `Buyer` will be provided by the user's address. + +#### BaseReq + +`BaseReq` is a type defined in the SDK that encapsulates much of the transaction configurations similar to CLI command flags. Users must provide the information in the body of their requests. + +* `From` indicates which [account](../core/accounts-fees.md) the transaction originates from. This account is used to sign the transaction. +* `Memo` sends a memo along with the transaction. +* `ChainID` specifies the unique identifier of the blockchain the transaction pertains to. +* `AccountNumber` is an identifier for the account. +* `Sequence`is the value of a counter measuring how many transactions have been sent from the account. It is used to prevent replay attacks. +* `Gas` refers to how much [gas](../core/gas.md), which represents computational resources, Tx consumes. Gas is dependent on the transaction and is not precisely calculated until execution, but can be estimated by providing auto as the value for `Gas`. +* `GasAdjustment` can be used to scale gas up in order to avoid underestimating. For example, users can specify their gas adjustment as 1.5 to use 1.5 times the estimated gas. +* `GasPrices` specifies how much the user is willing pay per unit of gas, which can be one or multiple denominations of tokens. For example, --gas-prices=0.025uatom, 0.025upho means the user is willing to pay 0.025uatom AND 0.025upho per unit of gas. +* `Fees` specifies how much in [fees](../core/accounts-fees.md) the user is willing to pay in total. Note that the user only needs to provide either `gas-prices` or `fees`, but not both, because they can be derived from each other. +* `Simulate` instructs the application to ignore gas and simulate the transaction running without broadcasting. + +### Request Handlers + +Request handlers must be defined for both transaction and query requests. Handlers' arguments include a reference to the application's `codec` and the [`CLIContext`](../interfaces/query-lifecycle.md#clicontext) created in the user interaction. + +Here is an example of a request handler for the nameservice module `buyNameReq` request (the same one shown above): + +```go +func buyNameHandler(cdc *codec.Codec, cliCtx context.CLIContext) http.HandlerFunc { + return func(w http.ResponseWriter, r *http.Request) { + var req buyNameReq + + if !rest.ReadRESTReq(w, r, cdc, &req) { + rest.WriteErrorResponse(w, http.StatusBadRequest, "failed to parse request") + return + } + + baseReq := req.BaseReq.Sanitize() + if !baseReq.ValidateBaic(w) { + return + } + + addr, err := sdk.AccAddressFromBech32(req.Buyer) + if err != nil { + rest.WriteErrorResponse(w, http.StatusBadRequest, err.Error()) + return + } + + coins, err := sdk.ParseCoins(req.Amount) + if err != nil { + rest.WriteErrorResponse(w, http.StatusBadRequest, err.Error()) + return + } + + //create message + msg := nameservice.NewMsgBuyName(req.Name, coins, addr) + err = msg.ValidateBasic() + if err != nil { + rest.WriteErrorResponse(w, http.StatusBadRequest, err.Error()) + return + } + clientrest.WriteGenerateStdTxResponse(w, cdc, cliCtx, baseReq, []sdk.Msg{msg}) + + } +} +``` + +The request handler can be broken down as follows: + +* **Parse Request:** The request handler first attempts to parse the request, and then run `Sanitize` and `ValidateBasic` on the underlying `BaseReq` to check the validity of the request. Next, it attempts to parse the arguments `Buyer` and `Amount` to the types `AccountAddress` and `Coins` respectively. +* **Message:** Then, a [message](./messages-and-queries.md) of the type `MsgBuyName` (defined by the module developer to trigger the state changes for this transaction) is created from the values and another sanity check, `ValidateBasic` is run on it. +* **Generate Transaction:** Finally, the HTTP `ResponseWriter`, application [`codec`](../core/encoding.md), [`CLIContext`](../interfaces/query-lifecycle.md#clicontext), request [`BaseReq`](../interfaces/rest.md#basereq), and message is passed to `WriteGenerateStdTxResponse` to further process the request. + +To read more about how a transaction is generated, visit the transactions documentation [here](../core/transactions.md#transaction-generation). + +### Register Routes + +The application CLI entrypoint will have a `RegisterRoutes` function in its `main.go` file, which calls the `registerRoutes` functions of each module utilized by the application. Module developers need to implement `registerRoutes` for their modules so that applications are able to route messages and queries to their corresponding handlers and queriers. + +The router used by the SDK is [Gorilla Mux](https://github.com/gorilla/mux). The router is initialized with the Gorilla Mux `NewRouter()` function. Then, the router's `HandleFunc` function can then be used to route urls with the defined request handlers and the HTTP method (e.g. "POST", "GET") as a route matcher. It is recommended to prefix every route with the name of the module to avoid collisions with other modules that have the same query or transaction names. + +Here is a `registerRoutes` function with one query route example from the [nameservice tutorial](https://cosmos.network/docs/tutorial/rest.html): + +``` go +func RegisterRoutes(cliCtx context.CLIContext, r *mux.Router, cdc *codec.Codec, storeName string) { + // ResolveName Query + r.HandleFunc(fmt.Sprintf("/%s/names/{%s}", storeName, restName), resolveNameHandler(cdc, cliCtx, storeName)).Methods("GET") +} +``` + +A few things to note: + +* The router `r` has already been initialized by the application and is passed in here as an argument - this function is able to add on the nameservice module's routes onto any application's router. The application must also provide a [`CLIContext`](../interfaces/query-lifecycle.md#clicontext) that the querier will need to process user requests and the application [`codec`](../core/encoding.md) for encoding and decoding application-specific types. +* `"/%s/names/{%s}", storeName, restName` is the url for the HTTP request. `storeName` is the name of the module, `restName` is a variable provided by the user to specify what kind of query they are making. +* `resolveNameHandler` is the query request handler defined by the module developer. It also takes the application `codec` and `CLIContext` passed in from the user side, as well as the `storeName`. +* `"GET"` is the HTTP Request method. As to be expected, queries are typically GET requests. Transactions are typically POST and PUT requests. + -### Query +## Next -## REST \ No newline at end of file +Read about the next topic in building modules. diff --git a/docs/concepts/app-anatomy.md b/docs/concepts/app-anatomy.md index 177a84f19c7e..78d7b1eda675 100644 --- a/docs/concepts/app-anatomy.md +++ b/docs/concepts/app-anatomy.md @@ -116,7 +116,7 @@ The SDK offers developers the possibility to implement automatic execution of co In general, the `BeginBlocker` and `EndBlocker` functions are mostly composed of the `BeginBlock` and `EndBlock` functions of each of the application's modules. This is done by calling the `BeginBlock` and `EndBlock` functions of the module manager, which in turn will call the `BeginBLock` and `EndBlock` functions of each of the modules it contains. Note that the order in which the modules' `BegingBlock` and `EndBlock` functions must be called has to be set in the module manager using the `SetOrderBeginBlock` and `SetOrderEndBlock` methods respectively. This is done in the [application's constructor](#application-constructor), and the `SetOrderBeginBlock` and `SetOrderEndBlock` methods have to be called before the `SetBeginBlocker` and `SetEndBlocker` functions. -As a sidenote, it is important to remember that application-specific blockchains are deterministic. Developers must be careful not to introduce non-determinism in `BeginBlocker` or `EndBlocker`, and must also be careful not to make them too computationally expensive, as [gas](./accounts-fees.md/gas) does not constrain the cost of `BeginBlocker` and `EndBlocker` execution. +As a sidenote, it is important to remember that application-specific blockchains are deterministic. Developers must be careful not to introduce non-determinism in `BeginBlocker` or `EndBlocker`, and must also be careful not to make them too computationally expensive, as [gas](./fees-signature.md/gas) does not constrain the cost of `BeginBlocker` and `EndBlocker` execution. You can see an example of `BeginBlocker` and `EndBlocker` functions [here](https://github.com/cosmos/gaia/blob/master/app/app.go#L224-L232). @@ -154,7 +154,7 @@ To learn more about the application module interface, [click here](./modules.md# A message is a custom type defined by each module that implements the [`message`](https://github.com/cosmos/cosmos-sdk/blob/master/types/tx_msg.go#L8-L29) interface. Each `transaction` contains one or multiple `messages`. When a valid block of transactions is received by the full-node, Tendermint relays each one to the application via [`DeliverTx`](https://tendermint.com/docs/app-dev/abci-spec.html#delivertx). Then, the application handles the transaction: 1. Upon receiving the transaction, the application first unmarshalls it from `[]bytes`. -2. Then, it verifies a few things about the transaction like [fee payment and signatures](#accounts-fees.md) before extracting the message(s) contained in the transaction. +2. Then, it verifies a few things about the transaction like [fee payment and signatures](#fees-signature.md) before extracting the message(s) contained in the transaction. 3. With the [`Type()`](https://github.com/cosmos/cosmos-sdk/blob/master/types/tx_msg.go#L16) method, `baseapp` is able to know which modules defines the message. It is then able to route it to the appropriate module's [handler](#handler) in order for the message to be processed. 4. If the message is successfully processed, the state is updated. diff --git a/docs/concepts/baseapp_old.md b/docs/concepts/baseapp_old.md deleted file mode 100644 index c4f71f33f696..000000000000 --- a/docs/concepts/baseapp_old.md +++ /dev/null @@ -1,128 +0,0 @@ -# BaseApp - -The BaseApp defines the foundational implementation for a basic ABCI application -so that your Cosmos-SDK application can communicate with an underlying -Tendermint node. - -The BaseApp is composed of many internal components. Some of the most important -include the `CommitMultiStore` and its internal state. The internal state is -essentially two sub-states, both of which are used for transaction execution -during different phases, `CheckTx` and `DeliverTx` respectively. During block -commitment, only the `DeliverTx` is persisted. - -The BaseApp requires stores to be mounted via capabilities keys - handlers can -only access stores they're given the key to. The `baseApp` ensures all stores are -properly loaded, cached, and committed. One mounted store is considered the -"main" (`baseApp.MainStoreKey`) - it holds the latest block header, from which we can find and load the -most recent state. - -The BaseApp distinguishes between two handler types - the `AnteHandler` and the -`MsgHandler`. The former is a global validity check (checking nonces, sigs and -sufficient balances to pay fees, e.g. things that apply to all transaction from -all modules), the later is the full state transition function. - -During `CheckTx` the state transition function is only applied to the `checkTxState` -and should return before any expensive state transitions are run -(this is up to each developer). It also needs to return the estimated gas cost. - -During `DeliverTx` the state transition function is applied to the blockchain -state and the transactions need to be fully executed. - -The BaseApp is responsible for managing the context passed into handlers - -it makes the block header available and provides the right stores for `CheckTx` -and `DeliverTx`. BaseApp is completely agnostic to serialization formats. - -## Routing - -TODO - -## Transaction Life Cycle - -During the execution of a transaction, it may pass through both `CheckTx` and -`DeliverTx` as defined in the ABCI specification. `CheckTx` is executed by the -proposing validator and is used for the Tendermint mempool for all full nodes. - -Both `CheckTx` and `DeliverTx` execute the application's AnteHandler (if -defined), where the AnteHandler is responsible for pre-message validation -checks such as account and signature validation, fee deduction and collection, -and incrementing sequence numbers. - -### CheckTx - -During the execution of `CheckTx`, only the AnteHandler is executed. - -State transitions due to the AnteHandler are persisted between subsequent calls -of `CheckTx` in the check-tx state, unless the AnteHandler fails and aborts. - -### DeliverTx - -During the execution of `DeliverTx`, the AnteHandler and Handler is executed. - -The transaction execution during `DeliverTx` operates in a similar fashion to -`CheckTx`. However, state transitions that occur during the AnteHandler are -persisted even when the following Handler processing logic fails. - -It is possible that a malicious proposer may include a transaction in a block -that fails the AnteHandler. In this case, all state transitions for the -offending transaction are discarded. - - -## Other ABCI Messages - -Besides `CheckTx` and `DeliverTx`, BaseApp handles the following ABCI messages. - -### Info -TODO complete description - -### SetOption -TODO complete description - -### Query -TODO complete description - -### InitChain -TODO complete description - -During chain initialization InitChain runs the initialization logic directly on -the CommitMultiStore. The deliver and check states are initialized with the -ChainID. - -Note that we do not commit after InitChain, so BeginBlock for block 1 starts -from the deliver state as initialized by InitChain. - -### BeginBlock -TODO complete description - -### EndBlock -TODO complete description - -### Commit -TODO complete description - - -## Gas Management - -### Gas: InitChain - -During InitChain, the block gas meter is initialized with an infinite amount of -gas to run any genesis transactions. - -Additionally, the InitChain request message includes ConsensusParams as -declared in the genesis.json file. - -### Gas: BeginBlock - -The block gas meter is reset during BeginBlock for the deliver state. If no -maximum block gas is set within baseapp then an infinite gas meter is set, -otherwise a gas meter with `ConsensusParam.BlockSize.MaxGas` is initialized. - -### Gas: DeliverTx - -Before the transaction logic is run, the `BlockGasMeter` is first checked to -see if any gas remains. If no gas remains, then `DeliverTx` immediately returns -an error. - -After the transaction has been processed, the used gas (up to the transaction -gas limit) is deducted from the BlockGasMeter. If the remaining gas exceeds the -meter's limits, then DeliverTx returns an error and the transaction is not -committed. diff --git a/docs/concepts/genesis.md b/docs/concepts/genesis.md deleted file mode 100644 index 5e3dbd31dcad..000000000000 --- a/docs/concepts/genesis.md +++ /dev/null @@ -1,3 +0,0 @@ -# Genesis File - -TODO \ No newline at end of file diff --git a/docs/concepts/store.md b/docs/concepts/store.md deleted file mode 100644 index 067eea3b79bd..000000000000 --- a/docs/concepts/store.md +++ /dev/null @@ -1,8 +0,0 @@ -# Store - -## Commit Multi Store - -## Database - -## Main Store - diff --git a/docs/core/baseapp_old.md b/docs/core/baseapp_old.md deleted file mode 100644 index c239272fcba3..000000000000 --- a/docs/core/baseapp_old.md +++ /dev/null @@ -1,148 +0,0 @@ -# BaseApp - -## Pre-requisite Reading - -- [Anatomy of an SDK application](./app-anatomy.md) -- [Lifecycle of an SDK transaction](./tx-lifecycle.md) - -## Synopsis - -This document describes `baseapp`, the abstraction that implements most of the common functionalities of an SDK application. - -- [Introduction](#introduction) -- [Type Definition](#type-definition) -- [States](#states) -- [Routing](#routing) -- [ABCI](#abci) -- [CheckTx](#abci-checktx) -- [DeliverTx](#abci-delivertx) -- [Commit](#abbci-commit) -- [Other ABCI Message](#other-abci-message) - + [Info](#info) - + [SetOption](#setoption) - + [Query](#query) - + [InitChain](#initchain) - + [BeginBlock](#beginblock) - + [EndBlock](#endblock) -- [Gas](#gas) - - -## Introduction - -`baseapp` is an abstraction that implements the core of an SDK application, namely: - -- The [Application-Blockchain Interface](#abci), for the state-machine to communicate with the underlying consensus engine (e.g. Tendermint). -- A [Router](#routing), to route [messages](./tx-msgs.md) and [queries](./querier.md) to the appropriate [module](./modules.md). -- Different [states](#states), as the state-machine can have different parallel states updated based on the ABCI message received. - -The goal of `baseapp` is to provide a boilerplate SDK application that developers can easily extend to build their own custom application. Usually, developers will create a custom type for their application, like so: - -```go -type app struct { - *bam.BaseApp // reference to baseapp - cdc *codec.Codec - - // list of application store keys - - // list of application keepers - - // module manager -} -``` - -Extending the application with `baseapp` gives the former access to all of `baseapp`'s methods. This allows developers to compose their custom application with the modules they want, while not having to concern themselves with the hard work of implementing the ABCI, the routing and state management logic. - -## Type Definition - -The [`baseapp` type](https://github.com/cosmos/cosmos-sdk/blob/master/baseapp/baseapp.go#L45-L91) holds many important parameters for any Cosmos SDK based application. Let us go through the most important components. - -*Note: Not all parameters are described, only the most important ones. Refer to the [type definition](https://github.com/cosmos/cosmos-sdk/blob/master/baseapp/baseapp.go#L45-L91) for the full list* - -First, the important parameters that are initialized during the initialization of the application: - -- A [`CommitMultiStore`](./store.md#commit-multi-store). This is the main store of the application, which holds the canonical state that is committed at the [end of each block](#commit). This store is **not** cached, meaning it is not used to update the application's intermediate (un-committed) states. The `CommitMultiStore` is a multi-store, meaning a store of stores. Each module of the application uses one or multiple `KVStores` in the multi-store to persist their subset of the state. -- A [database](./store.md#database) `db`, which is used by the `CommitMultiStore` to handle data storage. -- A [router](#messages). The `router` facilitates the routing of [messages](./tx-msgs.md) to the appropriate module for it to be processed. -- A [query router](#queries). The `query router` facilitates the routing of [queries](./querier.md) to the appropriate module for it to be processed. -- A [`txDecoder`](https://godoc.org/github.com/cosmos/cosmos-sdk/types#TxDecoder), used to decode transaction `[]byte` relayed by the underlying Tendermint engine. -- A [`baseKey`], to access the [main store](./store.md#main-store) in the `CommitMultiStore`. The main store is used to persist data related to the core of the application, like consensus parameters. -- A [`anteHandler`](./accounts-fees.md#antehandler), to handle signature verification and fee paiement when a transaction is received. -- An [`initChainer`](./app-anatomy.md#initchainer), [`beginBlocker` and `endBlocker`](./app-anatomy.md#beginblocker-and-endblocker), which are the functions executed when the application received the [InitChain], [BeginBlock] and [EndBlock] messages from the underlying Tendermint engine. - -Then, parameters used to define [volatile states](#volatile-states) (i.e. cached states): - -- `checkState`: This state is updated during [`CheckTx`](#checktx), and reset on [`Commit`](#commit). -- `deliverState`: This state is updated during [`DeliverTx`](#delivertx), and reset on [`Commit`](#commit). - -Finally, a few more important parameterd: - -- `voteInfos`: This parameter carries the list of validators whose precommit is missing, either because they did not vote or because the proposer did not include their vote. This information is carried by the [context](#context) and can be used by the application for various things like punishing absent validators. -- `minGasPrices`: This parameter defines the minimum [gas prices](./accounts-fees.md#gas) accepted by the node. This is a local parameter, meaning each full-node can set a different `minGasPrices`. It is run by the [`anteHandler`](./accounts-fees.md#antehandler) during `CheckTx`, mainly as a spam protection mechanism. The transaction enters the [mempool](https://tendermint.com/docs/tendermint-core/mempool.html#transaction-ordering) only if the gas price of the transaction is superior to one of the minimum gas price in `minGasPrices` (i.e. if `minGasPrices == 1uatom, 1upho`, the `gas-price` of the transaction must be superior to `1uatom` OR `1upho`). -- `appVersion`: Version of the application. It is set in the [application's constructor function](./baseapp.md#constructor-function). - -## States - -`baseapp` handles various parallel states for different purposes. There is the [main state](#main-state), which is the canonical state of the application, and volatile states like [`checkState`](#checkState) and [`deliverState`](#deliverstate), which are used to handle temporary states inbetween updates of the main state. - -### Main State - -The main state is the canonical state of the application. It is initialized on [`InitChain`](#initchain and updated on [`Commit`](#abci-commit) at the end of each block. - -``` -+--------+ +--------+ -| | | | -| S +----------------------------> | S' | -| | For each T in B: apply(T) | | -+--------+ +--------+ -``` - -The main state is held by `baseapp` in a structure called the [`CommitMultiStore`](./store.md#commit-multi-store). This multi-store is used by developers to instantiate all the stores they need for each of their application's modules. - -### Volatile States - -Volatile - or cached - states are used in between [`Commit`s](#commit) to manage temporary states. They are reset to the latest version of the main state after it is committed. There are two main volatile states: - -- `checkState`: This cached state is initialized during [`InitChain`](#initchain), updated during [`CheckTx`](#abci-checktx) when an unconfirmed transaction is received, and reset to the [main state](#main-state) on [`Commit`](#abci-commit). -- `deliverState`: This cached state is initialized during [`BeginBlock`](#beginblock), updated during [`DeliverTx`](#abci-delivertx) when a transaction included in a block is processed, and reset to the [main state](#main-state) on [`Commit`](#abci-commit). - -## Routing - -When messages and queries are received by the application, they must be routed to the appropriate module in order to be processed. Routing is done via `baseapp`, which holds a `router` for messages, and a `query router` for queries. - -### Message Routing - -Messages need to be routed after they are extracted from transactions, which are sent from the underlying Tendermint engine via the [`CheckTx`](#checktx) and [`DeliverTx`](#delivertx) ABCI messages. To do so, `baseapp` holds a [`router`](https://github.com/cosmos/cosmos-sdk/blob/master/baseapp/router.go) which maps `paths` (`string`) to the appropriate module [`handler`](./handler.md). Usually, the `path` is the name of the module. - -The application's `router` is initilalized with all the routes using the application's [module manager](./modules.md#module-manager), which itself is initialized with all the application's modules in the application's [constructor](./app-anatomy.md#app-constructor). - -### Query Routing - -Similar to messages, queries need to be routed to the appropriate module's [querier](./querier.md). To do so, `baseapp` holds a [`query router`](https://github.com/cosmos/cosmos-sdk/blob/master/baseapp/queryrouter.go), which maps `paths` (`string`) to the appropriate module [`querier`](./querier.md). Usually, the `path` is the name of the module. - -Just like the `router`, the `query router` is initilalized with all the query routes using the application's [module manager](./modules.md#module-manager), which itself is initialized with all the application's modules in the application's [constructor](./app-anatomy.md#app-constructor). - -## Main ABCI Messages - - - -### CheckTx - -### DeliverTx - -## RunTx and RunMsg - -## Other ABCI Messages - -### Commit - -### Info - -### SetOption - -### Query - -### InitChain - -### BeginBlock - -### EndBlock \ No newline at end of file diff --git a/docs/concepts/handler.md b/docs/modules/handler.md similarity index 100% rename from docs/concepts/handler.md rename to docs/modules/handler.md diff --git a/docs/concepts/invariants.md b/docs/modules/invariants.md similarity index 100% rename from docs/concepts/invariants.md rename to docs/modules/invariants.md diff --git a/docs/concepts/keeper.md b/docs/modules/keeper.md similarity index 100% rename from docs/concepts/keeper.md rename to docs/modules/keeper.md diff --git a/docs/modules/module-interfaces.md b/docs/modules/module-interfaces.md new file mode 100644 index 000000000000..0cd27c895326 --- /dev/null +++ b/docs/modules/module-interfaces.md @@ -0,0 +1,5 @@ +# Module Interfaces + +## CLI + +## REST \ No newline at end of file diff --git a/docs/concepts/modules.md b/docs/modules/modules.md similarity index 100% rename from docs/concepts/modules.md rename to docs/modules/modules.md diff --git a/docs/concepts/querier.md b/docs/modules/querier.md similarity index 100% rename from docs/concepts/querier.md rename to docs/modules/querier.md From 6bfd1750dadf8ca3b19d77ba1c1f4580e632ae3b Mon Sep 17 00:00:00 2001 From: gamarin Date: Fri, 5 Jul 2019 12:00:14 +0200 Subject: [PATCH 087/196] almost there --- docs/basics/accounts-fees.md | 2 +- docs/concepts/app-anatomy.md | 255 ------------------------------ docs/concepts/tx-msgs.md | 5 + docs/core/baseapp.md | 194 +++++++++++++---------- docs/modules/handler.md | 1 - docs/modules/invariants.md | 5 - docs/modules/keeper.md | 0 docs/modules/module-interfaces.md | 5 - docs/modules/modules.md | 8 - docs/modules/querier.md | 3 - 10 files changed, 115 insertions(+), 363 deletions(-) delete mode 100644 docs/concepts/app-anatomy.md create mode 100644 docs/concepts/tx-msgs.md delete mode 100644 docs/modules/handler.md delete mode 100644 docs/modules/invariants.md delete mode 100644 docs/modules/keeper.md delete mode 100644 docs/modules/module-interfaces.md delete mode 100644 docs/modules/modules.md delete mode 100644 docs/modules/querier.md diff --git a/docs/basics/accounts-fees.md b/docs/basics/accounts-fees.md index 9f03e0eb033d..20fe1fb2dac8 100644 --- a/docs/basics/accounts-fees.md +++ b/docs/basics/accounts-fees.md @@ -1,4 +1,4 @@ -# Accounts, Fees and Signatures +# Accounts, Fees and Gas ## Accounts diff --git a/docs/concepts/app-anatomy.md b/docs/concepts/app-anatomy.md deleted file mode 100644 index 78d7b1eda675..000000000000 --- a/docs/concepts/app-anatomy.md +++ /dev/null @@ -1,255 +0,0 @@ -# Anatomy of an SDK Application - -## Pre-requisite reading - -- [High-level overview of the architecture of an SDK application](../intro/sdk-app-architecture.md) -- [Cosmos SDK design overview](../intro/sdk-design.md) - -## Synopsis - -This document describes the core parts of a Cosmos SDK application. The placeholder name for this application will be `app`. - -- [Node Client](#node-client) -- [Core Application File](#core-application-file) -- [Modules](#modules) -- [Intefaces](#interfaces) -- [Dependencies and Makefile](#dependencies-and-makefile) - -The core parts listed above will generally translate to the following directory tree: - -``` -./app -├── cmd/ -│ ├── appd -│ └── appcli -├── app.go -├── x/ -│ ├── auth -│ └── bank -├── Gopkg.toml -└── Makefile -``` - -## Node Client - -The Daemon, or Full-Node Client, is the core process of an SDK-based blockchain. Participants in the network run this process to initialize their state-machine, connect with other full-nodes and update their state-machine as new blocks come in. - -``` - ^ +-------------------------------+ ^ - | | | | - | | State-machine = Application | | - | | | | Built with Cosmos SDK - | | ^ + | | - | +----------- | ABCI | ----------+ v - | | + v | ^ - | | | | -Blockchain Node | | Consensus | | - | | | | - | +-------------------------------+ | Tendermint Core - | | | | - | | Networking | | - | | | | - v +-------------------------------+ v -``` -The blockchain full-node presents itself as a binary, generally suffixed by `-d` (e.g. `appd` for `app` or `gaiad` for the `gaia`) for "daemon". This binary is built by running a simple `main.go` function placed in `cmd/appd/`. This operation usually happens through the [Makefil](#dependencies-and-makefile). - -To learn more about the `main.go` function, [click here](./node.md#main-function). - -Once the main binary is built, the node can be started by running the `start` command. The core logic behind the `start` command is implemented in the SDK itself in the [`/server/start.go`](https://github.com/cosmos/cosmos-sdk/blob/master/server/start.go) file. The main [`start` command function](https://github.com/cosmos/cosmos-sdk/blob/master/server/start.go#L31) takes a [`context`](https://godoc.org/github.com/cosmos/cosmos-sdk/client/context) and [`appCreator`](#constructor-function-(`appCreator`)) as arguments. The `appCreator` is a constructor function for the SDK application, and is used in the starting process of the full-node. - -The `start` command function primarily does three things: - -1. Create an instance of the state-machine defined in [`app.go`](#core-application-file) using the `appCreator`. -2. Initialize the state-machine with the latest known state, extracted from the `db` stored in the `~/.appd/data` folder. At this point, the state-machine is at height `appBlockHeight`. -3. Create and start a new Tendermint instance. Among other things, the node will perform a handshake with its peers. It will get the latest `blockHeight` from them, and replay blocks to sync to this height if it is greater than the local `appBlockHeight`. If `appBlockHeight` is `0`, the node is starting from genesis and Tendermint sends an `InitChain` message via the ABCI to the `app`, which triggers the [`InitChainer`](#initchainer). - -To learn more about the `start` command, [click here](./node.md#start-command). - -## Core Application File - -In general, the core of the state-machine is defined in a file called `app.go`. It mainly contains the **type definition of the application** and functions to **create and initialize it**. - -### Type Definition of the Application - -The first thing defined in `app.go` is the `type` of the application. It is generally comprised of the following parts: - -- **A reference to [`baseapp`](./baseapp.md).** The custom application defined in `app.go` is an extension of the `baseapp` type. `baseapp` implements most of the core logic for the application, including all the [ABCI methods](https://tendermint.com/docs/spec/abci/abci.html#overview) and the routing logic. When a transaction is relayed by Tendermint to the application, the latter uses `baseapp`'s methods to route them to the appropriate module. -- **A list of store keys**. The [store](./store.md), which contains the entire state, is implemented as a multistore (i.e. a store of stores) in the Cosmos SDK. Each module uses one or multiple stores in the multistore to persist their part of the state. These stores can be accessed with specific keys that are declared in the `app` type. These keys, along with the `keepers`, are at the heart of the [object-capabilities model](../intro/ocap.md) of the Cosmos SDK. -- **A list of module's `keepers`.** Each module defines an abstraction called `keeper`, which handles reads and writes for this module's store(s). The `keeper`'s methods of one module can be called from other modules (if authorized), which is why they are declared in the application's type and exported as interfaces to other modules so that they are only allowed to access the authorized functions. -- **A reference to a `codec`.** The Cosmos SDK gives developers the freedom to choose the encoding framework for their application. The application's `codec` is used to serialize and deserialize data structures in order to store them, as stores can only persist `[]bytes`. The `codec` must be deterministic. The default codec is [amino](./amino.md). -- **A reference to a [module manager](./modules.md#module-manager)**. The module manager is an object that contains a list of the application's module. It facilitates operations related to these modules, like registering [`routes`](./baseapp.md#routing), [query routes](#./baseapp.md#query-routing) or setting the order of execution between modules for various functions like [`InitChainer`](#initchainer), [`BeginBlocker` and `EndBlocker`](#beginblocker-and-endblocker). - -You can see an example of application type definition [here](https://github.com/cosmos/gaia/blob/master/app/app.go#L73-L107). - -### Constructor Function - -This function constructs a new application of the type defined above. It is [called](https://github.com/cosmos/cosmos-sdk/blob/master/server/start.go#L117) everytime the full-node is started with the `start` command. Here are the main actions performed by this function: - -- Instantiate a new application with a reference to a `baseapp` instance, a codec and all the appropriate store keys. -- Instantiate all the [`keeper`s](#keeper) defined in the application's `type` using the `NewKeeper` function of each of the application's modules. Note that `keepers` must be instantiated in the correct order, as the `NewKeeper` of one module might require a reference to another module's `keeper`. -- Instantiate the application's [module manager](./module-manager.md) with the [`AppModule`](#application-module-interface) object of each of the application's modules. -- With the module manager, initialize the application's [`routes`](./baseapp.md#routing) and [query routes](./baseapp.md#query-routing). When a transaction is relayed to the application by Tendermint via the ABCI, it is routed to the appropriate module's [`handler`](#handler) using the routes defined here. Likewise, when a query is received by the application, it is routed to the appropriate module's [`querier`](#querier) using the query routes defined here. -- With the module manager, register the [application's modules' invariants](./invariants.md). Invariants are variables (e.g. total supply of a token) that are evaluated at the end of each block. The process of checking invariants is done via a special module called the [`InvariantsRegistry`](./invariants.md#invariant-registry). The value of the ivnariant should be equal to a predicted value defined in the module. Should the value be different than the predicted one, special logic defined in the invariant registry will be triggered (usually the chain is halted). This is useful to make sure no critical bug goes unoticed and produces long-lasting effects that would be hard to fix. -- With the module manager, set the order of execution between the `InitGenesis`, `BegingBlocker` and `EndBlocker` functions of each of the [application's modules](#application-module-interface). Note that not all modules implement these functions. -- Set the remainer of application's parameters: - + [`InitChainer`](#initchainer): used to initialize the application when it is first started. - + [`BeginBlocker`, `EndBlocker`](#beginblocker-and-endlbocker): called at the beginning and the end of every block). - + [`anteHandler`](#baseapp.md#antehandler): used to handle fees and signature verification. -- Mount the stores. -- Return the application. - -Note that this function only creates an instance of the app, while the actual state is either carried over from the `~/.appd/data` folder if the node is restarted, or generated from the genesis file if the node is started for the first time. - -You can see an example of application constructor [here](https://github.com/cosmos/gaia/blob/master/app/app.go#L110-L222). - -### InitChainer - -The `InitChainer` is a function that initializes the state of the application from a [genesis file](./genesis.md) (i.e. token balances of genesis accounts). It is called when the application receives the `InitChain` message from the Tendermint engine, which happens when the node is started at `appBlockHeight == 0` (i.e. on genesis). The application must set the `InitChainer` in its constructor via the [`SetInitChainer`](https://godoc.org/github.com/cosmos/cosmos-sdk/baseapp#BaseApp.SetInitChainer) method. - -In general, the `InitChainer` is mostly composed of the `InitGenesis` function of each of the application's modules. This is done by calling the `InitGenesis` function of the module manager, which in turn will call the `InitGenesis` function of each of the modules it contains. Note that the order in which the modules' `InitGenesis` functions must be called has to be set in the module manager using the `SetOrderInitGenesis` method. This is done in the [application's constructor](#application-constructor), and the `SetOrderInitGenesis` has to be called before the `SetInitChainer`. - -You can see an example of an `InitChainer` [here](https://github.com/cosmos/gaia/blob/master/app/app.go#L235-L239). - -### BeginBlocker and EndBlocker - -The SDK offers developers the possibility to implement automatic execution of code as part of their application. This is implemented through two function called `BeginBlocker` and `EndBlocker`. They are called when the application receives respectively the `BeginBlock` and `EndBlock` messages from the Tendermint engine, which happens at the beginning and at the end of each block. The application must set the `BeginBlocker` and `EndBlocker` in its constructor via the [`SetBeginBlocker`](https://godoc.org/github.com/cosmos/cosmos-sdk/baseapp#BaseApp.SetBeginBlocker) and [`SetEndBlocker`](https://godoc.org/github.com/cosmos/cosmos-sdk/baseapp#BaseApp.SetEndBlocker) methods. - -In general, the `BeginBlocker` and `EndBlocker` functions are mostly composed of the `BeginBlock` and `EndBlock` functions of each of the application's modules. This is done by calling the `BeginBlock` and `EndBlock` functions of the module manager, which in turn will call the `BeginBLock` and `EndBlock` functions of each of the modules it contains. Note that the order in which the modules' `BegingBlock` and `EndBlock` functions must be called has to be set in the module manager using the `SetOrderBeginBlock` and `SetOrderEndBlock` methods respectively. This is done in the [application's constructor](#application-constructor), and the `SetOrderBeginBlock` and `SetOrderEndBlock` methods have to be called before the `SetBeginBlocker` and `SetEndBlocker` functions. - -As a sidenote, it is important to remember that application-specific blockchains are deterministic. Developers must be careful not to introduce non-determinism in `BeginBlocker` or `EndBlocker`, and must also be careful not to make them too computationally expensive, as [gas](./fees-signature.md/gas) does not constrain the cost of `BeginBlocker` and `EndBlocker` execution. - -You can see an example of `BeginBlocker` and `EndBlocker` functions [here](https://github.com/cosmos/gaia/blob/master/app/app.go#L224-L232). - -### Register Codec - -The `MakeCodec` function is the last important function of the `app.go` file. The goal of this function is to instantiate a codec `cdc` (e.g. [amino](./amino.md)) initiliaze the codec of the SDK and each of the application's modules using the `RegisterCodec` function. - -To register the application's modules, the `MakeCodec` function calls `RegisterCodec` on `ModuleBasics`. `ModuleBasics` is a [basic manager](./modules.md#basic-manager) which lists all of the application's modules. It is instanciated in the `init()` function, and only serves to easily register non-dependant elements of application's modules (such as codec). To learn more about the basic module manager, click [here](./modules.md#basic-manager). - -You can see an example of a `MakeCodec` [here](https://github.com/cosmos/gaia/blob/master/app/app.go#L64-L70) - -## Modules - -Modules are the heart and soul of an SDK application. They can be considered as state-machines within the state-machine. When a transaction is relayed from the underlying Tendermint engine via the ABCI to the application, it is routed by `baseapp` to the appropriate module in order to be processed. This paradigm enables developers to easily build complex state-machines, as most of the modules they need often already exist. For developers, most of the work involved in building an SDK application revolves around building custom modules required by their application that do not exist, and integrating them with modules that do already exist into one coherent application. In the application directory, the standard practice is to store modules in the `x/` folder (not to be confused with the SDK's `x/` folder, which contains already-built modules). - -To learn more about modules, [click here](./modules.md) - -### Application Module Interface - -Modules implement two interfaces defined in the Cosmos SDK, [`AppModuleBasic`](https://github.com/cosmos/cosmos-sdk/blob/master/types/module/module.go#L44-L57) and [`AppModule`](https://github.com/cosmos/cosmos-sdk/blob/master/types/module/module.go#L44-L57). The former implements basic non-dependant elements of the module, such as the `codec`, while the latter handles the bulk of the module methods (including methods that require references to other modules' `keeper`s). Both the `AppModule` and `AppModuleBasic` types are defined in a file called `./module.go`. - -`AppModule` exposes a collection of useful methods on the module that facilitates the composition of modules into a coherent application. Important methods include: - -- `Route()` and `QueryRoute()`: These methods the name of the route and querier route for the module, for [messages](#message-types) to be routed to the module's [`handler`](#handler) and queries to be routes to the module's [`querier`](#querier). -- `NewHandler()` and `NewQuerierHandler()`: These methods return a `handler` and `querierHandler` respectively, in order to process a message or a query once they are routed. -- `BeginBlock()`, `EndBlock()` and `InitGenesis()`: These methods are executed respectively at the beginning of each block, at the end of each block and at the start of the chain. They implement special logic the module requires to be triggered during those events. For example, the `EndBlock` function is frequently used by modules where voting occurs to tally the result of the votes. -- `RegisterInvariants()`: This method registers the [invariants](./invariants.md) for the module. Invariants are checked at the end of every block to make sure no unpredicted behaviour is occuring. - -`AppModule`'s methods are called from the `module manager`(./modules.md#module-manager), which manages the application's collection of modules. - -To learn more about the application module interface, [click here](./modules.md#application-module-interface). - -### Message Types - -A message is a custom type defined by each module that implements the [`message`](https://github.com/cosmos/cosmos-sdk/blob/master/types/tx_msg.go#L8-L29) interface. Each `transaction` contains one or multiple `messages`. When a valid block of transactions is received by the full-node, Tendermint relays each one to the application via [`DeliverTx`](https://tendermint.com/docs/app-dev/abci-spec.html#delivertx). Then, the application handles the transaction: - -1. Upon receiving the transaction, the application first unmarshalls it from `[]bytes`. -2. Then, it verifies a few things about the transaction like [fee payment and signatures](#fees-signature.md) before extracting the message(s) contained in the transaction. -3. With the [`Type()`](https://github.com/cosmos/cosmos-sdk/blob/master/types/tx_msg.go#L16) method, `baseapp` is able to know which modules defines the message. It is then able to route it to the appropriate module's [handler](#handler) in order for the message to be processed. -4. If the message is successfully processed, the state is updated. - -For a more detailed look at a transaction lifecycle, click [here](./tx-lifecycle.md). - -Module developers create custom message types when they build their own module. The general practice is to prefix the type declaration of the message with `Msg`. For example, the message type [`MsgSend`](https://github.com/cosmos/cosmos-sdk/blob/master/x/bank/types/msgs.go#L10-L15) allows users to transfer tokens. It is processed by the handler of the `bank` module, which ultimately calls the `keeper` of the `auth` module in order to update the state. - -To learn more about messages, [click here](./tx-msgs.md). - -### Handler - -The `handler` refers to the part of the module responsible for processing the message after it is routed by `baseapp`. `handler` functions of modules (except those of the `auth` module) are only executed if the transaction is relayed from Tendermint by the `DeliverTx` ABCI message. If the transaction is realyed by `CheckTx`, only stateless checks and fee-related (i.e. `auth` module-related) stateful checks are performed. To better understand the difference between `DeliverTx`and `CheckTx`, as well as the difference between stateful and stateless checks, click [here](./tx-lifecycle.md). - -The handler of a module is generally defined in a file called `handler.go` and consists of: - -- A **switch function** `NewHandler` to route the message to the appropriate handler function. This function returns a `handler` function, and is registered in the [`AppModule`](#application-module-interface) to be used in the application's module manager to initialize the [application's router](./baseapp.md#routing). See an example of such a switch [here](https://github.com/cosmos/sdk-application-tutorial/blob/master/x/nameservice/handler.go#L10-L22). -- **One handler function for each message type defined by the module**. Developers write the message processing logic in these functions. This generally involves doing stateful checks to ensure the message is valid and calling [`keeper`](#keeper)'s methods to update the state. - -Handler functions return a result of type [`sdk.Result`](https://github.com/cosmos/cosmos-sdk/blob/master/types/result.go#L14-L37), which informs the application on wether the message was succesfully processed and. - -To learn more about handlers, [click here](./handler.md). - -### Keeper - -`Keepers` are the gatekeepers of their module's store(s). To read or write in a module's store, it is mandatory to go through one of its `keeper`'s methods. This is ensured by the [object-capabilities](./ocap.md) model of the Cosmos SDK. Only objects that hold the key to a store can access it, and only the module's `keeper` should hold the key(s) to the module's store(s). - -`Keepers` are generally defined in a file called `keeper.go`. It contains the `keeper`'s type definition and methods. - -The `keeper` type definition generally consists of: - -- **Key(s)** to the module's store(s) in the multistore. -- Reference to **other module's `keepers`**. Only needed if the `keeper` needs to access other module's store(s) (either to read or write from them). -- A reference to the application's **codec**. The `keeper` needs it to marshal structs before storing them, or to unmarshal them when it retrieves them, because stores only accept `[]bytes` as value. - -Along with the type definition, the next important component of the `keeper.go` file is the `keeper`'s constructor function, `NewKeeper`. This function instantiates a new `keeper` of the type defined above, with a `codec`, store `keys` and potentially references to other modules' `keeper`s as parameters. The `NewKeeper` function is called from the [application's constructor](#constructor-function). - -The rest of the file defines the `keeper`'s methods, primarily getters and setters. You can check an example of a `keeper` implementation [here](https://github.com/cosmos/sdk-application-tutorial/blob/master/x/nameservice/keeper.go). - -To learn more about `keepers`, [click here](./keeper.md). - -### Querier - -`Queriers` are very similar to `handlers`, except they serve user queries to the state as opposed to processing transactions. A query is initiated from an [interface](#intefaces) by an end-user who provides a `queryRoute` and some `data`. The query is then routed to the correct application's `querier` by `baseapp`'s [`handleQueryCustom`](https://github.com/cosmos/cosmos-sdk/blob/master/baseapp/baseapp.go#L519-L556) method using `queryRoute`. - -The `Querier` of a module are defined in a file called `querier.go`, and consists of: - -- A **switch function** `NewQuerier` to route the query to the appropriate `querier` function. This function returns a `querier` function, and is is registered in the [`AppModule`](#application-module-interface) to be used in the application's module manager to initialize the [application's query router](./baseapp.md#query-routing). See an example of such a switch [here](https://github.com/cosmos/sdk-application-tutorial/blob/master/x/nameservice/querier.go#L21-L34). -- - **One querier function for each data type defined by the module that needs to be queryable**. Developers write the query processing logic in these functions. This generally involves calling [`keeper`](#keeper)'s methods to query the state and marshalling it to JSON. See an example of `querier` functions [here](https://github.com/cosmos/sdk-application-tutorial/blob/master/x/nameservice/querier.go#L37-L101). - -To learn more about `queriers`, [click here](./querier.md). - -### Command-Line and REST Interfaces - -Each module defines command-line commands and REST routes to be exposed to end-user via the [application's interfaces](#application-interfaces). This enables end-users to create messages of the types defined in the module, or to query the subset of the state managed by the module. - -#### CLI - -Generally, the commands related to a module are defined in a folder called `client/cli` in the module's folder. The CLI divides commands in two category, transactions and queries, defined in `client/cli/tx.go` and `client/cli/query.go` respectively. Both commands are built on top of the [Cobra Library](https://github.com/spf13/cobra): - -- Transactions commands let users generate new transactions so that they can be included in a block and eventually update the state. One command should be created for each [message type](#message-types) defined in the module. The command calls the constructor of the message with the parameters provided by the end-user, and wraps it into a transaction. The SDK handles signing and the addition of other transaction metadata. See examples of transactions commands [here](https://github.com/cosmos/sdk-application-tutorial/blob/master/x/nameservice/client/cli/tx.go). -- Queries let users query the subset of the state defined by the module. Query commands forward queries to the [application's query router](./baseapp.md#query-routing), which routes them to the appropriate [querier](#querier) the `queryRoute` parameter supplied. See examples of query commands [here](https://github.com/cosmos/sdk-application-tutorial/blob/master/x/nameservice/client/cli/query.go). - -To learn more about modules CLI, [click here](./module-interfaces.md#cli). - -#### REST - -The module's REST interface lets users generate transactions and query the state through REST calls to the application's [light-client daemon](./node.md#lcd). REST routes are defined in a file `client/rest/rest.go`, which is composed of: - -- A `RegisterRoutes` function, which registers each route defined in the file. This function is called from the [main application's interface](#application-interfaces) for each module used within the application. The router used in the SDK is [Gorilla's mux](https://github.com/gorilla/mux). -- Custom request type definitions for each query or transaction creation function that needs to be exposed. These custom request types build on the [base `request` type](https://github.com/cosmos/cosmos-sdk/blob/master/types/rest/rest.go#L32-L43) of the Cosmos SDK. -- One handler function for each request that can be routed to the given module. These functions implement the core logic necessary to serve the request. - -See an example of a module's `rest.go` file [here](https://github.com/cosmos/sdk-application-tutorial/blob/master/x/nameservice/client/rest/rest.go). - -To learn more about modules REST interface, [click here](./module-interfaces.md#rest). - -## Application Interface - -Interfaces let end-users interact with full-node clients. This means querying data from the full-node or creating and sending new transactions to be relayed by the full-node and eventually included in a block. - -The main interface is the [Command-Line Interface](./interfaces.md#cli). The CLI of an SDK application is built by aggregating [CLI commands](#cli) defined in each of the modules used by the application. The CLI of an application generally has the `-cli` suffix (e.g. `appcli`), and defined in a file called `cmd/appcli/main.go`. The file contains: - -- **A `main()` function**, which is executed to build the `appcli` interface client. This function prepares each command and adds them to the `rootCmd` before building them. At the root of `appCli`, the function adds generic commands like `status`, `keys` and `config`, query commands, tx commands and `rest-server`. -- **Query commands** are added by calling the `queryCmd` function, also defined in `appcli/main.go`. This function returns a Cobra command that contains the query commands defined in each of the application's modules (passed as an array of `sdk.ModuleClients` from the `main()` function), as well as some other lower level query commands such as block or validator queries. Query command are called by using the command `appcli query [query]` of the CLI. -- **Transaction commands** are added by calling the `txCmd` function. Similar to `queryCmd`, the function returns a Cobra command that contains the tx commands defined in each of the application's modules, as well as lower level tx commands like transaction signing or broadcasting. Tx commands are called by using the command `appcli tx [tx]` of the CLI. -- **A `registerRoutes` function**, which is called from the `main()` function when initializing the [application's light-client daemon (LCD)](./node.md#lcd) (i.e. `rest-server`). `registerRoutes` calls the `RegisterRoutes` function of each of the application's module, thereby registering the routes of the module to the lcd's router. The LCD can be started by running the following command `appcli rest-server`. - -See an example of an application's main command-line file [here](https://github.com/cosmos/sdk-application-tutorial/blob/master/cmd/nscli/main.go). - -To learn more about interfaces, [click here](./interfaces.md) - -## Dependencies and Makefile - - - -## Next - -Learn more about the [Lifecycle of a transaction](./tx-lifecycle.md). diff --git a/docs/concepts/tx-msgs.md b/docs/concepts/tx-msgs.md new file mode 100644 index 000000000000..fde1963e3c2a --- /dev/null +++ b/docs/concepts/tx-msgs.md @@ -0,0 +1,5 @@ +# Transactions and Messages + +## Transactions + +## Messages diff --git a/docs/core/baseapp.md b/docs/core/baseapp.md index 6c3d2dd9e506..7f8214b34e4c 100644 --- a/docs/core/baseapp.md +++ b/docs/core/baseapp.md @@ -7,7 +7,7 @@ ## Synopsis -This document describes `baseapp`, the abstraction that implements most of the common functionalities of an SDK application. +This document describes `baseapp`, the abstraction that implements most of the common functionalities of an SDK application. - [Introduction](#introduction) - [Type Definition](#type-definition) @@ -17,7 +17,7 @@ This document describes `baseapp`, the abstraction that implements most of the c - [Main ABCI Messages](#abci) + [CheckTx](#checktx) + [DeliverTx](#delivertx) -- [RunTx, AnteHandler and RunMsgs](#runtx-antehandler-and-runmsgs) +- [RunTx, AnteHandler and RunMsgs](#runtx-,antehandler-and-runmsgs) + [RunTx](#runtx) + [AnteHandler](#antehandler) + [RunMsgs](#runmsgs) @@ -28,18 +28,21 @@ This document describes `baseapp`, the abstraction that implements most of the c + [Commit](#commit) + [Info](#info) + [Query](#query) - + + + + ## Introduction `baseapp` is an abstraction that implements the core of an SDK application, namely: -- The [Application-Blockchain Interface](#abci), for the state-machine to communicate with the underlying consensus engine (e.g. Tendermint). -- A [Router](#routing), to route [messages](./tx-msgs.md) and [queries](./querier.md) to the appropriate [module](../building-modules/intro.md). -- Different [states](#states), as the state-machine can have different parallel states updated based on the ABCI message received. +- The [Application-Blockchain Interface](#abci), for the state-machine to communicate with the underlying consensus engine (e.g. Tendermint). +- A [Router](#routing), to route [messages](./tx-msgs.md) and [queries](./querier.md) to the appropriate [module](../building-modules/modules.md). +- Different [states](#states), as the state-machine can have different parallel states updated based on the ABCI message received. The goal of `baseapp` is to provide a boilerplate SDK application that developers can easily extend to build their own custom application. Usually, developers will create a custom type for their application, like so: -```go +```go type app struct { *bam.BaseApp // reference to baseapp cdc *codec.Codec @@ -52,24 +55,24 @@ type app struct { } ``` -Extending the application with `baseapp` gives the former access to all of `baseapp`'s methods. This allows developers to compose their custom application with the modules they want, while not having to concern themselves with the hard work of implementing the ABCI, the routing and state management logic. +Extending the application with `baseapp` gives the former access to all of `baseapp`'s methods. This allows developers to compose their custom application with the modules they want, while not having to concern themselves with the hard work of implementing the ABCI, the routing and state management logic. ## Type Definition The [`baseapp` type](https://github.com/cosmos/cosmos-sdk/blob/master/baseapp/baseapp.go#L45-L91) holds many important parameters for any Cosmos SDK based application. Let us go through the most important components. -*Note: Not all parameters are described, only the most important ones. Refer to the [type definition](https://github.com/cosmos/cosmos-sdk/blob/master/baseapp/baseapp.go#L45-L91) for the full list* +*Note: Not all parameters are described, only the most important ones. Refer to the [type definition](https://github.com/cosmos/cosmos-sdk/blob/master/baseapp/baseapp.go#L45-L91) for the full list* First, the important parameters that are initialized during the initialization of the application: -- A [`CommitMultiStore`](./store.md#commit-multi-store). This is the main store of the application, which holds the canonical state that is committed at the [end of each block](#commit). This store is **not** cached, meaning it is not used to update the application's intermediate (un-committed) states. The `CommitMultiStore` is a multi-store, meaning a store of stores. Each module of the application uses one or multiple `KVStores` in the multi-store to persist their subset of the state. +- A [`CommitMultiStore`](./store.md#commit-multi-store). This is the main store of the application, which holds the canonical state that is committed at the [end of each block](#commit). This store is **not** cached, meaning it is not used to update the application's intermediate (un-committed) states. The `CommitMultiStore` is a multi-store, meaning a store of stores. Each module of the application uses one or multiple `KVStores` in the multi-store to persist their subset of the state. - A [database](./store.md#database) `db`, which is used by the `CommitMultiStore` to handle data storage. -- A [router](#message-routing). The `router` facilitates the routing of [messages](../building-modules/messages-and-queries.md#messages) to the appropriate module for it to be processed. -- A [query router](#query-routing). The `query router` facilitates the routing of [queries](../building-modules/messages-and-queries.md#queries) to the appropriate module for it to be processed. +- A [router](#messages). The `router` facilitates the routing of [messages](./tx-msgs.md) to the appropriate module for it to be processed. +- A [query router](#queries). The `query router` facilitates the routing of [queries](./querier.md) to the appropriate module for it to be processed. - A [`txDecoder`](https://godoc.org/github.com/cosmos/cosmos-sdk/types#TxDecoder), used to decode transaction `[]byte` relayed by the underlying Tendermint engine. - A [`baseKey`], to access the [main store](./store.md#main-store) in the `CommitMultiStore`. The main store is used to persist data related to the core of the application, like consensus parameters. - A [`anteHandler`](#antehandler), to handle signature verification and fee paiement when a transaction is received. -- An [`initChainer`](../basics/app-anatomy.md#initchainer), [`beginBlocker` and `endBlocker`](../basics/app-anatomy.md#beginblocker-and-endblocker), which are the functions executed when the application received the [InitChain], [BeginBlock] and [EndBlock] messages from the underlying Tendermint engine. +- An [`initChainer`](./app-anatomy.md#initchainer), [`beginBlocker` and `endBlocker`](./app-anatomy.md#beginblocker-and-endblocker), which are the functions executed when the application received the [InitChain], [BeginBlock] and [EndBlock] messages from the underlying Tendermint engine. Then, parameters used to define [volatile states](#volatile-states) (i.e. cached states): @@ -84,13 +87,17 @@ Finally, a few more important parameterd: ## Constructor -`NewBaseApp(name string, logger log.Logger, db dbm.DB, txDecoder sdk.TxDecoder, options ...func(*BaseApp),)` is the constructor function for `baseapp`. It is called from the [application's constructor function](../basics/app-anatomy.md#constructor-function) each time the full-node is started. +`NewBaseApp(name string, logger log.Logger, db dbm.DB, txDecoder sdk.TxDecoder, options ...func(*BaseApp),)` is the constructor function for `baseapp`. It is called from the [application's constructor function](../basics/app-anatomy.md#constructor-function) each time the full-node is started. + +`baseapp`'s constructor function is pretty straightforward. The only thing worth noting is the possibility to add additional [`options`](https://github.com/cosmos/cosmos-sdk/blob/master/baseapp/options.go) to `baseapp` by passing `options functions` to the constructor function, which will execute them in order. `options` are generally `setter` functions for important parameters, like `SetPruning()` to active pruning or `SetMinGasPrices()` to set the node's `min-gas-prices`. + +A list of `options` examples can be found [here](https://github.com/cosmos/cosmos-sdk/blob/master/baseapp/options.go). Naturally, developers can add additional `options` based on their application's needs. + +## Constructor -`baseapp`'s constructor function is pretty straightforward. The only thing worth noting is the possibility to add additional [`options`](https://github.com/cosmos/cosmos-sdk/blob/master/baseapp/options.go) to `baseapp` by passing `options functions` to the constructor function, which will execute them in order. `options` are generally `setters` function for important parameters, like `SetPruning()` to active pruning or `SetMinGasPrices()` to set the node's `min-gas-prices`. -A list of `options` example can be found [here](https://github.com/cosmos/cosmos-sdk/blob/master/baseapp/options.go). Naturally, developers can add additional `options` based on their application's needs. -## States +## States `baseapp` handles various parallel states for different purposes. There is the [main state](#main-state), which is the canonical state of the application, and volatile states like [`checkState`](#checkState) and [`deliverState`](#deliverstate), which are used to handle temporary states inbetween updates of the main state. @@ -120,7 +127,54 @@ DeliverTx(tx1) | | | +----------------------+ +----------------------+ | | | | | DeliverState(t)(1) | | | | | +----------------------+ | | -DeliverTx(tx2) | | | | | +DeliverTx(tx2) | | | | | + | | v | | + | | +----------------------+ | | + | | | DeliverState(t)(2) | | | + | | +----------------------+ | | +DeliverTx(tx3) | | | | | + | | v | | + | | +----------------------+ | | + | | | DeliverState(t)(3) | | | + +----------------------+ +----------------------+ +----------------------+ +Commit() | | | + v v v + +----------------------+ +----------------------+ +----------------------+ + | CheckState(t+1)(0) | | DeliverState(t+1)(0) | | QueryState(t+1) | + +----------------------+ | | | | + . . . + . . . + . . . + +``` + +``` + To perform stateful checks To execute state To answer queries + on received transactions transitions during DeliverTx about last-committed state + +----------------------+ +----------------------+ +----------------------+ + | CheckState(t)(0) | | DeliverState(t)(0) | | QueryState(t) | + +----------------------+ | | | | +CheckTx(tx1) | | | | | + v | | | | + +----------------------+ | | | | + | CheckState(t)(1) | | | | | + +----------------------+ | | | | +CheckTx(tx2) | | | | | + v | | | | + +----------------------+ | | | | + | CheckState(t)(2) | | | | | + +----------------------+ | | | | +CheckTx(tx3) | | | | | + v | | | | + +----------------------+ | | | | + | CheckState(t)(3) | | | | | + +----------------------+ +----------------------+ | | +DeliverTx(tx1) | | | | + v v | | + +----------------------+ +----------------------+ | | + | | | DeliverState(t)(1) | | | + | | +----------------------+ | | +DeliverTx(tx2) | | | | | | | v | | | | +----------------------+ | | | | | DeliverState(t)(2) | | | @@ -138,12 +192,12 @@ Commit() | | . . . . . . . . . - + ``` ### Main State -The main state is the canonical state of the application. It is initialized on [`InitChain`](#initchain and updated on [`Commit`](#abci-commit) at the end of each block. +The main state is the canonical state of the application. It is initialized on [`InitChain`](#initchain and updated on [`Commit`](#abci-commit) at the end of each block. ``` +--------+ +--------+ @@ -159,13 +213,13 @@ The main state is held by `baseapp` in a structure called the [`CommitMultiStore Volatile - or cached - states are used in between [`Commit`s](#commit) to manage temporary states. They are reset to the latest version of the main state after it is committed. There are two main volatile states: -- `checkState`: This cached state is initialized during [`InitChain`](#initchain), updated during [`CheckTx`](#abci-checktx) when an unconfirmed transaction is received, and reset to the [main state](#main-state) on [`Commit`](#abci-commit). +- `checkState`: This cached state is initialized during [`InitChain`](#initchain), updated during [`CheckTx`](#abci-checktx) when an unconfirmed transaction is received, and reset to the [main state](#main-state) on [`Commit`](#abci-commit). - `deliverState`: This cached state is initialized during [`BeginBlock`](#beginblock), updated during [`DeliverTx`](#abci-delivertx) when a transaction included in a block is processed, and reset to the [main state](#main-state) on [`Commit`](#abci-commit). Both `checkState` and `deliverState` are of type [`state`](https://github.com/cosmos/cosmos-sdk/blob/master/baseapp/baseapp.go#L973-L976), which includes: -- A [`CacheMultiStore`](https://github.com/cosmos/cosmos-sdk/blob/master/store/cachemulti/store.go), which is a cached version of the main `CommitMultiStore`. A new version of this store is committed at the end of each successful `CheckTx`/`DeliverTx` execution. -- A [`Context`](./context.md), which carries general information (like raw transaction size, block height, ...) that might be needed in order to process the transaction during `CheckTx` and `DeliverTx`. The `context` also holds a cache-wrapped version of the `CacheMultiStore`, so that the `CacheMultiStore` can maintain the correct version even if an internal step of `CheckTx` or `DeliverTx` fails. +- A [`CacheMultiStore`](https://github.com/cosmos/cosmos-sdk/blob/master/store/cachemulti/store.go), which is a cached version of the main `CommitMultiStore`. A new version of this store is committed at the end of each successful `CheckTx`/`DeliverTx` execution. +- A [`Context`](./context.md), which carries general information (like raw transaction size, block height, ...) that might be needed in order to process the transaction during `CheckTx` and `DeliverTx`. The `context` also holds a cache-wrapped version of the `CacheMultiStore`, so that the `CacheMultiStore` can maintain the correct version even if an internal step of `CheckTx` or `DeliverTx` fails. ## Routing @@ -175,24 +229,24 @@ When messages and queries are received by the application, they must be routed t [`Message`s](#../building-modules/messages-and-queries.md#messages) need to be routed after they are extracted from transactions, which are sent from the underlying Tendermint engine via the [`CheckTx`](#checktx) and [`DeliverTx`](#delivertx) ABCI messages. To do so, `baseapp` holds a [`router`](https://github.com/cosmos/cosmos-sdk/blob/master/baseapp/router.go) which maps `paths` (`string`) to the appropriate module [`handler`](./handler.md). Usually, the `path` is the name of the module. -The application's `router` is initilalized with all the routes using the application's [module manager](../building-modules/module-manager.md), which itself is initialized with all the application's modules in the application's [constructor](../basics/app-anatomy.md#app-constructor). +The application's `router` is initilalized with all the routes using the application's [module manager](./modules.md#module-manager), which itself is initialized with all the application's modules in the application's [constructor](../basics/app-anatomy.md#app-constructor). ### Query Routing -Similar to `message`s, [`queries`](../building-modules/messages-and-queries.md#queries) need to be routed to the appropriate module's [querier](../building-modules/querier.md). To do so, `baseapp` holds a [`query router`](https://github.com/cosmos/cosmos-sdk/blob/master/baseapp/queryrouter.go), which maps `paths` (`string`) to the appropriate module `querier`. Usually, the `path` is the name of the module. +Similar to messages, queries need to be routed to the appropriate module's [querier](./querier.md). To do so, `baseapp` holds a [`query router`](https://github.com/cosmos/cosmos-sdk/blob/master/baseapp/queryrouter.go), which maps `paths` (`string`) to the appropriate module [`querier`](./querier.md). Usually, the `path` is the name of the module. Just like the `router`, the `query router` is initilalized with all the query routes using the application's [module manager](../building-modules/module-manager.md), which itself is initialized with all the application's modules in the application's [constructor](../basics/app-anatomy.md#app-constructor). ## Main ABCI Messages -The [Application-Blockchain Interface](https://tendermint.com/docs/spec/abci/) (ABCI) is a generic interface that connects a state-machine with a consensus engine to form a functional full-node. It can be wrapped in any language, and needs to be implemented by each application-specific blockchain built on top of an ABCI-compatible consensus engine like Tendermint. +The [Application-Blockchain Interface](https://tendermint.com/docs/spec/abci/) (ABCI) is a generic interface that connects a state-machine with a consensus engine to form a functional full-node. It can be wrapped in any language, and needs to be implemented by each application-specific blockchain built on top of an ABCI-compatible consensus engine like Tendermint. The consensus engine handles two main tasks: - The networking logic, which mainly consists in gossiping block parts, transactions and consensus votes. -- The consensus logic, which results in the deterministic ordering of transactions in the form of blocks. +- The consensus logic, which results in the deterministic ordering of transactions in the form of blocks. -It is **not** the role of the consensus engine to define the state or the validity of transactions. Generally, transactions are handled by the consensus engine in the form of `[]bytes`, and relayed to the application via the ABCI to be decoded and processed. At keys moments in the networking and consensus processes (e.g. beginning of a block, commit of a block, reception of an unconfirmed transaction, ...), the consensus engine emits ABCI messages for the state-machine to act on. +It is **not** the role of the consensus engine to define the state or the validity of transactions. Generally, transactions are handled by the consensus engine in the form of `[]bytes`, and relayed to the application via the ABCI to be decoded and processed. At keys moments in the networking and consensus processes (e.g. beginning of a block, commit of a block, reception of an unconfirmed transaction, ...), the consensus engine emits ABCI messages for the state-machine to act on. Developers building on top of the Cosmos SDK need not implement the ABCI themselves, as `baseapp` comes with a built-in implementation of the interface. Let us go through the main ABCI messages that `baseapp` implements: [`CheckTx`](#checktx) and [`DeliverTx`](#delivertx) @@ -204,43 +258,43 @@ Developers building on top of the Cosmos SDK need not implement the ABCI themsel 1. Extract the `message`s from the transaction. 2. Perform *stateless* checks by calling `ValidateBasic()` on each of the `messages`. This is done first, as *stateless* checks are less computationally expensive than *stateful* checks. If `ValidateBasic()` fail, `CheckTx` returns before running *stateful* checks, which saves resources. -3. Perform non-module related *stateful* checks on the account. This step is mainly about checking that the `message` signatures are valid, that enough fees are provided and that the sending account has enough funds to pay for said fees. Note that no precise [`gas`](./accounts-fees-gas.md#gas) counting occurs here, as `message`s are not processed. Usually, the [`anteHandler`](./accounts-fees-gas.md#antehandler) will check that the `gas` provided with the transaction is superior to a minimum reference gas amount based on the raw transaction size, in order to avoid spam with transactions that provide 0 gas. -4. Ensure that a [`Route`](#message-routing) exists for each `message`, but do **not** actually process `message`s. `Message`s only need to be processed when the canonical state need to be updated, which happens during `DeliverTx`. +3. Perform non-module related *stateful* checks on the account. This step is mainly about checking that the `message` signatures are valid, that enough fees are provided and that the sending account has enough funds to pay for said fees. Note that no precise [`gas`](./accounts-fees.md#gas) counting occurs here, as `message`s are not processed. Usually, the [`anteHandler`](./accounts-fees.md#antehandler) will check that the `gas` provided with the transaction is superior to a minimum reference gas amount based on the raw transaction size, in order to avoid spam with transactions that provide 0 gas. +4. Ensure that a [`Route`](#message-routing) exists for each `message`, but do **not** actually process `message`s. `Message`s only need to be processed when the canonical state need to be updated, which happens during `DeliverTx`. -Steps 2. and 3. are performed by the [`anteHandler`](./accounts-fees-gas.md#antehandler) in the [`RunTx`](#runtx-antehandler-and-runmsgs) function, which `CheckTx` calls with the `runTxModeCheck` mode. During each step of `CheckTx`, a special [volatile state](#volatile-states) called `checkState` is updated. This state is used to keep track of the temporary changes triggered by the `CheckTx` calls of each transaction without modifying the [main canonical state](#main-state) . For example, when a transaction goes through `CheckTx`, the transaction's fees are deducted from the sender's account in `checkState`. If a second transaction is received from the same account before the first is processed, and the account has consumed all its funds in `checkState` during the first transaction, the second transaction will fail `CheckTx` and be rejected. In any case, the sender's account will not actually pay the fees until the transaction is actually included in a block, because `checkState` never gets committed to the main state. `checkState` is reset to the latest state of the main state each time a blocks gets [committed](#commit). +Steps 2. and 3. are performed by the [`anteHandler`](./accounts-fees.md#antehandler) in the [`RunTx`](#runtx-,antehandler-and-runmsgs) function, which `CheckTx` calls with the `runTxModeCheck` mode. During each step of `CheckTx`, a special [volatile state](#volatile-states) called `checkState` is updated. This state is used to keep track of the temporary changes triggered by the `CheckTx` calls of each transaction without modifying the [main canonical state](#main-state) . For example, when a transaction goes through `CheckTx`, the transaction's fees are deducted from the sender's account in `checkState`. If a second transaction is received from the same account before the first is processed, and the account has consumed all its funds in `checkState` during the first transaction, the second transaction will fail `CheckTx` and be rejected. In any case, the sender's account will not actually pay the fees until the transaction is actually included in a block, because `checkState` never gets committed to the main state. `checkState` is reset to the latest state of the main state each time a blocks gets [committed](#commit). `CheckTx` returns a response to the underlying consensus engine of type [`abci.ResponseCheckTx`](https://tendermint.com/docs/spec/abci/abci.html#messages). The response contains: -- `Code (uint32)`: Response Code. `0` if successful. +- `Code (uint32)`: Response Code. `0` if successful. - `Data ([]byte)`: Result bytes, if any. - `Log (string):` The output of the application's logger. May be non-deterministic. - `Info (string):` Additional information. May be non-deterministic. -- `GasWanted (int64)`: Amount of gas requested for transaction. It is provided by users when they generate the transaction. -- `GasUsed (int64)`: Amount of gas consumed by transaction. During `CheckTx`, this value is computed by multiplying the standard cost of a transaction byte by the size of the raw transaction (click [here](https://github.com/cosmos/cosmos-sdk/blob/master/x/auth/ante.go#L101) for an example). +- `GasWanted (int64)`: Amount of gas requested for transaction. It is provided by users when they generate the transaction. +- `GasUsed (int64)`: Amount of gas consumed by transaction. During `CheckTx`, this value is computed by multiplying the standard cost of a transaction byte by the size of the raw transaction (click [here](https://github.com/cosmos/cosmos-sdk/blob/master/x/auth/ante.go#L101) for an example). - `Tags ([]cmn.KVPair)`: Key-Value tags for filtering and indexing transactions (eg. by account). - `Codespace (string)`: Namespace for the Code. ### DeliverTx -When the underlying consensus engine receives a block proposal, each transaction in the block needs to be processed by the application. To that end, the underlying consensus engine sends a `DeliverTx` message to the application for each transaction in a sequential order. +When the underlying consensus engine receives a block proposal, each transaction in the block needs to be processed by the application. To that end, the underlying consensus engine sends a `DeliverTx` message to the application for each transaction in a sequential order. -Before the first transaction of a given block is processed, a [volatile state](#volatile-states) called `deliverState` is intialized during [`BeginBlock`](#beginblock). This state is updated each time a transaction is processed via `DeliverTx`, and committed to the [main state](#main-state) when the block is [committed](#commit), after what is is set to `nil`. +Before the first transaction of a given block is processed, a [volatile state](#volatile-states) called `deliverState` is intialized during [`BeginBlock`](#beginblock). This state is updated each time a transaction is processed via `DeliverTx`, and committed to the [main state](#main-state) when the block is [committed](#commit), after what is is set to `nil`. `DeliverTx` performs the **exact same steps as `CheckTx`**, with a little caveat at step 3 and the addition of a fifth step: -3. The `anteHandler` does **not** check that the transaction's `gas-prices` is sufficient. That is because the `min-gas-prices` value `gas-prices` is checked against is local to the node, and therefore what is enough for one full-node might not be for another. This means that the proposer can potentially include transactions for free, although they are not incentivised to do so, as they earn a bonus on the total fee of the block they propose. -5. For each `message` in the transaction, route to the appropriate module's [`handler`](../building-modules/handler.md). Additional *stateful* checks are performed, and the cache-wrapped multistore held in `deliverState`'s `context` is updated by the module's `keeper`. If the `handler` returns successfully, the cache-wrapped multistore held in `context` is written to `deliverState` `CacheMultiStore`. +3. The `anteHandler` does **not** check that the transaction's `gas-prices` is sufficient. That is because the `min-gas-prices` value `gas-prices` is checked against is local to the node, and therefore what is enough for one full-node might not be for another. This means that the proposer can potentially include transactions for free, although they are not incentivised to do so, as they earn a bonus on the total fee of the block they propose. +5. For each `message` in the transaction, route to the appropriate module's [`handler`](../building-modules/handler.md). Additional *stateful* checks are performed, and the cache-wrapped multistore held in `deliverState`'s `context` is updated by the module's `keeper`. If the `handler` returns successfully, the cache-wrapped multistore held in `context` is written to `deliverState` `CacheMultiStore`. -During step 5., each read/write to the store increases the value of `GasConsumed`. You can find the default cost of each operation [here](https://github.com/cosmos/cosmos-sdk/blob/master/store/types/gas.go#L142-L150). At any point, if `GasConsumed > GasWanted`, the function returns with `Code != 0` and `DeliverTx` fails. +During step 5., each read/write to the store increases the value of `GasConsumed`. You can find the default cost of each operation [here](https://github.com/cosmos/cosmos-sdk/blob/master/store/types/gas.go#L142-L150). At any point, if `GasConsumed > GasWanted`, the function returns with `Code != 0` and `DeliverTx` fails. `DeliverTx` returns a response to the underlying consensus engine of type [`abci.ResponseCheckTx`](https://tendermint.com/docs/spec/abci/abci.html#messages). The response contains: -- `Code (uint32)`: Response Code. `0` if successful. +- `Code (uint32)`: Response Code. `0` if successful. - `Data ([]byte)`: Result bytes, if any. - `Log (string):` The output of the application's logger. May be non-deterministic. - `Info (string):` Additional information. May be non-deterministic. -- `GasWanted (int64)`: Amount of gas requested for transaction. It is provided by users when they generate the transaction. -- `GasUsed (int64)`: Amount of gas consumed by transaction. During `DeliverTx`, this value is computed by multiplying the standard cost of a transaction byte by the size of the raw transaction (click [here](https://github.com/cosmos/cosmos-sdk/blob/master/x/auth/ante.go#L101) for an example), and by adding gas each time a read/write to the store occurs. +- `GasWanted (int64)`: Amount of gas requested for transaction. It is provided by users when they generate the transaction. +- `GasUsed (int64)`: Amount of gas consumed by transaction. During `DeliverTx`, this value is computed by multiplying the standard cost of a transaction byte by the size of the raw transaction (click [here](https://github.com/cosmos/cosmos-sdk/blob/master/x/auth/ante.go#L101) for an example), and by adding gas each time a read/write to the store occurs. - `Tags ([]cmn.KVPair)`: Key-Value tags for filtering and indexing transactions (eg. by account). - `Codespace (string)`: Namespace for the Code. @@ -248,13 +302,13 @@ During step 5., each read/write to the store increases the value of `GasConsumed ### RunTx -`RunTx` is called from `CheckTx`/`DeliverTx` to handle the transaction, with `runTxModeCheck` or `runTxModeDeliver` as parameter to differentiate between the two modes of execution. Note that when `RunTx` receives a transaction, it has already been decoded. +`RunTx` is called from `CheckTx`/`DeliverTx` to handle the transaction, with `runTxModeCheck` or `runTxModeDeliver` as parameter to differentiate between the two modes of execution. Note that when `RunTx` receives a transaction, it has already been decoded. -The first thing `RunTx` does upon being called is to retrieve the `context`'s `CacheMultiStore` by calling the `getContextForTx()` function with the appropriate mode (either `runTxModeCheck` or `runTxModeDeliver`). This `CacheMultiStore` is a cached version of the main store instantiated during `BeginBlock` for `DeliverTx` and during the `Commit` of the previous block for `CheckTx`. After that, two `defer func()` are called for [`gas`](./accounts-fees-gas.md#gas) management. They are executed when `runTx` returns and make sure `gas` is actually consumed, and will throw errors, if any. +The first thing `RunTx` does upon being called is to retrieve the `context`'s `CacheMultiStore` by calling the `getContextForTx()` function with the appropriate mode (either `runTxModeCheck` or `runTxModeDeliver`). This `CacheMultiStore` is a cached version of the main store instantiated during `BeginBlock` for `DeliverTx` and during the `Commit` of the previous block for `CheckTx`. After that, two `defer func()` are called for [`gas`](./accounts-fees.md#gas) management. They are executed when `runTx` returns and make sure `gas` is actually consumed, and will throw errors, if any. -After that, `RunTx` calls `ValidateBasic()` on each `message`in the `Tx`, which runs prelimary *stateless* validity checks. If any `message` fails to pass `ValidateBasic()`, `RunTx` returns with an error. +After that, `RunTx` calls `ValidateBasic()` on each `message`in the `Tx`, which runs prelimary *stateless* validity checks. If any `message` fails to pass `ValidateBasic()`, `RunTx` returns with an error. -Then, the [`anteHandler`](#antehandler) of the application is run (if it exists). In preparation of this step, both the `checkState`/`deliverState`'s `context` and `context`'s `CacheMultiStore` are cached-wrapped using the [`cacheTxContext()`](https://github.com/cosmos/cosmos-sdk/blob/master/baseapp/baseapp.go#L781-L798) function. This allows `RunTx` not to commit the changes made to the state during the execution of `anteHandler` if it ends up failing. It also prevents the module implementing the `anteHandler` from writing to state, which is an important part of the [object-capabilities](./ocap.md) of the Cosmos SDK. +Then, the [`anteHandler`](#antehandler) of the application is run (if it exists). In preparation of this step, both the `checkState`/`deliverState`'s `context` and `context`'s `CacheMultiStore` are cached-wrapped using the [`cacheTxContext()`](https://github.com/cosmos/cosmos-sdk/blob/master/baseapp/baseapp.go#L781-L798) function. This allows `RunTx` not to commit the changes made to the state during the execution of `anteHandler` if it ends up failing. It also prevents the module implementing the `anteHandler` from writing to state, which is an important part of the [object-capabilities](./ocap.md) of the Cosmos SDK. Finally, the [`RunMsgs`](#runmsgs) function is called to process the `messages`s in the `Tx`. In preparation of this step, just like with the `anteHandler`, both the `checkState`/`deliverState`'s `context` and `context`'s `CacheMultiStore` are cached-wrapped using the `cacheTxContext()` function. @@ -264,66 +318,36 @@ The `AnteHandler` is a special handler that implements the [`anteHandler` interf The `AnteHandler` is theoretically optional, but still a very important component of public blockchain networks. It serves 3 primary purposes: -- Be a primary line of defense against spam and second line of defense (the first one being the mempool) against transaction replay with fees deduction and [`sequence`](./tx-msgs.md#sequence) checking. -- Perform preliminary *stateful* validity checks like ensuring signatures are valid or that the sender has enough funds to pay for fees. -- Play a role in the incentivisation of stakeholders via the collection of transaction fees. +- Be a primary line of defense against spam and second line of defense (the first one being the mempool) against transaction replay with fees deduction and [`sequence`](./tx-msgs.md#sequence) checking. +- Perform preliminary *stateful* validity checks like ensuring signatures are valid or that the sender has enough funds to pay for fees. +- Play a role in the incentivisation of stakeholders via the collection of transaction fees. `baseapp` holds an `anteHandler` as paraemter, which is initialized in the [application's constructor](../basics/app-anatomy.md#application-constructor). The most widely used `anteHandler` today is that of the [`auth` module](https://github.com/cosmos/cosmos-sdk/blob/master/x/auth/ante.go). ### RunMsgs -`RunMsgs` is called from `RunTx` with `runTxModeCheck` as parameter to check the existence of a route for each message the transaction, and with `runTxModeDeliver` to actually process the `message`s. +`RunMsgs` is called from `RunTx` with `runTxModeCheck` as parameter to check the existence of a route for each message the transaction, and with `runTxModeDeliver` to actually process the `message`s. -First, it retreives the `message`'s `route` using the `Msg.Route()` method. Then, using the application's [`router`](#routing) and the `route`, it checks for the existence of a `handler`. At this point, if `mode == runTxModeCheck`, `RunMsgs` returns. If instead `mode == runTxModeDeliver`, the [`handler`](../building-modules/handler.md) function for the message is executed, before `RunMsgs` returns. +First, it retreives the `message`'s `route` using the `Msg.Route()` method. Then, using the application's [`router`](#routing) and the `route`, it checks for the existence of a `handler`. At this point, if `mode == runTxModeCheck`, `RunMsgs` returns. If instead `mode == runTxModeDeliver`, the [`handler`](../building-modules.md#handler) function for the message is executed, before `RunMsgs` returns. ## Other ABCI Messages ### InitChain -The [`InitChain` ABCI message](https://tendermint.com/docs/app-dev/abci-spec.html#initchain) is sent from the underlying Tendermint engine when the chain is first started. It is mainly used to **initialize** parameters and state like: - -- [Consensus Parameters](https://tendermint.com/docs/spec/abci/apps.html#consensus-parameters) via `setConsensusParams`. -- [`checkState` and `deliverState`](#volatile-states) via `setCheckState` and `setDeliverState`. -- The [block gas meter](../basics/accounts-fees-gas.md#block-gas-meter), with infinite gas to process genesis transactions. - -Finally, the `InitChain(req abci.RequestInitChain)` method of `baseapp` calls the [`initChainer()`](../basics/app-anatomy.md#initchainer) of the application in order to initialize the main state of the application from the [`genesis file`](./genesis.md) and, if defined, call the `InitGenesis` function of each of the application's modules. +The `InitChain` ABCI message is sent from the underlying Tendermint engine when the chain is first started. ### BeginBlock -The [`BeginBlock` ABCI message](#https://tendermint.com/docs/app-dev/abci-spec.html#beginblock) is sent from the underlying Tendermint engine when a block proposal created by the correct proposer is received, before [`DeliverTx`](#delivertx) is run for each transaction in the block. It allows developers to have logic be executed at the beginning of each block. In the Cosmos SDK, the `BeginBlock(req abci.RequestBeginBlock)` method does the following: - -- Initialize [`deliverState`](#volatile-states) with the latest header using the `req abci.RequestBeginBlock` passed as parameter via the [`setDeliverState`](https://github.com/cosmos/cosmos-sdk/blob/master/baseapp/baseapp.go#L283-L289) function. -- Initialize the [block gas meter](../basics/accounts-fees-gas.md#block-gas-meter) with the `maxGas` limit. The `gas` consumed within the block cannot go above `maxGas`. This parameter is defined in the application's consensus parameters. -- Run the application's [`begingBlocker()`](../basics/app-anatomy.md#beginblocker-and-endblock), which mainly runs the `BeginBlocker()` method of each of the application's modules. -- Set the [`VoteInfos`](https://tendermint.com/docs/app-dev/abci-spec.html#voteinfo) of the application, i.e. the list of validators whose *precommit* for the previous block was included by the proposer of the current block. This information is carried into the [`Context`](./context.md) so that it can be used during `DeliverTx` and `EndBlock`. - ### EndBlock -The [`EndBlock` ABCI message](#https://tendermint.com/docs/app-dev/abci-spec.html#endblock) is sent from the underlying Tendermint engine after [`DeliverTx`](#delivertx) as been run for each transactioni n the block. It allows developers to have logic be executed at the end of each block. In the Cosmos SDK, the bulk `EndBlock(req abci.RequestEndBlock)` method is to run the application's [`endBlocker()`](../basics/app-anatomy.md#beginblocker-and-endblock), which mainly runs the `EndBlocker()` method of each of the application's modules. - ### Commit -The [`Commit` ABCI message](https://tendermint.com/docs/app-dev/abci-spec.html#commit) is sent from the underlying Tendermint engine after the full-node has received *precommits* from 2/3+ of validators (weighted by voting power). On the `baseapp` end, the `Commit(res abci.ResponseCommit)` function is implemented to commit all the valid state transitions that occured during `BeginBlock`, `DeliverTx` and `EndBlock` and to reset state for the next block. +The [`Commit` ABCI message](https://tendermint.com/docs/app-dev/abci-spec.html#commit) is sent from the underlying Tendermint engine after the full-node has received *precommits* from 2/3+ of validators (weighted by voting power). On the `baseapp` end, the `Commit(res abci.ResponseCommit)` function is implemented to commit all the valid state transitions that occured during `BeginBlock()`, `DeliverTx()` and `EndBlock()` and to reset state for the next block. To commit state-transitions, the `Commit` function calls the `Write()` function on `deliverState.ms`, where `deliverState.ms` is a cached multistore of the main store `app.cms`. Then, the `Commit` function sets `checkState` to the latest header (obtbained from `deliverState.ctx.BlockHeader`) and `deliverState` to `nil`. -Finally, `Commit` returns the hash of the commitment of `app.cms` back to the underlying consensus engine. This hash is used as a reference in the header of the next block. +Finally, `Commit` returns the hash of the commitment of `app.cms` back to the underlying consensus engine. This hash is used as a reference in the header of the next block. ### Info -The [`Info` ABCI message](https://tendermint.com/docs/app-dev/abci-spec.html#info) is a simple query from the underlying consensus engine, notably used to sync the latter with the application during a handshake that happens on startup. When called, the `Info(res abci.ResponseInfo)` function from `baseapp` will return the application's name, version and the hash of the last commit of `app.cms`. - -### Query - -The [`Query` ABCI message](https://tendermint.com/docs/app-dev/abci-spec.html#query) is used to serve queries received from the underlying consensus engine, including queries received via RPC like Tendermint RPC. It is the main entrypoint to build interfaces with the application. The application must respect a few rules when implementing the `Query` method, which are outlined [here](https://tendermint.com/docs/app-dev/abci-spec.html#query). - -The `baseapp` implementation of the `Query(req abci.RequestQuery)` method is a simple dispatcher serving 4 main categories of queries: - -- Application-related queries like querying the application's version, which are served via the `handleQueryApp` method. -- Direct queries to the multistore, which are served by the `handlerQueryStore` method. These direct queryeis are different from custom queries which go through `app.queryRouter`, and are mainly used by third-party service provider like block explorers. -- P2P queries, which are served via the `handleQueryP2P` method. These queries return either `app.addrPeerFilter` or `app.ipPeerFilter` that contain the list of peers filtered by address or IP respectively. These lists are first initialized via `options` in `baseapp`'s [constructor](#constructor). -- Custom queries, which encompass most queries, are served via the `handleQueryCustom` method. The `handleQueryCustom` cache-wraps the multistore before using the `queryRoute` obtained from [`app.queryRouter`](#query-routing) to map the query to the appropriate module's [`querier`](../building-modules/querier.md). - -## Next - -Learn more about [stores](./store.md). +### Query diff --git a/docs/modules/handler.md b/docs/modules/handler.md deleted file mode 100644 index f8fc820df8de..000000000000 --- a/docs/modules/handler.md +++ /dev/null @@ -1 +0,0 @@ -# Handlers \ No newline at end of file diff --git a/docs/modules/invariants.md b/docs/modules/invariants.md deleted file mode 100644 index 18cd9ad6224f..000000000000 --- a/docs/modules/invariants.md +++ /dev/null @@ -1,5 +0,0 @@ -# Invariants - -## What is an invariant - -## Invariant Registry \ No newline at end of file diff --git a/docs/modules/keeper.md b/docs/modules/keeper.md deleted file mode 100644 index e69de29bb2d1..000000000000 diff --git a/docs/modules/module-interfaces.md b/docs/modules/module-interfaces.md deleted file mode 100644 index 0cd27c895326..000000000000 --- a/docs/modules/module-interfaces.md +++ /dev/null @@ -1,5 +0,0 @@ -# Module Interfaces - -## CLI - -## REST \ No newline at end of file diff --git a/docs/modules/modules.md b/docs/modules/modules.md deleted file mode 100644 index 5c65c4d89f92..000000000000 --- a/docs/modules/modules.md +++ /dev/null @@ -1,8 +0,0 @@ -# SDK Modules - -Todo: Intro concept docs on modules - -## Application Module Interface - -## Module Manager - diff --git a/docs/modules/querier.md b/docs/modules/querier.md deleted file mode 100644 index 3afa9f0cc308..000000000000 --- a/docs/modules/querier.md +++ /dev/null @@ -1,3 +0,0 @@ -# Queriers - -TODO \ No newline at end of file From 8c6c26b221250966c99906bcdb1cb7cf24ac5d78 Mon Sep 17 00:00:00 2001 From: gamarin Date: Fri, 5 Jul 2019 19:53:40 +0200 Subject: [PATCH 088/196] finish first draft --- docs/basics/accounts-fees.md | 11 ------- docs/basics/app-anatomy.md | 4 +-- docs/core/baseapp.md | 63 ++++++++++++++++++++++++------------ 3 files changed, 45 insertions(+), 33 deletions(-) delete mode 100644 docs/basics/accounts-fees.md diff --git a/docs/basics/accounts-fees.md b/docs/basics/accounts-fees.md deleted file mode 100644 index 20fe1fb2dac8..000000000000 --- a/docs/basics/accounts-fees.md +++ /dev/null @@ -1,11 +0,0 @@ -# Accounts, Fees and Gas - -## Accounts - -## AnteHandler - -## Signatures - -## Fees - -## Gas \ No newline at end of file diff --git a/docs/basics/app-anatomy.md b/docs/basics/app-anatomy.md index bca2c0c2774f..af206c06cf6a 100644 --- a/docs/basics/app-anatomy.md +++ b/docs/basics/app-anatomy.md @@ -117,7 +117,7 @@ The SDK offers developers the possibility to implement automatic execution of co In general, the `BeginBlocker` and `EndBlocker` functions are mostly composed of the `BeginBlock` and `EndBlock` functions of each of the application's modules. This is done by calling the `BeginBlock` and `EndBlock` functions of the module manager, which in turn will call the `BeginBLock` and `EndBlock` functions of each of the modules it contains. Note that the order in which the modules' `BegingBlock` and `EndBlock` functions must be called has to be set in the module manager using the `SetOrderBeginBlock` and `SetOrderEndBlock` methods respectively. This is done in the [application's constructor](#application-constructor), and the `SetOrderBeginBlock` and `SetOrderEndBlock` methods have to be called before the `SetBeginBlocker` and `SetEndBlocker` functions. -As a sidenote, it is important to remember that application-specific blockchains are deterministic. Developers must be careful not to introduce non-determinism in `BeginBlocker` or `EndBlocker`, and must also be careful not to make them too computationally expensive, as [gas](./accounts-fees.md/gas) does not constrain the cost of `BeginBlocker` and `EndBlocker` execution. +As a sidenote, it is important to remember that application-specific blockchains are deterministic. Developers must be careful not to introduce non-determinism in `BeginBlocker` or `EndBlocker`, and must also be careful not to make them too computationally expensive, as [gas](./accounts-fees-gas.md/gas) does not constrain the cost of `BeginBlocker` and `EndBlocker` execution. You can see an example of `BeginBlocker` and `EndBlocker` functions [here](https://github.com/cosmos/gaia/blob/master/app/app.go#L224-L232). @@ -155,7 +155,7 @@ To learn more about the application module interface, [click here](../building-m A message is a custom type defined by each module that implements the [`message`](../building-modules/messages-and-queries.md#messages) interface. Each [`transaction`](../core/transaction.md) contains one or multiple `messages`. When a valid block of transactions is received by the full-node, Tendermint relays each one to the application via [`DeliverTx`](https://tendermint.com/docs/app-dev/abci-spec.html#delivertx). Then, the application handles the transaction: 1. Upon receiving the transaction, the application first unmarshalls it from `[]bytes`. -2. Then, it verifies a few things about the transaction like [fee payment and signatures](#accounts-fees.md) before extracting the message(s) contained in the transaction. +2. Then, it verifies a few things about the transaction like [fee payment and signatures](#accounts-fees-gas.md) before extracting the message(s) contained in the transaction. 3. With the [`Type()`](https://github.com/cosmos/cosmos-sdk/blob/master/types/tx_msg.go#L16) method, `baseapp` is able to know which modules defines the message. It is then able to route it to the appropriate module's [handler](#handler) in order for the message to be processed. 4. If the message is successfully processed, the state is updated. diff --git a/docs/core/baseapp.md b/docs/core/baseapp.md index 7f8214b34e4c..b0b889f7812d 100644 --- a/docs/core/baseapp.md +++ b/docs/core/baseapp.md @@ -29,9 +29,6 @@ This document describes `baseapp`, the abstraction that implements most of the c + [Info](#info) + [Query](#query) - - - ## Introduction `baseapp` is an abstraction that implements the core of an SDK application, namely: @@ -67,12 +64,12 @@ First, the important parameters that are initialized during the initialization o - A [`CommitMultiStore`](./store.md#commit-multi-store). This is the main store of the application, which holds the canonical state that is committed at the [end of each block](#commit). This store is **not** cached, meaning it is not used to update the application's intermediate (un-committed) states. The `CommitMultiStore` is a multi-store, meaning a store of stores. Each module of the application uses one or multiple `KVStores` in the multi-store to persist their subset of the state. - A [database](./store.md#database) `db`, which is used by the `CommitMultiStore` to handle data storage. -- A [router](#messages). The `router` facilitates the routing of [messages](./tx-msgs.md) to the appropriate module for it to be processed. -- A [query router](#queries). The `query router` facilitates the routing of [queries](./querier.md) to the appropriate module for it to be processed. +- A [router](#message-routing). The `router` facilitates the routing of [messages](./tx-msgs.md) to the appropriate module for it to be processed. +- A [query router](#query-routing). The `query router` facilitates the routing of [queries](./querier.md) to the appropriate module for it to be processed. - A [`txDecoder`](https://godoc.org/github.com/cosmos/cosmos-sdk/types#TxDecoder), used to decode transaction `[]byte` relayed by the underlying Tendermint engine. - A [`baseKey`], to access the [main store](./store.md#main-store) in the `CommitMultiStore`. The main store is used to persist data related to the core of the application, like consensus parameters. - A [`anteHandler`](#antehandler), to handle signature verification and fee paiement when a transaction is received. -- An [`initChainer`](./app-anatomy.md#initchainer), [`beginBlocker` and `endBlocker`](./app-anatomy.md#beginblocker-and-endblocker), which are the functions executed when the application received the [InitChain], [BeginBlock] and [EndBlock] messages from the underlying Tendermint engine. +- An [`initChainer`](../basics/app-anatomy.md#initchainer), [`beginBlocker` and `endBlocker`](../basics/app-anatomy.md#beginblocker-and-endblocker), which are the functions executed when the application received the [InitChain], [BeginBlock] and [EndBlock] messages from the underlying Tendermint engine. Then, parameters used to define [volatile states](#volatile-states) (i.e. cached states): @@ -89,13 +86,9 @@ Finally, a few more important parameterd: `NewBaseApp(name string, logger log.Logger, db dbm.DB, txDecoder sdk.TxDecoder, options ...func(*BaseApp),)` is the constructor function for `baseapp`. It is called from the [application's constructor function](../basics/app-anatomy.md#constructor-function) each time the full-node is started. -`baseapp`'s constructor function is pretty straightforward. The only thing worth noting is the possibility to add additional [`options`](https://github.com/cosmos/cosmos-sdk/blob/master/baseapp/options.go) to `baseapp` by passing `options functions` to the constructor function, which will execute them in order. `options` are generally `setter` functions for important parameters, like `SetPruning()` to active pruning or `SetMinGasPrices()` to set the node's `min-gas-prices`. - -A list of `options` examples can be found [here](https://github.com/cosmos/cosmos-sdk/blob/master/baseapp/options.go). Naturally, developers can add additional `options` based on their application's needs. - -## Constructor - +`baseapp`'s constructor function is pretty straightforward. The only thing worth noting is the possibility to add additional [`options`](https://github.com/cosmos/cosmos-sdk/blob/master/baseapp/options.go) to `baseapp` by passing `options functions` to the constructor function, which will execute them in order. `options` are generally `setters` function for important parameters, like `SetPruning()` to active pruning or `SetMinGasPrices()` to set the node's `min-gas-prices`. +A list of `options` example can be found [here](https://github.com/cosmos/cosmos-sdk/blob/master/baseapp/options.go). Naturally, developers can add additional `options` based on their application's needs. ## States @@ -149,8 +142,8 @@ Commit() | | ``` ``` - To perform stateful checks To execute state To answer queries - on received transactions transitions during DeliverTx about last-committed state + To perform stateful checks To execute state To serve queries + on received transactions transitions during DeliverTx on last-committed state +----------------------+ +----------------------+ +----------------------+ | CheckState(t)(0) | | DeliverState(t)(0) | | QueryState(t) | +----------------------+ | | | | @@ -246,7 +239,7 @@ The consensus engine handles two main tasks: - The networking logic, which mainly consists in gossiping block parts, transactions and consensus votes. - The consensus logic, which results in the deterministic ordering of transactions in the form of blocks. -It is **not** the role of the consensus engine to define the state or the validity of transactions. Generally, transactions are handled by the consensus engine in the form of `[]bytes`, and relayed to the application via the ABCI to be decoded and processed. At keys moments in the networking and consensus processes (e.g. beginning of a block, commit of a block, reception of an unconfirmed transaction, ...), the consensus engine emits ABCI messages for the state-machine to act on. +It is **not** the role of the consensus engine to define the state or the validity of transactions. Generally, transactions are handled by the consensus engine in the form of `[]bytes`, and relayed to the application via the ABCI to be decoded and processed. At keys moments in the networking and consensus processes (e.g. beginning of a block, commit of a block, reception of an unconfirmed transaction, ...), the consensus engine emits ABCI messages for the state-machine to act on. Developers building on top of the Cosmos SDK need not implement the ABCI themselves, as `baseapp` comes with a built-in implementation of the interface. Let us go through the main ABCI messages that `baseapp` implements: [`CheckTx`](#checktx) and [`DeliverTx`](#delivertx) @@ -258,10 +251,10 @@ Developers building on top of the Cosmos SDK need not implement the ABCI themsel 1. Extract the `message`s from the transaction. 2. Perform *stateless* checks by calling `ValidateBasic()` on each of the `messages`. This is done first, as *stateless* checks are less computationally expensive than *stateful* checks. If `ValidateBasic()` fail, `CheckTx` returns before running *stateful* checks, which saves resources. -3. Perform non-module related *stateful* checks on the account. This step is mainly about checking that the `message` signatures are valid, that enough fees are provided and that the sending account has enough funds to pay for said fees. Note that no precise [`gas`](./accounts-fees.md#gas) counting occurs here, as `message`s are not processed. Usually, the [`anteHandler`](./accounts-fees.md#antehandler) will check that the `gas` provided with the transaction is superior to a minimum reference gas amount based on the raw transaction size, in order to avoid spam with transactions that provide 0 gas. +3. Perform non-module related *stateful* checks on the account. This step is mainly about checking that the `message` signatures are valid, that enough fees are provided and that the sending account has enough funds to pay for said fees. Note that no precise [`gas`](./accounts-fees-gas.md#gas) counting occurs here, as `message`s are not processed. Usually, the [`anteHandler`](./accounts-fees-gas.md#antehandler) will check that the `gas` provided with the transaction is superior to a minimum reference gas amount based on the raw transaction size, in order to avoid spam with transactions that provide 0 gas. 4. Ensure that a [`Route`](#message-routing) exists for each `message`, but do **not** actually process `message`s. `Message`s only need to be processed when the canonical state need to be updated, which happens during `DeliverTx`. -Steps 2. and 3. are performed by the [`anteHandler`](./accounts-fees.md#antehandler) in the [`RunTx`](#runtx-,antehandler-and-runmsgs) function, which `CheckTx` calls with the `runTxModeCheck` mode. During each step of `CheckTx`, a special [volatile state](#volatile-states) called `checkState` is updated. This state is used to keep track of the temporary changes triggered by the `CheckTx` calls of each transaction without modifying the [main canonical state](#main-state) . For example, when a transaction goes through `CheckTx`, the transaction's fees are deducted from the sender's account in `checkState`. If a second transaction is received from the same account before the first is processed, and the account has consumed all its funds in `checkState` during the first transaction, the second transaction will fail `CheckTx` and be rejected. In any case, the sender's account will not actually pay the fees until the transaction is actually included in a block, because `checkState` never gets committed to the main state. `checkState` is reset to the latest state of the main state each time a blocks gets [committed](#commit). +Steps 2. and 3. are performed by the [`anteHandler`](./accounts-fees-gas.md#antehandler) in the [`RunTx`](#runtx-,antehandler-and-runmsgs) function, which `CheckTx` calls with the `runTxModeCheck` mode. During each step of `CheckTx`, a special [volatile state](#volatile-states) called `checkState` is updated. This state is used to keep track of the temporary changes triggered by the `CheckTx` calls of each transaction without modifying the [main canonical state](#main-state) . For example, when a transaction goes through `CheckTx`, the transaction's fees are deducted from the sender's account in `checkState`. If a second transaction is received from the same account before the first is processed, and the account has consumed all its funds in `checkState` during the first transaction, the second transaction will fail `CheckTx` and be rejected. In any case, the sender's account will not actually pay the fees until the transaction is actually included in a block, because `checkState` never gets committed to the main state. `checkState` is reset to the latest state of the main state each time a blocks gets [committed](#commit). `CheckTx` returns a response to the underlying consensus engine of type [`abci.ResponseCheckTx`](https://tendermint.com/docs/spec/abci/abci.html#messages). The response contains: @@ -304,7 +297,7 @@ During step 5., each read/write to the store increases the value of `GasConsumed `RunTx` is called from `CheckTx`/`DeliverTx` to handle the transaction, with `runTxModeCheck` or `runTxModeDeliver` as parameter to differentiate between the two modes of execution. Note that when `RunTx` receives a transaction, it has already been decoded. -The first thing `RunTx` does upon being called is to retrieve the `context`'s `CacheMultiStore` by calling the `getContextForTx()` function with the appropriate mode (either `runTxModeCheck` or `runTxModeDeliver`). This `CacheMultiStore` is a cached version of the main store instantiated during `BeginBlock` for `DeliverTx` and during the `Commit` of the previous block for `CheckTx`. After that, two `defer func()` are called for [`gas`](./accounts-fees.md#gas) management. They are executed when `runTx` returns and make sure `gas` is actually consumed, and will throw errors, if any. +The first thing `RunTx` does upon being called is to retrieve the `context`'s `CacheMultiStore` by calling the `getContextForTx()` function with the appropriate mode (either `runTxModeCheck` or `runTxModeDeliver`). This `CacheMultiStore` is a cached version of the main store instantiated during `BeginBlock` for `DeliverTx` and during the `Commit` of the previous block for `CheckTx`. After that, two `defer func()` are called for [`gas`](./accounts-fees-gas.md#gas) management. They are executed when `runTx` returns and make sure `gas` is actually consumed, and will throw errors, if any. After that, `RunTx` calls `ValidateBasic()` on each `message`in the `Tx`, which runs prelimary *stateless* validity checks. If any `message` fails to pass `ValidateBasic()`, `RunTx` returns with an error. @@ -334,15 +327,30 @@ First, it retreives the `message`'s `route` using the `Msg.Route()` method. Then ### InitChain -The `InitChain` ABCI message is sent from the underlying Tendermint engine when the chain is first started. +The [`InitChain` ABCI message](https://tendermint.com/docs/app-dev/abci-spec.html#initchain) is sent from the underlying Tendermint engine when the chain is first started. It is mainly used to **initialize** parameters and state like: + +- [Consensus Parameters](https://tendermint.com/docs/spec/abci/apps.html#consensus-parameters) via `setConsensusParams`. +- [`checkState` and `deliverState`](#volatile-states) via `setCheckState` and `setDeliverState`. +- The [block gas meter](../basics/accounts-fees-gas.md#block-gas-meter), with infinite gas to process genesis transactions. + +Finally, the `InitChain(req abci.RequestInitChain)` method of `baseapp` calls the [`initChainer()`](../basics/app-anatomy.md#initchainer) of the application in order to initialize the main state of the application from the [`genesis file`](./genesis.md) and, if defined, call the `InitGenesis` function of each of the application's modules. ### BeginBlock +The [`BeginBlock` ABCI message](#https://tendermint.com/docs/app-dev/abci-spec.html#beginblock) is sent from the underlying Tendermint engine when a block proposal created by the correct proposer is received, before [`DeliverTx`](#delivertx) is run for each transaction in the block. It allows developers to have logic be executed at the beginning of each block. In the Cosmos SDK, the `BeginBlock(req abci.RequestBeginBlock)` method does the following: + +- Initialize [`deliverState`](#volatile-states) with the latest header using the `req abci.RequestBeginBlock` passed as parameter via the [`setDeliverState`](https://github.com/cosmos/cosmos-sdk/blob/master/baseapp/baseapp.go#L283-L289) function. +- Initialize the [block gas meter](../basics/accounts-fees-gas.md#block-gas-meter) with the `maxGas` limit. The `gas` consumed within the block cannot go above `maxGas`. This parameter is defined in the application's consensus parameters. +- Run the application's [`begingBlocker()`](../basics/app-anatomy.md#beginblocker-and-endblock), which mainly runs the `BeginBlocker()` method of each of the application's modules. +- Set the [`VoteInfos`](https://tendermint.com/docs/app-dev/abci-spec.html#voteinfo) of the application, i.e. the list of validators whose *precommit* for the previous block was included by the proposer of the current block. This information is carried into the [`Context`](./context.md) so that it can be used during `DeliverTx` and `EndBlock`. + ### EndBlock +The [`EndBlock` ABCI message](#https://tendermint.com/docs/app-dev/abci-spec.html#endblock) is sent from the underlying Tendermint engine after [`DeliverTx`](#delivertx) as been run for each transactioni n the block. It allows developers to have logic be executed at the end of each block. In the Cosmos SDK, the bulk `EndBlock(req abci.RequestEndBlock)` method is to run the application's [`endBlocker()`](../basics/app-anatomy.md#beginblocker-and-endblock), which mainly runs the `EndBlocker()` method of each of the application's modules. + ### Commit -The [`Commit` ABCI message](https://tendermint.com/docs/app-dev/abci-spec.html#commit) is sent from the underlying Tendermint engine after the full-node has received *precommits* from 2/3+ of validators (weighted by voting power). On the `baseapp` end, the `Commit(res abci.ResponseCommit)` function is implemented to commit all the valid state transitions that occured during `BeginBlock()`, `DeliverTx()` and `EndBlock()` and to reset state for the next block. +The [`Commit` ABCI message](https://tendermint.com/docs/app-dev/abci-spec.html#commit) is sent from the underlying Tendermint engine after the full-node has received *precommits* from 2/3+ of validators (weighted by voting power). On the `baseapp` end, the `Commit(res abci.ResponseCommit)` function is implemented to commit all the valid state transitions that occured during `BeginBlock`, `DeliverTx` and `EndBlock` and to reset state for the next block. To commit state-transitions, the `Commit` function calls the `Write()` function on `deliverState.ms`, where `deliverState.ms` is a cached multistore of the main store `app.cms`. Then, the `Commit` function sets `checkState` to the latest header (obtbained from `deliverState.ctx.BlockHeader`) and `deliverState` to `nil`. @@ -350,4 +358,19 @@ Finally, `Commit` returns the hash of the commitment of `app.cms` back to the un ### Info +The [`Info` ABCI message](https://tendermint.com/docs/app-dev/abci-spec.html#info) is a simple query from the underlying consensus engine, notably used to sync the latter with the application during a handshake that happens on startup. When called, the `Info(res abci.ResponseInfo)` function from `baseapp` will return the application's name, version and the hash of the last commit of `app.cms`. + ### Query + +The [`Query` ABCI message](https://tendermint.com/docs/app-dev/abci-spec.html#query) is used to serve queries received from the underlying consensus engine, including queries received via RPC like Tendermint RPC. It is the main entrypoint to build interfaces with the application. The application must respect a few rules when implementing the `Query` method, which are outlined [here](https://tendermint.com/docs/app-dev/abci-spec.html#query). + +The `baseapp` implementation of the `Query(req abci.RequestQuery)` method is a simple dispatcher serving 4 main categories of queries: + +- Application-related queries like querying the application's version, which are served via the `handleQueryApp` method. +- Direct queries to the multistore, which are served by the `handlerQueryStore` method. These direct queryeis are different from custom queries which go through `app.queryRouter`, and are mainly used by third-party service provider like block explorers. +- P2P queries, which are served via the `handleQueryP2P` method. These queries return either `app.addrPeerFilter` or `app.ipPeerFilter` that contain the list of peers filtered by address or IP respectively. These lists are first initialized via `options` in `baseapp`'s [constructor](#constructor). +- Custom queries, which encompass most queries, are served via the `handleQueryCustom` method. The `handleQueryCustom` cache-wraps the multistore before using the `queryRoute` obtained from [`app.queryRouter`](#query-routing) to map the query to the appropriate module's [`querier`](../building-modules/querier.md). + +## Next + +Learn more about [stores](./store.md). From 96d044186d03b42236ced68a1c942fcf561a2d02 Mon Sep 17 00:00:00 2001 From: gamarin Date: Fri, 5 Jul 2019 19:59:09 +0200 Subject: [PATCH 089/196] remove old files --- docs/core/baseapp_old.md | 128 +++++++++++++++++++++++++++++++++++++++ 1 file changed, 128 insertions(+) create mode 100644 docs/core/baseapp_old.md diff --git a/docs/core/baseapp_old.md b/docs/core/baseapp_old.md new file mode 100644 index 000000000000..c4f71f33f696 --- /dev/null +++ b/docs/core/baseapp_old.md @@ -0,0 +1,128 @@ +# BaseApp + +The BaseApp defines the foundational implementation for a basic ABCI application +so that your Cosmos-SDK application can communicate with an underlying +Tendermint node. + +The BaseApp is composed of many internal components. Some of the most important +include the `CommitMultiStore` and its internal state. The internal state is +essentially two sub-states, both of which are used for transaction execution +during different phases, `CheckTx` and `DeliverTx` respectively. During block +commitment, only the `DeliverTx` is persisted. + +The BaseApp requires stores to be mounted via capabilities keys - handlers can +only access stores they're given the key to. The `baseApp` ensures all stores are +properly loaded, cached, and committed. One mounted store is considered the +"main" (`baseApp.MainStoreKey`) - it holds the latest block header, from which we can find and load the +most recent state. + +The BaseApp distinguishes between two handler types - the `AnteHandler` and the +`MsgHandler`. The former is a global validity check (checking nonces, sigs and +sufficient balances to pay fees, e.g. things that apply to all transaction from +all modules), the later is the full state transition function. + +During `CheckTx` the state transition function is only applied to the `checkTxState` +and should return before any expensive state transitions are run +(this is up to each developer). It also needs to return the estimated gas cost. + +During `DeliverTx` the state transition function is applied to the blockchain +state and the transactions need to be fully executed. + +The BaseApp is responsible for managing the context passed into handlers - +it makes the block header available and provides the right stores for `CheckTx` +and `DeliverTx`. BaseApp is completely agnostic to serialization formats. + +## Routing + +TODO + +## Transaction Life Cycle + +During the execution of a transaction, it may pass through both `CheckTx` and +`DeliverTx` as defined in the ABCI specification. `CheckTx` is executed by the +proposing validator and is used for the Tendermint mempool for all full nodes. + +Both `CheckTx` and `DeliverTx` execute the application's AnteHandler (if +defined), where the AnteHandler is responsible for pre-message validation +checks such as account and signature validation, fee deduction and collection, +and incrementing sequence numbers. + +### CheckTx + +During the execution of `CheckTx`, only the AnteHandler is executed. + +State transitions due to the AnteHandler are persisted between subsequent calls +of `CheckTx` in the check-tx state, unless the AnteHandler fails and aborts. + +### DeliverTx + +During the execution of `DeliverTx`, the AnteHandler and Handler is executed. + +The transaction execution during `DeliverTx` operates in a similar fashion to +`CheckTx`. However, state transitions that occur during the AnteHandler are +persisted even when the following Handler processing logic fails. + +It is possible that a malicious proposer may include a transaction in a block +that fails the AnteHandler. In this case, all state transitions for the +offending transaction are discarded. + + +## Other ABCI Messages + +Besides `CheckTx` and `DeliverTx`, BaseApp handles the following ABCI messages. + +### Info +TODO complete description + +### SetOption +TODO complete description + +### Query +TODO complete description + +### InitChain +TODO complete description + +During chain initialization InitChain runs the initialization logic directly on +the CommitMultiStore. The deliver and check states are initialized with the +ChainID. + +Note that we do not commit after InitChain, so BeginBlock for block 1 starts +from the deliver state as initialized by InitChain. + +### BeginBlock +TODO complete description + +### EndBlock +TODO complete description + +### Commit +TODO complete description + + +## Gas Management + +### Gas: InitChain + +During InitChain, the block gas meter is initialized with an infinite amount of +gas to run any genesis transactions. + +Additionally, the InitChain request message includes ConsensusParams as +declared in the genesis.json file. + +### Gas: BeginBlock + +The block gas meter is reset during BeginBlock for the deliver state. If no +maximum block gas is set within baseapp then an infinite gas meter is set, +otherwise a gas meter with `ConsensusParam.BlockSize.MaxGas` is initialized. + +### Gas: DeliverTx + +Before the transaction logic is run, the `BlockGasMeter` is first checked to +see if any gas remains. If no gas remains, then `DeliverTx` immediately returns +an error. + +After the transaction has been processed, the used gas (up to the transaction +gas limit) is deducted from the BlockGasMeter. If the remaining gas exceeds the +meter's limits, then DeliverTx returns an error and the transaction is not +committed. From 082ef4ccb56f1268a7769e2ce0b1bf7b6194f593 Mon Sep 17 00:00:00 2001 From: gamarin Date: Thu, 11 Jul 2019 18:43:04 +0200 Subject: [PATCH 090/196] finish intro --- docs/building-modules/README.md | 78 ++++++++++++++++++++++ docs/building-modules/intro.md | 29 ++++---- docs/building-modules/module-interfaces.md | 8 +++ docs/building-modules/modules-manager.md | 6 ++ docs/core/baseapp.md | 6 +- 5 files changed, 109 insertions(+), 18 deletions(-) create mode 100644 docs/building-modules/README.md create mode 100644 docs/building-modules/modules-manager.md diff --git a/docs/building-modules/README.md b/docs/building-modules/README.md new file mode 100644 index 000000000000..5b5743671751 --- /dev/null +++ b/docs/building-modules/README.md @@ -0,0 +1,78 @@ +# Auth + +The `x/auth` modules is used for accounts + +See the [API docs](https://godoc.org/github.com/cosmos/cosmos-sdk/x/auth) + +See the [specification](https://github.com/cosmos/cosmos-sdk/tree/master/docs/spec/auth) + +# Bank + +The `x/bank` module is for transferring coins between accounts. + +See the [API docs](https://godoc.org/github.com/cosmos/cosmos-sdk/x/bank). + +See the [specification](https://github.com/cosmos/cosmos-sdk/tree/master/docs/spec/bank) + +# Stake + +The `x/staking` module is for Cosmos Delegated-Proof-of-Stake. + +See the [API docs](https://godoc.org/github.com/cosmos/cosmos-sdk/x/staking). + +See the +[specification](https://github.com/cosmos/cosmos-sdk/tree/master/docs/spec/staking) + +# Slashing + +The `x/slashing` module is for Cosmos Delegated-Proof-of-Stake. + +See the [API docs](https://godoc.org/github.com/cosmos/cosmos-sdk/x/slashing) + +See the +[specification](https://github.com/cosmos/cosmos-sdk/tree/master/docs/spec/slashing) + +# Distribution + +The `x/distribution` module is for distributing fees and inflation across bonded +stakeholders. + +See the [API docs](https://godoc.org/github.com/cosmos/cosmos-sdk/x/distribution) + +See the +[specification](https://github.com/cosmos/cosmos-sdk/tree/master/docs/spec/distribution) + +# Governance + +The `x/gov` module is for bonded stakeholders to make proposals and vote on them. + +See the [API docs](https://godoc.org/github.com/cosmos/cosmos-sdk/x/gov) + +See the +[specification](https://github.com/cosmos/cosmos-sdk/tree/master/docs/spec/governance) + +To keep up with the current status of IBC, follow and contribute to [ICS](https://github.com/cosmos/ics) + +# Crisis + +The `x/crisis` module is for halting the blockchain under certain circumstances. + +See the [API Docs](https://godoc.org/github.com/cosmos/cosmos-sdk/x/crisis) + +See the [specification](https://github.com/cosmos/cosmos-sdk/blob/master/docs/spec/crisis) + +# Mint + +The `x/mint` module is for flexible inflation rates and effect a balance between market liquidity and staked supply. + +See the [API Docs](https://godoc.org/github.com/cosmos/cosmos-sdk/x/mint) + +See the [specification](https://github.com/cosmos/cosmos-sdk/blob/master/docs/spec/mint) + +# Params + +The `x/params` module provides a globally available parameter store. + +See the [API Docs](https://godoc.org/github.com/cosmos/cosmos-sdk/x/params) + +See the [specification](https://github.com/cosmos/cosmos-sdk/blob/master/docs/spec/params) diff --git a/docs/building-modules/intro.md b/docs/building-modules/intro.md index 403eb755a2a2..d3e8440992d5 100644 --- a/docs/building-modules/intro.md +++ b/docs/building-modules/intro.md @@ -7,7 +7,7 @@ ## Synopsis -Modules define most of the logic of any SDK application. Developers compose module together to build their custom application-specific blockchains. This document outlines the basic concepts behind SDK modules and how to approach module management. +Modules define most of the logic of any SDK application. Developers compose module together to build their custom application-specific blockchains. This document outlines the basic concepts behind SDK modules and how to approach module management. - [Role of Modules in an SDK application](#role-of-modules-in-an-sdk-application) - [How to Approach Building Modules as a Developer](#how-to-approach-building-modules-as-a-developer) @@ -18,14 +18,14 @@ Modules define most of the logic of any SDK application. Developers compose modu The Cosmos SDK can be thought as the Ruby-on-Rails of blockchain development. It comes with a core that provides the basic functionalities every blockchain application need, like a boilerplate implementation of the ABCI to communicate with the underlying consensus engine, a multistore to persist state, a server to form a full-node and interfaces to handle queries. -On top of this core, the SDK enables developers to build modules that implement the business logic of their application. In other words, SDK modules implement the bulk of the logic of applications, while the core does the wiring and enables modules to be composed together. The end goal is to build a robust ecosystem of open-source SDK modules, making it increasingly easier to build complex blockchain applications. +On top of this core, the SDK enables developers to build modules that implement the business logic of their application. In other words, SDK modules implement the bulk of the logic of applications, while the core does the wiring and enables modules to be composed together. The end goal is to build a robust ecosystem of open-source SDK modules, making it increasingly easier to build complex blockchain applications. -SDK Modules can be seen as little state-machines within the state-machine. They generally define a subset of the state using one ore multiple `KVStore` in the [main multistore](../core/store.md), as well as a subset of [`message` types](./message.md). These `message`s are routed by one of the main component of SDK core, [`baseapp`](../core/baseapp.md), to the [`handler`](./handler.md) of the module that define them. +SDK Modules can be seen as little state-machines within the state-machine. They generally define a subset of the state using one ore multiple `KVStore` in the [main multistore](../core/store.md), as well as a subset of [`message` types](./message.md). These `message`s are routed by one of the main component of SDK core, [`baseapp`](../core/baseapp.md), to the [`handler`](./handler.md) of the module that define them. ``` + | - | Transaction relayed from the full-node's consensus engine + | Transaction relayed from the full-node's consensus engine | to the node's application via DeliverTx | | @@ -67,29 +67,28 @@ SDK Modules can be seen as little state-machines within the state-machine. They v ``` -As a result of this architecture, building an SDK application usually revolves around writing modules to implement the specialized logic of the application, and composing them with existing modules to complete the application. Developers will generally work on modules that implement logic needed for their specific use case that do not exist yet, and will use existing modules for more generic functionalities like staking, accounts or token management. +As a result of this architecture, building an SDK application usually revolves around writing modules to implement the specialized logic of the application, and composing them with existing modules to complete the application. Developers will generally work on modules that implement logic needed for their specific use case that do not exist yet, and will use existing modules for more generic functionalities like staking, accounts or token management. ## How to Approach Building Modules as a Developer While there is no definitive guidelines for writing modules, here are some important design principles developers should keep in mind when building them: -- **Composability**: SDK applications are almost always composed of multiple modules. This means developers need to carefully consider the integration of their module not only with the core of the Cosmos SDK, but also with other modules. The former is achieved by following standard design patterns outlined [here](#main-components-of-sdk-modules), while the latter is achieved by properly exposing the store(s) of the module via the [`keeper`](./keeper.md). -- **Specialization**: A direct consequence of the **composability** feature is that modules should be **specialized**. Developers should carefully establish the scope of their module and not batch multiple functionalities into the same module. This separation of concern enables modules to be re-used in other projects and improves the upgradability of the application. **Specialization** also plays an important role in the [object-capabilities model](../core/ocap.md) of the Cosmos SDK. -- **Capabilities**: Most modules need to read and/or write to the store(s) of other modules. However, in an open-source environment, it is possible for some module to be malicious. That is why module developers need to carefully think not only about how their module interracts with other modules, and how to give access to the module's store(s). The Cosmos SDK takes a capabilities-oriented approach to inter-module security. This means that each store defined by a module is accessed by a `key`, which is held by the module's [`keeper`](./keeper.md). This `keeper` defines how to access the store(s) and under what conditions. Access to the module's store(s) is done by passing a reference to the module's `keeper`. +- **Composability**: SDK applications are almost always composed of multiple modules. This means developers need to carefully consider the integration of their module not only with the core of the Cosmos SDK, but also with other modules. The former is achieved by following standard design patterns outlined [here](#main-components-of-sdk-modules), while the latter is achieved by properly exposing the store(s) of the module via the [`keeper`](./keeper.md). +- **Specialization**: A direct consequence of the **composability** feature is that modules should be **specialized**. Developers should carefully establish the scope of their module and not batch multiple functionalities into the same module. This separation of concern enables modules to be re-used in other projects and improves the upgradability of the application. **Specialization** also plays an important role in the [object-capabilities model](../core/ocap.md) of the Cosmos SDK. +- **Capabilities**: Most modules need to read and/or write to the store(s) of other modules. However, in an open-source environment, it is possible for some module to be malicious. That is why module developers need to carefully think not only about how their module interracts with other modules, and how to give access to the module's store(s). The Cosmos SDK takes a capabilities-oriented approach to inter-module security. This means that each store defined by a module is accessed by a `key`, which is held by the module's [`keeper`](./keeper.md). This `keeper` defines how to access the store(s) and under what conditions. Access to the module's store(s) is done by passing a reference to the module's `keeper`. ## Main Components of SDK Module -Modules are by convention defined in the `.x/` subfolder (e.g. the `bank` module will be defined in the `./x/bank` folder). They generally share the same core components: +Modules generally share the same core components: -- Custom [`message` types](./message.md) to trigger state-transitions. -- A [`handler`](./handler.md) used to process messages when they are routed to the module by [`baseapp`](../core/baseapp.md#message-routing). -- A [`keeper`](./keeper.md), used to access the module's store(s) and update the state. +- Custom [`message` types](./message.md) to trigger state-transitions. +- A [`handler`](./handler.md) used to process messages when they are routed to the module by [`baseapp`](../core/baseapp.md#message-routing). +- A [`keeper`](./keeper.md), used to access the module's store(s) and update the state. - A [`querier`](./querier.md), used to process user queries when they are routed to the module by [`baseapp`](../core/baseapp.md#query-routing). - Interfaces, for end users to query the subset of the state defined by the module and create `message`s of the custom types defined in the module. -In addition to these components, modules implement the `AppModule` interface in order to be managed by the [`module manager`](./module-manager.md). +In addition to these components, modules implement the `module` interface in order to be managed by the [`module manager`](./module-manager.md). ## Next -Read more on the [`AppModule` interface and the `module manager`](./module-manager.md) - +Read more on the [`module interface` and the `module manager`](./module-manager.md) diff --git a/docs/building-modules/module-interfaces.md b/docs/building-modules/module-interfaces.md index c3ddea3298aa..377e9ed56f98 100644 --- a/docs/building-modules/module-interfaces.md +++ b/docs/building-modules/module-interfaces.md @@ -1,3 +1,4 @@ +<<<<<<< HEAD # Module Interfaces ## Prerequisites @@ -281,3 +282,10 @@ A few things to note: ## Next Read about the next topic in building modules. +======= +# Module Manager + +## Application Module Interface + +## Module Manager +>>>>>>> finish intro diff --git a/docs/building-modules/modules-manager.md b/docs/building-modules/modules-manager.md new file mode 100644 index 000000000000..c10974af7609 --- /dev/null +++ b/docs/building-modules/modules-manager.md @@ -0,0 +1,6 @@ +# Module Manager + +## Application Module Interface + +## Module Manager + diff --git a/docs/core/baseapp.md b/docs/core/baseapp.md index b0b889f7812d..d34db4912444 100644 --- a/docs/core/baseapp.md +++ b/docs/core/baseapp.md @@ -34,7 +34,7 @@ This document describes `baseapp`, the abstraction that implements most of the c `baseapp` is an abstraction that implements the core of an SDK application, namely: - The [Application-Blockchain Interface](#abci), for the state-machine to communicate with the underlying consensus engine (e.g. Tendermint). -- A [Router](#routing), to route [messages](./tx-msgs.md) and [queries](./querier.md) to the appropriate [module](../building-modules/modules.md). +- A [Router](#routing), to route [messages](./tx-msgs.md) and [queries](./querier.md) to the appropriate [module](../building-modules/intro.md). - Different [states](#states), as the state-machine can have different parallel states updated based on the ABCI message received. The goal of `baseapp` is to provide a boilerplate SDK application that developers can easily extend to build their own custom application. Usually, developers will create a custom type for their application, like so: @@ -222,7 +222,7 @@ When messages and queries are received by the application, they must be routed t [`Message`s](#../building-modules/messages-and-queries.md#messages) need to be routed after they are extracted from transactions, which are sent from the underlying Tendermint engine via the [`CheckTx`](#checktx) and [`DeliverTx`](#delivertx) ABCI messages. To do so, `baseapp` holds a [`router`](https://github.com/cosmos/cosmos-sdk/blob/master/baseapp/router.go) which maps `paths` (`string`) to the appropriate module [`handler`](./handler.md). Usually, the `path` is the name of the module. -The application's `router` is initilalized with all the routes using the application's [module manager](./modules.md#module-manager), which itself is initialized with all the application's modules in the application's [constructor](../basics/app-anatomy.md#app-constructor). +The application's `router` is initilalized with all the routes using the application's [module manager](../building-modules/module-manager.md), which itself is initialized with all the application's modules in the application's [constructor](../basics/app-anatomy.md#app-constructor). ### Query Routing @@ -321,7 +321,7 @@ The `AnteHandler` is theoretically optional, but still a very important componen `RunMsgs` is called from `RunTx` with `runTxModeCheck` as parameter to check the existence of a route for each message the transaction, and with `runTxModeDeliver` to actually process the `message`s. -First, it retreives the `message`'s `route` using the `Msg.Route()` method. Then, using the application's [`router`](#routing) and the `route`, it checks for the existence of a `handler`. At this point, if `mode == runTxModeCheck`, `RunMsgs` returns. If instead `mode == runTxModeDeliver`, the [`handler`](../building-modules.md#handler) function for the message is executed, before `RunMsgs` returns. +First, it retreives the `message`'s `route` using the `Msg.Route()` method. Then, using the application's [`router`](#routing) and the `route`, it checks for the existence of a `handler`. At this point, if `mode == runTxModeCheck`, `RunMsgs` returns. If instead `mode == runTxModeDeliver`, the [`handler`](../building-modules/handler.md) function for the message is executed, before `RunMsgs` returns. ## Other ABCI Messages From 00e88d8cb549122dc258faa4ba0c6dc6af1e879c Mon Sep 17 00:00:00 2001 From: gamarin Date: Thu, 18 Jul 2019 17:20:03 +0200 Subject: [PATCH 091/196] workinnn --- docs/basics/app-anatomy.md | 44 +++---- docs/building-modules/module-interfaces.md | 9 +- docs/building-modules/modules-manager.md | 145 ++++++++++++++++++++- docs/core/baseapp.md | 6 +- 4 files changed, 168 insertions(+), 36 deletions(-) diff --git a/docs/basics/app-anatomy.md b/docs/basics/app-anatomy.md index af206c06cf6a..2e4613c5e8b6 100644 --- a/docs/basics/app-anatomy.md +++ b/docs/basics/app-anatomy.md @@ -65,6 +65,8 @@ The `start` command function primarily does three things: 2. Initialize the state-machine with the latest known state, extracted from the `db` stored in the `~/.appd/data` folder. At this point, the state-machine is at height `appBlockHeight`. 3. Create and start a new Tendermint instance. Among other things, the node will perform a handshake with its peers. It will get the latest `blockHeight` from them, and replay blocks to sync to this height if it is greater than the local `appBlockHeight`. If `appBlockHeight` is `0`, the node is starting from genesis and Tendermint sends an `InitChain` message via the ABCI to the `app`, which triggers the [`InitChainer`](#initchainer). +To learn more about the `start` command, [click here](../core/node.md#start-command). + ## Core Application File In general, the core of the state-machine is defined in a file called `app.go`. It mainly contains the **type definition of the application** and functions to **create and initialize it**. @@ -73,11 +75,11 @@ In general, the core of the state-machine is defined in a file called `app.go`. The first thing defined in `app.go` is the `type` of the application. It is generally comprised of the following parts: -- **A reference to [`baseapp`](./baseapp.md).** The custom application defined in `app.go` is an extension of the `baseapp` type. `baseapp` implements most of the core logic for the application, including all the [ABCI methods](https://tendermint.com/docs/spec/abci/abci.html#overview) and the routing logic. When a transaction is relayed by Tendermint to the application, the latter uses `baseapp`'s methods to route them to the appropriate module. -- **A list of store keys**. The [store](./store.md), which contains the entire state, is implemented as a multistore (i.e. a store of stores) in the Cosmos SDK. Each module uses one or multiple stores in the multistore to persist their part of the state. These stores can be accessed with specific keys that are declared in the `app` type. These keys, along with the `keepers`, are at the heart of the [object-capabilities model](../intro/ocap.md) of the Cosmos SDK. -- **A list of module's `keepers`.** Each module defines an abstraction called `keeper`, which handles reads and writes for this module's store(s). The `keeper`'s methods of one module can be called from other modules (if authorized), which is why they are declared in the application's type and exported as interfaces to other modules so that they are only allowed to access the authorized functions. -- **A reference to a `codec`.** The Cosmos SDK gives developers the freedom to choose the encoding framework for their application. The application's `codec` is used to serialize and deserialize data structures in order to store them, as stores can only persist `[]bytes`. The `codec` must be deterministic. The default codec is [amino](./amino.md). -- **A reference to a [module manager](./modules.md#module-manager)**. The module manager is an object that contains a list of the application's module. It facilitates operations related to these modules, like registering [`routes`](./baseapp.md#routing), [query routes](#./baseapp.md#query-routing) or setting the order of execution between modules for various functions like [`InitChainer`](#initchainer), [`BeginBlocker` and `EndBlocker`](#beginblocker-and-endblocker). +- **A reference to [`baseapp`](../core/baseapp.md).** The custom application defined in `app.go` is an extension of the `baseapp` type. `baseapp` implements most of the core logic for the application, including all the [ABCI methods](https://tendermint.com/docs/spec/abci/abci.html#overview) and the routing logic. When a transaction is relayed by Tendermint to the application, the latter uses `baseapp`'s methods to route them to the appropriate module. +- **A list of store keys**. The [store](../core/store.md), which contains the entire state, is implemented as a multistore (i.e. a store of stores) in the Cosmos SDK. Each module uses one or multiple stores in the multistore to persist their part of the state. These stores can be accessed with specific keys that are declared in the `app` type. These keys, along with the `keepers`, are at the heart of the [object-capabilities model](../intro/ocap.md) of the Cosmos SDK. +- **A list of module's `keepers`.** Each module defines an abstraction called [`keeper`](../building-modules/keeper.md), which handles reads and writes for this module's store(s). The `keeper`'s methods of one module can be called from other modules (if authorized), which is why they are declared in the application's type and exported as interfaces to other modules so that they are only allowed to access the authorized functions. +- **A reference to a [`codec`](../core/encoding.md).** The Cosmos SDK gives developers the freedom to choose the encoding framework for their application. The application's `codec` is used to serialize and deserialize data structures in order to store them, as stores can only persist `[]bytes`. The `codec` must be deterministic. The default codec is [amino](./amino.md). +- **A reference to a [module manager](../building-modules/module-manager.md#manager)** and a [basic module manager](../building-modules/module-manager.md#basicmanager). The module manager is an object that contains a list of the application's module. It facilitates operations related to these modules, like registering [`routes`](./baseapp.md#routing), [query routes](#./baseapp.md#query-routing) or setting the order of execution between modules for various functions like [`InitChainer`](#initchainer), [`BeginBlocker` and `EndBlocker`](#beginblocker-and-endblocker). You can see an example of application type definition [here](https://github.com/cosmos/gaia/blob/master/app/app.go#L73-L107). @@ -88,14 +90,14 @@ This function constructs a new application of the type defined above. It is call - Instantiate a new [`codec`](../core/encoding.md) and initialize the `codec` of each of the application's module using the [basic manager](../building-modules/module-manager.md#basicmanager) - Instantiate a new application with a reference to a `baseapp` instance, a codec and all the appropriate store keys. - Instantiate all the [`keeper`s](#keeper) defined in the application's `type` using the `NewKeeper` function of each of the application's modules. Note that `keepers` must be instantiated in the correct order, as the `NewKeeper` of one module might require a reference to another module's `keeper`. -- Instantiate the application's [module manager](./module-manager.md) with the [`AppModule`](#application-module-interface) object of each of the application's modules. -- With the module manager, initialize the application's [`routes`](./baseapp.md#routing) and [query routes](./baseapp.md#query-routing). When a transaction is relayed to the application by Tendermint via the ABCI, it is routed to the appropriate module's [`handler`](#handler) using the routes defined here. Likewise, when a query is received by the application, it is routed to the appropriate module's [`querier`](#querier) using the query routes defined here. -- With the module manager, register the [application's modules' invariants](./invariants.md). Invariants are variables (e.g. total supply of a token) that are evaluated at the end of each block. The process of checking invariants is done via a special module called the [`InvariantsRegistry`](./invariants.md#invariant-registry). The value of the invariant should be equal to a predicted value defined in the module. Should the value be different than the predicted one, special logic defined in the invariant registry will be triggered (usually the chain is halted). This is useful to make sure no critical bug goes unnoticed and produces long-lasting effects that would be hard to fix. +- Instantiate the application's [module manager](../building-modules/module-manager.md#manager) with the [`AppModule`](#application-module-interface) object of each of the application's modules. +- With the module manager, initialize the application's [`routes`](../core/baseapp.md#routing) and [query routes](../core/baseapp.md#query-routing). When a transaction is relayed to the application by Tendermint via the ABCI, it is routed to the appropriate module's [`handler`](#handler) using the routes defined here. Likewise, when a query is received by the application, it is routed to the appropriate module's [`querier`](#querier) using the query routes defined here. +- With the module manager, register the [application's modules' invariants](./invariants.md). Invariants are variables (e.g. total supply of a token) that are evaluated at the end of each block. The process of checking invariants is done via a special module called the [`InvariantsRegistry`](../building-modules/invariants.md#invariant-registry). The value of the invariant should be equal to a predicted value defined in the module. Should the value be different than the predicted one, special logic defined in the invariant registry will be triggered (usually the chain is halted). This is useful to make sure no critical bug goes unnoticed and produces long-lasting effects that would be hard to fix. - With the module manager, set the order of execution between the `InitGenesis`, `BegingBlocker` and `EndBlocker` functions of each of the [application's modules](#application-module-interface). Note that not all modules implement these functions. - Set the remainer of application's parameters: + [`InitChainer`](#initchainer): used to initialize the application when it is first started. + [`BeginBlocker`, `EndBlocker`](#beginblocker-and-endlbocker): called at the beginning and the end of every block). - + [`anteHandler`](#baseapp.md#antehandler): used to handle fees and signature verification. + + [`anteHandler`](../core/baseapp.md#antehandler): used to handle fees and signature verification. - Mount the stores. - Return the application. @@ -105,7 +107,7 @@ You can see an example of application constructor [here](https://github.com/cosm ### InitChainer -The `InitChainer` is a function that initializes the state of the application from a [genesis file](./genesis.md) (i.e. token balances of genesis accounts). It is called when the application receives the `InitChain` message from the Tendermint engine, which happens when the node is started at `appBlockHeight == 0` (i.e. on genesis). The application must set the `InitChainer` in its constructor via the [`SetInitChainer`](https://godoc.org/github.com/cosmos/cosmos-sdk/baseapp#BaseApp.SetInitChainer) method. +The `InitChainer` is a function that initializes the state of the application from a [genesis file](../core/genesis.md) (i.e. token balances of genesis accounts). It is called when the application receives the `InitChain` message from the Tendermint engine, which happens when the node is started at `appBlockHeight == 0` (i.e. on genesis). The application must set the `InitChainer` in its constructor via the [`SetInitChainer`](https://godoc.org/github.com/cosmos/cosmos-sdk/baseapp#BaseApp.SetInitChainer) method. In general, the `InitChainer` is mostly composed of the `InitGenesis` function of each of the application's modules. This is done by calling the `InitGenesis` function of the module manager, which in turn will call the `InitGenesis` function of each of the modules it contains. Note that the order in which the modules' `InitGenesis` functions must be called has to be set in the module manager using the `SetOrderInitGenesis` method. This is done in the [application's constructor](#application-constructor), and the `SetOrderInitGenesis` has to be called before the `SetInitChainer`. @@ -131,24 +133,20 @@ You can see an example of a `MakeCodec` [here](https://github.com/cosmos/gaia/bl ## Modules -Modules are the heart and soul of an SDK application. They can be considered as state-machines within the state-machine. When a transaction is relayed from the underlying Tendermint engine via the ABCI to the application, it is routed by `baseapp` to the appropriate module in order to be processed. This paradigm enables developers to easily build complex state-machines, as most of the modules they need often already exist. For developers, most of the work involved in building an SDK application revolves around building custom modules required by their application that do not exist, and integrating them with modules that do already exist into one coherent application. In the application directory, the standard practice is to store modules in the `x/` folder (not to be confused with the SDK's `x/` folder, which contains already-built modules). +Modules are the heart and soul of an SDK application. They can be considered as state-machines within the state-machine. When a transaction is relayed from the underlying Tendermint engine via the ABCI to the application, it is routed by [`baseapp`](../core/baseapp.md) to the appropriate module in order to be processed. This paradigm enables developers to easily build complex state-machines, as most of the modules they need often already exist. For developers, most of the work involved in building an SDK application revolves around building custom modules required by their application that do not exist, and integrating them with modules that do already exist into one coherent application. In the application directory, the standard practice is to store modules in the `x/` folder (not to be confused with the SDK's `x/` folder, which contains already-built modules). To learn more about modules, [click here](./modules.md) ### Application Module Interface -Modules implement two interfaces defined in the Cosmos SDK, [`AppModuleBasic`](https://github.com/cosmos/cosmos-sdk/blob/master/types/module/module.go#L44-L57) and [`AppModule`](https://github.com/cosmos/cosmos-sdk/blob/master/types/module/module.go#L44-L57). The former implements basic non-dependant elements of the module, such as the `codec`, while the latter handles the bulk of the module methods (including methods that require references to other modules' `keeper`s). Both the `AppModule` and `AppModuleBasic` types are defined in a file called `./module.go`. - -`AppModule` exposes a collection of useful methods on the module that facilitates the composition of modules into a coherent application. Important methods include: - -- `Route()` and `QueryRoute()`: These methods the name of the route and querier route for the module, for [messages](#message-types) to be routed to the module's [`handler`](#handler) and queries to be routes to the module's [`querier`](#querier). -- `NewHandler()` and `NewQuerierHandler()`: These methods return a `handler` and `querierHandler` respectively, in order to process a message or a query once they are routed. -- `BeginBlock()`, `EndBlock()` and `InitGenesis()`: These methods are executed respectively at the beginning of each block, at the end of each block and at the start of the chain. They implement special logic the module requires to be triggered during those events. For example, the `EndBlock` function is frequently used by modules where voting occurs to tally the result of the votes. -- `RegisterInvariants()`: This method registers the [invariants](./invariants.md) for the module. Invariants are checked at the end of every block to make sure no unpredicted behaviour is occuring. +Modules implement two interfaces defined in the Cosmos SDK, [`AppModuleBasic`](../building-modules/module-manager.md#appmodulebasic) and [`AppModule`](../building-modules/module-manager.md#appmodule). The former implements basic non-dependant elements of the module, such as the `codec`, while the latter handles the bulk of the module methods (including methods that require references to other modules' `keeper`s). Both the `AppModule` and `AppModuleBasic` types are defined in a file called `./module.go`. -`AppModule`'s methods are called from the `module manager`(./modules.md#module-manager), which manages the application's collection of modules. +`AppModule` exposes a collection of useful methods on the module that facilitates the composition of modules into a coherent application. These methods are are called from the `module manager`(../building-modules/module-manager.md#manager), which manages the application's collection of modules. +To learn more about the application module interface, [click here](./modules.md#application-module-interface). +======= To learn more about the application module interface, [click here](../building-modules/module-manager.md#application-module-interfaces). +>>>>>>> workinnn ### Message Types @@ -171,7 +169,7 @@ The [`handler`](../building-modules/handler.md) refers to the part of the module The handler of a module is generally defined in a file called `handler.go` and consists of: -- A **switch function** `NewHandler` to route the message to the appropriate handler function. This function returns a `handler` function, and is registered in the [`AppModule`](#application-module-interface) to be used in the application's module manager to initialize the [application's router](./baseapp.md#routing). See an example of such a switch [here](https://github.com/cosmos/sdk-application-tutorial/blob/master/x/nameservice/handler.go#L10-L22). +- A **switch function** `NewHandler` to route the message to the appropriate handler function. This function returns a `handler` function, and is registered in the [`AppModule`](#application-module-interface) to be used in the application's module manager to initialize the [application's router](../core/baseapp.md#routing). See an example of such a switch [here](https://github.com/cosmos/sdk-application-tutorial/blob/master/x/nameservice/handler.go#L10-L22). - **One handler function for each message type defined by the module**. Developers write the message processing logic in these functions. This generally involves doing stateful checks to ensure the message is valid and calling [`keeper`](#keeper)'s methods to update the state. Handler functions return a result of type [`sdk.Result`](https://github.com/cosmos/cosmos-sdk/blob/master/types/result.go#L14-L37), which informs the application on whether the message was successfully processed. @@ -198,7 +196,7 @@ To learn more about `keepers`, [click here](../building-modules/keeper.md). ### Querier -`Queriers` are very similar to `handlers`, except they serve user queries to the state as opposed to processing transactions. A query is initiated from an [interface](#intefaces) by an end-user who provides a `queryRoute` and some `data`. The query is then routed to the correct application's `querier` by `baseapp`'s [`handleQueryCustom`](https://github.com/cosmos/cosmos-sdk/blob/master/baseapp/baseapp.go#L519-L556) method using `queryRoute`. +[`Queriers`](../building-modules/querier.md) are very similar to `handlers`, except they serve user queries to the state as opposed to processing transactions. A [query](../building-modules/messages-and-queries.md#queries) is initiated from an [interface](#interfaces) by an end-user who provides a `queryRoute` and some `data`. The query is then routed to the correct application's `querier` by `baseapp`'s [`handleQueryCustom`](https://github.com/cosmos/cosmos-sdk/blob/master/baseapp/baseapp.go#L519-L556) method using `queryRoute`. The `Querier` of a module is defined in a file called `querier.go`, and consists of: @@ -241,7 +239,7 @@ The main interface is the [Command-Line Interface](../interfaces/cli.md). The CL - **A `main()` function**, which is executed to build the `appcli` interface client. This function prepares each command and adds them to the `rootCmd` before building them. At the root of `appCli`, the function adds generic commands like `status`, `keys` and `config`, query commands, tx commands and `rest-server`. - **Query commands** are added by calling the `queryCmd` function, also defined in `appcli/main.go`. This function returns a Cobra command that contains the query commands defined in each of the application's modules (passed as an array of `sdk.ModuleClients` from the `main()` function), as well as some other lower level query commands such as block or validator queries. Query command are called by using the command `appcli query [query]` of the CLI. - **Transaction commands** are added by calling the `txCmd` function. Similar to `queryCmd`, the function returns a Cobra command that contains the tx commands defined in each of the application's modules, as well as lower level tx commands like transaction signing or broadcasting. Tx commands are called by using the command `appcli tx [tx]` of the CLI. -- **A `registerRoutes` function**, which is called from the `main()` function when initializing the [application's light-client daemon (LCD)](./node.md#lcd) (i.e. `rest-server`). `registerRoutes` calls the `RegisterRoutes` function of each of the application's module, thereby registering the routes of the module to the lcd's router. The LCD can be started by running the following command `appcli rest-server`. +- **A `registerRoutes` function**, which is called from the `main()` function when initializing the [application's light-client daemon (LCD)](../core/node.md#lcd) (i.e. `rest-server`). `registerRoutes` calls the `RegisterRoutes` function of each of the application's module, thereby registering the routes of the module to the lcd's router. The LCD can be started by running the following command `appcli rest-server`. See an example of an application's main command-line file [here](https://github.com/cosmos/sdk-application-tutorial/blob/master/cmd/nscli/main.go). diff --git a/docs/building-modules/module-interfaces.md b/docs/building-modules/module-interfaces.md index 377e9ed56f98..01b20e6bff15 100644 --- a/docs/building-modules/module-interfaces.md +++ b/docs/building-modules/module-interfaces.md @@ -1,4 +1,3 @@ -<<<<<<< HEAD # Module Interfaces ## Prerequisites @@ -19,6 +18,7 @@ This document details how to build CLI and REST interfaces for a module. Example ## CLI +<<<<<<< HEAD One of the main interfaces for an application is the [command-line interface](../interfaces/cli.md). This entrypoint created by the application developer will add commands from the application's modules to let end-users create [**messages**](./messages-and-queries.md) and [**queries**](./messages-and-queries.md). The CLI files are typically found in the `./x/moduleName/client/cli` folder. ### Transaction Commands @@ -282,10 +282,3 @@ A few things to note: ## Next Read about the next topic in building modules. -======= -# Module Manager - -## Application Module Interface - -## Module Manager ->>>>>>> finish intro diff --git a/docs/building-modules/modules-manager.md b/docs/building-modules/modules-manager.md index c10974af7609..bfe4c9d2d297 100644 --- a/docs/building-modules/modules-manager.md +++ b/docs/building-modules/modules-manager.md @@ -1,6 +1,147 @@ # Module Manager -## Application Module Interface +## Pre-requisite Reading -## Module Manager +- [Introduction to SDK Modules](./intro.md) +## Synopsis + +Cosmos SDK modules need to implement the [`AppModule` interfaces](#application-module-interfaces), in order to be managed by the application's [module manager](#module-manager). The module manager plays an important role in [`message` and `query` routing](../core/baseapp.md#routing), and allows the application developer to set the order of execution of a variety of functions like [`BeginBlocker` and `EndBlocker`](../basics/app-anatomy.md#begingblocker-and-endblocker). + +## Application Module Interfaces + +[Application module interfaces](https://github.com/cosmos/cosmos-sdk/blob/master/types/module/module.go) exist to facilitate the composition of modules together to form a functional SDK application. There are 3 main application module interfaces: + +- [`AppModuleBasic`](#appmodulebasic) for independent module functionalities. +- [`AppModule`](#appmodule) for inter-dependent module functionalities (except genesis-related functionalities). +- [`AppModuleGenesis`](#appmodulegenesis) for inter-dependent genesis-related module functionalities. + +The `AppModuleBasic` interface exists to define independent methods of the module, i.e. those that do not depend on other modules in the application. This allows for the construction of the basic application structure early in the application definition, generally in the `init()` function of the [main application file](../basics/app-antomy.md#core-application-file). + +The `AppModule` interface exists to define inter-dependent module methods. Many modules need to interract with other modules, typically through [`keeper`s](./keeper.md), which means there is a need for an interface where modules list their `keeper`s and other methods that require a reference to another module's object. `AppModule` interface also enables the module manager to set the order of execution between module's methods like `BeginBlock` and `EndBlock`, which is important in cases where the order of execution between modules matters in the context of the application. + +Lastly the interface for genesis functionality `AppModuleGenesis` is separated out from full module functionality `AppModule` so that modules which +are only used for genesis can take advantage of the `Module` patterns without having to define many placeholder functions. + +### `AppModuleBasic` + +The [`AppModuleBasic`](https://github.com/cosmos/cosmos-sdk/blob/master/types/module/module.go#L45-L57) interface defines the independent methods modules need to implement. + +```go +type AppModuleBasic interface { + Name() string + RegisterCodec(*codec.Codec) + + // genesis + DefaultGenesis() json.RawMessage + ValidateGenesis(json.RawMessage) error + + // client functionality + RegisterRESTRoutes(context.CLIContext, *mux.Router) + GetTxCmd(*codec.Codec) *cobra.Command + GetQueryCmd(*codec.Codec) *cobra.Command +} +``` + +Let us go through the methods: + +- `Name()`: Returns the name of the module as a `string`. +- `RegisterCodec(*codec.Codec)`: Registers the `codec` for the module, which is used to marhsal and unmarshal structs to/from `[]byte` in order to persist them in the moduel's `KVStore`. +- `DefaultGenesis()`: Returns a default [`GenesisState`](./genesis.md#genesisstate) for the module, marshalled to `json.RawMessage`. The default `GenesisState` need to be defined by the module developer and is primarily used for testing. +- `ValidateGenesis(json.RawMessage)`: Used to validate the `GenesisState` defined by a module, given in its `json.RawMessage` form. It will usually unmarshall the `json` before running a custom [`ValidateGenesis`](./genesis.md#validategenesis) function defined by the module developer. +- `RegisterRESTRoutes(context.CLIContext, *mux.Router)`: Registers the REST routes for the module. These routes will be used to map REST request to the module in order to process them. See [../interfaces/rest.md] for more. +- `GetTxCmd(*codec.Codec)`: Returns the root [`Tx` command](./module-interfaces.md#tx) for the module. The subcommands of this root command are used by end-users to generate new transactions containing [`message`s](./messages-and-queries.md#queries) defined in the module. +- `GetQueryCmd(*codec.Codec)`: Return the root [`query` command](./module-intefaces.md#query) for the module. The subcommands of this root command are used by end-users to generate new queries to the subset of the state defined by the module. + +All the `AppModuleBasic` of an application are managed by the [`BasicManager`](#basicmanager). + +### `AppModuleGenesis` + +The [`AppModuleGenesis`](https://github.com/cosmos/cosmos-sdk/blob/master/types/module/module.go#L123-L127) interface is a simple embedding of the `AppModuleBasic` interface with two added methods. + +```go +type AppModuleGenesis interface { + AppModuleBasic + InitGenesis(sdk.Context, json.RawMessage) []abci.ValidatorUpdate + ExportGenesis(sdk.Context) json.RawMessage +} +``` + +Let us go through the two added methods: + +- `InitGenesis(sdk.Context, json.RawMessage)`: Initializes the subset of the state managed by the module. It is called at genesis (i.e. when the chain is first started). +- `ExportGenesis(sdk.Context)`: Exports the latest subset of the state managed by the module to be used in a new genesis file. `ExportGenesis` is called for each module when a new chain is started from the state of an existing chain. + +It does not have its own manager, and exists separately from [`AppModule`](#appmodule) only for modules that exist only to implement genesis functionalities, so that they can be managed without having to implement all of `AppModule`'s methods. If the module is not only used during genesis, `InitGenesis(sdk.Context, json.RawMessage)` and `ExportGenesis(sdk.Context)` will generally be defined as methods of the concrete type implementing hte `AppModule` interface. + +### `AppModule` + +The [`AppModule`](https://github.com/cosmos/cosmos-sdk/blob/master/types/module/module.go#L130-L144) interface defines the inter-dependent methods modules need to implement. + +```go +type AppModule interface { + AppModuleGenesis + + // registers + RegisterInvariants(sdk.InvariantRegistry) + + // routes + Route() string + NewHandler() sdk.Handler + QuerierRoute() string + NewQuerierHandler() sdk.Querier + + BeginBlock(sdk.Context, abci.RequestBeginBlock) + EndBlock(sdk.Context, abci.RequestEndBlock) []abci.ValidatorUpdate +} +``` + +`AppModule`s are managed by the [module manager](#manager). This interface embeds the `AppModuleGenesis` interface so that the manager can access all the independent and genesis inter-dependent methods of the module. This means that a concrete type implementing the `AppModule` interface must either implement all the methods of `AppModuleGenesis` (and by extension `AppModuleBasic`), or include a concrete type that does as parameter. + +Let us go through the methods of `AppModule`: + +- `RegisterInvariants(sdk.InvariantRegistry)`: Registers the [`invariants`](./invariants.md) of the module. If the invariants deviates from its predicted value, the [`InvariantRegistry`](./invariants.md#registry) triggers appropriate logic (most often the chain will be halted). +- `Route()`: Returns the name of the module's route, for [`message`s](./messages-and-queries.md#messages) to be routed to the module by [`baseapp`](../core/baseapp.md#message-routing). +- `NewHandler()`: Returns a [`handler`](./handler.md) given the `Type()` of the `message`, in order to process the `message`. +- `QuerierRoute()`: Returns the name of the module's query route, for [`queries`](./messages-and-queries.md#queries) to be routes to the module by [`baseapp`](../core/baseapp.md#query-routing). +- `NewQuerierHandler()`: Returns a [`querier`](./querier.md) given the query `path`, in order to process the `query`. +- `BeginBlock(sdk.Context, abci.RequestBeginBlock)`: This method gives module developers the option to implement logic that is automatically triggered at the beginning of each block. Implement empty if no logic needs to be triggered at the beginning of each block for this module. +- `EndBlock(sdk.Context, abci.RequestEndBlock)`: This method gives module developers the option to implement logic that is automatically triggered at the beginning of each block. This is also where the module can inform the underlying consensus engine of validator set changes (e.g. the `staking` module). Implement empty if no logic needs to be triggered at the beginning of each block for this module. + +### Implementing the Application Module Interfaces + +Typically, the various application module interfaces are implemented in a file called `module.go`, located in the module's folder (e.g. `./x/module/module.go`). + +Almost every module need to implement the `AppModuleBasic` and `AppModule` interfaces. If the module is only used for genesis, it will implement `AppModuleGenesis` instead of `AppModule`. The concrete type that implements the interface can add parameters that are required for the implementation of the various methods of the interface. For example, the `NewHandler()` function often calls a `NewHandler(k keeper)` function defined in [`handler.go`](./handler.md) and therefore needs to pass the module's [`keeper`](./keeper.md) as parameter. + +```go +// example +type AppModule struct { + AppModuleBasic + keeper Keeper +} +``` + +In the example above, you can see that the `AppModule` concrete type references an `AppModuleBasic`, and not an `AppModuleGenesis`. That is because `AppModuleGenesis` only needs to be implemented in modules that focus on genesis-related functionalities. In most modules, the concrete `AppModule` type will have a reference to an `AppModuleBasic` and implement the two added methods of `AppModuleGenesis` directly in the `AppModule` type. + +If no parameter is required (which is often the case for `AppModuleBasic`), just declare an empty concrete type like so: + +```go +type AppModuleBasic struct{} +``` + +## Module Managers + +Module managers are used to manage collections of `AppModuleBasic` and `AppModule`. + +### `BasicManager` + +The `BasicManager` is a structure that lists all the `AppModuleBasic` of an application: + +```go +type BasicManager map[string]AppModuleBasic +``` + + + +### `Manager` diff --git a/docs/core/baseapp.md b/docs/core/baseapp.md index d34db4912444..44c46f26f489 100644 --- a/docs/core/baseapp.md +++ b/docs/core/baseapp.md @@ -64,8 +64,8 @@ First, the important parameters that are initialized during the initialization o - A [`CommitMultiStore`](./store.md#commit-multi-store). This is the main store of the application, which holds the canonical state that is committed at the [end of each block](#commit). This store is **not** cached, meaning it is not used to update the application's intermediate (un-committed) states. The `CommitMultiStore` is a multi-store, meaning a store of stores. Each module of the application uses one or multiple `KVStores` in the multi-store to persist their subset of the state. - A [database](./store.md#database) `db`, which is used by the `CommitMultiStore` to handle data storage. -- A [router](#message-routing). The `router` facilitates the routing of [messages](./tx-msgs.md) to the appropriate module for it to be processed. -- A [query router](#query-routing). The `query router` facilitates the routing of [queries](./querier.md) to the appropriate module for it to be processed. +- A [router](#message-routing). The `router` facilitates the routing of [messages](../building-modules/messages-and-queries.md#messages) to the appropriate module for it to be processed. +- A [query router](#query-routing). The `query router` facilitates the routing of [queries](../building-modules/messages-and-queries.md#queries) to the appropriate module for it to be processed. - A [`txDecoder`](https://godoc.org/github.com/cosmos/cosmos-sdk/types#TxDecoder), used to decode transaction `[]byte` relayed by the underlying Tendermint engine. - A [`baseKey`], to access the [main store](./store.md#main-store) in the `CommitMultiStore`. The main store is used to persist data related to the core of the application, like consensus parameters. - A [`anteHandler`](#antehandler), to handle signature verification and fee paiement when a transaction is received. @@ -226,7 +226,7 @@ The application's `router` is initilalized with all the routes using the applica ### Query Routing -Similar to messages, queries need to be routed to the appropriate module's [querier](./querier.md). To do so, `baseapp` holds a [`query router`](https://github.com/cosmos/cosmos-sdk/blob/master/baseapp/queryrouter.go), which maps `paths` (`string`) to the appropriate module [`querier`](./querier.md). Usually, the `path` is the name of the module. +Similar to `message`s, [`queries`](../building-modules/messages-and-queries.md#queries) need to be routed to the appropriate module's [querier](../building-modules/querier.md). To do so, `baseapp` holds a [`query router`](https://github.com/cosmos/cosmos-sdk/blob/master/baseapp/queryrouter.go), which maps `paths` (`string`) to the appropriate module `querier`. Usually, the `path` is the name of the module. Just like the `router`, the `query router` is initilalized with all the query routes using the application's [module manager](../building-modules/module-manager.md), which itself is initialized with all the application's modules in the application's [constructor](../basics/app-anatomy.md#app-constructor). From 996e47d4c6f21c75e2c9a703ea683184e629538b Mon Sep 17 00:00:00 2001 From: Gloria Zhao Date: Sat, 20 Jul 2019 11:10:20 -0700 Subject: [PATCH 092/196] initial commit after rebase --- docs/interfaces/cli.md | 145 ++++++++++++++++++++++++++++- docs/interfaces/query-lifecycle.md | 33 +++++++ 2 files changed, 176 insertions(+), 2 deletions(-) create mode 100644 docs/interfaces/query-lifecycle.md diff --git a/docs/interfaces/cli.md b/docs/interfaces/cli.md index fda1ef60b91e..b09d4581cbdf 100644 --- a/docs/interfaces/cli.md +++ b/docs/interfaces/cli.md @@ -1,3 +1,144 @@ -# CLI +# Command-Line Interface -> TODO: Rewrite this section to explain how CLI works for a generic SDK app. +## Prerequisites + +* [Anatomy of an SDK App](./app-anatomy.md) + +## Synopsis + +This document describes how to create a commmand-line interface for an SDK application. A separate document for creating module interfaces can be found [here](#./module-interfaces.md). + +1. [Application CLI](#Application-cli) +2. [Commands](#commands) +3. [Flags](#flags) +4. [Initialization and Configurations](#initialization-and-configurations) + +## Application CLI + +One of the main entrypoints of an application is the command-line interface. This entrypoint is created as a `main.go` file which compiles to a binary, conventionally placed in the application's `app/cmd/cli` folder. + +### Cobra + +There is no set way to create a CLI, but SDK modules all use the [Cobra Library](https://github.com/spf13/cobra). Building a CLI with Cobra entails defining commands, arguments, and flags. [**Commands**](#commands) represent the action users wish to take, such as `tx` for creating a transaction and `query` for querying the application. Each command can also have nested subcommands, necessary for naming the specific transaction type. Users also supply **Arguments**, such as account numbers to send coins to, and [**Flags**](#flags) to modify various aspects of the commands, such as gas prices or which node to broadcast to. + +### Main Function + +The `main.go` file needs to have a `main()` function that does the following to run the command-line interface: + +* **Instantiate the `codec`** by calling the application's `MakeCodec()` function. The `codec` is used to code and encode data structures for the application - stores can only persist `[]byte`s so the developer must define a serialization format for their data structures or use the default, [Amino](./amino.md). +* **Configurations** are set by reading in configuration files (e.g. the sdk config file). +* **Create the root command** to which all the application commands will be added as subcommands and add any required flags to it, such as `--chain-id`. +* **Add subcommands** for all the possible user interactions, including [transaction commands](#transaction-commands) and [query commands](#query-commands). +* **Create an Executor** and execute the root command. + +The rest of the document will detail what needs to be implemented for each step. + +## Commands + +Every application CLI first constructs a root command, then adds functionality by aggregating subcommands (often with further nested subcommands) using `AddCommand()`. The bulk of an application's unique capabilities lies in its transaction and query commands, called `TxCmd` and `QueryCmd` respectively. + +### Root Command + +The root command (also called `rootCmd`) is what the user first types into the command line to indicate which application they wish to interact with. The string used to invoke the command (the "Use" field) is typically the name of the application suffixed with `-cli`, e.g. `appcli`. The root command must include the following commands to support basic functionality in the application. + +* **Status** command from the SDK rpc client tools, which prints information about the status of the connected `Node`. +* **Config** command from the SDK client tools, which allows the user to edit a `config.toml` file that sets values for [flags](#flags) such as `--chain-id` and which `--node` they wish to connect to. +* **Keys** commands from the SDK client tools, which includes a collection of subcommands for using the key functions in the SDK crypto tools, including adding a new key and saving it to disk, listing all public keys stored in the key manager, and deleting a key. +* [**Transaction**](#transaction-commands) commands. +* [**Query**](#query-commands) commands. + +### Transaction Commands + +Application [transactions](#./transactions.md) are objects that trigger state changes. To enable the creation of transactions using the CLI interface, `TxCmd` should add the following commands: + +* **Sign** command from the [`auth`](https://github.com/cosmos/cosmos-sdk/tree/67f6b021180c7ef0bcf25b6597a629aca27766b8/docs/spec/auth) module, which signs messages in a transaction. To enable multisig, it should also add the `auth` module MultiSign command. Since every transaction requires some sort of signature in order to be valid, this command is necessary for every application. +* **Broadcast** command from the SDK client tools, which broadcasts transactions. +* **Send** command from the [`bank`](https://github.com/cosmos/cosmos-sdk/tree/67f6b021180c7ef0bcf25b6597a629aca27766b8/docs/spec/bank) module, which is a transaction that allows accounts to send coins to one another, including gas and fees for transactions. +* Any application-specific transaction commands defined by the application developer. +* All commands in each module the application is dependent on, retrieved by calling `GetTxCmd()` on all the modules or using the Module Manager's `AddTxCommands()` function. + +### Query Commands + +Application queries are objects that allow users to retrieve information about the application's state. To enable basic queries, `QueryCmd` should add the following commands: + +* **QueryTx** and/or other transaction query commands from the `auth` module which allow the user to search for a transaction by inputting its hash, a list of tags, or a block height. These various queries allow users to see if transactions have been included in a block. +* **Account** command from the `auth` module, which displays the state (e.g. account balance) of an account given an address. +* **Validator** command from the SDK rpc client tools, which displays the validator set of a given height. +* **Block** command from the SDK rpc client tools, which displays the block data for a given height. +* Any application-specific query commands defined by the application developer. +* All commands in each module the application is dependent on, retrieved by calling `GetQueryCmd()` on all the modules or using the Module Manager's `AddQueryCommands()` function. + +## Flags + +Flags are used to modify commands. Users can explicitly include them in commands or pre-configure them by entering a command in the format `appcli config ` into their command line. Commonly pre-configured flags include the `--node` to connect to and `--chain-id` of the blockchain the user wishes to interact with. + +A _persistent_ flag (as opposed to a _local_ flag) added to a command transcends all of its children. Additionally, all flags have default values when they are added to commands; some toggle an option off but others are empty values that the user needs to override to create valid commands. A flag can be explicitly marked as _required_ so that an error is automatically thrown if the user does not provide a value, but it is also acceptable to handle unexpected missing flags differently. + +### Root Command Flags + +It is common to add a _persistent_ flag for `--chain-id`, the unique identifier of the blockchain the application pertains to, to the root command. Adding this flag makes sense as the chain ID should not be changing across commands in this application CLI. + +### Transaction Flags + +To **create** a transaction, the user enters a `tx` command and provides several flags. + +* `--from` indicates which account the transaction originates from. This account is used to sign the transaction. +* `--gas` refers to how much gas, which represents computational resources, Tx consumes. Gas is dependent on the transaction and is not precisely calculated until execution, but can be estimated by providing auto as the value for --gas. +* `--gas-adjustment` (optional) can be used to scale gas up in order to avoid underestimating. For example, users can specify their gas adjustment as 1.5 to use 1.5 times the estimated gas. +* `--gas-prices` specifies how much the user is willing pay per unit of gas, which can be one or multiple denominations of tokens. For example, --gas-prices=0.025uatom, 0.025upho means the user is willing to pay 0.025uatom AND 0.025upho per unit of gas. +* `--fees` specifies how much in fees the user is willing to pay in total. Note that the user only needs to provide either `gas-prices` or `fees`, but not both, because they can be derived from each other. +* `--generate-only` (optional) instructs the application to simply generate the unsigned transaction and output or write to a file. Without this flag, the transaction is created, signed, and broadcasted all in one command. +* `--dry-run` (optional), similar to `--generate-only`, instructs the application to ignore the `--gas` flag and simulate the transaction running without broadcasting. +* `--indent` (optional) adds an indent to the JSON response. +* `--memo` sends a memo along with the transaction. + +For example, the following command creates a transaction to send 1000uatom from `sender-address` to `recipient-address`. The user is willing to pay 0.025uatom per unit gas but wants the transaction to be only generated offline (i.e. not broadcasted) and written, in JSON format, to the file `myUnsignedTx.json`. + +```bash +appcli tx send 1000uatom --from --gas auto -gas-prices 0.025uatom --generate-only > myUnsignedTx.json +``` + +To **sign** a transaction generated offline using the `--generate-only` flag, the user enters a `tx sign` command (by default, the transaction is automatically signed upon creation). There are four values for flags that must be provided if a transaction is expected to be signed: + +* `--from` specifies an address; the corresponding private key is used to sign the transaction. +* `--chain-id` specifies the unique identifier of the blockchain the transaction pertains to. +* `--sequence` is the value of a counter measuring how many transactions have been sent from the account. It is used to prevent replay attacks. +* `--account-number` is an identifier for the account. +* `--validate-signatures` (optional) instructs the process to sign the transaction and verify that all signatures have been provided. +* `--ledger` (optional) lets the user perform the action using a Ledger Nano S, which needs to be plugged in and unlocked. + +For example, the following command signs the inputted transaction, `myUnsignedTx.json`, and writes the signed transaction to the file `mySignedTx.json`. + +```bash +appcli tx sign myUnsignedTx.json --from --chain-id --sequence --account-number > mySignedTx.json +``` + +To **broadcast** a signed transaction generated offline, the user enters a `tx broadcast` command. Only one flag is required here: + +* `--node` specifies which node to broadcast to. +* `--trust-node` (optional) indicates whether or not the node and its response proofs can be trusted. +* `--broadcast-mode` (optional) specifies when the process should return. Options include asynchronous (return immediately), synchronous (return after `CheckTx` passes), or block (return after block commit). + +For example, the following command broadcasts the signed transaction, `mySignedTx.json` to a particular node. + +```bash +appcli tx broadcast mySignedTx.json --node +``` +### Query Flags + +Queries also have flags. + +* `--node` indicates which full-node to connect to. +* `--trust-node` (optional) represents whether or not the connected node is trusted. If the node is not trusted, all proofs in the responses are verified. +* `--indent` (optional) adds an indent to the JSON response. +* `--height` (optional) can be provided to query the blockchain at a specific height. +* `--ledger` (optional) lets the user perform the action using a Ledger Nano S. + + +## Initialization and Configurations + +TODO + +## Next + +Read about how to build a CLI for your module [here](./module-interfaces#cli) diff --git a/docs/interfaces/query-lifecycle.md b/docs/interfaces/query-lifecycle.md new file mode 100644 index 000000000000..895c83af4abc --- /dev/null +++ b/docs/interfaces/query-lifecycle.md @@ -0,0 +1,33 @@ +# Query Lifecycle + +## Prerequisites + +## Synopsis + +This document describes SDK interfaces through the lifecycle of a query, from the user interface to application stores and back. The query will be referred to as `query`. + +1. [Interfaces](#interfaces) +2. [CLIContext](#clicontext) +3. [Tendermint and ABCI](#tendermint-and-abci) +4. [Application Query Handling](#application-query-handling) +5. [Response](#response) + +## Interfaces + +### CLI + +### REST + +## CLIContext + +## Tendermint and ABCI + +## Application Query Handling + +### Baseapp + +## Response + +## Next + +Read about how to build a [Command-Line Interface](./cli.md). From 5b10675d02b755007105a9d87fbb658599f6cc6b Mon Sep 17 00:00:00 2001 From: Gloria Zhao Date: Sat, 20 Jul 2019 16:19:39 -0700 Subject: [PATCH 093/196] query-lifecycle and started modules-interfaces --- docs/building-modules/module-interfaces.md | 1 - docs/interfaces/cli.md | 16 ++++-- .../{interfaces.md => interfaces-intro.md} | 2 +- docs/interfaces/query-lifecycle.md | 57 +++++++++++++++++-- docs/interfaces/rest.md | 1 + 5 files changed, 64 insertions(+), 13 deletions(-) rename docs/interfaces/{interfaces.md => interfaces-intro.md} (73%) create mode 100644 docs/interfaces/rest.md diff --git a/docs/building-modules/module-interfaces.md b/docs/building-modules/module-interfaces.md index 01b20e6bff15..c3ddea3298aa 100644 --- a/docs/building-modules/module-interfaces.md +++ b/docs/building-modules/module-interfaces.md @@ -18,7 +18,6 @@ This document details how to build CLI and REST interfaces for a module. Example ## CLI -<<<<<<< HEAD One of the main interfaces for an application is the [command-line interface](../interfaces/cli.md). This entrypoint created by the application developer will add commands from the application's modules to let end-users create [**messages**](./messages-and-queries.md) and [**queries**](./messages-and-queries.md). The CLI files are typically found in the `./x/moduleName/client/cli` folder. ### Transaction Commands diff --git a/docs/interfaces/cli.md b/docs/interfaces/cli.md index b09d4581cbdf..58f9b9422887 100644 --- a/docs/interfaces/cli.md +++ b/docs/interfaces/cli.md @@ -2,20 +2,20 @@ ## Prerequisites -* [Anatomy of an SDK App](./app-anatomy.md) +* [Query Lifecycle](./query-lifecycle.md) ## Synopsis This document describes how to create a commmand-line interface for an SDK application. A separate document for creating module interfaces can be found [here](#./module-interfaces.md). -1. [Application CLI](#Application-cli) +1. [Application CLI](#application-cli) 2. [Commands](#commands) 3. [Flags](#flags) 4. [Initialization and Configurations](#initialization-and-configurations) ## Application CLI -One of the main entrypoints of an application is the command-line interface. This entrypoint is created as a `main.go` file which compiles to a binary, conventionally placed in the application's `app/cmd/cli` folder. +One of the main entrypoints of an application is the command-line interface. This entrypoint is created as a `main.go` file which compiles to a binary, conventionally placed in the application's `app/cmd/cli` folder. The CLI for an application will typically be referred to as the name of the application suffixed with `-cli`, e.g. `appcli`. ### Cobra @@ -135,10 +135,14 @@ Queries also have flags. * `--ledger` (optional) lets the user perform the action using a Ledger Nano S. -## Initialization and Configurations +## Configurations -TODO +The last function to define is, `initConfig`, which should do exactly what it sounds like - initial configurations. To call this function, set it as a `PersistentPreRunE` function for the root command, so that it always executes before the main execution of the root command and any of its subcommands. `initConfig` should do the following: + +1. Read in the `config.toml` file. This same file is edited through `config` commands. +2. Use the [Viper](https://github.com/spf13/viper) to read in configurations from the file and set them. +3. Set any persistent flags defined by the user: `--chain-id`, `--encoding`, `--output`, etc. ## Next -Read about how to build a CLI for your module [here](./module-interfaces#cli) +Read about how to build a module CLI [here](./module-interfaces#cli) diff --git a/docs/interfaces/interfaces.md b/docs/interfaces/interfaces-intro.md similarity index 73% rename from docs/interfaces/interfaces.md rename to docs/interfaces/interfaces-intro.md index bb580a5cf171..43ae0f9a0a6e 100644 --- a/docs/interfaces/interfaces.md +++ b/docs/interfaces/interfaces-intro.md @@ -1,3 +1,3 @@ # Interfaces -TODO \ No newline at end of file +TODO diff --git a/docs/interfaces/query-lifecycle.md b/docs/interfaces/query-lifecycle.md index 895c83af4abc..08662b041c25 100644 --- a/docs/interfaces/query-lifecycle.md +++ b/docs/interfaces/query-lifecycle.md @@ -14,20 +14,67 @@ This document describes SDK interfaces through the lifecycle of a query, from th ## Interfaces -### CLI +A **query** is a request for information made by users of applications. They can query information about the network, the application itself, and application state directly from the application's stores or modules. There are a few ways `query` can be made. + +## CLI + +The main interface for an application is the command-line interface. Users run the CLI directly from their machines and type commands to create queries. For the purpose of explaining a query lifecycle, let's say `query` is requesting a list of delegations made by a certain delegator address in the application called `app`. To create this query from the command-line, users would type the following command: + +``` +appcli query staking delegations +``` + +### CLIContext + +The first thing that is created in the execution of a CLI command is a `CLIContext`. A [Context](../core/context.md) is an immutable object that stores all the data needed to process a request. In particular, a `CLIContext` stores the following: + +* **Codec**: The encoder/decoder used by the application, used to marshal the parameters and query before making the Tendermint RPC request and unmarshal the returned response into a JSON object. +* **Account Decoder**: The account decoder from the [`auth`](https://github.com/cosmos/cosmos-sdk/tree/67f6b021180c7ef0bcf25b6597a629aca27766b8/docs/spec/auth) module, which translates `[]byte`s into accounts. +* **RPC Client**: The [Tendermint RPC Client](https://github.com/tendermint/tendermint/blob/master/rpc/client/interface.go). +* **Keybase**: A [Key Manager](.//core/accounts-keys.md) used to sign transactions and handle other operations with keys. +* **Output Writer**: A [Writer](https://golang.org/pkg/io/#Writer) used to output the response. +* **Configurations**: The flags configured by the user for this command, including `--height`, specifying the height of the blockchain to query and `--indent`, which indicates to add an indent to the JSON response. + +For full specification of the `CLIContext` type, click [here](https://github.com/cosmos/cosmos-sdk/blob/73e5ef7c13c420f9ee879fdf1b60cf0bdc8f325e/client/context/context.go#L36-L59). + +### Parameters and Route Creation + +After a `CLIContext` is created for the CLI command, the command is parsed to create a query route and arguments. + +The command contains arguments; in this case, `query` contains a `delegatorAddress`. Since requests can only contain `[]byte`s, the `CLIContext` `codec` is used to marshal the address as the type `QueryDelegatorParams`. All query arguments (e.g. the `staking` module also has `QueryValidatorParams` and `QueryBondsParams`) have their own types that the application `codec` understands how to encode. All of this logic is specified in the module [`querier`](.//building-modules/querier.md). + +A `route` is also created for `query` so that the application will understand how to route it. Baseapp will understand this query to be a `custom` query in the module `staking` with the type `QueryDelegatorDelegations`. Thus, the route will be `"custom/staking/delegatorDelegations"`. + +### ABCI Query + +The `CLIContext`'s main `query` function takes the `route`, which is now called `path`, and arguments, now called `key`. It first retrieves the RPC Client (called the **node**) configured by the user to relay this query to, and creates the `ABCIQueryOptions` (parameters formatted for the ABCI call). The node is used to make the ABCI call, `ABCIQueryWithOptions`. + +From here, continue reading about how the CLI command is handled by skipping to the [Tendermint and ABCI](#tendermint-and-abci) section, or first read about how to make the same `query` using the [REST Interface](#rest). + +## REST + +Another interface through which users can make queries is a REST interface. -### REST -## CLIContext ## Tendermint and ABCI +Nodes running the consensus engine (e.g. Tendermint Core) make ABCI calls to interact with the application. At this point, `query` exists as an ABCI `RequestQuery` and the [ABCI Client](https://github.com/tendermint/tendermint/blob/51b3428f5c0f4fdd2e469147cd90353faa4bd704/abci/client/client.go#L16-L50) calls the ABCI method [`Query()`](https://tendermint.com/docs/spec/abci/abci.html#query) on the application. + +Read more about ABCI Clients and Tendermint RPC in the Tendermint documentation [here](https://tendermint.com/rpc). + ## Application Query Handling -### Baseapp +[Baseapp](../core/baseapp.md) implements the ABCI [`Query()`](../core/baseapp.md#query) function and handles four different types of queries: `app`, `store`, `p2p`, and `custom`. The `queryRoute` is parsed such that the first string must be one of the four options, then the rest of the path is parsed within the subroutines handling each type of query. The first three types are application-level and thus directly handled by Baseapp or the stores, but the `custom` query type requires Baseapp to route the query to a module's [querier](../building-modules/querier.md). + +Since `query` is a custom query type, Baseapp first parses the path to retrieve the name of the path. retrieves the querier using its `QueryRouter`. ## Response +The ABCI `Query()` function returns an ABCI Response of type `ResponseQuery`. + +The `CLIContext` `query` routine receives the response and, if `--trust-node` is toggled to `false` and a proof needs to be verified, the response is verified with the `CLIContext` `verifyProof` function before the response is returned. + ## Next -Read about how to build a [Command-Line Interface](./cli.md). +Read about how to build a [Command-Line Interface](./cli.md), or a [REST Interface](./rest.md). diff --git a/docs/interfaces/rest.md b/docs/interfaces/rest.md new file mode 100644 index 000000000000..9133e5ce9e2f --- /dev/null +++ b/docs/interfaces/rest.md @@ -0,0 +1 @@ +# REST Interface From b6e4e17dd1aa38e42d0fdba19cdf724651835136 Mon Sep 17 00:00:00 2001 From: Gloria Zhao Date: Sun, 21 Jul 2019 14:16:18 -0700 Subject: [PATCH 094/196] query-lifecycle first draft done --- docs/interfaces/query-lifecycle.md | 62 ++++++++++++++++++++---------- 1 file changed, 42 insertions(+), 20 deletions(-) diff --git a/docs/interfaces/query-lifecycle.md b/docs/interfaces/query-lifecycle.md index 08662b041c25..9635afa59743 100644 --- a/docs/interfaces/query-lifecycle.md +++ b/docs/interfaces/query-lifecycle.md @@ -4,7 +4,7 @@ ## Synopsis -This document describes SDK interfaces through the lifecycle of a query, from the user interface to application stores and back. The query will be referred to as `query`. +This document describes SDK interfaces in detail through the lifecycle of a query, from the user interface to application stores and back. The query will be referred to as `query`. 1. [Interfaces](#interfaces) 2. [CLIContext](#clicontext) @@ -14,19 +14,43 @@ This document describes SDK interfaces through the lifecycle of a query, from th ## Interfaces -A **query** is a request for information made by users of applications. They can query information about the network, the application itself, and application state directly from the application's stores or modules. There are a few ways `query` can be made. +A **query** is a request for information made by users of applications. They can query information about the network, the application itself, and application state directly from the application's stores or modules. -## CLI +For the purpose of explaining a query lifecycle, let's say `query` is requesting a list of delegations made by a certain delegator address in the application called `app`. There are a few ways `query` can be made on the user side. -The main interface for an application is the command-line interface. Users run the CLI directly from their machines and type commands to create queries. For the purpose of explaining a query lifecycle, let's say `query` is requesting a list of delegations made by a certain delegator address in the application called `app`. To create this query from the command-line, users would type the following command: +### CLI + +The main interface for an application is the command-line interface. Users run the CLI directly from their machines and type commands to create queries. To create this query from the command-line, users would type the following command: ``` appcli query staking delegations ``` +To provide values such as `--chain-id`, the ID of the blockchain to make the query to, the user must use the `config` command to set them or provide them as flags. + +This query command is defined by the module developer and added to the list of subcommands by the application developer when creating the CLI. To see the command itself, click [here](). + +### REST + +Another interface through which users can make queries is through HTTP Requests to a REST server. The REST server contains, among other things, a [`CLIContext`](#clicontext) and [mux](./rest.md)(#gorilla-mux) router. The request looks like this: + +```bash +http://localhost:{PORT}/staking/delegators/{delegatorAddr}/delegations +``` + +To provide values such as `--chain-id`, the ID of the blockchain to make the query to, the user must configure their REST server with the values or provide them in the request body. + +The router automatically routes the `query` HTTP request to the staking module `delegatorDelegationsHandlerFn()` function (to see the handler itself, click [here]()). Since this function is defined within the module and thus has no inherent knowledge of the application `query` belongs to, it takes in the application `codec` and `CLIContext` as parameters. + +To read about how the router is used, click [here](./rest.md). + +## Request and Command Handling + +The user interactions are somewhat similar, but the underlying functions are almost identical. This section describes how the CLI command or HTTP request is processed, up until the ABCI request is sent. This step of processing heavily involves a `CLIContext`. + ### CLIContext -The first thing that is created in the execution of a CLI command is a `CLIContext`. A [Context](../core/context.md) is an immutable object that stores all the data needed to process a request. In particular, a `CLIContext` stores the following: +The first thing that is created in the execution of a CLI command is a `CLIContext`, while the REST Server directly provides a `CLIContext` for the REST Request handler. A [Context](../core/context.md) is an immutable object that stores all the data needed to process a request. In particular, a `CLIContext` stores the following: * **Codec**: The encoder/decoder used by the application, used to marshal the parameters and query before making the Tendermint RPC request and unmarshal the returned response into a JSON object. * **Account Decoder**: The account decoder from the [`auth`](https://github.com/cosmos/cosmos-sdk/tree/67f6b021180c7ef0bcf25b6597a629aca27766b8/docs/spec/auth) module, which translates `[]byte`s into accounts. @@ -39,27 +63,19 @@ For full specification of the `CLIContext` type, click [here](https://github.com ### Parameters and Route Creation -After a `CLIContext` is created for the CLI command, the command is parsed to create a query route and arguments. +The next step is to parse the command or request, extract the arguments, create a `queryRoute`, and encode everything. -The command contains arguments; in this case, `query` contains a `delegatorAddress`. Since requests can only contain `[]byte`s, the `CLIContext` `codec` is used to marshal the address as the type `QueryDelegatorParams`. All query arguments (e.g. the `staking` module also has `QueryValidatorParams` and `QueryBondsParams`) have their own types that the application `codec` understands how to encode. All of this logic is specified in the module [`querier`](.//building-modules/querier.md). +In this case, `query` contains a `delegatorAddress` as its only argument. Since requests can only contain `[]byte`s, the `CLIContext` `codec` is used to marshal the address as the type `QueryDelegatorParams`. All query arguments (e.g. the `staking` module also has `QueryValidatorParams` and `QueryBondsParams`) have their own types that the application `codec` understands how to encode and decode. All of this logic is specified in the module [`querier`](.//building-modules/querier.md). -A `route` is also created for `query` so that the application will understand how to route it. Baseapp will understand this query to be a `custom` query in the module `staking` with the type `QueryDelegatorDelegations`. Thus, the route will be `"custom/staking/delegatorDelegations"`. +A `route` is also created for `query` so that the application will understand which module to route the query to. Baseapp will understand this query to be a `custom` query in the module `staking` with the type `QueryDelegatorDelegations`. Thus, the route will be `"custom/staking/delegatorDelegations"`. ### ABCI Query -The `CLIContext`'s main `query` function takes the `route`, which is now called `path`, and arguments, now called `key`. It first retrieves the RPC Client (called the **node**) configured by the user to relay this query to, and creates the `ABCIQueryOptions` (parameters formatted for the ABCI call). The node is used to make the ABCI call, `ABCIQueryWithOptions`. - -From here, continue reading about how the CLI command is handled by skipping to the [Tendermint and ABCI](#tendermint-and-abci) section, or first read about how to make the same `query` using the [REST Interface](#rest). - -## REST - -Another interface through which users can make queries is a REST interface. - - +The `CLIContext`'s main `query` function takes the `route`, which is now called `path`, and arguments, now called `key`. It first retrieves the RPC Client (called the **node**) configured by the user to relay this query to, and creates the `ABCIQueryOptions` (parameters formatted for the ABCI call). The node is then used to make the ABCI call, `ABCIQueryWithOptions`. ## Tendermint and ABCI -Nodes running the consensus engine (e.g. Tendermint Core) make ABCI calls to interact with the application. At this point, `query` exists as an ABCI `RequestQuery` and the [ABCI Client](https://github.com/tendermint/tendermint/blob/51b3428f5c0f4fdd2e469147cd90353faa4bd704/abci/client/client.go#L16-L50) calls the ABCI method [`Query()`](https://tendermint.com/docs/spec/abci/abci.html#query) on the application. +With a call to `ABCIQueryWithOptions()`, `query` arrives at the consensus engine portion of its lifecycle. Nodes running the consensus engine (e.g. Tendermint Core) make ABCI calls to interact with the application. At this point, `query` exists as an ABCI `RequestQuery` and the [ABCI Client](https://github.com/tendermint/tendermint/blob/51b3428f5c0f4fdd2e469147cd90353faa4bd704/abci/client/client.go#L16-L50) calls the ABCI method [`Query()`](https://tendermint.com/docs/spec/abci/abci.html#query) on the application. Read more about ABCI Clients and Tendermint RPC in the Tendermint documentation [here](https://tendermint.com/rpc). @@ -71,9 +87,15 @@ Since `query` is a custom query type, Baseapp first parses the path to retrieve ## Response -The ABCI `Query()` function returns an ABCI Response of type `ResponseQuery`. +Since `Query()` is an ABCI function, Baseapp returns the `query` response as an `abci.ResponseQuery`. The `CLIContext` `query` routine receives the response and, if `--trust-node` is toggled to `false` and a proof needs to be verified, the response is verified with the `CLIContext` `verifyProof` function before the response is returned. + +### CLI Response + +The application `codec` is used to unmarshal the response to a JSON and the `CLIContext` prints the output to the command line, applying any configurations such as `--indent`. + +### REST Response -The `CLIContext` `query` routine receives the response and, if `--trust-node` is toggled to `false` and a proof needs to be verified, the response is verified with the `CLIContext` `verifyProof` function before the response is returned. +The REST server uses the `CLIContext` to format the response properly, then uses the HTTP package to write the appropriate response or error. ## Next From a708cc2ce26c3ee6e5007dda89299fdc468d0236 Mon Sep 17 00:00:00 2001 From: Gloria Zhao Date: Tue, 23 Jul 2019 09:33:59 -0700 Subject: [PATCH 095/196] module interfaces first draft --- docs/interfaces/query-lifecycle.md | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/docs/interfaces/query-lifecycle.md b/docs/interfaces/query-lifecycle.md index 9635afa59743..6c60c92fe3b7 100644 --- a/docs/interfaces/query-lifecycle.md +++ b/docs/interfaces/query-lifecycle.md @@ -32,7 +32,7 @@ This query command is defined by the module developer and added to the list of s ### REST -Another interface through which users can make queries is through HTTP Requests to a REST server. The REST server contains, among other things, a [`CLIContext`](#clicontext) and [mux](./rest.md)(#gorilla-mux) router. The request looks like this: +Another interface through which users can make queries is through HTTP Requests to a REST server. The REST server contains, among other things, a [`CLIContext`](#clicontext) and [mux](./rest.md#gorilla-mux) router. The request looks like this: ```bash http://localhost:{PORT}/staking/delegators/{delegatorAddr}/delegations @@ -46,7 +46,7 @@ To read about how the router is used, click [here](./rest.md). ## Request and Command Handling -The user interactions are somewhat similar, but the underlying functions are almost identical. This section describes how the CLI command or HTTP request is processed, up until the ABCI request is sent. This step of processing heavily involves a `CLIContext`. +The interactions from the users' perspective are a bit different, but the underlying functions are almost identical. This section describes how the CLI command or HTTP request is processed, up until the ABCI request is sent. This step of processing heavily involves a `CLIContext`. ### CLIContext @@ -65,7 +65,7 @@ For full specification of the `CLIContext` type, click [here](https://github.com The next step is to parse the command or request, extract the arguments, create a `queryRoute`, and encode everything. -In this case, `query` contains a `delegatorAddress` as its only argument. Since requests can only contain `[]byte`s, the `CLIContext` `codec` is used to marshal the address as the type `QueryDelegatorParams`. All query arguments (e.g. the `staking` module also has `QueryValidatorParams` and `QueryBondsParams`) have their own types that the application `codec` understands how to encode and decode. All of this logic is specified in the module [`querier`](.//building-modules/querier.md). +In this case, `query` contains a `delegatorAddress` as its only argument. However, the request can only contain `[]byte`s, as it will be relayed to a consensus engine node that has no inherent knowledge of the application types. Thus, the `CLIContext` `codec` is used to marshal the address as the type `QueryDelegatorParams`. All query arguments (e.g. the `staking` module also has `QueryValidatorParams` and `QueryBondsParams`) have their own types that the application `codec` understands how to encode and decode. The module [`querier`](.//building-modules/querier.md) declares these types and the application registers the `codec`s. A `route` is also created for `query` so that the application will understand which module to route the query to. Baseapp will understand this query to be a `custom` query in the module `staking` with the type `QueryDelegatorDelegations`. Thus, the route will be `"custom/staking/delegatorDelegations"`. @@ -83,7 +83,7 @@ Read more about ABCI Clients and Tendermint RPC in the Tendermint documentation [Baseapp](../core/baseapp.md) implements the ABCI [`Query()`](../core/baseapp.md#query) function and handles four different types of queries: `app`, `store`, `p2p`, and `custom`. The `queryRoute` is parsed such that the first string must be one of the four options, then the rest of the path is parsed within the subroutines handling each type of query. The first three types are application-level and thus directly handled by Baseapp or the stores, but the `custom` query type requires Baseapp to route the query to a module's [querier](../building-modules/querier.md). -Since `query` is a custom query type, Baseapp first parses the path to retrieve the name of the path. retrieves the querier using its `QueryRouter`. +Since `query` is a custom query type, Baseapp first parses the path, then uses the `QueryRouter` to retrieve the corresponding querier. ## Response @@ -95,7 +95,7 @@ The application `codec` is used to unmarshal the response to a JSON and the `CLI ### REST Response -The REST server uses the `CLIContext` to format the response properly, then uses the HTTP package to write the appropriate response or error. +The REST server uses the `CLIContext` to format the response properly, then uses the HTTP package to write the appropriate response or error. ## Next From 9affd0f29ed175f0e425061b85c7377f085441bc Mon Sep 17 00:00:00 2001 From: Gloria Zhao Date: Thu, 25 Jul 2019 19:31:35 -0700 Subject: [PATCH 096/196] rest and intro skeletons --- docs/interfaces/cli.md | 12 ++++++------ docs/interfaces/interfaces-intro.md | 2 +- docs/interfaces/query-lifecycle.md | 10 +++++----- docs/interfaces/rest.md | 29 +++++++++++++++++++++++++++++ 4 files changed, 41 insertions(+), 12 deletions(-) diff --git a/docs/interfaces/cli.md b/docs/interfaces/cli.md index 58f9b9422887..94fca6537b06 100644 --- a/docs/interfaces/cli.md +++ b/docs/interfaces/cli.md @@ -6,12 +6,12 @@ ## Synopsis -This document describes how to create a commmand-line interface for an SDK application. A separate document for creating module interfaces can be found [here](#./module-interfaces.md). +This document describes how to create a commmand-line interface for an SDK application. A separate document for creating a module CLI can be found [here](#../module-interfaces.md#cli). -1. [Application CLI](#application-cli) -2. [Commands](#commands) -3. [Flags](#flags) -4. [Initialization and Configurations](#initialization-and-configurations) +- [Application CLI](#application-cli) +- [Commands](#commands) +- [Flags](#flags) +- [Initialization and Configurations](#initialization-and-configurations) ## Application CLI @@ -19,7 +19,7 @@ One of the main entrypoints of an application is the command-line interface. Thi ### Cobra -There is no set way to create a CLI, but SDK modules all use the [Cobra Library](https://github.com/spf13/cobra). Building a CLI with Cobra entails defining commands, arguments, and flags. [**Commands**](#commands) represent the action users wish to take, such as `tx` for creating a transaction and `query` for querying the application. Each command can also have nested subcommands, necessary for naming the specific transaction type. Users also supply **Arguments**, such as account numbers to send coins to, and [**Flags**](#flags) to modify various aspects of the commands, such as gas prices or which node to broadcast to. +There is no set way to create a CLI, but SDK modules all use the [Cobra Library](https://github.com/spf13/cobra) in order to implement the [`AppModuleBasic`]() interface. Building a CLI with Cobra entails defining commands, arguments, and flags. [**Commands**](#commands) represent the action users wish to take, such as `tx` for creating a transaction and `query` for querying the application. Each command can also have nested subcommands, necessary for naming the specific transaction type. Users also supply **Arguments**, such as account numbers to send coins to, and [**Flags**](#flags) to modify various aspects of the commands, such as gas prices or which node to broadcast to. ### Main Function diff --git a/docs/interfaces/interfaces-intro.md b/docs/interfaces/interfaces-intro.md index 43ae0f9a0a6e..09466179cc60 100644 --- a/docs/interfaces/interfaces-intro.md +++ b/docs/interfaces/interfaces-intro.md @@ -1,3 +1,3 @@ # Interfaces -TODO +This document introduces interfaces for SDK applications. The two main interfaces are the Command-Line Interface and REST Interface. diff --git a/docs/interfaces/query-lifecycle.md b/docs/interfaces/query-lifecycle.md index 6c60c92fe3b7..83fe119d1b7b 100644 --- a/docs/interfaces/query-lifecycle.md +++ b/docs/interfaces/query-lifecycle.md @@ -6,11 +6,11 @@ This document describes SDK interfaces in detail through the lifecycle of a query, from the user interface to application stores and back. The query will be referred to as `query`. -1. [Interfaces](#interfaces) -2. [CLIContext](#clicontext) -3. [Tendermint and ABCI](#tendermint-and-abci) -4. [Application Query Handling](#application-query-handling) -5. [Response](#response) +- [Interfaces](#interfaces) +- [CLIContext](#clicontext) +- [Tendermint and ABCI](#tendermint-and-abci) +- [Application Query Handling](#application-query-handling) +- [Response](#response) ## Interfaces diff --git a/docs/interfaces/rest.md b/docs/interfaces/rest.md index 9133e5ce9e2f..ba22e264ab2b 100644 --- a/docs/interfaces/rest.md +++ b/docs/interfaces/rest.md @@ -1 +1,30 @@ # REST Interface + +## Prerequisites + +* [Query Lifecycle](./query-lifecycle.md) + +## Synopsis + +This document describes how to create a REST interface for an SDK application. A separate document for creating module REST Routes can be found [here](#../module-interfaces.md#rest). + +- [Application REST Interface](#application-rest-interface) +- [REST Server](#rest-server) +- [Router](#router) +- [Registering Routes](#registering-routes) + +## Application REST Interface + +## REST Server + +The SDK REST Server has the following: + +* **Mux Router** +* **CLIContext** +* **Keybase** +* **Logger** +* **Listener** + +## Registering Routes + +For information about how to define REST Routes for modules, click [here](../building-modules.md#rest) From cf13f009a465860f459702cebb2cba1e174a849f Mon Sep 17 00:00:00 2001 From: Gloria Zhao Date: Fri, 26 Jul 2019 10:34:32 -0700 Subject: [PATCH 097/196] rest and intro done --- docs/interfaces/cli.md | 6 ++-- docs/interfaces/interfaces-intro.md | 44 ++++++++++++++++++++++++++++- docs/interfaces/query-lifecycle.md | 2 ++ docs/interfaces/rest.md | 41 +++++++++++++++++++++------ 4 files changed, 81 insertions(+), 12 deletions(-) diff --git a/docs/interfaces/cli.md b/docs/interfaces/cli.md index 94fca6537b06..75c36f6b3079 100644 --- a/docs/interfaces/cli.md +++ b/docs/interfaces/cli.md @@ -8,18 +8,18 @@ This document describes how to create a commmand-line interface for an SDK application. A separate document for creating a module CLI can be found [here](#../module-interfaces.md#cli). -- [Application CLI](#application-cli) +- [Application CLI Components](#application-cli-components) - [Commands](#commands) - [Flags](#flags) - [Initialization and Configurations](#initialization-and-configurations) -## Application CLI +## Application CLI Components One of the main entrypoints of an application is the command-line interface. This entrypoint is created as a `main.go` file which compiles to a binary, conventionally placed in the application's `app/cmd/cli` folder. The CLI for an application will typically be referred to as the name of the application suffixed with `-cli`, e.g. `appcli`. ### Cobra -There is no set way to create a CLI, but SDK modules all use the [Cobra Library](https://github.com/spf13/cobra) in order to implement the [`AppModuleBasic`]() interface. Building a CLI with Cobra entails defining commands, arguments, and flags. [**Commands**](#commands) represent the action users wish to take, such as `tx` for creating a transaction and `query` for querying the application. Each command can also have nested subcommands, necessary for naming the specific transaction type. Users also supply **Arguments**, such as account numbers to send coins to, and [**Flags**](#flags) to modify various aspects of the commands, such as gas prices or which node to broadcast to. +There is no set way to create a CLI, but SDK modules all use the [Cobra Library](https://github.com/spf13/cobra) in order to implement the [`AppModuleBasic`](../building-modules) interface. Building a CLI with Cobra entails defining commands, arguments, and flags. [**Commands**](#commands) represent the action users wish to take, such as `tx` for creating a transaction and `query` for querying the application. Each command can also have nested subcommands, necessary for naming the specific transaction type. Users also supply **Arguments**, such as account numbers to send coins to, and [**Flags**](#flags) to modify various aspects of the commands, such as gas prices or which node to broadcast to. ### Main Function diff --git a/docs/interfaces/interfaces-intro.md b/docs/interfaces/interfaces-intro.md index 09466179cc60..6e6d91d3f6ec 100644 --- a/docs/interfaces/interfaces-intro.md +++ b/docs/interfaces/interfaces-intro.md @@ -1,3 +1,45 @@ # Interfaces -This document introduces interfaces for SDK applications. The two main interfaces are the Command-Line Interface and REST Interface. +## Prerequisites + +* [Anatomy of an SDK Application](../basics/app-anatomy.md) +* [Lifecycle of a Transaction](../basics/tx-lifecycle.md) + + +## Synopsis + +Every application must include some interface users can use to interact with the defined functionalities. This document introduces user interfaces for SDK applications. + +- [Types of Application Interfaces](#types-of-application-interfaces) +- [Module vs Application Interfaces](#module-vs-application-interfaces) + + [Module Developer Responsibilities](#module-developer-responsibilities) + + [Application Developer Responsibilities](#application-developer-responsibilities) + + +## Types of Application Interfaces + +SDK applications should have a Command-Line Interface (CLI) and REST Interface to support HTTP requests. The SDK is opinionated about how to create these two interfaces; all modules specify [Cobra commands](https://github.com/spf13/cobra) and register routes using [Gorilla Mux routers](https://github.com/gorilla/mux). + + +## Module vs Application Interfaces + +The CLI and REST Interface are conventionally defined in the application `/cmd/cli` folder. The process of creating an application interface is vastly different from a module interface, though the components are closely intertwined. As expected, the module interface handles the bulk of the underlying logic, unpacking user requests into arguments and routes, and neatly marshaling everything into ABCI requests to be handled by Baseapp. On the other hand, the application interface handles the user configurations and customizations, instantiates the application-specific values and objects, and passes everything to module interface functions. + +### Module Developer Responsibilities + +In regards to interfaces, the module developers' responsibilities include: + +* **CLI commands:** Specifically, [Transaction commands](../building-modules/interfaces.md#transaction-commands) and [Query commands](../building-modules/interfaces.md#query-commands). These are commands that users will invoke when interacting with the application. For example, if an application enables sending coins through the [`auth`](https://github.com/cosmos/cosmos-sdk/tree/67f6b021180c7ef0bcf25b6597a629aca27766b8/docs/spec/auth) module, users will create `auth send` transactions. +* **Request Handlers:** Also categorized into Transaction and Query requests. Transactions will require HTTP [Request Types](../building-modules/interfaces.md#request-types) in addition to [Request Handlers](../building-modules/interfaces.md#request-handlers) in order to encapsulate all of the user's options (e.g. gas prices). +* **REST Routes:** Given a router, the module interface registers paths with the aforementioned [Request Handlers](../building-modules/interfaces.md#request-handlers) for each type of request. + +Module interfaces are designed to be generic. Both commands and request types will include required user input (through flags or request body) which will be different for each application. This section of documents will only detail application interfaces; to read about how to build module interfaces, click [here](../building-modules/interfaces.md). + +### Application Developer Responsibilities + +In regards to interfaces, the application developers' responsibilities include: + +* **CLI Root Command:** The root command adds subcommands to include all of the functionality for the application, mainly module transaction and query commands. +* **App Configurations:** All application-specific values are the responsibility of the application developer, including the `codec` used to marshal requests before relaying them to a node. +* **User Configurations:** Some values are specific to the user, such as the user's address and which node they are connected to. +* **RegisterRoutes Function:** To be passed to an instantiated REST Server so that it knows how to route requests for this particular application. diff --git a/docs/interfaces/query-lifecycle.md b/docs/interfaces/query-lifecycle.md index 83fe119d1b7b..78a7ca4e2035 100644 --- a/docs/interfaces/query-lifecycle.md +++ b/docs/interfaces/query-lifecycle.md @@ -2,6 +2,8 @@ ## Prerequisites +[Introduction to Interfaces](./interfaces-intro.md) + ## Synopsis This document describes SDK interfaces in detail through the lifecycle of a query, from the user interface to application stores and back. The query will be referred to as `query`. diff --git a/docs/interfaces/rest.md b/docs/interfaces/rest.md index ba22e264ab2b..9297de98d58b 100644 --- a/docs/interfaces/rest.md +++ b/docs/interfaces/rest.md @@ -3,6 +3,7 @@ ## Prerequisites * [Query Lifecycle](./query-lifecycle.md) +* [Application CLI](./cli.md) ## Synopsis @@ -10,21 +11,45 @@ This document describes how to create a REST interface for an SDK application. A - [Application REST Interface](#application-rest-interface) - [REST Server](#rest-server) -- [Router](#router) - [Registering Routes](#registering-routes) ## Application REST Interface +Building a REST Interface for an application involves creating a REST server to route requests and output responses. The SDK has its own REST Server type used for LCDs (light-client daemons). It has a `ServeCommand` that takes in an application's `codec` and `RegisterRoutes` function, starts up a new SDK REST Server, and registers routes using function provided from the application. To enable this command, it should be added as a subcommand of the root command `RootCmd` in the `main()` function of the CLI interface. + +Users can use the application CLI to start a new LCD, a local server through which they can securely interact with the application without downloading the entire state. The command entered by users would look something like this: + +```bash +appcli rest-server --chain-id --trust-node +``` + ## REST Server -The SDK REST Server has the following: +A REST Server is used to receive and route HTTP Requests, obtain the results from the application, and return the response to the user. The REST Server defined by the SDK LCD package contains the following: + +* **Router:** A router for HTTP requests. A new router can be instantiated for an application and used to match routes based on path, request method, headers, etc. The SDK uses the [Gorilla Mux Router](https://github.com/gorilla/mux). +* **CLIContext:** A [`CLIContext`](./query-lifecycle.md#clicontext) created for a user interaction. +* **Keybase:** A [Keybase](../core/keys-accounts.md) is a key manager. +* **Logger:** A logger from Tendermint `Log`, a log package structured around key-value pairs that allows logging level to be set differently for different keys. The logger takes `Debug()`, `Info()`, and `Error()`s. +* **Listener:** A [listener](https://golang.org/pkg/net/#Listener) from the net package. -* **Mux Router** -* **CLIContext** -* **Keybase** -* **Logger** -* **Listener** +Of the five, the only attribute that developers will need to configure is the router. ## Registering Routes -For information about how to define REST Routes for modules, click [here](../building-modules.md#rest) +To include routes for each module in an application, the CLI must have some kind of function to Register Routes in its REST Server. This `RegisterRoutes` function is utilized by the `ServeCommand` and must include routes for each of the application's modules. Since each module used by an SDK application implements a [`RegisterRESTRoutes`](../building-modules.md#rest) function, application developers simply use the Module Manager to call this function for each module. + +At the bare minimum, a `RegisterRoutes` function should use the SDK client package `RegisterRoutes` function to be able to route RPC calls, and instruct the application Module Manager to call `RegisterRESTRoutes` for all of its modules: + +```go +func registerRoutes(rs *lcd.RestServer) { + client.RegisterRoutes(rs.CliCtx, rs.Mux) + app.ModuleBasics.RegisterRESTRoutes(rs.CliCtx, rs.Mux) +} +``` + +This function is specific to the application and passed in to the `ServeCommand`, which should be added to the `rootCmd` as such: + +```go +rootCmd.AddCommand(lcd.ServeCommand(cdc, registerRoutes)) +``` From d64ce4ceacb498ec14e12a8d93525870177ae8e9 Mon Sep 17 00:00:00 2001 From: Gloria Zhao Date: Fri, 26 Jul 2019 15:38:50 -0700 Subject: [PATCH 098/196] small edits and links --- docs/interfaces/cli.md | 14 +++++----- docs/interfaces/interfaces-intro.md | 13 +++++++--- docs/interfaces/query-lifecycle.md | 40 ++++++++++++++--------------- docs/interfaces/rest.md | 24 ++++++++++++++++- 4 files changed, 57 insertions(+), 34 deletions(-) diff --git a/docs/interfaces/cli.md b/docs/interfaces/cli.md index 75c36f6b3079..5c8d9b9f4811 100644 --- a/docs/interfaces/cli.md +++ b/docs/interfaces/cli.md @@ -2,7 +2,7 @@ ## Prerequisites -* [Query Lifecycle](./query-lifecycle.md) +* [Lifecycle of a Query](./query-lifecycle.md) ## Synopsis @@ -19,7 +19,7 @@ One of the main entrypoints of an application is the command-line interface. Thi ### Cobra -There is no set way to create a CLI, but SDK modules all use the [Cobra Library](https://github.com/spf13/cobra) in order to implement the [`AppModuleBasic`](../building-modules) interface. Building a CLI with Cobra entails defining commands, arguments, and flags. [**Commands**](#commands) represent the action users wish to take, such as `tx` for creating a transaction and `query` for querying the application. Each command can also have nested subcommands, necessary for naming the specific transaction type. Users also supply **Arguments**, such as account numbers to send coins to, and [**Flags**](#flags) to modify various aspects of the commands, such as gas prices or which node to broadcast to. +There is no set way to create a CLI, but SDK modules all use the [Cobra Library](https://github.com/spf13/cobra) in order to implement the [`AppModuleBasic`](../building-modules/modules-manager.md) interface. Building a CLI with Cobra entails defining commands, arguments, and flags. [**Commands**](#commands) represent the action users wish to take, such as `tx` for creating a transaction and `query` for querying the application. Each command can also have nested subcommands, necessary for naming the specific transaction type. Users also supply **Arguments**, such as account numbers to send coins to, and [**Flags**](#flags) to modify various aspects of the commands, such as gas prices or which node to broadcast to. ### Main Function @@ -49,23 +49,21 @@ The root command (also called `rootCmd`) is what the user first types into the c ### Transaction Commands -Application [transactions](#./transactions.md) are objects that trigger state changes. To enable the creation of transactions using the CLI interface, `TxCmd` should add the following commands: +[Transactions](#./transactions.md) are objects wrapping messages that trigger state changes within modules. To enable the creation of transactions using the CLI interface, `TxCmd` should add the following commands: -* **Sign** command from the [`auth`](https://github.com/cosmos/cosmos-sdk/tree/67f6b021180c7ef0bcf25b6597a629aca27766b8/docs/spec/auth) module, which signs messages in a transaction. To enable multisig, it should also add the `auth` module MultiSign command. Since every transaction requires some sort of signature in order to be valid, this command is necessary for every application. +* **Sign** command from the [`auth`](https://github.com/cosmos/cosmos-sdk/blob/master/docs/spec/auth) module, which signs messages in a transaction. To enable multisig, it should also add the `auth` module MultiSign command. Since every transaction requires some sort of signature in order to be valid, this command is necessary for every application. * **Broadcast** command from the SDK client tools, which broadcasts transactions. -* **Send** command from the [`bank`](https://github.com/cosmos/cosmos-sdk/tree/67f6b021180c7ef0bcf25b6597a629aca27766b8/docs/spec/bank) module, which is a transaction that allows accounts to send coins to one another, including gas and fees for transactions. -* Any application-specific transaction commands defined by the application developer. +* **Send** command from the [`bank`](https://github.com/cosmos/cosmos-sdk/blob/master/docs/spec/bank) module, which is a transaction that allows accounts to send coins to one another, including gas and fees for transactions. * All commands in each module the application is dependent on, retrieved by calling `GetTxCmd()` on all the modules or using the Module Manager's `AddTxCommands()` function. ### Query Commands -Application queries are objects that allow users to retrieve information about the application's state. To enable basic queries, `QueryCmd` should add the following commands: +[**Queries**](../building-modules/messages-and-queries.md#queries) are objects that allow users to retrieve information about the application's state. To enable basic queries, `QueryCmd` should add the following commands: * **QueryTx** and/or other transaction query commands from the `auth` module which allow the user to search for a transaction by inputting its hash, a list of tags, or a block height. These various queries allow users to see if transactions have been included in a block. * **Account** command from the `auth` module, which displays the state (e.g. account balance) of an account given an address. * **Validator** command from the SDK rpc client tools, which displays the validator set of a given height. * **Block** command from the SDK rpc client tools, which displays the block data for a given height. -* Any application-specific query commands defined by the application developer. * All commands in each module the application is dependent on, retrieved by calling `GetQueryCmd()` on all the modules or using the Module Manager's `AddQueryCommands()` function. ## Flags diff --git a/docs/interfaces/interfaces-intro.md b/docs/interfaces/interfaces-intro.md index 6e6d91d3f6ec..9e68ee971027 100644 --- a/docs/interfaces/interfaces-intro.md +++ b/docs/interfaces/interfaces-intro.md @@ -18,18 +18,18 @@ Every application must include some interface users can use to interact with the ## Types of Application Interfaces -SDK applications should have a Command-Line Interface (CLI) and REST Interface to support HTTP requests. The SDK is opinionated about how to create these two interfaces; all modules specify [Cobra commands](https://github.com/spf13/cobra) and register routes using [Gorilla Mux routers](https://github.com/gorilla/mux). +SDK applications should have a Command-Line Interface (CLI) and REST Interface to support HTTP requests. The SDK is opinionated about how to create these two interfaces; all modules specify [Cobra commands](https://github.com/spf13/cobra) and register routes using [Gorilla Mux routers](https://github.com/gorilla/mux). The CLI and REST Interface are conventionally defined in the application `/cmd/cli` folder. ## Module vs Application Interfaces -The CLI and REST Interface are conventionally defined in the application `/cmd/cli` folder. The process of creating an application interface is vastly different from a module interface, though the components are closely intertwined. As expected, the module interface handles the bulk of the underlying logic, unpacking user requests into arguments and routes, and neatly marshaling everything into ABCI requests to be handled by Baseapp. On the other hand, the application interface handles the user configurations and customizations, instantiates the application-specific values and objects, and passes everything to module interface functions. +The process of creating an application interface is very different from creating a module interface, though the components are closely intertwined. As expected, the module interface handles the bulk of the underlying logic, unpacking user requests into arguments and routes, and neatly marshaling everything into ABCI requests to be handled by Baseapp. On the other hand, the application interface handles the user configurations and customizations, instantiates the application-specific values and objects, and passes everything to module interface functions. ### Module Developer Responsibilities In regards to interfaces, the module developers' responsibilities include: -* **CLI commands:** Specifically, [Transaction commands](../building-modules/interfaces.md#transaction-commands) and [Query commands](../building-modules/interfaces.md#query-commands). These are commands that users will invoke when interacting with the application. For example, if an application enables sending coins through the [`auth`](https://github.com/cosmos/cosmos-sdk/tree/67f6b021180c7ef0bcf25b6597a629aca27766b8/docs/spec/auth) module, users will create `auth send` transactions. +* **CLI commands:** Specifically, [Transaction commands](../building-modules/interfaces.md#transaction-commands) and [Query commands](../building-modules/interfaces.md#query-commands). These are commands that users will invoke when interacting with the application to create transactions and queries. For example, if an application enables sending coins through the [`auth`](https://github.com/cosmos/cosmos-sdk/tree/67f6b021180c7ef0bcf25b6597a629aca27766b8/docs/spec/auth) module, users will create `tx auth send` transactions. * **Request Handlers:** Also categorized into Transaction and Query requests. Transactions will require HTTP [Request Types](../building-modules/interfaces.md#request-types) in addition to [Request Handlers](../building-modules/interfaces.md#request-handlers) in order to encapsulate all of the user's options (e.g. gas prices). * **REST Routes:** Given a router, the module interface registers paths with the aforementioned [Request Handlers](../building-modules/interfaces.md#request-handlers) for each type of request. @@ -41,5 +41,10 @@ In regards to interfaces, the application developers' responsibilities include: * **CLI Root Command:** The root command adds subcommands to include all of the functionality for the application, mainly module transaction and query commands. * **App Configurations:** All application-specific values are the responsibility of the application developer, including the `codec` used to marshal requests before relaying them to a node. -* **User Configurations:** Some values are specific to the user, such as the user's address and which node they are connected to. +* **User Configurations:** Some values are specific to the user, such as the user's address and which node they are connected to. * **RegisterRoutes Function:** To be passed to an instantiated REST Server so that it knows how to route requests for this particular application. + + +## Next + +Read about the [Lifecycle of a Query](./query-lifecycle.md). diff --git a/docs/interfaces/query-lifecycle.md b/docs/interfaces/query-lifecycle.md index 78a7ca4e2035..b95d6980fae0 100644 --- a/docs/interfaces/query-lifecycle.md +++ b/docs/interfaces/query-lifecycle.md @@ -2,11 +2,11 @@ ## Prerequisites -[Introduction to Interfaces](./interfaces-intro.md) +* [Introduction to Interfaces](./interfaces-intro.md) ## Synopsis -This document describes SDK interfaces in detail through the lifecycle of a query, from the user interface to application stores and back. The query will be referred to as `query`. +This document describes SDK interfaces in detail through the lifecycle of a query, from the user interface to application stores and back. The query will be referred to as `Query`. - [Interfaces](#interfaces) - [CLIContext](#clicontext) @@ -16,35 +16,33 @@ This document describes SDK interfaces in detail through the lifecycle of a quer ## Interfaces -A **query** is a request for information made by users of applications. They can query information about the network, the application itself, and application state directly from the application's stores or modules. +A [**query**](../building-modules/messages-and-queries.md#queries) is a request for information made by users of applications. Users can query information about the network, the application itself, and application state directly from the application's stores or modules. -For the purpose of explaining a query lifecycle, let's say `query` is requesting a list of delegations made by a certain delegator address in the application called `app`. There are a few ways `query` can be made on the user side. +For the purpose of explaining a query lifecycle, let's say `Query` is requesting a list of delegations made by a certain delegator address in the application called `app`. There are a few ways `Query` can be made on the user side. ### CLI -The main interface for an application is the command-line interface. Users run the CLI directly from their machines and type commands to create queries. To create this query from the command-line, users would type the following command: +The main interface for an application is the command-line interface. Users run the CLI directly from their machines and type commands to create queries. To create this query from their terminal, users would type the following command: ``` appcli query staking delegations ``` -To provide values such as `--chain-id`, the ID of the blockchain to make the query to, the user must use the `config` command to set them or provide them as flags. +To provide values such as `--chain-id` (the ID of the blockchain to make the query to), the user must use the `config` command to set them or provide them as flags. -This query command is defined by the module developer and added to the list of subcommands by the application developer when creating the CLI. To see the command itself, click [here](). +This query command is defined by the module developer and added to the list of subcommands by the application developer when creating the CLI. ### REST Another interface through which users can make queries is through HTTP Requests to a REST server. The REST server contains, among other things, a [`CLIContext`](#clicontext) and [mux](./rest.md#gorilla-mux) router. The request looks like this: ```bash -http://localhost:{PORT}/staking/delegators/{delegatorAddr}/delegations +GET http://localhost:{PORT}/staking/delegators/{delegatorAddr}/delegations ``` -To provide values such as `--chain-id`, the ID of the blockchain to make the query to, the user must configure their REST server with the values or provide them in the request body. +To provide values such as `--chain-id` (the ID of the blockchain to make the query to), the user must configure their local REST server with the values or provide them in the request body. -The router automatically routes the `query` HTTP request to the staking module `delegatorDelegationsHandlerFn()` function (to see the handler itself, click [here]()). Since this function is defined within the module and thus has no inherent knowledge of the application `query` belongs to, it takes in the application `codec` and `CLIContext` as parameters. - -To read about how the router is used, click [here](./rest.md). +The router automatically routes the `Query` HTTP request to the staking module `delegatorDelegationsHandlerFn()` function (to see the handler itself, click [here]()). Since this function is defined within the module and thus has no inherent knowledge of the application `Query` belongs to, it takes in the application `codec` and `CLIContext` as parameters. ## Request and Command Handling @@ -55,29 +53,29 @@ The interactions from the users' perspective are a bit different, but the underl The first thing that is created in the execution of a CLI command is a `CLIContext`, while the REST Server directly provides a `CLIContext` for the REST Request handler. A [Context](../core/context.md) is an immutable object that stores all the data needed to process a request. In particular, a `CLIContext` stores the following: * **Codec**: The encoder/decoder used by the application, used to marshal the parameters and query before making the Tendermint RPC request and unmarshal the returned response into a JSON object. -* **Account Decoder**: The account decoder from the [`auth`](https://github.com/cosmos/cosmos-sdk/tree/67f6b021180c7ef0bcf25b6597a629aca27766b8/docs/spec/auth) module, which translates `[]byte`s into accounts. -* **RPC Client**: The [Tendermint RPC Client](https://github.com/tendermint/tendermint/blob/master/rpc/client/interface.go). +* **Account Decoder**: The account decoder from the [`auth`](.../spec/auth) module, which translates `[]byte`s into accounts. +* **RPC Client**: The [Tendermint RPC Client](https://github.com/tendermint/tendermint/blob/master/rpc/client/interface.go), or node, to which the request will be relayed to. * **Keybase**: A [Key Manager](.//core/accounts-keys.md) used to sign transactions and handle other operations with keys. * **Output Writer**: A [Writer](https://golang.org/pkg/io/#Writer) used to output the response. * **Configurations**: The flags configured by the user for this command, including `--height`, specifying the height of the blockchain to query and `--indent`, which indicates to add an indent to the JSON response. -For full specification of the `CLIContext` type, click [here](https://github.com/cosmos/cosmos-sdk/blob/73e5ef7c13c420f9ee879fdf1b60cf0bdc8f325e/client/context/context.go#L36-L59). +For full specification of the `CLIContext` type, click [here](https://github.com/cosmos/cosmos-sdk/blob/master/client/context/context.go#L36-L59). ### Parameters and Route Creation The next step is to parse the command or request, extract the arguments, create a `queryRoute`, and encode everything. -In this case, `query` contains a `delegatorAddress` as its only argument. However, the request can only contain `[]byte`s, as it will be relayed to a consensus engine node that has no inherent knowledge of the application types. Thus, the `CLIContext` `codec` is used to marshal the address as the type `QueryDelegatorParams`. All query arguments (e.g. the `staking` module also has `QueryValidatorParams` and `QueryBondsParams`) have their own types that the application `codec` understands how to encode and decode. The module [`querier`](.//building-modules/querier.md) declares these types and the application registers the `codec`s. +In this case, `Query` contains a `delegatorAddress` as its only argument. However, the request can only contain `[]byte`s, as it will be relayed to a consensus engine node that has no inherent knowledge of the application types. Thus, the `CLIContext` `codec` is used to marshal the address as the type `QueryDelegatorParams`. All query arguments (e.g. the `staking` module also has `QueryValidatorParams` and `QueryBondsParams`) have their own types that the application `codec` understands how to encode and decode. The module [`querier`](.//building-modules/querier.md) declares these types and the application registers the `codec`s. -A `route` is also created for `query` so that the application will understand which module to route the query to. Baseapp will understand this query to be a `custom` query in the module `staking` with the type `QueryDelegatorDelegations`. Thus, the route will be `"custom/staking/delegatorDelegations"`. +A `route` is also created for `Query` so that the application will understand which module to route the query to. Baseapp will understand this query to be a `custom` query in the module `staking` with the type `QueryDelegatorDelegations`. Thus, the route will be `"custom/staking/delegatorDelegations"`. ### ABCI Query -The `CLIContext`'s main `query` function takes the `route`, which is now called `path`, and arguments, now called `key`. It first retrieves the RPC Client (called the **node**) configured by the user to relay this query to, and creates the `ABCIQueryOptions` (parameters formatted for the ABCI call). The node is then used to make the ABCI call, `ABCIQueryWithOptions`. +The `CLIContext`'s main `Query` function takes the `route`, which is now called `path`, and arguments, now called `key`. It first retrieves the RPC Client (called the **node**) configured by the user to relay this query to, and creates the `ABCIQueryOptions` (parameters formatted for the ABCI call). The node is then used to make the ABCI call, `ABCIQueryWithOptions`. ## Tendermint and ABCI -With a call to `ABCIQueryWithOptions()`, `query` arrives at the consensus engine portion of its lifecycle. Nodes running the consensus engine (e.g. Tendermint Core) make ABCI calls to interact with the application. At this point, `query` exists as an ABCI `RequestQuery` and the [ABCI Client](https://github.com/tendermint/tendermint/blob/51b3428f5c0f4fdd2e469147cd90353faa4bd704/abci/client/client.go#L16-L50) calls the ABCI method [`Query()`](https://tendermint.com/docs/spec/abci/abci.html#query) on the application. +With a call to `ABCIQueryWithOptions()`, `Query` arrives at the consensus engine portion of its lifecycle. Nodes running the consensus engine (e.g. Tendermint Core) make ABCI calls to interact with the application. At this point, `Query` exists as an ABCI `RequestQuery` and the [ABCI Client](https://github.com/tendermint/tendermint/blob/51b3428f5c0f4fdd2e469147cd90353faa4bd704/abci/client/client.go#L16-L50) calls the ABCI method [`Query()`](https://tendermint.com/docs/spec/abci/abci.html#query) on the application. Read more about ABCI Clients and Tendermint RPC in the Tendermint documentation [here](https://tendermint.com/rpc). @@ -85,11 +83,11 @@ Read more about ABCI Clients and Tendermint RPC in the Tendermint documentation [Baseapp](../core/baseapp.md) implements the ABCI [`Query()`](../core/baseapp.md#query) function and handles four different types of queries: `app`, `store`, `p2p`, and `custom`. The `queryRoute` is parsed such that the first string must be one of the four options, then the rest of the path is parsed within the subroutines handling each type of query. The first three types are application-level and thus directly handled by Baseapp or the stores, but the `custom` query type requires Baseapp to route the query to a module's [querier](../building-modules/querier.md). -Since `query` is a custom query type, Baseapp first parses the path, then uses the `QueryRouter` to retrieve the corresponding querier. +Since `Query` is a custom query type, Baseapp first parses the path, then uses the `QueryRouter` to retrieve the corresponding querier. The querier is responsible for recognizing this query, retrieving the appropriate values from the application's stores, and returning a response. ## Response -Since `Query()` is an ABCI function, Baseapp returns the `query` response as an `abci.ResponseQuery`. The `CLIContext` `query` routine receives the response and, if `--trust-node` is toggled to `false` and a proof needs to be verified, the response is verified with the `CLIContext` `verifyProof` function before the response is returned. +Since `Query()` is an ABCI function, Baseapp returns the `Query` response as an `abci.ResponseQuery`. The `CLIContext` `Query` routine receives the response and, if `--trust-node` is toggled to `false` and a proof needs to be verified, the response is verified with the `CLIContext` `verifyProof` function before the response is returned. ### CLI Response diff --git a/docs/interfaces/rest.md b/docs/interfaces/rest.md index 9297de98d58b..ce3b8db10b42 100644 --- a/docs/interfaces/rest.md +++ b/docs/interfaces/rest.md @@ -10,12 +10,13 @@ This document describes how to create a REST interface for an SDK application. A separate document for creating module REST Routes can be found [here](#../module-interfaces.md#rest). - [Application REST Interface](#application-rest-interface) +- [Request Types](#request-types) - [REST Server](#rest-server) - [Registering Routes](#registering-routes) ## Application REST Interface -Building a REST Interface for an application involves creating a REST server to route requests and output responses. The SDK has its own REST Server type used for LCDs (light-client daemons). It has a `ServeCommand` that takes in an application's `codec` and `RegisterRoutes` function, starts up a new SDK REST Server, and registers routes using function provided from the application. To enable this command, it should be added as a subcommand of the root command `RootCmd` in the `main()` function of the CLI interface. +Building the REST Interface for an application involves creating a REST server to route requests and output responses. The SDK has its own REST Server type used for LCDs (light-client daemons). It has a `ServeCommand` that takes in an application's `codec` and `RegisterRoutes` function, starts up a new SDK REST Server, and registers routes using function provided from the application. To enable this command, it should be added as a subcommand of the root command `RootCmd` in the `main()` function of the CLI interface. Users can use the application CLI to start a new LCD, a local server through which they can securely interact with the application without downloading the entire state. The command entered by users would look something like this: @@ -23,6 +24,27 @@ Users can use the application CLI to start a new LCD, a local server through whi appcli rest-server --chain-id --trust-node ``` +## Request Types + +HTTP Request types are defined by the module interfaces for every type of transaction. The structs all include a base request `baseReq`, the name of the request, and any arguments for the transaction. + +### BaseReq + +`BaseReq` is a type defined in the SDK that encapsulates much of the transaction configurations similar to CLI command flags. Users must provide the information in the body of their requests. + +* `From` indicates which account the transaction originates from. This account is used to sign the transaction. +* `Memo` sends a memo along with the transaction. +* `ChainID` specifies the unique identifier of the blockchain the transaction pertains to. +* `AccountNumber` is an identifier for the account. +* `Sequence`is the value of a counter measuring how many transactions have been sent from the account. It is used to prevent replay attacks. +* `Gas` refers to how much gas, which represents computational resources, Tx consumes. Gas is dependent on the transaction and is not precisely calculated until execution, but can be estimated by providing auto as the value for `Gas`. +* `GasAdjustment` can be used to scale gas up in order to avoid underestimating. For example, users can specify their gas adjustment as 1.5 to use 1.5 times the estimated gas. +* `GasPrices` specifies how much the user is willing pay per unit of gas, which can be one or multiple denominations of tokens. For example, --gas-prices=0.025uatom, 0.025upho means the user is willing to pay 0.025uatom AND 0.025upho per unit of gas. +* `Fees` specifies how much in fees the user is willing to pay in total. Note that the user only needs to provide either `gas-prices` or `fees`, but not both, because they can be derived from each other. +* `Simulate` instructs the application to ignore gas and simulate the transaction running without broadcasting. + +Additionally, each request may contain arguments such as a specific address pertaining to the request. + ## REST Server A REST Server is used to receive and route HTTP Requests, obtain the results from the application, and return the response to the user. The REST Server defined by the SDK LCD package contains the following: From cab3c2e7baa6dce30c31b82779e0112f825af3ac Mon Sep 17 00:00:00 2001 From: Gloria Zhao Date: Tue, 30 Jul 2019 20:35:21 -0700 Subject: [PATCH 099/196] comments --- docs/building-modules/module-interfaces.md | 34 +++++++++------------- docs/interfaces/cli.md | 4 +-- 2 files changed, 16 insertions(+), 22 deletions(-) diff --git a/docs/building-modules/module-interfaces.md b/docs/building-modules/module-interfaces.md index c3ddea3298aa..a75b5b0d169a 100644 --- a/docs/building-modules/module-interfaces.md +++ b/docs/building-modules/module-interfaces.md @@ -145,11 +145,11 @@ Finally, the module also needs a `GetQueryCmd`, which aggregates all of the quer [Flags](../interfaces/cli.md#flags) are entered by the user and allow for command customizations. Examples include the [fees](../core/accounts-fees.md) or gas prices users are willing to pay for their transactions. -The flags for a module are typically found in a `flags.go` file in the `./x/moduleName/client/cli` folder. Module developers can create a list of possible flags including the value type, default value, and a description displayed if the user uses a `help` command. In each transaction getter function, they can add flags to the commands and, optionally, mark flags as *required* so that an error is thrown if the user does not provide values for them. +The flags for a module are typically found in the `flags.go` file in the `./x/moduleName/client/cli` folder. Module developers can create a list of possible flags including the value type, default value, and a description displayed if the user uses a `help` command. In each transaction getter function, they can add flags to the commands and, optionally, mark flags as *required* so that an error is thrown if the user does not provide values for them. For full details on flags, visit the [Cobra Documentation](https://github.com/spf13/cobra). -For example, the SDK `./client/flags` package includes a [`PostCommands()`](https://github.com/cosmos/cosmos-sdk/blob/master/client/flags/flags.go#L85-L116) function that adds necessary flags to transaction commands, such as the `from` flag to indicate which address the transaction originates from. Here is an example of how to add a flag using the `from` flag from this function. +For example, the SDK `./client/flags` package includes a [`PostCommands`](https://github.com/cosmos/cosmos-sdk/blob/master/client/flags/flags.go#L85-L116) function that adds necessary flags to transaction commands, such as the `from` flag to indicate which address the transaction originates from. Here is an example of how to add a flag using the `from` flag from this function. ```go cmd.Flags().String(FlagFrom, "", "Name or address of private key with which to sign") @@ -163,11 +163,11 @@ A flag can be marked as *required* so that an error is automatically thrown if t cmd.MarkFlagRequired(FlagFrom) ``` -Since `PostCommands()` includes all of the basic flags required for a transaction command, module developers may choose not to add any of their own (specifying arguments instead may often be more appropriate). For a full list of what flags are included in the `PostCommands()` function, including which are required inputs from users, see the CLI documentation [here](../interfaces/cli.md#transaction-flags). +For a full list of what flags are in `PostCommands`, including which are required inputs from users, see the CLI documentation [here](../interfaces/cli.md#transaction-flags). ## REST -Applications are typically required to support web services that use HTTP requests (e.g. a web wallet like [Lunie.io](lunie.io)). Thus, application developers will also use REST Routes to route HTTP requests to the application's modules; these routes will be used by service providers. The module developer's responsibility is to define the REST client by defining [routes](#register-routes) for all possible [requests](#request-types) and [handlers](#request-handlers) for each of them. It's up to the module developer how to organize the REST interface files; there is typically a `rest.go` file found in the module's `./x/moduleName/client/rest` folder. +Applications are typically required to support web services that use HTTP requests (e.g. a web wallet like [Lunie.io](lunie.io)). Thus, application developers will also use REST Routes to route HTTP requests to the application's modules; these routes will be used by service providers. The module developer's responsibility is to define the REST client by defining routes for all possible requests and handlers for each of them. The REST interface file `rest.go` is typically found in the module's `./x/moduleName/client/rest` folder. ### Request Types @@ -183,24 +183,8 @@ type buyNameReq struct { Buyer string `json:"buyer"` } ``` - The `BaseReq` includes basic information that every request needs to have, similar to required flags in a CLI. All of these values, including `GasPrices` and `AccountNumber`, will be provided in the request body. The user will also need to specify the arguments `Name` and `Amount` fields in the body and `Buyer` will be provided by the user's address. -#### BaseReq - -`BaseReq` is a type defined in the SDK that encapsulates much of the transaction configurations similar to CLI command flags. Users must provide the information in the body of their requests. - -* `From` indicates which [account](../core/accounts-fees.md) the transaction originates from. This account is used to sign the transaction. -* `Memo` sends a memo along with the transaction. -* `ChainID` specifies the unique identifier of the blockchain the transaction pertains to. -* `AccountNumber` is an identifier for the account. -* `Sequence`is the value of a counter measuring how many transactions have been sent from the account. It is used to prevent replay attacks. -* `Gas` refers to how much [gas](../core/gas.md), which represents computational resources, Tx consumes. Gas is dependent on the transaction and is not precisely calculated until execution, but can be estimated by providing auto as the value for `Gas`. -* `GasAdjustment` can be used to scale gas up in order to avoid underestimating. For example, users can specify their gas adjustment as 1.5 to use 1.5 times the estimated gas. -* `GasPrices` specifies how much the user is willing pay per unit of gas, which can be one or multiple denominations of tokens. For example, --gas-prices=0.025uatom, 0.025upho means the user is willing to pay 0.025uatom AND 0.025upho per unit of gas. -* `Fees` specifies how much in [fees](../core/accounts-fees.md) the user is willing to pay in total. Note that the user only needs to provide either `gas-prices` or `fees`, but not both, because they can be derived from each other. -* `Simulate` instructs the application to ignore gas and simulate the transaction running without broadcasting. - ### Request Handlers Request handlers must be defined for both transaction and query requests. Handlers' arguments include a reference to the application's `codec` and the [`CLIContext`](../interfaces/query-lifecycle.md#clicontext) created in the user interaction. @@ -257,6 +241,16 @@ To read more about how a transaction is generated, visit the transactions docume ### Register Routes +The request handler can be broken down as follows: + +* **Parse Request:** The request handler first attempts to parse the request, and then run `Sanitize` and `ValidateBasic` on the underlying `BaseReq` to check the validity of the request. Next, it attempts to parse the arguments `Buyer` and `Amount` to the types `AccountAddress` and `Coins` respectively. +* **Message:** Then, a [message](./messages-and-queries.md) of the type `MsgBuyName` (defined by the module developer to trigger the state changes for this transaction) is created from the values and another sanity check, `ValidateBasic` is run on it. +* **Generate Transaction:** Finally, the HTTP `ResponseWriter`, application [`codec`](../core/encoding.md), [`CLIContext`](../interfaces/query-lifecycle.md#clicontext), request [`BaseReq`](../interfaces/rest.md#basereq), and message is passed to `WriteGenerateStdTxResponse` to further process the request. + +To read more about how a transaction is generated, visit the transactions documentation [here](../core/transactions.md#transaction-generation). + +### Register Routes + The application CLI entrypoint will have a `RegisterRoutes` function in its `main.go` file, which calls the `registerRoutes` functions of each module utilized by the application. Module developers need to implement `registerRoutes` for their modules so that applications are able to route messages and queries to their corresponding handlers and queriers. The router used by the SDK is [Gorilla Mux](https://github.com/gorilla/mux). The router is initialized with the Gorilla Mux `NewRouter()` function. Then, the router's `HandleFunc` function can then be used to route urls with the defined request handlers and the HTTP method (e.g. "POST", "GET") as a route matcher. It is recommended to prefix every route with the name of the module to avoid collisions with other modules that have the same query or transaction names. diff --git a/docs/interfaces/cli.md b/docs/interfaces/cli.md index 5c8d9b9f4811..974ca5384e33 100644 --- a/docs/interfaces/cli.md +++ b/docs/interfaces/cli.md @@ -78,7 +78,7 @@ It is common to add a _persistent_ flag for `--chain-id`, the unique identifier ### Transaction Flags -To **create** a transaction, the user enters a `tx` command and provides several flags. +To **create** a transaction, the user enters a `tx` command and provides several flags. These are the basic flags added to every command using the SDK `./client/flags` package [`PostCommands`](https://github.com/cosmos/cosmos-sdk/blob/master/client/flags/flags.go#L85-L116) function: * `--from` indicates which account the transaction originates from. This account is used to sign the transaction. * `--gas` refers to how much gas, which represents computational resources, Tx consumes. Gas is dependent on the transaction and is not precisely calculated until execution, but can be estimated by providing auto as the value for --gas. @@ -124,7 +124,7 @@ appcli tx broadcast mySignedTx.json --node ``` ### Query Flags -Queries also have flags. +Queries also have flags. These are the basic flags added to every command using the SDK `./client/flags` package [`GetCommand`](https://github.com/cosmos/cosmos-sdk/blob/master/client/flags/flags.go#L67-L82) function: * `--node` indicates which full-node to connect to. * `--trust-node` (optional) represents whether or not the connected node is trusted. If the node is not trusted, all proofs in the responses are verified. From 2ec8d9458e5bb0d7f193ddd23181e1684c13c077 Mon Sep 17 00:00:00 2001 From: Gloria Zhao Date: Fri, 2 Aug 2019 15:31:21 -0700 Subject: [PATCH 100/196] revisions --- docs/building-modules/module-interfaces.md | 17 +-- docs/interfaces/cli.md | 149 +++++++++++++++++++-- docs/interfaces/interfaces-intro.md | 20 +-- docs/interfaces/query-lifecycle.md | 34 ++--- docs/interfaces/rest.md | 12 +- 5 files changed, 173 insertions(+), 59 deletions(-) diff --git a/docs/building-modules/module-interfaces.md b/docs/building-modules/module-interfaces.md index a75b5b0d169a..e4a1ff940713 100644 --- a/docs/building-modules/module-interfaces.md +++ b/docs/building-modules/module-interfaces.md @@ -145,11 +145,11 @@ Finally, the module also needs a `GetQueryCmd`, which aggregates all of the quer [Flags](../interfaces/cli.md#flags) are entered by the user and allow for command customizations. Examples include the [fees](../core/accounts-fees.md) or gas prices users are willing to pay for their transactions. -The flags for a module are typically found in the `flags.go` file in the `./x/moduleName/client/cli` folder. Module developers can create a list of possible flags including the value type, default value, and a description displayed if the user uses a `help` command. In each transaction getter function, they can add flags to the commands and, optionally, mark flags as *required* so that an error is thrown if the user does not provide values for them. +The flags for a module are typically found in a `flags.go` file in the `./x/moduleName/client/cli` folder. Module developers can create a list of possible flags including the value type, default value, and a description displayed if the user uses a `help` command. In each transaction getter function, they can add flags to the commands and, optionally, mark flags as *required* so that an error is thrown if the user does not provide values for them. For full details on flags, visit the [Cobra Documentation](https://github.com/spf13/cobra). -For example, the SDK `./client/flags` package includes a [`PostCommands`](https://github.com/cosmos/cosmos-sdk/blob/master/client/flags/flags.go#L85-L116) function that adds necessary flags to transaction commands, such as the `from` flag to indicate which address the transaction originates from. Here is an example of how to add a flag using the `from` flag from this function. +For example, the SDK `./client/flags` package includes a [`PostCommands()`](https://github.com/cosmos/cosmos-sdk/blob/master/client/flags/flags.go#L85-L116) function that adds necessary flags to transaction commands, such as the `from` flag to indicate which address the transaction originates from. Here is an example of how to add a flag using the `from` flag from this function. ```go cmd.Flags().String(FlagFrom, "", "Name or address of private key with which to sign") @@ -163,11 +163,11 @@ A flag can be marked as *required* so that an error is automatically thrown if t cmd.MarkFlagRequired(FlagFrom) ``` -For a full list of what flags are in `PostCommands`, including which are required inputs from users, see the CLI documentation [here](../interfaces/cli.md#transaction-flags). +Since `PostCommands()` includes all of the basic flags required for a transaction command, module developers may choose not to add any of their own (specifying arguments instead may often be more appropriate). For a full list of what flags are included in the `PostCommands()` function, including which are required inputs from users, see the CLI documentation [here](../interfaces/cli.md#transaction-flags). ## REST -Applications are typically required to support web services that use HTTP requests (e.g. a web wallet like [Lunie.io](lunie.io)). Thus, application developers will also use REST Routes to route HTTP requests to the application's modules; these routes will be used by service providers. The module developer's responsibility is to define the REST client by defining routes for all possible requests and handlers for each of them. The REST interface file `rest.go` is typically found in the module's `./x/moduleName/client/rest` folder. +Applications are typically required to support web services that use HTTP requests (e.g. a web wallet like [Lunie.io](lunie.io)). Thus, application developers will also use REST Routes to route HTTP requests to the application's modules; these routes will be used by service providers. The module developer's responsibility is to define the REST client by defining [routes](#register-routes) for all possible [requests](#request-types) and [handlers](#request-handlers) for each of them. It's up to the module developer how to organize the REST interface files; there is typically a `rest.go` file found in the module's `./x/moduleName/client/rest` folder. ### Request Types @@ -239,15 +239,6 @@ The request handler can be broken down as follows: To read more about how a transaction is generated, visit the transactions documentation [here](../core/transactions.md#transaction-generation). -### Register Routes - -The request handler can be broken down as follows: - -* **Parse Request:** The request handler first attempts to parse the request, and then run `Sanitize` and `ValidateBasic` on the underlying `BaseReq` to check the validity of the request. Next, it attempts to parse the arguments `Buyer` and `Amount` to the types `AccountAddress` and `Coins` respectively. -* **Message:** Then, a [message](./messages-and-queries.md) of the type `MsgBuyName` (defined by the module developer to trigger the state changes for this transaction) is created from the values and another sanity check, `ValidateBasic` is run on it. -* **Generate Transaction:** Finally, the HTTP `ResponseWriter`, application [`codec`](../core/encoding.md), [`CLIContext`](../interfaces/query-lifecycle.md#clicontext), request [`BaseReq`](../interfaces/rest.md#basereq), and message is passed to `WriteGenerateStdTxResponse` to further process the request. - -To read more about how a transaction is generated, visit the transactions documentation [here](../core/transactions.md#transaction-generation). ### Register Routes diff --git a/docs/interfaces/cli.md b/docs/interfaces/cli.md index 974ca5384e33..6287c0d24026 100644 --- a/docs/interfaces/cli.md +++ b/docs/interfaces/cli.md @@ -11,7 +11,7 @@ This document describes how to create a commmand-line interface for an SDK appli - [Application CLI Components](#application-cli-components) - [Commands](#commands) - [Flags](#flags) -- [Initialization and Configurations](#initialization-and-configurations) +- [Configurations](#configurations) ## Application CLI Components @@ -19,19 +19,19 @@ One of the main entrypoints of an application is the command-line interface. Thi ### Cobra -There is no set way to create a CLI, but SDK modules all use the [Cobra Library](https://github.com/spf13/cobra) in order to implement the [`AppModuleBasic`](../building-modules/modules-manager.md) interface. Building a CLI with Cobra entails defining commands, arguments, and flags. [**Commands**](#commands) represent the action users wish to take, such as `tx` for creating a transaction and `query` for querying the application. Each command can also have nested subcommands, necessary for naming the specific transaction type. Users also supply **Arguments**, such as account numbers to send coins to, and [**Flags**](#flags) to modify various aspects of the commands, such as gas prices or which node to broadcast to. +There is no set way to create a CLI, but SDK modules all use the [Cobra Library](https://github.com/spf13/cobra) in order to implement the [`AppModuleBasic`](../building-modules/modules-manager.md) interface. Building a CLI with Cobra entails defining commands, arguments, and flags. [**Commands**](#commands) understand the actions users wish to take, such as `tx` for creating a transaction and `query` for querying the application. Each command can also have nested subcommands, necessary for naming the specific transaction type. Users also supply **Arguments**, such as account numbers to send coins to, and [**Flags**](#flags) to modify various aspects of the commands, such as gas prices or which node to broadcast to. ### Main Function The `main.go` file needs to have a `main()` function that does the following to run the command-line interface: -* **Instantiate the `codec`** by calling the application's `MakeCodec()` function. The `codec` is used to code and encode data structures for the application - stores can only persist `[]byte`s so the developer must define a serialization format for their data structures or use the default, [Amino](./amino.md). +* **Instantiate the `codec`** by calling the application's `MakeCodec()` function. The [`codec`](../core/encoding.md) is used to code and encode data structures for the application - stores can only persist `[]byte`s so the developer must define a serialization format for their data structures or use the default, [Amino](../core/amino.md). * **Configurations** are set by reading in configuration files (e.g. the sdk config file). * **Create the root command** to which all the application commands will be added as subcommands and add any required flags to it, such as `--chain-id`. * **Add subcommands** for all the possible user interactions, including [transaction commands](#transaction-commands) and [query commands](#query-commands). * **Create an Executor** and execute the root command. -The rest of the document will detail what needs to be implemented for each step. +An example of the `main()` function for the [nameservice tutorial](https://cosmos.network/docs/tutorial) CLI can be found [here](https://github.com/cosmos/sdk-application-tutorial/blob/master/cmd/nscli/main.go#L26-L67). The rest of the document will detail what needs to be implemented for each step and include smaller portions of code from the nameservice CLI `main.go` file. ## Commands @@ -41,20 +41,74 @@ Every application CLI first constructs a root command, then adds functionality b The root command (also called `rootCmd`) is what the user first types into the command line to indicate which application they wish to interact with. The string used to invoke the command (the "Use" field) is typically the name of the application suffixed with `-cli`, e.g. `appcli`. The root command must include the following commands to support basic functionality in the application. -* **Status** command from the SDK rpc client tools, which prints information about the status of the connected `Node`. +* **Status** command from the SDK rpc client tools, which prints information about the status of the connected [`Node`](,,/core/node.md). * **Config** command from the SDK client tools, which allows the user to edit a `config.toml` file that sets values for [flags](#flags) such as `--chain-id` and which `--node` they wish to connect to. * **Keys** commands from the SDK client tools, which includes a collection of subcommands for using the key functions in the SDK crypto tools, including adding a new key and saving it to disk, listing all public keys stored in the key manager, and deleting a key. * [**Transaction**](#transaction-commands) commands. * [**Query**](#query-commands) commands. +Here is an example from the [nameservice tutorial](https://cosmos.network/docs/tutorial) CLI's `main()` function. It instantiates the root command, adds a [*persistent* flag](#flags) and `PreRun` function to be run before every execution, and adds all of the necessary subcommands. + + +```go +rootCmd := &cobra.Command{ + Use: "nscli", + Short: "nameservice Client", +} +rootCmd.AddCommand( + rpc.StatusCommand(), + client.ConfigCmd(defaultCLIHome), + queryCmd(cdc, mc), + txCmd(cdc, mc), + client.LineBreak, + lcd.ServeCommand(cdc, registerRoutes), + client.LineBreak, + keys.Commands(), + client.LineBreak, +) +``` + +All of these things are done within the `main()` function. At the end of the `main()` function, it is necessary to create an `executor` and `Execute()` the root command in the `main()` function: + +```go +executor := cli.PrepareMainCmd(rootCmd, "NS", defaultCLIHome) +err := executor.Execute() +``` + ### Transaction Commands -[Transactions](#./transactions.md) are objects wrapping messages that trigger state changes within modules. To enable the creation of transactions using the CLI interface, `TxCmd` should add the following commands: +[Transactions](#./transactions.md) are objects wrapping [messages](../building-modules/messages-and-queries.md) that trigger state changes within modules. To enable the creation of transactions using the CLI interface, `TxCmd` should add the following commands: -* **Sign** command from the [`auth`](https://github.com/cosmos/cosmos-sdk/blob/master/docs/spec/auth) module, which signs messages in a transaction. To enable multisig, it should also add the `auth` module MultiSign command. Since every transaction requires some sort of signature in order to be valid, this command is necessary for every application. +* **Sign** command from the [`auth`](https://github.com/cosmos/cosmos-sdk/blob/master/docs/spec/auth) module, which signs messages in a transaction. To enable multisig, it should also add the `auth` module `MultiSign` command. Since every transaction requires some sort of signature in order to be valid, this command is necessary for every application. * **Broadcast** command from the SDK client tools, which broadcasts transactions. * **Send** command from the [`bank`](https://github.com/cosmos/cosmos-sdk/blob/master/docs/spec/bank) module, which is a transaction that allows accounts to send coins to one another, including gas and fees for transactions. -* All commands in each module the application is dependent on, retrieved by calling `GetTxCmd()` on all the modules or using the Module Manager's `AddTxCommands()` function. +* All commands in each module the application is dependent on, retrieved by calling [`GetTxCmd()`](../building-modules/interfaces.md#GetTxCmd) on all the modules or using the Module Manager's [`AddTxCommands()`](../building-modules/module-manager.md) function. + +Here is an example of a `TxCmd` aggregating these subcommands from the [nameservice tutorial](https://cosmos.network/docs/tutorial). + +```go +func txCmd(cdc *amino.Codec, mc []sdk.ModuleClients) *cobra.Command { + txCmd := &cobra.Command{ + Use: "tx", + Short: "Transactions subcommands", + } + + txCmd.AddCommand( + bankcmd.SendTxCmd(cdc), + client.LineBreak, + authcmd.GetSignCommand(cdc), + tx.GetBroadcastCommand(cdc), + client.LineBreak, + ) + + for _, m := range mc { + txCmd.AddCommand(m.GetTxCmd()) + } + + return txCmd +} +``` + ### Query Commands @@ -64,24 +118,55 @@ The root command (also called `rootCmd`) is what the user first types into the c * **Account** command from the `auth` module, which displays the state (e.g. account balance) of an account given an address. * **Validator** command from the SDK rpc client tools, which displays the validator set of a given height. * **Block** command from the SDK rpc client tools, which displays the block data for a given height. -* All commands in each module the application is dependent on, retrieved by calling `GetQueryCmd()` on all the modules or using the Module Manager's `AddQueryCommands()` function. +* All commands in each module the application is dependent on, retrieved by calling [`GetQueryCmd()`](../building-modules/interfaces.md#GetqueryCmd) on all the modules or using the Module Manager's `AddQueryCommands()` function. + +Here is an example of a `QueryCmd` aggregating subcommands, also from the nameservice tutorial (it is structurally identical to `TxCmd`): + +```go +func queryCmd(cdc *amino.Codec, mc []sdk.ModuleClients) *cobra.Command { + queryCmd := &cobra.Command{ + Use: "query", + Aliases: []string{"q"}, + Short: "Querying subcommands", + } + + queryCmd.AddCommand( + rpc.ValidatorCommand(cdc), + rpc.BlockCommand(), + tx.SearchTxCmd(cdc), + tx.QueryTxCmd(cdc), + client.LineBreak, + authcmd.GetAccountCmd(storeAcc, cdc), + ) + + for _, m := range mc { + queryCmd.AddCommand(m.GetQueryCmd()) + } + + return queryCmd +} +``` ## Flags Flags are used to modify commands. Users can explicitly include them in commands or pre-configure them by entering a command in the format `appcli config ` into their command line. Commonly pre-configured flags include the `--node` to connect to and `--chain-id` of the blockchain the user wishes to interact with. -A _persistent_ flag (as opposed to a _local_ flag) added to a command transcends all of its children. Additionally, all flags have default values when they are added to commands; some toggle an option off but others are empty values that the user needs to override to create valid commands. A flag can be explicitly marked as _required_ so that an error is automatically thrown if the user does not provide a value, but it is also acceptable to handle unexpected missing flags differently. +A *persistent* flag (as opposed to a _local_ flag) added to a command transcends all of its children: subcommands will inherit the configured values for these flags. Additionally, all flags have default values when they are added to commands; some toggle an option off but others are empty values that the user needs to override to create valid commands. A flag can be explicitly marked as _required_ so that an error is automatically thrown if the user does not provide a value, but it is also acceptable to handle unexpected missing flags differently. ### Root Command Flags -It is common to add a _persistent_ flag for `--chain-id`, the unique identifier of the blockchain the application pertains to, to the root command. Adding this flag makes sense as the chain ID should not be changing across commands in this application CLI. +It is common to add a _persistent_ flag for `--chain-id`, the unique identifier of the blockchain the application pertains to, to the root command. Adding this flag makes sense as the chain ID should not be changing across commands in this application CLI. Here is what that looks like: + +```go +rootCmd.PersistentFlags().String(client.FlagChainID, "", "Chain ID of tendermint node") +``` ### Transaction Flags To **create** a transaction, the user enters a `tx` command and provides several flags. These are the basic flags added to every command using the SDK `./client/flags` package [`PostCommands`](https://github.com/cosmos/cosmos-sdk/blob/master/client/flags/flags.go#L85-L116) function: -* `--from` indicates which account the transaction originates from. This account is used to sign the transaction. -* `--gas` refers to how much gas, which represents computational resources, Tx consumes. Gas is dependent on the transaction and is not precisely calculated until execution, but can be estimated by providing auto as the value for --gas. +* `--from` indicates which [account](../core/accounts-fees.md) the transaction originates from. This account is used to sign the transaction. +* `--gas` refers to how much [gas](../core/gas.md), which represents computational resources, Tx consumes. Gas is dependent on the computational needs of the transaction and is not precisely calculated until execution, but can be estimated by providing auto as the value for --gas. * `--gas-adjustment` (optional) can be used to scale gas up in order to avoid underestimating. For example, users can specify their gas adjustment as 1.5 to use 1.5 times the estimated gas. * `--gas-prices` specifies how much the user is willing pay per unit of gas, which can be one or multiple denominations of tokens. For example, --gas-prices=0.025uatom, 0.025upho means the user is willing to pay 0.025uatom AND 0.025upho per unit of gas. * `--fees` specifies how much in fees the user is willing to pay in total. Note that the user only needs to provide either `gas-prices` or `fees`, but not both, because they can be derived from each other. @@ -122,6 +207,7 @@ For example, the following command broadcasts the signed transaction, `mySignedT ```bash appcli tx broadcast mySignedTx.json --node ``` + ### Query Flags Queries also have flags. These are the basic flags added to every command using the SDK `./client/flags` package [`GetCommand`](https://github.com/cosmos/cosmos-sdk/blob/master/client/flags/flags.go#L67-L82) function: @@ -135,12 +221,47 @@ Queries also have flags. These are the basic flags added to every command using ## Configurations -The last function to define is, `initConfig`, which should do exactly what it sounds like - initial configurations. To call this function, set it as a `PersistentPreRunE` function for the root command, so that it always executes before the main execution of the root command and any of its subcommands. `initConfig` should do the following: +The last function to define is, `initConfig`, which should do exactly what it sounds like - initial configurations. To call this function, set it as a `PersistentPreRunE` function for the root command, so that it always executes before the main execution of the root command and any of its subcommands. `initConfig()` should do the following: 1. Read in the `config.toml` file. This same file is edited through `config` commands. 2. Use the [Viper](https://github.com/spf13/viper) to read in configurations from the file and set them. 3. Set any persistent flags defined by the user: `--chain-id`, `--encoding`, `--output`, etc. +Here is an example of an `initConfig()` function from the nameservice tutorial CLI: + +```go +func initConfig(cmd *cobra.Command) error { + home, err := cmd.PersistentFlags().GetString(cli.HomeFlag) + if err != nil { + return err + } + + cfgFile := path.Join(home, "config", "config.toml") + if _, err := os.Stat(cfgFile); err == nil { + viper.SetConfigFile(cfgFile) + + if err := viper.ReadInConfig(); err != nil { + return err + } + } + if err := viper.BindPFlag(client.FlagChainID, cmd.PersistentFlags().Lookup(client.FlagChainID)); err != nil { + return err + } + if err := viper.BindPFlag(cli.EncodingFlag, cmd.PersistentFlags().Lookup(cli.EncodingFlag)); err != nil { + return err + } + return viper.BindPFlag(cli.OutputFlag, cmd.PersistentFlags().Lookup(cli.OutputFlag)) +} +``` + +Here is an example of how to add `initConfig` as a `PersistentPreRunE` to the root command: + +```go +rootCmd.PersistentPreRunE = func(_ *cobra.Command, _ []string) error { + return initConfig(rootCmd) +} +``` + ## Next Read about how to build a module CLI [here](./module-interfaces#cli) diff --git a/docs/interfaces/interfaces-intro.md b/docs/interfaces/interfaces-intro.md index 9e68ee971027..e457925acaad 100644 --- a/docs/interfaces/interfaces-intro.md +++ b/docs/interfaces/interfaces-intro.md @@ -8,7 +8,7 @@ ## Synopsis -Every application must include some interface users can use to interact with the defined functionalities. This document introduces user interfaces for SDK applications. +Typically, SDK applications include some type of interface that users interact with to utilize the application's functionalities. This document introduces user command-line and REST interfaces. - [Types of Application Interfaces](#types-of-application-interfaces) - [Module vs Application Interfaces](#module-vs-application-interfaces) @@ -18,31 +18,31 @@ Every application must include some interface users can use to interact with the ## Types of Application Interfaces -SDK applications should have a Command-Line Interface (CLI) and REST Interface to support HTTP requests. The SDK is opinionated about how to create these two interfaces; all modules specify [Cobra commands](https://github.com/spf13/cobra) and register routes using [Gorilla Mux routers](https://github.com/gorilla/mux). The CLI and REST Interface are conventionally defined in the application `/cmd/cli` folder. +SDK applications generally have a Command-Line Interface (CLI) and REST Interface to support interactions with a [full-node](../core/node.md). The SDK is opinionated about how to create these two interfaces; all modules specify [Cobra commands](https://github.com/spf13/cobra) and register routes using [Gorilla Mux routers](https://github.com/gorilla/mux). The CLI and REST Interface are conventionally defined in the application `app/cmd/cli` folder. ## Module vs Application Interfaces -The process of creating an application interface is very different from creating a module interface, though the components are closely intertwined. As expected, the module interface handles the bulk of the underlying logic, unpacking user requests into arguments and routes, and neatly marshaling everything into ABCI requests to be handled by Baseapp. On the other hand, the application interface handles the user configurations and customizations, instantiates the application-specific values and objects, and passes everything to module interface functions. +The process of creating an application interface is distinct from creating a [module interface](../building-modules/interfaces.md), though the components are closely intertwined. As expected, the module interface handles the bulk of the underlying logic, defining ways for end-users to create [messages](../building-modules/messages-and-queries.md#messages) handled by the module and [queries](../building-modules/messages-and-queries.md#queries) to the subset of application state within the scope of the module. On the other hand, the application interfaces aggregate module-level interfaces in order to route messages and queries to the appropriate modules. Application interfaces also handle root-level responsibilities such as signing and broadcasting [transactions](../core/transactions.md) that wrap messages. ### Module Developer Responsibilities -In regards to interfaces, the module developers' responsibilities include: +In regards to interfaces, module developers include the following definitions: * **CLI commands:** Specifically, [Transaction commands](../building-modules/interfaces.md#transaction-commands) and [Query commands](../building-modules/interfaces.md#query-commands). These are commands that users will invoke when interacting with the application to create transactions and queries. For example, if an application enables sending coins through the [`auth`](https://github.com/cosmos/cosmos-sdk/tree/67f6b021180c7ef0bcf25b6597a629aca27766b8/docs/spec/auth) module, users will create `tx auth send` transactions. * **Request Handlers:** Also categorized into Transaction and Query requests. Transactions will require HTTP [Request Types](../building-modules/interfaces.md#request-types) in addition to [Request Handlers](../building-modules/interfaces.md#request-handlers) in order to encapsulate all of the user's options (e.g. gas prices). * **REST Routes:** Given a router, the module interface registers paths with the aforementioned [Request Handlers](../building-modules/interfaces.md#request-handlers) for each type of request. -Module interfaces are designed to be generic. Both commands and request types will include required user input (through flags or request body) which will be different for each application. This section of documents will only detail application interfaces; to read about how to build module interfaces, click [here](../building-modules/interfaces.md). +Module interfaces are designed to be generic. Both commands and request types include required user input (through flags or request body) which are different for each application. This section of documents will only detail application interfaces; to read about how to build module interfaces, click [here](../building-modules/interfaces.md). ### Application Developer Responsibilities -In regards to interfaces, the application developers' responsibilities include: +In regards to interfaces, application developers include: -* **CLI Root Command:** The root command adds subcommands to include all of the functionality for the application, mainly module transaction and query commands. -* **App Configurations:** All application-specific values are the responsibility of the application developer, including the `codec` used to marshal requests before relaying them to a node. -* **User Configurations:** Some values are specific to the user, such as the user's address and which node they are connected to. -* **RegisterRoutes Function:** To be passed to an instantiated REST Server so that it knows how to route requests for this particular application. +* **CLI Root Command:** The [root command](./cli.md#root-command) adds subcommands to include all of the functionality for the application, mainly module [transaction](./cli.md#transaction-commands) and [query](./cli.md#query-commands) commands from the application's module(s). +* **App Configurations:** All application-specific values are the responsibility of the application developer, including the [`codec`](../core/encoding.md) used to marshal requests before relaying them to a node. +* **User Configurations:** Some values are specific to the user, such as the user's address and which node they are connected to. The CLI has a [configurations](./cli.md#configurations) function to set these values. +* **RegisterRoutes Function:** [Routes](./rest.md#registerroutes) must be registered and passed to an instantiated [REST server](./rest.md#rest-server) so that it knows how to route requests for this particular application. ## Next diff --git a/docs/interfaces/query-lifecycle.md b/docs/interfaces/query-lifecycle.md index b95d6980fae0..44026d16bc2d 100644 --- a/docs/interfaces/query-lifecycle.md +++ b/docs/interfaces/query-lifecycle.md @@ -9,7 +9,7 @@ This document describes SDK interfaces in detail through the lifecycle of a query, from the user interface to application stores and back. The query will be referred to as `Query`. - [Interfaces](#interfaces) -- [CLIContext](#clicontext) +- [Request and Command Handling](#request-and-command-handling) - [Tendermint and ABCI](#tendermint-and-abci) - [Application Query Handling](#application-query-handling) - [Response](#response) @@ -18,11 +18,11 @@ This document describes SDK interfaces in detail through the lifecycle of a quer A [**query**](../building-modules/messages-and-queries.md#queries) is a request for information made by users of applications. Users can query information about the network, the application itself, and application state directly from the application's stores or modules. -For the purpose of explaining a query lifecycle, let's say `Query` is requesting a list of delegations made by a certain delegator address in the application called `app`. There are a few ways `Query` can be made on the user side. +For the purpose of explaining a query lifecycle, let's say `Query` is requesting a list of delegations made by a certain delegator address in the application called `app`. As to be expected, the [`staking`](https://github.com/cosmos/cosmos-sdk/blob/master/docs/spec/staking) module handles this query. But first, there are a few ways `Query` can be created by users. ### CLI -The main interface for an application is the command-line interface. Users run the CLI directly from their machines and type commands to create queries. To create this query from their terminal, users would type the following command: +The main interface for an application is the command-line interface. Users connect to a full node and run the CLI directly from their machines. To create `Query` from their terminal, users type the following command: ``` appcli query staking delegations @@ -30,20 +30,22 @@ appcli query staking delegations To provide values such as `--chain-id` (the ID of the blockchain to make the query to), the user must use the `config` command to set them or provide them as flags. -This query command is defined by the module developer and added to the list of subcommands by the application developer when creating the CLI. +This query command was defined by the [`staking`](https://github.com/cosmos/cosmos-sdk/blob/master/docs/spec/staking) module developer and added to the list of subcommands by the application developer when creating the CLI. The code for this particular command can be found [here](https://github.com/cosmos/cosmos-sdk/blob/master/x/staking/client/cli/query.go#L253-L294). ### REST -Another interface through which users can make queries is through HTTP Requests to a REST server. The REST server contains, among other things, a [`CLIContext`](#clicontext) and [mux](./rest.md#gorilla-mux) router. The request looks like this: +Another interface through which users can make queries is through HTTP Requests to a [REST server](./rest.md#rest-server). The REST server contains, among other things, a [`CLIContext`](#clicontext) and [mux](./rest.md#gorilla-mux) router. The request looks like this: ```bash GET http://localhost:{PORT}/staking/delegators/{delegatorAddr}/delegations ``` -To provide values such as `--chain-id` (the ID of the blockchain to make the query to), the user must configure their local REST server with the values or provide them in the request body. +To provide values such as `--chain-id` (the ID of the blockchain to make the query to) that are required by [`baseReq`](./rest.md#basereq), the user must configure their local REST server with the values or provide them in the request body. The router automatically routes the `Query` HTTP request to the staking module `delegatorDelegationsHandlerFn()` function (to see the handler itself, click [here]()). Since this function is defined within the module and thus has no inherent knowledge of the application `Query` belongs to, it takes in the application `codec` and `CLIContext` as parameters. +When users interact with the interfaces, the result is a CLI command or HTTP request. `Query` is then created when the command is executed or request handled. + ## Request and Command Handling The interactions from the users' perspective are a bit different, but the underlying functions are almost identical. This section describes how the CLI command or HTTP request is processed, up until the ABCI request is sent. This step of processing heavily involves a `CLIContext`. @@ -52,7 +54,7 @@ The interactions from the users' perspective are a bit different, but the underl The first thing that is created in the execution of a CLI command is a `CLIContext`, while the REST Server directly provides a `CLIContext` for the REST Request handler. A [Context](../core/context.md) is an immutable object that stores all the data needed to process a request. In particular, a `CLIContext` stores the following: -* **Codec**: The encoder/decoder used by the application, used to marshal the parameters and query before making the Tendermint RPC request and unmarshal the returned response into a JSON object. +* **Codec**: The [encoder/decoder](,./core/encoding.md) used by the application, used to marshal the parameters and query before making the Tendermint RPC request and unmarshal the returned response into a JSON object. * **Account Decoder**: The account decoder from the [`auth`](.../spec/auth) module, which translates `[]byte`s into accounts. * **RPC Client**: The [Tendermint RPC Client](https://github.com/tendermint/tendermint/blob/master/rpc/client/interface.go), or node, to which the request will be relayed to. * **Keybase**: A [Key Manager](.//core/accounts-keys.md) used to sign transactions and handle other operations with keys. @@ -65,37 +67,37 @@ For full specification of the `CLIContext` type, click [here](https://github.com The next step is to parse the command or request, extract the arguments, create a `queryRoute`, and encode everything. -In this case, `Query` contains a `delegatorAddress` as its only argument. However, the request can only contain `[]byte`s, as it will be relayed to a consensus engine node that has no inherent knowledge of the application types. Thus, the `CLIContext` `codec` is used to marshal the address as the type `QueryDelegatorParams`. All query arguments (e.g. the `staking` module also has `QueryValidatorParams` and `QueryBondsParams`) have their own types that the application `codec` understands how to encode and decode. The module [`querier`](.//building-modules/querier.md) declares these types and the application registers the `codec`s. +In this case, `Query` contains an [address](../core/accounts-fees.md) `delegatorAddress` as its only argument. However, the request can only contain `[]byte`s, as it will be relayed to a consensus engine node that has no inherent knowledge of the application types. Thus, the `CLIContext` `codec` is used to marshal the address as the type [`QueryDelegatorParams`](https://github.com/cosmos/cosmos-sdk/blob/master/x/staking/types/querier.go#L30-L38). All query arguments (e.g. the [`staking`](https://github.com/cosmos/cosmos-sdk/blob/master/docs/spec/staking) module also has [`QueryValidatorParams`](https://github.com/cosmos/cosmos-sdk/blob/master/x/staking/types/querier.go#L45-L53) and [`QueryBondsParams`](https://github.com/cosmos/cosmos-sdk/blob/master/x/staking/types/querier.go#L59-L69)) have their own types that the application `codec` understands how to encode and decode. The module [`querier`](.//building-modules/querier.md) declares these types and the application registers the `codec`s. -A `route` is also created for `Query` so that the application will understand which module to route the query to. Baseapp will understand this query to be a `custom` query in the module `staking` with the type `QueryDelegatorDelegations`. Thus, the route will be `"custom/staking/delegatorDelegations"`. +A `route` is also created for `Query` so that the application will understand which module to route the query to. [Baseapp](../core/baseapp.md#query-routing) will understand this query to be a `custom` query in the module `staking` with the type `QueryDelegatorDelegations`. Thus, the route will be `"custom/staking/delegatorDelegations"`. ### ABCI Query -The `CLIContext`'s main `Query` function takes the `route`, which is now called `path`, and arguments, now called `key`. It first retrieves the RPC Client (called the **node**) configured by the user to relay this query to, and creates the `ABCIQueryOptions` (parameters formatted for the ABCI call). The node is then used to make the ABCI call, `ABCIQueryWithOptions`. +The `CLIContext`'s main `Query` function takes the `route`, which is now called `path`, and arguments, now called `key`. It first retrieves the RPC Client (called the [**node**](../core/node.md)) configured by the user to relay this query to, and creates the `ABCIQueryOptions` (parameters formatted for the ABCI call). The node is then used to make the ABCI call, `ABCIQueryWithOptions()`. ## Tendermint and ABCI -With a call to `ABCIQueryWithOptions()`, `Query` arrives at the consensus engine portion of its lifecycle. Nodes running the consensus engine (e.g. Tendermint Core) make ABCI calls to interact with the application. At this point, `Query` exists as an ABCI `RequestQuery` and the [ABCI Client](https://github.com/tendermint/tendermint/blob/51b3428f5c0f4fdd2e469147cd90353faa4bd704/abci/client/client.go#L16-L50) calls the ABCI method [`Query()`](https://tendermint.com/docs/spec/abci/abci.html#query) on the application. +With a call to `ABCIQueryWithOptions()`, `Query` arrives at the consensus engine portion of its lifecycle. Nodes running the consensus engine (e.g. Tendermint Core) make ABCI calls to interact with the application. At this point, `Query` exists as an ABCI `RequestQuery` and the [ABCI Client](https://github.com/tendermint/tendermint/blob/master/abci/client/client.go#L16-L50) calls the ABCI method [`Query()`](https://tendermint.com/docs/spec/abci/abci.html#query) on the application. Read more about ABCI Clients and Tendermint RPC in the Tendermint documentation [here](https://tendermint.com/rpc). ## Application Query Handling -[Baseapp](../core/baseapp.md) implements the ABCI [`Query()`](../core/baseapp.md#query) function and handles four different types of queries: `app`, `store`, `p2p`, and `custom`. The `queryRoute` is parsed such that the first string must be one of the four options, then the rest of the path is parsed within the subroutines handling each type of query. The first three types are application-level and thus directly handled by Baseapp or the stores, but the `custom` query type requires Baseapp to route the query to a module's [querier](../building-modules/querier.md). +[Baseapp](../core/baseapp.md) implements the ABCI [`Query()`](../core/baseapp.md#query) function and handles four different types of queries: `app`, `store`, `p2p`, and `custom`. The `queryRoute` is parsed such that the first string must be one of the four options, then the rest of the path is parsed within the subroutines handling each type of query. The first three types (`app`, `store`, `p2p`) are purely application-level and thus directly handled by Baseapp or the stores, but the `custom` query type requires Baseapp to route the query to a module's [querier](../building-modules/querier.md). -Since `Query` is a custom query type, Baseapp first parses the path, then uses the `QueryRouter` to retrieve the corresponding querier. The querier is responsible for recognizing this query, retrieving the appropriate values from the application's stores, and returning a response. +Since `Query` is a custom query type from the `staking` module, Baseapp first parses the path, then uses the `QueryRouter` to retrieve the corresponding querier. The querier is responsible for recognizing this query, retrieving the appropriate values from the application's stores, and returning a response. ## Response -Since `Query()` is an ABCI function, Baseapp returns the `Query` response as an `abci.ResponseQuery`. The `CLIContext` `Query` routine receives the response and, if `--trust-node` is toggled to `false` and a proof needs to be verified, the response is verified with the `CLIContext` `verifyProof` function before the response is returned. +Since `Query()` is an ABCI function, Baseapp returns the response as an [`abci.ResponseQuery`](https://tendermint.com/docs/spec/abci/abci.html#messages) type. The `CLIContext` `Query()` routine receives the response and, if `--trust-node` is toggled to `false` and a proof needs to be verified, the response is verified with the `CLIContext` [`verifyProof()`](https://github.com/cosmos/cosmos-sdk/blob/master/client/context/query.go#L136-L173) function before the response is returned. ### CLI Response -The application `codec` is used to unmarshal the response to a JSON and the `CLIContext` prints the output to the command line, applying any configurations such as `--indent`. +The application [`codec`](../core/encoding.md) is used to unmarshal the response to a JSON and the `CLIContext` prints the output to the command line, applying any configurations such as `--indent`. ### REST Response -The REST server uses the `CLIContext` to format the response properly, then uses the HTTP package to write the appropriate response or error. +The [REST server](./rest.md#rest-server) uses the `CLIContext` to format the response properly, then uses the HTTP package to write the appropriate response or error. ## Next diff --git a/docs/interfaces/rest.md b/docs/interfaces/rest.md index ce3b8db10b42..858c4b9420a4 100644 --- a/docs/interfaces/rest.md +++ b/docs/interfaces/rest.md @@ -16,7 +16,7 @@ This document describes how to create a REST interface for an SDK application. A ## Application REST Interface -Building the REST Interface for an application involves creating a REST server to route requests and output responses. The SDK has its own REST Server type used for LCDs (light-client daemons). It has a `ServeCommand` that takes in an application's `codec` and `RegisterRoutes` function, starts up a new SDK REST Server, and registers routes using function provided from the application. To enable this command, it should be added as a subcommand of the root command `RootCmd` in the `main()` function of the CLI interface. +Building the REST Interface for an application involves creating a [REST server](./rest.md#rest-server) to route requests and output responses. The SDK has its own REST Server type used for [LCDs](../core/node.md) (light-client daemons). It has a `ServeCommand` that takes in an application's `codec` and `RegisterRoutes()` function, starts up a new REST Server, and registers routes using function provided from the application. To enable this command, it should be added as a subcommand of the root command `RootCmd` in the `main()` function of the CLI interface. Users can use the application CLI to start a new LCD, a local server through which they can securely interact with the application without downloading the entire state. The command entered by users would look something like this: @@ -32,15 +32,15 @@ HTTP Request types are defined by the module interfaces for every type of transa `BaseReq` is a type defined in the SDK that encapsulates much of the transaction configurations similar to CLI command flags. Users must provide the information in the body of their requests. -* `From` indicates which account the transaction originates from. This account is used to sign the transaction. +* `From` indicates which [account](../core/accounts-fees.md) the transaction originates from. This account is used to sign the transaction. * `Memo` sends a memo along with the transaction. * `ChainID` specifies the unique identifier of the blockchain the transaction pertains to. * `AccountNumber` is an identifier for the account. * `Sequence`is the value of a counter measuring how many transactions have been sent from the account. It is used to prevent replay attacks. -* `Gas` refers to how much gas, which represents computational resources, Tx consumes. Gas is dependent on the transaction and is not precisely calculated until execution, but can be estimated by providing auto as the value for `Gas`. +* `Gas` refers to how much [gas](../core/gas.md), which represents computational resources, Tx consumes. Gas is dependent on the transaction and is not precisely calculated until execution, but can be estimated by providing auto as the value for `Gas`. * `GasAdjustment` can be used to scale gas up in order to avoid underestimating. For example, users can specify their gas adjustment as 1.5 to use 1.5 times the estimated gas. * `GasPrices` specifies how much the user is willing pay per unit of gas, which can be one or multiple denominations of tokens. For example, --gas-prices=0.025uatom, 0.025upho means the user is willing to pay 0.025uatom AND 0.025upho per unit of gas. -* `Fees` specifies how much in fees the user is willing to pay in total. Note that the user only needs to provide either `gas-prices` or `fees`, but not both, because they can be derived from each other. +* `Fees` specifies how much in [fees](../core/accounts-fees.md) the user is willing to pay in total. Note that the user only needs to provide either `gas-prices` or `fees`, but not both, because they can be derived from each other. * `Simulate` instructs the application to ignore gas and simulate the transaction running without broadcasting. Additionally, each request may contain arguments such as a specific address pertaining to the request. @@ -59,9 +59,9 @@ Of the five, the only attribute that developers will need to configure is the ro ## Registering Routes -To include routes for each module in an application, the CLI must have some kind of function to Register Routes in its REST Server. This `RegisterRoutes` function is utilized by the `ServeCommand` and must include routes for each of the application's modules. Since each module used by an SDK application implements a [`RegisterRESTRoutes`](../building-modules.md#rest) function, application developers simply use the Module Manager to call this function for each module. +To include routes for each module in an application, the CLI must have some kind of function to Register Routes in its REST Server. This `RegisterRoutes()` function is utilized by the `ServeCommand` and must include routes for each of the application's modules. Since each module used by an SDK application implements a [`RegisterRESTRoutes`](../building-modules.md#rest) function, application developers simply use the Module Manager to call this function for each module. -At the bare minimum, a `RegisterRoutes` function should use the SDK client package `RegisterRoutes` function to be able to route RPC calls, and instruct the application Module Manager to call `RegisterRESTRoutes` for all of its modules: +At the bare minimum, a `RegisterRoutes()` function should use the SDK client package `RegisterRoutes()` function to be able to route RPC calls, and instruct the application Module Manager to call `RegisterRESTRoutes()` for all of its modules: ```go func registerRoutes(rs *lcd.RestServer) { From f53347f03e204a21443bd2a611d45960e977bc2d Mon Sep 17 00:00:00 2001 From: Gloria Zhao Date: Mon, 12 Aug 2019 11:35:39 -0400 Subject: [PATCH 101/196] cli.md comments --- docs/interfaces/cli.md | 155 ++++++++++++++++++++++++----------------- 1 file changed, 90 insertions(+), 65 deletions(-) diff --git a/docs/interfaces/cli.md b/docs/interfaces/cli.md index 6287c0d24026..f1864a2593cb 100644 --- a/docs/interfaces/cli.md +++ b/docs/interfaces/cli.md @@ -6,7 +6,7 @@ ## Synopsis -This document describes how to create a commmand-line interface for an SDK application. A separate document for creating a module CLI can be found [here](#../module-interfaces.md#cli). +This document describes how to create a commmand-line interface (CLI) for an application. A separate document for implementing a CLI for an SDK module can be found [here](#../building-modules/interfaces.md#cli). - [Application CLI Components](#application-cli-components) - [Commands](#commands) @@ -15,11 +15,20 @@ This document describes how to create a commmand-line interface for an SDK appli ## Application CLI Components -One of the main entrypoints of an application is the command-line interface. This entrypoint is created as a `main.go` file which compiles to a binary, conventionally placed in the application's `app/cmd/cli` folder. The CLI for an application will typically be referred to as the name of the application suffixed with `-cli`, e.g. `appcli`. +One of the main entrypoints of an application is the command-line interface. This entrypoint is created as a `main.go` file which compiles to a binary, conventionally placed in the application's `./cmd/cli` folder. The CLI for an application is typically be referred to as the name of the application suffixed with `-cli`, e.g. `appcli`. Here is where the interfaces docs lie in the directory from the [nameservice tutorial](https://cosmos.network/docs/tutorial) ### Cobra -There is no set way to create a CLI, but SDK modules all use the [Cobra Library](https://github.com/spf13/cobra) in order to implement the [`AppModuleBasic`](../building-modules/modules-manager.md) interface. Building a CLI with Cobra entails defining commands, arguments, and flags. [**Commands**](#commands) understand the actions users wish to take, such as `tx` for creating a transaction and `query` for querying the application. Each command can also have nested subcommands, necessary for naming the specific transaction type. Users also supply **Arguments**, such as account numbers to send coins to, and [**Flags**](#flags) to modify various aspects of the commands, such as gas prices or which node to broadcast to. +There is no set way to create a CLI, but SDK modules all use the [Cobra Library](https://github.com/spf13/cobra). Building a CLI with Cobra entails defining commands, arguments, and flags. [**Commands**](#commands) understand the actions users wish to take, such as `tx` for creating a transaction and `query` for querying the application. Each command can also have nested subcommands, necessary for naming the specific transaction type. Users also supply **Arguments**, such as account numbers to send coins to, and [**Flags**](#flags) to modify various aspects of the commands, such as gas prices or which node to broadcast to. + +Here is an example of a command a user might enter to interact with the nameservice CLI `nscli` in order to buy a name: + +```bash +nscli tx nameservice buy-name --gas auto --gas-prices +``` +The first four strings specify the command: the root command for the entire application `nscli`, the subcommand `tx`, the subcommand `nameservice` to indicate which module to route the command to, and the type of transaction `buy-name`. The next two strings are arguments: the `name` the user wishes to buy and the `amount` they want to pay for it. Finally, the last few strings of the command are flags to indicate how much the user is willing to pay in fees (calculated using the amount of gas used to execute the transaction and the gas prices provided by the user). + +The CLI interacts with a node (running `nsd`) to handle this command. ### Main Function @@ -39,11 +48,53 @@ Every application CLI first constructs a root command, then adds functionality b ### Root Command -The root command (also called `rootCmd`) is what the user first types into the command line to indicate which application they wish to interact with. The string used to invoke the command (the "Use" field) is typically the name of the application suffixed with `-cli`, e.g. `appcli`. The root command must include the following commands to support basic functionality in the application. - -* **Status** command from the SDK rpc client tools, which prints information about the status of the connected [`Node`](,,/core/node.md). -* **Config** command from the SDK client tools, which allows the user to edit a `config.toml` file that sets values for [flags](#flags) such as `--chain-id` and which `--node` they wish to connect to. -* **Keys** commands from the SDK client tools, which includes a collection of subcommands for using the key functions in the SDK crypto tools, including adding a new key and saving it to disk, listing all public keys stored in the key manager, and deleting a key. +The root command (called `rootCmd`) is what the user first types into the command line to indicate which application they wish to interact with. The string used to invoke the command (the "Use" field) is typically the name of the application suffixed with `-cli`, e.g. `appcli`. The root command must include the following commands to support basic functionality in the application. + +* **Status** command from the SDK rpc client tools, which prints information about the status of the connected [`Node`](,,/core/node.md). The Status of a node includes [`NodeInfo`](https://github.com/tendermint/tendermint/blob/master/p2p/node_info.go#L75-L92), `SyncInfo` and `ValidatorInfo`: this information includes the node ID, latest block hash, and the validator public key and voting power. Here is an example of what the `status command` outputs: +```json +{ + "jsonrpc": "2.0", + "id": "", + "result": { + "node_info": { + "protocol_version": { + "p2p": "4", + "block": "7", + "app": "0" + }, + "id": "53729852020041b956e86685e24394e0bee4373f", + "listen_addr": "10.0.2.15:26656", + "network": "test-chain-Y1OHx6", + "version": "0.24.0-2ce1abc2", + "channels": "4020212223303800", + "moniker": "ubuntu-xenial", + "other": { + "tx_index": "on", + "rpc_addr": "tcp://0.0.0.0:26657" + } + }, + "sync_info": { + "latest_block_hash": "F51538DA498299F4C57AC8162AAFA0254CE08286", + "latest_app_hash": "0000000000000000", + "latest_block_height": "18", + "latest_block_time": "2018-09-17T11:42:19.149920551Z", + "catching_up": false + }, + "validator_info": { + "address": "D9F56456D7C5793815D0E9AF07C3A355D0FC64FD", + "pub_key": { + "type": "tendermint/PubKeyEd25519", + "value": "wVxKNtEsJmR4vvh651LrVoRguPs+6yJJ9Bz174gw9DM=" + }, + "voting_power": "10" + } + } +} +``` +* **Config** [command](https://github.com/cosmos/cosmos-sdk/blob/master/client/config.go) from the SDK client tools, which allows the user to edit a `config.toml` file that sets values for [flags](#flags) such as `--chain-id` and which `--node` they wish to connect to. +The `config` command can be invoked by typing `appcli config` with optional arguments ` [value]` and a `--get` flag to query configurations or `--home` flag to create a new configuration. +* **Keys** [commands](https://github.com/cosmos/cosmos-sdk/blob/master/client/keys) from the SDK client tools, which includes a collection of subcommands for using the key functions in the SDK crypto tools, including adding a new key and saving it to disk, listing all public keys stored in the key manager, and deleting a key. +For example, users can type `appcli keys add ` to add a new key and save an encrypted copy to disk, using the flag `--recover` to recover a private key from a seed phrase or the flag `--multisig` to group multiple keys together to create a multisig key. For full details on the `add` key command, see the code [here](https://github.com/cosmos/cosmos-sdk/blob/master/client/keys/add.go). * [**Transaction**](#transaction-commands) commands. * [**Query**](#query-commands) commands. @@ -77,12 +128,12 @@ err := executor.Execute() ### Transaction Commands -[Transactions](#./transactions.md) are objects wrapping [messages](../building-modules/messages-and-queries.md) that trigger state changes within modules. To enable the creation of transactions using the CLI interface, `TxCmd` should add the following commands: +[Transactions](#./transactions.md) are objects wrapping [messages](../building-modules/messages-and-queries.md) that trigger state changes. To enable the creation of transactions using the CLI interface, `TxCmd` needs to add the following commands: -* **Sign** command from the [`auth`](https://github.com/cosmos/cosmos-sdk/blob/master/docs/spec/auth) module, which signs messages in a transaction. To enable multisig, it should also add the `auth` module `MultiSign` command. Since every transaction requires some sort of signature in order to be valid, this command is necessary for every application. -* **Broadcast** command from the SDK client tools, which broadcasts transactions. -* **Send** command from the [`bank`](https://github.com/cosmos/cosmos-sdk/blob/master/docs/spec/bank) module, which is a transaction that allows accounts to send coins to one another, including gas and fees for transactions. -* All commands in each module the application is dependent on, retrieved by calling [`GetTxCmd()`](../building-modules/interfaces.md#GetTxCmd) on all the modules or using the Module Manager's [`AddTxCommands()`](../building-modules/module-manager.md) function. +* **Sign** [command](https://github.com/cosmos/cosmos-sdk/blob/master/x/auth/client/cli/tx_sign.go#L30-L83) from the [`auth`](https://github.com/cosmos/cosmos-sdk/blob/master/docs/spec/auth) module, the command that signs messages in a transaction. To enable multisig, add the `auth` module [`MultiSign`](https://github.com/cosmos/cosmos-sdk/blob/master/x/auth/client/cli/tx_multisign.go#L26-L151) command. Since every transaction requires some sort of signature in order to be valid, this command is necessary for every application. +* **Broadcast** [command](https://github.com/cosmos/cosmos-sdk/blob/master/client/context/broadcast.go) from the SDK client tools, which broadcasts transactions. +* **Send** [command](https://github.com/cosmos/cosmos-sdk/blob/master/x/bank/client/cli/tx.go#L31-L60) from the [`bank`](https://github.com/cosmos/cosmos-sdk/blob/master/docs/spec/bank) module, which is a transaction that allows accounts to send coins to one another, including gas and fees for transactions. +* All [module transaction commands](../building-modules/interfaces.md) the application is dependent on, retrieved by calling [`GetTxCmd()`](../building-modules/interfaces.md#GetTxCmd) on all the modules or using the Module Manager's [`AddTxCommands()`](../building-modules/module-manager.md) function. Here is an example of a `TxCmd` aggregating these subcommands from the [nameservice tutorial](https://cosmos.network/docs/tutorial). @@ -112,13 +163,13 @@ func txCmd(cdc *amino.Codec, mc []sdk.ModuleClients) *cobra.Command { ### Query Commands -[**Queries**](../building-modules/messages-and-queries.md#queries) are objects that allow users to retrieve information about the application's state. To enable basic queries, `QueryCmd` should add the following commands: +[**Queries**](../building-modules/messages-and-queries.md#queries) are objects that allow users to retrieve information about the application's state. To enable basic queries, `QueryCmd` needs to add the following commands: -* **QueryTx** and/or other transaction query commands from the `auth` module which allow the user to search for a transaction by inputting its hash, a list of tags, or a block height. These various queries allow users to see if transactions have been included in a block. -* **Account** command from the `auth` module, which displays the state (e.g. account balance) of an account given an address. -* **Validator** command from the SDK rpc client tools, which displays the validator set of a given height. -* **Block** command from the SDK rpc client tools, which displays the block data for a given height. -* All commands in each module the application is dependent on, retrieved by calling [`GetQueryCmd()`](../building-modules/interfaces.md#GetqueryCmd) on all the modules or using the Module Manager's `AddQueryCommands()` function. +* **QueryTx** and/or other transaction [query commands](https://github.com/cosmos/cosmos-sdk/blob/master/x/auth/client/cli/query.go) from the `auth` module which allow the user to search for a transaction by inputting its hash, a list of tags, or a block height. These queries allow users to see if transactions have been included in a block. +* **Account** [command](https://github.com/cosmos/cosmos-sdk/blob/master/x/auth/client/cli/query.go#L45-L73) from the `auth` module, which displays the state (e.g. account balance) of an account given an address. +* **Validator** [command](https://github.com/cosmos/cosmos-sdk/blob/master/client/rpc/validators.go) from the SDK rpc client tools, which displays the validator set of a given height. +* **Block** [command](https://github.com/cosmos/cosmos-sdk/blob/master/client/rpc/block.go) from the SDK rpc client tools, which displays the block data for a given height. +* All [module query commands](../building-modules/interfaces.md) the application is dependent on, retrieved by calling [`GetQueryCmd()`](../building-modules/interfaces.md#GetqueryCmd) on all the modules or using the Module Manager's `AddQueryCommands()` function. Here is an example of a `QueryCmd` aggregating subcommands, also from the nameservice tutorial (it is structurally identical to `TxCmd`): @@ -153,75 +204,49 @@ Flags are used to modify commands. Users can explicitly include them in commands A *persistent* flag (as opposed to a _local_ flag) added to a command transcends all of its children: subcommands will inherit the configured values for these flags. Additionally, all flags have default values when they are added to commands; some toggle an option off but others are empty values that the user needs to override to create valid commands. A flag can be explicitly marked as _required_ so that an error is automatically thrown if the user does not provide a value, but it is also acceptable to handle unexpected missing flags differently. -### Root Command Flags - -It is common to add a _persistent_ flag for `--chain-id`, the unique identifier of the blockchain the application pertains to, to the root command. Adding this flag makes sense as the chain ID should not be changing across commands in this application CLI. Here is what that looks like: +Every flag has a name the user types to use the flag. For example, the commonly used `--from` flag is declared as a constant in the SDK [flags](https://github.com/cosmos/cosmos-sdk/blob/master/client/flags/flags.go) file: ```go -rootCmd.PersistentFlags().String(client.FlagChainID, "", "Chain ID of tendermint node") +const FlagFrom = "from" ``` -### Transaction Flags - -To **create** a transaction, the user enters a `tx` command and provides several flags. These are the basic flags added to every command using the SDK `./client/flags` package [`PostCommands`](https://github.com/cosmos/cosmos-sdk/blob/master/client/flags/flags.go#L85-L116) function: - -* `--from` indicates which [account](../core/accounts-fees.md) the transaction originates from. This account is used to sign the transaction. -* `--gas` refers to how much [gas](../core/gas.md), which represents computational resources, Tx consumes. Gas is dependent on the computational needs of the transaction and is not precisely calculated until execution, but can be estimated by providing auto as the value for --gas. -* `--gas-adjustment` (optional) can be used to scale gas up in order to avoid underestimating. For example, users can specify their gas adjustment as 1.5 to use 1.5 times the estimated gas. -* `--gas-prices` specifies how much the user is willing pay per unit of gas, which can be one or multiple denominations of tokens. For example, --gas-prices=0.025uatom, 0.025upho means the user is willing to pay 0.025uatom AND 0.025upho per unit of gas. -* `--fees` specifies how much in fees the user is willing to pay in total. Note that the user only needs to provide either `gas-prices` or `fees`, but not both, because they can be derived from each other. -* `--generate-only` (optional) instructs the application to simply generate the unsigned transaction and output or write to a file. Without this flag, the transaction is created, signed, and broadcasted all in one command. -* `--dry-run` (optional), similar to `--generate-only`, instructs the application to ignore the `--gas` flag and simulate the transaction running without broadcasting. -* `--indent` (optional) adds an indent to the JSON response. -* `--memo` sends a memo along with the transaction. +The flag can be added to a command `cmd`, adding a default value and description: -For example, the following command creates a transaction to send 1000uatom from `sender-address` to `recipient-address`. The user is willing to pay 0.025uatom per unit gas but wants the transaction to be only generated offline (i.e. not broadcasted) and written, in JSON format, to the file `myUnsignedTx.json`. - -```bash -appcli tx send 1000uatom --from --gas auto -gas-prices 0.025uatom --generate-only > myUnsignedTx.json +```go +cmd.Flags().String(FlagFrom, "", "Name or address of private key with which to sign") ``` -To **sign** a transaction generated offline using the `--generate-only` flag, the user enters a `tx sign` command (by default, the transaction is automatically signed upon creation). There are four values for flags that must be provided if a transaction is expected to be signed: +The SDK client package includes a list of [flags](https://github.com/cosmos/cosmos-sdk/blob/master/client/flags/flags.go) that are commonly used across existing commands. -* `--from` specifies an address; the corresponding private key is used to sign the transaction. -* `--chain-id` specifies the unique identifier of the blockchain the transaction pertains to. -* `--sequence` is the value of a counter measuring how many transactions have been sent from the account. It is used to prevent replay attacks. -* `--account-number` is an identifier for the account. -* `--validate-signatures` (optional) instructs the process to sign the transaction and verify that all signatures have been provided. -* `--ledger` (optional) lets the user perform the action using a Ledger Nano S, which needs to be plugged in and unlocked. +### Root Command Flags -For example, the following command signs the inputted transaction, `myUnsignedTx.json`, and writes the signed transaction to the file `mySignedTx.json`. +It is common to add a _persistent_ flag for `--chain-id`, the unique identifier of the blockchain the application pertains to, to the root command. Adding this flag makes sense as the chain ID should not be changing across commands in this application CLI. Here is what that looks like: -```bash -appcli tx sign myUnsignedTx.json --from --chain-id --sequence --account-number > mySignedTx.json +```go +rootCmd.PersistentFlags().String(client.FlagChainID, "", "Chain ID of tendermint node") ``` -To **broadcast** a signed transaction generated offline, the user enters a `tx broadcast` command. Only one flag is required here: +### Transaction and Query Flags -* `--node` specifies which node to broadcast to. -* `--trust-node` (optional) indicates whether or not the node and its response proofs can be trusted. -* `--broadcast-mode` (optional) specifies when the process should return. Options include asynchronous (return immediately), synchronous (return after `CheckTx` passes), or block (return after block commit). +To create a transaction, users enter a `tx` command and provide several flags. The SDK `./client/flags` package [`PostCommands()`](https://github.com/cosmos/cosmos-sdk/blob/master/client/flags/flags.go#L85-L116) function adds a set of basic flags to every transaction command. For queries, the [`GetCommand()`](https://github.com/cosmos/cosmos-sdk/blob/master/client/flags/flags.go#L67-L82) function adds basic flags to query commands, such as the block `--height` to query from. -For example, the following command broadcasts the signed transaction, `mySignedTx.json` to a particular node. +For example, the following command creates a transaction to send 1000uatom from `sender-address` to `recipient-address`. The user is willing to pay 0.025uatom per unit gas but wants the transaction to be only generated offline (i.e. not broadcasted) and written, in JSON format, to the file `myUnsignedTx.json`. ```bash -appcli tx broadcast mySignedTx.json --node +appcli tx send 1000uatom --from --gas auto -gas-prices 0.025uatom --generate-only > myUnsignedTx.json ``` -### Query Flags - -Queries also have flags. These are the basic flags added to every command using the SDK `./client/flags` package [`GetCommand`](https://github.com/cosmos/cosmos-sdk/blob/master/client/flags/flags.go#L67-L82) function: +Here are the flags used: -* `--node` indicates which full-node to connect to. -* `--trust-node` (optional) represents whether or not the connected node is trusted. If the node is not trusted, all proofs in the responses are verified. -* `--indent` (optional) adds an indent to the JSON response. -* `--height` (optional) can be provided to query the blockchain at a specific height. -* `--ledger` (optional) lets the user perform the action using a Ledger Nano S. +* `--from` indicates which [account](../core/accounts-fees.md) the transaction originates from. This account is used to sign the transaction. +* `--gas` refers to how much [gas](../core/gas.md), which represents computational resources, Tx consumes. Gas is dependent on the computational needs of the transaction and is not precisely calculated until execution, but can be estimated by providing auto as the value for --gas. +* `--gas-prices` specifies how much the user is willing pay per unit of gas, which can be one or multiple denominations of tokens. For example, --gas-prices=0.025uatom, 0.025upho means the user is willing to pay 0.025uatom AND 0.025upho per unit of gas. +* `--generate-only` (optional) instructs the application to simply generate the unsigned transaction and output or write to a file. Without this flag, the transaction is created, signed, and broadcasted all in one command. ## Configurations -The last function to define is, `initConfig`, which should do exactly what it sounds like - initial configurations. To call this function, set it as a `PersistentPreRunE` function for the root command, so that it always executes before the main execution of the root command and any of its subcommands. `initConfig()` should do the following: +The last function to define is, `initConfig`, which does exactly what it sounds like - initial configurations. To call this function, set it as a `PersistentPreRunE` function for the root command, so that it always executes before the main execution of the root command and any of its subcommands. `initConfig()` does the following: 1. Read in the `config.toml` file. This same file is edited through `config` commands. 2. Use the [Viper](https://github.com/spf13/viper) to read in configurations from the file and set them. From d861ad71c324606c8badb91e9c303c534d24c725 Mon Sep 17 00:00:00 2001 From: Gloria Zhao Date: Tue, 13 Aug 2019 23:53:19 -0400 Subject: [PATCH 102/196] comments --- docs/building-modules/module-interfaces.md | 16 +++++++++ docs/interfaces/query-lifecycle.md | 38 +++++++++++++--------- docs/interfaces/rest.md | 35 ++++++++------------ 3 files changed, 52 insertions(+), 37 deletions(-) diff --git a/docs/building-modules/module-interfaces.md b/docs/building-modules/module-interfaces.md index e4a1ff940713..f1136e63d72c 100644 --- a/docs/building-modules/module-interfaces.md +++ b/docs/building-modules/module-interfaces.md @@ -183,8 +183,24 @@ type buyNameReq struct { Buyer string `json:"buyer"` } ``` + The `BaseReq` includes basic information that every request needs to have, similar to required flags in a CLI. All of these values, including `GasPrices` and `AccountNumber`, will be provided in the request body. The user will also need to specify the arguments `Name` and `Amount` fields in the body and `Buyer` will be provided by the user's address. +#### BaseReq + +`BaseReq` is a type defined in the SDK that encapsulates much of the transaction configurations similar to CLI command flags. Users must provide the information in the body of their requests. + +* `From` indicates which [account](../core/accounts-fees.md) the transaction originates from. This account is used to sign the transaction. +* `Memo` sends a memo along with the transaction. +* `ChainID` specifies the unique identifier of the blockchain the transaction pertains to. +* `AccountNumber` is an identifier for the account. +* `Sequence`is the value of a counter measuring how many transactions have been sent from the account. It is used to prevent replay attacks. +* `Gas` refers to how much [gas](../core/gas.md), which represents computational resources, Tx consumes. Gas is dependent on the transaction and is not precisely calculated until execution, but can be estimated by providing auto as the value for `Gas`. +* `GasAdjustment` can be used to scale gas up in order to avoid underestimating. For example, users can specify their gas adjustment as 1.5 to use 1.5 times the estimated gas. +* `GasPrices` specifies how much the user is willing pay per unit of gas, which can be one or multiple denominations of tokens. For example, --gas-prices=0.025uatom, 0.025upho means the user is willing to pay 0.025uatom AND 0.025upho per unit of gas. +* `Fees` specifies how much in [fees](../core/accounts-fees.md) the user is willing to pay in total. Note that the user only needs to provide either `gas-prices` or `fees`, but not both, because they can be derived from each other. +* `Simulate` instructs the application to ignore gas and simulate the transaction running without broadcasting. + ### Request Handlers Request handlers must be defined for both transaction and query requests. Handlers' arguments include a reference to the application's `codec` and the [`CLIContext`](../interfaces/query-lifecycle.md#clicontext) created in the user interaction. diff --git a/docs/interfaces/query-lifecycle.md b/docs/interfaces/query-lifecycle.md index 44026d16bc2d..7771e4398456 100644 --- a/docs/interfaces/query-lifecycle.md +++ b/docs/interfaces/query-lifecycle.md @@ -16,22 +16,30 @@ This document describes SDK interfaces in detail through the lifecycle of a quer ## Interfaces -A [**query**](../building-modules/messages-and-queries.md#queries) is a request for information made by users of applications. Users can query information about the network, the application itself, and application state directly from the application's stores or modules. +A [**query**](../building-modules/messages-and-queries.md#queries) is a request for information made by end-users of applications through an interface and processed by a full-node. Users can query information about the network, the application itself, and application state directly from the application's stores or modules. Note that queries are different from [transactions](../core/transactions.md) (view the lifecycle [here](../basics/tx-lifecycle.md)), particularly in that they do not require consensus to be processed; they can be fully handled by one full-node. For the purpose of explaining a query lifecycle, let's say `Query` is requesting a list of delegations made by a certain delegator address in the application called `app`. As to be expected, the [`staking`](https://github.com/cosmos/cosmos-sdk/blob/master/docs/spec/staking) module handles this query. But first, there are a few ways `Query` can be created by users. ### CLI -The main interface for an application is the command-line interface. Users connect to a full node and run the CLI directly from their machines. To create `Query` from their terminal, users type the following command: +The main interface for an application is the command-line interface. Users connect to a full-node and run the CLI directly from their machines - the CLI interacts directly with the full-node. To create `Query` from their terminal, users type the following command: -``` +```bash appcli query staking delegations ``` -To provide values such as `--chain-id` (the ID of the blockchain to make the query to), the user must use the `config` command to set them or provide them as flags. +Note that the general format is as follows: + +```bash +appcli query [moduleName] [command] --flag +``` + +To provide values such as `--node` (the full-node the CLI connects to), the user must use the `config` command to set them or provide them as flags. This query command was defined by the [`staking`](https://github.com/cosmos/cosmos-sdk/blob/master/docs/spec/staking) module developer and added to the list of subcommands by the application developer when creating the CLI. The code for this particular command can be found [here](https://github.com/cosmos/cosmos-sdk/blob/master/x/staking/client/cli/query.go#L253-L294). +The CLI understands a specific set of commands, defined in a hierarchical structure by the application developer: from the [root command](./cli.md#root-command) (`appcli`), the type of command (`query`), the module that contains the command (`staking`), and command itself (`delegations`). Thus, the CLI knows exactly which module handles this command and directly passes the call there. + ### REST Another interface through which users can make queries is through HTTP Requests to a [REST server](./rest.md#rest-server). The REST server contains, among other things, a [`CLIContext`](#clicontext) and [mux](./rest.md#gorilla-mux) router. The request looks like this: @@ -40,15 +48,15 @@ Another interface through which users can make queries is through HTTP Requests GET http://localhost:{PORT}/staking/delegators/{delegatorAddr}/delegations ``` -To provide values such as `--chain-id` (the ID of the blockchain to make the query to) that are required by [`baseReq`](./rest.md#basereq), the user must configure their local REST server with the values or provide them in the request body. +To provide values such as `--node` (the full-node the CLI connects to) that are required by [`baseReq`](./rest.md#basereq), the user must configure their local REST server with the values or provide them in the request body. -The router automatically routes the `Query` HTTP request to the staking module `delegatorDelegationsHandlerFn()` function (to see the handler itself, click [here]()). Since this function is defined within the module and thus has no inherent knowledge of the application `Query` belongs to, it takes in the application `codec` and `CLIContext` as parameters. +The router automatically routes the `Query` HTTP request to the staking module `delegatorDelegationsHandlerFn()` function (to see the handler itself, click [here](https://github.com/cosmos/cosmos-sdk/blob/master/x/staking/client/rest/query.go#L103-L106)). Since this function is defined within the module and thus has no inherent knowledge of the application `Query` belongs to, it takes in the application `codec` and `CLIContext` as parameters. -When users interact with the interfaces, the result is a CLI command or HTTP request. `Query` is then created when the command is executed or request handled. +To summarize, when users interact with the interfaces, they create a CLI command or HTTP request. `Query` is then created when the command is executed or HTTP request is handled. ## Request and Command Handling -The interactions from the users' perspective are a bit different, but the underlying functions are almost identical. This section describes how the CLI command or HTTP request is processed, up until the ABCI request is sent. This step of processing heavily involves a `CLIContext`. +The interactions from the users' perspective are a bit different, but the underlying functions are almost identical because they are implementations of the same command defined by the module developer. This step of processing heavily involves a `CLIContext`. ### CLIContext @@ -65,27 +73,27 @@ For full specification of the `CLIContext` type, click [here](https://github.com ### Parameters and Route Creation -The next step is to parse the command or request, extract the arguments, create a `queryRoute`, and encode everything. +The first step is to parse the command or request, extract the arguments, create a `queryRoute`, and encode everything. -In this case, `Query` contains an [address](../core/accounts-fees.md) `delegatorAddress` as its only argument. However, the request can only contain `[]byte`s, as it will be relayed to a consensus engine node that has no inherent knowledge of the application types. Thus, the `CLIContext` `codec` is used to marshal the address as the type [`QueryDelegatorParams`](https://github.com/cosmos/cosmos-sdk/blob/master/x/staking/types/querier.go#L30-L38). All query arguments (e.g. the [`staking`](https://github.com/cosmos/cosmos-sdk/blob/master/docs/spec/staking) module also has [`QueryValidatorParams`](https://github.com/cosmos/cosmos-sdk/blob/master/x/staking/types/querier.go#L45-L53) and [`QueryBondsParams`](https://github.com/cosmos/cosmos-sdk/blob/master/x/staking/types/querier.go#L59-L69)) have their own types that the application `codec` understands how to encode and decode. The module [`querier`](.//building-modules/querier.md) declares these types and the application registers the `codec`s. +**Arguments:** In this case, `Query` contains an [address](../core/accounts-fees.md) `delegatorAddress` as its only argument. However, the request can only contain `[]byte`s, as it will be relayed to a consensus engine node that has no inherent knowledge of the application types. Thus, the `CLIContext` `codec` is used to marshal the address as the type [`QueryDelegatorParams`](https://github.com/cosmos/cosmos-sdk/blob/master/x/staking/types/querier.go#L30-L38). All query arguments (e.g. the [`staking`](https://github.com/cosmos/cosmos-sdk/blob/master/docs/spec/staking) module also has [`QueryValidatorParams`](https://github.com/cosmos/cosmos-sdk/blob/master/x/staking/types/querier.go#L45-L53) and [`QueryBondsParams`](https://github.com/cosmos/cosmos-sdk/blob/master/x/staking/types/querier.go#L59-L69)) have their own types that the application `codec` understands how to encode and decode. The module [`querier`](.//building-modules/querier.md) declares these types and the application registers the `codec`s. -A `route` is also created for `Query` so that the application will understand which module to route the query to. [Baseapp](../core/baseapp.md#query-routing) will understand this query to be a `custom` query in the module `staking` with the type `QueryDelegatorDelegations`. Thus, the route will be `"custom/staking/delegatorDelegations"`. +**Route:** A `route` is also created for `Query` so that the application will understand which module to route the query to. [Baseapp](../core/baseapp.md#query-routing) will understand this query to be a `custom` query in the module `staking` with the type `QueryDelegatorDelegations`. Thus, the route will be `"custom/staking/delegatorDelegations"`. ### ABCI Query -The `CLIContext`'s main `Query` function takes the `route`, which is now called `path`, and arguments, now called `key`. It first retrieves the RPC Client (called the [**node**](../core/node.md)) configured by the user to relay this query to, and creates the `ABCIQueryOptions` (parameters formatted for the ABCI call). The node is then used to make the ABCI call, `ABCIQueryWithOptions()`. +The `CLIContext`'s main `Query` function takes the `route` and arguments. It first retrieves the RPC Client (called the [**node**](../core/node.md)) configured by the user to relay this query to, and creates the `ABCIQueryOptions` (parameters formatted for the ABCI call). The node is then used to make the ABCI call, `ABCIQueryWithOptions()`. ## Tendermint and ABCI -With a call to `ABCIQueryWithOptions()`, `Query` arrives at the consensus engine portion of its lifecycle. Nodes running the consensus engine (e.g. Tendermint Core) make ABCI calls to interact with the application. At this point, `Query` exists as an ABCI `RequestQuery` and the [ABCI Client](https://github.com/tendermint/tendermint/blob/master/abci/client/client.go#L16-L50) calls the ABCI method [`Query()`](https://tendermint.com/docs/spec/abci/abci.html#query) on the application. +With a call to `ABCIQueryWithOptions()`, `Query` is received by a full-node which will then process the request. Note that, while the RPC is made to the consensus engine (e.g. Tendermint Core) of a full-node, queries are not part of consensus and will not be broadcasted to the rest of the network, as they do not require anything the network needs to agree upon. Read more about ABCI Clients and Tendermint RPC in the Tendermint documentation [here](https://tendermint.com/rpc). ## Application Query Handling -[Baseapp](../core/baseapp.md) implements the ABCI [`Query()`](../core/baseapp.md#query) function and handles four different types of queries: `app`, `store`, `p2p`, and `custom`. The `queryRoute` is parsed such that the first string must be one of the four options, then the rest of the path is parsed within the subroutines handling each type of query. The first three types (`app`, `store`, `p2p`) are purely application-level and thus directly handled by Baseapp or the stores, but the `custom` query type requires Baseapp to route the query to a module's [querier](../building-modules/querier.md). +[baseapp](../core/baseapp.md) implements the ABCI [`Query()`](../core/baseapp.md#query) function and handles four different types of queries: `app`, `store`, `p2p`, and `custom`. The `queryRoute` is parsed such that the first string must be one of the four options, then the rest of the path is parsed within the subroutines handling each type of query. The first three types (`app`, `store`, `p2p`) are purely application-level and thus directly handled by Baseapp or the stores, but the `custom` query type requires Baseapp to route the query to a module's [querier](../building-modules/querier.md). -Since `Query` is a custom query type from the `staking` module, Baseapp first parses the path, then uses the `QueryRouter` to retrieve the corresponding querier. The querier is responsible for recognizing this query, retrieving the appropriate values from the application's stores, and returning a response. +Since `Query` is a custom query type from the `staking` module, Baseapp first parses the path, then uses the `QueryRouter` to retrieve the corresponding querier. The querier is responsible for recognizing this query, retrieving the appropriate values from the application's stores, and returning a response. Read more about queriers [here](../building-modules/querier.md). ## Response diff --git a/docs/interfaces/rest.md b/docs/interfaces/rest.md index 858c4b9420a4..5f187d01ea8c 100644 --- a/docs/interfaces/rest.md +++ b/docs/interfaces/rest.md @@ -7,16 +7,20 @@ ## Synopsis -This document describes how to create a REST interface for an SDK application. A separate document for creating module REST Routes can be found [here](#../module-interfaces.md#rest). +This document describes how to create a REST interface for an SDK application. A separate document for creating a module REST interface can be found [here](#../module-interfaces.md#rest). - [Application REST Interface](#application-rest-interface) -- [Request Types](#request-types) - [REST Server](#rest-server) - [Registering Routes](#registering-routes) +- [Request Types](#request-types) ## Application REST Interface -Building the REST Interface for an application involves creating a [REST server](./rest.md#rest-server) to route requests and output responses. The SDK has its own REST Server type used for [LCDs](../core/node.md) (light-client daemons). It has a `ServeCommand` that takes in an application's `codec` and `RegisterRoutes()` function, starts up a new REST Server, and registers routes using function provided from the application. To enable this command, it should be added as a subcommand of the root command `RootCmd` in the `main()` function of the CLI interface. +Building the REST Interface for an application involves creating a [REST server](./rest.md#rest-server) to route requests and output responses. The SDK has its own REST Server type used for [LCDs](../core/node.md) (light-client daemons). It has a `ServeCommand` that takes in an application's `codec` and `RegisterRoutes()` function, starts up a new REST Server, and registers routes using function provided from the application. To enable this command, it should be added as a subcommand of the root command in the `main()` function of the CLI interface: + +```go +rootCmd.AddCommand(lcd.ServeCommand(cdc, registerRoutes)) +``` Users can use the application CLI to start a new LCD, a local server through which they can securely interact with the application without downloading the entire state. The command entered by users would look something like this: @@ -24,26 +28,7 @@ Users can use the application CLI to start a new LCD, a local server through whi appcli rest-server --chain-id --trust-node ``` -## Request Types - -HTTP Request types are defined by the module interfaces for every type of transaction. The structs all include a base request `baseReq`, the name of the request, and any arguments for the transaction. - -### BaseReq -`BaseReq` is a type defined in the SDK that encapsulates much of the transaction configurations similar to CLI command flags. Users must provide the information in the body of their requests. - -* `From` indicates which [account](../core/accounts-fees.md) the transaction originates from. This account is used to sign the transaction. -* `Memo` sends a memo along with the transaction. -* `ChainID` specifies the unique identifier of the blockchain the transaction pertains to. -* `AccountNumber` is an identifier for the account. -* `Sequence`is the value of a counter measuring how many transactions have been sent from the account. It is used to prevent replay attacks. -* `Gas` refers to how much [gas](../core/gas.md), which represents computational resources, Tx consumes. Gas is dependent on the transaction and is not precisely calculated until execution, but can be estimated by providing auto as the value for `Gas`. -* `GasAdjustment` can be used to scale gas up in order to avoid underestimating. For example, users can specify their gas adjustment as 1.5 to use 1.5 times the estimated gas. -* `GasPrices` specifies how much the user is willing pay per unit of gas, which can be one or multiple denominations of tokens. For example, --gas-prices=0.025uatom, 0.025upho means the user is willing to pay 0.025uatom AND 0.025upho per unit of gas. -* `Fees` specifies how much in [fees](../core/accounts-fees.md) the user is willing to pay in total. Note that the user only needs to provide either `gas-prices` or `fees`, but not both, because they can be derived from each other. -* `Simulate` instructs the application to ignore gas and simulate the transaction running without broadcasting. - -Additionally, each request may contain arguments such as a specific address pertaining to the request. ## REST Server @@ -75,3 +60,9 @@ This function is specific to the application and passed in to the `ServeCommand` ```go rootCmd.AddCommand(lcd.ServeCommand(cdc, registerRoutes)) ``` + +## Request Types + +HTTP Request types are defined by the module interfaces for every type of transaction. The structs all include a base request [`baseReq`](../building-modules/module-interfaces.md#basereq), the name of the request, and any arguments for the transaction. + +Additionally, each request may contain arguments such as a specific address pertaining to the request. From a1546911e745d0f73505f38c99b1bcae4fe13d46 Mon Sep 17 00:00:00 2001 From: Gloria Zhao Date: Tue, 13 Aug 2019 23:54:43 -0400 Subject: [PATCH 103/196] minor edits --- docs/interfaces/query-lifecycle.md | 2 +- docs/interfaces/rest.md | 8 -------- 2 files changed, 1 insertion(+), 9 deletions(-) diff --git a/docs/interfaces/query-lifecycle.md b/docs/interfaces/query-lifecycle.md index 7771e4398456..e6a0fa9f4ff4 100644 --- a/docs/interfaces/query-lifecycle.md +++ b/docs/interfaces/query-lifecycle.md @@ -48,7 +48,7 @@ Another interface through which users can make queries is through HTTP Requests GET http://localhost:{PORT}/staking/delegators/{delegatorAddr}/delegations ``` -To provide values such as `--node` (the full-node the CLI connects to) that are required by [`baseReq`](./rest.md#basereq), the user must configure their local REST server with the values or provide them in the request body. +To provide values such as `--node` (the full-node the CLI connects to) that are required by [`baseReq`](../building-modules/module-interfaces.md#basereq), the user must configure their local REST server with the values or provide them in the request body. The router automatically routes the `Query` HTTP request to the staking module `delegatorDelegationsHandlerFn()` function (to see the handler itself, click [here](https://github.com/cosmos/cosmos-sdk/blob/master/x/staking/client/rest/query.go#L103-L106)). Since this function is defined within the module and thus has no inherent knowledge of the application `Query` belongs to, it takes in the application `codec` and `CLIContext` as parameters. diff --git a/docs/interfaces/rest.md b/docs/interfaces/rest.md index 5f187d01ea8c..bf4a010d0fa8 100644 --- a/docs/interfaces/rest.md +++ b/docs/interfaces/rest.md @@ -12,7 +12,6 @@ This document describes how to create a REST interface for an SDK application. A - [Application REST Interface](#application-rest-interface) - [REST Server](#rest-server) - [Registering Routes](#registering-routes) -- [Request Types](#request-types) ## Application REST Interface @@ -29,7 +28,6 @@ appcli rest-server --chain-id --trust-node ``` - ## REST Server A REST Server is used to receive and route HTTP Requests, obtain the results from the application, and return the response to the user. The REST Server defined by the SDK LCD package contains the following: @@ -60,9 +58,3 @@ This function is specific to the application and passed in to the `ServeCommand` ```go rootCmd.AddCommand(lcd.ServeCommand(cdc, registerRoutes)) ``` - -## Request Types - -HTTP Request types are defined by the module interfaces for every type of transaction. The structs all include a base request [`baseReq`](../building-modules/module-interfaces.md#basereq), the name of the request, and any arguments for the transaction. - -Additionally, each request may contain arguments such as a specific address pertaining to the request. From 3c7d671e0348493d953db2e6a362cabe3569d332 Mon Sep 17 00:00:00 2001 From: Gloria Zhao Date: Mon, 19 Aug 2019 19:31:02 -0700 Subject: [PATCH 104/196] better flow for query lifecycle --- docs/interfaces/query-lifecycle.md | 101 ++++++++++++++++++++++++----- 1 file changed, 85 insertions(+), 16 deletions(-) diff --git a/docs/interfaces/query-lifecycle.md b/docs/interfaces/query-lifecycle.md index e6a0fa9f4ff4..6c69aa454e68 100644 --- a/docs/interfaces/query-lifecycle.md +++ b/docs/interfaces/query-lifecycle.md @@ -8,13 +8,13 @@ This document describes SDK interfaces in detail through the lifecycle of a query, from the user interface to application stores and back. The query will be referred to as `Query`. -- [Interfaces](#interfaces) -- [Request and Command Handling](#request-and-command-handling) -- [Tendermint and ABCI](#tendermint-and-abci) +- [Query Creation](#query-creation) +- [Query Preparation](#query-preparation) +- [RPC](#rpc) - [Application Query Handling](#application-query-handling) - [Response](#response) -## Interfaces +## Query Creation A [**query**](../building-modules/messages-and-queries.md#queries) is a request for information made by end-users of applications through an interface and processed by a full-node. Users can query information about the network, the application itself, and application state directly from the application's stores or modules. Note that queries are different from [transactions](../core/transactions.md) (view the lifecycle [here](../basics/tx-lifecycle.md)), particularly in that they do not require consensus to be processed; they can be fully handled by one full-node. @@ -52,11 +52,11 @@ To provide values such as `--node` (the full-node the CLI connects to) that are The router automatically routes the `Query` HTTP request to the staking module `delegatorDelegationsHandlerFn()` function (to see the handler itself, click [here](https://github.com/cosmos/cosmos-sdk/blob/master/x/staking/client/rest/query.go#L103-L106)). Since this function is defined within the module and thus has no inherent knowledge of the application `Query` belongs to, it takes in the application `codec` and `CLIContext` as parameters. -To summarize, when users interact with the interfaces, they create a CLI command or HTTP request. `Query` is then created when the command is executed or HTTP request is handled. +To summarize, when users interact with the interfaces, they create a CLI command or HTTP request. `Query` now exists in one of these two forms, but needs to be transformed into an object understood by a full-node. -## Request and Command Handling +## Query Preparation -The interactions from the users' perspective are a bit different, but the underlying functions are almost identical because they are implementations of the same command defined by the module developer. This step of processing heavily involves a `CLIContext`. +The interactions from the users' perspective are a bit different, but the underlying functions are almost identical because they are implementations of the same command defined by the module developer. This step of processing happens within the CLI or REST server and heavily involves a `CLIContext`. ### CLIContext @@ -69,23 +69,69 @@ The first thing that is created in the execution of a CLI command is a `CLIConte * **Output Writer**: A [Writer](https://golang.org/pkg/io/#Writer) used to output the response. * **Configurations**: The flags configured by the user for this command, including `--height`, specifying the height of the blockchain to query and `--indent`, which indicates to add an indent to the JSON response. -For full specification of the `CLIContext` type, click [here](https://github.com/cosmos/cosmos-sdk/blob/master/client/context/context.go#L36-L59). +The `CLIContext` also contains various functions such as `Query()` which retrieves the RPC Client and makes an ABCI call to relay a query to a full-node. For full specification of the `CLIContext` type, click [here](https://github.com/cosmos/cosmos-sdk/blob/master/client/context/context.go#L36-L59). -### Parameters and Route Creation -The first step is to parse the command or request, extract the arguments, create a `queryRoute`, and encode everything. +The `CLIContext`'s primary role is to store data used during interactions with the end-user and provide methods to interact with this data - it is used before and after the query is processed by the full-node. Specifically, in handling `Query`, the `CLIContext` is utilized to encode the query parameters, retrieve the full-node, and write the output. Prior to being relayed to a full-node, the query needs to be encoded into a `[]byte` form, as full-nodes are application-agnostic and do not understand specific types. The full-node (RPC Client) itself is retrieved using the `CLIContext`, which knows which node the user CLI is connected to. The query is relayed to this full-node to be processed. Finally, the `CLIContext` contains a `Writer` to write output when the response is returned. These steps are further described in later sections. -**Arguments:** In this case, `Query` contains an [address](../core/accounts-fees.md) `delegatorAddress` as its only argument. However, the request can only contain `[]byte`s, as it will be relayed to a consensus engine node that has no inherent knowledge of the application types. Thus, the `CLIContext` `codec` is used to marshal the address as the type [`QueryDelegatorParams`](https://github.com/cosmos/cosmos-sdk/blob/master/x/staking/types/querier.go#L30-L38). All query arguments (e.g. the [`staking`](https://github.com/cosmos/cosmos-sdk/blob/master/docs/spec/staking) module also has [`QueryValidatorParams`](https://github.com/cosmos/cosmos-sdk/blob/master/x/staking/types/querier.go#L45-L53) and [`QueryBondsParams`](https://github.com/cosmos/cosmos-sdk/blob/master/x/staking/types/querier.go#L59-L69)) have their own types that the application `codec` understands how to encode and decode. The module [`querier`](.//building-modules/querier.md) declares these types and the application registers the `codec`s. +### Arguments and Route Creation -**Route:** A `route` is also created for `Query` so that the application will understand which module to route the query to. [Baseapp](../core/baseapp.md#query-routing) will understand this query to be a `custom` query in the module `staking` with the type `QueryDelegatorDelegations`. Thus, the route will be `"custom/staking/delegatorDelegations"`. +At this point in the lifecycle, the user has created a CLI command or HTTP Request with all of the data they wish to include in their `Query`. A `CLIContext` exists to assist in the rest of the `Query`'s journey. Now, the next step is to parse the command or request, extract the arguments, create a `queryRoute`, and encode everything. -### ABCI Query +#### Parse Arguments -The `CLIContext`'s main `Query` function takes the `route` and arguments. It first retrieves the RPC Client (called the [**node**](../core/node.md)) configured by the user to relay this query to, and creates the `ABCIQueryOptions` (parameters formatted for the ABCI call). The node is then used to make the ABCI call, `ABCIQueryWithOptions()`. +In this case, `Query` contains an [address](../core/accounts-fees.md) `delegatorAddress` as its only argument. However, the request can only contain `[]byte`s, as it will be relayed to a consensus engine node that has no inherent knowledge of the application types. Thus, the `CLIContext` `codec` is used to marshal the address as the type [`QueryDelegatorParams`](https://github.com/cosmos/cosmos-sdk/blob/master/x/staking/types/querier.go#L30-L38). All query arguments (e.g. the [`staking`](https://github.com/cosmos/cosmos-sdk/blob/master/docs/spec/staking) module also has [`QueryValidatorParams`](https://github.com/cosmos/cosmos-sdk/blob/master/x/staking/types/querier.go#L45-L53) and [`QueryBondsParams`](https://github.com/cosmos/cosmos-sdk/blob/master/x/staking/types/querier.go#L59-L69)) have their own types that the application `codec` understands how to encode and decode. The module [`querier`](.//building-modules/querier.md) declares these types and the application registers the `codec`s. -## Tendermint and ABCI +Here is what the code looks like for the CLI command: -With a call to `ABCIQueryWithOptions()`, `Query` is received by a full-node which will then process the request. Note that, while the RPC is made to the consensus engine (e.g. Tendermint Core) of a full-node, queries are not part of consensus and will not be broadcasted to the rest of the network, as they do not require anything the network needs to agree upon. +```go +delAddr, err := sdk.AccAddressFromBech32(args[0]) +bz, err := cdc.MarshalJSON(types.NewQueryDelegatorParams(delAddr)) +``` + +Here is what the code looks like for the HTTP Request: + +```go +vars := mux.Vars(r) +bech32delegator := vars["delegatorAddr"] +delegatorAddr, err := sdk.AccAddressFromBech32(bech32delegator) +cliCtx, ok := rest.ParseQueryHeightOrReturnBadRequest(w, cliCtx, r) +if !ok { + return +} +params := types.NewQueryDelegatorParams(delegatorAddr) +``` + +#### Query Route Creation + +Important to note is that there will never be a "query" object created for `Query`; the SDK actually takes a simpler approach. Instead of an object, all the full-node needs to process a query is its `route` which specifies exactly which module to route the query to and the name of this query type. The `route` will be passed to the application baseapp, then module, then [querier](../building-modules/querier.md), and each will understand the `route` and pass it to the appropriate next step. [baseapp](../core/baseapp.md#query-routing) will understand this query to be a `custom` query in the module `staking`, and the `staking` module querier supports the type `QueryDelegatorDelegations`. Thus, the route will be `"custom/staking/delegatorDelegations"`. + +Here is what the code looks like: + +```go +route := fmt.Sprintf("custom/%s/%s", queryRoute, types.QueryDelegatorDelegations) +``` + +Now, `Query` exists as a set of encoded arguments and a route to a specific module and its query type. It is ready to be relayed to a full-node. + +#### ABCI Query Call + +The `CLIContext` has a `Query()` function used to retrieve the pre-configured node and relay a query to it; the function takes the query `route` and arguments as parameters. It first retrieves the RPC Client (called the [**node**](../core/node.md)) configured by the user to relay this query to, and creates the `ABCIQueryOptions` (parameters formatted for the ABCI call). The node is then used to make the ABCI call, `ABCIQueryWithOptions()`. + +Here is what the code looks like (for full specification of all `CLIContext` query functionality, click [here](https://github.com/cosmos/cosmos-sdk/blob/master/client/context/query.go)): + +```go +node, err := ctx.GetNode() +opts := rpcclient.ABCIQueryOptions{ + Height: ctx.Height, + Prove: !ctx.TrustNode, +} +result, err := node.ABCIQueryWithOptions(path, key, opts) +``` + +## RPC + +With a call to `ABCIQueryWithOptions()`, `Query` is received by a [full-node](../core/encoding.md) which will then process the request. Note that, while the RPC is made to the consensus engine (e.g. Tendermint Core) of a full-node, queries are not part of consensus and will not be broadcasted to the rest of the network, as they do not require anything the network needs to agree upon. Read more about ABCI Clients and Tendermint RPC in the Tendermint documentation [here](https://tendermint.com/rpc). @@ -103,10 +149,33 @@ Since `Query()` is an ABCI function, Baseapp returns the response as an [`abci.R The application [`codec`](../core/encoding.md) is used to unmarshal the response to a JSON and the `CLIContext` prints the output to the command line, applying any configurations such as `--indent`. +Here is what the code looks like: + +```go +res, _, err := cliCtx.QueryWithData(route, bz) +var resp types.DelegationResponses +if err := cdc.UnmarshalJSON(res, &resp); err != nil { + return err +} +return cliCtx.PrintOutput(resp) +``` + ### REST Response The [REST server](./rest.md#rest-server) uses the `CLIContext` to format the response properly, then uses the HTTP package to write the appropriate response or error. +Here is what the code looks like: + +```go +res, height, err := cliCtx.QueryWithData(endpoint, bz) +if err != nil { + rest.WriteErrorResponse(w, http.StatusInternalServerError, err.Error()) + return +} +cliCtx = cliCtx.WithHeight(height) +rest.PostProcessResponse(w, cliCtx, res) +``` + ## Next Read about how to build a [Command-Line Interface](./cli.md), or a [REST Interface](./rest.md). From 463bffa63416969bf750b8597ee54e502c7f1ecf Mon Sep 17 00:00:00 2001 From: Gloria Zhao Date: Wed, 21 Aug 2019 14:28:34 -0700 Subject: [PATCH 105/196] checkout master-docs files --- docs/.vuepress/config.js | 3 +- docs/basics/app-anatomy.md | 94 +++++++--------- docs/building-modules/intro.md | 29 ++--- docs/core/baseapp.md | 165 +++++++++++------------------ docs/core/node.md | 2 +- docs/intro/README.md | 15 +-- docs/intro/sdk-app-architecture.md | 26 ++--- docs/intro/why-app-specific.md | 39 +++---- 8 files changed, 155 insertions(+), 218 deletions(-) diff --git a/docs/.vuepress/config.js b/docs/.vuepress/config.js index 602d20781420..9ee6a31059c5 100644 --- a/docs/.vuepress/config.js +++ b/docs/.vuepress/config.js @@ -31,8 +31,7 @@ module.exports = { "/intro/", "/intro/why-app-specific", "/intro/sdk-app-architecture", - "/intro/sdk-design", - "/intro/ocap" + "/intro/sdk-design" ] }, { diff --git a/docs/basics/app-anatomy.md b/docs/basics/app-anatomy.md index 2e4613c5e8b6..dc58e389342a 100644 --- a/docs/basics/app-anatomy.md +++ b/docs/basics/app-anatomy.md @@ -55,9 +55,9 @@ Blockchain Node | | Consensus | | The blockchain full-node presents itself as a binary, generally suffixed by `-d` for "daemon" (e.g. `appd` for `app` or `gaiad` for `gaia`). This binary is built by running a simple `main.go` function placed in `cmd/appd/`. This operation usually happens through the [Makefile](#dependencies-and-makefile). -To learn more about the `main.go` function, [click here](../core/node.md#main-function). +To learn more about the `main.go` function, [click here](./node.md#main-function). -Once the main binary is built, the node can be started by running the `start` command. The core logic behind the `start` command is implemented in the SDK itself in the [`/server/start.go`](https://github.com/cosmos/cosmos-sdk/blob/master/server/start.go) file. The main [`start` command function](https://github.com/cosmos/cosmos-sdk/blob/master/server/start.go#L31) takes a [`context`](https://godoc.org/github.com/cosmos/cosmos-sdk/client/context) and [`appCreator`](#constructor-function-(`appCreator`)) as arguments. The `appCreator` is a constructor function for the SDK application, and is used in the starting process of the full-node. +Once the main binary is built, the node can be started by running the `start` command. The core logic behind the `start` command is implemented in the SDK itself in the [`/server/start.go`](https://github.com/cosmos/cosmos-sdk/blob/master/server/start.go) file. The main [`start` command function](https://github.com/cosmos/cosmos-sdk/blob/master/server/start.go#L31) takes a [`context`](https://godoc.org/github.com/cosmos/cosmos-sdk/client/context) and [`appCreator`](<#constructor-function-(`appCreator`)>) as arguments. The `appCreator` is a constructor function for the SDK application, and is used in the starting process of the full-node. The `start` command function primarily does three things: @@ -65,8 +65,6 @@ The `start` command function primarily does three things: 2. Initialize the state-machine with the latest known state, extracted from the `db` stored in the `~/.appd/data` folder. At this point, the state-machine is at height `appBlockHeight`. 3. Create and start a new Tendermint instance. Among other things, the node will perform a handshake with its peers. It will get the latest `blockHeight` from them, and replay blocks to sync to this height if it is greater than the local `appBlockHeight`. If `appBlockHeight` is `0`, the node is starting from genesis and Tendermint sends an `InitChain` message via the ABCI to the `app`, which triggers the [`InitChainer`](#initchainer). -To learn more about the `start` command, [click here](../core/node.md#start-command). - ## Core Application File In general, the core of the state-machine is defined in a file called `app.go`. It mainly contains the **type definition of the application** and functions to **create and initialize it**. @@ -75,11 +73,11 @@ In general, the core of the state-machine is defined in a file called `app.go`. The first thing defined in `app.go` is the `type` of the application. It is generally comprised of the following parts: -- **A reference to [`baseapp`](../core/baseapp.md).** The custom application defined in `app.go` is an extension of the `baseapp` type. `baseapp` implements most of the core logic for the application, including all the [ABCI methods](https://tendermint.com/docs/spec/abci/abci.html#overview) and the routing logic. When a transaction is relayed by Tendermint to the application, the latter uses `baseapp`'s methods to route them to the appropriate module. -- **A list of store keys**. The [store](../core/store.md), which contains the entire state, is implemented as a multistore (i.e. a store of stores) in the Cosmos SDK. Each module uses one or multiple stores in the multistore to persist their part of the state. These stores can be accessed with specific keys that are declared in the `app` type. These keys, along with the `keepers`, are at the heart of the [object-capabilities model](../intro/ocap.md) of the Cosmos SDK. -- **A list of module's `keepers`.** Each module defines an abstraction called [`keeper`](../building-modules/keeper.md), which handles reads and writes for this module's store(s). The `keeper`'s methods of one module can be called from other modules (if authorized), which is why they are declared in the application's type and exported as interfaces to other modules so that they are only allowed to access the authorized functions. -- **A reference to a [`codec`](../core/encoding.md).** The Cosmos SDK gives developers the freedom to choose the encoding framework for their application. The application's `codec` is used to serialize and deserialize data structures in order to store them, as stores can only persist `[]bytes`. The `codec` must be deterministic. The default codec is [amino](./amino.md). -- **A reference to a [module manager](../building-modules/module-manager.md#manager)** and a [basic module manager](../building-modules/module-manager.md#basicmanager). The module manager is an object that contains a list of the application's module. It facilitates operations related to these modules, like registering [`routes`](./baseapp.md#routing), [query routes](#./baseapp.md#query-routing) or setting the order of execution between modules for various functions like [`InitChainer`](#initchainer), [`BeginBlocker` and `EndBlocker`](#beginblocker-and-endblocker). +- **A reference to [`baseapp`](./baseapp.md).** The custom application defined in `app.go` is an extension of the `baseapp` type. `baseapp` implements most of the core logic for the application, including all the [ABCI methods](https://tendermint.com/docs/spec/abci/abci.html#overview) and the routing logic. When a transaction is relayed by Tendermint to the application, the latter uses `baseapp`'s methods to route them to the appropriate module. +- **A list of store keys**. The [store](./store.md), which contains the entire state, is implemented as a multistore (i.e. a store of stores) in the Cosmos SDK. Each module uses one or multiple stores in the multistore to persist their part of the state. These stores can be accessed with specific keys that are declared in the `app` type. These keys, along with the `keepers`, are at the heart of the [object-capabilities model](../intro/ocap.md) of the Cosmos SDK. +- **A list of module's `keepers`.** Each module defines an abstraction called `keeper`, which handles reads and writes for this module's store(s). The `keeper`'s methods of one module can be called from other modules (if authorized), which is why they are declared in the application's type and exported as interfaces to other modules so that they are only allowed to access the authorized functions. +- **A reference to a `codec`.** The Cosmos SDK gives developers the freedom to choose the encoding framework for their application. The application's `codec` is used to serialize and deserialize data structures in order to store them, as stores can only persist `[]bytes`. The `codec` must be deterministic. The default codec is [amino](./amino.md). +- **A reference to a [module manager](./modules.md#module-manager)**. The module manager is an object that contains a list of the application's module. It facilitates operations related to these modules, like registering [`routes`](./baseapp.md#routing), [query routes](#./baseapp.md#query-routing) or setting the order of execution between modules for various functions like [`InitChainer`](#initchainer), [`BeginBlocker` and `EndBlocker`](#beginblocker-and-endblocker). You can see an example of application type definition [here](https://github.com/cosmos/gaia/blob/master/app/app.go#L73-L107). @@ -87,17 +85,16 @@ You can see an example of application type definition [here](https://github.com/ This function constructs a new application of the type defined above. It is called every time the full-node is started with the [`start`](https://github.com/cosmos/cosmos-sdk/blob/master/server/start.go#L117) command. Here are the main actions performed by this function: -- Instantiate a new [`codec`](../core/encoding.md) and initialize the `codec` of each of the application's module using the [basic manager](../building-modules/module-manager.md#basicmanager) - Instantiate a new application with a reference to a `baseapp` instance, a codec and all the appropriate store keys. - Instantiate all the [`keeper`s](#keeper) defined in the application's `type` using the `NewKeeper` function of each of the application's modules. Note that `keepers` must be instantiated in the correct order, as the `NewKeeper` of one module might require a reference to another module's `keeper`. -- Instantiate the application's [module manager](../building-modules/module-manager.md#manager) with the [`AppModule`](#application-module-interface) object of each of the application's modules. -- With the module manager, initialize the application's [`routes`](../core/baseapp.md#routing) and [query routes](../core/baseapp.md#query-routing). When a transaction is relayed to the application by Tendermint via the ABCI, it is routed to the appropriate module's [`handler`](#handler) using the routes defined here. Likewise, when a query is received by the application, it is routed to the appropriate module's [`querier`](#querier) using the query routes defined here. -- With the module manager, register the [application's modules' invariants](./invariants.md). Invariants are variables (e.g. total supply of a token) that are evaluated at the end of each block. The process of checking invariants is done via a special module called the [`InvariantsRegistry`](../building-modules/invariants.md#invariant-registry). The value of the invariant should be equal to a predicted value defined in the module. Should the value be different than the predicted one, special logic defined in the invariant registry will be triggered (usually the chain is halted). This is useful to make sure no critical bug goes unnoticed and produces long-lasting effects that would be hard to fix. -- With the module manager, set the order of execution between the `InitGenesis`, `BegingBlocker` and `EndBlocker` functions of each of the [application's modules](#application-module-interface). Note that not all modules implement these functions. +- Instantiate the application's [module manager](./module-manager.md) with the [`AppModule`](#application-module-interface) object of each of the application's modules. +- With the module manager, initialize the application's [`routes`](./baseapp.md#routing) and [query routes](./baseapp.md#query-routing). When a transaction is relayed to the application by Tendermint via the ABCI, it is routed to the appropriate module's [`handler`](#handler) using the routes defined here. Likewise, when a query is received by the application, it is routed to the appropriate module's [`querier`](#querier) using the query routes defined here. +- With the module manager, register the [application's modules' invariants](./invariants.md). Invariants are variables (e.g. total supply of a token) that are evaluated at the end of each block. The process of checking invariants is done via a special module called the [`InvariantsRegistry`](./invariants.md#invariant-registry). The value of the invariant should be equal to a predicted value defined in the module. Should the value be different than the predicted one, special logic defined in the invariant registry will be triggered (usually the chain is halted). This is useful to make sure no critical bug goes unnoticed and produces long-lasting effects that would be hard to fix. +- With the module manager, set the order of execution between the `InitGenesis`, `BegingBlocker` and `EndBlocker` functions of each of the [application's modules](#application-module-interface). Note that not all modules implement these functions. - Set the remainer of application's parameters: - + [`InitChainer`](#initchainer): used to initialize the application when it is first started. - + [`BeginBlocker`, `EndBlocker`](#beginblocker-and-endlbocker): called at the beginning and the end of every block). - + [`anteHandler`](../core/baseapp.md#antehandler): used to handle fees and signature verification. + - [`InitChainer`](#initchainer): used to initialize the application when it is first started. + - [`BeginBlocker`, `EndBlocker`](#beginblocker-and-endlbocker): called at the beginning and the end of every block). + - [`anteHandler`](#baseapp.md#antehandler): used to handle fees and signature verification. - Mount the stores. - Return the application. @@ -107,7 +104,7 @@ You can see an example of application constructor [here](https://github.com/cosm ### InitChainer -The `InitChainer` is a function that initializes the state of the application from a [genesis file](../core/genesis.md) (i.e. token balances of genesis accounts). It is called when the application receives the `InitChain` message from the Tendermint engine, which happens when the node is started at `appBlockHeight == 0` (i.e. on genesis). The application must set the `InitChainer` in its constructor via the [`SetInitChainer`](https://godoc.org/github.com/cosmos/cosmos-sdk/baseapp#BaseApp.SetInitChainer) method. +The `InitChainer` is a function that initializes the state of the application from a [genesis file](./genesis.md) (i.e. token balances of genesis accounts). It is called when the application receives the `InitChain` message from the Tendermint engine, which happens when the node is started at `appBlockHeight == 0` (i.e. on genesis). The application must set the `InitChainer` in its constructor via the [`SetInitChainer`](https://godoc.org/github.com/cosmos/cosmos-sdk/baseapp#BaseApp.SetInitChainer) method. In general, the `InitChainer` is mostly composed of the `InitGenesis` function of each of the application's modules. This is done by calling the `InitGenesis` function of the module manager, which in turn will call the `InitGenesis` function of each of the modules it contains. Note that the order in which the modules' `InitGenesis` functions must be called has to be set in the module manager using the `SetOrderInitGenesis` method. This is done in the [application's constructor](#application-constructor), and the `SetOrderInitGenesis` has to be called before the `SetInitChainer`. @@ -119,40 +116,39 @@ The SDK offers developers the possibility to implement automatic execution of co In general, the `BeginBlocker` and `EndBlocker` functions are mostly composed of the `BeginBlock` and `EndBlock` functions of each of the application's modules. This is done by calling the `BeginBlock` and `EndBlock` functions of the module manager, which in turn will call the `BeginBLock` and `EndBlock` functions of each of the modules it contains. Note that the order in which the modules' `BegingBlock` and `EndBlock` functions must be called has to be set in the module manager using the `SetOrderBeginBlock` and `SetOrderEndBlock` methods respectively. This is done in the [application's constructor](#application-constructor), and the `SetOrderBeginBlock` and `SetOrderEndBlock` methods have to be called before the `SetBeginBlocker` and `SetEndBlocker` functions. -As a sidenote, it is important to remember that application-specific blockchains are deterministic. Developers must be careful not to introduce non-determinism in `BeginBlocker` or `EndBlocker`, and must also be careful not to make them too computationally expensive, as [gas](./accounts-fees-gas.md/gas) does not constrain the cost of `BeginBlocker` and `EndBlocker` execution. +As a sidenote, it is important to remember that application-specific blockchains are deterministic. Developers must be careful not to introduce non-determinism in `BeginBlocker` or `EndBlocker`, and must also be careful not to make them too computationally expensive, as gas does not constrain the cost of `BeginBlocker` and `EndBlocker` execution. You can see an example of `BeginBlocker` and `EndBlocker` functions [here](https://github.com/cosmos/gaia/blob/master/app/app.go#L224-L232). ### Register Codec -The `MakeCodec` function is the last important function of the `app.go` file. The goal of this function is to instantiate a codec `cdc` (e.g. [amino](./amino.md)) initiliaze the codec of the SDK and each of the application's modules using the `RegisterCodec` function. +The `MakeCodec` function is the last important function of the `app.go` file. The goal of this function is to instantiate a codec `cdc` (e.g. amino) initialize the codec of the SDK and each of the application's modules using the `RegisterCodec` function. -To register the application's modules, the `MakeCodec` function calls `RegisterCodec` on `ModuleBasics`. `ModuleBasics` is a [basic manager](../building-modules/module-manager.md#basicmanager) which lists all of the application's modules. It is instanciated in the `init()` function, and only serves to easily register non-dependant elements of application's modules (such as codec). To learn more about the basic module manager, click [here](../building-modules/module-manager.md#basicmanager). +To register the application's modules, the `MakeCodec` function calls `RegisterCodec` on `ModuleBasics`. `ModuleBasics` is a basic manager which lists all of the application's modules. It is instantiated in the `init()` function, and only serves to easily register non-dependent elements of application's modules (such as codec). To learn more about the basic module manager,. You can see an example of a `MakeCodec` [here](https://github.com/cosmos/gaia/blob/master/app/app.go#L64-L70) ## Modules -Modules are the heart and soul of an SDK application. They can be considered as state-machines within the state-machine. When a transaction is relayed from the underlying Tendermint engine via the ABCI to the application, it is routed by [`baseapp`](../core/baseapp.md) to the appropriate module in order to be processed. This paradigm enables developers to easily build complex state-machines, as most of the modules they need often already exist. For developers, most of the work involved in building an SDK application revolves around building custom modules required by their application that do not exist, and integrating them with modules that do already exist into one coherent application. In the application directory, the standard practice is to store modules in the `x/` folder (not to be confused with the SDK's `x/` folder, which contains already-built modules). - -To learn more about modules, [click here](./modules.md) +Modules are the heart and soul of an SDK application. They can be considered as state-machines within the state-machine. When a transaction is relayed from the underlying Tendermint engine via the ABCI to the application, it is routed by `baseapp` to the appropriate module in order to be processed. This paradigm enables developers to easily build complex state-machines, as most of the modules they need often already exist. For developers, most of the work involved in building an SDK application revolves around building custom modules required by their application that do not exist, and integrating them with modules that do already exist into one coherent application. In the application directory, the standard practice is to store modules in the `x/` folder (not to be confused with the SDK's `x/` folder, which contains already-built modules). ### Application Module Interface -Modules implement two interfaces defined in the Cosmos SDK, [`AppModuleBasic`](../building-modules/module-manager.md#appmodulebasic) and [`AppModule`](../building-modules/module-manager.md#appmodule). The former implements basic non-dependant elements of the module, such as the `codec`, while the latter handles the bulk of the module methods (including methods that require references to other modules' `keeper`s). Both the `AppModule` and `AppModuleBasic` types are defined in a file called `./module.go`. +Modules implement two interfaces defined in the Cosmos SDK, [`AppModuleBasic`](https://github.com/cosmos/cosmos-sdk/blob/master/types/module/module.go#L44-L57) and [`AppModule`](https://github.com/cosmos/cosmos-sdk/blob/master/types/module/module.go#L44-L57). The former implements basic non-dependant elements of the module, such as the `codec`, while the latter handles the bulk of the module methods (including methods that require references to other modules' `keeper`s). Both the `AppModule` and `AppModuleBasic` types are defined in a file called `./module.go`. -`AppModule` exposes a collection of useful methods on the module that facilitates the composition of modules into a coherent application. These methods are are called from the `module manager`(../building-modules/module-manager.md#manager), which manages the application's collection of modules. +`AppModule` exposes a collection of useful methods on the module that facilitates the composition of modules into a coherent application. Important methods include: -To learn more about the application module interface, [click here](./modules.md#application-module-interface). -======= -To learn more about the application module interface, [click here](../building-modules/module-manager.md#application-module-interfaces). ->>>>>>> workinnn +- `Route()` and `QueryRoute()`: These methods the name of the route and querier route for the module, for [messages](#message-types) to be routed to the module's [`handler`](#handler) and queries to be routes to the module's [`querier`](#querier). +- `NewHandler()` and `NewQuerierHandler()`: These methods return a `handler` and `querierHandler` respectively, in order to process a message or a query once they are routed. +- `BeginBlock()`, `EndBlock()` and `InitGenesis()`: These methods are executed respectively at the beginning of each block, at the end of each block and at the start of the chain. They implement special logic the module requires to be triggered during those events. For example, the `EndBlock` function is frequently used by modules where voting occurs to tally the result of the votes. +- `RegisterInvariants()`: This method registers the [invariants](./invariants.md) for the module. Invariants are checked at the end of every block to make sure no unpredicted behaviour is occuring. +- `AppModule`'s methods are called from the `module manager`, which manages the application's collection of modules. ### Message Types -A message is a custom type defined by each module that implements the [`message`](../building-modules/messages-and-queries.md#messages) interface. Each [`transaction`](../core/transaction.md) contains one or multiple `messages`. When a valid block of transactions is received by the full-node, Tendermint relays each one to the application via [`DeliverTx`](https://tendermint.com/docs/app-dev/abci-spec.html#delivertx). Then, the application handles the transaction: +A message is a custom type defined by each module that implements the [`message`](https://github.com/cosmos/cosmos-sdk/blob/master/types/tx_msg.go#L8-L29) interface. Each `transaction` contains one or multiple `messages`. When a valid block of transactions is received by the full-node, Tendermint relays each one to the application via [`DeliverTx`](https://tendermint.com/docs/app-dev/abci-spec.html#delivertx). Then, the application handles the transaction: -1. Upon receiving the transaction, the application first unmarshalls it from `[]bytes`. +1. Upon receiving the transaction, the application first unmarshals it from `[]bytes`. 2. Then, it verifies a few things about the transaction like [fee payment and signatures](#accounts-fees-gas.md) before extracting the message(s) contained in the transaction. 3. With the [`Type()`](https://github.com/cosmos/cosmos-sdk/blob/master/types/tx_msg.go#L16) method, `baseapp` is able to know which modules defines the message. It is then able to route it to the appropriate module's [handler](#handler) in order for the message to be processed. 4. If the message is successfully processed, the state is updated. @@ -161,24 +157,20 @@ For a more detailed look at a transaction lifecycle, click [here](./tx-lifecycle Module developers create custom message types when they build their own module. The general practice is to prefix the type declaration of the message with `Msg`. For example, the message type [`MsgSend`](https://github.com/cosmos/cosmos-sdk/blob/master/x/bank/types/msgs.go#L10-L15) allows users to transfer tokens. It is processed by the handler of the `bank` module, which ultimately calls the `keeper` of the `auth` module in order to update the state. -To learn more about messages, [click here](../building-modules/messages-and-queries.md#messages). - ### Handler -The [`handler`](../building-modules/handler.md) refers to the part of the module responsible for processing the message after it is routed by `baseapp`. `handler` functions of modules (except those of the `auth` module) are only executed if the transaction is relayed from Tendermint by the `DeliverTx` ABCI message. If the transaction is relayed by `CheckTx`, only stateless checks and fee-related (i.e. `auth` module-related) stateful checks are performed. To better understand the difference between `DeliverTx`and `CheckTx`, as well as the difference between stateful and stateless checks, click [here](./tx-lifecycle.md). +The `handler` refers to the part of the module responsible for processing the message after it is routed by `baseapp`. `handler` functions of modules (except those of the `auth` module) are only executed if the transaction is relayed from Tendermint by the `DeliverTx` ABCI message. If the transaction is relayed by `CheckTx`, only stateless checks and fee-related (i.e. `auth` module-related) stateful checks are performed. To better understand the difference between `DeliverTx`and `CheckTx`, as well as the difference between stateful and stateless checks, click [here](./tx-lifecycle.md). The handler of a module is generally defined in a file called `handler.go` and consists of: -- A **switch function** `NewHandler` to route the message to the appropriate handler function. This function returns a `handler` function, and is registered in the [`AppModule`](#application-module-interface) to be used in the application's module manager to initialize the [application's router](../core/baseapp.md#routing). See an example of such a switch [here](https://github.com/cosmos/sdk-application-tutorial/blob/master/x/nameservice/handler.go#L10-L22). +- A **switch function** `NewHandler` to route the message to the appropriate handler function. This function returns a `handler` function, and is registered in the [`AppModule`](#application-module-interface) to be used in the application's module manager to initialize the application's router. See an example of such a switch [here](https://github.com/cosmos/sdk-application-tutorial/blob/master/x/nameservice/handler.go#L10-L22). - **One handler function for each message type defined by the module**. Developers write the message processing logic in these functions. This generally involves doing stateful checks to ensure the message is valid and calling [`keeper`](#keeper)'s methods to update the state. Handler functions return a result of type [`sdk.Result`](https://github.com/cosmos/cosmos-sdk/blob/master/types/result.go#L14-L37), which informs the application on whether the message was successfully processed. -To learn more about handlers, [click here](../building-modules/handler.md). - ### Keeper -[`Keepers`](../building-module/keeper.md) are the gatekeepers of their module's store(s). To read or write in a module's store, it is mandatory to go through one of its `keeper`'s methods. This is ensured by the [object-capabilities](../core/ocap.md) model of the Cosmos SDK. Only objects that hold the key to a store can access it, and only the module's `keeper` should hold the key(s) to the module's store(s). +`Keepers` are the gatekeepers of their module's store(s). To read or write in a module's store, it is mandatory to go through one of its `keeper`'s methods. This is ensured by the [object-capabilities](./ocap.md) model of the Cosmos SDK. Only objects that hold the key to a store can access it, and only the module's `keeper` should hold the key(s) to the module's store(s). `Keepers` are generally defined in a file called `keeper.go`. It contains the `keeper`'s type definition and methods. @@ -192,18 +184,14 @@ Along with the type definition, the next important component of the `keeper.go` The rest of the file defines the `keeper`'s methods, primarily getters and setters. You can check an example of a `keeper` implementation [here](https://github.com/cosmos/sdk-application-tutorial/blob/master/x/nameservice/keeper.go). -To learn more about `keepers`, [click here](../building-modules/keeper.md). - ### Querier -[`Queriers`](../building-modules/querier.md) are very similar to `handlers`, except they serve user queries to the state as opposed to processing transactions. A [query](../building-modules/messages-and-queries.md#queries) is initiated from an [interface](#interfaces) by an end-user who provides a `queryRoute` and some `data`. The query is then routed to the correct application's `querier` by `baseapp`'s [`handleQueryCustom`](https://github.com/cosmos/cosmos-sdk/blob/master/baseapp/baseapp.go#L519-L556) method using `queryRoute`. +`Queriers` are very similar to `handlers`, except they serve user queries to the state as opposed to processing transactions. A query is initiated from an [interface](#intefaces) by an end-user who provides a `queryRoute` and some `data`. The query is then routed to the correct application's `querier` by `baseapp`'s [`handleQueryCustom`](https://github.com/cosmos/cosmos-sdk/blob/master/baseapp/baseapp.go#L519-L556) method using `queryRoute`. The `Querier` of a module is defined in a file called `querier.go`, and consists of: -- A **switch function** `NewQuerier` to route the query to the appropriate `querier` function. This function returns a `querier` function, and is is registered in the [`AppModule`](#application-module-interface) to be used in the application's module manager to initialize the [application's query router](../core/baseapp.md#query-routing). See an example of such a switch [here](https://github.com/cosmos/sdk-application-tutorial/blob/master/x/nameservice/querier.go#L21-L34). -- - **One querier function for each data type defined by the module that needs to be queryable**. Developers write the query processing logic in these functions. This generally involves calling [`keeper`](#keeper)'s methods to query the state and marshalling it to JSON. See an example of `querier` functions [here](https://github.com/cosmos/sdk-application-tutorial/blob/master/x/nameservice/querier.go#L37-L101). - -To learn more about `queriers`, [click here](../building-modules/querier.md). +- A **switch function** `NewQuerier` to route the query to the appropriate `querier` function. This function returns a `querier` function, and is is registered in the [`AppModule`](#application-module-interface) to be used in the application's module manager to initialize the application's query router. See an example of such a switch [here](https://github.com/cosmos/sdk-application-tutorial/blob/master/x/nameservice/querier.go#L21-L34). +- - **One querier function for each data type defined by the module that needs to be queryable**. Developers write the query processing logic in these functions. This generally involves calling [`keeper`](#keeper)'s methods to query the state and marshaling it to JSON. See an example of `querier` functions [here](https://github.com/cosmos/sdk-application-tutorial/blob/master/x/nameservice/querier.go#L37-L101). ### Command-Line and REST Interfaces @@ -216,11 +204,9 @@ Generally, the commands related to a module are defined in a folder called `clie - Transactions commands let users generate new transactions so that they can be included in a block and eventually update the state. One command should be created for each [message type](#message-types) defined in the module. The command calls the constructor of the message with the parameters provided by the end-user, and wraps it into a transaction. The SDK handles signing and the addition of other transaction metadata. See examples of transactions commands [here](https://github.com/cosmos/sdk-application-tutorial/blob/master/x/nameservice/client/cli/tx.go). - Queries let users query the subset of the state defined by the module. Query commands forward queries to the [application's query router](./baseapp.md#query-routing), which routes them to the appropriate [querier](#querier) the `queryRoute` parameter supplied. See examples of query commands [here](https://github.com/cosmos/sdk-application-tutorial/blob/master/x/nameservice/client/cli/query.go). -To learn more about modules CLI, [click here](../building-modules/module-interfaces.md#cli). - #### REST -The module's REST interface lets users generate transactions and query the state through REST calls to the application's [light client daemon](../core/node.md#lcd) (LCD). REST routes are defined in a file `client/rest/rest.go`, which is composed of: +The module's REST interface lets users generate transactions and query the state through REST calls to the application's light client daemon (LCD). REST routes are defined in a file `client/rest/rest.go`, which is composed of: - A `RegisterRoutes` function, which registers each route defined in the file. This function is called from the [main application's interface](#application-interfaces) for each module used within the application. The router used in the SDK is [Gorilla's mux](https://github.com/gorilla/mux). - Custom request type definitions for each query or transaction creation function that needs to be exposed. These custom request types build on the [base `request` type](https://github.com/cosmos/cosmos-sdk/blob/master/types/rest/rest.go#L32-L43) of the Cosmos SDK. @@ -228,23 +214,19 @@ The module's REST interface lets users generate transactions and query the state See an example of a module's `rest.go` file [here](https://github.com/cosmos/sdk-application-tutorial/blob/master/x/nameservice/client/rest/rest.go). -To learn more about modules REST interface, [click here](../building-modules/module-interfaces.md#rest). - ## Application Interface Interfaces let end-users interact with full-node clients. This means querying data from the full-node or creating and sending new transactions to be relayed by the full-node and eventually included in a block. -The main interface is the [Command-Line Interface](../interfaces/cli.md). The CLI of an SDK application is built by aggregating [CLI commands](#cli) defined in each of the modules used by the application. The CLI of an application generally has the `-cli` suffix (e.g. `appcli`), and defined in a file called `cmd/appcli/main.go`. The file contains: +The main interface is the Command-Line Interface. The CLI of an SDK application is built by aggregating [CLI commands](#cli) defined in each of the modules used by the application. The CLI of an application generally has the `-cli` suffix (e.g. `appcli`), and defined in a file called `cmd/appcli/main.go`. The file contains: - **A `main()` function**, which is executed to build the `appcli` interface client. This function prepares each command and adds them to the `rootCmd` before building them. At the root of `appCli`, the function adds generic commands like `status`, `keys` and `config`, query commands, tx commands and `rest-server`. - **Query commands** are added by calling the `queryCmd` function, also defined in `appcli/main.go`. This function returns a Cobra command that contains the query commands defined in each of the application's modules (passed as an array of `sdk.ModuleClients` from the `main()` function), as well as some other lower level query commands such as block or validator queries. Query command are called by using the command `appcli query [query]` of the CLI. -- **Transaction commands** are added by calling the `txCmd` function. Similar to `queryCmd`, the function returns a Cobra command that contains the tx commands defined in each of the application's modules, as well as lower level tx commands like transaction signing or broadcasting. Tx commands are called by using the command `appcli tx [tx]` of the CLI. -- **A `registerRoutes` function**, which is called from the `main()` function when initializing the [application's light-client daemon (LCD)](../core/node.md#lcd) (i.e. `rest-server`). `registerRoutes` calls the `RegisterRoutes` function of each of the application's module, thereby registering the routes of the module to the lcd's router. The LCD can be started by running the following command `appcli rest-server`. +- **Transaction commands** are added by calling the `txCmd` function. Similar to `queryCmd`, the function returns a Cobra command that contains the tx commands defined in each of the application's modules, as well as lower level tx commands like transaction signing or broadcasting. Tx commands are called by using the command `appcli tx [tx]` of the CLI. +- **A `registerRoutes` function**, which is called from the `main()` function when initializing the [application's light-client daemon (LCD)](./node.md#lcd) (i.e. `rest-server`). `registerRoutes` calls the `RegisterRoutes` function of each of the application's module, thereby registering the routes of the module to the lcd's router. The LCD can be started by running the following command `appcli rest-server`. See an example of an application's main command-line file [here](https://github.com/cosmos/sdk-application-tutorial/blob/master/cmd/nscli/main.go). -To learn more about interfaces, [click here](../interfaces/intro.md). - ## Dependencies and Makefile This section is optional, as developers are free to choose their depencency manager and project building method. That said, the current most used framework for versioning control is [`go.mod`](https://github.com/golang/go/wiki/Modules). It ensures each of the libraries used throughout the application are imported with the correct version. An example can be found [here](https://github.com/cosmos/sdk-application-tutorial/blob/master/go.mod). diff --git a/docs/building-modules/intro.md b/docs/building-modules/intro.md index d3e8440992d5..403eb755a2a2 100644 --- a/docs/building-modules/intro.md +++ b/docs/building-modules/intro.md @@ -7,7 +7,7 @@ ## Synopsis -Modules define most of the logic of any SDK application. Developers compose module together to build their custom application-specific blockchains. This document outlines the basic concepts behind SDK modules and how to approach module management. +Modules define most of the logic of any SDK application. Developers compose module together to build their custom application-specific blockchains. This document outlines the basic concepts behind SDK modules and how to approach module management. - [Role of Modules in an SDK application](#role-of-modules-in-an-sdk-application) - [How to Approach Building Modules as a Developer](#how-to-approach-building-modules-as-a-developer) @@ -18,14 +18,14 @@ Modules define most of the logic of any SDK application. Developers compose modu The Cosmos SDK can be thought as the Ruby-on-Rails of blockchain development. It comes with a core that provides the basic functionalities every blockchain application need, like a boilerplate implementation of the ABCI to communicate with the underlying consensus engine, a multistore to persist state, a server to form a full-node and interfaces to handle queries. -On top of this core, the SDK enables developers to build modules that implement the business logic of their application. In other words, SDK modules implement the bulk of the logic of applications, while the core does the wiring and enables modules to be composed together. The end goal is to build a robust ecosystem of open-source SDK modules, making it increasingly easier to build complex blockchain applications. +On top of this core, the SDK enables developers to build modules that implement the business logic of their application. In other words, SDK modules implement the bulk of the logic of applications, while the core does the wiring and enables modules to be composed together. The end goal is to build a robust ecosystem of open-source SDK modules, making it increasingly easier to build complex blockchain applications. -SDK Modules can be seen as little state-machines within the state-machine. They generally define a subset of the state using one ore multiple `KVStore` in the [main multistore](../core/store.md), as well as a subset of [`message` types](./message.md). These `message`s are routed by one of the main component of SDK core, [`baseapp`](../core/baseapp.md), to the [`handler`](./handler.md) of the module that define them. +SDK Modules can be seen as little state-machines within the state-machine. They generally define a subset of the state using one ore multiple `KVStore` in the [main multistore](../core/store.md), as well as a subset of [`message` types](./message.md). These `message`s are routed by one of the main component of SDK core, [`baseapp`](../core/baseapp.md), to the [`handler`](./handler.md) of the module that define them. ``` + | - | Transaction relayed from the full-node's consensus engine + | Transaction relayed from the full-node's consensus engine | to the node's application via DeliverTx | | @@ -67,28 +67,29 @@ SDK Modules can be seen as little state-machines within the state-machine. They v ``` -As a result of this architecture, building an SDK application usually revolves around writing modules to implement the specialized logic of the application, and composing them with existing modules to complete the application. Developers will generally work on modules that implement logic needed for their specific use case that do not exist yet, and will use existing modules for more generic functionalities like staking, accounts or token management. +As a result of this architecture, building an SDK application usually revolves around writing modules to implement the specialized logic of the application, and composing them with existing modules to complete the application. Developers will generally work on modules that implement logic needed for their specific use case that do not exist yet, and will use existing modules for more generic functionalities like staking, accounts or token management. ## How to Approach Building Modules as a Developer While there is no definitive guidelines for writing modules, here are some important design principles developers should keep in mind when building them: -- **Composability**: SDK applications are almost always composed of multiple modules. This means developers need to carefully consider the integration of their module not only with the core of the Cosmos SDK, but also with other modules. The former is achieved by following standard design patterns outlined [here](#main-components-of-sdk-modules), while the latter is achieved by properly exposing the store(s) of the module via the [`keeper`](./keeper.md). -- **Specialization**: A direct consequence of the **composability** feature is that modules should be **specialized**. Developers should carefully establish the scope of their module and not batch multiple functionalities into the same module. This separation of concern enables modules to be re-used in other projects and improves the upgradability of the application. **Specialization** also plays an important role in the [object-capabilities model](../core/ocap.md) of the Cosmos SDK. -- **Capabilities**: Most modules need to read and/or write to the store(s) of other modules. However, in an open-source environment, it is possible for some module to be malicious. That is why module developers need to carefully think not only about how their module interracts with other modules, and how to give access to the module's store(s). The Cosmos SDK takes a capabilities-oriented approach to inter-module security. This means that each store defined by a module is accessed by a `key`, which is held by the module's [`keeper`](./keeper.md). This `keeper` defines how to access the store(s) and under what conditions. Access to the module's store(s) is done by passing a reference to the module's `keeper`. +- **Composability**: SDK applications are almost always composed of multiple modules. This means developers need to carefully consider the integration of their module not only with the core of the Cosmos SDK, but also with other modules. The former is achieved by following standard design patterns outlined [here](#main-components-of-sdk-modules), while the latter is achieved by properly exposing the store(s) of the module via the [`keeper`](./keeper.md). +- **Specialization**: A direct consequence of the **composability** feature is that modules should be **specialized**. Developers should carefully establish the scope of their module and not batch multiple functionalities into the same module. This separation of concern enables modules to be re-used in other projects and improves the upgradability of the application. **Specialization** also plays an important role in the [object-capabilities model](../core/ocap.md) of the Cosmos SDK. +- **Capabilities**: Most modules need to read and/or write to the store(s) of other modules. However, in an open-source environment, it is possible for some module to be malicious. That is why module developers need to carefully think not only about how their module interracts with other modules, and how to give access to the module's store(s). The Cosmos SDK takes a capabilities-oriented approach to inter-module security. This means that each store defined by a module is accessed by a `key`, which is held by the module's [`keeper`](./keeper.md). This `keeper` defines how to access the store(s) and under what conditions. Access to the module's store(s) is done by passing a reference to the module's `keeper`. ## Main Components of SDK Module -Modules generally share the same core components: +Modules are by convention defined in the `.x/` subfolder (e.g. the `bank` module will be defined in the `./x/bank` folder). They generally share the same core components: -- Custom [`message` types](./message.md) to trigger state-transitions. -- A [`handler`](./handler.md) used to process messages when they are routed to the module by [`baseapp`](../core/baseapp.md#message-routing). -- A [`keeper`](./keeper.md), used to access the module's store(s) and update the state. +- Custom [`message` types](./message.md) to trigger state-transitions. +- A [`handler`](./handler.md) used to process messages when they are routed to the module by [`baseapp`](../core/baseapp.md#message-routing). +- A [`keeper`](./keeper.md), used to access the module's store(s) and update the state. - A [`querier`](./querier.md), used to process user queries when they are routed to the module by [`baseapp`](../core/baseapp.md#query-routing). - Interfaces, for end users to query the subset of the state defined by the module and create `message`s of the custom types defined in the module. -In addition to these components, modules implement the `module` interface in order to be managed by the [`module manager`](./module-manager.md). +In addition to these components, modules implement the `AppModule` interface in order to be managed by the [`module manager`](./module-manager.md). ## Next -Read more on the [`module interface` and the `module manager`](./module-manager.md) +Read more on the [`AppModule` interface and the `module manager`](./module-manager.md) + diff --git a/docs/core/baseapp.md b/docs/core/baseapp.md index 44c46f26f489..6c3d2dd9e506 100644 --- a/docs/core/baseapp.md +++ b/docs/core/baseapp.md @@ -7,7 +7,7 @@ ## Synopsis -This document describes `baseapp`, the abstraction that implements most of the common functionalities of an SDK application. +This document describes `baseapp`, the abstraction that implements most of the common functionalities of an SDK application. - [Introduction](#introduction) - [Type Definition](#type-definition) @@ -17,7 +17,7 @@ This document describes `baseapp`, the abstraction that implements most of the c - [Main ABCI Messages](#abci) + [CheckTx](#checktx) + [DeliverTx](#delivertx) -- [RunTx, AnteHandler and RunMsgs](#runtx-,antehandler-and-runmsgs) +- [RunTx, AnteHandler and RunMsgs](#runtx-antehandler-and-runmsgs) + [RunTx](#runtx) + [AnteHandler](#antehandler) + [RunMsgs](#runmsgs) @@ -28,18 +28,18 @@ This document describes `baseapp`, the abstraction that implements most of the c + [Commit](#commit) + [Info](#info) + [Query](#query) - + ## Introduction `baseapp` is an abstraction that implements the core of an SDK application, namely: -- The [Application-Blockchain Interface](#abci), for the state-machine to communicate with the underlying consensus engine (e.g. Tendermint). +- The [Application-Blockchain Interface](#abci), for the state-machine to communicate with the underlying consensus engine (e.g. Tendermint). - A [Router](#routing), to route [messages](./tx-msgs.md) and [queries](./querier.md) to the appropriate [module](../building-modules/intro.md). -- Different [states](#states), as the state-machine can have different parallel states updated based on the ABCI message received. +- Different [states](#states), as the state-machine can have different parallel states updated based on the ABCI message received. The goal of `baseapp` is to provide a boilerplate SDK application that developers can easily extend to build their own custom application. Usually, developers will create a custom type for their application, like so: -```go +```go type app struct { *bam.BaseApp // reference to baseapp cdc *codec.Codec @@ -52,24 +52,24 @@ type app struct { } ``` -Extending the application with `baseapp` gives the former access to all of `baseapp`'s methods. This allows developers to compose their custom application with the modules they want, while not having to concern themselves with the hard work of implementing the ABCI, the routing and state management logic. +Extending the application with `baseapp` gives the former access to all of `baseapp`'s methods. This allows developers to compose their custom application with the modules they want, while not having to concern themselves with the hard work of implementing the ABCI, the routing and state management logic. ## Type Definition The [`baseapp` type](https://github.com/cosmos/cosmos-sdk/blob/master/baseapp/baseapp.go#L45-L91) holds many important parameters for any Cosmos SDK based application. Let us go through the most important components. -*Note: Not all parameters are described, only the most important ones. Refer to the [type definition](https://github.com/cosmos/cosmos-sdk/blob/master/baseapp/baseapp.go#L45-L91) for the full list* +*Note: Not all parameters are described, only the most important ones. Refer to the [type definition](https://github.com/cosmos/cosmos-sdk/blob/master/baseapp/baseapp.go#L45-L91) for the full list* First, the important parameters that are initialized during the initialization of the application: -- A [`CommitMultiStore`](./store.md#commit-multi-store). This is the main store of the application, which holds the canonical state that is committed at the [end of each block](#commit). This store is **not** cached, meaning it is not used to update the application's intermediate (un-committed) states. The `CommitMultiStore` is a multi-store, meaning a store of stores. Each module of the application uses one or multiple `KVStores` in the multi-store to persist their subset of the state. +- A [`CommitMultiStore`](./store.md#commit-multi-store). This is the main store of the application, which holds the canonical state that is committed at the [end of each block](#commit). This store is **not** cached, meaning it is not used to update the application's intermediate (un-committed) states. The `CommitMultiStore` is a multi-store, meaning a store of stores. Each module of the application uses one or multiple `KVStores` in the multi-store to persist their subset of the state. - A [database](./store.md#database) `db`, which is used by the `CommitMultiStore` to handle data storage. - A [router](#message-routing). The `router` facilitates the routing of [messages](../building-modules/messages-and-queries.md#messages) to the appropriate module for it to be processed. - A [query router](#query-routing). The `query router` facilitates the routing of [queries](../building-modules/messages-and-queries.md#queries) to the appropriate module for it to be processed. - A [`txDecoder`](https://godoc.org/github.com/cosmos/cosmos-sdk/types#TxDecoder), used to decode transaction `[]byte` relayed by the underlying Tendermint engine. - A [`baseKey`], to access the [main store](./store.md#main-store) in the `CommitMultiStore`. The main store is used to persist data related to the core of the application, like consensus parameters. - A [`anteHandler`](#antehandler), to handle signature verification and fee paiement when a transaction is received. -- An [`initChainer`](../basics/app-anatomy.md#initchainer), [`beginBlocker` and `endBlocker`](../basics/app-anatomy.md#beginblocker-and-endblocker), which are the functions executed when the application received the [InitChain], [BeginBlock] and [EndBlock] messages from the underlying Tendermint engine. +- An [`initChainer`](../basics/app-anatomy.md#initchainer), [`beginBlocker` and `endBlocker`](../basics/app-anatomy.md#beginblocker-and-endblocker), which are the functions executed when the application received the [InitChain], [BeginBlock] and [EndBlock] messages from the underlying Tendermint engine. Then, parameters used to define [volatile states](#volatile-states) (i.e. cached states): @@ -84,13 +84,13 @@ Finally, a few more important parameterd: ## Constructor -`NewBaseApp(name string, logger log.Logger, db dbm.DB, txDecoder sdk.TxDecoder, options ...func(*BaseApp),)` is the constructor function for `baseapp`. It is called from the [application's constructor function](../basics/app-anatomy.md#constructor-function) each time the full-node is started. +`NewBaseApp(name string, logger log.Logger, db dbm.DB, txDecoder sdk.TxDecoder, options ...func(*BaseApp),)` is the constructor function for `baseapp`. It is called from the [application's constructor function](../basics/app-anatomy.md#constructor-function) each time the full-node is started. -`baseapp`'s constructor function is pretty straightforward. The only thing worth noting is the possibility to add additional [`options`](https://github.com/cosmos/cosmos-sdk/blob/master/baseapp/options.go) to `baseapp` by passing `options functions` to the constructor function, which will execute them in order. `options` are generally `setters` function for important parameters, like `SetPruning()` to active pruning or `SetMinGasPrices()` to set the node's `min-gas-prices`. +`baseapp`'s constructor function is pretty straightforward. The only thing worth noting is the possibility to add additional [`options`](https://github.com/cosmos/cosmos-sdk/blob/master/baseapp/options.go) to `baseapp` by passing `options functions` to the constructor function, which will execute them in order. `options` are generally `setters` function for important parameters, like `SetPruning()` to active pruning or `SetMinGasPrices()` to set the node's `min-gas-prices`. -A list of `options` example can be found [here](https://github.com/cosmos/cosmos-sdk/blob/master/baseapp/options.go). Naturally, developers can add additional `options` based on their application's needs. +A list of `options` example can be found [here](https://github.com/cosmos/cosmos-sdk/blob/master/baseapp/options.go). Naturally, developers can add additional `options` based on their application's needs. -## States +## States `baseapp` handles various parallel states for different purposes. There is the [main state](#main-state), which is the canonical state of the application, and volatile states like [`checkState`](#checkState) and [`deliverState`](#deliverstate), which are used to handle temporary states inbetween updates of the main state. @@ -120,54 +120,7 @@ DeliverTx(tx1) | | | +----------------------+ +----------------------+ | | | | | DeliverState(t)(1) | | | | | +----------------------+ | | -DeliverTx(tx2) | | | | | - | | v | | - | | +----------------------+ | | - | | | DeliverState(t)(2) | | | - | | +----------------------+ | | -DeliverTx(tx3) | | | | | - | | v | | - | | +----------------------+ | | - | | | DeliverState(t)(3) | | | - +----------------------+ +----------------------+ +----------------------+ -Commit() | | | - v v v - +----------------------+ +----------------------+ +----------------------+ - | CheckState(t+1)(0) | | DeliverState(t+1)(0) | | QueryState(t+1) | - +----------------------+ | | | | - . . . - . . . - . . . - -``` - -``` - To perform stateful checks To execute state To serve queries - on received transactions transitions during DeliverTx on last-committed state - +----------------------+ +----------------------+ +----------------------+ - | CheckState(t)(0) | | DeliverState(t)(0) | | QueryState(t) | - +----------------------+ | | | | -CheckTx(tx1) | | | | | - v | | | | - +----------------------+ | | | | - | CheckState(t)(1) | | | | | - +----------------------+ | | | | -CheckTx(tx2) | | | | | - v | | | | - +----------------------+ | | | | - | CheckState(t)(2) | | | | | - +----------------------+ | | | | -CheckTx(tx3) | | | | | - v | | | | - +----------------------+ | | | | - | CheckState(t)(3) | | | | | - +----------------------+ +----------------------+ | | -DeliverTx(tx1) | | | | - v v | | - +----------------------+ +----------------------+ | | - | | | DeliverState(t)(1) | | | - | | +----------------------+ | | -DeliverTx(tx2) | | | | | +DeliverTx(tx2) | | | | | | | v | | | | +----------------------+ | | | | | DeliverState(t)(2) | | | @@ -185,12 +138,12 @@ Commit() | | . . . . . . . . . - + ``` ### Main State -The main state is the canonical state of the application. It is initialized on [`InitChain`](#initchain and updated on [`Commit`](#abci-commit) at the end of each block. +The main state is the canonical state of the application. It is initialized on [`InitChain`](#initchain and updated on [`Commit`](#abci-commit) at the end of each block. ``` +--------+ +--------+ @@ -206,13 +159,13 @@ The main state is held by `baseapp` in a structure called the [`CommitMultiStore Volatile - or cached - states are used in between [`Commit`s](#commit) to manage temporary states. They are reset to the latest version of the main state after it is committed. There are two main volatile states: -- `checkState`: This cached state is initialized during [`InitChain`](#initchain), updated during [`CheckTx`](#abci-checktx) when an unconfirmed transaction is received, and reset to the [main state](#main-state) on [`Commit`](#abci-commit). +- `checkState`: This cached state is initialized during [`InitChain`](#initchain), updated during [`CheckTx`](#abci-checktx) when an unconfirmed transaction is received, and reset to the [main state](#main-state) on [`Commit`](#abci-commit). - `deliverState`: This cached state is initialized during [`BeginBlock`](#beginblock), updated during [`DeliverTx`](#abci-delivertx) when a transaction included in a block is processed, and reset to the [main state](#main-state) on [`Commit`](#abci-commit). Both `checkState` and `deliverState` are of type [`state`](https://github.com/cosmos/cosmos-sdk/blob/master/baseapp/baseapp.go#L973-L976), which includes: -- A [`CacheMultiStore`](https://github.com/cosmos/cosmos-sdk/blob/master/store/cachemulti/store.go), which is a cached version of the main `CommitMultiStore`. A new version of this store is committed at the end of each successful `CheckTx`/`DeliverTx` execution. -- A [`Context`](./context.md), which carries general information (like raw transaction size, block height, ...) that might be needed in order to process the transaction during `CheckTx` and `DeliverTx`. The `context` also holds a cache-wrapped version of the `CacheMultiStore`, so that the `CacheMultiStore` can maintain the correct version even if an internal step of `CheckTx` or `DeliverTx` fails. +- A [`CacheMultiStore`](https://github.com/cosmos/cosmos-sdk/blob/master/store/cachemulti/store.go), which is a cached version of the main `CommitMultiStore`. A new version of this store is committed at the end of each successful `CheckTx`/`DeliverTx` execution. +- A [`Context`](./context.md), which carries general information (like raw transaction size, block height, ...) that might be needed in order to process the transaction during `CheckTx` and `DeliverTx`. The `context` also holds a cache-wrapped version of the `CacheMultiStore`, so that the `CacheMultiStore` can maintain the correct version even if an internal step of `CheckTx` or `DeliverTx` fails. ## Routing @@ -222,24 +175,24 @@ When messages and queries are received by the application, they must be routed t [`Message`s](#../building-modules/messages-and-queries.md#messages) need to be routed after they are extracted from transactions, which are sent from the underlying Tendermint engine via the [`CheckTx`](#checktx) and [`DeliverTx`](#delivertx) ABCI messages. To do so, `baseapp` holds a [`router`](https://github.com/cosmos/cosmos-sdk/blob/master/baseapp/router.go) which maps `paths` (`string`) to the appropriate module [`handler`](./handler.md). Usually, the `path` is the name of the module. -The application's `router` is initilalized with all the routes using the application's [module manager](../building-modules/module-manager.md), which itself is initialized with all the application's modules in the application's [constructor](../basics/app-anatomy.md#app-constructor). +The application's `router` is initilalized with all the routes using the application's [module manager](../building-modules/module-manager.md), which itself is initialized with all the application's modules in the application's [constructor](../basics/app-anatomy.md#app-constructor). ### Query Routing -Similar to `message`s, [`queries`](../building-modules/messages-and-queries.md#queries) need to be routed to the appropriate module's [querier](../building-modules/querier.md). To do so, `baseapp` holds a [`query router`](https://github.com/cosmos/cosmos-sdk/blob/master/baseapp/queryrouter.go), which maps `paths` (`string`) to the appropriate module `querier`. Usually, the `path` is the name of the module. +Similar to `message`s, [`queries`](../building-modules/messages-and-queries.md#queries) need to be routed to the appropriate module's [querier](../building-modules/querier.md). To do so, `baseapp` holds a [`query router`](https://github.com/cosmos/cosmos-sdk/blob/master/baseapp/queryrouter.go), which maps `paths` (`string`) to the appropriate module `querier`. Usually, the `path` is the name of the module. Just like the `router`, the `query router` is initilalized with all the query routes using the application's [module manager](../building-modules/module-manager.md), which itself is initialized with all the application's modules in the application's [constructor](../basics/app-anatomy.md#app-constructor). ## Main ABCI Messages -The [Application-Blockchain Interface](https://tendermint.com/docs/spec/abci/) (ABCI) is a generic interface that connects a state-machine with a consensus engine to form a functional full-node. It can be wrapped in any language, and needs to be implemented by each application-specific blockchain built on top of an ABCI-compatible consensus engine like Tendermint. +The [Application-Blockchain Interface](https://tendermint.com/docs/spec/abci/) (ABCI) is a generic interface that connects a state-machine with a consensus engine to form a functional full-node. It can be wrapped in any language, and needs to be implemented by each application-specific blockchain built on top of an ABCI-compatible consensus engine like Tendermint. The consensus engine handles two main tasks: - The networking logic, which mainly consists in gossiping block parts, transactions and consensus votes. -- The consensus logic, which results in the deterministic ordering of transactions in the form of blocks. +- The consensus logic, which results in the deterministic ordering of transactions in the form of blocks. -It is **not** the role of the consensus engine to define the state or the validity of transactions. Generally, transactions are handled by the consensus engine in the form of `[]bytes`, and relayed to the application via the ABCI to be decoded and processed. At keys moments in the networking and consensus processes (e.g. beginning of a block, commit of a block, reception of an unconfirmed transaction, ...), the consensus engine emits ABCI messages for the state-machine to act on. +It is **not** the role of the consensus engine to define the state or the validity of transactions. Generally, transactions are handled by the consensus engine in the form of `[]bytes`, and relayed to the application via the ABCI to be decoded and processed. At keys moments in the networking and consensus processes (e.g. beginning of a block, commit of a block, reception of an unconfirmed transaction, ...), the consensus engine emits ABCI messages for the state-machine to act on. Developers building on top of the Cosmos SDK need not implement the ABCI themselves, as `baseapp` comes with a built-in implementation of the interface. Let us go through the main ABCI messages that `baseapp` implements: [`CheckTx`](#checktx) and [`DeliverTx`](#delivertx) @@ -251,43 +204,43 @@ Developers building on top of the Cosmos SDK need not implement the ABCI themsel 1. Extract the `message`s from the transaction. 2. Perform *stateless* checks by calling `ValidateBasic()` on each of the `messages`. This is done first, as *stateless* checks are less computationally expensive than *stateful* checks. If `ValidateBasic()` fail, `CheckTx` returns before running *stateful* checks, which saves resources. -3. Perform non-module related *stateful* checks on the account. This step is mainly about checking that the `message` signatures are valid, that enough fees are provided and that the sending account has enough funds to pay for said fees. Note that no precise [`gas`](./accounts-fees-gas.md#gas) counting occurs here, as `message`s are not processed. Usually, the [`anteHandler`](./accounts-fees-gas.md#antehandler) will check that the `gas` provided with the transaction is superior to a minimum reference gas amount based on the raw transaction size, in order to avoid spam with transactions that provide 0 gas. -4. Ensure that a [`Route`](#message-routing) exists for each `message`, but do **not** actually process `message`s. `Message`s only need to be processed when the canonical state need to be updated, which happens during `DeliverTx`. +3. Perform non-module related *stateful* checks on the account. This step is mainly about checking that the `message` signatures are valid, that enough fees are provided and that the sending account has enough funds to pay for said fees. Note that no precise [`gas`](./accounts-fees-gas.md#gas) counting occurs here, as `message`s are not processed. Usually, the [`anteHandler`](./accounts-fees-gas.md#antehandler) will check that the `gas` provided with the transaction is superior to a minimum reference gas amount based on the raw transaction size, in order to avoid spam with transactions that provide 0 gas. +4. Ensure that a [`Route`](#message-routing) exists for each `message`, but do **not** actually process `message`s. `Message`s only need to be processed when the canonical state need to be updated, which happens during `DeliverTx`. -Steps 2. and 3. are performed by the [`anteHandler`](./accounts-fees-gas.md#antehandler) in the [`RunTx`](#runtx-,antehandler-and-runmsgs) function, which `CheckTx` calls with the `runTxModeCheck` mode. During each step of `CheckTx`, a special [volatile state](#volatile-states) called `checkState` is updated. This state is used to keep track of the temporary changes triggered by the `CheckTx` calls of each transaction without modifying the [main canonical state](#main-state) . For example, when a transaction goes through `CheckTx`, the transaction's fees are deducted from the sender's account in `checkState`. If a second transaction is received from the same account before the first is processed, and the account has consumed all its funds in `checkState` during the first transaction, the second transaction will fail `CheckTx` and be rejected. In any case, the sender's account will not actually pay the fees until the transaction is actually included in a block, because `checkState` never gets committed to the main state. `checkState` is reset to the latest state of the main state each time a blocks gets [committed](#commit). +Steps 2. and 3. are performed by the [`anteHandler`](./accounts-fees-gas.md#antehandler) in the [`RunTx`](#runtx-antehandler-and-runmsgs) function, which `CheckTx` calls with the `runTxModeCheck` mode. During each step of `CheckTx`, a special [volatile state](#volatile-states) called `checkState` is updated. This state is used to keep track of the temporary changes triggered by the `CheckTx` calls of each transaction without modifying the [main canonical state](#main-state) . For example, when a transaction goes through `CheckTx`, the transaction's fees are deducted from the sender's account in `checkState`. If a second transaction is received from the same account before the first is processed, and the account has consumed all its funds in `checkState` during the first transaction, the second transaction will fail `CheckTx` and be rejected. In any case, the sender's account will not actually pay the fees until the transaction is actually included in a block, because `checkState` never gets committed to the main state. `checkState` is reset to the latest state of the main state each time a blocks gets [committed](#commit). `CheckTx` returns a response to the underlying consensus engine of type [`abci.ResponseCheckTx`](https://tendermint.com/docs/spec/abci/abci.html#messages). The response contains: -- `Code (uint32)`: Response Code. `0` if successful. +- `Code (uint32)`: Response Code. `0` if successful. - `Data ([]byte)`: Result bytes, if any. - `Log (string):` The output of the application's logger. May be non-deterministic. - `Info (string):` Additional information. May be non-deterministic. -- `GasWanted (int64)`: Amount of gas requested for transaction. It is provided by users when they generate the transaction. -- `GasUsed (int64)`: Amount of gas consumed by transaction. During `CheckTx`, this value is computed by multiplying the standard cost of a transaction byte by the size of the raw transaction (click [here](https://github.com/cosmos/cosmos-sdk/blob/master/x/auth/ante.go#L101) for an example). +- `GasWanted (int64)`: Amount of gas requested for transaction. It is provided by users when they generate the transaction. +- `GasUsed (int64)`: Amount of gas consumed by transaction. During `CheckTx`, this value is computed by multiplying the standard cost of a transaction byte by the size of the raw transaction (click [here](https://github.com/cosmos/cosmos-sdk/blob/master/x/auth/ante.go#L101) for an example). - `Tags ([]cmn.KVPair)`: Key-Value tags for filtering and indexing transactions (eg. by account). - `Codespace (string)`: Namespace for the Code. ### DeliverTx -When the underlying consensus engine receives a block proposal, each transaction in the block needs to be processed by the application. To that end, the underlying consensus engine sends a `DeliverTx` message to the application for each transaction in a sequential order. +When the underlying consensus engine receives a block proposal, each transaction in the block needs to be processed by the application. To that end, the underlying consensus engine sends a `DeliverTx` message to the application for each transaction in a sequential order. -Before the first transaction of a given block is processed, a [volatile state](#volatile-states) called `deliverState` is intialized during [`BeginBlock`](#beginblock). This state is updated each time a transaction is processed via `DeliverTx`, and committed to the [main state](#main-state) when the block is [committed](#commit), after what is is set to `nil`. +Before the first transaction of a given block is processed, a [volatile state](#volatile-states) called `deliverState` is intialized during [`BeginBlock`](#beginblock). This state is updated each time a transaction is processed via `DeliverTx`, and committed to the [main state](#main-state) when the block is [committed](#commit), after what is is set to `nil`. `DeliverTx` performs the **exact same steps as `CheckTx`**, with a little caveat at step 3 and the addition of a fifth step: -3. The `anteHandler` does **not** check that the transaction's `gas-prices` is sufficient. That is because the `min-gas-prices` value `gas-prices` is checked against is local to the node, and therefore what is enough for one full-node might not be for another. This means that the proposer can potentially include transactions for free, although they are not incentivised to do so, as they earn a bonus on the total fee of the block they propose. -5. For each `message` in the transaction, route to the appropriate module's [`handler`](../building-modules/handler.md). Additional *stateful* checks are performed, and the cache-wrapped multistore held in `deliverState`'s `context` is updated by the module's `keeper`. If the `handler` returns successfully, the cache-wrapped multistore held in `context` is written to `deliverState` `CacheMultiStore`. +3. The `anteHandler` does **not** check that the transaction's `gas-prices` is sufficient. That is because the `min-gas-prices` value `gas-prices` is checked against is local to the node, and therefore what is enough for one full-node might not be for another. This means that the proposer can potentially include transactions for free, although they are not incentivised to do so, as they earn a bonus on the total fee of the block they propose. +5. For each `message` in the transaction, route to the appropriate module's [`handler`](../building-modules/handler.md). Additional *stateful* checks are performed, and the cache-wrapped multistore held in `deliverState`'s `context` is updated by the module's `keeper`. If the `handler` returns successfully, the cache-wrapped multistore held in `context` is written to `deliverState` `CacheMultiStore`. -During step 5., each read/write to the store increases the value of `GasConsumed`. You can find the default cost of each operation [here](https://github.com/cosmos/cosmos-sdk/blob/master/store/types/gas.go#L142-L150). At any point, if `GasConsumed > GasWanted`, the function returns with `Code != 0` and `DeliverTx` fails. +During step 5., each read/write to the store increases the value of `GasConsumed`. You can find the default cost of each operation [here](https://github.com/cosmos/cosmos-sdk/blob/master/store/types/gas.go#L142-L150). At any point, if `GasConsumed > GasWanted`, the function returns with `Code != 0` and `DeliverTx` fails. `DeliverTx` returns a response to the underlying consensus engine of type [`abci.ResponseCheckTx`](https://tendermint.com/docs/spec/abci/abci.html#messages). The response contains: -- `Code (uint32)`: Response Code. `0` if successful. +- `Code (uint32)`: Response Code. `0` if successful. - `Data ([]byte)`: Result bytes, if any. - `Log (string):` The output of the application's logger. May be non-deterministic. - `Info (string):` Additional information. May be non-deterministic. -- `GasWanted (int64)`: Amount of gas requested for transaction. It is provided by users when they generate the transaction. -- `GasUsed (int64)`: Amount of gas consumed by transaction. During `DeliverTx`, this value is computed by multiplying the standard cost of a transaction byte by the size of the raw transaction (click [here](https://github.com/cosmos/cosmos-sdk/blob/master/x/auth/ante.go#L101) for an example), and by adding gas each time a read/write to the store occurs. +- `GasWanted (int64)`: Amount of gas requested for transaction. It is provided by users when they generate the transaction. +- `GasUsed (int64)`: Amount of gas consumed by transaction. During `DeliverTx`, this value is computed by multiplying the standard cost of a transaction byte by the size of the raw transaction (click [here](https://github.com/cosmos/cosmos-sdk/blob/master/x/auth/ante.go#L101) for an example), and by adding gas each time a read/write to the store occurs. - `Tags ([]cmn.KVPair)`: Key-Value tags for filtering and indexing transactions (eg. by account). - `Codespace (string)`: Namespace for the Code. @@ -295,13 +248,13 @@ During step 5., each read/write to the store increases the value of `GasConsumed ### RunTx -`RunTx` is called from `CheckTx`/`DeliverTx` to handle the transaction, with `runTxModeCheck` or `runTxModeDeliver` as parameter to differentiate between the two modes of execution. Note that when `RunTx` receives a transaction, it has already been decoded. +`RunTx` is called from `CheckTx`/`DeliverTx` to handle the transaction, with `runTxModeCheck` or `runTxModeDeliver` as parameter to differentiate between the two modes of execution. Note that when `RunTx` receives a transaction, it has already been decoded. The first thing `RunTx` does upon being called is to retrieve the `context`'s `CacheMultiStore` by calling the `getContextForTx()` function with the appropriate mode (either `runTxModeCheck` or `runTxModeDeliver`). This `CacheMultiStore` is a cached version of the main store instantiated during `BeginBlock` for `DeliverTx` and during the `Commit` of the previous block for `CheckTx`. After that, two `defer func()` are called for [`gas`](./accounts-fees-gas.md#gas) management. They are executed when `runTx` returns and make sure `gas` is actually consumed, and will throw errors, if any. -After that, `RunTx` calls `ValidateBasic()` on each `message`in the `Tx`, which runs prelimary *stateless* validity checks. If any `message` fails to pass `ValidateBasic()`, `RunTx` returns with an error. +After that, `RunTx` calls `ValidateBasic()` on each `message`in the `Tx`, which runs prelimary *stateless* validity checks. If any `message` fails to pass `ValidateBasic()`, `RunTx` returns with an error. -Then, the [`anteHandler`](#antehandler) of the application is run (if it exists). In preparation of this step, both the `checkState`/`deliverState`'s `context` and `context`'s `CacheMultiStore` are cached-wrapped using the [`cacheTxContext()`](https://github.com/cosmos/cosmos-sdk/blob/master/baseapp/baseapp.go#L781-L798) function. This allows `RunTx` not to commit the changes made to the state during the execution of `anteHandler` if it ends up failing. It also prevents the module implementing the `anteHandler` from writing to state, which is an important part of the [object-capabilities](./ocap.md) of the Cosmos SDK. +Then, the [`anteHandler`](#antehandler) of the application is run (if it exists). In preparation of this step, both the `checkState`/`deliverState`'s `context` and `context`'s `CacheMultiStore` are cached-wrapped using the [`cacheTxContext()`](https://github.com/cosmos/cosmos-sdk/blob/master/baseapp/baseapp.go#L781-L798) function. This allows `RunTx` not to commit the changes made to the state during the execution of `anteHandler` if it ends up failing. It also prevents the module implementing the `anteHandler` from writing to state, which is an important part of the [object-capabilities](./ocap.md) of the Cosmos SDK. Finally, the [`RunMsgs`](#runmsgs) function is called to process the `messages`s in the `Tx`. In preparation of this step, just like with the `anteHandler`, both the `checkState`/`deliverState`'s `context` and `context`'s `CacheMultiStore` are cached-wrapped using the `cacheTxContext()` function. @@ -311,17 +264,17 @@ The `AnteHandler` is a special handler that implements the [`anteHandler` interf The `AnteHandler` is theoretically optional, but still a very important component of public blockchain networks. It serves 3 primary purposes: -- Be a primary line of defense against spam and second line of defense (the first one being the mempool) against transaction replay with fees deduction and [`sequence`](./tx-msgs.md#sequence) checking. -- Perform preliminary *stateful* validity checks like ensuring signatures are valid or that the sender has enough funds to pay for fees. -- Play a role in the incentivisation of stakeholders via the collection of transaction fees. +- Be a primary line of defense against spam and second line of defense (the first one being the mempool) against transaction replay with fees deduction and [`sequence`](./tx-msgs.md#sequence) checking. +- Perform preliminary *stateful* validity checks like ensuring signatures are valid or that the sender has enough funds to pay for fees. +- Play a role in the incentivisation of stakeholders via the collection of transaction fees. `baseapp` holds an `anteHandler` as paraemter, which is initialized in the [application's constructor](../basics/app-anatomy.md#application-constructor). The most widely used `anteHandler` today is that of the [`auth` module](https://github.com/cosmos/cosmos-sdk/blob/master/x/auth/ante.go). ### RunMsgs -`RunMsgs` is called from `RunTx` with `runTxModeCheck` as parameter to check the existence of a route for each message the transaction, and with `runTxModeDeliver` to actually process the `message`s. +`RunMsgs` is called from `RunTx` with `runTxModeCheck` as parameter to check the existence of a route for each message the transaction, and with `runTxModeDeliver` to actually process the `message`s. -First, it retreives the `message`'s `route` using the `Msg.Route()` method. Then, using the application's [`router`](#routing) and the `route`, it checks for the existence of a `handler`. At this point, if `mode == runTxModeCheck`, `RunMsgs` returns. If instead `mode == runTxModeDeliver`, the [`handler`](../building-modules/handler.md) function for the message is executed, before `RunMsgs` returns. +First, it retreives the `message`'s `route` using the `Msg.Route()` method. Then, using the application's [`router`](#routing) and the `route`, it checks for the existence of a `handler`. At this point, if `mode == runTxModeCheck`, `RunMsgs` returns. If instead `mode == runTxModeDeliver`, the [`handler`](../building-modules/handler.md) function for the message is executed, before `RunMsgs` returns. ## Other ABCI Messages @@ -329,9 +282,9 @@ First, it retreives the `message`'s `route` using the `Msg.Route()` method. Then The [`InitChain` ABCI message](https://tendermint.com/docs/app-dev/abci-spec.html#initchain) is sent from the underlying Tendermint engine when the chain is first started. It is mainly used to **initialize** parameters and state like: -- [Consensus Parameters](https://tendermint.com/docs/spec/abci/apps.html#consensus-parameters) via `setConsensusParams`. +- [Consensus Parameters](https://tendermint.com/docs/spec/abci/apps.html#consensus-parameters) via `setConsensusParams`. - [`checkState` and `deliverState`](#volatile-states) via `setCheckState` and `setDeliverState`. -- The [block gas meter](../basics/accounts-fees-gas.md#block-gas-meter), with infinite gas to process genesis transactions. +- The [block gas meter](../basics/accounts-fees-gas.md#block-gas-meter), with infinite gas to process genesis transactions. Finally, the `InitChain(req abci.RequestInitChain)` method of `baseapp` calls the [`initChainer()`](../basics/app-anatomy.md#initchainer) of the application in order to initialize the main state of the application from the [`genesis file`](./genesis.md) and, if defined, call the `InitGenesis` function of each of the application's modules. @@ -339,37 +292,37 @@ Finally, the `InitChain(req abci.RequestInitChain)` method of `baseapp` calls th The [`BeginBlock` ABCI message](#https://tendermint.com/docs/app-dev/abci-spec.html#beginblock) is sent from the underlying Tendermint engine when a block proposal created by the correct proposer is received, before [`DeliverTx`](#delivertx) is run for each transaction in the block. It allows developers to have logic be executed at the beginning of each block. In the Cosmos SDK, the `BeginBlock(req abci.RequestBeginBlock)` method does the following: -- Initialize [`deliverState`](#volatile-states) with the latest header using the `req abci.RequestBeginBlock` passed as parameter via the [`setDeliverState`](https://github.com/cosmos/cosmos-sdk/blob/master/baseapp/baseapp.go#L283-L289) function. -- Initialize the [block gas meter](../basics/accounts-fees-gas.md#block-gas-meter) with the `maxGas` limit. The `gas` consumed within the block cannot go above `maxGas`. This parameter is defined in the application's consensus parameters. +- Initialize [`deliverState`](#volatile-states) with the latest header using the `req abci.RequestBeginBlock` passed as parameter via the [`setDeliverState`](https://github.com/cosmos/cosmos-sdk/blob/master/baseapp/baseapp.go#L283-L289) function. +- Initialize the [block gas meter](../basics/accounts-fees-gas.md#block-gas-meter) with the `maxGas` limit. The `gas` consumed within the block cannot go above `maxGas`. This parameter is defined in the application's consensus parameters. - Run the application's [`begingBlocker()`](../basics/app-anatomy.md#beginblocker-and-endblock), which mainly runs the `BeginBlocker()` method of each of the application's modules. - Set the [`VoteInfos`](https://tendermint.com/docs/app-dev/abci-spec.html#voteinfo) of the application, i.e. the list of validators whose *precommit* for the previous block was included by the proposer of the current block. This information is carried into the [`Context`](./context.md) so that it can be used during `DeliverTx` and `EndBlock`. ### EndBlock -The [`EndBlock` ABCI message](#https://tendermint.com/docs/app-dev/abci-spec.html#endblock) is sent from the underlying Tendermint engine after [`DeliverTx`](#delivertx) as been run for each transactioni n the block. It allows developers to have logic be executed at the end of each block. In the Cosmos SDK, the bulk `EndBlock(req abci.RequestEndBlock)` method is to run the application's [`endBlocker()`](../basics/app-anatomy.md#beginblocker-and-endblock), which mainly runs the `EndBlocker()` method of each of the application's modules. +The [`EndBlock` ABCI message](#https://tendermint.com/docs/app-dev/abci-spec.html#endblock) is sent from the underlying Tendermint engine after [`DeliverTx`](#delivertx) as been run for each transactioni n the block. It allows developers to have logic be executed at the end of each block. In the Cosmos SDK, the bulk `EndBlock(req abci.RequestEndBlock)` method is to run the application's [`endBlocker()`](../basics/app-anatomy.md#beginblocker-and-endblock), which mainly runs the `EndBlocker()` method of each of the application's modules. ### Commit -The [`Commit` ABCI message](https://tendermint.com/docs/app-dev/abci-spec.html#commit) is sent from the underlying Tendermint engine after the full-node has received *precommits* from 2/3+ of validators (weighted by voting power). On the `baseapp` end, the `Commit(res abci.ResponseCommit)` function is implemented to commit all the valid state transitions that occured during `BeginBlock`, `DeliverTx` and `EndBlock` and to reset state for the next block. +The [`Commit` ABCI message](https://tendermint.com/docs/app-dev/abci-spec.html#commit) is sent from the underlying Tendermint engine after the full-node has received *precommits* from 2/3+ of validators (weighted by voting power). On the `baseapp` end, the `Commit(res abci.ResponseCommit)` function is implemented to commit all the valid state transitions that occured during `BeginBlock`, `DeliverTx` and `EndBlock` and to reset state for the next block. To commit state-transitions, the `Commit` function calls the `Write()` function on `deliverState.ms`, where `deliverState.ms` is a cached multistore of the main store `app.cms`. Then, the `Commit` function sets `checkState` to the latest header (obtbained from `deliverState.ctx.BlockHeader`) and `deliverState` to `nil`. -Finally, `Commit` returns the hash of the commitment of `app.cms` back to the underlying consensus engine. This hash is used as a reference in the header of the next block. +Finally, `Commit` returns the hash of the commitment of `app.cms` back to the underlying consensus engine. This hash is used as a reference in the header of the next block. ### Info -The [`Info` ABCI message](https://tendermint.com/docs/app-dev/abci-spec.html#info) is a simple query from the underlying consensus engine, notably used to sync the latter with the application during a handshake that happens on startup. When called, the `Info(res abci.ResponseInfo)` function from `baseapp` will return the application's name, version and the hash of the last commit of `app.cms`. +The [`Info` ABCI message](https://tendermint.com/docs/app-dev/abci-spec.html#info) is a simple query from the underlying consensus engine, notably used to sync the latter with the application during a handshake that happens on startup. When called, the `Info(res abci.ResponseInfo)` function from `baseapp` will return the application's name, version and the hash of the last commit of `app.cms`. -### Query +### Query -The [`Query` ABCI message](https://tendermint.com/docs/app-dev/abci-spec.html#query) is used to serve queries received from the underlying consensus engine, including queries received via RPC like Tendermint RPC. It is the main entrypoint to build interfaces with the application. The application must respect a few rules when implementing the `Query` method, which are outlined [here](https://tendermint.com/docs/app-dev/abci-spec.html#query). +The [`Query` ABCI message](https://tendermint.com/docs/app-dev/abci-spec.html#query) is used to serve queries received from the underlying consensus engine, including queries received via RPC like Tendermint RPC. It is the main entrypoint to build interfaces with the application. The application must respect a few rules when implementing the `Query` method, which are outlined [here](https://tendermint.com/docs/app-dev/abci-spec.html#query). The `baseapp` implementation of the `Query(req abci.RequestQuery)` method is a simple dispatcher serving 4 main categories of queries: - Application-related queries like querying the application's version, which are served via the `handleQueryApp` method. -- Direct queries to the multistore, which are served by the `handlerQueryStore` method. These direct queryeis are different from custom queries which go through `app.queryRouter`, and are mainly used by third-party service provider like block explorers. +- Direct queries to the multistore, which are served by the `handlerQueryStore` method. These direct queryeis are different from custom queries which go through `app.queryRouter`, and are mainly used by third-party service provider like block explorers. - P2P queries, which are served via the `handleQueryP2P` method. These queries return either `app.addrPeerFilter` or `app.ipPeerFilter` that contain the list of peers filtered by address or IP respectively. These lists are first initialized via `options` in `baseapp`'s [constructor](#constructor). -- Custom queries, which encompass most queries, are served via the `handleQueryCustom` method. The `handleQueryCustom` cache-wraps the multistore before using the `queryRoute` obtained from [`app.queryRouter`](#query-routing) to map the query to the appropriate module's [`querier`](../building-modules/querier.md). +- Custom queries, which encompass most queries, are served via the `handleQueryCustom` method. The `handleQueryCustom` cache-wraps the multistore before using the `queryRoute` obtained from [`app.queryRouter`](#query-routing) to map the query to the appropriate module's [`querier`](../building-modules/querier.md). ## Next diff --git a/docs/core/node.md b/docs/core/node.md index 36fe12602d0d..85c6152542ad 100644 --- a/docs/core/node.md +++ b/docs/core/node.md @@ -2,7 +2,7 @@ ## Pre-Requisite Reading -## main function +## `main` function TODO diff --git a/docs/intro/README.md b/docs/intro/README.md index e676fd179b16..9df4e13e443c 100644 --- a/docs/intro/README.md +++ b/docs/intro/README.md @@ -2,15 +2,15 @@ ## What is the SDK? -The [Cosmos-SDK](https://github.com/cosmos/cosmos-sdk) is an open-source framework for building multi-asset public Proof-of-Stake (PoS) blockchains, like the Cosmos Hub, as well as permissionned Proof-Of-Authority (PoA) blockchains. Blockchains built with the Cosmos SDK are generally referred to as **application-specific blockchains**. +The [Cosmos-SDK](https://github.com/cosmos/cosmos-sdk) is an open-source framework for building multi-asset public Proof-of-Stake (PoS) blockchains, like the Cosmos Hub, as well as permissioned Proof-Of-Authority (PoA) blockchains. Blockchains built with the Cosmos SDK are generally referred to as **application-specific blockchains**. -The goal of the Cosmos SDK is to allow developers to easily create custom blockchains from scratch that can natively interoperate with other blockchains. We envision the SDK as the npm-like framework to build secure blockchain applications on top of [Tendermint](https://github.com/tendermint/tendermint). SDK-based blockchains are built out of composable modules, most of which are open source and readily available for any developers to use. Anyone can create a module for the Cosmos-SDK, and integrating already-built modules is as simple as importing them into your blockchain application. What's more, the Cosmos SDK is a capabilities-based system, which allows developer to better reason about the security of interactions between modules. For a deeper look at capabilities, jump to [this section](./ocap.md). +The goal of the Cosmos SDK is to allow developers to easily create custom blockchains from scratch that can natively interoperate with other blockchains. We envision the SDK as the npm-like framework to build secure blockchain applications on top of [Tendermint](https://github.com/tendermint/tendermint). SDK-based blockchains are built out of composable modules, most of which are open source and readily available for any developers to use. Anyone can create a module for the Cosmos-SDK, and integrating already-built modules is as simple as importing them into your blockchain application. What's more, the Cosmos SDK is a capabilities-based system, which allows developers to better reason about the security of interactions between modules. For a deeper look at capabilities, jump to [this section](./ocap.md). ## What are Application-Specific Blockchains? One development paradigm in the blockchain world today is that of virtual-machine blockchains like Ethereum, where development generally revolves around building a decentralised applications on top of an existing blockchain as a set of smart contracts. While smart contracts can be very good for some use cases like single-use applications (e.g. ICOs), they often fall short for building complex decentralised platforms. More generally, smart contracts can be limiting in terms of flexibility, sovereignty and performance. -Application-specific blockchains offer a radically different development paradigm than virtual-machine blockchains. An application-specific blockchain is a blockchain customized to operate a single application: developers have all the freedom to make the design decisions required for the application to run optimally. They can also provide better sovereignty, security and performance. +Application-specific blockchains offer a radically different development paradigm than virtual-machine blockchains. An application-specific blockchain is a blockchain customized to operate a single application: developers have all the freedom to make the design decisions required for the application to run optimally. They can also provide better sovereignty, security and performance. To learn more about application-specific blockchains, [click here](./why-app-specific.md). @@ -18,12 +18,13 @@ To learn more about application-specific blockchains, [click here](./why-app-spe The Cosmos SDK is the most advanced framework for building custom application-specific blockchains today. Here are a few reasons why you might want to consider building your decentralised application with the Cosmos SDK: -- The default consensus engine available within the SDK is [Tendermint Core](https://github.com/tendermint/tendermint). Tendermint is the most (and only) mature BFT consensus engine in existence. It is widely used accross the industry and is considered the gold standard consensus engine for building Proof-of-Stake systems. -- The SDK is open source and designed to make it easy to build blockchains out of composable modules. As the ecosystem of open source SDK modules grow, it will become increasingly easier to build complex decentralised platforms with it. -- The SDK is inspired by capabilities-based security, and informed by years of wrestling with blockchain state-machines. This makes the Cosmos SDK a very secure environment to build blockchains. -- Most importantly, the Cosmos SDK has already been used to build many application-specific blockchains that are already in production. Among others, we can cite [Cosmos Hub](https://hub.cosmos.network), [Iris](https://irisnet.org), [Binance Chain](https://docs.binance.org/), [Terra](https://terra.money/) or [Lino](https://lino.network/). Many more are building on the Cosmos SDK. You can get a view of the ecosystem [here](https://cosmos.network/ecosystem). +- The default consensus engine available within the SDK is [Tendermint Core](https://github.com/tendermint/tendermint). Tendermint is the most (and only) mature BFT consensus engine in existence. It is widely used across the industry and is considered the gold standard consensus engine for building Proof-of-Stake systems. +- The SDK is open source and designed to make it easy to build blockchains out of composable modules. As the ecosystem of open source SDK modules grow, it will become increasingly easier to build complex decentralised platforms with it. +- The SDK is inspired by capabilities-based security, and informed by years of wrestling with blockchain state-machines. This makes the Cosmos SDK a very secure environment to build blockchains. +- Most importantly, the Cosmos SDK has already been used to build many application-specific blockchains that are already in production. Among others, we can cite [Cosmos Hub](https://hub.cosmos.network), [IRIS Hub](https://irisnet.org), [Binance Chain](https://docs.binance.org/), [Terra](https://terra.money/) or [Lino](https://lino.network/). Many more are building on the Cosmos SDK. You can get a view of the ecosystem [here](https://cosmos.network/ecosystem). ## Getting started with the Cosmos SDK - Learn more about the [architecture of an SDK application](./sdk-app-architecture.md) - Learn how to build an application-specific blockchain from scratch with the [SDK Tutorial](https://cosmos.network/docs/tutorial) + diff --git a/docs/intro/sdk-app-architecture.md b/docs/intro/sdk-app-architecture.md index a420fe627c33..94007a2742dc 100644 --- a/docs/intro/sdk-app-architecture.md +++ b/docs/intro/sdk-app-architecture.md @@ -1,12 +1,12 @@ # SDK Application Architecture -## State machine +## State machine -At its core, a blockchain is a [replicated deterministic state machine](https://en.wikipedia.org/wiki/State_machine_replication). +At its core, a blockchain is a [replicated deterministic state machine](https://en.wikipedia.org/wiki/State_machine_replication). -A state machine is a computer science concept whereby a machine can have multiple states, but only one at any given time. There is a `state`, which describes the current state of the system, and `transactions`, that trigger state transitions. +A state machine is a computer science concept whereby a machine can have multiple states, but only one at any given time. There is a `state`, which describes the current state of the system, and `transactions`, that trigger state transitions. -Given a state S and a transaction T, the state machine will return a new state S'. +Given a state S and a transaction T, the state machine will return a new state S'. ``` +--------+ +--------+ @@ -26,9 +26,9 @@ In practice, the transactions are bundled in blocks to make the process more eff +--------+ +--------+ ``` -In a blockchain context, the state machine is deterministic. This means that if you start at a given state and replay the same sequence of transactions, you will always end up with the same final state. +In a blockchain context, the state machine is deterministic. This means that if you start at a given state and replay the same sequence of transactions, you will always end up with the same final state. -The Cosmos SDK gives you maximum flexibility to define the state of your application, transaction types and state transition functions. The process of building the state-machine with the SDK will be described more in depth in the following sections. But first, let us see how it is replicated using **Tendermint**. +The Cosmos SDK gives you maximum flexibility to define the state of your application, transaction types and state transition functions. The process of building the state-machine with the SDK will be described more in depth in the following sections. But first, let us see how it is replicated using **Tendermint**. ### Tendermint @@ -54,14 +54,14 @@ Blockchain node | | Consensus | | Tendermint is an application-agnostic engine that is responsible for handling the *networking* and *consensus* layers of your blockchain. In practice, this means that Tendermint is responsible for propagating and ordering transaction bytes. Tendermint Core relies on an eponymous Byzantine-Fault-Tolerant (BFT) algorithm to reach consensus on the order of transactions. For more on Tendermint, click [here](https://tendermint.com/docs/introduction/what-is-tendermint.html). -Tendermint consensus algorithm works with a set of special nodes called *Validators*. Validators are responsible for adding blocks of transactions to the blockchain. At any given block, there is a validator set V. A validator in V is chosen by the algorithm to be the proposer of the next block. This block is considered valid if more than two thirds of V signed a *[prevote](https://tendermint.com/docs/spec/consensus/consensus.html#prevote-step-height-h-round-r)* and a *[precommit](https://tendermint.com/docs/spec/consensus/consensus.html#precommit-step-height-h-round-r)* on it, and if all the transactions that it contains are valid. The validator set can be changed by rules written in the state-machine. For a deeper look at the algorithm, click [here](https://tendermint.com/docs/introduction/what-is-tendermint.html#consensus-overview). +The Tendermint consensus algorithm works with a set of special nodes called *Validators*. Validators are responsible for adding blocks of transactions to the blockchain. At any given block, there is a validator set V. A validator in V is chosen by the algorithm to be the proposer of the next block. This block is considered valid if more than two thirds of V signed a *[prevote](https://tendermint.com/docs/spec/consensus/consensus.html#prevote-step-height-h-round-r)* and a *[precommit](https://tendermint.com/docs/spec/consensus/consensus.html#precommit-step-height-h-round-r)* on it, and if all the transactions that it contains are valid. The validator set can be changed by rules written in the state-machine. For a deeper look at the algorithm, click [here](https://tendermint.com/docs/introduction/what-is-tendermint.html#consensus-overview). -The main part of a Cosmos SDK application is a blockchain daemon that is run by each node in the network locally. If less than one third of the *validator set* is byzantine (i.e. malicious), then each node should obtain the same result when querying the state at the same time. +The main part of a Cosmos SDK application is a blockchain daemon that is run by each node in the network locally. If less than one third of the *validator set* is byzantine (i.e. malicious), then each node should obtain the same result when querying the state at the same time. ## ABCI -Tendermint passes transactions from the network to the application through an interface called the [ABCI](https://github.com/tendermint/tendermint/tree/master/abci), which the application must implement. +Tendermint passes transactions from the network to the application through an interface called the [ABCI](https://github.com/tendermint/tendermint/tree/master/abci), which the application must implement. ``` +---------------------+ @@ -81,16 +81,16 @@ Tendermint passes transactions from the network to the application through an in +---------------------+ ``` -Note that **Tendermint only handles transaction bytes**. It has no knowledge of what these bytes mean. All Tendermint does is order these transaction bytes deterministically. Tendermint passes the bytes to the application via the ABCI, and expects a return code to inform it if the messages contained in the transactions were successfully processed or not. +Note that **Tendermint only handles transaction bytes**. It has no knowledge of what these bytes mean. All Tendermint does is order these transaction bytes deterministically. Tendermint passes the bytes to the application via the ABCI, and expects a return code to inform it if the messages contained in the transactions were successfully processed or not. Here are the most important messages of the ABCI: -- `CheckTx`: When a transaction is received by Tendermint Core, it is passed to the application to check if a few basic requirements are met. `CheckTx` is used to protect the mempool of full-nodes against spam. A special handler called the "Ante Handler" is used to execute a series of validation steps such as checking for sufficient fees and validating the signatures. If the check is valid, the transaction is added to the [mempool](https://tendermint.com/docs/spec/reactors/mempool/functionality.html#mempool-functionality) and relayed to peer nodes. Note that transactions are not processed (i.e. no modification of the state occurs) with `CheckTx` since they have not been included in a block yet. +- `CheckTx`: When a transaction is received by Tendermint Core, it is passed to the application to check if a few basic requirements are met. `CheckTx` is used to protect the mempool of full-nodes against spam. A special handler called the "Ante Handler" is used to execute a series of validation steps such as checking for sufficient fees and validating the signatures. If the check is valid, the transaction is added to the [mempool](https://tendermint.com/docs/spec/reactors/mempool/functionality.html#mempool-functionality) and relayed to peer nodes. Note that transactions are not processed (i.e. no modification of the state occurs) with `CheckTx` since they have not been included in a block yet. - `DeliverTx`: When a [valid block](https://tendermint.com/docs/spec/blockchain/blockchain.html#validation) is received by Tendermint Core, each transaction in the given block is passed to the application via `DeliverTx` to be processed. It is during this stage that the state transitions occur. The "Ante Handler" executes again along with the actual handlers for each message in the transaction. - - `BeginBlock`/`EndBlock`: These messages are executed at the beginning and the end of each block, whether the block contains transaction or not. It is useful to trigger automatic execution of logic. Proceed with caution though, as computationally expensive loops could slow down your blockchain, or even freeze it if the loop is infinite. + - `BeginBlock`/`EndBlock`: These messages are executed at the beginning and the end of each block, whether the block contains transaction or not. It is useful to trigger automatic execution of logic. Proceed with caution though, as computationally expensive loops could slow down your blockchain, or even freeze it if the loop is infinite. For a more detailed view of the ABCI methods and types, click [here](https://tendermint.com/docs/spec/abci/abci.html#overview). Any application built on Tendermint needs to implement the ABCI interface in order to communicate with the underlying local Tendermint engine. Fortunately, you do not have to implement the ABCI interface. The Cosmos SDK provides a boilerplate implementation of it in the form of [baseapp](./sdk-design.md#baseapp). -### Next, let us go into the [high-level design principles of the SDK](./sdk-design.md) +### Next, let us go into the [high-level design principles of the SDK](./sdk-design.md) \ No newline at end of file diff --git a/docs/intro/why-app-specific.md b/docs/intro/why-app-specific.md index 0873f87d0e4a..1b160429f6eb 100644 --- a/docs/intro/why-app-specific.md +++ b/docs/intro/why-app-specific.md @@ -4,7 +4,7 @@ This document explains what application-specific blockchains are, and why develo ## What are application-specific blockchains? -Application-specific blockchains are blockchains customized to operate a single application. Instead of building a decentralised application on top of an underlying blockchain like Ethereum, developers build their own blockchain from the ground up. This means building a full-node client, a light-client, and all the necessary interfaces (CLI, REST, ...) to interract with the nodes. +Application-specific blockchains are blockchains customized to operate a single application. Instead of building a decentralised application on top of an underlying blockchain like Ethereum, developers build their own blockchain from the ground up. This means building a full-node client, a light-client, and all the necessary interfaces (CLI, REST, ...) to interract with the nodes. ``` ^ +-------------------------------+ ^ @@ -24,13 +24,13 @@ Blockchain node | | Consensus | | ## What are the shortcomings of Smart Contracts? -Virtual-machine blockchains like Ethereum addressed the demand for more programmability back in 2014. At the time, the options available for building decentralised applications were quite limited. Most developers would build on top of the complex and limited Bitcoin scripting language, or fork the Bitcoin codebase which was hard to work with and customize. +Virtual-machine blockchains like Ethereum addressed the demand for more programmability back in 2014. At the time, the options available for building decentralised applications were quite limited. Most developers would build on top of the complex and limited Bitcoin scripting language, or fork the Bitcoin codebase which was hard to work with and customize. Virtual-machine blockchains came in with a new value proposition. Their state-machine incorporates a virtual-machine that is able to interpret turing-complete programs called Smart Contracts. These Smart Contracts are very good for use cases like one-time events (e.g. ICOs), but they can fall short for building complex decentralised platforms: -- Smart Contracts are generally developed with specific programming languages that can be interpreted by the underlying virtual-machine. These programming languages are often immature and inherently limited by the constraints of the virtual-machine. For example, the Ethereum Virtual Machine does not allow developers to implement automatic execution of code. Developers are also limited to the account-based system of the EVM, and they can only choose from a limited set of functions for their cryptographic operations. These are examples, but they hint at the lack of **flexibility** a smart contract environment often entails. +- Smart Contracts are generally developed with specific programming languages that can be interpreted by the underlying virtual-machine. These programming languages are often immature and inherently limited by the constraints of the virtual-machine. For example, the Ethereum Virtual Machine does not allow developers to implement automatic execution of code. Developers are also limited to the account-based system of the EVM, and they can only choose from a limited set of functions for their cryptographic operations. These are examples, but they hint at the lack of **flexibility** a smart contract environment often entails. - Smart Contracts are all run by the same virtual machine. This means that they compete for resources, which can severly restrain **performance**. And even if the state-machine were to be split in multiple subsets (e.g. via sharding), Smart Contracts would still need to be interpeted by a virtual machine, which would limit performance compared to a native application implemented at state-machine level (our benchmarks show an improvement on the order of x10 in performance when the virtual-machine is removed). -- Another issue with the fact that Smart Contracts share the same underlying environment is the resulting limitation in **sovereignty**. A decentralised application is an ecosystem that involves multiple players. If the application is built on a general-purpose virtual-machine blockchain, these players have very limited sovereignty over it, and are ultimately superseded by the governance of the underlying blockchain. If there is a bug in the application, very little can be done about it. +- Another issue with the fact that Smart Contracts share the same underlying environment is the resulting limitation in **sovereignty**. A decentralised application is an ecosystem that involves multiple players. If the application is built on a general-purpose virtual-machine blockchain, these players have very limited sovereignty over it, and are ultimately superseded by the governance of the underlying blockchain. If there is a bug in the application, very little can be done about it. Application-Specific Blockchains are designed to address these shortcomings. @@ -40,35 +40,36 @@ Application-Specific Blockchains are designed to address these shortcomings. Application-specific blockchains give maximum flexibility to developers: -- Developers can choose among multiple frameworks to build their state-machine. The most widely used today is the Cosmos SDK, but others exist (e.g. Lotion, Weave, ...). The choice will most of the time be done based on the programming language they want to use (Cosmos SDK and Weave are in Golang, Lotion is in Javascript, ...). -- Developers can swap consensus engine. Today, only Tendermint is production-ready, but in the future other engines are expected to emerge. -- Even when they settle for a framework and consensus engine, developers still have the freedom to tweak them if they don't perfectly match their requirements in their pristine forms. -- Developers are free to explore the full spectrum of tradeoffs (e.g. number of validators vs transaction throughput, safety vs availability in asynchrony, ...) and design choices (DB or IAVL tree for storage, UTXO or account model, ...). -- Developers can implement automatic execution of code. In the Cosmos SDK, logic can be automatically triggered at the beginning and the end of each block. They are also free to choose the cryptographic library used in their application, as opposed to being constrained by what is made available by the underlying environment in the case of virtual-machine blockchains. +- In Cosmos blockchains, the state-machine is typically connected to the underlying consensus engine via an interface called the [ABCI](https://tendermint.com/docs/spec/abci/). This interface can be wrapped in any programming language, meaning developers can build their state-machine in the programming language of their choice. +- Developers can choose among multiple frameworks to build their state-machine. The most widely used today is the Cosmos SDK, but others exist (e.g. [Lotion](https://github.com/nomic-io/lotion), [Weave](https://github.com/iov-one/weave), ...). The choice will most of the time be done based on the programming language they want to use (Cosmos SDK and Weave are in Golang, Lotion is in Javascript, ...). +- The ABCI also allows developers to swap the consensus engine of their application-specific blockchain. Today, only Tendermint is production-ready, but in the future other engines are expected to emerge. +- Even when they settle for a framework and consensus engine, developers still have the freedom to tweak them if they don't perfectly match their requirements in their pristine forms. +- Developers are free to explore the full spectrum of tradeoffs (e.g. number of validators vs transaction throughput, safety vs availability in asynchrony, ...) and design choices (DB or IAVL tree for storage, UTXO or account model, ...). +- Developers can implement automatic execution of code. In the Cosmos SDK, logic can be automatically triggered at the beginning and the end of each block. They are also free to choose the cryptographic library used in their application, as opposed to being constrained by what is made available by the underlying environment in the case of virtual-machine blockchains. -The list above contains a few examples that show how much flexibility application-specific blockchains give to developers. The goal of Cosmos and the Cosmos SDK is to make developer tooling as generic and composable as possible, so that each part of the stack can be forked, tweaked and improved without losing compatibility. As the community grows, more alternative for each of the core building blocks will emerge, giving more options to developers. +The list above contains a few examples that show how much flexibility application-specific blockchains give to developers. The goal of Cosmos and the Cosmos SDK is to make developer tooling as generic and composable as possible, so that each part of the stack can be forked, tweaked and improved without losing compatibility. As the community grows, more alternative for each of the core building blocks will emerge, giving more options to developers. ### Performance Decentralised applications built with Smart Contracts are inherently capped in performance by the underlying environment. For a decentralised application to optimise performance, it needs to be built as an application-specific blockchains. Here are the benefits of an application-specific blockchains with regards to performance: -- Developers of application-specific blockchains can choose to operate with novel consensus engine such as Tendermint BFT. Compared to Proof-of-Work (used by most virtual-machine blockchains today), it offers significant gains in throuhgput. -- An application-specific blockchain only operates a single application, so that the application does not compete with others for computation. This is the opposite of most non-sharded virtual-machine blockchains today, where smart contracts all compete for computation. -- Even if a virtual-machine blockchain offered application-based sharding coupled with an efficient consensus algorithm, performance would still be limited by the virtual-machine itself. The real throughput bottleneck is the state-machine, and requiring transactions to be interpreted by a virtual-machine significantly increases the computational complexity of processing them. +- Developers of application-specific blockchains can choose to operate with novel consensus engine such as Tendermint BFT. Compared to Proof-of-Work (used by most virtual-machine blockchains today), it offers significant gains in throuhgput. +- An application-specific blockchain only operates a single application, so that the application does not compete with others for computation and storage. This is the opposite of most non-sharded virtual-machine blockchains today, where smart contracts all compete for computation and storage. +- Even if a virtual-machine blockchain offered application-based sharding coupled with an efficient consensus algorithm, performance would still be limited by the virtual-machine itself. The real throughput bottleneck is the state-machine, and requiring transactions to be interpreted by a virtual-machine significantly increases the computational complexity of processing them. -### Security +### Security Security is hard to quantify, and greatly varies from platform to platform. That said here are some important benefits an application-specific blockchain can bring in terms of security: -- Developers can choose proven programming language like Golang when building their application-specific blockchains, as opposed to smart contract programming languages that are often more immature. -- Developers are not constrained by the cryptographic functions made available by the underlying virtual-machines. They can use their own custom cryptography, and rely on well-audited crypto libraries. -- Developers do not have to worry about potential bugs or exploitable mechanisms in the underlying virtual-machine, making it easier to reason about the security of the application. +- Developers can choose proven programming languages like Golang when building their application-specific blockchains, as opposed to smart contract programming languages that are often more immature. +- Developers are not constrained by the cryptographic functions made available by the underlying virtual-machines. They can use their own custom cryptography, and rely on well-audited crypto libraries. +- Developers do not have to worry about potential bugs or exploitable mechanisms in the underlying virtual-machine, making it easier to reason about the security of the application. ### Sovereignty -One of the major benefits of application-specific blockchains is sovereignty. A decentralised application is an ecosystem that involves many actors: users, developers, third-party services, and more. When developers build on virtual-machine blockchain where many decentralised applications coexist, the community of the application is different than the community of the underlying blockchain, and the latter supersedes the former. If there is a bug or if a new feature is needed, the community of the application has very little sovereignty to upgrade the code. If the community of the underlying blockchain refuses to act, nothing can happen. +One of the major benefits of application-specific blockchains is sovereignty. A decentralised application is an ecosystem that involves many actors: users, developers, third-party services, and more. When developers build on virtual-machine blockchain where many decentralised applications coexist, the community of the application is different than the community of the underlying blockchain, and the latter supersedes the former. If there is a bug or if a new feature is needed, the community of the application has very little sovereignty to upgrade the code. If the community of the underlying blockchain refuses to act, nothing can happen. -The fundamental issue here is that the governance of the application and the governance of the network are not aligned. This issue is solved by application-specific blockchains. Because application-specific blockchains specialize to operate a single application, the community of the application has full control over the entire chain. This ensures the community will not be stuck if a bug is discovered, and that it has the entire freedom to choose how it is going to evolve. +The fundamental issue here is that the governance of the application and the governance of the network are not aligned. This issue is solved by application-specific blockchains. Because application-specific blockchains specialize to operate a single application, the community of the application has full control over the entire chain. This ensures the community will not be stuck if a bug is discovered, and that it has the entire freedom to choose how it is going to evolve. ## Start Building Your Application-Specific Blockchain Today From 5b24d33068470b482bfeb661b6a52081092517cb Mon Sep 17 00:00:00 2001 From: Gloria Zhao Date: Wed, 21 Aug 2019 14:32:01 -0700 Subject: [PATCH 106/196] deleted some --- docs/basics/app-anatomy.md | 103 +++++++++------- docs/building-modules/modules-manager.md | 147 ----------------------- docs/concepts/encoding.md | 3 - docs/concepts/tx-msgs.md | 5 - 4 files changed, 58 insertions(+), 200 deletions(-) delete mode 100644 docs/building-modules/modules-manager.md delete mode 100644 docs/concepts/encoding.md delete mode 100644 docs/concepts/tx-msgs.md diff --git a/docs/basics/app-anatomy.md b/docs/basics/app-anatomy.md index dc58e389342a..15e1c9fc1e22 100644 --- a/docs/basics/app-anatomy.md +++ b/docs/basics/app-anatomy.md @@ -55,7 +55,7 @@ Blockchain Node | | Consensus | | The blockchain full-node presents itself as a binary, generally suffixed by `-d` for "daemon" (e.g. `appd` for `app` or `gaiad` for `gaia`). This binary is built by running a simple `main.go` function placed in `cmd/appd/`. This operation usually happens through the [Makefile](#dependencies-and-makefile). -To learn more about the `main.go` function, [click here](./node.md#main-function). +To learn more about the `main.go` function, [click here](../core/node.md#main-function). Once the main binary is built, the node can be started by running the `start` command. The core logic behind the `start` command is implemented in the SDK itself in the [`/server/start.go`](https://github.com/cosmos/cosmos-sdk/blob/master/server/start.go) file. The main [`start` command function](https://github.com/cosmos/cosmos-sdk/blob/master/server/start.go#L31) takes a [`context`](https://godoc.org/github.com/cosmos/cosmos-sdk/client/context) and [`appCreator`](<#constructor-function-(`appCreator`)>) as arguments. The `appCreator` is a constructor function for the SDK application, and is used in the starting process of the full-node. @@ -73,11 +73,11 @@ In general, the core of the state-machine is defined in a file called `app.go`. The first thing defined in `app.go` is the `type` of the application. It is generally comprised of the following parts: -- **A reference to [`baseapp`](./baseapp.md).** The custom application defined in `app.go` is an extension of the `baseapp` type. `baseapp` implements most of the core logic for the application, including all the [ABCI methods](https://tendermint.com/docs/spec/abci/abci.html#overview) and the routing logic. When a transaction is relayed by Tendermint to the application, the latter uses `baseapp`'s methods to route them to the appropriate module. -- **A list of store keys**. The [store](./store.md), which contains the entire state, is implemented as a multistore (i.e. a store of stores) in the Cosmos SDK. Each module uses one or multiple stores in the multistore to persist their part of the state. These stores can be accessed with specific keys that are declared in the `app` type. These keys, along with the `keepers`, are at the heart of the [object-capabilities model](../intro/ocap.md) of the Cosmos SDK. -- **A list of module's `keepers`.** Each module defines an abstraction called `keeper`, which handles reads and writes for this module's store(s). The `keeper`'s methods of one module can be called from other modules (if authorized), which is why they are declared in the application's type and exported as interfaces to other modules so that they are only allowed to access the authorized functions. -- **A reference to a `codec`.** The Cosmos SDK gives developers the freedom to choose the encoding framework for their application. The application's `codec` is used to serialize and deserialize data structures in order to store them, as stores can only persist `[]bytes`. The `codec` must be deterministic. The default codec is [amino](./amino.md). -- **A reference to a [module manager](./modules.md#module-manager)**. The module manager is an object that contains a list of the application's module. It facilitates operations related to these modules, like registering [`routes`](./baseapp.md#routing), [query routes](#./baseapp.md#query-routing) or setting the order of execution between modules for various functions like [`InitChainer`](#initchainer), [`BeginBlocker` and `EndBlocker`](#beginblocker-and-endblocker). +- **A reference to [`baseapp`](../core/baseapp.md).** The custom application defined in `app.go` is an extension of the `baseapp` type. `baseapp` implements most of the core logic for the application, including all the [ABCI methods](https://tendermint.com/docs/spec/abci/abci.html#overview) and the routing logic. When a transaction is relayed by Tendermint to the application, the latter uses `baseapp`'s methods to route them to the appropriate module. +- **A list of store keys**. The [store](../core/store.md), which contains the entire state, is implemented as a multistore (i.e. a store of stores) in the Cosmos SDK. Each module uses one or multiple stores in the multistore to persist their part of the state. These stores can be accessed with specific keys that are declared in the `app` type. These keys, along with the `keepers`, are at the heart of the [object-capabilities model](../intro/ocap.md) of the Cosmos SDK. +- **A list of module's `keepers`.** Each module defines an abstraction called [`keeper`](../building-modules/keeper.md), which handles reads and writes for this module's store(s). The `keeper`'s methods of one module can be called from other modules (if authorized), which is why they are declared in the application's type and exported as interfaces to other modules so that they are only allowed to access the authorized functions. +- **A reference to a [`codec`](../core/encoding.md).** The Cosmos SDK gives developers the freedom to choose the encoding framework for their application. The application's `codec` is used to serialize and deserialize data structures in order to store them, as stores can only persist `[]bytes`. The `codec` must be deterministic. The default codec is [amino](./amino.md). +- **A reference to a [module manager](../building-modules/module-manager.md#manager)** and a [basic module manager](../building-modules/module-manager.md#basicmanager). The module manager is an object that contains a list of the application's module. It facilitates operations related to these modules, like registering [`routes`](./baseapp.md#routing), [query routes](#./baseapp.md#query-routing) or setting the order of execution between modules for various functions like [`InitChainer`](#initchainer), [`BeginBlocker` and `EndBlocker`](#beginblocker-and-endblocker). You can see an example of application type definition [here](https://github.com/cosmos/gaia/blob/master/app/app.go#L73-L107). @@ -85,18 +85,19 @@ You can see an example of application type definition [here](https://github.com/ This function constructs a new application of the type defined above. It is called every time the full-node is started with the [`start`](https://github.com/cosmos/cosmos-sdk/blob/master/server/start.go#L117) command. Here are the main actions performed by this function: +- Instantiate a new [`codec`](../core/encoding.md) and initialize the `codec` of each of the application's module using the [basic manager](../building-modules/module-manager.md#basicmanager) - Instantiate a new application with a reference to a `baseapp` instance, a codec and all the appropriate store keys. -- Instantiate all the [`keeper`s](#keeper) defined in the application's `type` using the `NewKeeper` function of each of the application's modules. Note that `keepers` must be instantiated in the correct order, as the `NewKeeper` of one module might require a reference to another module's `keeper`. -- Instantiate the application's [module manager](./module-manager.md) with the [`AppModule`](#application-module-interface) object of each of the application's modules. -- With the module manager, initialize the application's [`routes`](./baseapp.md#routing) and [query routes](./baseapp.md#query-routing). When a transaction is relayed to the application by Tendermint via the ABCI, it is routed to the appropriate module's [`handler`](#handler) using the routes defined here. Likewise, when a query is received by the application, it is routed to the appropriate module's [`querier`](#querier) using the query routes defined here. -- With the module manager, register the [application's modules' invariants](./invariants.md). Invariants are variables (e.g. total supply of a token) that are evaluated at the end of each block. The process of checking invariants is done via a special module called the [`InvariantsRegistry`](./invariants.md#invariant-registry). The value of the invariant should be equal to a predicted value defined in the module. Should the value be different than the predicted one, special logic defined in the invariant registry will be triggered (usually the chain is halted). This is useful to make sure no critical bug goes unnoticed and produces long-lasting effects that would be hard to fix. -- With the module manager, set the order of execution between the `InitGenesis`, `BegingBlocker` and `EndBlocker` functions of each of the [application's modules](#application-module-interface). Note that not all modules implement these functions. +- Instantiate all the [`keeper`s](#keeper) defined in the application's `type` using the `NewKeeper` function of each of the application's modules. Note that `keepers` must be instantiated in the correct order, as the `NewKeeper` of one module might require a reference to another module's `keeper`. +- Instantiate the application's [module manager](../building-modules/module-manager.md#manager) with the [`AppModule`](#application-module-interface) object of each of the application's modules. +- With the module manager, initialize the application's [`routes`](../core/baseapp.md#routing) and [query routes](../core/baseapp.md#query-routing). When a transaction is relayed to the application by Tendermint via the ABCI, it is routed to the appropriate module's [`handler`](#handler) using the routes defined here. Likewise, when a query is received by the application, it is routed to the appropriate module's [`querier`](#querier) using the query routes defined here. +- With the module manager, register the [application's modules' invariants](./invariants.md). Invariants are variables (e.g. total supply of a token) that are evaluated at the end of each block. The process of checking invariants is done via a special module called the [`InvariantsRegistry`](../building-modules/invariants.md#invariant-registry). The value of the invariant should be equal to a predicted value defined in the module. Should the value be different than the predicted one, special logic defined in the invariant registry will be triggered (usually the chain is halted). This is useful to make sure no critical bug goes unnoticed and produces long-lasting effects that would be hard to fix. +- With the module manager, set the order of execution between the `InitGenesis`, `BegingBlocker` and `EndBlocker` functions of each of the [application's modules](#application-module-interface). Note that not all modules implement these functions. - Set the remainer of application's parameters: - - [`InitChainer`](#initchainer): used to initialize the application when it is first started. - - [`BeginBlocker`, `EndBlocker`](#beginblocker-and-endlbocker): called at the beginning and the end of every block). - - [`anteHandler`](#baseapp.md#antehandler): used to handle fees and signature verification. -- Mount the stores. -- Return the application. + + [`InitChainer`](#initchainer): used to initialize the application when it is first started. + + [`BeginBlocker`, `EndBlocker`](#beginblocker-and-endlbocker): called at the beginning and the end of every block). + + [`anteHandler`](../core/baseapp.md#antehandler): used to handle fees and signature verification. +- Mount the stores. +- Return the application. Note that this function only creates an instance of the app, while the actual state is either carried over from the `~/.appd/data` folder if the node is restarted, or generated from the genesis file if the node is started for the first time. @@ -104,7 +105,7 @@ You can see an example of application constructor [here](https://github.com/cosm ### InitChainer -The `InitChainer` is a function that initializes the state of the application from a [genesis file](./genesis.md) (i.e. token balances of genesis accounts). It is called when the application receives the `InitChain` message from the Tendermint engine, which happens when the node is started at `appBlockHeight == 0` (i.e. on genesis). The application must set the `InitChainer` in its constructor via the [`SetInitChainer`](https://godoc.org/github.com/cosmos/cosmos-sdk/baseapp#BaseApp.SetInitChainer) method. +The `InitChainer` is a function that initializes the state of the application from a [genesis file](../core/genesis.md) (i.e. token balances of genesis accounts). It is called when the application receives the `InitChain` message from the Tendermint engine, which happens when the node is started at `appBlockHeight == 0` (i.e. on genesis). The application must set the `InitChainer` in its constructor via the [`SetInitChainer`](https://godoc.org/github.com/cosmos/cosmos-sdk/baseapp#BaseApp.SetInitChainer) method. In general, the `InitChainer` is mostly composed of the `InitGenesis` function of each of the application's modules. This is done by calling the `InitGenesis` function of the module manager, which in turn will call the `InitGenesis` function of each of the modules it contains. Note that the order in which the modules' `InitGenesis` functions must be called has to be set in the module manager using the `SetOrderInitGenesis` method. This is done in the [application's constructor](#application-constructor), and the `SetOrderInitGenesis` has to be called before the `SetInitChainer`. @@ -116,7 +117,7 @@ The SDK offers developers the possibility to implement automatic execution of co In general, the `BeginBlocker` and `EndBlocker` functions are mostly composed of the `BeginBlock` and `EndBlock` functions of each of the application's modules. This is done by calling the `BeginBlock` and `EndBlock` functions of the module manager, which in turn will call the `BeginBLock` and `EndBlock` functions of each of the modules it contains. Note that the order in which the modules' `BegingBlock` and `EndBlock` functions must be called has to be set in the module manager using the `SetOrderBeginBlock` and `SetOrderEndBlock` methods respectively. This is done in the [application's constructor](#application-constructor), and the `SetOrderBeginBlock` and `SetOrderEndBlock` methods have to be called before the `SetBeginBlocker` and `SetEndBlocker` functions. -As a sidenote, it is important to remember that application-specific blockchains are deterministic. Developers must be careful not to introduce non-determinism in `BeginBlocker` or `EndBlocker`, and must also be careful not to make them too computationally expensive, as gas does not constrain the cost of `BeginBlocker` and `EndBlocker` execution. +As a sidenote, it is important to remember that application-specific blockchains are deterministic. Developers must be careful not to introduce non-determinism in `BeginBlocker` or `EndBlocker`, and must also be careful not to make them too computationally expensive, as [gas](./accounts-fees-gas.md/gas) does not constrain the cost of `BeginBlocker` and `EndBlocker` execution. You can see an example of `BeginBlocker` and `EndBlocker` functions [here](https://github.com/cosmos/gaia/blob/master/app/app.go#L224-L232). @@ -124,53 +125,55 @@ You can see an example of `BeginBlocker` and `EndBlocker` functions [here](https The `MakeCodec` function is the last important function of the `app.go` file. The goal of this function is to instantiate a codec `cdc` (e.g. amino) initialize the codec of the SDK and each of the application's modules using the `RegisterCodec` function. -To register the application's modules, the `MakeCodec` function calls `RegisterCodec` on `ModuleBasics`. `ModuleBasics` is a basic manager which lists all of the application's modules. It is instantiated in the `init()` function, and only serves to easily register non-dependent elements of application's modules (such as codec). To learn more about the basic module manager,. +To register the application's modules, the `MakeCodec` function calls `RegisterCodec` on `ModuleBasics`. `ModuleBasics` is a [basic manager](../building-modules/module-manager.md#basicmanager) which lists all of the application's modules. It is instanciated in the `init()` function, and only serves to easily register non-dependant elements of application's modules (such as codec). To learn more about the basic module manager, click [here](../building-modules/module-manager.md#basicmanager). You can see an example of a `MakeCodec` [here](https://github.com/cosmos/gaia/blob/master/app/app.go#L64-L70) ## Modules -Modules are the heart and soul of an SDK application. They can be considered as state-machines within the state-machine. When a transaction is relayed from the underlying Tendermint engine via the ABCI to the application, it is routed by `baseapp` to the appropriate module in order to be processed. This paradigm enables developers to easily build complex state-machines, as most of the modules they need often already exist. For developers, most of the work involved in building an SDK application revolves around building custom modules required by their application that do not exist, and integrating them with modules that do already exist into one coherent application. In the application directory, the standard practice is to store modules in the `x/` folder (not to be confused with the SDK's `x/` folder, which contains already-built modules). +Modules are the heart and soul of an SDK application. They can be considered as state-machines within the state-machine. When a transaction is relayed from the underlying Tendermint engine via the ABCI to the application, it is routed by [`baseapp`](../core/baseapp.md) to the appropriate module in order to be processed. This paradigm enables developers to easily build complex state-machines, as most of the modules they need often already exist. For developers, most of the work involved in building an SDK application revolves around building custom modules required by their application that do not exist, and integrating them with modules that do already exist into one coherent application. In the application directory, the standard practice is to store modules in the `x/` folder (not to be confused with the SDK's `x/` folder, which contains already-built modules). + +To learn more about modules, [click here](./modules.md) ### Application Module Interface -Modules implement two interfaces defined in the Cosmos SDK, [`AppModuleBasic`](https://github.com/cosmos/cosmos-sdk/blob/master/types/module/module.go#L44-L57) and [`AppModule`](https://github.com/cosmos/cosmos-sdk/blob/master/types/module/module.go#L44-L57). The former implements basic non-dependant elements of the module, such as the `codec`, while the latter handles the bulk of the module methods (including methods that require references to other modules' `keeper`s). Both the `AppModule` and `AppModuleBasic` types are defined in a file called `./module.go`. +Modules implement two interfaces defined in the Cosmos SDK, [`AppModuleBasic`](../building-modules/module-manager.md#appmodulebasic) and [`AppModule`](../building-modules/module-manager.md#appmodule). The former implements basic non-dependant elements of the module, such as the `codec`, while the latter handles the bulk of the module methods (including methods that require references to other modules' `keeper`s). Both the `AppModule` and `AppModuleBasic` types are defined in a file called `./module.go`. -`AppModule` exposes a collection of useful methods on the module that facilitates the composition of modules into a coherent application. Important methods include: +`AppModule` exposes a collection of useful methods on the module that facilitates the composition of modules into a coherent application. These methods are are called from the `module manager`(../building-modules/module-manager.md#manager), which manages the application's collection of modules. -- `Route()` and `QueryRoute()`: These methods the name of the route and querier route for the module, for [messages](#message-types) to be routed to the module's [`handler`](#handler) and queries to be routes to the module's [`querier`](#querier). -- `NewHandler()` and `NewQuerierHandler()`: These methods return a `handler` and `querierHandler` respectively, in order to process a message or a query once they are routed. -- `BeginBlock()`, `EndBlock()` and `InitGenesis()`: These methods are executed respectively at the beginning of each block, at the end of each block and at the start of the chain. They implement special logic the module requires to be triggered during those events. For example, the `EndBlock` function is frequently used by modules where voting occurs to tally the result of the votes. -- `RegisterInvariants()`: This method registers the [invariants](./invariants.md) for the module. Invariants are checked at the end of every block to make sure no unpredicted behaviour is occuring. -- `AppModule`'s methods are called from the `module manager`, which manages the application's collection of modules. +To learn more about the application module interface, [click here](../building-modules/module-manager.md#application-module-interfaces). ### Message Types -A message is a custom type defined by each module that implements the [`message`](https://github.com/cosmos/cosmos-sdk/blob/master/types/tx_msg.go#L8-L29) interface. Each `transaction` contains one or multiple `messages`. When a valid block of transactions is received by the full-node, Tendermint relays each one to the application via [`DeliverTx`](https://tendermint.com/docs/app-dev/abci-spec.html#delivertx). Then, the application handles the transaction: +A message is a custom type defined by each module that implements the [`message`](../building-modules/messages-and-queries.md#messages) interface. Each [`transaction`](../core/transaction.md) contains one or multiple `messages`. When a valid block of transactions is received by the full-node, Tendermint relays each one to the application via [`DeliverTx`](https://tendermint.com/docs/app-dev/abci-spec.html#delivertx). Then, the application handles the transaction: -1. Upon receiving the transaction, the application first unmarshals it from `[]bytes`. -2. Then, it verifies a few things about the transaction like [fee payment and signatures](#accounts-fees-gas.md) before extracting the message(s) contained in the transaction. -3. With the [`Type()`](https://github.com/cosmos/cosmos-sdk/blob/master/types/tx_msg.go#L16) method, `baseapp` is able to know which modules defines the message. It is then able to route it to the appropriate module's [handler](#handler) in order for the message to be processed. -4. If the message is successfully processed, the state is updated. +1. Upon receiving the transaction, the application first unmarshalls it from `[]bytes`. +2. Then, it verifies a few things about the transaction like [fee payment and signatures](#accounts-fees-gas.md) before extracting the message(s) contained in the transaction. +3. With the [`Type()`](https://github.com/cosmos/cosmos-sdk/blob/master/types/tx_msg.go#L16) method, `baseapp` is able to know which modules defines the message. It is then able to route it to the appropriate module's [handler](#handler) in order for the message to be processed. +4. If the message is successfully processed, the state is updated. For a more detailed look at a transaction lifecycle, click [here](./tx-lifecycle.md). Module developers create custom message types when they build their own module. The general practice is to prefix the type declaration of the message with `Msg`. For example, the message type [`MsgSend`](https://github.com/cosmos/cosmos-sdk/blob/master/x/bank/types/msgs.go#L10-L15) allows users to transfer tokens. It is processed by the handler of the `bank` module, which ultimately calls the `keeper` of the `auth` module in order to update the state. +To learn more about messages, [click here](../building-modules/messages-and-queries.md#messages). + ### Handler -The `handler` refers to the part of the module responsible for processing the message after it is routed by `baseapp`. `handler` functions of modules (except those of the `auth` module) are only executed if the transaction is relayed from Tendermint by the `DeliverTx` ABCI message. If the transaction is relayed by `CheckTx`, only stateless checks and fee-related (i.e. `auth` module-related) stateful checks are performed. To better understand the difference between `DeliverTx`and `CheckTx`, as well as the difference between stateful and stateless checks, click [here](./tx-lifecycle.md). +The [`handler`](../building-modules/handler.md) refers to the part of the module responsible for processing the message after it is routed by `baseapp`. `handler` functions of modules (except those of the `auth` module) are only executed if the transaction is relayed from Tendermint by the `DeliverTx` ABCI message. If the transaction is relayed by `CheckTx`, only stateless checks and fee-related (i.e. `auth` module-related) stateful checks are performed. To better understand the difference between `DeliverTx`and `CheckTx`, as well as the difference between stateful and stateless checks, click [here](./tx-lifecycle.md). The handler of a module is generally defined in a file called `handler.go` and consists of: -- A **switch function** `NewHandler` to route the message to the appropriate handler function. This function returns a `handler` function, and is registered in the [`AppModule`](#application-module-interface) to be used in the application's module manager to initialize the application's router. See an example of such a switch [here](https://github.com/cosmos/sdk-application-tutorial/blob/master/x/nameservice/handler.go#L10-L22). -- **One handler function for each message type defined by the module**. Developers write the message processing logic in these functions. This generally involves doing stateful checks to ensure the message is valid and calling [`keeper`](#keeper)'s methods to update the state. +- A **switch function** `NewHandler` to route the message to the appropriate handler function. This function returns a `handler` function, and is registered in the [`AppModule`](#application-module-interface) to be used in the application's module manager to initialize the [application's router](../core/baseapp.md#routing). See an example of such a switch [here](https://github.com/cosmos/sdk-application-tutorial/blob/master/x/nameservice/handler.go#L10-L22). +- **One handler function for each message type defined by the module**. Developers write the message processing logic in these functions. This generally involves doing stateful checks to ensure the message is valid and calling [`keeper`](#keeper)'s methods to update the state. Handler functions return a result of type [`sdk.Result`](https://github.com/cosmos/cosmos-sdk/blob/master/types/result.go#L14-L37), which informs the application on whether the message was successfully processed. +To learn more about handlers, [click here](../building-modules/handler.md). + ### Keeper -`Keepers` are the gatekeepers of their module's store(s). To read or write in a module's store, it is mandatory to go through one of its `keeper`'s methods. This is ensured by the [object-capabilities](./ocap.md) model of the Cosmos SDK. Only objects that hold the key to a store can access it, and only the module's `keeper` should hold the key(s) to the module's store(s). +[`Keepers`](../building-module/keeper.md) are the gatekeepers of their module's store(s). To read or write in a module's store, it is mandatory to go through one of its `keeper`'s methods. This is ensured by the [object-capabilities](../core/ocap.md) model of the Cosmos SDK. Only objects that hold the key to a store can access it, and only the module's `keeper` should hold the key(s) to the module's store(s). `Keepers` are generally defined in a file called `keeper.go`. It contains the `keeper`'s type definition and methods. @@ -184,14 +187,18 @@ Along with the type definition, the next important component of the `keeper.go` The rest of the file defines the `keeper`'s methods, primarily getters and setters. You can check an example of a `keeper` implementation [here](https://github.com/cosmos/sdk-application-tutorial/blob/master/x/nameservice/keeper.go). -### Querier +To learn more about `keepers`, [click here](../building-modules/keeper.md). + +### Querier -`Queriers` are very similar to `handlers`, except they serve user queries to the state as opposed to processing transactions. A query is initiated from an [interface](#intefaces) by an end-user who provides a `queryRoute` and some `data`. The query is then routed to the correct application's `querier` by `baseapp`'s [`handleQueryCustom`](https://github.com/cosmos/cosmos-sdk/blob/master/baseapp/baseapp.go#L519-L556) method using `queryRoute`. +[`Queriers`](../building-modules/querier.md) are very similar to `handlers`, except they serve user queries to the state as opposed to processing transactions. A [query](../building-modules/messages-and-queries.md#queries) is initiated from an [interface](#interfaces) by an end-user who provides a `queryRoute` and some `data`. The query is then routed to the correct application's `querier` by `baseapp`'s [`handleQueryCustom`](https://github.com/cosmos/cosmos-sdk/blob/master/baseapp/baseapp.go#L519-L556) method using `queryRoute`. The `Querier` of a module is defined in a file called `querier.go`, and consists of: -- A **switch function** `NewQuerier` to route the query to the appropriate `querier` function. This function returns a `querier` function, and is is registered in the [`AppModule`](#application-module-interface) to be used in the application's module manager to initialize the application's query router. See an example of such a switch [here](https://github.com/cosmos/sdk-application-tutorial/blob/master/x/nameservice/querier.go#L21-L34). -- - **One querier function for each data type defined by the module that needs to be queryable**. Developers write the query processing logic in these functions. This generally involves calling [`keeper`](#keeper)'s methods to query the state and marshaling it to JSON. See an example of `querier` functions [here](https://github.com/cosmos/sdk-application-tutorial/blob/master/x/nameservice/querier.go#L37-L101). +- A **switch function** `NewQuerier` to route the query to the appropriate `querier` function. This function returns a `querier` function, and is is registered in the [`AppModule`](#application-module-interface) to be used in the application's module manager to initialize the [application's query router](../core/baseapp.md#query-routing). See an example of such a switch [here](https://github.com/cosmos/sdk-application-tutorial/blob/master/x/nameservice/querier.go#L21-L34). +- - **One querier function for each data type defined by the module that needs to be queryable**. Developers write the query processing logic in these functions. This generally involves calling [`keeper`](#keeper)'s methods to query the state and marshalling it to JSON. See an example of `querier` functions [here](https://github.com/cosmos/sdk-application-tutorial/blob/master/x/nameservice/querier.go#L37-L101). + +To learn more about `queriers`, [click here](../building-modules/querier.md). ### Command-Line and REST Interfaces @@ -204,9 +211,11 @@ Generally, the commands related to a module are defined in a folder called `clie - Transactions commands let users generate new transactions so that they can be included in a block and eventually update the state. One command should be created for each [message type](#message-types) defined in the module. The command calls the constructor of the message with the parameters provided by the end-user, and wraps it into a transaction. The SDK handles signing and the addition of other transaction metadata. See examples of transactions commands [here](https://github.com/cosmos/sdk-application-tutorial/blob/master/x/nameservice/client/cli/tx.go). - Queries let users query the subset of the state defined by the module. Query commands forward queries to the [application's query router](./baseapp.md#query-routing), which routes them to the appropriate [querier](#querier) the `queryRoute` parameter supplied. See examples of query commands [here](https://github.com/cosmos/sdk-application-tutorial/blob/master/x/nameservice/client/cli/query.go). +To learn more about modules CLI, [click here](../building-modules/module-interfaces.md#cli). + #### REST -The module's REST interface lets users generate transactions and query the state through REST calls to the application's light client daemon (LCD). REST routes are defined in a file `client/rest/rest.go`, which is composed of: +The module's REST interface lets users generate transactions and query the state through REST calls to the application's [light client daemon](../core/node.md#lcd) (LCD). REST routes are defined in a file `client/rest/rest.go`, which is composed of: - A `RegisterRoutes` function, which registers each route defined in the file. This function is called from the [main application's interface](#application-interfaces) for each module used within the application. The router used in the SDK is [Gorilla's mux](https://github.com/gorilla/mux). - Custom request type definitions for each query or transaction creation function that needs to be exposed. These custom request types build on the [base `request` type](https://github.com/cosmos/cosmos-sdk/blob/master/types/rest/rest.go#L32-L43) of the Cosmos SDK. @@ -214,19 +223,23 @@ The module's REST interface lets users generate transactions and query the state See an example of a module's `rest.go` file [here](https://github.com/cosmos/sdk-application-tutorial/blob/master/x/nameservice/client/rest/rest.go). +To learn more about modules REST interface, [click here](../building-modules/module-interfaces.md#rest). + ## Application Interface Interfaces let end-users interact with full-node clients. This means querying data from the full-node or creating and sending new transactions to be relayed by the full-node and eventually included in a block. -The main interface is the Command-Line Interface. The CLI of an SDK application is built by aggregating [CLI commands](#cli) defined in each of the modules used by the application. The CLI of an application generally has the `-cli` suffix (e.g. `appcli`), and defined in a file called `cmd/appcli/main.go`. The file contains: +The main interface is the [Command-Line Interface](../interfaces/cli.md). The CLI of an SDK application is built by aggregating [CLI commands](#cli) defined in each of the modules used by the application. The CLI of an application generally has the `-cli` suffix (e.g. `appcli`), and defined in a file called `cmd/appcli/main.go`. The file contains: - **A `main()` function**, which is executed to build the `appcli` interface client. This function prepares each command and adds them to the `rootCmd` before building them. At the root of `appCli`, the function adds generic commands like `status`, `keys` and `config`, query commands, tx commands and `rest-server`. -- **Query commands** are added by calling the `queryCmd` function, also defined in `appcli/main.go`. This function returns a Cobra command that contains the query commands defined in each of the application's modules (passed as an array of `sdk.ModuleClients` from the `main()` function), as well as some other lower level query commands such as block or validator queries. Query command are called by using the command `appcli query [query]` of the CLI. -- **Transaction commands** are added by calling the `txCmd` function. Similar to `queryCmd`, the function returns a Cobra command that contains the tx commands defined in each of the application's modules, as well as lower level tx commands like transaction signing or broadcasting. Tx commands are called by using the command `appcli tx [tx]` of the CLI. -- **A `registerRoutes` function**, which is called from the `main()` function when initializing the [application's light-client daemon (LCD)](./node.md#lcd) (i.e. `rest-server`). `registerRoutes` calls the `RegisterRoutes` function of each of the application's module, thereby registering the routes of the module to the lcd's router. The LCD can be started by running the following command `appcli rest-server`. +- **Query commands** are added by calling the `queryCmd` function, also defined in `appcli/main.go`. This function returns a Cobra command that contains the query commands defined in each of the application's modules (passed as an array of `sdk.ModuleClients` from the `main()` function), as well as some other lower level query commands such as block or validator queries. Query command are called by using the command `appcli query [query]` of the CLI. +- **Transaction commands** are added by calling the `txCmd` function. Similar to `queryCmd`, the function returns a Cobra command that contains the tx commands defined in each of the application's modules, as well as lower level tx commands like transaction signing or broadcasting. Tx commands are called by using the command `appcli tx [tx]` of the CLI. +- **A `registerRoutes` function**, which is called from the `main()` function when initializing the [application's light-client daemon (LCD)](../core/node.md#lcd) (i.e. `rest-server`). `registerRoutes` calls the `RegisterRoutes` function of each of the application's module, thereby registering the routes of the module to the lcd's router. The LCD can be started by running the following command `appcli rest-server`. See an example of an application's main command-line file [here](https://github.com/cosmos/sdk-application-tutorial/blob/master/cmd/nscli/main.go). +To learn more about interfaces, [click here](../interfaces/intro.md). + ## Dependencies and Makefile This section is optional, as developers are free to choose their depencency manager and project building method. That said, the current most used framework for versioning control is [`go.mod`](https://github.com/golang/go/wiki/Modules). It ensures each of the libraries used throughout the application are imported with the correct version. An example can be found [here](https://github.com/cosmos/sdk-application-tutorial/blob/master/go.mod). diff --git a/docs/building-modules/modules-manager.md b/docs/building-modules/modules-manager.md deleted file mode 100644 index bfe4c9d2d297..000000000000 --- a/docs/building-modules/modules-manager.md +++ /dev/null @@ -1,147 +0,0 @@ -# Module Manager - -## Pre-requisite Reading - -- [Introduction to SDK Modules](./intro.md) - -## Synopsis - -Cosmos SDK modules need to implement the [`AppModule` interfaces](#application-module-interfaces), in order to be managed by the application's [module manager](#module-manager). The module manager plays an important role in [`message` and `query` routing](../core/baseapp.md#routing), and allows the application developer to set the order of execution of a variety of functions like [`BeginBlocker` and `EndBlocker`](../basics/app-anatomy.md#begingblocker-and-endblocker). - -## Application Module Interfaces - -[Application module interfaces](https://github.com/cosmos/cosmos-sdk/blob/master/types/module/module.go) exist to facilitate the composition of modules together to form a functional SDK application. There are 3 main application module interfaces: - -- [`AppModuleBasic`](#appmodulebasic) for independent module functionalities. -- [`AppModule`](#appmodule) for inter-dependent module functionalities (except genesis-related functionalities). -- [`AppModuleGenesis`](#appmodulegenesis) for inter-dependent genesis-related module functionalities. - -The `AppModuleBasic` interface exists to define independent methods of the module, i.e. those that do not depend on other modules in the application. This allows for the construction of the basic application structure early in the application definition, generally in the `init()` function of the [main application file](../basics/app-antomy.md#core-application-file). - -The `AppModule` interface exists to define inter-dependent module methods. Many modules need to interract with other modules, typically through [`keeper`s](./keeper.md), which means there is a need for an interface where modules list their `keeper`s and other methods that require a reference to another module's object. `AppModule` interface also enables the module manager to set the order of execution between module's methods like `BeginBlock` and `EndBlock`, which is important in cases where the order of execution between modules matters in the context of the application. - -Lastly the interface for genesis functionality `AppModuleGenesis` is separated out from full module functionality `AppModule` so that modules which -are only used for genesis can take advantage of the `Module` patterns without having to define many placeholder functions. - -### `AppModuleBasic` - -The [`AppModuleBasic`](https://github.com/cosmos/cosmos-sdk/blob/master/types/module/module.go#L45-L57) interface defines the independent methods modules need to implement. - -```go -type AppModuleBasic interface { - Name() string - RegisterCodec(*codec.Codec) - - // genesis - DefaultGenesis() json.RawMessage - ValidateGenesis(json.RawMessage) error - - // client functionality - RegisterRESTRoutes(context.CLIContext, *mux.Router) - GetTxCmd(*codec.Codec) *cobra.Command - GetQueryCmd(*codec.Codec) *cobra.Command -} -``` - -Let us go through the methods: - -- `Name()`: Returns the name of the module as a `string`. -- `RegisterCodec(*codec.Codec)`: Registers the `codec` for the module, which is used to marhsal and unmarshal structs to/from `[]byte` in order to persist them in the moduel's `KVStore`. -- `DefaultGenesis()`: Returns a default [`GenesisState`](./genesis.md#genesisstate) for the module, marshalled to `json.RawMessage`. The default `GenesisState` need to be defined by the module developer and is primarily used for testing. -- `ValidateGenesis(json.RawMessage)`: Used to validate the `GenesisState` defined by a module, given in its `json.RawMessage` form. It will usually unmarshall the `json` before running a custom [`ValidateGenesis`](./genesis.md#validategenesis) function defined by the module developer. -- `RegisterRESTRoutes(context.CLIContext, *mux.Router)`: Registers the REST routes for the module. These routes will be used to map REST request to the module in order to process them. See [../interfaces/rest.md] for more. -- `GetTxCmd(*codec.Codec)`: Returns the root [`Tx` command](./module-interfaces.md#tx) for the module. The subcommands of this root command are used by end-users to generate new transactions containing [`message`s](./messages-and-queries.md#queries) defined in the module. -- `GetQueryCmd(*codec.Codec)`: Return the root [`query` command](./module-intefaces.md#query) for the module. The subcommands of this root command are used by end-users to generate new queries to the subset of the state defined by the module. - -All the `AppModuleBasic` of an application are managed by the [`BasicManager`](#basicmanager). - -### `AppModuleGenesis` - -The [`AppModuleGenesis`](https://github.com/cosmos/cosmos-sdk/blob/master/types/module/module.go#L123-L127) interface is a simple embedding of the `AppModuleBasic` interface with two added methods. - -```go -type AppModuleGenesis interface { - AppModuleBasic - InitGenesis(sdk.Context, json.RawMessage) []abci.ValidatorUpdate - ExportGenesis(sdk.Context) json.RawMessage -} -``` - -Let us go through the two added methods: - -- `InitGenesis(sdk.Context, json.RawMessage)`: Initializes the subset of the state managed by the module. It is called at genesis (i.e. when the chain is first started). -- `ExportGenesis(sdk.Context)`: Exports the latest subset of the state managed by the module to be used in a new genesis file. `ExportGenesis` is called for each module when a new chain is started from the state of an existing chain. - -It does not have its own manager, and exists separately from [`AppModule`](#appmodule) only for modules that exist only to implement genesis functionalities, so that they can be managed without having to implement all of `AppModule`'s methods. If the module is not only used during genesis, `InitGenesis(sdk.Context, json.RawMessage)` and `ExportGenesis(sdk.Context)` will generally be defined as methods of the concrete type implementing hte `AppModule` interface. - -### `AppModule` - -The [`AppModule`](https://github.com/cosmos/cosmos-sdk/blob/master/types/module/module.go#L130-L144) interface defines the inter-dependent methods modules need to implement. - -```go -type AppModule interface { - AppModuleGenesis - - // registers - RegisterInvariants(sdk.InvariantRegistry) - - // routes - Route() string - NewHandler() sdk.Handler - QuerierRoute() string - NewQuerierHandler() sdk.Querier - - BeginBlock(sdk.Context, abci.RequestBeginBlock) - EndBlock(sdk.Context, abci.RequestEndBlock) []abci.ValidatorUpdate -} -``` - -`AppModule`s are managed by the [module manager](#manager). This interface embeds the `AppModuleGenesis` interface so that the manager can access all the independent and genesis inter-dependent methods of the module. This means that a concrete type implementing the `AppModule` interface must either implement all the methods of `AppModuleGenesis` (and by extension `AppModuleBasic`), or include a concrete type that does as parameter. - -Let us go through the methods of `AppModule`: - -- `RegisterInvariants(sdk.InvariantRegistry)`: Registers the [`invariants`](./invariants.md) of the module. If the invariants deviates from its predicted value, the [`InvariantRegistry`](./invariants.md#registry) triggers appropriate logic (most often the chain will be halted). -- `Route()`: Returns the name of the module's route, for [`message`s](./messages-and-queries.md#messages) to be routed to the module by [`baseapp`](../core/baseapp.md#message-routing). -- `NewHandler()`: Returns a [`handler`](./handler.md) given the `Type()` of the `message`, in order to process the `message`. -- `QuerierRoute()`: Returns the name of the module's query route, for [`queries`](./messages-and-queries.md#queries) to be routes to the module by [`baseapp`](../core/baseapp.md#query-routing). -- `NewQuerierHandler()`: Returns a [`querier`](./querier.md) given the query `path`, in order to process the `query`. -- `BeginBlock(sdk.Context, abci.RequestBeginBlock)`: This method gives module developers the option to implement logic that is automatically triggered at the beginning of each block. Implement empty if no logic needs to be triggered at the beginning of each block for this module. -- `EndBlock(sdk.Context, abci.RequestEndBlock)`: This method gives module developers the option to implement logic that is automatically triggered at the beginning of each block. This is also where the module can inform the underlying consensus engine of validator set changes (e.g. the `staking` module). Implement empty if no logic needs to be triggered at the beginning of each block for this module. - -### Implementing the Application Module Interfaces - -Typically, the various application module interfaces are implemented in a file called `module.go`, located in the module's folder (e.g. `./x/module/module.go`). - -Almost every module need to implement the `AppModuleBasic` and `AppModule` interfaces. If the module is only used for genesis, it will implement `AppModuleGenesis` instead of `AppModule`. The concrete type that implements the interface can add parameters that are required for the implementation of the various methods of the interface. For example, the `NewHandler()` function often calls a `NewHandler(k keeper)` function defined in [`handler.go`](./handler.md) and therefore needs to pass the module's [`keeper`](./keeper.md) as parameter. - -```go -// example -type AppModule struct { - AppModuleBasic - keeper Keeper -} -``` - -In the example above, you can see that the `AppModule` concrete type references an `AppModuleBasic`, and not an `AppModuleGenesis`. That is because `AppModuleGenesis` only needs to be implemented in modules that focus on genesis-related functionalities. In most modules, the concrete `AppModule` type will have a reference to an `AppModuleBasic` and implement the two added methods of `AppModuleGenesis` directly in the `AppModule` type. - -If no parameter is required (which is often the case for `AppModuleBasic`), just declare an empty concrete type like so: - -```go -type AppModuleBasic struct{} -``` - -## Module Managers - -Module managers are used to manage collections of `AppModuleBasic` and `AppModule`. - -### `BasicManager` - -The `BasicManager` is a structure that lists all the `AppModuleBasic` of an application: - -```go -type BasicManager map[string]AppModuleBasic -``` - - - -### `Manager` diff --git a/docs/concepts/encoding.md b/docs/concepts/encoding.md deleted file mode 100644 index 8113f63e9630..000000000000 --- a/docs/concepts/encoding.md +++ /dev/null @@ -1,3 +0,0 @@ -# Amnio Encoding - -TODO \ No newline at end of file diff --git a/docs/concepts/tx-msgs.md b/docs/concepts/tx-msgs.md deleted file mode 100644 index fde1963e3c2a..000000000000 --- a/docs/concepts/tx-msgs.md +++ /dev/null @@ -1,5 +0,0 @@ -# Transactions and Messages - -## Transactions - -## Messages From e96b1664dcf1d35c441f8ae6f41f01f62bbeb84b Mon Sep 17 00:00:00 2001 From: Gloria Zhao Date: Wed, 21 Aug 2019 14:33:26 -0700 Subject: [PATCH 107/196] remove modules readme --- docs/building-modules/README.md | 78 --------------------------------- 1 file changed, 78 deletions(-) delete mode 100644 docs/building-modules/README.md diff --git a/docs/building-modules/README.md b/docs/building-modules/README.md deleted file mode 100644 index 5b5743671751..000000000000 --- a/docs/building-modules/README.md +++ /dev/null @@ -1,78 +0,0 @@ -# Auth - -The `x/auth` modules is used for accounts - -See the [API docs](https://godoc.org/github.com/cosmos/cosmos-sdk/x/auth) - -See the [specification](https://github.com/cosmos/cosmos-sdk/tree/master/docs/spec/auth) - -# Bank - -The `x/bank` module is for transferring coins between accounts. - -See the [API docs](https://godoc.org/github.com/cosmos/cosmos-sdk/x/bank). - -See the [specification](https://github.com/cosmos/cosmos-sdk/tree/master/docs/spec/bank) - -# Stake - -The `x/staking` module is for Cosmos Delegated-Proof-of-Stake. - -See the [API docs](https://godoc.org/github.com/cosmos/cosmos-sdk/x/staking). - -See the -[specification](https://github.com/cosmos/cosmos-sdk/tree/master/docs/spec/staking) - -# Slashing - -The `x/slashing` module is for Cosmos Delegated-Proof-of-Stake. - -See the [API docs](https://godoc.org/github.com/cosmos/cosmos-sdk/x/slashing) - -See the -[specification](https://github.com/cosmos/cosmos-sdk/tree/master/docs/spec/slashing) - -# Distribution - -The `x/distribution` module is for distributing fees and inflation across bonded -stakeholders. - -See the [API docs](https://godoc.org/github.com/cosmos/cosmos-sdk/x/distribution) - -See the -[specification](https://github.com/cosmos/cosmos-sdk/tree/master/docs/spec/distribution) - -# Governance - -The `x/gov` module is for bonded stakeholders to make proposals and vote on them. - -See the [API docs](https://godoc.org/github.com/cosmos/cosmos-sdk/x/gov) - -See the -[specification](https://github.com/cosmos/cosmos-sdk/tree/master/docs/spec/governance) - -To keep up with the current status of IBC, follow and contribute to [ICS](https://github.com/cosmos/ics) - -# Crisis - -The `x/crisis` module is for halting the blockchain under certain circumstances. - -See the [API Docs](https://godoc.org/github.com/cosmos/cosmos-sdk/x/crisis) - -See the [specification](https://github.com/cosmos/cosmos-sdk/blob/master/docs/spec/crisis) - -# Mint - -The `x/mint` module is for flexible inflation rates and effect a balance between market liquidity and staked supply. - -See the [API Docs](https://godoc.org/github.com/cosmos/cosmos-sdk/x/mint) - -See the [specification](https://github.com/cosmos/cosmos-sdk/blob/master/docs/spec/mint) - -# Params - -The `x/params` module provides a globally available parameter store. - -See the [API Docs](https://godoc.org/github.com/cosmos/cosmos-sdk/x/params) - -See the [specification](https://github.com/cosmos/cosmos-sdk/blob/master/docs/spec/params) From 0444f02c8e5ce08821b559e7be349bb69874ed96 Mon Sep 17 00:00:00 2001 From: Gloria Zhao Date: Tue, 27 Aug 2019 19:44:42 -0700 Subject: [PATCH 108/196] cli.md comments --- docs/interfaces/cli.md | 36 ++++++++++++++++++++---------------- 1 file changed, 20 insertions(+), 16 deletions(-) diff --git a/docs/interfaces/cli.md b/docs/interfaces/cli.md index f1864a2593cb..ed15192968c5 100644 --- a/docs/interfaces/cli.md +++ b/docs/interfaces/cli.md @@ -6,7 +6,7 @@ ## Synopsis -This document describes how to create a commmand-line interface (CLI) for an application. A separate document for implementing a CLI for an SDK module can be found [here](#../building-modules/interfaces.md#cli). +This document describes how to create a commmand-line interface (CLI) for an [**application**](../basics/app-anatomy.md). A separate document for implementing a CLI for an SDK [**module**](../building-modules/intro.md) can be found [here](#../building-modules/interfaces.md#cli). - [Application CLI Components](#application-cli-components) - [Commands](#commands) @@ -19,7 +19,7 @@ One of the main entrypoints of an application is the command-line interface. Thi ### Cobra -There is no set way to create a CLI, but SDK modules all use the [Cobra Library](https://github.com/spf13/cobra). Building a CLI with Cobra entails defining commands, arguments, and flags. [**Commands**](#commands) understand the actions users wish to take, such as `tx` for creating a transaction and `query` for querying the application. Each command can also have nested subcommands, necessary for naming the specific transaction type. Users also supply **Arguments**, such as account numbers to send coins to, and [**Flags**](#flags) to modify various aspects of the commands, such as gas prices or which node to broadcast to. +There is no set way to create a CLI, but SDK modules typically use the [Cobra Library](https://github.com/spf13/cobra). Building a CLI with Cobra entails defining commands, arguments, and flags. [**Commands**](#commands) understand the actions users wish to take, such as `tx` for creating a transaction and `query` for querying the application. Each command can also have nested subcommands, necessary for naming the specific transaction type. Users also supply **Arguments**, such as account numbers to send coins to, and [**Flags**](#flags) to modify various aspects of the commands, such as gas prices or which node to broadcast to. Here is an example of a command a user might enter to interact with the nameservice CLI `nscli` in order to buy a name: @@ -28,17 +28,17 @@ nscli tx nameservice buy-name --gas auto --gas-prices ` into their command line. Commonly pre-configured flags include the `--node` to connect to and `--chain-id` of the blockchain the user wishes to interact with. +Flags are used to modify commands; developers can include them in a `flags.go` file with their CLI. Users can explicitly include them in commands or pre-configure them by entering a command in the format `appcli config ` into their command line. Commonly pre-configured flags include the `--node` to connect to and `--chain-id` of the blockchain the user wishes to interact with. A *persistent* flag (as opposed to a _local_ flag) added to a command transcends all of its children: subcommands will inherit the configured values for these flags. Additionally, all flags have default values when they are added to commands; some toggle an option off but others are empty values that the user needs to override to create valid commands. A flag can be explicitly marked as _required_ so that an error is automatically thrown if the user does not provide a value, but it is also acceptable to handle unexpected missing flags differently. -Every flag has a name the user types to use the flag. For example, the commonly used `--from` flag is declared as a constant in the SDK [flags](https://github.com/cosmos/cosmos-sdk/blob/master/client/flags/flags.go) file: +### Creating Flags + +Every flag has a name the user types to include the flag. For example, the commonly used `--from` flag is declared as a constant in the SDK [flags](https://github.com/cosmos/cosmos-sdk/blob/master/client/flags/flags.go) file: ```go const FlagFrom = "from" ``` -The flag can be added to a command `cmd`, adding a default value and description: +The flag can be added to a command `cmd` right after the command is created, adding a default value and description: ```go cmd.Flags().String(FlagFrom, "", "Name or address of private key with which to sign") ``` -The SDK client package includes a list of [flags](https://github.com/cosmos/cosmos-sdk/blob/master/client/flags/flags.go) that are commonly used across existing commands. +The SDK client package includes a list of [flags](https://github.com/cosmos/cosmos-sdk/blob/master/client/flags/flags.go) that are commonly used across existing commands. Developers are free to create their own custom flags, following this format. ### Root Command Flags -It is common to add a _persistent_ flag for `--chain-id`, the unique identifier of the blockchain the application pertains to, to the root command. Adding this flag makes sense as the chain ID should not be changing across commands in this application CLI. Here is what that looks like: +It is common to add a _persistent_ flag for `--chain-id`, the unique identifier of the blockchain the application pertains to, to the root command. Adding this flag can be done in the `main()` function. Adding this flag makes sense as the chain ID should not be changing across commands in this application CLI. Here is what that looks like: ```go rootCmd.PersistentFlags().String(client.FlagChainID, "", "Chain ID of tendermint node") @@ -228,7 +232,7 @@ rootCmd.PersistentFlags().String(client.FlagChainID, "", "Chain ID of tendermint ### Transaction and Query Flags -To create a transaction, users enter a `tx` command and provide several flags. The SDK `./client/flags` package [`PostCommands()`](https://github.com/cosmos/cosmos-sdk/blob/master/client/flags/flags.go#L85-L116) function adds a set of basic flags to every transaction command. For queries, the [`GetCommand()`](https://github.com/cosmos/cosmos-sdk/blob/master/client/flags/flags.go#L67-L82) function adds basic flags to query commands, such as the block `--height` to query from. +To create a transaction, users enter a `tx` command and provide several flags. The SDK `./client/flags` package [`PostCommands()`](https://github.com/cosmos/cosmos-sdk/blob/master/client/flags/flags.go#L85-L116) function adds a set of basic flags to every transaction command. For queries, the [`GetCommand()`](https://github.com/cosmos/cosmos-sdk/blob/master/client/flags/flags.go#L67-L82) function adds basic flags to query commands, such as the block `--height` to query from. For example, the following command creates a transaction to send 1000uatom from `sender-address` to `recipient-address`. The user is willing to pay 0.025uatom per unit gas but wants the transaction to be only generated offline (i.e. not broadcasted) and written, in JSON format, to the file `myUnsignedTx.json`. @@ -246,13 +250,13 @@ Here are the flags used: ## Configurations -The last function to define is, `initConfig`, which does exactly what it sounds like - initial configurations. To call this function, set it as a `PersistentPreRunE` function for the root command, so that it always executes before the main execution of the root command and any of its subcommands. `initConfig()` does the following: +The last function to define in `main.go` is `initConfig`, which does exactly what it sounds like - initialize configurations. To call this function, set it as a `PersistentPreRunE` function for the root command, so that it always executes before the main execution of the root command and any of its subcommands. `initConfig()` does the following: 1. Read in the `config.toml` file. This same file is edited through `config` commands. 2. Use the [Viper](https://github.com/spf13/viper) to read in configurations from the file and set them. 3. Set any persistent flags defined by the user: `--chain-id`, `--encoding`, `--output`, etc. -Here is an example of an `initConfig()` function from the nameservice tutorial CLI: +Here is an example of an `initConfig()` function from the [nameservice tutorial CLI](https://cosmos.network/docs/tutorial/entrypoint.html#nscli): ```go func initConfig(cmd *cobra.Command) error { From 70fd35c5a380497f69ff7db00ce5af4d3e01cafe Mon Sep 17 00:00:00 2001 From: Gloria Zhao Date: Tue, 27 Aug 2019 20:05:43 -0700 Subject: [PATCH 109/196] comments --- docs/interfaces/query-lifecycle.md | 43 ++++++++---------------------- docs/interfaces/rest.md | 4 +-- 2 files changed, 13 insertions(+), 34 deletions(-) diff --git a/docs/interfaces/query-lifecycle.md b/docs/interfaces/query-lifecycle.md index 6c69aa454e68..6c8a5b842620 100644 --- a/docs/interfaces/query-lifecycle.md +++ b/docs/interfaces/query-lifecycle.md @@ -60,7 +60,7 @@ The interactions from the users' perspective are a bit different, but the underl ### CLIContext -The first thing that is created in the execution of a CLI command is a `CLIContext`, while the REST Server directly provides a `CLIContext` for the REST Request handler. A [Context](../core/context.md) is an immutable object that stores all the data needed to process a request. In particular, a `CLIContext` stores the following: +The first thing that is created in the execution of a CLI command is a `CLIContext`, while the REST Server directly provides a `CLIContext` for the REST Request handler. A [Context](../core/context.md) is an immutable object that stores all the data needed to process a request on the user side. In particular, a `CLIContext` stores the following: * **Codec**: The [encoder/decoder](,./core/encoding.md) used by the application, used to marshal the parameters and query before making the Tendermint RPC request and unmarshal the returned response into a JSON object. * **Account Decoder**: The account decoder from the [`auth`](.../spec/auth) module, which translates `[]byte`s into accounts. @@ -76,11 +76,11 @@ The `CLIContext`'s primary role is to store data used during interactions with t ### Arguments and Route Creation -At this point in the lifecycle, the user has created a CLI command or HTTP Request with all of the data they wish to include in their `Query`. A `CLIContext` exists to assist in the rest of the `Query`'s journey. Now, the next step is to parse the command or request, extract the arguments, create a `queryRoute`, and encode everything. +At this point in the lifecycle, the user has created a CLI command or HTTP Request with all of the data they wish to include in their `Query`. A `CLIContext` exists to assist in the rest of the `Query`'s journey. Now, the next step is to parse the command or request, extract the arguments, create a `queryRoute`, and encode everything. These steps all happen on the user side within the interface they are interacting with. #### Parse Arguments -In this case, `Query` contains an [address](../core/accounts-fees.md) `delegatorAddress` as its only argument. However, the request can only contain `[]byte`s, as it will be relayed to a consensus engine node that has no inherent knowledge of the application types. Thus, the `CLIContext` `codec` is used to marshal the address as the type [`QueryDelegatorParams`](https://github.com/cosmos/cosmos-sdk/blob/master/x/staking/types/querier.go#L30-L38). All query arguments (e.g. the [`staking`](https://github.com/cosmos/cosmos-sdk/blob/master/docs/spec/staking) module also has [`QueryValidatorParams`](https://github.com/cosmos/cosmos-sdk/blob/master/x/staking/types/querier.go#L45-L53) and [`QueryBondsParams`](https://github.com/cosmos/cosmos-sdk/blob/master/x/staking/types/querier.go#L59-L69)) have their own types that the application `codec` understands how to encode and decode. The module [`querier`](.//building-modules/querier.md) declares these types and the application registers the `codec`s. +In this case, `Query` contains an [address](../core/accounts-fees.md) `delegatorAddress` as its only argument. However, the request can only contain `[]byte`s, as it will be relayed to a consensus engine (e.g. Tendermint Core) of a full-node that has no inherent knowledge of the application types. Thus, the `codec` of `CLIContext` is used to marshal the address as the type [`QueryDelegatorParams`](https://github.com/cosmos/cosmos-sdk/blob/master/x/staking/types/querier.go#L30-L38). All query arguments have their own types that the application `codec` understands how to encode and decode. For example, the [`staking`](https://github.com/cosmos/cosmos-sdk/blob/master/docs/spec/staking) module also has [`QueryValidatorParams`](https://github.com/cosmos/cosmos-sdk/blob/master/x/staking/types/querier.go#L45-L53) and [`QueryBondsParams`](https://github.com/cosmos/cosmos-sdk/blob/master/x/staking/types/querier.go#L59-L69). The module [`querier`](.//building-modules/querier.md) declares these types and the application registers the `codec`s. Here is what the code looks like for the CLI command: @@ -104,7 +104,7 @@ params := types.NewQueryDelegatorParams(delegatorAddr) #### Query Route Creation -Important to note is that there will never be a "query" object created for `Query`; the SDK actually takes a simpler approach. Instead of an object, all the full-node needs to process a query is its `route` which specifies exactly which module to route the query to and the name of this query type. The `route` will be passed to the application baseapp, then module, then [querier](../building-modules/querier.md), and each will understand the `route` and pass it to the appropriate next step. [baseapp](../core/baseapp.md#query-routing) will understand this query to be a `custom` query in the module `staking`, and the `staking` module querier supports the type `QueryDelegatorDelegations`. Thus, the route will be `"custom/staking/delegatorDelegations"`. +Important to note is that there will never be a "query" object created for `Query`; the SDK actually takes a simpler approach. Instead of an object, all the full-node needs to process a query is its `route` which specifies exactly which module to route the query to and the name of this query type. The `route` will be passed to the application `baseapp`, then module, then [querier](../building-modules/querier.md), and each will understand the `route` and pass it to the appropriate next step. [`baseapp`](../core/baseapp.md#query-routing) will understand this query to be a `custom` query in the module `staking`, and the `staking` module querier supports the type `QueryDelegatorDelegations`. Thus, the route will be `"custom/staking/delegatorDelegations"`. Here is what the code looks like: @@ -137,44 +137,23 @@ Read more about ABCI Clients and Tendermint RPC in the Tendermint documentation ## Application Query Handling -[baseapp](../core/baseapp.md) implements the ABCI [`Query()`](../core/baseapp.md#query) function and handles four different types of queries: `app`, `store`, `p2p`, and `custom`. The `queryRoute` is parsed such that the first string must be one of the four options, then the rest of the path is parsed within the subroutines handling each type of query. The first three types (`app`, `store`, `p2p`) are purely application-level and thus directly handled by Baseapp or the stores, but the `custom` query type requires Baseapp to route the query to a module's [querier](../building-modules/querier.md). +When a query is received by the full-node after it has been relayed from the underlying consensus engine, it is now being handled within an environment that understands application-specific types and has a copy of the state. [`baseapp`](../core/baseapp.md) implements the ABCI [`Query()`](../core/baseapp.md#query) function and handles four different types of queries: `app`, `store`, `p2p`, and `custom`. The `queryRoute` is parsed such that the first string must be one of the four options, then the rest of the path is parsed within the subroutines handling each type of query. The first three types (`app`, `store`, `p2p`) are purely application-level and thus directly handled by `baseapp` or the stores, but the `custom` query type requires `baseapp` to route the query to a module's [querier](../building-modules/querier.md). -Since `Query` is a custom query type from the `staking` module, Baseapp first parses the path, then uses the `QueryRouter` to retrieve the corresponding querier. The querier is responsible for recognizing this query, retrieving the appropriate values from the application's stores, and returning a response. Read more about queriers [here](../building-modules/querier.md). +Since `Query` is a custom query type from the `staking` module, `baseapp` first parses the path, then uses the `QueryRouter` to retrieve the corresponding querier, and routes the query to the module. The querier is responsible for recognizing this query, retrieving the appropriate values from the application's stores, and returning a response. Read more about queriers [here](../building-modules/querier.md). + +Once a result is received from the querier, `baseapp` begins the process of returning a response to the user. ## Response -Since `Query()` is an ABCI function, Baseapp returns the response as an [`abci.ResponseQuery`](https://tendermint.com/docs/spec/abci/abci.html#messages) type. The `CLIContext` `Query()` routine receives the response and, if `--trust-node` is toggled to `false` and a proof needs to be verified, the response is verified with the `CLIContext` [`verifyProof()`](https://github.com/cosmos/cosmos-sdk/blob/master/client/context/query.go#L136-L173) function before the response is returned. +Since `Query()` is an ABCI function, `baseapp` returns the response as an [`abci.ResponseQuery`](https://tendermint.com/docs/spec/abci/abci.html#messages) type. The `CLIContext` `Query()` routine receives the response and, if `--trust-node` is toggled to `false` and a proof needs to be verified, the response is verified with the `CLIContext` [`verifyProof()`](https://github.com/cosmos/cosmos-sdk/blob/master/client/context/query.go#L136-L173) function before the response is returned. ### CLI Response -The application [`codec`](../core/encoding.md) is used to unmarshal the response to a JSON and the `CLIContext` prints the output to the command line, applying any configurations such as `--indent`. - -Here is what the code looks like: - -```go -res, _, err := cliCtx.QueryWithData(route, bz) -var resp types.DelegationResponses -if err := cdc.UnmarshalJSON(res, &resp); err != nil { - return err -} -return cliCtx.PrintOutput(resp) -``` +The application [`codec`](../core/encoding.md) is used to unmarshal the response to a JSON and the `CLIContext` prints the output to the command line, applying any configurations such as `--indent`. To see the code, click [here](https://github.com/cosmos/cosmos-sdk/blob/master/x/staking/client/cli/query.go#L252-L293). ### REST Response -The [REST server](./rest.md#rest-server) uses the `CLIContext` to format the response properly, then uses the HTTP package to write the appropriate response or error. - -Here is what the code looks like: - -```go -res, height, err := cliCtx.QueryWithData(endpoint, bz) -if err != nil { - rest.WriteErrorResponse(w, http.StatusInternalServerError, err.Error()) - return -} -cliCtx = cliCtx.WithHeight(height) -rest.PostProcessResponse(w, cliCtx, res) -``` +The [REST server](./rest.md#rest-server) uses the `CLIContext` to format the response properly, then uses the HTTP package to write the appropriate response or error. To see the code, click [here](https://github.com/cosmos/cosmos-sdk/blob/master/x/staking/client/rest/utils.go#L115-L148). ## Next diff --git a/docs/interfaces/rest.md b/docs/interfaces/rest.md index bf4a010d0fa8..2b0e3ba2b633 100644 --- a/docs/interfaces/rest.md +++ b/docs/interfaces/rest.md @@ -7,7 +7,7 @@ ## Synopsis -This document describes how to create a REST interface for an SDK application. A separate document for creating a module REST interface can be found [here](#../module-interfaces.md#rest). +This document describes how to create a REST interface for an SDK **application**. A separate document for creating a [**module**](../building-modules/intro.md) REST interface can be found [here](#../module-interfaces.md#rest). - [Application REST Interface](#application-rest-interface) - [REST Server](#rest-server) @@ -42,7 +42,7 @@ Of the five, the only attribute that developers will need to configure is the ro ## Registering Routes -To include routes for each module in an application, the CLI must have some kind of function to Register Routes in its REST Server. This `RegisterRoutes()` function is utilized by the `ServeCommand` and must include routes for each of the application's modules. Since each module used by an SDK application implements a [`RegisterRESTRoutes`](../building-modules.md#rest) function, application developers simply use the Module Manager to call this function for each module. +To include routes for each module in an application, the CLI must have some kind of function to Register Routes in its REST Server. This `RegisterRoutes()` function is utilized by the `ServeCommand` and must include routes for each of the application's modules. Since each module used by an SDK application implements a [`RegisterRESTRoutes`](../building-modules.md/module-interfaces.md#rest) function, application developers simply use the Module Manager to call this function for each module. At the bare minimum, a `RegisterRoutes()` function should use the SDK client package `RegisterRoutes()` function to be able to route RPC calls, and instruct the application Module Manager to call `RegisterRESTRoutes()` for all of its modules: From ee08a01e42ed0ce89a4aef5af91a3a3973754441 Mon Sep 17 00:00:00 2001 From: Gloria Zhao Date: Tue, 27 Aug 2019 20:15:45 -0700 Subject: [PATCH 110/196] module-interfaces comments --- docs/building-modules/module-interfaces.md | 18 ++++++++---------- 1 file changed, 8 insertions(+), 10 deletions(-) diff --git a/docs/building-modules/module-interfaces.md b/docs/building-modules/module-interfaces.md index f1136e63d72c..300bd6b0817c 100644 --- a/docs/building-modules/module-interfaces.md +++ b/docs/building-modules/module-interfaces.md @@ -18,11 +18,11 @@ This document details how to build CLI and REST interfaces for a module. Example ## CLI -One of the main interfaces for an application is the [command-line interface](../interfaces/cli.md). This entrypoint created by the application developer will add commands from the application's modules to let end-users create [**messages**](./messages-and-queries.md) and [**queries**](./messages-and-queries.md). The CLI files are typically found in the `./x/moduleName/client/cli` folder. +One of the main interfaces for an application is the [command-line interface](../interfaces/cli.md). This entrypoint created by the application developer will add commands from the application's modules to let end-users create [**messages**](./messages-and-queries.md#messages) and [**queries**](./messages-and-queries.md#queries). The CLI files are typically found in the `./x/moduleName/client/cli` folder. ### Transaction Commands -[Transactions](../core/transactions.md) are created by users to wrap messages that trigger state changes when they get included in a valid block. Transaction commands typically have their own `tx.go` file in the module `./x/moduleName/client/cli` folder. The commands are specified in getter functions prefixed with `GetCmd` and include the name of the command. Here is an example from the nameservice tutorial: +[Transactions](../core/transactions.md) are created by users to wrap messages that trigger state changes when they get included in a valid block. Transaction commands typically have their own `tx.go` file in the module `./x/moduleName/client/cli` folder. The commands are specified in getter functions prefixed with `GetCmd` and include the name of the command. Here is an example from the [nameservice tutorial](https://cosmos.network/docs/tutorial/cli.html#transactions): ```go func GetCmdBuyName(cdc *codec.Codec) *cobra.Command { @@ -74,9 +74,6 @@ This getter function creates the command for the Buy Name transaction. It does t + Depending on what the user wants, the transaction is either generated offline or signed and broadcasted to the preconfigured node using `GenerateOrBroadcastMsgs()`. - **Flags.** Add any [flags](#flags) to the command. No flags were specified here, but all transaction commands have flags to provide additional information from the user (e.g. amount of fees they are willing to pay). These *persistent* [transaction flags](../interfaces/cli.md#flags) can be added to a higher-level command so that they apply to all transaction commands. - -#### GetTxCmd - Finally, the module needs to have a `GetTxCmd()`, which aggregates all of the transaction commands of the module. Often, each command getter function has its own file in the module's `cli` folder, and a separate `tx.go` file contains `GetTxCmd()`. Application developers wishing to include the module's transactions will call this function to add them as subcommands in their CLI. Here is the [`auth`](https://github.com/cosmos/cosmos-sdk/tree/67f6b021180c7ef0bcf25b6597a629aca27766b8/docs/spec/auth) `GetTxCmd()` function, which adds the `Sign` and `MultiSign` commands. An application using this module likely adds `auth` module commands to its root `TxCmd` command by calling `txCmd.AddCommand(authModuleClient.GetTxCmd())`. ```go @@ -98,7 +95,7 @@ func GetTxCmd(cdc *codec.Codec) *cobra.Command { ### Query Commands -[Queries](./messages-and-queries.md) allow users to gather information about the application or network state; they are routed by the application and processed by the module in which they are defined. Query commands typically have their own `query.go` file in the module `x/moduleName/client/cli` folder. Like transaction commands, they are specified in getter functions and have the prefix `GetCmdQuery`. Here is an example of a query command from the nameservice module: +[Queries](./messages-and-queries.md#queries) allow users to gather information about the application or network state; they are routed by the application and processed by the module in which they are defined. Query commands typically have their own `query.go` file in the module `x/moduleName/client/cli` folder. Like transaction commands, they are specified in getter functions and have the prefix `GetCmdQuery`. Here is an example of a query command from the [nameservice module CLI](https://cosmos.network/docs/tutorial/cli.html#queries): ```go func GetCmdWhois(queryRoute string, cdc *codec.Codec) *cobra.Command { @@ -137,9 +134,8 @@ This query returns the address that owns a particular name. The getter function + The `codec` is used to nmarshal the response and the `CLIContext` is used to print the output back to the user. - **Flags.** Add any [flags](#flags) to the command. -#### GetQueryCmd -Finally, the module also needs a `GetQueryCmd`, which aggregates all of the query commands of the module. Application developers wishing to include the module's queries will call this function to add them as subcommands in their CLI. Its structure is identical to the [`GetTxCmd`](#gettxcmd) command. +Finally, the module also needs a `GetQueryCmd`, which aggregates all of the query commands of the module. Application developers wishing to include the module's queries will call this function to add them as subcommands in their CLI. Its structure is identical to the `GetTxCmd` command shown above. ### Flags @@ -167,11 +163,13 @@ Since `PostCommands()` includes all of the basic flags required for a transactio ## REST -Applications are typically required to support web services that use HTTP requests (e.g. a web wallet like [Lunie.io](lunie.io)). Thus, application developers will also use REST Routes to route HTTP requests to the application's modules; these routes will be used by service providers. The module developer's responsibility is to define the REST client by defining [routes](#register-routes) for all possible [requests](#request-types) and [handlers](#request-handlers) for each of them. It's up to the module developer how to organize the REST interface files; there is typically a `rest.go` file found in the module's `./x/moduleName/client/rest` folder. +Applications typically support web services that use HTTP requests (e.g. a web wallet like [Lunie.io](lunie.io)). Thus, application developers will also use REST Routes to route HTTP requests to the application's modules; these routes will be used by service providers. The module developer's responsibility is to define the REST client by defining [routes](#register-routes) for all possible [requests](#request-types) and [handlers](#request-handlers) for each of them. It's up to the module developer how to organize the REST interface files; there is typically a `rest.go` file found in the module's `./x/moduleName/client/rest` folder. + +To support HTTP requests, the module developer needs to define possible request types, how to handle them, and provide a way to register them with a provided router. ### Request Types -Request types must be defined for all *transaction* requests. Conventionally, each request is named with the suffix `Req`, e.g. `SendReq` for a Send transaction. Each struct should include a base request [`baseReq`](../interfaces/rest.md#basereq), the name of the transaction, and all the arguments the user must provide for the transaction. +Request types, which define structured interactions from users, must be defined for all *transaction* requests. Users using this method to interact with an application will send HTTP Requests with the required fields in order to trigger state changes in the application. Conventionally, each request is named with the suffix `Req`, e.g. `SendReq` for a Send transaction. Each struct should include a base request [`baseReq`](../interfaces/rest.md#basereq), the name of the transaction, and all the arguments the user must provide for the transaction. Here is an example of a request to buy a name from the [nameservice](https://cosmos.network/docs/tutorial/rest.html) module: From b4d1657d798c2024b70f1e83fc0f75aba7f07a60 Mon Sep 17 00:00:00 2001 From: gamarin Date: Thu, 12 Sep 2019 15:23:21 +0200 Subject: [PATCH 111/196] keeper --- docs/building-modules/extending-modules | 0 docs/building-modules/keeper.md | 89 +++++++++++++++++++ docs/building-modules/messages-and-queries.md | 4 +- docs/building-modules/querier.md | 2 +- 4 files changed, 92 insertions(+), 3 deletions(-) create mode 100644 docs/building-modules/extending-modules diff --git a/docs/building-modules/extending-modules b/docs/building-modules/extending-modules new file mode 100644 index 000000000000..e69de29bb2d1 diff --git a/docs/building-modules/keeper.md b/docs/building-modules/keeper.md index e69de29bb2d1..b9c478ed9281 100644 --- a/docs/building-modules/keeper.md +++ b/docs/building-modules/keeper.md @@ -0,0 +1,89 @@ +# Keepers + +## Pre-requisite Reading + +- [Introduction to SDK Modules](./intro.md) + +## Synopsis + +`Keeper`s refer to a Cosmos SDK abstraction whose role is to manage access to the subset of the state defined by various modules. `Keeper`s are module-specific, i.e. the subset of state defined by a module can only be accessed by a `keeper` defined in said module. If a module needs to access the subset of state defined by another module, a reference to the second module's internal `keeper` needs to be passed to the first one. + +- [Motivation](#motivation) +- [Type Definition](#type-definition) +- [Implementing Methods](#implementing-methods) + +## Motivation + +The Cosmos SDK is a framework that makes it easy for developers to build complex decentralised applications from scratch, mainly by composing modules together. As the ecosystem of open source modules for the Cosmos SDK expands, it will become increasingly likely that some contain vulnerabilities, as a result of the negligence or malice of their developer. + +The Cosmos SDK adopts a [capabilities-based approach](./ocap.md) to help developers better protect their application from unwanted inter-modules interactions, and `keeper`s are at the core of this approach. A `keeper` can be thougt quite literally as the gatekeeper of a module's store(s). Each store defined within a module comes with a `storeKey`, which grants unlimited access to it. The module's `keeper` holds this `storeKey` (which should otherwise remain unexposed), and defines [methods](#implementing-methods) for reading and writting to the store(s). + +The core idea behind the object-capabilities approach is to only reveal what is necessary to get the work done. In practice, this means that instead of handling permissions of modules through an access-control lists, the `keeper`s of modules get a reference to a specific instance of the other modules' `keeper`s they need access to. As a consequence, a module can only interract with the subset of state defined in another module via the methods exposed by the instance of the other module's `keeper`. This is a great way for developers to control the interactions that their own module have with modules developed by external developers. + +## Type Definition + +`keeper`s are generally implemented in a `internal/keeper/keeper.go` file located in the module's folder. By convention, the type `keeper` of a module is simply named `Keeper` and usually follows the following structure: + +```go +type Keeper struct { + // External keepers, if any + + // Store key(s) + + // codec +} +``` + +For example, here is the [type definition of the `keeper` from the nameservice tutorial](https://github.com/cosmos/sdk-application-tutorial/blob/master/x/nameservice/internal/keeper/keeper.go#L10-L17): + +```go +type Keeper struct { + CoinKeeper types.CoinKeeper + + storeKey sdk.StoreKey // Unexposed key to access store from sdk.Context + + cdc *codec.Codec // The wire codec for binary encoding/decoding. +} +``` + +Let us go through the different paramters: + +- An expected `keeper` is a `keeper` external to a module that is required by the internal `keeper` of said module. External `keeper`s are listed in the internal `keeper`'s type definition as interfaces. These interfaces are themselves defined in a `internal/types/expected_keepers.go` file within the module's folder. In this context, interfaces are used to reduce the number of dependencies, as well as to facilitate the maintenance of the module itself. +- `storeKey`s grant access to the store(s) of the [multistore](../core/store.md) managed by the module. They should always remain unexposed to external modules. +- A [codec `cdc`](../core/encoding.md), used to marshall and unmarshall struct to/from `[]byte`. + +Of course, it is possible to define different types of internal `keeper`s for the same module (e.g. a read-only `keeper`). Each type of `keeper` comes with its own constructor function, which is called from the [application's constructor function](../basics/app-anatomy.md). This is where `keeper`s are instanciated, and where developers make sure to pass correct instances of modules' `keeper`s to other modules that require it. + +## Implementing Methods + +`Keeper`s primarily expose getters and setters methods for the store(s) managed by their module. These methods should remain as simple as possible and strictly be limited to getting or setting the requested value, as validity checks should have already been performed via the `ValidateBasic()` method of the [`message`](./messages-and-queries.md#messages) and the [`handler`](./handler.go) when `keeper`s' methods are called. + +Typically, a *getter* method will present with the following signature + +```go +func (k Keeper) Get(ctx sdk.Context, key string) returnType +``` + +and go through the following steps: + +1. Retrieve the appropriate store from the `ctx` using the `storeKey`. This is done through the `KVStore(storeKey sdk.StoreKey` method of the `ctx`. +2. If it exists, get the `[]byte` value stored at location `[]byte(key)` using the `Get(key []byte)` method of the store. +3. Unmarshall the retrieved value from `[]byte` to `returnType` using the codec `cdc`. Return the value. + +Similarly, a *setter* method will present with the following signature + +```go +func (k Keeper) Set(ctx sdk.Context, key string, value valueType) +``` + +and go through the following steps: + +1. Retrieve the appropriate store from the `ctx` using the `storeKey`. This is done through the `KVStore(storeKey sdk.StoreKey` method of the `ctx`. +2. Marhsall `value` to `[]byte` using the codec `cdc`. +3. Set the encoded value in the store at location `key` using the `Set(key []byte, value []byte)` method of the store. + +For more, see an example of `keeper`'s [methods implementation from the nameservice tutorial](https://github.com/cosmos/sdk-application-tutorial/blob/master/x/nameservice/internal/keeper/keeper.go). + +## Next + +Learn about [invariants](./invariants.md). \ No newline at end of file diff --git a/docs/building-modules/messages-and-queries.md b/docs/building-modules/messages-and-queries.md index 58beabb08c3a..52614ddbdc82 100644 --- a/docs/building-modules/messages-and-queries.md +++ b/docs/building-modules/messages-and-queries.md @@ -17,7 +17,7 @@ When a transaction is relayed from the underlying consensus engine to the SDK application, it is first decoded by [`baseapp`](../basics/baseapp.md). Then, each `message` contained in the transaction is extracted and routed to the appropriate module via `baseapp`'s `router` so that it can be processed by the module's [`handler`](./handler.md). For a more detailed explanation of the lifecycle of a transaction, click [here](../basics/tx-lifecycle.md). -Defining `message`s is the responsibility of module developers. Typically, they are defined in a `types/msgs.go` file inside the module's folder. The `message`'s type definition usually includes a list of parameters needed to process the message that will be provided by end-users when they want to create a new transaction containing said `message`. +Defining `message`s is the responsibility of module developers. Typically, they are defined in a `internal/types/msgs.go` file inside the module's folder. The `message`'s type definition usually includes a list of parameters needed to process the message that will be provided by end-users when they want to create a new transaction containing said `message`. ```go // Example of a message type definition @@ -60,7 +60,7 @@ The `path` for each `query` must be defined by the module developer in the modul - A [`querier`](./querier.md), to process the `query` once it has been [routed to the module](../core/baseapp.md#query-routing). - [Query commands](./module-interfaces.md#query-commands) in the module's CLI file, where the `path` for each `query` is specified. -- `query` return types. Typically defined in a file `types/querier.go`, they specify the result type of each of the module's `queries`. These custom types must implement the `String()` method of [`fmt.Stringer`](https://golang.org/pkg/fmt/#Stringer). See an example of `query` return types from the [nameservice tutorial](https://github.com/cosmos/sdk-application-tutorial/blob/master/x/nameservice/internal/types/querier.go). +- `query` return types. Typically defined in a file `internal/types/querier.go`, they specify the result type of each of the module's `queries`. These custom types must implement the `String()` method of [`fmt.Stringer`](https://golang.org/pkg/fmt/#Stringer). See an example of `query` return types from the [nameservice tutorial](https://github.com/cosmos/sdk-application-tutorial/blob/master/x/nameservice/internal/types/querier.go). ## Next diff --git a/docs/building-modules/querier.md b/docs/building-modules/querier.md index e865f82eccab..d67ed78979a9 100644 --- a/docs/building-modules/querier.md +++ b/docs/building-modules/querier.md @@ -29,7 +29,7 @@ Let us break it down: ## Implementation of a module `querier`s -Module `querier`s are typically implemented in a `querier.go` file inside the module's folder. The [module manager](./module-manager.md) is used to add the module's `querier`s to the [application's `queryRouter`](../core/baseapp.md#query-routing) via the `NewQuerier()` method. Typically, the manager's `NewQuerier()` method simply calls a `NewQuerier()` method defined in `keeper/querier.go`, which looks like the following: +Module `querier`s are typically implemented in a `internal/keeper/querier.go` file inside the module's folder. The [module manager](./module-manager.md) is used to add the module's `querier`s to the [application's `queryRouter`](../core/baseapp.md#query-routing) via the `NewQuerier()` method. Typically, the manager's `NewQuerier()` method simply calls a `NewQuerier()` method defined in `keeper/querier.go`, which looks like the following: ```go func NewQuerier(keeper Keeper) sdk.Querier { From 190c5d3547ea1e1f4689dd1a53a31d02e12c23ef Mon Sep 17 00:00:00 2001 From: gamarin Date: Thu, 12 Sep 2019 19:43:04 +0200 Subject: [PATCH 112/196] genesis --- docs/basics/app-anatomy.md | 2 +- ...extending-modules => extending-modules.md} | 0 docs/building-modules/genesis.md | 46 +++++++++++++++++-- docs/building-modules/handler.md | 2 +- docs/core/baseapp.md | 2 +- 5 files changed, 45 insertions(+), 7 deletions(-) rename docs/building-modules/{extending-modules => extending-modules.md} (100%) diff --git a/docs/basics/app-anatomy.md b/docs/basics/app-anatomy.md index 15e1c9fc1e22..85b532f8d871 100644 --- a/docs/basics/app-anatomy.md +++ b/docs/basics/app-anatomy.md @@ -90,7 +90,7 @@ This function constructs a new application of the type defined above. It is call - Instantiate all the [`keeper`s](#keeper) defined in the application's `type` using the `NewKeeper` function of each of the application's modules. Note that `keepers` must be instantiated in the correct order, as the `NewKeeper` of one module might require a reference to another module's `keeper`. - Instantiate the application's [module manager](../building-modules/module-manager.md#manager) with the [`AppModule`](#application-module-interface) object of each of the application's modules. - With the module manager, initialize the application's [`routes`](../core/baseapp.md#routing) and [query routes](../core/baseapp.md#query-routing). When a transaction is relayed to the application by Tendermint via the ABCI, it is routed to the appropriate module's [`handler`](#handler) using the routes defined here. Likewise, when a query is received by the application, it is routed to the appropriate module's [`querier`](#querier) using the query routes defined here. -- With the module manager, register the [application's modules' invariants](./invariants.md). Invariants are variables (e.g. total supply of a token) that are evaluated at the end of each block. The process of checking invariants is done via a special module called the [`InvariantsRegistry`](../building-modules/invariants.md#invariant-registry). The value of the invariant should be equal to a predicted value defined in the module. Should the value be different than the predicted one, special logic defined in the invariant registry will be triggered (usually the chain is halted). This is useful to make sure no critical bug goes unnoticed and produces long-lasting effects that would be hard to fix. +- With the module manager, register the [application's modules' invariants](../building-modules/invariants.md). Invariants are variables (e.g. total supply of a token) that are evaluated at the end of each block. The process of checking invariants is done via a special module called the [`InvariantsRegistry`](../building-modules/invariants.md#invariant-registry). The value of the invariant should be equal to a predicted value defined in the module. Should the value be different than the predicted one, special logic defined in the invariant registry will be triggered (usually the chain is halted). This is useful to make sure no critical bug goes unnoticed and produces long-lasting effects that would be hard to fix. - With the module manager, set the order of execution between the `InitGenesis`, `BegingBlocker` and `EndBlocker` functions of each of the [application's modules](#application-module-interface). Note that not all modules implement these functions. - Set the remainer of application's parameters: + [`InitChainer`](#initchainer): used to initialize the application when it is first started. diff --git a/docs/building-modules/extending-modules b/docs/building-modules/extending-modules.md similarity index 100% rename from docs/building-modules/extending-modules rename to docs/building-modules/extending-modules.md diff --git a/docs/building-modules/genesis.md b/docs/building-modules/genesis.md index c877e33debff..dfe0b15bc2ad 100644 --- a/docs/building-modules/genesis.md +++ b/docs/building-modules/genesis.md @@ -1,9 +1,47 @@ # Module Genesis -## `GenesisState` +## Pre-requisite Reading -## `DefaultGenesis` +- [Module Manager](./module-manager.md) +- [Keepers](./keeper.md) -## `InitGenesis` +## Synopsis -## `ValidateGenesis` \ No newline at end of file +Modules generally handle a subset of the state and, as such, they need to define the related subset of the genesis file as well as methods to initialize, verify and export it. + +- [Type Definition](#type-definition) + + [InitGenesis](#initgenesis) + + [DefaultGenesis](#defaultgenesis) +- [Other Genesis Functions](#other-genesis-functions) + + [ValidateGenesis](#validategenesis) + + [ExportGenesis](#exportgenesis) + +## Type Definition + +The subset of the genesis state defined from a given module is generally defined in a `internal/types/genesis.go` file, along with the `DefaultGenesis` and `ValidateGenesis` methods. The struct defining the subset of the genesis state defined by the module is usually called `GenesisState` and contains all the module-related values that need to be initialized during the genesis process. + +See an example of `GenesisState` type definition from the [nameservice tutoria](https://github.com/cosmos/sdk-application-tutorial/blob/master/x/nameservice/genesis.go#L10-L12). + +### `DefaultGenesis` + +The `DefaultGenesis()` method is a simple method that calls the constructor function for `GenesisState` with the default value for each parameter. See an example [here](https://github.com/cosmos/sdk-application-tutorial/blob/master/x/nameservice/genesis.go#L14-L16). + +### `ValidateGenesis` + +The `ValidateGenesis(genesisState GenesisState)` method is called to verify that the provided `genesisState` is correct. It should perform validity checks on each of the parameter listed in `GenesisState`. See an example [here](https://github.com/cosmos/sdk-application-tutorial/blob/master/x/nameservice/genesis.go#L18-L31). + +## Other Genesis Methods + +Other than the methods related directly to `GenesisState`, module developers are expected to implement two other methods as part of the [`AppModuleGenesis` interface](./module-manager.md#appmodulegenesis) (only if the module needs to initialize a subset of state in genesis). These methods are [`InitGenesis`](#initgenesis) and [`ExportGenesis`](#exportgenesis). + +### `InitGenesis` + +The `InitGenesis` method is executed during [`InitChain`](../core/baseapp.md#initchain) when the application is first started. Given a `GenesisState`, it initializes the subset of the state managed by the module by using the module's [`keeper`](./keeper.md) setter function on each parameter within the `GenesisState`. + +See an [example of `InitGenesis` from the nameservice tutorial](https://github.com/cosmos/sdk-application-tutorial/blob/master/x/nameservice/genesis.go#L39-L44). + +### `ExportGenesis` + +The `ExportGenesis` method is executed whenever an export of the state is made. It takes the latest known version of the subset of the state managed by the module and creates a new `GenesisState` out of it. This is mainly used when the chain needs to be upgraded via a hard fork. + +See an [example of `ExportGenesis` from the nameservice tutorial](https://github.com/cosmos/sdk-application-tutorial/blob/master/x/nameservice/genesis.go#L46-L57). \ No newline at end of file diff --git a/docs/building-modules/handler.md b/docs/building-modules/handler.md index 5ecee9f5b98b..5ba01658fac5 100644 --- a/docs/building-modules/handler.md +++ b/docs/building-modules/handler.md @@ -2,7 +2,7 @@ ## Pre-requisite Reading -- [Module Manager](./module-manager.md). +- [Module Manager](./module-manager.md) - [Messages and Queries](./messages-and-queries.md) ## Synopsis diff --git a/docs/core/baseapp.md b/docs/core/baseapp.md index b0ef299e363b..38cc42228eb6 100644 --- a/docs/core/baseapp.md +++ b/docs/core/baseapp.md @@ -286,7 +286,7 @@ The [`InitChain` ABCI message](https://tendermint.com/docs/app-dev/abci-spec.htm - [`checkState` and `deliverState`](#volatile-states) via `setCheckState` and `setDeliverState`. - The [block gas meter](../basics/accounts-fees-gas.md#block-gas-meter), with infinite gas to process genesis transactions. -Finally, the `InitChain(req abci.RequestInitChain)` method of `baseapp` calls the [`initChainer()`](../basics/app-anatomy.md#initchainer) of the application in order to initialize the main state of the application from the [`genesis file`](./genesis.md) and, if defined, call the `InitGenesis` function of each of the application's modules. +Finally, the `InitChain(req abci.RequestInitChain)` method of `baseapp` calls the [`initChainer()`](../basics/app-anatomy.md#initchainer) of the application in order to initialize the main state of the application from the [`genesis file`](./genesis.md) and, if defined, call the [`InitGenesis`](../building-modules/genesis.md#initgenesis) function of each of the application's modules. ### BeginBlock From d2a2d91cc2b7bf3445c44f5d03f2a549652b3e01 Mon Sep 17 00:00:00 2001 From: gamarin Date: Fri, 13 Sep 2019 17:40:42 +0200 Subject: [PATCH 113/196] finish --- docs/building-modules/beginblock-endblock.md | 29 +++++++ docs/building-modules/extending-modules.md | 0 docs/building-modules/handler.md | 15 ++++ docs/building-modules/invariants.md | 85 +++++++++++++++++++- docs/building-modules/module-manager.md | 4 +- docs/building-modules/querier.md | 2 +- docs/building-modules/structure.md | 81 +++++++++++++++++++ docs/core/baseapp.md | 4 +- docs/{building-modules => core}/events.md | 0 9 files changed, 213 insertions(+), 7 deletions(-) create mode 100644 docs/building-modules/beginblock-endblock.md delete mode 100644 docs/building-modules/extending-modules.md create mode 100644 docs/building-modules/structure.md rename docs/{building-modules => core}/events.md (100%) diff --git a/docs/building-modules/beginblock-endblock.md b/docs/building-modules/beginblock-endblock.md new file mode 100644 index 000000000000..70582b7ae019 --- /dev/null +++ b/docs/building-modules/beginblock-endblock.md @@ -0,0 +1,29 @@ +# BeginBlocker and EndBlocker + +## Pre-requisite Reading + +- [Module Manager](./module-manager.md) + +## Synopsis + +`BeginBlocker` and `EndBlocker` are optional methods module developers can implement in their module. They will be triggered at the beginning and at the end of each block respectively. + +## BeginBlocker and EndBlocker + +`BeginBlocker` and `EndBlocker` are a way for module developers to add automatic execution of logic to their module. This is a powerful tool that should be used carefully, as complex automatic functions can slow down or even halt the chain. + +When needed, `BeginBlocker` and `EndBlocker` are implemented as part of the [`AppModule` interface](./module-manager.md#appmodule). The `BeginBlock` and `EndBlock` methods of the interface implemented in `module.go` generally defer to `BeginBlocker` and `EndBlocker` methods respectively, which are usually implemented in a `abci.go` file. + +The actual implementation of `BeginBlocker` and `EndBlocker` are very similar to that of a [`handler`](./handler.md): + +- They generally use the [`keeper`](./keeper.md) and [`ctx`](../core/context.md) to retrieve information about the latest state. +- If needed, they use the `keeper` and `ctx` to trigger state-transitions. +- If needed, they can emit [`events`](../core/events.md) via the `ctx`'s `EventManager`. + +A specificity of the `EndBlocker` is that it can return validator updates to the underlying consensus engine in the form of an [`[]abci.ValidatorUpdates`](https://tendermint.com/docs/app-dev/abci-spec.html#validatorupdate). + +For more, see an [example implementation of `BeginBlocker` from the `distr` module](https://github.com/cosmos/cosmos-sdk/blob/master/x/distribution/abci.go). + +## Next + +Learn about [`keeper`s](./keeper.md). \ No newline at end of file diff --git a/docs/building-modules/extending-modules.md b/docs/building-modules/extending-modules.md deleted file mode 100644 index e69de29bb2d1..000000000000 diff --git a/docs/building-modules/handler.md b/docs/building-modules/handler.md index 5ba01658fac5..17d46d87d7ea 100644 --- a/docs/building-modules/handler.md +++ b/docs/building-modules/handler.md @@ -51,6 +51,21 @@ This simple switch returns a `handler` function specific to the type of the rece - First, they perform *stateful* checks to make sure the `message` is valid. At this stage, the `message`'s `ValidateBasic()` method has already been called, meaning *stateless* checks on the message (like making sure parameters are correctly formatted) have already been performed. Checks performed in the `handler` can be more expensive and require access to the state. For example, a `handler` for a `transfer` message might check that the sending account has enough funds to actually perform the transfer. To access the state, the `handler` needs to call the [`keeper`'s](./keeper.md) getter functions. - Then, if the checks are successfull, the `handler` calls the [`keeper`'s](./keeper.md) setter functions to actually perform the state transition. +Before returning, `handler` functions generally emit one or multiple [`events`](../core/events.md) via the `EventManager` held in the `ctx`: + +```go +ctx.EventManager().EmitEvent( + sdk.NewEvent( + eventType, // e.g. sdk.EventTypeMessage for a message, types.CustomEventType for a custom event defined in the module + sdk.NewAttribute(attributeKey, attributeValue), + ), + ) +``` + +These `events` are relayed back to the underlying consensus engine and can be used by service providers to implement services around the application. Click [here](../core/events.md) to learn more about `events`. + +Finally, the `handler` function returns a [`sdk.Result`](https://github.com/tendermint/tendermint/blob/master/abci/types/result.go) which contains the aforementioned `events` and an optional `Data` field. + For a deeper look at `handler`s, see this [example implementation of a `handler` function](https://github.com/cosmos/sdk-application-tutorial/blob/master/x/nameservice/handler.go) from the nameservice tutorial. ## Next diff --git a/docs/building-modules/invariants.md b/docs/building-modules/invariants.md index 18cd9ad6224f..1f57b86deece 100644 --- a/docs/building-modules/invariants.md +++ b/docs/building-modules/invariants.md @@ -1,5 +1,86 @@ # Invariants -## What is an invariant +## Pre-requisite Reading -## Invariant Registry \ No newline at end of file +- [Keepers](./keeper.md) + +## Synopsis + +An invariant is a property of the application that should always be true. An `Invariant` is a function that checks for a particular invariant. These functions are useful to detect bugs early on and act upon them to limit the potential consequences (e.g. by halting the chain). They are also useful in the development process of the application to detect bugs via simulations. + +- [Implementing `Invariant`s](#implementing-invariants) +- [Invariant Registry](#invariant-registry) + +## Implementing `Invariant`s + +An `Invariant` is a function that checks for a particular invariant within a module. Module `Invariant`s must follow the [`Invariant`s type](https://github.com/cosmos/cosmos-sdk/blob/master/types/invariant.go#L9): + +```go +type Invariant func(ctx Context) (string, bool) +``` + +where the `string` return value is the invariant message, which can be used when printing logs, and the `bool` return value is the actual result of the invariant check. + +In practice, each module implements `Invariant`s in a `internal/keeper/invariants.go` file within the module's folder. The standard is to implement one `Invariant` function per logical grouping of invariants with the following model: + +```go +// Example for an Invariant that checks balance-related invariants + +func BalanceInvariants(k Keeper) sdk.Invariant { + return func(ctx sdk.Context) (string, bool) { + // Implement checks for balance-related invariants + } +} +``` + +Additionally, module developers should generally implement an `AllInvariants` function that runs all the `Invariant`s functions of the module: + +```go +// AllInvariants runs all invariants of the module. +// In this example, the module implements two Invariants: BalanceInvariants and DepositsInvariants + +func AllInvariants(k Keeper) sdk.Invariant { + + return func(ctx sdk.Context) (string, bool) { + res, stop := BalanceInvariants(k)(ctx) + if stop { + return res, stop + } + + return DepositsInvariant(k)(ctx) + } +} +``` + +Finally, module developers need to implement the `RegisterInvariants` method as part of the [`AppModule` interface](./module-manager.md#appmodule). Indeed, the `RegisterInvariants` method of the module, implemented in the `module.go` file, typically only defers the call to a `RegisterInvariants` method implemented in `internal/keeper/invariants.go`. The `RegisterInvariants` method registers a route for each `Invariant` function in the [`InvariantRegistry`](#invariant-registry): + + +```go +// RegisterInvariants registers all staking invariants +func RegisterInvariants(ir sdk.InvariantRegistry, k Keeper) { + ir.RegisterRoute(types.ModuleName, "module-accounts", + BalanceInvariants(k)) + ir.RegisterRoute(types.ModuleName, "nonnegative-power", + DepositsInvariant(k)) +} +``` + +For more, see an example of [`Invariant`s implementation from the `staking` module](https://github.com/cosmos/cosmos-sdk/blob/master/x/staking/keeper/invariants.go). + +## Invariant Registry + +The `InvariantRegistry` is a registry where the `Invariant`s of all the modules of an application are registered. Typically, it is implemented as a specific module. The module must implement an object that follow the [`sdk.InvariantRegistry` interface](https://github.com/cosmos/cosmos-sdk/blob/master/types/invariant.go#L14-L17). + +```go +type InvariantRegistry interface { + RegisterRoute(moduleName, route string, invar Invariant) +} +``` + +Typically, this interface is implemented in the module's `keeper`. You can see an example implementation of an `InvariantRegistry` from the `crisis` module [here](https://github.com/cosmos/cosmos-sdk/blob/master/x/crisis/internal/keeper/keeper.go). s + +`Invariant`s can be triggered manually via [`message`s](./messages-and-queries), but most often they are triggered automatically at the end of each block (see an example [here](https://github.com/cosmos/cosmos-sdk/blob/master/x/crisis/abci.go)). In both cases, if one of the `Invariant`s returns false, the `InvariantRegistry` can trigger special logic (e.g. have the application panic and print the `Invariant`s message in the log). + +## Next + +Learn about the recommended [structure for modules](./structure.md). diff --git a/docs/building-modules/module-manager.md b/docs/building-modules/module-manager.md index 6aefacc0d71c..ceb65c913875 100644 --- a/docs/building-modules/module-manager.md +++ b/docs/building-modules/module-manager.md @@ -187,8 +187,8 @@ The module manager is used throughout the application whenever an action on a co - `RegisterRoutes(router sdk.Router, queryRouter sdk.QueryRouter)`: Registers module routes to the application's `router`, in order to route [`message`s](./messages-and-queries.md#messages) to the appropriate [`handler`](./handler.md), and module query routes to the application's `queryRouter`, in order to route [`queries`](./messages-and-queries.md#queries) to the appropriate [`querier`](./querier.md). - `InitGenesis(ctx sdk.Context, genesisData map[string]json.RawMessage)`: Calls the [`InitGenesis`](./genesis.md#initgenesis) function of each module when the application is first started, in the order defined in `OrderInitGenesis`. Returns an `abci.ResponseInitChain` to the underlying consensus engine, which can contain validator updates. - `ExportGenesis(ctx sdk.Context)`: Calls the [`ExportGenesis`](./genesis.md#exportgenesis) function of each module, in the order defined in `OrderExportGenesis`. The export constructs a genesis file from a previously existing state, and is mainly used when a hard-fork upgrade of the chain is required. -- `BeginBlock(ctx sdk.Context, req abci.RequestBeginBlock)`: At the beginning of each block, this function calls the [`BeginBlock`] function of each module, in the order defined in `OrderBeginBlockers`. It creates a child [context](../core/context.md) with an event manager to aggregate [events](./events.md) emitted from all modules. The function returns an `abci.ResponseBeginBlock` which contains the aforementioned events. -- `EndBlock(ctx sdk.Context, req abci.RequestEndBlock)`: At the end of each block, this function calls the [`EndBlock`] function of each module, in the order defined in `OrderEndBlockers`. It creates a child [context](../core/context.md) with an event manager to aggregate [events](./events.md) emitted from all modules. The function returns an `abci.ResponseEndBlock` which contains the aforementioned events, as well as validator set updates (if any). +- `BeginBlock(ctx sdk.Context, req abci.RequestBeginBlock)`: At the beginning of each block, this function is called from [`baseapp`](../core/baseapp.md#beginblock) and, in turn, calls the [`BeginBlock`](./beginblock-endblock.md) function of each module, in the order defined in `OrderBeginBlockers`. It creates a child [context](../core/context.md) with an event manager to aggregate [events](../core/events.md) emitted from all modules. The function returns an `abci.ResponseBeginBlock` which contains the aforementioned events. +- `EndBlock(ctx sdk.Context, req abci.RequestEndBlock)`: At the end of each block, this function is called from [`baseapp`](../core/baseapp.md#endblock) and, in turn, calls the [`EndBlock`](./beginblock-endblock.md) function of each module, in the order defined in `OrderEndBlockers`. It creates a child [context](../core/context.md) with an event manager to aggregate [events](../core/events.md) emitted from all modules. The function returns an `abci.ResponseEndBlock` which contains the aforementioned events, as well as validator set updates (if any). ## Next diff --git a/docs/building-modules/querier.md b/docs/building-modules/querier.md index d67ed78979a9..7882a92aaead 100644 --- a/docs/building-modules/querier.md +++ b/docs/building-modules/querier.md @@ -54,4 +54,4 @@ For a deeper look at `querier`s, see this [example implementation of a `querier` ## Next -Learn about [`keeper`s](./keeper.md). +Learn about [`BeginBlocker` and `EndBlocker`](./beginblock-endblock.md). diff --git a/docs/building-modules/structure.md b/docs/building-modules/structure.md new file mode 100644 index 000000000000..d36d7a085bfe --- /dev/null +++ b/docs/building-modules/structure.md @@ -0,0 +1,81 @@ +# Module Structure Specification + +This document outlines the recommended structure of Cosmos SDK modules. These +ideas are meant to be applied as suggestions. Application developers are encouraged +to improve upon and contribute to module structure and development design. + +## Structure + +A typical Cosmos SDK module can be structured as follows: + +```shell +x/{module} +├── client +│ ├── cli +│ │ ├── query.go +│ │ └── tx.go +│ └── rest +│ ├── query.go +│ └── tx.go +├── exported +│ └── exported.go +├── internal +│ ├── keeper +│ │ ├── invariants.go +│ │ ├── keeper.go +│ │ ├── ... +│ │ └── querier.go +│ └── types +│ ├── codec.go +│ ├── errors.go +│ ├── events.go +│ ├── expected_keepers.go +│ ├── genesis.go +│ ├── keys.go +│ ├── msgs.go +│ ├── params.go +│ ├── ... +│ └── querier.go +├── abci.go +├── alias.go +├── genesis.go +├── handler.go +├── module.go +├── ... +└── simulation.go +``` + +- `abci.go`: The module's `BeginBlocker` and `EndBlocker` implementations (if any). +- `alias.go`: The module's exported types, constants, and variables. These are mainly +to improve developer ergonomics by only needing to import a single package. Note, +there is nothing preventing developers from importing other packages from the module +(excluding`internal/`) but it is recommended that `alias.go` have everything +exposed that other modules may need. The majority of the exported values here will +typically come from `internal/` (see below). +- `client/`: The module's CLI and REST client functionality implementation and +testing. +- `exported/`: The module's exported types -- typically type interfaces. If a module +relies on other module keepers, it is expected to receive them as interface +contracts through the `expected_keepers.go` (which are detailed below) design to +avoid having a direct dependency on the implementing module. However, these +contracts can define methods that operate on and/or return types that are specific +to the contract's implementing module and this is where `exported/` comes into play. +Types defined here allow for `expected_keepers.go` in other modules to define +contracts that use single canonical types. This pattern allows for code to remain +DRY and also alleviates import cycle chaos. +- `genesis.go`: The module's genesis related business logic (e.g. `InitGenesis`). +Note, genesis types are defined in `internal/types`. +- `handler.go`: The module's message handlers. +- `internal/`: The module's internal types and implementations. The purpose of +this package is mainly two fold. First, it signals that this package is not +intended to be used or imported anywhere outside the defining module. Secondly, +it goes hand-in-hand with `alias.go` in that it allows public types and functions +to be used internally while not being exposed outside to the outside world. This +allows for greater freedom of development while maintaining API stability. + - `internal/types`: The module's type definitions such as messages, `KVStore` + keys, parameter types, and `expected_keepers.go` contracts. + - `internal/keeper`: The module's keeper implementation along with any auxiliary + implementations such as the querier and invariants. +- `module.go`: The module's implementation of the `AppModule` and `AppModuleBasic` +interfaces. +- `simulation.go`: The module's simulation messages and related types (if any). \ No newline at end of file diff --git a/docs/core/baseapp.md b/docs/core/baseapp.md index 38cc42228eb6..99bb2b605ab6 100644 --- a/docs/core/baseapp.md +++ b/docs/core/baseapp.md @@ -294,12 +294,12 @@ The [`BeginBlock` ABCI message](#https://tendermint.com/docs/app-dev/abci-spec.h - Initialize [`deliverState`](#volatile-states) with the latest header using the `req abci.RequestBeginBlock` passed as parameter via the [`setDeliverState`](https://github.com/cosmos/cosmos-sdk/blob/master/baseapp/baseapp.go#L283-L289) function. - Initialize the [block gas meter](../basics/accounts-fees-gas.md#block-gas-meter) with the `maxGas` limit. The `gas` consumed within the block cannot go above `maxGas`. This parameter is defined in the application's consensus parameters. -- Run the application's [`begingBlocker()`](../basics/app-anatomy.md#beginblocker-and-endblock), which mainly runs the `BeginBlocker()` method of each of the application's modules. +- Run the application's [`begingBlocker()`](../basics/app-anatomy.md#beginblocker-and-endblock), which mainly runs the [`BeginBlocker()`](../building-modules/beginblock-endblock.md#beginblock) method of each of the application's modules. - Set the [`VoteInfos`](https://tendermint.com/docs/app-dev/abci-spec.html#voteinfo) of the application, i.e. the list of validators whose *precommit* for the previous block was included by the proposer of the current block. This information is carried into the [`Context`](./context.md) so that it can be used during `DeliverTx` and `EndBlock`. ### EndBlock -The [`EndBlock` ABCI message](#https://tendermint.com/docs/app-dev/abci-spec.html#endblock) is sent from the underlying Tendermint engine after [`DeliverTx`](#delivertx) as been run for each transactioni n the block. It allows developers to have logic be executed at the end of each block. In the Cosmos SDK, the bulk `EndBlock(req abci.RequestEndBlock)` method is to run the application's [`endBlocker()`](../basics/app-anatomy.md#beginblocker-and-endblock), which mainly runs the `EndBlocker()` method of each of the application's modules. +The [`EndBlock` ABCI message](#https://tendermint.com/docs/app-dev/abci-spec.html#endblock) is sent from the underlying Tendermint engine after [`DeliverTx`](#delivertx) as been run for each transactioni n the block. It allows developers to have logic be executed at the end of each block. In the Cosmos SDK, the bulk `EndBlock(req abci.RequestEndBlock)` method is to run the application's [`EndBlocker()`](../basics/app-anatomy.md#beginblocker-and-endblock), which mainly runs the [`EndBlocker()`](../building-modules/beginblock-endblock.md#beginblock) method of each of the application's modules. ### Commit diff --git a/docs/building-modules/events.md b/docs/core/events.md similarity index 100% rename from docs/building-modules/events.md rename to docs/core/events.md From c09597f236654b3c2db6c2b1692f9ac520ac212c Mon Sep 17 00:00:00 2001 From: gamarin2 Date: Mon, 16 Sep 2019 12:30:07 +0200 Subject: [PATCH 114/196] Apply suggestions from code review Co-Authored-By: Hans Schoenburg --- docs/building-modules/beginblock-endblock.md | 4 ++-- docs/building-modules/invariants.md | 4 ++-- docs/building-modules/keeper.md | 12 ++++++------ docs/building-modules/module-manager.md | 6 +++--- docs/core/baseapp.md | 2 +- 5 files changed, 14 insertions(+), 14 deletions(-) diff --git a/docs/building-modules/beginblock-endblock.md b/docs/building-modules/beginblock-endblock.md index 70582b7ae019..322d3f27e344 100644 --- a/docs/building-modules/beginblock-endblock.md +++ b/docs/building-modules/beginblock-endblock.md @@ -22,8 +22,8 @@ The actual implementation of `BeginBlocker` and `EndBlocker` are very similar to A specificity of the `EndBlocker` is that it can return validator updates to the underlying consensus engine in the form of an [`[]abci.ValidatorUpdates`](https://tendermint.com/docs/app-dev/abci-spec.html#validatorupdate). -For more, see an [example implementation of `BeginBlocker` from the `distr` module](https://github.com/cosmos/cosmos-sdk/blob/master/x/distribution/abci.go). +For more, see an [example implementation of `BeginBlocker` from the `distr` module](https://github.com/cosmos/cosmos-sdk/blob/master/x/distribution/abci.go) and an [example implementation of `EndBlocker`]( https://github.com/cosmos/cosmos-sdk/blob/master/x/staking/handler.go#L44) ## Next -Learn about [`keeper`s](./keeper.md). \ No newline at end of file +Learn about [`keeper`s](./keeper.md). diff --git a/docs/building-modules/invariants.md b/docs/building-modules/invariants.md index 1f57b86deece..e6097757a476 100644 --- a/docs/building-modules/invariants.md +++ b/docs/building-modules/invariants.md @@ -77,9 +77,9 @@ type InvariantRegistry interface { } ``` -Typically, this interface is implemented in the module's `keeper`. You can see an example implementation of an `InvariantRegistry` from the `crisis` module [here](https://github.com/cosmos/cosmos-sdk/blob/master/x/crisis/internal/keeper/keeper.go). s +Typically, this interface is implemented in the module's `keeper`. You can see an example implementation of an `InvariantRegistry` from the `crisis` module [here](https://github.com/cosmos/cosmos-sdk/blob/master/x/crisis/internal/keeper/keeper.go). -`Invariant`s can be triggered manually via [`message`s](./messages-and-queries), but most often they are triggered automatically at the end of each block (see an example [here](https://github.com/cosmos/cosmos-sdk/blob/master/x/crisis/abci.go)). In both cases, if one of the `Invariant`s returns false, the `InvariantRegistry` can trigger special logic (e.g. have the application panic and print the `Invariant`s message in the log). +`Invariant`s can be checked manually via [`message`s](./messages-and-queries), but most often they are checked automatically at the end of each block (see an example [here](https://github.com/cosmos/cosmos-sdk/blob/master/x/crisis/abci.go)). In both cases, if one of the `Invariant`s returns false, the `InvariantRegistry` can trigger special logic (e.g. have the application panic and print the `Invariant`s message in the log). ## Next diff --git a/docs/building-modules/keeper.md b/docs/building-modules/keeper.md index b9c478ed9281..1903d1f85ab4 100644 --- a/docs/building-modules/keeper.md +++ b/docs/building-modules/keeper.md @@ -6,7 +6,7 @@ ## Synopsis -`Keeper`s refer to a Cosmos SDK abstraction whose role is to manage access to the subset of the state defined by various modules. `Keeper`s are module-specific, i.e. the subset of state defined by a module can only be accessed by a `keeper` defined in said module. If a module needs to access the subset of state defined by another module, a reference to the second module's internal `keeper` needs to be passed to the first one. +`Keeper`s refer to a Cosmos SDK abstraction whose role is to manage access to the subset of the state defined by various modules. `Keeper`s are module-specific, i.e. the subset of state defined by a module can only be accessed by a `keeper` defined in said module. If a module needs to access the subset of state defined by another module, a reference to the second module's internal `keeper` needs to be passed to the first one. This is done in `app.go` during the instantiation of module keepers. - [Motivation](#motivation) - [Type Definition](#type-definition) @@ -16,9 +16,9 @@ The Cosmos SDK is a framework that makes it easy for developers to build complex decentralised applications from scratch, mainly by composing modules together. As the ecosystem of open source modules for the Cosmos SDK expands, it will become increasingly likely that some contain vulnerabilities, as a result of the negligence or malice of their developer. -The Cosmos SDK adopts a [capabilities-based approach](./ocap.md) to help developers better protect their application from unwanted inter-modules interactions, and `keeper`s are at the core of this approach. A `keeper` can be thougt quite literally as the gatekeeper of a module's store(s). Each store defined within a module comes with a `storeKey`, which grants unlimited access to it. The module's `keeper` holds this `storeKey` (which should otherwise remain unexposed), and defines [methods](#implementing-methods) for reading and writting to the store(s). +The Cosmos SDK adopts an [object-capabilities-based approach](./ocap.md) to help developers better protect their application from unwanted inter-module interactions, and `keeper`s are at the core of this approach. A `keeper` can be thought of quite literally as the gatekeeper of a module's store(s). Each store defined within a module comes with a `storeKey`, which grants unlimited access to it. The module's `keeper` holds this `storeKey` (which should otherwise remain unexposed), and defines [methods](#implementing-methods) for reading and writing to the store(s). -The core idea behind the object-capabilities approach is to only reveal what is necessary to get the work done. In practice, this means that instead of handling permissions of modules through an access-control lists, the `keeper`s of modules get a reference to a specific instance of the other modules' `keeper`s they need access to. As a consequence, a module can only interract with the subset of state defined in another module via the methods exposed by the instance of the other module's `keeper`. This is a great way for developers to control the interactions that their own module have with modules developed by external developers. +The core idea behind the object-capabilities approach is to only reveal what is necessary to get the work done. In practice, this means that instead of handling permissions of modules through access-control lists, module `keeper`s are passed a reference to the specific instance of the other modules' `keeper`s that they need to access. As a consequence, a module can only interact with the subset of state defined in another module via the methods exposed by the instance of the other module's `keeper`. This is a great way for developers to control the interactions that their own module can have with modules developed by external developers. ## Type Definition @@ -46,7 +46,7 @@ type Keeper struct { } ``` -Let us go through the different paramters: +Let us go through the different parameters: - An expected `keeper` is a `keeper` external to a module that is required by the internal `keeper` of said module. External `keeper`s are listed in the internal `keeper`'s type definition as interfaces. These interfaces are themselves defined in a `internal/types/expected_keepers.go` file within the module's folder. In this context, interfaces are used to reduce the number of dependencies, as well as to facilitate the maintenance of the module itself. - `storeKey`s grant access to the store(s) of the [multistore](../core/store.md) managed by the module. They should always remain unexposed to external modules. @@ -56,7 +56,7 @@ Of course, it is possible to define different types of internal `keeper`s for th ## Implementing Methods -`Keeper`s primarily expose getters and setters methods for the store(s) managed by their module. These methods should remain as simple as possible and strictly be limited to getting or setting the requested value, as validity checks should have already been performed via the `ValidateBasic()` method of the [`message`](./messages-and-queries.md#messages) and the [`handler`](./handler.go) when `keeper`s' methods are called. +`Keeper`s primarily expose getter and setter methods for the store(s) managed by their module. These methods should remain as simple as possible and strictly be limited to getting or setting the requested value, as validity checks should have already been performed via the `ValidateBasic()` method of the [`message`](./messages-and-queries.md#messages) and the [`handler`](./handler.go) when `keeper`s' methods are called. Typically, a *getter* method will present with the following signature @@ -86,4 +86,4 @@ For more, see an example of `keeper`'s [methods implementation from the nameserv ## Next -Learn about [invariants](./invariants.md). \ No newline at end of file +Learn about [invariants](./invariants.md). diff --git a/docs/building-modules/module-manager.md b/docs/building-modules/module-manager.md index ceb65c913875..68398c6a5fbb 100644 --- a/docs/building-modules/module-manager.md +++ b/docs/building-modules/module-manager.md @@ -164,7 +164,7 @@ It implements the following methods: ### `Manager` -The [`Manager`](https://github.com/cosmos/cosmos-sdk/blob/master/types/module/module.go#L203-L209) is a structure that lists all the `AppModule` of an application, and defines the order of execution between several key components of these modules: +The [`Manager`](https://github.com/cosmos/cosmos-sdk/blob/master/types/module/module.go#L203-L209) is a structure that holds all the `AppModule` of an application, and defines the order of execution between several key components of these modules: ```go type Manager struct { @@ -176,7 +176,7 @@ type Manager struct { } ``` -The module manager is used throughout the application whenever an action on a collection of module is required. It implements the following methods: +The module manager is used throughout the application whenever an action on a collection of modules is required. It implements the following methods: - `NewManager(modules ...AppModule)`: Constructor function. It takes a list of the application's `AppModule`s and builds a new `Manager`. It is generally called from the application's main [constructor function](../basics/app-anatomy.md#constructor-function). - `SetOrderInitGenesis(moduleNames ...string)`: Sets the order in which the [`InitGenesis`](./genesis.md#initgenesis) function of each module will be called when the application is first started. This function is generally called from the application's main [constructor function](../basics/app-anatomy.md#constructor-function). @@ -192,4 +192,4 @@ The module manager is used throughout the application whenever an action on a co ## Next -Learn more about [`message`s and `queries`](./messages-and-queries.md). \ No newline at end of file +Learn more about [`message`s and `queries`](./messages-and-queries.md). diff --git a/docs/core/baseapp.md b/docs/core/baseapp.md index 99bb2b605ab6..105515b989a8 100644 --- a/docs/core/baseapp.md +++ b/docs/core/baseapp.md @@ -299,7 +299,7 @@ The [`BeginBlock` ABCI message](#https://tendermint.com/docs/app-dev/abci-spec.h ### EndBlock -The [`EndBlock` ABCI message](#https://tendermint.com/docs/app-dev/abci-spec.html#endblock) is sent from the underlying Tendermint engine after [`DeliverTx`](#delivertx) as been run for each transactioni n the block. It allows developers to have logic be executed at the end of each block. In the Cosmos SDK, the bulk `EndBlock(req abci.RequestEndBlock)` method is to run the application's [`EndBlocker()`](../basics/app-anatomy.md#beginblocker-and-endblock), which mainly runs the [`EndBlocker()`](../building-modules/beginblock-endblock.md#beginblock) method of each of the application's modules. +The [`EndBlock` ABCI message](#https://tendermint.com/docs/app-dev/abci-spec.html#endblock) is sent from the underlying Tendermint engine after [`DeliverTx`](#delivertx) as been run for each transaction in the block. It allows developers to have logic be executed at the end of each block. In the Cosmos SDK, the bulk `EndBlock(req abci.RequestEndBlock)` method is to run the application's [`EndBlocker()`](../basics/app-anatomy.md#beginblocker-and-endblock), which mainly runs the [`EndBlocker()`](../building-modules/beginblock-endblock.md#beginblock) method of each of the application's modules. ### Commit From e20c6d392bfaf3a8321ac4718465a25e3f8e2b21 Mon Sep 17 00:00:00 2001 From: gamarin Date: Mon, 16 Sep 2019 12:44:05 +0200 Subject: [PATCH 115/196] hans review --- docs/building-modules/intro.md | 2 +- docs/building-modules/invariants.md | 4 +++- docs/building-modules/messages-and-queries.md | 2 +- 3 files changed, 5 insertions(+), 3 deletions(-) diff --git a/docs/building-modules/intro.md b/docs/building-modules/intro.md index 7eefb949160c..0a2fb5902bc9 100644 --- a/docs/building-modules/intro.md +++ b/docs/building-modules/intro.md @@ -7,7 +7,7 @@ ## Synopsis -Modules define most of the logic of any SDK application. Developers compose module together to build their custom application-specific blockchains. This document outlines the basic concepts behind SDK modules and how to approach module management. +Modules define most of the logic of any SDK application. Developers compose module together using the Cosmos SDK to build their custom application-specific blockchains. This document outlines the basic concepts behind SDK modules and how to approach module management. - [Role of Modules in an SDK application](#role-of-modules-in-an-sdk-application) - [How to Approach Building Modules as a Developer](#how-to-approach-building-modules-as-a-developer) diff --git a/docs/building-modules/invariants.md b/docs/building-modules/invariants.md index e6097757a476..72bbd53c7e05 100644 --- a/docs/building-modules/invariants.md +++ b/docs/building-modules/invariants.md @@ -69,7 +69,9 @@ For more, see an example of [`Invariant`s implementation from the `staking` modu ## Invariant Registry -The `InvariantRegistry` is a registry where the `Invariant`s of all the modules of an application are registered. Typically, it is implemented as a specific module. The module must implement an object that follow the [`sdk.InvariantRegistry` interface](https://github.com/cosmos/cosmos-sdk/blob/master/types/invariant.go#L14-L17). +The `InvariantRegistry` is a registry where the `Invariant`s of all the modules of an application are registered. There is only one `InvariantRegistry` per **application**, meaning module developers need not implement their own `InvariantRegistry` when building a module. All module developers need to do is to register their modules' invariants in the `InvariantRegistry`, as explained in the section above. + +Typically, the `InvariantRegistry` is implemented as a specific module (the most used implementation is that of the [`crisis` module](https://github.com/cosmos/cosmos-sdk/blob/master/x/crisis/)). This module must implement an object that follow the [`sdk.InvariantRegistry` interface](https://github.com/cosmos/cosmos-sdk/blob/master/types/invariant.go#L14-L17). ```go type InvariantRegistry interface { diff --git a/docs/building-modules/messages-and-queries.md b/docs/building-modules/messages-and-queries.md index 52614ddbdc82..7ebfaf2c76dd 100644 --- a/docs/building-modules/messages-and-queries.md +++ b/docs/building-modules/messages-and-queries.md @@ -33,7 +33,7 @@ The `Msg` is typically accompagnied by a standard constructor function, that is - `Route() string`: Name of the route for this message. Typically all `message`s in a module have the same route, which is most often the module's name. - `Type() string`: Type of the message, used primarly in [events](./events.md). This should return a message-specific `string`, typically the denomination of the message itself. -- `ValidateBasic() Error`: This method is called by `baseapp` very early in the processing of the `message`, in order to discard obviously invalid messages. `ValidateBasic` should only include *stateless* checks, i.e. checks that do not require access to the state. This usually consists in checking that the message's parameters are correctly formatted and valid (i.e. that the `amount` is strictly positive for a transfer). +- `ValidateBasic() Error`: This method is called by `baseapp` very early in the processing of the `message` (in both [`CheckTx`](../core/baseapp.md#checktx) and [`DeliverTx`](../core/baseapp.md#delivertx)), in order to discard obviously invalid messages. `ValidateBasic` should only include *stateless* checks, i.e. checks that do not require access to the state. This usually consists in checking that the message's parameters are correctly formatted and valid (i.e. that the `amount` is strictly positive for a transfer). - `GetSignBytes() []byte`: Return the canonical byte representation of the message. Used to generate a signature. - `GetSigners() []AccAddress`: Return the list of signers. The SDK will make sure that each `message` contained in a transaction is signed by all the signers listed in the list returned by this method. From 628ad722c3bf6ff788df6d3ab0a39798102cb420 Mon Sep 17 00:00:00 2001 From: gamarin2 Date: Mon, 16 Sep 2019 12:45:12 +0200 Subject: [PATCH 116/196] Update docs/core/baseapp.md Co-Authored-By: Hans Schoenburg --- docs/core/baseapp.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/core/baseapp.md b/docs/core/baseapp.md index 105515b989a8..3fd6cd34681d 100644 --- a/docs/core/baseapp.md +++ b/docs/core/baseapp.md @@ -294,7 +294,7 @@ The [`BeginBlock` ABCI message](#https://tendermint.com/docs/app-dev/abci-spec.h - Initialize [`deliverState`](#volatile-states) with the latest header using the `req abci.RequestBeginBlock` passed as parameter via the [`setDeliverState`](https://github.com/cosmos/cosmos-sdk/blob/master/baseapp/baseapp.go#L283-L289) function. - Initialize the [block gas meter](../basics/accounts-fees-gas.md#block-gas-meter) with the `maxGas` limit. The `gas` consumed within the block cannot go above `maxGas`. This parameter is defined in the application's consensus parameters. -- Run the application's [`begingBlocker()`](../basics/app-anatomy.md#beginblocker-and-endblock), which mainly runs the [`BeginBlocker()`](../building-modules/beginblock-endblock.md#beginblock) method of each of the application's modules. +- Run the application's [`beginBlocker()`](../basics/app-anatomy.md#beginblocker-and-endblock), which mainly runs the [`BeginBlocker()`](../building-modules/beginblock-endblock.md#beginblock) method of each of the application's modules. - Set the [`VoteInfos`](https://tendermint.com/docs/app-dev/abci-spec.html#voteinfo) of the application, i.e. the list of validators whose *precommit* for the previous block was included by the proposer of the current block. This information is carried into the [`Context`](./context.md) so that it can be used during `DeliverTx` and `EndBlock`. ### EndBlock From 9fa66e4eca6dfcecad25c53e7a01fd786f2d6ac1 Mon Sep 17 00:00:00 2001 From: gamarin Date: Tue, 17 Sep 2019 17:38:42 +0200 Subject: [PATCH 117/196] working --- docs/basics/accounts-fees-gas.md | 160 +++++++++++++++++++++++++++++-- docs/basics/tx-lifecycle.md | 12 +-- docs/building-modules/handler.md | 9 ++ docs/core/baseapp.md | 5 +- docs/core/events.md | 51 +++++++++- 5 files changed, 222 insertions(+), 15 deletions(-) diff --git a/docs/basics/accounts-fees-gas.md b/docs/basics/accounts-fees-gas.md index 10b0d82885ed..1daf3ecc4b3b 100644 --- a/docs/basics/accounts-fees-gas.md +++ b/docs/basics/accounts-fees-gas.md @@ -1,15 +1,163 @@ # Accounts, Fees and Gas +## Pre-requisite Reading + +- [Anatomy of an SDK Application](./app-anatomy.md) + +## Synopsis + +This document describes the in-built accounts system of the Cosmos SDK, as well as the default strategies to handle fees and gas within a Cosmos SDK application. + +- [Accounts](#accounts) + + [KeyBase](#keybase) + + [Addresses](#addresses) + + [Signatures](#signatures) +- [Fees and Gas](#fees-and-gas) + + [AnteHandler](#antehandler) + + [Gas](#gas) + + [Gas Meter](#gas-meter) + + [Block Gas Meter](#block-gas-meter) + ## Accounts -## AnteHandler +In the Cosmos SDK, an *account* designates a pair of *public key* `PubKey` and *private key* `PrivKey`. The `PubKey` can be derived to generate various `Addresses`, which are used to identify users (among other parties) in the application. `Addresses` are also associated with [`message`s](../building-modules/messages-and-queries.md#messages) to identify the sender of the `message`. The `PrivKey` is used to generate [digital signatures](#signatures) to prove that an `Address` associated with the `PrivKey` approved of a given `message`. + +To derive `PubKey`s and `PrivKey`s, the Cosmos SDK uses a standard called [BIP32](https://github.com/bitcoin/bips/blob/master/bip-0032.mediawiki). This standard defines how to build an HD wallet, where a wallet is a set of accounts. At the core of every account, there is a seed, which takes the form of a 12 or 24-words mnemonic. From this mnemonic, it is possible to derive any number of `PrivKey`s using one-way cryptographic function. Then, a `PubKey` can be derived from the `PrivKey`. Naturally, the mnemonic is the most sensitive information, as private keys can always be re-generated if the mnemonic is preserved. + +``` + Account 0 Account 1 Account 2 + ++------------------+ +------------------+ +------------------+ +| | | | | | +| Address 0 | | Address 1 | | Address 2 | +| ^ | | ^ | | ^ | +| | | | | | | | | +| | | | | | | | | +| | | | | | | | | +| + | | + | | + | +| Public key 0 | | Public key 1 | | Public key 2 | +| ^ | | ^ | | ^ | +| | | | | | | | | +| | | | | | | | | +| | | | | | | | | +| + | | + | | + | +| Private key 0 | | Private key 1 | | Private key 2 | +| ^ | | ^ | | ^ | ++------------------+ +------------------+ +------------------+ + | | | + | | | + | | | + +--------------------------------------------------------------------+ + | + | + +---------+---------+ + | | + | Master PrivKey | + | | + +-------------------+ + | + | + +---------+---------+ + | | + | Mnemonic (Seed) | + | | + +-------------------+ +``` + +In the Cosmos SDK, accounts are stored and managed via an object called a [`Keybase`](#keybase). + +### Keybase + +A `Keybase` is an object that stores and manages accounts. In the Cosmos SDK, a `Keybase` implementation follows the [`Keybase` interface](https://github.com/cosmos/cosmos-sdk/blob/master/crypto/keys/types.go#L14-L60): + +```go +type Keybase interface { + // CRUD on the keystore + List() ([]Info, error) + Get(name string) (Info, error) + GetByAddress(address types.AccAddress) (Info, error) + Delete(name, passphrase string, skipPass bool) error + + // Sign some bytes, looking up the private key to use + Sign(name, passphrase string, msg []byte) ([]byte, crypto.PubKey, error) + + // CreateMnemonic creates a new mnemonic, and derives a hierarchical deterministic + // key from that. + CreateMnemonic(name string, language Language, passwd string, algo SigningAlgo) (info Info, seed string, err error) + + // CreateAccount creates an account based using the BIP44 path (44'/118'/{account}'/0/{index} + CreateAccount(name, mnemonic, bip39Passwd, encryptPasswd string, account uint32, index uint32) (Info, error) + + // Derive computes a BIP39 seed from th mnemonic and bip39Passwd. + // Derive private key from the seed using the BIP44 params. + // Encrypt the key to disk using encryptPasswd. + // See https://github.com/cosmos/cosmos-sdk/issues/2095 + Derive(name, mnemonic, bip39Passwd, encryptPasswd string, params hd.BIP44Params) (Info, error) + + // CreateLedger creates, stores, and returns a new Ledger key reference + CreateLedger(name string, algo SigningAlgo, hrp string, account, index uint32) (info Info, err error) + + // CreateOffline creates, stores, and returns a new offline key reference + CreateOffline(name string, pubkey crypto.PubKey) (info Info, err error) + + // CreateMulti creates, stores, and returns a new multsig (offline) key reference + CreateMulti(name string, pubkey crypto.PubKey) (info Info, err error) + + // The following operations will *only* work on locally-stored keys + Update(name, oldpass string, getNewpass func() (string, error)) error + Import(name string, armor string) (err error) + ImportPrivKey(name, armor, passphrase string) error + ImportPubKey(name string, armor string) (err error) + Export(name string) (armor string, err error) + ExportPubKey(name string) (armor string, err error) + ExportPrivKey(name, decryptPassphrase, encryptPassphrase string) (armor string, err error) + + // ExportPrivateKeyObject *only* works on locally-stored keys. Temporary method until we redo the exporting API + ExportPrivateKeyObject(name string, passphrase string) (crypto.PrivKey, error) + + // CloseDB closes the database. + CloseDB() +} +``` + +The default implementation of `Keybase` of the Cosmos SDK is [`dbKeybase`](https://github.com/cosmos/cosmos-sdk/blob/master/crypto/keys/keybase.go). A few notes on the `Keybase` methods as implemented in `dbKeybase`: + +- `Sign(name, passphrase string, msg []byte) ([]byte, crypto.PubKey, error)` strictly deals with the signature of the `message` bytes. Some preliminary work should be done beforehand to prepare and encode the `message` into a canonical `[]byte` form. See an example of `message` preparation from the `auth` module](https://github.com/cosmos/cosmos-sdk/blob/master/x/auth/types/txbuilder.go#L177-L207). +- `CreateMnemonic(name string, language Language, passwd string, algo SigningAlgo) (info Info, seed string, err error)` creates a new mnemonic and prints it in the logs, but it **does not persist it on disk**. +- `CreateAccount(name, mnemonic, bip39Passwd, encryptPasswd string, account uint32, index uint32) (Info, error)` creates a new account based on the [`bip44 path`](https://github.com/bitcoin/bips/blob/master/bip-0044.mediawiki) and persists it on disk (note that the `PrivKey` is [encrypted with a passphrase before being persisted](https://github.com/cosmos/cosmos-sdk/blob/master/crypto/keys/mintkey/mintkey.go), it is **never stored unencrypted**). In the context of this method, the `account` parameter refers to the derivation path (e.g. `0`, `1`, `2`, ...) used to derive the `PrivKey` from the mnemonic (note that given the same mnemonic and `account`, `CreateAccount` will always return the same `PrivKey`). As for the `address` parameter, it refers to the derivation path used to derive `Addresses` from the `PubKey`. Any number of `Addresses` can be derived from the same `PubKey`, giving the possibility to developers to make use of single-use addresses for accounts. Finally, note that the `CreateAccount` method derives keys and addresses using `secp256k1` as implemented in the [Tendermint library](https://github.com/tendermint/tendermint/blob/master/crypto/secp256k1). As a result, it only works for creating account keys and addresses, not consensus keys. See [`Addresses`](#addresses) for more. + +The current implementation of `dbKeybase` is basic and does not offer on-demand locking. If an instance of `dbKeybase` is created, the underlying `db` is locked meaning no other process can access it besides the one in which it was instantiated. This is the reason why the default SDK client uses another implementation of the `Keybase` interface called [`lazyKeybase`](https://github.com/cosmos/cosmos-sdk/blob/master/crypto/keys/lazy_keybase.go). `lazyKeybase` is simple wrapper around `dbKeybase` which locks the database only when operations are to be performed and unlocks it immediately after: + +```go +// Example Get method of lazyKeybase + +func (lkb lazyKeybase) Get(name string) (Info, error) { + db, err := sdk.NewLevelDB(lkb.name, lkb.dir) + if err != nil { + return nil, err + } + defer db.Close() + + return newDbKeybase(db).Get(name) +} +``` + +With the `lazyKeybase`, it is possible for the [command-line interface](../interfaces/cli.md) to create a new account while the [rest server](../interfaces/rest.md) is running. It is also possible to pipe multiple CLI commands. + +The `lazyKeybase` is typically used from + +### Addresses + + + +### Signatures -## Signatures +## Fees and Gas -## Fees +### AnteHandler -## Gas +### Gas -## Gas Meter +### Gas Meter -## Block Gas Meter \ No newline at end of file +### Block Gas Meter \ No newline at end of file diff --git a/docs/basics/tx-lifecycle.md b/docs/basics/tx-lifecycle.md index 01bf4848d5ff..d0b6892ba885 100644 --- a/docs/basics/tx-lifecycle.md +++ b/docs/basics/tx-lifecycle.md @@ -2,17 +2,17 @@ ## Prerequisite Reading -* [Anatomy of an SDK Application](./app-anatomy.md) +- [Anatomy of an SDK Application](./app-anatomy.md) ## Synopsis This document describes the lifecycle of a transaction from creation to committed state changes. Transaction definition is described in a [different doc](../core/tx-msgs.md#transactions). The transaction will be referred to as `Tx`. -1. [Creation](#creation) -2. [Addition to Mempool](#addition-to-mempool) -3. [Inclusion in a Block](#inclusion-in-a-block) -4. [State Changes](#state-changes) -5. [Consensus and Commit](#consensus-and-commit) +- [Creation](#creation) +- [Addition to Mempool](#addition-to-mempool) +- [Inclusion in a Block](#inclusion-in-a-block) +- [State Changes](#state-changes) +- [Consensus and Commit](#consensus-and-commit) ## Creation diff --git a/docs/building-modules/handler.md b/docs/building-modules/handler.md index 17d46d87d7ea..018ddfd52730 100644 --- a/docs/building-modules/handler.md +++ b/docs/building-modules/handler.md @@ -66,6 +66,15 @@ These `events` are relayed back to the underlying consensus engine and can be us Finally, the `handler` function returns a [`sdk.Result`](https://github.com/tendermint/tendermint/blob/master/abci/types/result.go) which contains the aforementioned `events` and an optional `Data` field. +```go +// Example handler result + +return sdk.Result{ + Data: GetProposalIDBytes(proposal.ProposalID), + Events: ctx.EventManager().Events(), + } +``` + For a deeper look at `handler`s, see this [example implementation of a `handler` function](https://github.com/cosmos/sdk-application-tutorial/blob/master/x/nameservice/handler.go) from the nameservice tutorial. ## Next diff --git a/docs/core/baseapp.md b/docs/core/baseapp.md index 3fd6cd34681d..4655d817a9d4 100644 --- a/docs/core/baseapp.md +++ b/docs/core/baseapp.md @@ -217,9 +217,10 @@ Steps 2. and 3. are performed by the [`anteHandler`](./accounts-fees-gas.md#ant - `Info (string):` Additional information. May be non-deterministic. - `GasWanted (int64)`: Amount of gas requested for transaction. It is provided by users when they generate the transaction. - `GasUsed (int64)`: Amount of gas consumed by transaction. During `CheckTx`, this value is computed by multiplying the standard cost of a transaction byte by the size of the raw transaction (click [here](https://github.com/cosmos/cosmos-sdk/blob/master/x/auth/ante.go#L101) for an example). -- `Tags ([]cmn.KVPair)`: Key-Value tags for filtering and indexing transactions (eg. by account). +- `Events ([]cmn.KVPair)`: Key-Value tags for filtering and indexing transactions (eg. by account). See [`event`s](./events.md) for more. - `Codespace (string)`: Namespace for the Code. + ### DeliverTx When the underlying consensus engine receives a block proposal, each transaction in the block needs to be processed by the application. To that end, the underlying consensus engine sends a `DeliverTx` message to the application for each transaction in a sequential order. @@ -241,7 +242,7 @@ During step 5., each read/write to the store increases the value of `GasConsumed - `Info (string):` Additional information. May be non-deterministic. - `GasWanted (int64)`: Amount of gas requested for transaction. It is provided by users when they generate the transaction. - `GasUsed (int64)`: Amount of gas consumed by transaction. During `DeliverTx`, this value is computed by multiplying the standard cost of a transaction byte by the size of the raw transaction (click [here](https://github.com/cosmos/cosmos-sdk/blob/master/x/auth/ante.go#L101) for an example), and by adding gas each time a read/write to the store occurs. -- `Tags ([]cmn.KVPair)`: Key-Value tags for filtering and indexing transactions (eg. by account). +- `Events ([]cmn.KVPair)`: Key-Value tags for filtering and indexing transactions (eg. by account). See [`event`s](./events.md) for more. - `Codespace (string)`: Namespace for the Code. ## RunTx, AnteHandler and RunMsgs diff --git a/docs/core/events.md b/docs/core/events.md index cbf945847cd4..97c8ec70e46e 100644 --- a/docs/core/events.md +++ b/docs/core/events.md @@ -1 +1,50 @@ -# Events \ No newline at end of file +# Events + +## Pre-Requisite Reading + +- [Anatomy of an SDK application](../basics/app-anatomy.md) + +## Synopsis + +`Event`s are objects that contain information about the execution of the application. They are mainly used by service providers like block explorers and wallet to track the execution of various messages and index transactions. + +- [Events](#events) +- [EventManager](#eventmanager) + +## Events + +`Event`s are implemented in the Cosmos SDK as an alias of the [ABCI `event` type](https://github.com/tendermint/tendermint/blob/master/abci/types/types.pb.go#L2661-L2667). They contain: + +- A **type** of type `string`, which can refer to the type of action that led to the `event`'s emission (e.g. a certain value going above a threshold), or to the type of `message` if the event is triggered at the end of that `message` processing. +- A list of [`attributes`](https://github.com/cosmos/cosmos-sdk/blob/master/types/events.go#L53-L56), which are key-value pairs that give more information about the `event`. + +`Event`s are returned to the underlying consensus engine in the response of the following ABCI messages: [`CheckTx`](./baseapp.md#checktx), [`DeliverTx`](./baseapp.md#delivertx), [`BeginBlock`](./baseapp.md#beginblock) and [`EndBlock`](./baseapp.md#endblock). + +## EventManager + +In Cosmos SDK applications, `event`s are generally managed by an object called the [`EventManager`](https://github.com/cosmos/cosmos-sdk/blob/master/types/events.go#L18-L20). It is implemented as a simple wrapper around a slice of `event`s: + +```go +type EventManager struct { + events Events +} +``` + +The `EventManager` comes with a set of useful methods to manage `event`s. Among them, the one that is used the most by module and application developers is the [`EmitEvent`](https://github.com/cosmos/cosmos-sdk/blob/master/types/events.go#L29-L31) method, which registers an `event` in the `EventManager`. + +Typically, module developers will implement event emission via the `EventManager` in the [`handler`](../building-modules/handler.md) of modules, as well as in the [`BeginBlocker` and/or`EndBlocker` functions](../building-modules/beginblock-endblock.md). The `EventManager` is accessed via the context [`ctx`](./context.md), and event emission generally follows this pattern: + +```go +ctx.EventManager().EmitEvent( + sdk.NewEvent( + eventType, // e.g. sdk.EventTypeMessage for a message, types.CustomEventType for a custom event defined in the module + sdk.NewAttribute(attributeKey, attributeValue), + ), + ) +``` + +See the [`handler` concept doc](../building-modules/handler.md) for a more detailed view on how to typically implement `events` and use the `EventManager` in modules. + +## Next + +Learn about [encoding](./encoding.md) \ No newline at end of file From 6914e0da10f3800895dcfcb2539914b6f0d1646a Mon Sep 17 00:00:00 2001 From: Gloria Zhao Date: Tue, 17 Sep 2019 12:00:48 -0700 Subject: [PATCH 118/196] last comment --- docs/building-modules/module-interfaces.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/docs/building-modules/module-interfaces.md b/docs/building-modules/module-interfaces.md index 300bd6b0817c..ef4ea1273bc2 100644 --- a/docs/building-modules/module-interfaces.md +++ b/docs/building-modules/module-interfaces.md @@ -129,8 +129,8 @@ This query returns the address that owns a particular name. The getter function - **`RunE`.** The function should be specified as a `RunE` to allow for errors to be returned. This function encapsulates all of the logic to create a new query that is ready to be relayed to nodes. + The function should first initialize a new [`CLIContext`](./query-lifecycle.md#clicontext) with the application `codec`. + If applicable, the `CLIContext` is used to retrieve any parameters (e.g. the query originator's address to be used in the query) and marshal them with the query parameter type, in preparation to be relayed to a node. There are no `CLIContext` parameters in this case because the query does not involve any information about the user. - + The `queryRoute` is used to construct a route Baseapp will use to route the query to the appropriate [querier](./querier.md). Module queries are `custom` type queries (some SDK modules have exceptions, such as `auth` and `gov` module queries). - + The `CLIContext` query function relays the query to a node and retrieves the response. + + The `queryRoute` is used to construct a `path` [`baseapp`](../basics/baseapp.md) will use to route the query to the appropriate [querier](./querier.md). The expected format for a query `path` is "queryCategory/queryRoute/queryType/arg1/arg2/...", where `queryCategory` can be `p2p`, `store`, `app`, or `custom`, `queryRoute` is the name of the module, and `queryType` is the name of the query type defined within the module. [`baseapp`](../basics/baseapp.md) can handle each type of `queryCategory` by routing it to a module querier or retrieving results directly from stores and functions for querying peer nodes. Module queries are `custom` type queries (some SDK modules have exceptions, such as `auth` and `gov` module queries). + + The `CLIContext` `QueryWithData()` function is used to relay the query to a node and retrieve the response. It requires the `path`. It returns the result and height of the query upon success or an error if the query fails. In addition, it will verify the returned proof if `TrustNode` is disabled. If proof verification fails or the query height is invalid, an error will be returned. + The `codec` is used to nmarshal the response and the `CLIContext` is used to print the output back to the user. - **Flags.** Add any [flags](#flags) to the command. From 036f418e36ce451006e056afbdc4929686df1099 Mon Sep 17 00:00:00 2001 From: gamarin Date: Tue, 17 Sep 2019 21:37:31 +0200 Subject: [PATCH 119/196] workin --- docs/basics/accounts-fees-gas.md | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/docs/basics/accounts-fees-gas.md b/docs/basics/accounts-fees-gas.md index 1daf3ecc4b3b..edf3f8546407 100644 --- a/docs/basics/accounts-fees-gas.md +++ b/docs/basics/accounts-fees-gas.md @@ -124,9 +124,9 @@ The default implementation of `Keybase` of the Cosmos SDK is [`dbKeybase`](https - `Sign(name, passphrase string, msg []byte) ([]byte, crypto.PubKey, error)` strictly deals with the signature of the `message` bytes. Some preliminary work should be done beforehand to prepare and encode the `message` into a canonical `[]byte` form. See an example of `message` preparation from the `auth` module](https://github.com/cosmos/cosmos-sdk/blob/master/x/auth/types/txbuilder.go#L177-L207). - `CreateMnemonic(name string, language Language, passwd string, algo SigningAlgo) (info Info, seed string, err error)` creates a new mnemonic and prints it in the logs, but it **does not persist it on disk**. -- `CreateAccount(name, mnemonic, bip39Passwd, encryptPasswd string, account uint32, index uint32) (Info, error)` creates a new account based on the [`bip44 path`](https://github.com/bitcoin/bips/blob/master/bip-0044.mediawiki) and persists it on disk (note that the `PrivKey` is [encrypted with a passphrase before being persisted](https://github.com/cosmos/cosmos-sdk/blob/master/crypto/keys/mintkey/mintkey.go), it is **never stored unencrypted**). In the context of this method, the `account` parameter refers to the derivation path (e.g. `0`, `1`, `2`, ...) used to derive the `PrivKey` from the mnemonic (note that given the same mnemonic and `account`, `CreateAccount` will always return the same `PrivKey`). As for the `address` parameter, it refers to the derivation path used to derive `Addresses` from the `PubKey`. Any number of `Addresses` can be derived from the same `PubKey`, giving the possibility to developers to make use of single-use addresses for accounts. Finally, note that the `CreateAccount` method derives keys and addresses using `secp256k1` as implemented in the [Tendermint library](https://github.com/tendermint/tendermint/blob/master/crypto/secp256k1). As a result, it only works for creating account keys and addresses, not consensus keys. See [`Addresses`](#addresses) for more. +- `CreateAccount(name, mnemonic, bip39Passwd, encryptPasswd string, account uint32, index uint32) (Info, error)` creates a new account based on the [`bip44 path`](https://github.com/bitcoin/bips/blob/master/bip-0044.mediawiki) and persists it on disk (note that the `PrivKey` is [encrypted with a passphrase before being persisted](https://github.com/cosmos/cosmos-sdk/blob/master/crypto/keys/mintkey/mintkey.go), it is **never stored unencrypted**). In the context of this method, the `account` and `address` parameters refer to the segment of the BIP44 derivation path (e.g. `0`, `1`, `2`, ...) used to derive the `PrivKey` and `PubKey` from the mnemonic (note that given the same mnemonic and `account`, the same `PrivKey` will be generated, and given the same `account` and `address`, the same `PubKey` and `Address` will be generated). Finally, note that the `CreateAccount` method derives keys and addresses using `secp256k1` as implemented in the [Tendermint library](https://github.com/tendermint/tendermint/blob/master/crypto/secp256k1). As a result, it only works for creating account keys and addresses, not consensus keys. See [`Addresses`](#addresses) for more. -The current implementation of `dbKeybase` is basic and does not offer on-demand locking. If an instance of `dbKeybase` is created, the underlying `db` is locked meaning no other process can access it besides the one in which it was instantiated. This is the reason why the default SDK client uses another implementation of the `Keybase` interface called [`lazyKeybase`](https://github.com/cosmos/cosmos-sdk/blob/master/crypto/keys/lazy_keybase.go). `lazyKeybase` is simple wrapper around `dbKeybase` which locks the database only when operations are to be performed and unlocks it immediately after: +The current implementation of `dbKeybase` is basic and does not offer on-demand locking. If an instance of `dbKeybase` is created, the underlying `db` is locked meaning no other process can access it besides the one in which it was instantiated. This is the reason why the [default SDK client](https://github.com/cosmos/cosmos-sdk/tree/master/client/keys) uses another implementation of the `Keybase` interface called [`lazyKeybase`](https://github.com/cosmos/cosmos-sdk/blob/master/crypto/keys/lazy_keybase.go). `lazyKeybase` is simple wrapper around `dbKeybase` which locks the database only when operations are to be performed and unlocks it immediately after: ```go // Example Get method of lazyKeybase @@ -144,11 +144,13 @@ func (lkb lazyKeybase) Get(name string) (Info, error) { With the `lazyKeybase`, it is possible for the [command-line interface](../interfaces/cli.md) to create a new account while the [rest server](../interfaces/rest.md) is running. It is also possible to pipe multiple CLI commands. -The `lazyKeybase` is typically used from - -### Addresses +### Addresses and PubKeys +`Addresses` and `PubKey`s are both public information that identify actors in the application. There are 3 main types of `Addresses`/`PubKeys` available by default in the Cosmos SDK: +- Addresses and Keys for **accounts**, which identify users (e.g. the sender of a `message`). They are derived using the **`secp256k1`** curve. +- Addresses and Keys for **validator operators**, which identify the operators of validators. They are derived using the **`secp256k1`** curve. +- Addresses and Keys for **consensus nodes**, which identify the validator nodes participating in consensus. They are derived using the **`ed25519`** curve. ### Signatures From 01e79c8412afc42ce964d1b4688921ce30086897 Mon Sep 17 00:00:00 2001 From: Federico Kunze <31522760+fedekunze@users.noreply.github.com> Date: Tue, 1 Oct 2019 18:25:41 +0200 Subject: [PATCH 120/196] Apply suggestions from code review --- docs/building-modules/handler.md | 6 +++--- docs/building-modules/querier.md | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/docs/building-modules/handler.md b/docs/building-modules/handler.md index 17d46d87d7ea..6569681b293a 100644 --- a/docs/building-modules/handler.md +++ b/docs/building-modules/handler.md @@ -7,7 +7,7 @@ ## Synopsis -A `Handler` designates a function that processes [`message`s](./messages-and-queries.md#messages). `handler`s are specific to the module in which they are defined, and only process `message`s defined within said module. They are called from `baseapp` during [`DeliverTx`](../core/baseapp.md#delivertx). +A `Handler` designates a function that processes [`message`s](./messages-and-queries.md#messages). `Handler`s are specific to the module in which they are defined, and only process `message`s defined within the said module. They are called from `baseapp` during [`DeliverTx`](../core/baseapp.md#delivertx). - [`handler` type](#handler-type) - [Implementation of a module `handler`s](#implementation-of-a-module-handlers) @@ -22,7 +22,7 @@ type Handler func(ctx Context, msg Msg) Result Let us break it down: -- The [`msg`](./messages-and-queries.md#messages) is the actual object being processed. +- The [`Msg`](./messages-and-queries.md#messages) is the actual object being processed. - The [`Context`](../core/context.md) contains all the necessary information needed to process the `msg`, as well as a cache-wrapped copy of the latest state. If the `msg` is succesfully processed, the modified version of the temporary state contained in the `ctx` will be written to the main state. - The [`Result`](https://github.com/cosmos/cosmos-sdk/blob/master/types/result.go#L14-L38) returned to `baseapp`, which contains (among other things) information on the execution of the `handler`, [`gas`](../basics/accounts-fees-gas.md#gas) consumption and [`events`](./events.md). @@ -70,4 +70,4 @@ For a deeper look at `handler`s, see this [example implementation of a `handler` ## Next -Learn about [queriers](./querier.md). \ No newline at end of file +Learn about [queriers](./querier.md). diff --git a/docs/building-modules/querier.md b/docs/building-modules/querier.md index 7882a92aaead..15e03b1a2666 100644 --- a/docs/building-modules/querier.md +++ b/docs/building-modules/querier.md @@ -12,7 +12,7 @@ A `Querier` designates a function that processes [`queries`](./messages-and-quer - [`querier` type](#querier-type) - [Implementation of a module `queriers`](#implementation-of-a-module-queriers) -## `querier` type +## `Querier` type The [`querier` type](https://github.com/cosmos/cosmos-sdk/blob/master/types/queryable.go#L6) defined in the Cosmos SDK specifies the typical structure of a `querier` function: From c151b31a2bbcfca01473013550c25ea00039f884 Mon Sep 17 00:00:00 2001 From: gamarin Date: Fri, 4 Oct 2019 17:03:51 +0200 Subject: [PATCH 121/196] encoding and node --- docs/basics/accounts-fees-gas.md | 147 +++++++++++++++++-- docs/basics/app-anatomy.md | 2 +- docs/building-modules/beginblock-endblock.md | 2 +- docs/core/baseapp.md | 4 +- docs/core/encoding.md | 65 +++++++- docs/core/genesis.md | 3 - docs/core/node.md | 73 ++++++++- docs/core/store.md | 6 +- docs/modules/SPEC.md | 81 ---------- 9 files changed, 278 insertions(+), 105 deletions(-) delete mode 100644 docs/core/genesis.md delete mode 100644 docs/modules/SPEC.md diff --git a/docs/basics/accounts-fees-gas.md b/docs/basics/accounts-fees-gas.md index edf3f8546407..5418b1666f85 100644 --- a/docs/basics/accounts-fees-gas.md +++ b/docs/basics/accounts-fees-gas.md @@ -10,13 +10,14 @@ This document describes the in-built accounts system of the Cosmos SDK, as well - [Accounts](#accounts) + [KeyBase](#keybase) - + [Addresses](#addresses) - + [Signatures](#signatures) + + [Addresses and Pubkeys](#addresses-and-pubkeys) + * [Pubkeys](#pubkeys) + * [Addresses](#addresses) - [Fees and Gas](#fees-and-gas) - + [AnteHandler](#antehandler) - + [Gas](#gas) + [Gas Meter](#gas-meter) - + [Block Gas Meter](#block-gas-meter) + * [Main Gas Meter](#main-gas-meter) + * [Block Gas Meter](#block-gas-meter) + + [AnteHandler](#antehandler) ## Accounts @@ -122,7 +123,7 @@ type Keybase interface { The default implementation of `Keybase` of the Cosmos SDK is [`dbKeybase`](https://github.com/cosmos/cosmos-sdk/blob/master/crypto/keys/keybase.go). A few notes on the `Keybase` methods as implemented in `dbKeybase`: -- `Sign(name, passphrase string, msg []byte) ([]byte, crypto.PubKey, error)` strictly deals with the signature of the `message` bytes. Some preliminary work should be done beforehand to prepare and encode the `message` into a canonical `[]byte` form. See an example of `message` preparation from the `auth` module](https://github.com/cosmos/cosmos-sdk/blob/master/x/auth/types/txbuilder.go#L177-L207). +- `Sign(name, passphrase string, msg []byte) ([]byte, crypto.PubKey, error)` strictly deals with the signature of the `message` bytes. Some preliminary work should be done beforehand to prepare and encode the `message` into a canonical `[]byte` form. See an example of `message` preparation from the `auth` module](https://github.com/cosmos/cosmos-sdk/blob/master/x/auth/types/txbuilder.go#L177-L207). Note that signature verification is not implemented in the SDK by default. It is deferred to the [`anteHandler`](#antehandler). - `CreateMnemonic(name string, language Language, passwd string, algo SigningAlgo) (info Info, seed string, err error)` creates a new mnemonic and prints it in the logs, but it **does not persist it on disk**. - `CreateAccount(name, mnemonic, bip39Passwd, encryptPasswd string, account uint32, index uint32) (Info, error)` creates a new account based on the [`bip44 path`](https://github.com/bitcoin/bips/blob/master/bip-0044.mediawiki) and persists it on disk (note that the `PrivKey` is [encrypted with a passphrase before being persisted](https://github.com/cosmos/cosmos-sdk/blob/master/crypto/keys/mintkey/mintkey.go), it is **never stored unencrypted**). In the context of this method, the `account` and `address` parameters refer to the segment of the BIP44 derivation path (e.g. `0`, `1`, `2`, ...) used to derive the `PrivKey` and `PubKey` from the mnemonic (note that given the same mnemonic and `account`, the same `PrivKey` will be generated, and given the same `account` and `address`, the same `PubKey` and `Address` will be generated). Finally, note that the `CreateAccount` method derives keys and addresses using `secp256k1` as implemented in the [Tendermint library](https://github.com/tendermint/tendermint/blob/master/crypto/secp256k1). As a result, it only works for creating account keys and addresses, not consensus keys. See [`Addresses`](#addresses) for more. @@ -150,16 +151,140 @@ With the `lazyKeybase`, it is possible for the [command-line interface](../inter - Addresses and Keys for **accounts**, which identify users (e.g. the sender of a `message`). They are derived using the **`secp256k1`** curve. - Addresses and Keys for **validator operators**, which identify the operators of validators. They are derived using the **`secp256k1`** curve. -- Addresses and Keys for **consensus nodes**, which identify the validator nodes participating in consensus. They are derived using the **`ed25519`** curve. +- Addresses and Keys for **consensus nodes**, which identify the validator nodes participating in consensus. They are derived using the **`ed25519`** curve. + +| | Address bech32 Prefix | Pubkey bech32 Prefix | Curve | Address byte length | Pubkey byte length | +|--------------------|-----------------------|----------------------|-------------|---------------------|--------------------| +| Accounts | cosmos | cosmospub | `secp256k1` | `20` | `33` | +| Validator Operator | cosmosvaloper | cosmosvaloperpub | `secp256k1` | `20` | `33` | +| Consensus Nodes | cosmosvalcons | cosmosvalconspub | `ed25519` | `20` | `32` | + +#### PubKeys + +`PubKey`s used in the Cosmos SDK follow the [`Pubkey` interface defined in [tendermint's `crypto` package](https://github.com/tendermint/tendermint/blob/master/crypto/crypto.go#L22-L27): + + +```go +type PubKey interface { + Address() Address + Bytes() []byte + VerifyBytes(msg []byte, sig []byte) bool + Equals(PubKey) bool +} +``` + +For `secp256k1` keys, the actual implementation can be found [here](https://github.com/tendermint/tendermint/blob/master/crypto/secp256k1/secp256k1.go#L140). For `ed25519` keys, it can be found [here](https://github.com/tendermint/tendermint/blob/master/crypto/ed25519/ed25519.go#L135). + +Note that in the Cosmos SDK, `Pubkeys` are not manipulated in their raw form. Instead, they are double encoded using [`Amino`](../core/encoding.md#amino) and [`bech32`](https://en.bitcoin.it/wiki/Bech32). In the SDK is done by first calling the `Bytes()` method on the raw `Pubkey` (which applies amino encoding), and then the `ConvertAndEncode` method of `bech32`. You can check out the implementation [here](https://github.com/cosmos/cosmos-sdk/blob/master/types/address.go#L579-L729). + +#### Addresses + +The Cosmos SDK comes by default with 3 types of addresses: -### Signatures +- `AccAddress` for accounts. +- `ValAddress` for validator operators. +- `ConsAddress` for validator nodes. + +Each of these address types are an alias for an hex-encoded `[]byte` array of length 20. Here is the standard way to obtain an address `aa` from a `Pubkey pub`: + +```go +aa := sdk.AccAddress(pub.Address().Bytes()) +``` + +These addresses implement the [`Address` interface](https://github.com/cosmos/cosmos-sdk/blob/master/types/address.go#L72-L80): + +```go +type Address interface { + Equals(Address) bool + Empty() bool + Marshal() ([]byte, error) + MarshalJSON() ([]byte, error) + Bytes() []byte + String() string + Format(s fmt.State, verb rune) +} +``` + +Of note, the `Marhsal()` and `Bytes()` method both return the same raw `[]byte` form of the address, the former being needed for Protobuff compatibility. Also, the `String()` method is used to return the `bech32` encoded form of the address, which should be the only address format with which end-user interract. See an example [here](https://github.com/cosmos/cosmos-sdk/blob/master/types/address.go#L230-L243). ## Fees and Gas -### AnteHandler +In the Cosmos SDK, `gas` is a special unit that is used to track the consumption of resources during execution. `gas` is typically consumed whenever read and writes are made to the store, but it can also be consumed if expensive computation needs to be done. It serves two main purposes: -### Gas +- Make sure blocks are not consuming too many resources and will be finalized. This is implemented by default in the SDK via the [block gas meter](#block-gas-meter). +- Prevent spam and abuse from end-user. To this end, `gas` consumed during [`message`](../building-modules/messages-and-queries.md#messages) execution is typically priced, resulting in a `fee` (`fees = gas * gas-prices`). This fee generally has to be paid by the sender of the `message`. Note that the SDK does not enforce `gas` pricing by default, as there may be other ways to prevent spam (e.g. bandwidth schemes). Still, most applications will implement `fee` mechanisms to prevent spam. This is done via the [`AnteHandler`](#antehandler). ### Gas Meter -### Block Gas Meter \ No newline at end of file +In the Cosmos SDK, `gas` is a simple alias for `uint64`, and is managed by an object called a *gas meter*. Gas meters implement the [`GasMeter` interface](https://github.com/cosmos/cosmos-sdk/blob/master/store/types/gas.go#L32-L44): + +```go +type GasMeter interface { + GasConsumed() Gas + GasConsumedToLimit() Gas + Limit() Gas + ConsumeGas(amount Gas, descriptor string) + IsPastLimit() bool + IsOutOfGas() bool +} +``` + +where: + +- `GasConsumed()` returns the amount of gas that was consumed by the gas meter instance. +- `GasConsumedToLimit()` returns the amount of gas that was consumed by gas meter instance, or the limit if it is reached. +- `Limit()` returns the limit of the gas meter instance. `0` if the gas meter is infinite. +- `ConsumeGas(amount Gas, descriptor string)` consumes the amount of `gas` provided. If the `gas` overflows, it panics with the `descriptor` message. If the gas meter is not infinite, it panics if `gas` consumed goes above the limit. +- `IsPastLimit()` returns `true` if the amount of gas consumed by the gas meter instance is strictly above the limit, `false` otherwise. +- `IsOutOfGas()` returns `true` if the amount of gas consumed by the gas meter instance is above or equal to the limit, `false` otherwise. + +The gas meter is generally held in [`ctx`](../core/context.md), and consuming gas is done with the following pattern: + +```go +ctx.GasMeter().ConsumeGas(amount, "description") +``` + +By default, the Cosmos SDK makes use of two different gas meters, the [main gas meter](#main-gas-metter[) and the [block gas meter](#block-gas-meter). + +#### Main Gas Meter + +`ctx.GasMeter()` is the main gas meter of the application. The main gas meter is initialized in `BeginBlock` via `setDeliverState`, and then tracks gas consumption during execution sequences that lead to state-transitions, i.e. those originally triggered by [`BeginBlock`](../core/baseapp.md#beginblock), [`DeliverTx`](../core/baseapp.md#delivertx) and [`EndBlock`](../core/baseapp.md#endblock). At the beginning of each `DeliverTx`, the main gas meter **must be set to 0** in the [`AnteHandler`](#antehandler), so that it can track gas comsumption per-transaction. + +Gas comsumption can be done manually, generally by the module developer in the [`BeginBlocker`, `EndBlocker`](../building-modules/beginblock-endblock.md) or [`handler`](../building-modules/handler.md), but most of the time it is done automatically whenever there is a read or write to the store. This automatic gas consumption logic is implemented in a special store called [`GasKv`](../core/store.md#gaskv-store). + +#### Block Gas Meter + +`ctx.BlockGasMeter()` is the gas meter used to track gas consumption per block and make sure it does not go above a certain limit. A new instance of the `BlockGasMeter` is created each time [`BeginBlock`](../core/baseapp.go#beginblock) is called. The `BlockGasMeter` is finite, and the limit of gas per block is defined in the application's consensus parameters. + +When a new [transaction](../core/transaction.md) is being processed via `DeliverTx`, the current value of `BlockGasMeter` is checked to see if it is above the limit. If it is, `DeliverTx` returns immediately. This can happen even with the first transaction in a block, as `BeginBlock` itself can consume gas. If not, the transaction is processed normally. At the end of `DeliverTx`, the gas tracked by `ctx.BlockGasMeter()` is increased by the amount consumed to process the transaction: + +```go +ctx.BlockGasMeter().ConsumeGas( + ctx.GasMeter().GasConsumedToLimit(), + "block gas meter", + ) +``` + +### AnteHandler + +The `AnteHandler` is a special `handler` that is run for every transaction during `CheckTx` and `DeliverTx`, before the `handler` of each `message` in the transaction. `AnteHandler` have a different signature than `handler`s: + +```go +// AnteHandler authenticates transactions, before their internal messages are handled. +// If newCtx.IsZero(), ctx is used instead. +type AnteHandler func(ctx Context, tx Tx, simulate bool) (newCtx Context, result Result, abort bool) +``` + +Being a `handler`, the `anteHandler` is not implemented in the core SDK but in a module. This gives the possibility to developers to choose the version of `AnteHandler` that fits their application's needs. That said, most applications today use the default implementation defined in the [`auth` module](https://github.com/cosmos/cosmos-sdk/tree/master/x/auth). Here is what the `anteHandler` is intended to do in a normal Cosmos SDK application: + +- Verify that the transaction are of the correct type. Transaction types are defined in the module that implements the `anteHandler`, and they follow the [transaction interface](https://github.com/cosmos/cosmos-sdk/blob/master/types/tx_msg.go#L34-L41). This enables developers to play with various types for the transaction of their application. In the default `auth` module, the standard transaction type is [`StdTx`](https://github.com/cosmos/cosmos-sdk/blob/master/x/auth/types/stdtx.go#L23-L28). +- Verify signatures for each [`message`](../building-modules/messages-and-queries.md#messages) contained in the transaction. Each `message` should be signed by one or multiple sender(s), and these signatures must be verified in the `anteHandler`. +- During `CheckTx`, verify that the gas prices provided with the transaction is greater than the local `min-gas-prices` (as a reminder, gas-prices can be deducted from the following equation: `fees = gas * gas-prices`). `min-gas-prices` is a parameter local to each full-node and used during `CheckTx` to discard transactions that do not provide a minimum amount of fees. This ensure that the mempool cannot be spammed with garbage transactions. +- Verify that the sender of the transaction has enough funds to cover for the `fees`. When the end-user generates a transaction, they must indicate 2 of the 3 following parameters (the third one being implicit): `fees`, `gas` and `gas-prices`. This signals how much they are willing to pay for nodes to execute their transaction. The provided `gas` value is stored in a parameter called `GasWanted` for later use. +- Set `newCtx.GasMeter` to 0, with a limit of `GasWanted`. **This step is extremely important**, as it not only makes sure the transaction cannot consume infinite gas, but also that `ctx.GasMeter` is reset in-between each `DeliverTx` (`ctx` is set to `newCtx` after `anteHandler` is run). + +As explained above, the `anteHandler` returns a maximum limit of `gas` the transaction can consume during execution called `GasWanted`. The actual amount consumed in the end is denominated `GasUsed`, and we must therefore have `GasUsed =< GasWanted`. Both `GasWanted` and `GasUsed` are relayed to the underlying consensus engine when [`DeliverTx`](../core/baseapp.md#delivertx) returns. + +## Next + +Learn about [baseapp](../core/baseapp.md). \ No newline at end of file diff --git a/docs/basics/app-anatomy.md b/docs/basics/app-anatomy.md index 85b532f8d871..881c1b70d493 100644 --- a/docs/basics/app-anatomy.md +++ b/docs/basics/app-anatomy.md @@ -73,7 +73,7 @@ In general, the core of the state-machine is defined in a file called `app.go`. The first thing defined in `app.go` is the `type` of the application. It is generally comprised of the following parts: -- **A reference to [`baseapp`](../core/baseapp.md).** The custom application defined in `app.go` is an extension of the `baseapp` type. `baseapp` implements most of the core logic for the application, including all the [ABCI methods](https://tendermint.com/docs/spec/abci/abci.html#overview) and the routing logic. When a transaction is relayed by Tendermint to the application, the latter uses `baseapp`'s methods to route them to the appropriate module. +- **A reference to [`baseapp`](../core/baseapp.md).** The custom application defined in `app.go` is an extension of the `baseapp` type. When a transaction is relayed by Tendermint to the application, the latter uses `baseapp`'s methods to route them to the appropriate module. `baseapp` implements most of the core logic for the application, including all the [ABCI methods](https://tendermint.com/docs/spec/abci/abci.html#overview) and the routing logic. Since `baseapp` implements these ABCI methods and `app` extends `baseapp`, it means that `app` satisfies the [`abci.Application` interface](https://github.com/tendermint/tendermint/blob/master/abci/types/application.go#L11-L26), which is a must for the [full-node](../core/node.md) to work. - **A list of store keys**. The [store](../core/store.md), which contains the entire state, is implemented as a multistore (i.e. a store of stores) in the Cosmos SDK. Each module uses one or multiple stores in the multistore to persist their part of the state. These stores can be accessed with specific keys that are declared in the `app` type. These keys, along with the `keepers`, are at the heart of the [object-capabilities model](../intro/ocap.md) of the Cosmos SDK. - **A list of module's `keepers`.** Each module defines an abstraction called [`keeper`](../building-modules/keeper.md), which handles reads and writes for this module's store(s). The `keeper`'s methods of one module can be called from other modules (if authorized), which is why they are declared in the application's type and exported as interfaces to other modules so that they are only allowed to access the authorized functions. - **A reference to a [`codec`](../core/encoding.md).** The Cosmos SDK gives developers the freedom to choose the encoding framework for their application. The application's `codec` is used to serialize and deserialize data structures in order to store them, as stores can only persist `[]bytes`. The `codec` must be deterministic. The default codec is [amino](./amino.md). diff --git a/docs/building-modules/beginblock-endblock.md b/docs/building-modules/beginblock-endblock.md index 322d3f27e344..66d08e2858f5 100644 --- a/docs/building-modules/beginblock-endblock.md +++ b/docs/building-modules/beginblock-endblock.md @@ -20,7 +20,7 @@ The actual implementation of `BeginBlocker` and `EndBlocker` are very similar to - If needed, they use the `keeper` and `ctx` to trigger state-transitions. - If needed, they can emit [`events`](../core/events.md) via the `ctx`'s `EventManager`. -A specificity of the `EndBlocker` is that it can return validator updates to the underlying consensus engine in the form of an [`[]abci.ValidatorUpdates`](https://tendermint.com/docs/app-dev/abci-spec.html#validatorupdate). +A specificity of the `EndBlocker` is that it can return validator updates to the underlying consensus engine in the form of an [`[]abci.ValidatorUpdates`](https://tendermint.com/docs/app-dev/abci-spec.html#validatorupdate). This is the preferred way to implement custom validator changes. For more, see an [example implementation of `BeginBlocker` from the `distr` module](https://github.com/cosmos/cosmos-sdk/blob/master/x/distribution/abci.go) and an [example implementation of `EndBlocker`]( https://github.com/cosmos/cosmos-sdk/blob/master/x/staking/handler.go#L44) diff --git a/docs/core/baseapp.md b/docs/core/baseapp.md index 4655d817a9d4..330a41ed512b 100644 --- a/docs/core/baseapp.md +++ b/docs/core/baseapp.md @@ -14,7 +14,7 @@ This document describes `baseapp`, the abstraction that implements most of the c - [Constructor](#constructor) - [States](#states) - [Routing](#routing) -- [Main ABCI Messages](#abci) +- [Main ABCI Messages](#main-abci-messages) + [CheckTx](#checktx) + [DeliverTx](#delivertx) - [RunTx, AnteHandler and RunMsgs](#runtx-antehandler-and-runmsgs) @@ -293,7 +293,7 @@ Finally, the `InitChain(req abci.RequestInitChain)` method of `baseapp` calls th The [`BeginBlock` ABCI message](#https://tendermint.com/docs/app-dev/abci-spec.html#beginblock) is sent from the underlying Tendermint engine when a block proposal created by the correct proposer is received, before [`DeliverTx`](#delivertx) is run for each transaction in the block. It allows developers to have logic be executed at the beginning of each block. In the Cosmos SDK, the `BeginBlock(req abci.RequestBeginBlock)` method does the following: -- Initialize [`deliverState`](#volatile-states) with the latest header using the `req abci.RequestBeginBlock` passed as parameter via the [`setDeliverState`](https://github.com/cosmos/cosmos-sdk/blob/master/baseapp/baseapp.go#L283-L289) function. +- Initialize [`deliverState`](#volatile-states) with the latest header using the `req abci.RequestBeginBlock` passed as parameter via the [`setDeliverState`](https://github.com/cosmos/cosmos-sdk/blob/master/baseapp/baseapp.go#L283-L289) function. This function also resets the [main gas meter](../basics/accounts-fees-gas.md#main-gas-meter). - Initialize the [block gas meter](../basics/accounts-fees-gas.md#block-gas-meter) with the `maxGas` limit. The `gas` consumed within the block cannot go above `maxGas`. This parameter is defined in the application's consensus parameters. - Run the application's [`beginBlocker()`](../basics/app-anatomy.md#beginblocker-and-endblock), which mainly runs the [`BeginBlocker()`](../building-modules/beginblock-endblock.md#beginblock) method of each of the application's modules. - Set the [`VoteInfos`](https://tendermint.com/docs/app-dev/abci-spec.html#voteinfo) of the application, i.e. the list of validators whose *precommit* for the previous block was included by the proposer of the current block. This information is carried into the [`Context`](./context.md) so that it can be used during `DeliverTx` and `EndBlock`. diff --git a/docs/core/encoding.md b/docs/core/encoding.md index 1dcfba3b2313..2e568e0b89a7 100644 --- a/docs/core/encoding.md +++ b/docs/core/encoding.md @@ -1,3 +1,66 @@ # Encoding -TODO \ No newline at end of file +## Pre-requisite Reading + +- [Anatomy of an SDK application](../basics/app-anatomy.md) + +## Synopsis + +The `codec` is used everywhere in the Cosmos SDK to encode and decode structs and interfaces. The specific codec used in the Cosmos SDK is called `go-amino`. + +## Encoding + +Every Cosmos SDK application exposes a global `codec` to marshal/unmarshal structs and interfaces in order to store and/or transfer them. As of now, the `codec` used in the Cosmos SDK is [go-amino](https://github.com/tendermint/go-amino), which possesses the following important properties: + +- Interface support. +- Deterministic encoding of value (which is required considering that blockchains are deterministic replicated state-machines). +- Upgradeable schemas. + +The application's `codec` is typically initialized in the [application's constructor function](../basics/app-anatomy.md#constructor-function), where it is also passed to each of the application's modules via the [basic manager](../building-modules/module-manager.md#basic-manager). + +Among other things, the `codec` is used by module's [`keeper`s](../building-modules/keeper.md) to marshal objects into `[]byte` before storing them in the module's [`KVStore`](./store.md#kvstore), or to unmarshal them from `[]byte` when retrieving them: + +```go +// typical pattern to marshal an object to []byte before storing it +bz := keeper.cdc.MustMarshalBinaryBare(object) + +//typical pattern to unmarshal an object from []byte when retrieving it +keeper.cdc.MustUnmarshalBinaryBare(bz, &object) +``` + +Alternatively, it is possible to use `MustMarshalBinaryLengthPrefixed`/`MustUnmarshalBinaryLengthPrefixed` instead of `MustMarshalBinaryBare`/`MustUnmarshalBinaryBare` for the same encoding prefixed by a uvarint encoding of the object to encode. + +Another important use of the `codec` is the encoding and decoding of [transactions](./transactions.md). Transactions are defined at the Cosmos SDK level, but passed to the underlying consensus engine in order to be relayed to other peers. Since the underlying consensus engine is agnostic to the application, it only accepts transactions in the form of `[]byte`. The encoding is done by an object called [`TxEncoder`](https://github.com/cosmos/cosmos-sdk/blob/master/types/tx_msg.go#L48-L49) and the decoding by an object called [`TxDecoder`](https://github.com/cosmos/cosmos-sdk/blob/master/types/tx_msg.go#L45-L47). A [standard implementation](https://github.com/cosmos/cosmos-sdk/blob/master/x/auth/types/stdtx.go) of both these objects can be found in the `auth` module: + +```go +// DefaultTxDecoder logic for standard transaction decoding +func DefaultTxDecoder(cdc *codec.Codec) sdk.TxDecoder { + return func(txBytes []byte) (sdk.Tx, sdk.Error) { + var tx = StdTx{} + + if len(txBytes) == 0 { + return nil, sdk.ErrTxDecode("txBytes are empty") + } + + // StdTx.Msg is an interface. The concrete types + // are registered by MakeTxCodec + err := cdc.UnmarshalBinaryLengthPrefixed(txBytes, &tx) + if err != nil { + return nil, sdk.ErrTxDecode("error decoding transaction").TraceSDK(err.Error()) + } + + return tx, nil + } +} + +// DefaultTxEncoder logic for standard transaction encoding +func DefaultTxEncoder(cdc *codec.Codec) sdk.TxEncoder { + return func(tx sdk.Tx) ([]byte, error) { + return cdc.MarshalBinaryLengthPrefixed(tx) + } +} +``` + +## Next + +Learn about next concept \ No newline at end of file diff --git a/docs/core/genesis.md b/docs/core/genesis.md deleted file mode 100644 index 5e3dbd31dcad..000000000000 --- a/docs/core/genesis.md +++ /dev/null @@ -1,3 +0,0 @@ -# Genesis File - -TODO \ No newline at end of file diff --git a/docs/core/node.md b/docs/core/node.md index 85c6152542ad..33f3e508ca0e 100644 --- a/docs/core/node.md +++ b/docs/core/node.md @@ -1,13 +1,78 @@ # Node Client (Daemon) -## Pre-Requisite Reading +## Pre-requisite Reading + +- [Anatomy of an SDK application](../basics/app-anatomy.md) + +## Synopsis + +The main endpoint of an SDK application is the daemon client, otherwise known as the full-node client. The full-node runs the state-machine, starting from a genesis file. It connects to peers running the same client in order to receive and relay transactions, block proposals and signatures. The full-node is constituted of the application, defined with the Cosmos SDK, and of a consensus engine connected to the application via the ABCI. + +- [`main` function](#main-function) +- [`start` command](#start-command) ## `main` function -TODO +The full-node client of any SDK application is built by running a `main` function. The client is generally named by appending the `-d` suffix to the application name (e.g. `appd` for an application named `app`), and the `main` function is defined in a `cmd/appd/main.go` file. Running this function creates an executable `.appd` that comes with a set of commands. For an app named `app`, the main command is [`appd start`](#start-command), which starts the full-node. + +In general, developers will implement the `main.go` function with the following structure: + +- First, a [`codec`](./encoding.md) is instanciated for the application. +- Then, the [`config`](https://github.com/cosmos/cosmos-sdk/blob/master/types/config.go) is retrieved and config parameters are set. This mainly involves setting the bech32 prefixes for [addresses and pubkeys](../basics/accounts-fees-gas.md#addresses-and-pubkeys). +- Using [cobra](https://github.com/spf13/cobra), the root command of the full-node client is created. After that, all the custom commands of the application are added using the `AddCommand()` method of `rootCmd`. +- Add default server commands to `rootCmd` using the `server.AddCommands(ctx, cdc, rootCmd, newApp, exportAppStateAndTMValidators)` method. These commands are separated from the ones added above since they are standard and defined at SDK level. They should be shared by all SDK-based application. They include the most important command: the [`start` command](#start-command). +- Prepare and execute the [`executor`](https://github.com/tendermint/tendermint/blob/master/libs/cli/setup.go#L75-L78). + +See an [example of `main` function](https://github.com/cosmos/gaia/blob/master/cmd/gaiad/main.go) from the `gaia` application. ## `start` command -TODO +The `start` command is defined in the `/server` folder of the Cosmos SDK. It is added to the root command of the full-node client in the [`main` function](#main-function) and called by the end-user to start their node: + +```go +// For an example app named "app", the following command starts the full-node + +appd start +``` + +As a reminder, the full-node is composed of three conceptual layers: the networking layer, the consensus layer and the application layer. The first two are generally bundled together in an entity called the consensus engine, while the third is the state-machine defined with the help of the Cosmos SDK. Currently, the Cosmos SDK uses Tendermint as the default consensus engine, meaning the start command is implemented to boot up a Tendermint node. + +The flow of the `start` command is pretty straightforward. First, it retrieves the `config` from the `context` in order to open the `db`. This `db` contains the latest known state of the application (empty if the application is started from the first time). + +With the `db`, the `start` command creates a new instance of the application using the [application's constructor function](../basics/app-anatomy.md#constructor-function). + +```go +app := appCreator(ctx.Logger, db, traceWriter) +``` + +In the background, the `db` is used by the `appCreator` to mount the main [`CommitMultiStore`](./store.md#commitmultistore) of the application. Then, the instance of `app` is used to instanciate a new Tendermint node: + + +```go +tmNode, err := node.NewNode( + cfg, + pvm.LoadOrGenFilePV(cfg.PrivValidatorKeyFile(), cfg.PrivValidatorStateFile()), + nodeKey, + proxy.NewLocalClientCreator(app), + node.DefaultGenesisDocProviderFunc(cfg), + node.DefaultDBProvider, + node.DefaultMetricsProvider(cfg.Instrumentation), + ctx.Logger.With("module", "node"), + ) +``` + +The Tendermint node can be created with `app` because the latter satisfies the [`abci.Application` interface](https://github.com/tendermint/tendermint/blob/master/abci/types/application.go#L11-L26) (given that `app` extends [`baseapp`](./baseapp.md)). As part of the `NewNode` method, Tendermint makes sure that the height of the application (i.e. number of blocks since genesis) is equal to the height of the Tendermint node. The difference between these two heights should always be negative or null. If it is strictly negative, `NewNode` will replay blocks until the height of the application reaches the height of the Tendermint node. Finally, if the height of the application is `0`, the Tendermint node will call [`InitChain`](./baseapp.md#initchain) on the application to initialize the state. + +Once the Tendermint node is instanciated and in sync with the application, the node can be started: + +```go +if err := tmNode.Start(); err != nil { + return nil, err + } +``` + +Upon starting, the node will bootstrap its RPC and P2P server and start dialing peers. During handshake with its peers, if the node realizes they are ahead, it will query all the blocks sequentially in order to catch up. Then, it will wait for new block proposals and block signatures from validators in order to make progress. + +## Next -## Light-Client Daemon (LCD) +Read more about the next core concept. \ No newline at end of file diff --git a/docs/core/store.md b/docs/core/store.md index 067eea3b79bd..000013cff2f2 100644 --- a/docs/core/store.md +++ b/docs/core/store.md @@ -1,6 +1,10 @@ # Store -## Commit Multi Store +## `CommitMultiStore` + +## GasKv Store + +## KVStore ## Database diff --git a/docs/modules/SPEC.md b/docs/modules/SPEC.md deleted file mode 100644 index 8b0f62c0e825..000000000000 --- a/docs/modules/SPEC.md +++ /dev/null @@ -1,81 +0,0 @@ -# Module Specification - -This document outlines the recommended structure of Cosmos SDK modules. These -ideas are meant to be applied as suggestions. Application developers are encouraged -to improve upon and contribute to module structure and development design. - -## Structure - -A typical Cosmos SDK module can be structured as follows: - -```shell -x/{module} -├── client -│   ├── cli -│   │ ├── query.go -│   │   └── tx.go -│   └── rest -│   ├── query.go -│   └── tx.go -├── exported -│   └── exported.go -├── internal -│   ├── keeper -│   │   ├── invariants.go -│   │   ├── keeper.go -│   │   ├── ... -│   │   └── querier.go -│   └── types -│   ├── codec.go -│   ├── errors.go -│   ├── events.go -│   ├── expected_keepers.go -│   ├── genesis.go -│   ├── keys.go -│   ├── msgs.go -│   ├── params.go -│   ├── ... -│   └── querier.go -├── abci.go -├── alias.go -├── genesis.go -├── handler.go -├── module.go -├── ... -└── simulation.go -``` - -- `abci.go`: The module's `BeginBlocker` and `EndBlocker` implementations (if any). -- `alias.go`: The module's exported types, constants, and variables. These are mainly -to improve developer ergonomics by only needing to import a single package. Note, -there is nothing preventing developers from importing other packages from the module -(excluding`internal/`) but it is recommended that `alias.go` have everything -exposed that other modules may need. The majority of the exported values here will -typically come from `internal/` (see below). -- `client/`: The module's CLI and REST client functionality implementation and -testing. -- `exported/`: The module's exported types -- typically type interfaces. If a module -relies on other module keepers, it is expected to receive them as interface -contracts through the `expected_keepers.go` (which are detailed below) design to -avoid having a direct dependency on the implementing module. However, these -contracts can define methods that operate on and/or return types that are specific -to the contract's implementing module and this is where `exported/` comes into play. -Types defined here allow for `expected_keepers.go` in other modules to define -contracts that use single canonical types. This pattern allows for code to remain -DRY and also alleviates import cycle chaos. -- `genesis.go`: The module's genesis related business logic (e.g. `InitGenesis`). -Note, genesis types are defined in `internal/types`. -- `handler.go`: The module's message handlers. -- `internal/`: The module's internal types and implementations. The purpose of -this package is mainly two fold. First, it signals that this package is not -intended to be used or imported anywhere outside the defining module. Secondly, -it goes hand-in-hand with `alias.go` in that it allows public types and functions -to be used internally while not being exposed outside to the outside world. This -allows for greater freedom of development while maintaining API stability. - - `internal/types`: The module's type definitions such as messages, `KVStore` - keys, parameter types, and `expected_keepers.go` contracts. - - `internal/keeper`: The module's keeper implementation along with any auxiliary - implementations such as the querier and invariants. -- `module.go`: The module's implementation of the `AppModule` and `AppModuleBasic` -interfaces. -- `simulation.go`: The module's simulation messages and related types (if any). From 5ef23b07bb135e0d8960e9b2684a96a323c518aa Mon Sep 17 00:00:00 2001 From: gamarin Date: Fri, 11 Oct 2019 15:08:49 +0200 Subject: [PATCH 122/196] almost finish store --- docs/core/store.md | 449 ++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 444 insertions(+), 5 deletions(-) diff --git a/docs/core/store.md b/docs/core/store.md index 000013cff2f2..f57118c7961a 100644 --- a/docs/core/store.md +++ b/docs/core/store.md @@ -1,12 +1,451 @@ # Store -## `CommitMultiStore` +## Pre-requisite Reading -## GasKv Store +- [Anatomy of an SDK application](../basics/app-anatomy.md) -## KVStore +## Synopsis -## Database +A store is a data structure that holds the state of the application. -## Main Store +- [Introduction to SDK Stores](#introduction-to-sdk-stores) + + [Store Interface](#store-interface) + + [Commit Store](#commit-store) +- [Multistore](#multistore) + + [Multistore Interface](#multistore-interface) + + [CommitMultiStore](#commitmultistore) + + [CacheMultiStore](#cachemultistore) +- [Base Layer KvStores](#base-layer-kvstores) + + [`KVStore` and `CommitKVStore` Interfaces](#kvstore-and-commitkvstore-interfaces) + + [`IAVL` Store](#iavl-store) + + [`DBAdapter` Store](#dbadapter-store) + + [`Transient` Store](#transient-store) +- [KVStore Wrappers](#kvstore-wrappers) + + [CacheKVStore](#cachekvstore) + + [`GasKv` Store](#gaskv-store) + + [`TraceKV` Store](#tracekv-store) + + [`Prefix` Store](#prefix-store) + +## Introduction to SDK Stores + +The Cosmos SDK comes with a large set of stores to persist the state of applications. By default, the main store of SDK applications is a multistore, i.e. a store of stores. Developers can add any number of key-value stores to the multistore, depending on their application needs. The multistore exists to support the modularity of the Cosmos SDK, as it lets each module declare and manage their own subset of the state. Key-value stores in the multistore can be accessed with a specific `key`, which is typically held in the [`keeper`](../building-modules/keeper.md) of the module that declared the store. + +``` ++-----------------------------------------------------+ +| | +| +--------------------------------------------+ | +| | | | +| | KVStore 1 - Manage by keeper of Module 1 | +| | | | +| +--------------------------------------------+ | +| | +| +--------------------------------------------+ | +| | | | +| | KVStore 2 - Manage by keeper of Module 2 | | +| | | | +| +--------------------------------------------+ | +| | +| +--------------------------------------------+ | +| | | | +| | KVStore 3 - Manage by keeper of Module 2 | | +| | | | +| +--------------------------------------------+ | +| | +| +--------------------------------------------+ | +| | | | +| | KVStore 4 - Manage by keeper of Module 3 | | +| | | | +| +--------------------------------------------+ | +| | +| +--------------------------------------------+ | +| | | | +| | KVStore 5 - Manage by keeper of Module 4 | | +| | | | +| +--------------------------------------------+ | +| | +| Main Multistore | +| | ++-----------------------------------------------------+ + + Application's State +``` + +### Store Interface + +At its very core, a Cosmos SDK `store` is an object that holds a `CacheWrapper` and implements a `GetStoreType()` method: + +```go +type Store interface { + GetStoreType() StoreType + CacheWrapper +} +``` + +The `GetStoreType` is a simple method that returns the type of store, whereas a `CacheWrapper` is a simple interface that specifies cache-wrapping and `Write` methods: + +```go +type CacheWrap interface { + // Write syncs with the underlying store. + Write() + + // CacheWrap recursively wraps again. + CacheWrap() CacheWrap + + // CacheWrapWithTrace recursively wraps again with tracing enabled. + CacheWrapWithTrace(w io.Writer, tc TraceContext) CacheWrap +} + +type CacheWrapper interface { //nolint + // CacheWrap cache wraps. + CacheWrap() CacheWrap + + // CacheWrapWithTrace cache wraps with tracing enabled. + CacheWrapWithTrace(w io.Writer, tc TraceContext) CacheWrap +} +``` + +Cache-wrapping is used ubiquitously in the Cosmos SDK and required to be implemented on every store type. A cache-wrapper creates a light snapshot of a store that can be passed around and updated without affecting the main underlying store. This is used to trigger temporary state-transitions that may be reverted later should an error occur. If a state-transition sequence is performed without issue, the cached store can be comitted to the main store at the end of the sequence. + +### Commit Store + +A commit store is a store that has the ability to commit changes made to the underlying tree or db. The Cosmos SDK differentiates simple stores from commit stores by extending the basic store interfaces with a `Committer`: + +```go +// Stores of MultiStore must implement CommitStore. +type CommitStore interface { + Committer + Store +} +``` + +The `Committer` is an interface that defines methods to persist changes to disk: + +```go +// something that can persist to disk +type Committer interface { + Commit() CommitID + LastCommitID() CommitID + SetPruning(PruningOptions) +} +``` + +The `CommitID` is a deterministic commit of the state tree. Its hash is returned to the underlying consensus engine and stored in the block header. Note that commit store interfaces exist for various purposes, one of which is to make sure not every object can commit the store. As part of the [object-capabilities model](./ocap.md) of the Cosmos SDK, only `baseapp` should have the ability to commit stores. For example, this is the reason why the `ctx.KVStore()` method by which modules typically access stores returns a `KVStore` and not a `CommitKVStore`. + +The Cosmos SDK comes with many types of stores, the most used being [`CommitMultiStore`](#multistore), [`KVStore`](#kvstore) and [`GasKv` store](#gaskv-store). [Other types of stores](#other-stores) include `Transient` and `TraceKV` stores. + +## Multistore + +### Multistore Interface + +Each Cosmos SDK application holds a multistore at its root to persist its state. The multistore is a store of `KVStores` that follows the `Multistore` interface: + +```go +type MultiStore interface { //nolint + Store + + // Cache wrap MultiStore. + // NOTE: Caller should probably not call .Write() on each, but + // call CacheMultiStore.Write(). + CacheMultiStore() CacheMultiStore + + // CacheMultiStoreWithVersion cache-wraps the underlying MultiStore where + // each stored is loaded at a specific version (height). + CacheMultiStoreWithVersion(version int64) (CacheMultiStore, error) + + // Convenience for fetching substores. + // If the store does not exist, panics. + GetStore(StoreKey) Store + GetKVStore(StoreKey) KVStore + + // TracingEnabled returns if tracing is enabled for the MultiStore. + TracingEnabled() bool + + // SetTracer sets the tracer for the MultiStore that the underlying + // stores will utilize to trace operations. The modified MultiStore is + // returned. + SetTracer(w io.Writer) MultiStore + + // SetTracingContext sets the tracing context for a MultiStore. It is + // implied that the caller should update the context when necessary between + // tracing operations. The modified MultiStore is returned. + SetTracingContext(TraceContext) MultiStore +} +``` + +### CommitMultiStore + +The main type of `Multistore` used in the Cosmos SDK is `CommitMultiStore`, which is an extension of the `Multistore` interface: + +```go +// A non-cache MultiStore. +type CommitMultiStore interface { + Committer + MultiStore + + // Mount a store of type using the given db. + // If db == nil, the new store will use the CommitMultiStore db. + MountStoreWithDB(key StoreKey, typ StoreType, db dbm.DB) + + // Panics on a nil key. + GetCommitStore(key StoreKey) CommitStore + + // Panics on a nil key. + GetCommitKVStore(key StoreKey) CommitKVStore + + // Load the latest persisted version. Called once after all calls to + // Mount*Store() are complete. + LoadLatestVersion() error + + // LoadLatestVersionAndUpgrade will load the latest version, but also + // rename/delete/create sub-store keys, before registering all the keys + // in order to handle breaking formats in migrations + LoadLatestVersionAndUpgrade(upgrades *StoreUpgrades) error + + // LoadVersionAndUpgrade will load the named version, but also + // rename/delete/create sub-store keys, before registering all the keys + // in order to handle breaking formats in migrations + LoadVersionAndUpgrade(ver int64, upgrades *StoreUpgrades) error + + // Load a specific persisted version. When you load an old version, or when + // the last commit attempt didn't complete, the next commit after loading + // must be idempotent (return the same commit id). Otherwise the behavior is + // undefined. + LoadVersion(ver int64) error + + // Set an inter-block (persistent) cache that maintains a mapping from + // StoreKeys to CommitKVStores. + SetInterBlockCache(MultiStorePersistentCache) +} +``` + +As for concrete implementation, the [`rootMulti.Store`](https://github.com/cosmos/cosmos-sdk/blob/master/store/rootmulti/store.go) is the go-to implementation of the `CommitMultiStore` interface. The `rootMulti.Store` is a base-layer multistore built around a `db` on top of which multiple `KVStores` can be mounted, and is the default multistore store used in [`baseapp`](./baseapp.md). + +### CacheMultiStore + +Whenever the `rootMulti.Store` needs to be cached-wrapped, a [`cachemulti.Store`](https://github.com/cosmos/cosmos-sdk/blob/master/store/cachemulti/store.go) is used. + +```go +type Store struct { + db types.CacheKVStore + stores map[types.StoreKey] types.CacheWrap +} +``` + +`cachemulti.Store` cache wraps all substores in its constructor and hold them in `Store.stores`. `Store.GetKVStore()` returns the store from `Store.stores`, and `Store.Write()` recursively calls `CacheWrap.Write()` on all the substores. + +## Base-layer KVStores + +### `KVStore` and `CommitKVStore` Interfaces + +A `KVStore` is a simple key-value store used to store and retrieve data. A `CommitKVStore` is a `KVStore` that also implements a `Committer`. By default, stores mounted in `baseapp`'s main `CommitMultiStore` are `CommitKVStore`s. The `KVStore` interface is primarily used to restrict modules from accessing the committer . + +Individual `KVStore`s are used by modules to manage a subset of the global state. `KVStores` can be accessed by objects that hold a specific key. This `key` should only be exposed to the [`keeper`](../building-modules/keeper.md) of the module that defines the store. + +`CommitKVStore`s are declared by proxy of their respective `key` and mounted on the application's [multistore](#multistore) in the [main application file](../basics/app-anatomy.md#core-application-file). In the same file, the `key` is also passed to the module's `keeper` that is responsible for managing the store. + +```go +type KVStore interface { + Store + + // Get returns nil iff key doesn't exist. Panics on nil key. + Get(key []byte) []byte + + // Has checks if a key exists. Panics on nil key. + Has(key []byte) bool + + // Set sets the key. Panics on nil key or value. + Set(key, value []byte) + + // Delete deletes the key. Panics on nil key. + Delete(key []byte) + + // Iterator over a domain of keys in ascending order. End is exclusive. + // Start must be less than end, or the Iterator is invalid. + // Iterator must be closed by caller. + // To iterate over entire domain, use store.Iterator(nil, nil) + // CONTRACT: No writes may happen within a domain while an iterator exists over it. + // Exceptionally allowed for cachekv.Store, safe to write in the modules. + Iterator(start, end []byte) Iterator + + // Iterator over a domain of keys in descending order. End is exclusive. + // Start must be less than end, or the Iterator is invalid. + // Iterator must be closed by caller. + // CONTRACT: No writes may happen within a domain while an iterator exists over it. + // Exceptionally allowed for cachekv.Store, safe to write in the modules. + ReverseIterator(start, end []byte) Iterator +} + +// Stores of MultiStore must implement CommitStore. +type CommitKVStore interface { + Committer + KVStore +} +``` + +Apart from the traditional `Get` and `Set` methods, a `KVStore` is expected to implement an `Iterator()` method which returns an `Iterator` object. The `Iterator()` method is used to iterate over a domain of keys, typically keys that share a common prefix. Here is a common pattern of using an `Iterator` that might be found in a module's `keeper`: + +```go +store := ctx.KVStore(keeper.storeKey) +iterator := sdk.KVStorePrefixIterator(store, prefix) // proxy for store.Iterator + +defer iterator.Close() +for ; iterator.Valid(); iterator.Next() { + var object types.Object + keeper.cdc.MustUnmarshalBinaryLengthPrefixed(iterator.Value(), &object) + + if cb(object) { + break + } +} +``` + +### `IAVL` Store + +The default implementation of `KVStore` and `CommitKVStore` used in `baseapp` is the [`iavl.Store`](https://github.com/cosmos/cosmos-sdk/blob/master/store/iavl/store.go). `iavl` stores are based around an [IAVL Tree](https://github.com/tendermint/iavl), a self-balancing binary tree which guarantees that: + +- `Get` and `Set` operations are O(log n), where n is the number of elements in the tree. +- Iteration efficiently returns the sorted elements within the range. +- Each tree version is immutable and can be retrieved even after a commit (depending on the pruning settings). + +### `DbAdapter` Store + +`dbadapter.Store` is a adapter for `dbm.DB` making it fulfilling the `KVStore` interface. + +```go +type Store struct { + dbm.DB +} +``` + +`dbadapter.Store` embeds `dbm.DB`, meaning most of the `KVStore` interface functions are implemented. The other functions (mostly miscellaneous) are manually implemented. This store is primarily used within [Transient Stores](#transient-stores) + +### `Transient` Store + +`Transient.Store` is a base-layer `KVStore` which is automatically discarded at the end of the block. + +```go +type Store struct { + dbadapter.Store +} +``` + +`Transient.Store` is a `dbadapter.Store` with a `dbm.NewMemDB()`. All `KVStore` methods are reused. When `Store.Commit()` is called, a new `dbadapter.Store` is assigned, discarding previous reference and making it garbage collected. + +## KVStore Wrappers + +### CacheKVStore + +`cachekv.Store` is a wrapper `KVStore` which provides buffered writing / cached reading functionalities over the underlying `KVStore`. + +```go +type Store struct { + cache map[string]cValue + parent types.KVStore +} +``` + +This is the type used whenever an IAVL Store needs to be cache-wrapped (typically when setting value that might be reverted later). + +#### `Get` + +`Store.Get()` checks `Store.cache` first in order to find if there is any cached value associated with the key. If the value exists, the function returns it. If not, the function calls `Store.parent.Get()`, sets the key-value pair to the `Store.cache`, and returns it. + +#### `Set` + +`Store.Set()` sets the key-value pair to the `Store.cache`. `cValue` has the field dirty bool which indicates whether the cached value is different from the underlying value. When `Store.Set()` cache new pair, the `cValue.dirty` is set `true` so when `Store.Write()` is called it can be written to the underlying store. + +#### `Iterator` + +`Store.Iterator()` have to traverse on both caches items and the original items. In `Store.iterator()`, two iterators are generated for each of them, and merged. `memIterator` is essentially a slice of the `KVPairs`, used for cached items. `mergeIterator` is a combination of two iterators, where traverse happens ordered on both iterators. + +### `GasKv` Store + +Cosmos SDK applications use [`gas`](../basics/accounts-fees-gas.md#fees-and-gas) to track resources usage and prevent spam. [`GasKv.Store`](https://github.com/cosmos/cosmos-sdk/blob/master/store/gaskv/store.go) is a `KVStore` wrapper that enables automatic gas consumption each time a read or write to the store is made. It is the solution of choice to track storage usage in Cosmos SDK applications. + +```go +type Store struct { + gasMeter types.GasMeter + gasConfig types.GasConfig + parent types.KVStore +} +``` + +When methods of the parent `KVStore` are called, `GasKv.Store` automatically consumes appropriate amount of gas depending on the `Store.gasConfig`: + +```go +type GasConfig struct { + HasCost Gas + DeleteCost Gas + ReadCostFlat Gas + ReadCostPerByte Gas + WriteCostFlat Gas + WriteCostPerByte Gas + IterNextCostFlat Gas +} +``` + +By default, all `KVStores` are wrapped in `GasKv.Stores` when retrieved. This is done in the `KVStore()` method of the [`context`](./context.md): + +```go +// KVStore fetches a KVStore from the MultiStore. +func (c Context) KVStore(key StoreKey) KVStore { + return gaskv.NewStore(c.MultiStore().GetKVStore(key), c.GasMeter(), stypes.KVGasConfig()) +} +``` + +In this case, the default gas configuration is used: + +```go +func KVGasConfig() GasConfig { + return GasConfig{ + HasCost: 1000, + DeleteCost: 1000, + ReadCostFlat: 1000, + ReadCostPerByte: 3, + WriteCostFlat: 2000, + WriteCostPerByte: 30, + IterNextCostFlat: 30, + } +} +``` + +### `TraceKv` Store + +`tracekv.Store` is a wrapper `KVStore` which provides operation tracing functionalities over the underlying `KVStore`. + +```go +type Store struct { + parent types.KVStore + writer io.Writer + context types.TraceContext +} +``` + +When each `KVStore` methods are called, `tracekv.Store` automatically logs `traceOperation` to the `Store.writer`. + +```go +type traceOperation struct { + Operation operation + Key string + Value string + Metadata map[string]interface{} +} +``` + +`traceOperation.Metadata` is filled with `Store.context` when it is not nil. `TraceContext` is a `map[string]interface{}`. + +### `Prefix` Store + +`prefix.Store` is a wrapper `KVStore` which provides automatic key-prefixing functionalities over the underlying `KVStore`. + +```go +type Store struct { + parent types.KVStore + prefix []byte +} +``` + +When `Store.{Get, Set}()` is called, the store forwards the call to its parent, with the key prefixed with the `Store.prefix`. + +When `Store.Iterator()` is called, it does not simply prefix the `Store.prefix`, since it does not work as intended. In that case, some of the elements are traversed even they are not starting with the prefix. From 7af02f87bd01f59467e3f473a387857265785394 Mon Sep 17 00:00:00 2001 From: gamarin Date: Fri, 11 Oct 2019 16:44:57 +0200 Subject: [PATCH 123/196] finish docs --- docs/core/store.md | 16 +++++++++++++++- 1 file changed, 15 insertions(+), 1 deletion(-) diff --git a/docs/core/store.md b/docs/core/store.md index f57118c7961a..e8016d87119e 100644 --- a/docs/core/store.md +++ b/docs/core/store.md @@ -172,6 +172,8 @@ type MultiStore interface { //nolint } ``` +If tracing is enabled, then cache-wrapping the multistore will wrap all the underlying `KVStore` in [`TraceKv.Store`](#tracekv-store) before caching them. + ### CommitMultiStore The main type of `Multistore` used in the Cosmos SDK is `CommitMultiStore`, which is an extension of the `Multistore` interface: @@ -331,6 +333,18 @@ type Store struct { `Transient.Store` is a `dbadapter.Store` with a `dbm.NewMemDB()`. All `KVStore` methods are reused. When `Store.Commit()` is called, a new `dbadapter.Store` is assigned, discarding previous reference and making it garbage collected. +This type of store is useful to persist information that is only relevant per-block. One example would be to store [parameter changes](https://github.com/cosmos/cosmos-sdk/blob/master/x/params/subspace/subspace.go#L27) (i.e. a bool set to `true` if a parameter changed in a block). + +Transient stores are typically accessed via the [`context`](./context.md) via the `TransientStore()` method: + +```go +// TransientStore fetches a TransientStore from the MultiStore. + +func (c Context) TransientStore(key StoreKey) KVStore { + return gaskv.NewStore(c.MultiStore().GetKVStore(key), c.GasMeter(), stypes.TransientGasConfig()) +} +``` + ## KVStore Wrappers ### CacheKVStore @@ -411,7 +425,7 @@ func KVGasConfig() GasConfig { ### `TraceKv` Store -`tracekv.Store` is a wrapper `KVStore` which provides operation tracing functionalities over the underlying `KVStore`. +`tracekv.Store` is a wrapper `KVStore` which provides operation tracing functionalities over the underlying `KVStore`. It is applied automatically by the Cosmos SDK on all `KVStore` if tracing is enabled on the parent `MultiStore`. ```go type Store struct { From 2b419e9cdda6f98583c7577d3750184180a57460 Mon Sep 17 00:00:00 2001 From: gamarin Date: Fri, 11 Oct 2019 16:51:49 +0200 Subject: [PATCH 124/196] fixes --- docs/basics/tx-lifecycle.md | 2 +- docs/building-modules/genesis.md | 6 +++++- docs/building-modules/invariants.md | 2 +- docs/building-modules/module-interfaces.md | 2 +- docs/building-modules/structure.md | 4 ++++ docs/core/baseapp.md | 4 ++++ docs/core/context.md | 2 +- docs/core/encoding.md | 2 +- docs/core/events.md | 2 +- docs/core/node.md | 2 +- docs/core/ocap.md | 4 ++++ docs/core/store.md | 3 +++ docs/core/transactions.md | 4 ++++ docs/core/tx-msgs.md | 5 ----- 14 files changed, 31 insertions(+), 13 deletions(-) delete mode 100644 docs/core/tx-msgs.md diff --git a/docs/basics/tx-lifecycle.md b/docs/basics/tx-lifecycle.md index d0b6892ba885..8f685249a635 100644 --- a/docs/basics/tx-lifecycle.md +++ b/docs/basics/tx-lifecycle.md @@ -262,4 +262,4 @@ in `[]byte` form, is stored in a block and appended to the blockchain. ## Next -Learn about [Baseapp](../core/baseapp.md). +Learn about [accounts, fees and gas](../accounts-fees-gas.md). diff --git a/docs/building-modules/genesis.md b/docs/building-modules/genesis.md index dfe0b15bc2ad..fcff8ac2c69d 100644 --- a/docs/building-modules/genesis.md +++ b/docs/building-modules/genesis.md @@ -44,4 +44,8 @@ See an [example of `InitGenesis` from the nameservice tutorial](https://github.c The `ExportGenesis` method is executed whenever an export of the state is made. It takes the latest known version of the subset of the state managed by the module and creates a new `GenesisState` out of it. This is mainly used when the chain needs to be upgraded via a hard fork. -See an [example of `ExportGenesis` from the nameservice tutorial](https://github.com/cosmos/sdk-application-tutorial/blob/master/x/nameservice/genesis.go#L46-L57). \ No newline at end of file +See an [example of `ExportGenesis` from the nameservice tutorial](https://github.com/cosmos/sdk-application-tutorial/blob/master/x/nameservice/genesis.go#L46-L57). + +## Next + +Learn about [modules interfaces](#module-interfaces.md). \ No newline at end of file diff --git a/docs/building-modules/invariants.md b/docs/building-modules/invariants.md index 72bbd53c7e05..7af843472db6 100644 --- a/docs/building-modules/invariants.md +++ b/docs/building-modules/invariants.md @@ -85,4 +85,4 @@ Typically, this interface is implemented in the module's `keeper`. You can see a ## Next -Learn about the recommended [structure for modules](./structure.md). +Learn about [genesis functionalities](./genesis.md). diff --git a/docs/building-modules/module-interfaces.md b/docs/building-modules/module-interfaces.md index ef4ea1273bc2..e4e80f90a86f 100644 --- a/docs/building-modules/module-interfaces.md +++ b/docs/building-modules/module-interfaces.md @@ -279,4 +279,4 @@ A few things to note: ## Next -Read about the next topic in building modules. +Read about the recommended [module structure](./structure.md). diff --git a/docs/building-modules/structure.md b/docs/building-modules/structure.md index eccd80cf9fad..77934dfc5b2f 100644 --- a/docs/building-modules/structure.md +++ b/docs/building-modules/structure.md @@ -79,3 +79,7 @@ allows for greater freedom of development while maintaining API stability. - `module.go`: The module's implementation of the `AppModule` and `AppModuleBasic` interfaces. - `simulation.go`: The module's simulation messages and related types (if any). + +## Next + +Learn about [interfaces](../interfaces/interfaces-intro.md). \ No newline at end of file diff --git a/docs/core/baseapp.md b/docs/core/baseapp.md index 028cac587dab..ef2488e9daa5 100644 --- a/docs/core/baseapp.md +++ b/docs/core/baseapp.md @@ -366,3 +366,7 @@ Each `query` comes with a `path`, which contains multiple `string`s. By conventi - Direct queries to the multistore, which are served by the `handlerQueryStore` method. These direct queryeis are different from custom queries which go through `app.queryRouter`, and are mainly used by third-party service provider like block explorers. - P2P queries, which are served via the `handleQueryP2P` method. These queries return either `app.addrPeerFilter` or `app.ipPeerFilter` that contain the list of peers filtered by address or IP respectively. These lists are first initialized via `options` in `baseapp`'s [constructor](#constructor). - Custom queries, which encompass most queries, are served via the `handleQueryCustom` method. The `handleQueryCustom` cache-wraps the multistore before using the `queryRoute` obtained from [`app.queryRouter`](#query-routing) to map the query to the appropriate module's `querier`. + +## Next + +Learn more about [transactions](./transactions.md). \ No newline at end of file diff --git a/docs/core/context.md b/docs/core/context.md index 64d9eb704276..cef84e5b610e 100644 --- a/docs/core/context.md +++ b/docs/core/context.md @@ -129,4 +129,4 @@ a successful run over all the messages, the cached multistore is written back to ## Next -Read about the next core concept. +Learn about the [node client](./node.md) diff --git a/docs/core/encoding.md b/docs/core/encoding.md index 2e568e0b89a7..aacc168bc9fa 100644 --- a/docs/core/encoding.md +++ b/docs/core/encoding.md @@ -63,4 +63,4 @@ func DefaultTxEncoder(cdc *codec.Codec) sdk.TxEncoder { ## Next -Learn about next concept \ No newline at end of file +Learn about [events](./events.md). \ No newline at end of file diff --git a/docs/core/events.md b/docs/core/events.md index 97c8ec70e46e..e3e0f7318814 100644 --- a/docs/core/events.md +++ b/docs/core/events.md @@ -47,4 +47,4 @@ See the [`handler` concept doc](../building-modules/handler.md) for a more detai ## Next -Learn about [encoding](./encoding.md) \ No newline at end of file +Learn about [object-capabilities](./ocap.md) \ No newline at end of file diff --git a/docs/core/node.md b/docs/core/node.md index 33f3e508ca0e..2e0a52c1fa0c 100644 --- a/docs/core/node.md +++ b/docs/core/node.md @@ -75,4 +75,4 @@ Upon starting, the node will bootstrap its RPC and P2P server and start dialing ## Next -Read more about the next core concept. \ No newline at end of file +Learn about the [store](./store.md). \ No newline at end of file diff --git a/docs/core/ocap.md b/docs/core/ocap.md index ff0fa78cd684..3b27034c1e1a 100644 --- a/docs/core/ocap.md +++ b/docs/core/ocap.md @@ -92,3 +92,7 @@ app.Router(). AddRoute(slashing.RouterKey, slashing.NewHandler(app.slashingKeeper)). AddRoute(gov.RouterKey, gov.NewHandler(app.govKeeper)) ``` + +## Next + +Learn about [building modules](../building-modules/intro.md). \ No newline at end of file diff --git a/docs/core/store.md b/docs/core/store.md index e8016d87119e..821b461da4b1 100644 --- a/docs/core/store.md +++ b/docs/core/store.md @@ -463,3 +463,6 @@ When `Store.{Get, Set}()` is called, the store forwards the call to its parent, When `Store.Iterator()` is called, it does not simply prefix the `Store.prefix`, since it does not work as intended. In that case, some of the elements are traversed even they are not starting with the prefix. +## Next + +Learn about [encoding](./encoding.md). \ No newline at end of file diff --git a/docs/core/transactions.md b/docs/core/transactions.md index 4751be98836e..f9c27d6c2201 100644 --- a/docs/core/transactions.md +++ b/docs/core/transactions.md @@ -78,3 +78,7 @@ Every message in a transaction must be signed by the addresses specified by `Get ## Handlers The final components developers must implement to enable transactions are handlers and keepers. Since messages are module types, each module needs a Handler to process all of its message types and enact the state changes within the module's scope. This design puts more responsibility in module developers, allowing application developers to reuse common functionalities without having to implement state transition logic repetitively. To read more about handlers, visit the documentation for building modules [here](../building-modules/handler.md). + +## Next + +Learn about the [context](./context.md). \ No newline at end of file diff --git a/docs/core/tx-msgs.md b/docs/core/tx-msgs.md deleted file mode 100644 index 35e8aeb39e42..000000000000 --- a/docs/core/tx-msgs.md +++ /dev/null @@ -1,5 +0,0 @@ -# Transactions and Messages - -## Transactions - -## Messages \ No newline at end of file From 6ee28c4ee04b6ab65af2cb830d5cae72d2614b6c Mon Sep 17 00:00:00 2001 From: gamarin Date: Fri, 18 Oct 2019 17:47:18 +0200 Subject: [PATCH 125/196] fede comments + permalinks --- docs/basics/accounts-fees-gas.md | 6 +++--- docs/basics/app-anatomy.md | 28 ++++++++++++---------------- docs/core/context.md | 2 +- docs/core/encoding.md | 2 +- docs/core/events.md | 2 +- docs/core/node.md | 30 +++++++++++++++--------------- docs/core/store.md | 10 +++++----- docs/interfaces/query-lifecycle.md | 2 +- docs/intro/sdk-app-architecture.md | 2 +- docs/intro/sdk-design.md | 4 ++-- 10 files changed, 42 insertions(+), 46 deletions(-) diff --git a/docs/basics/accounts-fees-gas.md b/docs/basics/accounts-fees-gas.md index 5418b1666f85..a9bc16975c17 100644 --- a/docs/basics/accounts-fees-gas.md +++ b/docs/basics/accounts-fees-gas.md @@ -125,7 +125,7 @@ The default implementation of `Keybase` of the Cosmos SDK is [`dbKeybase`](https - `Sign(name, passphrase string, msg []byte) ([]byte, crypto.PubKey, error)` strictly deals with the signature of the `message` bytes. Some preliminary work should be done beforehand to prepare and encode the `message` into a canonical `[]byte` form. See an example of `message` preparation from the `auth` module](https://github.com/cosmos/cosmos-sdk/blob/master/x/auth/types/txbuilder.go#L177-L207). Note that signature verification is not implemented in the SDK by default. It is deferred to the [`anteHandler`](#antehandler). - `CreateMnemonic(name string, language Language, passwd string, algo SigningAlgo) (info Info, seed string, err error)` creates a new mnemonic and prints it in the logs, but it **does not persist it on disk**. -- `CreateAccount(name, mnemonic, bip39Passwd, encryptPasswd string, account uint32, index uint32) (Info, error)` creates a new account based on the [`bip44 path`](https://github.com/bitcoin/bips/blob/master/bip-0044.mediawiki) and persists it on disk (note that the `PrivKey` is [encrypted with a passphrase before being persisted](https://github.com/cosmos/cosmos-sdk/blob/master/crypto/keys/mintkey/mintkey.go), it is **never stored unencrypted**). In the context of this method, the `account` and `address` parameters refer to the segment of the BIP44 derivation path (e.g. `0`, `1`, `2`, ...) used to derive the `PrivKey` and `PubKey` from the mnemonic (note that given the same mnemonic and `account`, the same `PrivKey` will be generated, and given the same `account` and `address`, the same `PubKey` and `Address` will be generated). Finally, note that the `CreateAccount` method derives keys and addresses using `secp256k1` as implemented in the [Tendermint library](https://github.com/tendermint/tendermint/blob/master/crypto/secp256k1). As a result, it only works for creating account keys and addresses, not consensus keys. See [`Addresses`](#addresses) for more. +- `CreateAccount(name, mnemonic, bip39Passwd, encryptPasswd string, account uint32, index uint32) (Info, error)` creates a new account based on the [`bip44 path`](https://github.com/bitcoin/bips/blob/master/bip-0044.mediawiki) and persists it on disk (note that the `PrivKey` is [encrypted with a passphrase before being persisted](https://github.com/cosmos/cosmos-sdk/blob/master/crypto/keys/mintkey/mintkey.go), it is **never stored unencrypted**). In the context of this method, the `account` and `address` parameters refer to the segment of the BIP44 derivation path (e.g. `0`, `1`, `2`, ...) used to derive the `PrivKey` and `PubKey` from the mnemonic (note that given the same mnemonic and `account`, the same `PrivKey` will be generated, and given the same `account` and `address`, the same `PubKey` and `Address` will be generated). Finally, note that the `CreateAccount` method derives keys and addresses using `secp256k1` as implemented in the [Tendermint library](https://github.com/tendermint/tendermint/tree/bc572217c07b90ad9cee851f193aaa8e9557cbc7/crypto/secp256k1). As a result, it only works for creating account keys and addresses, not consensus keys. See [`Addresses`](#addresses) for more. The current implementation of `dbKeybase` is basic and does not offer on-demand locking. If an instance of `dbKeybase` is created, the underlying `db` is locked meaning no other process can access it besides the one in which it was instantiated. This is the reason why the [default SDK client](https://github.com/cosmos/cosmos-sdk/tree/master/client/keys) uses another implementation of the `Keybase` interface called [`lazyKeybase`](https://github.com/cosmos/cosmos-sdk/blob/master/crypto/keys/lazy_keybase.go). `lazyKeybase` is simple wrapper around `dbKeybase` which locks the database only when operations are to be performed and unlocks it immediately after: @@ -161,7 +161,7 @@ With the `lazyKeybase`, it is possible for the [command-line interface](../inter #### PubKeys -`PubKey`s used in the Cosmos SDK follow the [`Pubkey` interface defined in [tendermint's `crypto` package](https://github.com/tendermint/tendermint/blob/master/crypto/crypto.go#L22-L27): +`PubKey`s used in the Cosmos SDK follow the [`Pubkey` interface defined in [tendermint's `crypto` package](https://github.com/tendermint/tendermint/blob/bc572217c07b90ad9cee851f193aaa8e9557cbc7/crypto/crypto.go#L22-L27): ```go @@ -173,7 +173,7 @@ type PubKey interface { } ``` -For `secp256k1` keys, the actual implementation can be found [here](https://github.com/tendermint/tendermint/blob/master/crypto/secp256k1/secp256k1.go#L140). For `ed25519` keys, it can be found [here](https://github.com/tendermint/tendermint/blob/master/crypto/ed25519/ed25519.go#L135). +For `secp256k1` keys, the actual implementation can be found [here](https://github.com/tendermint/tendermint/blob/bc572217c07b90ad9cee851f193aaa8e9557cbc7/crypto/secp256k1/secp256k1.go#L140). For `ed25519` keys, it can be found [here](https://github.com/tendermint/tendermint/blob/bc572217c07b90ad9cee851f193aaa8e9557cbc7/crypto/ed25519/ed25519.go#L135). Note that in the Cosmos SDK, `Pubkeys` are not manipulated in their raw form. Instead, they are double encoded using [`Amino`](../core/encoding.md#amino) and [`bech32`](https://en.bitcoin.it/wiki/Bech32). In the SDK is done by first calling the `Bytes()` method on the raw `Pubkey` (which applies amino encoding), and then the `ConvertAndEncode` method of `bech32`. You can check out the implementation [here](https://github.com/cosmos/cosmos-sdk/blob/master/types/address.go#L579-L729). diff --git a/docs/basics/app-anatomy.md b/docs/basics/app-anatomy.md index 37170bc19138..cf1adfc0519b 100644 --- a/docs/basics/app-anatomy.md +++ b/docs/basics/app-anatomy.md @@ -73,7 +73,7 @@ In general, the core of the state-machine is defined in a file called `app.go`. The first thing defined in `app.go` is the `type` of the application. It is generally comprised of the following parts: -- **A reference to [`baseapp`](../core/baseapp.md).** The custom application defined in `app.go` is an extension of the `baseapp` type. When a transaction is relayed by Tendermint to the application, the latter uses `baseapp`'s methods to route them to the appropriate module. `baseapp` implements most of the core logic for the application, including all the [ABCI methods](https://tendermint.com/docs/spec/abci/abci.html#overview) and the routing logic. Since `baseapp` implements these ABCI methods and `app` extends `baseapp`, it means that `app` satisfies the [`abci.Application` interface](https://github.com/tendermint/tendermint/blob/master/abci/types/application.go#L11-L26), which is a must for the [full-node](../core/node.md) to work. +- **A reference to [`baseapp`](../core/baseapp.md).** The custom application defined in `app.go` is an extension of the `baseapp` type. When a transaction is relayed by Tendermint to the application, the latter uses `baseapp`'s methods to route them to the appropriate module. `baseapp` implements most of the core logic for the application, including all the [ABCI methods](https://tendermint.com/docs/spec/abci/abci.html#overview) and the routing logic. Since `baseapp` implements these ABCI methods and `app` extends `baseapp`, it means that `app` satisfies the [`abci.Application` interface](https://github.com/tendermint/tendermint/blob/bc572217c07b90ad9cee851f193aaa8e9557cbc7/abci/types/application.go#L11-L26), which is a must for the [full-node](../core/node.md) to work. - **A list of store keys**. The [store](../core/store.md), which contains the entire state, is implemented as a multistore (i.e. a store of stores) in the Cosmos SDK. Each module uses one or multiple stores in the multistore to persist their part of the state. These stores can be accessed with specific keys that are declared in the `app` type. These keys, along with the `keepers`, are at the heart of the [object-capabilities model](../intro/ocap.md) of the Cosmos SDK. - **A list of module's `keepers`.** Each module defines an abstraction called [`keeper`](../building-modules/keeper.md), which handles reads and writes for this module's store(s). The `keeper`'s methods of one module can be called from other modules (if authorized), which is why they are declared in the application's type and exported as interfaces to other modules so that they are only allowed to access the authorized functions. - **A reference to a [`codec`](../core/encoding.md).** The Cosmos SDK gives developers the freedom to choose the encoding framework for their application. The application's `codec` is used to serialize and deserialize data structures in order to store them, as stores can only persist `[]bytes`. The `codec` must be deterministic. The default codec is [amino](./amino.md). @@ -101,7 +101,7 @@ This function constructs a new application of the type defined above. It is call Note that this function only creates an instance of the app, while the actual state is either carried over from the `~/.appd/data` folder if the node is restarted, or generated from the genesis file if the node is started for the first time. -You can see an example of application constructor [here](https://github.com/cosmos/gaia/blob/master/app/app.go#L110-L222). +You can see an example of application constructor [here](https://github.com/cosmos/gaia/blob/f41a660cdd5bea173139965ade55bd25d1ee3429/app/app.go#L110-L222). ### InitChainer @@ -109,7 +109,7 @@ The `InitChainer` is a function that initializes the state of the application fr In general, the `InitChainer` is mostly composed of the `InitGenesis` function of each of the application's modules. This is done by calling the `InitGenesis` function of the module manager, which in turn will call the `InitGenesis` function of each of the modules it contains. Note that the order in which the modules' `InitGenesis` functions must be called has to be set in the module manager using the `SetOrderInitGenesis` method. This is done in the [application's constructor](#application-constructor), and the `SetOrderInitGenesis` has to be called before the `SetInitChainer`. -You can see an example of an `InitChainer` [here](https://github.com/cosmos/gaia/blob/master/app/app.go#L235-L239). +You can see an example of an `InitChainer` [here](https://github.com/cosmos/gaia/blob/f41a660cdd5bea173139965ade55bd25d1ee3429/app/app.go#L235-L239). ### BeginBlocker and EndBlocker @@ -119,7 +119,7 @@ In general, the `BeginBlocker` and `EndBlocker` functions are mostly composed of As a sidenote, it is important to remember that application-specific blockchains are deterministic. Developers must be careful not to introduce non-determinism in `BeginBlocker` or `EndBlocker`, and must also be careful not to make them too computationally expensive, as [gas](./accounts-fees-gas.md/gas) does not constrain the cost of `BeginBlocker` and `EndBlocker` execution. -You can see an example of `BeginBlocker` and `EndBlocker` functions [here](https://github.com/cosmos/gaia/blob/master/app/app.go#L224-L232). +You can see an example of `BeginBlocker` and `EndBlocker` functions [here](https://github.com/cosmos/gaia/blob/f41a660cdd5bea173139965ade55bd25d1ee3429/app/app.go#L224-L232). ### Register Codec @@ -127,7 +127,7 @@ The `MakeCodec` function is the last important function of the `app.go` file. Th To register the application's modules, the `MakeCodec` function calls `RegisterCodec` on `ModuleBasics`. `ModuleBasics` is a [basic manager](../building-modules/module-manager.md#basicmanager) which lists all of the application's modules. It is instanciated in the `init()` function, and only serves to easily register non-dependant elements of application's modules (such as codec). To learn more about the basic module manager, click [here](../building-modules/module-manager.md#basicmanager). -You can see an example of a `MakeCodec` [here](https://github.com/cosmos/gaia/blob/master/app/app.go#L64-L70) +You can see an example of a `MakeCodec` [here](https://github.com/cosmos/gaia/blob/f41a660cdd5bea173139965ade55bd25d1ee3429/app/app.go#L64-L70) ## Modules @@ -164,7 +164,7 @@ The [`handler`](../building-modules/handler.md) refers to the part of the module The handler of a module is generally defined in a file called `handler.go` and consists of: -- A **switch function** `NewHandler` to route the message to the appropriate handler function. This function returns a `handler` function, and is registered in the [`AppModule`](#application-module-interface) to be used in the application's module manager to initialize the [application's router](../core/baseapp.md#routing). See an example of such a switch [here](https://github.com/cosmos/sdk-application-tutorial/blob/master/x/nameservice/handler.go#L10-L22). +- A **switch function** `NewHandler` to route the message to the appropriate handler function. This function returns a `handler` function, and is registered in the [`AppModule`](#application-module-interface) to be used in the application's module manager to initialize the [application's router](../core/baseapp.md#routing). See an example of such a switch [here](https://github.com/cosmos/sdk-application-tutorial/blob/c6754a1e313eb1ed973c5c91dcc606f2fd288811/x/nameservice/handler.go#L10-L22). - **One handler function for each message type defined by the module**. Developers write the message processing logic in these functions. This generally involves doing stateful checks to ensure the message is valid and calling [`keeper`](#keeper)'s methods to update the state. Handler functions return a result of type [`sdk.Result`](https://github.com/cosmos/cosmos-sdk/blob/master/types/result.go#L14-L37), which informs the application on whether the message was successfully processed. @@ -183,9 +183,7 @@ The `keeper` type definition generally consists of: - Reference to **other module's `keepers`**. Only needed if the `keeper` needs to access other module's store(s) (either to read or write from them). - A reference to the application's **codec**. The `keeper` needs it to marshal structs before storing them, or to unmarshal them when it retrieves them, because stores only accept `[]bytes` as value. -Along with the type definition, the next important component of the `keeper.go` file is the `keeper`'s constructor function, `NewKeeper`. This function instantiates a new `keeper` of the type defined above, with a `codec`, store `keys` and potentially references to other modules' `keeper`s as parameters. The `NewKeeper` function is called from the [application's constructor](#constructor-function). - -The rest of the file defines the `keeper`'s methods, primarily getters and setters. You can check an example of a `keeper` implementation [here](https://github.com/cosmos/sdk-application-tutorial/blob/master/x/nameservice/keeper.go). +Along with the type definition, the next important component of the `keeper.go` file is the `keeper`'s constructor function, `NewKeeper`. This function instantiates a new `keeper` of the type defined above, with a `codec`, store `keys` and potentially references to other modules' `keeper`s as parameters. The `NewKeeper` function is called from the [application's constructor](#constructor-function). The rest of the file defines the `keeper`'s methods, primarily getters and setters. To learn more about `keepers`, [click here](../building-modules/keeper.md). @@ -196,7 +194,7 @@ To learn more about `keepers`, [click here](../building-modules/keeper.md). The `Querier` of a module is defined in a file called `querier.go`, and consists of: - A **switch function** `NewQuerier` to route the query to the appropriate `querier` function. This function returns a `querier` function, and is is registered in the [`AppModule`](#application-module-interface) to be used in the application's module manager to initialize the [application's query router](../core/baseapp.md#query-routing). See an example of such a switch [here](https://github.com/cosmos/sdk-application-tutorial/blob/master/x/nameservice/querier.go#L21-L34). -- - **One querier function for each data type defined by the module that needs to be queryable**. Developers write the query processing logic in these functions. This generally involves calling [`keeper`](#keeper)'s methods to query the state and marshalling it to JSON. See an example of `querier` functions [here](https://github.com/cosmos/sdk-application-tutorial/blob/master/x/nameservice/querier.go#L37-L101). +- - **One querier function for each data type defined by the module that needs to be queryable**. Developers write the query processing logic in these functions. This generally involves calling [`keeper`](#keeper)'s methods to query the state and marshalling it to JSON. To learn more about `queriers`, [click here](../building-modules/querier.md). @@ -208,8 +206,8 @@ Each module defines command-line commands and REST routes to be exposed to end-u Generally, the commands related to a module are defined in a folder called `client/cli` in the module's folder. The CLI divides commands in two category, transactions and queries, defined in `client/cli/tx.go` and `client/cli/query.go` respectively. Both commands are built on top of the [Cobra Library](https://github.com/spf13/cobra): -- Transactions commands let users generate new transactions so that they can be included in a block and eventually update the state. One command should be created for each [message type](#message-types) defined in the module. The command calls the constructor of the message with the parameters provided by the end-user, and wraps it into a transaction. The SDK handles signing and the addition of other transaction metadata. See examples of transactions commands [here](https://github.com/cosmos/sdk-application-tutorial/blob/master/x/nameservice/client/cli/tx.go). -- Queries let users query the subset of the state defined by the module. Query commands forward queries to the [application's query router](./baseapp.md#query-routing), which routes them to the appropriate [querier](#querier) the `queryRoute` parameter supplied. See examples of query commands [here](https://github.com/cosmos/sdk-application-tutorial/blob/master/x/nameservice/client/cli/query.go). +- Transactions commands let users generate new transactions so that they can be included in a block and eventually update the state. One command should be created for each [message type](#message-types) defined in the module. The command calls the constructor of the message with the parameters provided by the end-user, and wraps it into a transaction. The SDK handles signing and the addition of other transaction metadata. +- Queries let users query the subset of the state defined by the module. Query commands forward queries to the [application's query router](./baseapp.md#query-routing), which routes them to the appropriate [querier](#querier) the `queryRoute` parameter supplied. To learn more about modules CLI, [click here](../building-modules/module-interfaces.md#cli). @@ -221,8 +219,6 @@ The module's REST interface lets users generate transactions and query the state - Custom request type definitions for each query or transaction creation function that needs to be exposed. These custom request types build on the [base `request` type](https://github.com/cosmos/cosmos-sdk/blob/master/types/rest/rest.go#L32-L43) of the Cosmos SDK. - One handler function for each request that can be routed to the given module. These functions implement the core logic necessary to serve the request. -See an example of a module's `rest.go` file [here](https://github.com/cosmos/sdk-application-tutorial/blob/master/x/nameservice/client/rest/rest.go). - To learn more about modules REST interface, [click here](../building-modules/module-interfaces.md#rest). ## Application Interface @@ -242,9 +238,9 @@ To learn more about interfaces, [click here](../interfaces/intro.md). ## Dependencies and Makefile -This section is optional, as developers are free to choose their dependency manager and project building method. That said, the current most used framework for versioning control is [`go.mod`](https://github.com/golang/go/wiki/Modules). It ensures each of the libraries used throughout the application are imported with the correct version. An example can be found [here](https://github.com/cosmos/sdk-application-tutorial/blob/master/go.mod). +This section is optional, as developers are free to choose their dependency manager and project building method. That said, the current most used framework for versioning control is [`go.mod`](https://github.com/golang/go/wiki/Modules). It ensures each of the libraries used throughout the application are imported with the correct version. An example can be found [here](https://github.com/cosmos/sdk-application-tutorial/blob/c6754a1e313eb1ed973c5c91dcc606f2fd288811/go.mod). -For building the application, a [Makefile](https://en.wikipedia.org/wiki/Makefile) is generally used. The Makefile primarily ensures that the `go.mod` is run before building the two entrypoints to the application, [`appd`](#node-client) and [`appcli`](#application-interface). An example of Makefile can be found [here](https://github.com/cosmos/sdk-application-tutorial/blob/master/Makefile). +For building the application, a [Makefile](https://en.wikipedia.org/wiki/Makefile) is generally used. The Makefile primarily ensures that the `go.mod` is run before building the two entrypoints to the application, [`appd`](#node-client) and [`appcli`](#application-interface). An example of Makefile can be found [here](https://github.com/cosmos/sdk-application-tutorial/blob/c6754a1e313eb1ed973c5c91dcc606f2fd288811/Makefile). ## Next diff --git a/docs/core/context.md b/docs/core/context.md index cef84e5b610e..8c170d591708 100644 --- a/docs/core/context.md +++ b/docs/core/context.md @@ -49,7 +49,7 @@ respective `KVStore` using their unique `StoreKey`. - **ABCI Header:** The [header](https://tendermint.com/docs/spec/abci/abci.html#header) is an ABCI type. It carries important information about the state of the blockchain, such as block height and proposer of the current block. - **Chain ID:** The unique identification number of the blockchain a block pertains to. - **Transaction Bytes:** The `[]byte` representation of a transaction being processed using the context. Every transaction is processed by various parts of the SDK and consensus engine (e.g. Tendermint) throughout its [lifecycle](../basics/tx-lifecycle.md), some of which to not have any understanding of transaction types. Thus, transactions are marshaled into the generic `[]byte` type using some kind of [encoding format](./encoding.md) such as [Amino](./amino.md). -- **Logger:** A [Logger](https://github.com/tendermint/tendermint/blob/master/libs/log/logger.go) from the Tendermint libraries. Learn more about logs [here](https://tendermint.com/docs/tendermint-core/how-to-read-logs.html#how-to-read-logs). Modules call this method to create their own unique module-specific logger. +- **Logger:** A [Logger](https://github.com/tendermint/tendermint/blob/bc572217c07b90ad9cee851f193aaa8e9557cbc7/libs/log/logger.go) from the Tendermint libraries. Learn more about logs [here](https://tendermint.com/docs/tendermint-core/how-to-read-logs.html#how-to-read-logs). Modules call this method to create their own unique module-specific logger. - **VoteInfo:** A list of the ABCI type [`VoteInfo`](https://tendermint.com/docs/spec/abci/abci.html#voteinfo), which includes the name of a validator and a boolean indicating whether they have signed the block. - **Gas Meters:** Specifically, a `gasMeter` for the transaction currently being processed using the context and a `blockGasMeter` for the entire block it belongs to. Users specify how much in fees they wish to pay for the execution of their transaction; these gas meters keep track of how much [gas](../basics/accounts-fees-gas.md) has been used in the transaction or block so far. If the gas meter runs out, execution halts. - **CheckTx Mode:** A boolean value indicating whether a transaction should be processed in `CheckTx` or `DeliverTx` mode. diff --git a/docs/core/encoding.md b/docs/core/encoding.md index aacc168bc9fa..b4cbb999eb45 100644 --- a/docs/core/encoding.md +++ b/docs/core/encoding.md @@ -28,7 +28,7 @@ bz := keeper.cdc.MustMarshalBinaryBare(object) keeper.cdc.MustUnmarshalBinaryBare(bz, &object) ``` -Alternatively, it is possible to use `MustMarshalBinaryLengthPrefixed`/`MustUnmarshalBinaryLengthPrefixed` instead of `MustMarshalBinaryBare`/`MustUnmarshalBinaryBare` for the same encoding prefixed by a uvarint encoding of the object to encode. +Alternatively, it is possible to use `MustMarshalBinaryLengthPrefixed`/`MustUnmarshalBinaryLengthPrefixed` instead of `MustMarshalBinaryBare`/`MustUnmarshalBinaryBare` for the same encoding prefixed by a `uvarint` encoding of the object to encode. Another important use of the `codec` is the encoding and decoding of [transactions](./transactions.md). Transactions are defined at the Cosmos SDK level, but passed to the underlying consensus engine in order to be relayed to other peers. Since the underlying consensus engine is agnostic to the application, it only accepts transactions in the form of `[]byte`. The encoding is done by an object called [`TxEncoder`](https://github.com/cosmos/cosmos-sdk/blob/master/types/tx_msg.go#L48-L49) and the decoding by an object called [`TxDecoder`](https://github.com/cosmos/cosmos-sdk/blob/master/types/tx_msg.go#L45-L47). A [standard implementation](https://github.com/cosmos/cosmos-sdk/blob/master/x/auth/types/stdtx.go) of both these objects can be found in the `auth` module: diff --git a/docs/core/events.md b/docs/core/events.md index e3e0f7318814..4915c0b0aee2 100644 --- a/docs/core/events.md +++ b/docs/core/events.md @@ -13,7 +13,7 @@ ## Events -`Event`s are implemented in the Cosmos SDK as an alias of the [ABCI `event` type](https://github.com/tendermint/tendermint/blob/master/abci/types/types.pb.go#L2661-L2667). They contain: +`Event`s are implemented in the Cosmos SDK as an alias of the [ABCI `event` type](https://github.com/tendermint/tendermint/blob/bc572217c07b90ad9cee851f193aaa8e9557cbc7/abci/types/types.pb.go#L2661-L2667). They contain: - A **type** of type `string`, which can refer to the type of action that led to the `event`'s emission (e.g. a certain value going above a threshold), or to the type of `message` if the event is triggered at the end of that `message` processing. - A list of [`attributes`](https://github.com/cosmos/cosmos-sdk/blob/master/types/events.go#L53-L56), which are key-value pairs that give more information about the `event`. diff --git a/docs/core/node.md b/docs/core/node.md index 2e0a52c1fa0c..7c8102062de7 100644 --- a/docs/core/node.md +++ b/docs/core/node.md @@ -20,10 +20,10 @@ In general, developers will implement the `main.go` function with the following - First, a [`codec`](./encoding.md) is instanciated for the application. - Then, the [`config`](https://github.com/cosmos/cosmos-sdk/blob/master/types/config.go) is retrieved and config parameters are set. This mainly involves setting the bech32 prefixes for [addresses and pubkeys](../basics/accounts-fees-gas.md#addresses-and-pubkeys). - Using [cobra](https://github.com/spf13/cobra), the root command of the full-node client is created. After that, all the custom commands of the application are added using the `AddCommand()` method of `rootCmd`. -- Add default server commands to `rootCmd` using the `server.AddCommands(ctx, cdc, rootCmd, newApp, exportAppStateAndTMValidators)` method. These commands are separated from the ones added above since they are standard and defined at SDK level. They should be shared by all SDK-based application. They include the most important command: the [`start` command](#start-command). -- Prepare and execute the [`executor`](https://github.com/tendermint/tendermint/blob/master/libs/cli/setup.go#L75-L78). +- Add default server commands to `rootCmd` using the `server.AddCommands(ctx, cdc, rootCmd, newApp, exportAppStateAndTMValidators)` method. These commands are separated from the ones added above since they are standard and defined at SDK level. They should be shared by all SDK-based applications. They include the most important command: the [`start` command](#start-command). +- Prepare and execute the [`executor`](https://github.com/tendermint/tendermint/blob/bc572217c07b90ad9cee851f193aaa8e9557cbc7/libs/cli/setup.go#L75-L78). -See an [example of `main` function](https://github.com/cosmos/gaia/blob/master/cmd/gaiad/main.go) from the `gaia` application. +See an [example of `main` function](https://github.com/cosmos/gaia/blob/f41a660cdd5bea173139965ade55bd25d1ee3429/cmd/gaiad/main.go) from the `gaia` application. ## `start` command @@ -50,25 +50,25 @@ In the background, the `db` is used by the `appCreator` to mount the main [`Comm ```go tmNode, err := node.NewNode( - cfg, - pvm.LoadOrGenFilePV(cfg.PrivValidatorKeyFile(), cfg.PrivValidatorStateFile()), - nodeKey, - proxy.NewLocalClientCreator(app), - node.DefaultGenesisDocProviderFunc(cfg), - node.DefaultDBProvider, - node.DefaultMetricsProvider(cfg.Instrumentation), - ctx.Logger.With("module", "node"), - ) + cfg, + pvm.LoadOrGenFilePV(cfg.PrivValidatorKeyFile(), cfg.PrivValidatorStateFile()), + nodeKey, + proxy.NewLocalClientCreator(app), + node.DefaultGenesisDocProviderFunc(cfg), + node.DefaultDBProvider, + node.DefaultMetricsProvider(cfg.Instrumentation), + ctx.Logger.With("module", "node"), +) ``` -The Tendermint node can be created with `app` because the latter satisfies the [`abci.Application` interface](https://github.com/tendermint/tendermint/blob/master/abci/types/application.go#L11-L26) (given that `app` extends [`baseapp`](./baseapp.md)). As part of the `NewNode` method, Tendermint makes sure that the height of the application (i.e. number of blocks since genesis) is equal to the height of the Tendermint node. The difference between these two heights should always be negative or null. If it is strictly negative, `NewNode` will replay blocks until the height of the application reaches the height of the Tendermint node. Finally, if the height of the application is `0`, the Tendermint node will call [`InitChain`](./baseapp.md#initchain) on the application to initialize the state. +The Tendermint node can be created with `app` because the latter satisfies the [`abci.Application` interface](https://github.com/tendermint/tendermint/blob/bc572217c07b90ad9cee851f193aaa8e9557cbc7/abci/types/application.go#L11-L26) (given that `app` extends [`baseapp`](./baseapp.md)). As part of the `NewNode` method, Tendermint makes sure that the height of the application (i.e. number of blocks since genesis) is equal to the height of the Tendermint node. The difference between these two heights should always be negative or null. If it is strictly negative, `NewNode` will replay blocks until the height of the application reaches the height of the Tendermint node. Finally, if the height of the application is `0`, the Tendermint node will call [`InitChain`](./baseapp.md#initchain) on the application to initialize the state. Once the Tendermint node is instanciated and in sync with the application, the node can be started: ```go if err := tmNode.Start(); err != nil { - return nil, err - } + return nil, err +} ``` Upon starting, the node will bootstrap its RPC and P2P server and start dialing peers. During handshake with its peers, if the node realizes they are ahead, it will query all the blocks sequentially in order to catch up. Then, it will wait for new block proposals and block signatures from validators in order to make progress. diff --git a/docs/core/store.md b/docs/core/store.md index 821b461da4b1..3d68c40cf5a6 100644 --- a/docs/core/store.md +++ b/docs/core/store.md @@ -14,8 +14,8 @@ A store is a data structure that holds the state of the application. - [Multistore](#multistore) + [Multistore Interface](#multistore-interface) + [CommitMultiStore](#commitmultistore) - + [CacheMultiStore](#cachemultistore) -- [Base Layer KvStores](#base-layer-kvstores) + + [CacheMuliStore](#cachemultistore) +- [Base Layer KVStores](#base-layer-kvstores) + [`KVStore` and `CommitKVStore` Interfaces](#kvstore-and-commitkvstore-interfaces) + [`IAVL` Store](#iavl-store) + [`DBAdapter` Store](#dbadapter-store) @@ -28,7 +28,7 @@ A store is a data structure that holds the state of the application. ## Introduction to SDK Stores -The Cosmos SDK comes with a large set of stores to persist the state of applications. By default, the main store of SDK applications is a multistore, i.e. a store of stores. Developers can add any number of key-value stores to the multistore, depending on their application needs. The multistore exists to support the modularity of the Cosmos SDK, as it lets each module declare and manage their own subset of the state. Key-value stores in the multistore can be accessed with a specific `key`, which is typically held in the [`keeper`](../building-modules/keeper.md) of the module that declared the store. +The Cosmos SDK comes with a large set of stores to persist the state of applications. By default, the main store of SDK applications is a multistore, i.e. a store of stores. Developers can add any number of key-value stores to the multistore, depending on their application needs. The multistore exists to support the modularity of the Cosmos SDK, as it lets each module declare and manage their own subset of the state. Key-value stores in the multistore can only be accessed with a specific capability `key`, which is typically held in the [`keeper`](../building-modules/keeper.md) of the module that declared the store. ``` +-----------------------------------------------------+ @@ -95,7 +95,7 @@ type CacheWrap interface { CacheWrapWithTrace(w io.Writer, tc TraceContext) CacheWrap } -type CacheWrapper interface { //nolint +type CacheWrapper interface { // CacheWrap cache wraps. CacheWrap() CacheWrap @@ -140,7 +140,7 @@ The Cosmos SDK comes with many types of stores, the most used being [`CommitMult Each Cosmos SDK application holds a multistore at its root to persist its state. The multistore is a store of `KVStores` that follows the `Multistore` interface: ```go -type MultiStore interface { //nolint +type MultiStore interface { Store // Cache wrap MultiStore. diff --git a/docs/interfaces/query-lifecycle.md b/docs/interfaces/query-lifecycle.md index 6c8a5b842620..efbeadc81be3 100644 --- a/docs/interfaces/query-lifecycle.md +++ b/docs/interfaces/query-lifecycle.md @@ -64,7 +64,7 @@ The first thing that is created in the execution of a CLI command is a `CLIConte * **Codec**: The [encoder/decoder](,./core/encoding.md) used by the application, used to marshal the parameters and query before making the Tendermint RPC request and unmarshal the returned response into a JSON object. * **Account Decoder**: The account decoder from the [`auth`](.../spec/auth) module, which translates `[]byte`s into accounts. -* **RPC Client**: The [Tendermint RPC Client](https://github.com/tendermint/tendermint/blob/master/rpc/client/interface.go), or node, to which the request will be relayed to. +* **RPC Client**: The [Tendermint RPC Client](https://github.com/tendermint/tendermint/blob/bc572217c07b90ad9cee851f193aaa8e9557cbc7/rpc/client/interface.go), or node, to which the request will be relayed to. * **Keybase**: A [Key Manager](.//core/accounts-keys.md) used to sign transactions and handle other operations with keys. * **Output Writer**: A [Writer](https://golang.org/pkg/io/#Writer) used to output the response. * **Configurations**: The flags configured by the user for this command, including `--height`, specifying the height of the blockchain to query and `--indent`, which indicates to add an indent to the JSON response. diff --git a/docs/intro/sdk-app-architecture.md b/docs/intro/sdk-app-architecture.md index ccf84fc48dbe..9ec8ad0a2f9d 100644 --- a/docs/intro/sdk-app-architecture.md +++ b/docs/intro/sdk-app-architecture.md @@ -65,7 +65,7 @@ The main part of a Cosmos SDK application is a blockchain daemon that is run by ## ABCI -Tendermint passes transactions from the network to the application through an interface called the [ABCI](https://github.com/tendermint/tendermint/tree/master/abci), which the application must implement. +Tendermint passes transactions from the network to the application through an interface called the [ABCI](https://github.com/tendermint/tendermint/tree/bc572217c07b90ad9cee851f193aaa8e9557cbc7/abci), which the application must implement. ``` +---------------------+ diff --git a/docs/intro/sdk-design.md b/docs/intro/sdk-design.md index 5096ab811e51..bab16940fe69 100644 --- a/docs/intro/sdk-design.md +++ b/docs/intro/sdk-design.md @@ -17,7 +17,7 @@ The application also enables you to generate transactions, encode them and pass ## `baseapp` -`baseApp` is the boilerplate implementation of the ABCI of the Cosmos SDK. It comes with a `router` to route transactions to their respective module. The main `app.go` file of your application will define your custom `app` type that will embed `baseapp`. This way, your custom `app` type will automatically inherit all the ABCI methods of `baseapp`. See an example of this in the [SDK application tutorial](https://github.com/cosmos/sdk-application-tutorial/blob/master/app.go#L27). +`baseApp` is the boilerplate implementation of the ABCI of the Cosmos SDK. It comes with a `router` to route transactions to their respective module. The main `app.go` file of your application will define your custom `app` type that will embed `baseapp`. This way, your custom `app` type will automatically inherit all the ABCI methods of `baseapp`. See an example of this in the [SDK application tutorial](https://github.com/cosmos/sdk-application-tutorial/blob/c6754a1e313eb1ed973c5c91dcc606f2fd288811/app.go#L27). The goal of `baseapp` is to provide a secure interface between the store and the extensible state machine while defining as little about the state machine as possible (staying true to the ABCI). @@ -25,7 +25,7 @@ For more on `baseapp`, please click [here](../concepts/baseapp.md). ## Multistore - The Cosmos SDK provides a multistore for persisting state. The multistore allows developers to declare any number of [`KVStores`](https://github.com/blocklayerhq/chainkit). These `KVStores` only accept the `[]byte` type as value and therefore any custom structure needs to be marshalled using [go-amino](https://github.com/tendermint/go-amino) before being stored. + The Cosmos SDK provides a multistore for persisting state. The multistore allows developers to declare any number of [`KVStores`](../core/store.md#base-layer-kvstores). These `KVStores` only accept the `[]byte` type as value and therefore any custom structure needs to be marshalled using [go-amino](https://github.com/tendermint/go-amino) before being stored. The multistore abstraction is used to divide the state in distinct compartments, each managed by its own module. For more on the multistore, click [here](../concepts/store.md) From e13a4bc593d0b31377725153873689d4c11defc5 Mon Sep 17 00:00:00 2001 From: gamarin Date: Mon, 21 Oct 2019 14:45:45 +0200 Subject: [PATCH 126/196] hans review --- .../{accounts-fees-gas.md => accounts.md} | 105 ++---------------- docs/basics/app-anatomy.md | 4 +- docs/basics/gas-fees.md | 91 +++++++++++++++ docs/basics/tx-lifecycle.md | 8 +- docs/building-modules/handler.md | 2 +- docs/building-modules/module-interfaces.md | 6 +- docs/core/baseapp.md | 12 +- docs/core/context.md | 4 +- docs/core/node.md | 4 +- docs/core/store.md | 2 +- docs/interfaces/cli.md | 4 +- docs/interfaces/query-lifecycle.md | 4 +- docs/interfaces/rest.md | 2 +- 13 files changed, 125 insertions(+), 123 deletions(-) rename docs/basics/{accounts-fees-gas.md => accounts.md} (61%) create mode 100644 docs/basics/gas-fees.md diff --git a/docs/basics/accounts-fees-gas.md b/docs/basics/accounts.md similarity index 61% rename from docs/basics/accounts-fees-gas.md rename to docs/basics/accounts.md index a9bc16975c17..98e3344a9ab5 100644 --- a/docs/basics/accounts-fees-gas.md +++ b/docs/basics/accounts.md @@ -1,4 +1,4 @@ -# Accounts, Fees and Gas +# Accounts ## Pre-requisite Reading @@ -6,20 +6,9 @@ ## Synopsis -This document describes the in-built accounts system of the Cosmos SDK, as well as the default strategies to handle fees and gas within a Cosmos SDK application. +This document describes the in-built accounts system of the Cosmos SDK. -- [Accounts](#accounts) - + [KeyBase](#keybase) - + [Addresses and Pubkeys](#addresses-and-pubkeys) - * [Pubkeys](#pubkeys) - * [Addresses](#addresses) -- [Fees and Gas](#fees-and-gas) - + [Gas Meter](#gas-meter) - * [Main Gas Meter](#main-gas-meter) - * [Block Gas Meter](#block-gas-meter) - + [AnteHandler](#antehandler) - -## Accounts +## Account Definition In the Cosmos SDK, an *account* designates a pair of *public key* `PubKey` and *private key* `PrivKey`. The `PubKey` can be derived to generate various `Addresses`, which are used to identify users (among other parties) in the application. `Addresses` are also associated with [`message`s](../building-modules/messages-and-queries.md#messages) to identify the sender of the `message`. The `PrivKey` is used to generate [digital signatures](#signatures) to prove that an `Address` associated with the `PrivKey` approved of a given `message`. @@ -67,7 +56,7 @@ To derive `PubKey`s and `PrivKey`s, the Cosmos SDK uses a standard called [BIP32 In the Cosmos SDK, accounts are stored and managed via an object called a [`Keybase`](#keybase). -### Keybase +## Keybase A `Keybase` is an object that stores and manages accounts. In the Cosmos SDK, a `Keybase` implementation follows the [`Keybase` interface](https://github.com/cosmos/cosmos-sdk/blob/master/crypto/keys/types.go#L14-L60): @@ -145,7 +134,7 @@ func (lkb lazyKeybase) Get(name string) (Info, error) { With the `lazyKeybase`, it is possible for the [command-line interface](../interfaces/cli.md) to create a new account while the [rest server](../interfaces/rest.md) is running. It is also possible to pipe multiple CLI commands. -### Addresses and PubKeys +## Addresses and PubKeys `Addresses` and `PubKey`s are both public information that identify actors in the application. There are 3 main types of `Addresses`/`PubKeys` available by default in the Cosmos SDK: @@ -159,7 +148,7 @@ With the `lazyKeybase`, it is possible for the [command-line interface](../inter | Validator Operator | cosmosvaloper | cosmosvaloperpub | `secp256k1` | `20` | `33` | | Consensus Nodes | cosmosvalcons | cosmosvalconspub | `ed25519` | `20` | `32` | -#### PubKeys +### PubKeys `PubKey`s used in the Cosmos SDK follow the [`Pubkey` interface defined in [tendermint's `crypto` package](https://github.com/tendermint/tendermint/blob/bc572217c07b90ad9cee851f193aaa8e9557cbc7/crypto/crypto.go#L22-L27): @@ -177,7 +166,7 @@ For `secp256k1` keys, the actual implementation can be found [here](https://gith Note that in the Cosmos SDK, `Pubkeys` are not manipulated in their raw form. Instead, they are double encoded using [`Amino`](../core/encoding.md#amino) and [`bech32`](https://en.bitcoin.it/wiki/Bech32). In the SDK is done by first calling the `Bytes()` method on the raw `Pubkey` (which applies amino encoding), and then the `ConvertAndEncode` method of `bech32`. You can check out the implementation [here](https://github.com/cosmos/cosmos-sdk/blob/master/types/address.go#L579-L729). -#### Addresses +### Addresses The Cosmos SDK comes by default with 3 types of addresses: @@ -207,84 +196,6 @@ type Address interface { Of note, the `Marhsal()` and `Bytes()` method both return the same raw `[]byte` form of the address, the former being needed for Protobuff compatibility. Also, the `String()` method is used to return the `bech32` encoded form of the address, which should be the only address format with which end-user interract. See an example [here](https://github.com/cosmos/cosmos-sdk/blob/master/types/address.go#L230-L243). -## Fees and Gas - -In the Cosmos SDK, `gas` is a special unit that is used to track the consumption of resources during execution. `gas` is typically consumed whenever read and writes are made to the store, but it can also be consumed if expensive computation needs to be done. It serves two main purposes: - -- Make sure blocks are not consuming too many resources and will be finalized. This is implemented by default in the SDK via the [block gas meter](#block-gas-meter). -- Prevent spam and abuse from end-user. To this end, `gas` consumed during [`message`](../building-modules/messages-and-queries.md#messages) execution is typically priced, resulting in a `fee` (`fees = gas * gas-prices`). This fee generally has to be paid by the sender of the `message`. Note that the SDK does not enforce `gas` pricing by default, as there may be other ways to prevent spam (e.g. bandwidth schemes). Still, most applications will implement `fee` mechanisms to prevent spam. This is done via the [`AnteHandler`](#antehandler). - -### Gas Meter - -In the Cosmos SDK, `gas` is a simple alias for `uint64`, and is managed by an object called a *gas meter*. Gas meters implement the [`GasMeter` interface](https://github.com/cosmos/cosmos-sdk/blob/master/store/types/gas.go#L32-L44): - -```go -type GasMeter interface { - GasConsumed() Gas - GasConsumedToLimit() Gas - Limit() Gas - ConsumeGas(amount Gas, descriptor string) - IsPastLimit() bool - IsOutOfGas() bool -} -``` - -where: - -- `GasConsumed()` returns the amount of gas that was consumed by the gas meter instance. -- `GasConsumedToLimit()` returns the amount of gas that was consumed by gas meter instance, or the limit if it is reached. -- `Limit()` returns the limit of the gas meter instance. `0` if the gas meter is infinite. -- `ConsumeGas(amount Gas, descriptor string)` consumes the amount of `gas` provided. If the `gas` overflows, it panics with the `descriptor` message. If the gas meter is not infinite, it panics if `gas` consumed goes above the limit. -- `IsPastLimit()` returns `true` if the amount of gas consumed by the gas meter instance is strictly above the limit, `false` otherwise. -- `IsOutOfGas()` returns `true` if the amount of gas consumed by the gas meter instance is above or equal to the limit, `false` otherwise. - -The gas meter is generally held in [`ctx`](../core/context.md), and consuming gas is done with the following pattern: - -```go -ctx.GasMeter().ConsumeGas(amount, "description") -``` - -By default, the Cosmos SDK makes use of two different gas meters, the [main gas meter](#main-gas-metter[) and the [block gas meter](#block-gas-meter). - -#### Main Gas Meter - -`ctx.GasMeter()` is the main gas meter of the application. The main gas meter is initialized in `BeginBlock` via `setDeliverState`, and then tracks gas consumption during execution sequences that lead to state-transitions, i.e. those originally triggered by [`BeginBlock`](../core/baseapp.md#beginblock), [`DeliverTx`](../core/baseapp.md#delivertx) and [`EndBlock`](../core/baseapp.md#endblock). At the beginning of each `DeliverTx`, the main gas meter **must be set to 0** in the [`AnteHandler`](#antehandler), so that it can track gas comsumption per-transaction. - -Gas comsumption can be done manually, generally by the module developer in the [`BeginBlocker`, `EndBlocker`](../building-modules/beginblock-endblock.md) or [`handler`](../building-modules/handler.md), but most of the time it is done automatically whenever there is a read or write to the store. This automatic gas consumption logic is implemented in a special store called [`GasKv`](../core/store.md#gaskv-store). - -#### Block Gas Meter - -`ctx.BlockGasMeter()` is the gas meter used to track gas consumption per block and make sure it does not go above a certain limit. A new instance of the `BlockGasMeter` is created each time [`BeginBlock`](../core/baseapp.go#beginblock) is called. The `BlockGasMeter` is finite, and the limit of gas per block is defined in the application's consensus parameters. - -When a new [transaction](../core/transaction.md) is being processed via `DeliverTx`, the current value of `BlockGasMeter` is checked to see if it is above the limit. If it is, `DeliverTx` returns immediately. This can happen even with the first transaction in a block, as `BeginBlock` itself can consume gas. If not, the transaction is processed normally. At the end of `DeliverTx`, the gas tracked by `ctx.BlockGasMeter()` is increased by the amount consumed to process the transaction: - -```go -ctx.BlockGasMeter().ConsumeGas( - ctx.GasMeter().GasConsumedToLimit(), - "block gas meter", - ) -``` - -### AnteHandler - -The `AnteHandler` is a special `handler` that is run for every transaction during `CheckTx` and `DeliverTx`, before the `handler` of each `message` in the transaction. `AnteHandler` have a different signature than `handler`s: - -```go -// AnteHandler authenticates transactions, before their internal messages are handled. -// If newCtx.IsZero(), ctx is used instead. -type AnteHandler func(ctx Context, tx Tx, simulate bool) (newCtx Context, result Result, abort bool) -``` - -Being a `handler`, the `anteHandler` is not implemented in the core SDK but in a module. This gives the possibility to developers to choose the version of `AnteHandler` that fits their application's needs. That said, most applications today use the default implementation defined in the [`auth` module](https://github.com/cosmos/cosmos-sdk/tree/master/x/auth). Here is what the `anteHandler` is intended to do in a normal Cosmos SDK application: - -- Verify that the transaction are of the correct type. Transaction types are defined in the module that implements the `anteHandler`, and they follow the [transaction interface](https://github.com/cosmos/cosmos-sdk/blob/master/types/tx_msg.go#L34-L41). This enables developers to play with various types for the transaction of their application. In the default `auth` module, the standard transaction type is [`StdTx`](https://github.com/cosmos/cosmos-sdk/blob/master/x/auth/types/stdtx.go#L23-L28). -- Verify signatures for each [`message`](../building-modules/messages-and-queries.md#messages) contained in the transaction. Each `message` should be signed by one or multiple sender(s), and these signatures must be verified in the `anteHandler`. -- During `CheckTx`, verify that the gas prices provided with the transaction is greater than the local `min-gas-prices` (as a reminder, gas-prices can be deducted from the following equation: `fees = gas * gas-prices`). `min-gas-prices` is a parameter local to each full-node and used during `CheckTx` to discard transactions that do not provide a minimum amount of fees. This ensure that the mempool cannot be spammed with garbage transactions. -- Verify that the sender of the transaction has enough funds to cover for the `fees`. When the end-user generates a transaction, they must indicate 2 of the 3 following parameters (the third one being implicit): `fees`, `gas` and `gas-prices`. This signals how much they are willing to pay for nodes to execute their transaction. The provided `gas` value is stored in a parameter called `GasWanted` for later use. -- Set `newCtx.GasMeter` to 0, with a limit of `GasWanted`. **This step is extremely important**, as it not only makes sure the transaction cannot consume infinite gas, but also that `ctx.GasMeter` is reset in-between each `DeliverTx` (`ctx` is set to `newCtx` after `anteHandler` is run). - -As explained above, the `anteHandler` returns a maximum limit of `gas` the transaction can consume during execution called `GasWanted`. The actual amount consumed in the end is denominated `GasUsed`, and we must therefore have `GasUsed =< GasWanted`. Both `GasWanted` and `GasUsed` are relayed to the underlying consensus engine when [`DeliverTx`](../core/baseapp.md#delivertx) returns. - ## Next -Learn about [baseapp](../core/baseapp.md). \ No newline at end of file +Learn about [gas and fees](./gas-fees.md). \ No newline at end of file diff --git a/docs/basics/app-anatomy.md b/docs/basics/app-anatomy.md index cf1adfc0519b..dba3e1bd7454 100644 --- a/docs/basics/app-anatomy.md +++ b/docs/basics/app-anatomy.md @@ -117,7 +117,7 @@ The SDK offers developers the possibility to implement automatic execution of co In general, the `BeginBlocker` and `EndBlocker` functions are mostly composed of the `BeginBlock` and `EndBlock` functions of each of the application's modules. This is done by calling the `BeginBlock` and `EndBlock` functions of the module manager, which in turn will call the `BeginBLock` and `EndBlock` functions of each of the modules it contains. Note that the order in which the modules' `BegingBlock` and `EndBlock` functions must be called has to be set in the module manager using the `SetOrderBeginBlock` and `SetOrderEndBlock` methods respectively. This is done in the [application's constructor](#application-constructor), and the `SetOrderBeginBlock` and `SetOrderEndBlock` methods have to be called before the `SetBeginBlocker` and `SetEndBlocker` functions. -As a sidenote, it is important to remember that application-specific blockchains are deterministic. Developers must be careful not to introduce non-determinism in `BeginBlocker` or `EndBlocker`, and must also be careful not to make them too computationally expensive, as [gas](./accounts-fees-gas.md/gas) does not constrain the cost of `BeginBlocker` and `EndBlocker` execution. +As a sidenote, it is important to remember that application-specific blockchains are deterministic. Developers must be careful not to introduce non-determinism in `BeginBlocker` or `EndBlocker`, and must also be careful not to make them too computationally expensive, as [gas](./gas-fees.md) does not constrain the cost of `BeginBlocker` and `EndBlocker` execution. You can see an example of `BeginBlocker` and `EndBlocker` functions [here](https://github.com/cosmos/gaia/blob/f41a660cdd5bea173139965ade55bd25d1ee3429/app/app.go#L224-L232). @@ -148,7 +148,7 @@ To learn more about the application module interface, [click here](../building-m A message is a custom type defined by each module that implements the [`message`](../building-modules/messages-and-queries.md#messages) interface. Each [`transaction`](../core/transaction.md) contains one or multiple `messages`. When a valid block of transactions is received by the full-node, Tendermint relays each one to the application via [`DeliverTx`](https://tendermint.com/docs/app-dev/abci-spec.html#delivertx). Then, the application handles the transaction: 1. Upon receiving the transaction, the application first unmarshalls it from `[]bytes`. -2. Then, it verifies a few things about the transaction like [fee payment and signatures](#accounts-fees-gas.md) before extracting the message(s) contained in the transaction. +2. Then, it verifies a few things about the transaction like [fee payment and signatures](#gas-fees.md#antehandler) before extracting the message(s) contained in the transaction. 3. With the [`Type()`](https://github.com/cosmos/cosmos-sdk/blob/master/types/tx_msg.go#L16) method, `baseapp` is able to know which modules defines the message. It is then able to route it to the appropriate module's [handler](#handler) in order for the message to be processed. 4. If the message is successfully processed, the state is updated. diff --git a/docs/basics/gas-fees.md b/docs/basics/gas-fees.md new file mode 100644 index 000000000000..908197f2d951 --- /dev/null +++ b/docs/basics/gas-fees.md @@ -0,0 +1,91 @@ +# Gas and Fees + +## Pre-requisite Reading + +- [Anatomy of an SDK Application](./app-anatomy.md) + +## Synopsis + +This document describes the default strategies to handle gas and fees within a Cosmos SDK application. + +## Introduction to `Gas` and `Fees` + +In the Cosmos SDK, `gas` is a special unit that is used to track the consumption of resources during execution. `gas` is typically consumed whenever read and writes are made to the store, but it can also be consumed if expensive computation needs to be done. It serves two main purposes: + +- Make sure blocks are not consuming too many resources and will be finalized. This is implemented by default in the SDK via the [block gas meter](#block-gas-meter). +- Prevent spam and abuse from end-user. To this end, `gas` consumed during [`message`](../building-modules/messages-and-queries.md#messages) execution is typically priced, resulting in a `fee` (`fees = gas * gas-prices`). This fee generally has to be paid by the sender of the `message`. Note that the SDK does not enforce `gas` pricing by default, as there may be other ways to prevent spam (e.g. bandwidth schemes). Still, most applications will implement `fee` mechanisms to prevent spam. This is done via the [`AnteHandler`](#antehandler). + +## Gas Meter + +In the Cosmos SDK, `gas` is a simple alias for `uint64`, and is managed by an object called a *gas meter*. Gas meters implement the [`GasMeter` interface](https://github.com/cosmos/cosmos-sdk/blob/master/store/types/gas.go#L32-L44): + +```go +type GasMeter interface { + GasConsumed() Gas + GasConsumedToLimit() Gas + Limit() Gas + ConsumeGas(amount Gas, descriptor string) + IsPastLimit() bool + IsOutOfGas() bool +} +``` + +where: + +- `GasConsumed()` returns the amount of gas that was consumed by the gas meter instance. +- `GasConsumedToLimit()` returns the amount of gas that was consumed by gas meter instance, or the limit if it is reached. +- `Limit()` returns the limit of the gas meter instance. `0` if the gas meter is infinite. +- `ConsumeGas(amount Gas, descriptor string)` consumes the amount of `gas` provided. If the `gas` overflows, it panics with the `descriptor` message. If the gas meter is not infinite, it panics if `gas` consumed goes above the limit. +- `IsPastLimit()` returns `true` if the amount of gas consumed by the gas meter instance is strictly above the limit, `false` otherwise. +- `IsOutOfGas()` returns `true` if the amount of gas consumed by the gas meter instance is above or equal to the limit, `false` otherwise. + +The gas meter is generally held in [`ctx`](../core/context.md), and consuming gas is done with the following pattern: + +```go +ctx.GasMeter().ConsumeGas(amount, "description") +``` + +By default, the Cosmos SDK makes use of two different gas meters, the [main gas meter](#main-gas-metter[) and the [block gas meter](#block-gas-meter). + +### Main Gas Meter + +`ctx.GasMeter()` is the main gas meter of the application. The main gas meter is initialized in `BeginBlock` via `setDeliverState`, and then tracks gas consumption during execution sequences that lead to state-transitions, i.e. those originally triggered by [`BeginBlock`](../core/baseapp.md#beginblock), [`DeliverTx`](../core/baseapp.md#delivertx) and [`EndBlock`](../core/baseapp.md#endblock). At the beginning of each `DeliverTx`, the main gas meter **must be set to 0** in the [`AnteHandler`](#antehandler), so that it can track gas comsumption per-transaction. + +Gas comsumption can be done manually, generally by the module developer in the [`BeginBlocker`, `EndBlocker`](../building-modules/beginblock-endblock.md) or [`handler`](../building-modules/handler.md), but most of the time it is done automatically whenever there is a read or write to the store. This automatic gas consumption logic is implemented in a special store called [`GasKv`](../core/store.md#gaskv-store). + +### Block Gas Meter + +`ctx.BlockGasMeter()` is the gas meter used to track gas consumption per block and make sure it does not go above a certain limit. A new instance of the `BlockGasMeter` is created each time [`BeginBlock`](../core/baseapp.go#beginblock) is called. The `BlockGasMeter` is finite, and the limit of gas per block is defined in the application's consensus parameters. + +When a new [transaction](../core/transaction.md) is being processed via `DeliverTx`, the current value of `BlockGasMeter` is checked to see if it is above the limit. If it is, `DeliverTx` returns immediately. This can happen even with the first transaction in a block, as `BeginBlock` itself can consume gas. If not, the transaction is processed normally. At the end of `DeliverTx`, the gas tracked by `ctx.BlockGasMeter()` is increased by the amount consumed to process the transaction: + +```go +ctx.BlockGasMeter().ConsumeGas( + ctx.GasMeter().GasConsumedToLimit(), + "block gas meter", + ) +``` + +## AnteHandler + +The `AnteHandler` is a special `handler` that is run for every transaction during `CheckTx` and `DeliverTx`, before the `handler` of each `message` in the transaction. `AnteHandler` have a different signature than `handler`s: + +```go +// AnteHandler authenticates transactions, before their internal messages are handled. +// If newCtx.IsZero(), ctx is used instead. +type AnteHandler func(ctx Context, tx Tx, simulate bool) (newCtx Context, result Result, abort bool) +``` + +Being a `handler`, the `anteHandler` is not implemented in the core SDK but in a module. This gives the possibility to developers to choose the version of `AnteHandler` that fits their application's needs. That said, most applications today use the default implementation defined in the [`auth` module](https://github.com/cosmos/cosmos-sdk/tree/master/x/auth). Here is what the `anteHandler` is intended to do in a normal Cosmos SDK application: + +- Verify that the transaction are of the correct type. Transaction types are defined in the module that implements the `anteHandler`, and they follow the [transaction interface](https://github.com/cosmos/cosmos-sdk/blob/master/types/tx_msg.go#L34-L41). This enables developers to play with various types for the transaction of their application. In the default `auth` module, the standard transaction type is [`StdTx`](https://github.com/cosmos/cosmos-sdk/blob/master/x/auth/types/stdtx.go#L23-L28). +- Verify signatures for each [`message`](../building-modules/messages-and-queries.md#messages) contained in the transaction. Each `message` should be signed by one or multiple sender(s), and these signatures must be verified in the `anteHandler`. +- During `CheckTx`, verify that the gas prices provided with the transaction is greater than the local `min-gas-prices` (as a reminder, gas-prices can be deducted from the following equation: `fees = gas * gas-prices`). `min-gas-prices` is a parameter local to each full-node and used during `CheckTx` to discard transactions that do not provide a minimum amount of fees. This ensure that the mempool cannot be spammed with garbage transactions. +- Verify that the sender of the transaction has enough funds to cover for the `fees`. When the end-user generates a transaction, they must indicate 2 of the 3 following parameters (the third one being implicit): `fees`, `gas` and `gas-prices`. This signals how much they are willing to pay for nodes to execute their transaction. The provided `gas` value is stored in a parameter called `GasWanted` for later use. +- Set `newCtx.GasMeter` to 0, with a limit of `GasWanted`. **This step is extremely important**, as it not only makes sure the transaction cannot consume infinite gas, but also that `ctx.GasMeter` is reset in-between each `DeliverTx` (`ctx` is set to `newCtx` after `anteHandler` is run). + +As explained above, the `anteHandler` returns a maximum limit of `gas` the transaction can consume during execution called `GasWanted`. The actual amount consumed in the end is denominated `GasUsed`, and we must therefore have `GasUsed =< GasWanted`. Both `GasWanted` and `GasUsed` are relayed to the underlying consensus engine when [`DeliverTx`](../core/baseapp.md#delivertx) returns. + +## Next + +Learn about [baseapp](../core/baseapp.md). \ No newline at end of file diff --git a/docs/basics/tx-lifecycle.md b/docs/basics/tx-lifecycle.md index 8f685249a635..86b5f2753da6 100644 --- a/docs/basics/tx-lifecycle.md +++ b/docs/basics/tx-lifecycle.md @@ -26,13 +26,13 @@ One of the main application interfaces is the command-line interface. The transa This command will automatically **create** the transaction, **sign** it using the account's private key, and **broadcast** it to the specified peer node. -There are several required and optional flags for transaction creation. The `--from` flag specifies which [account](./accounts-fees-gas.md#accounts) the transaction is originating from. For example, if the transaction is sending coins, the funds will be drawn from the specified `from` address. +There are several required and optional flags for transaction creation. The `--from` flag specifies which [account](./accounts.md) the transaction is originating from. For example, if the transaction is sending coins, the funds will be drawn from the specified `from` address. #### Gas and Fees -Additionally, there are several [flags](../interfaces/cli.md) users can use to indicate how much they are willing to pay in [fees](./accounts-fees-gas.md#fees): +Additionally, there are several [flags](../interfaces/cli.md) users can use to indicate how much they are willing to pay in [fees](./gas-fees.md): -* `--gas` refers to how much [gas](./accounts-fees-gas.md#gas), which represents computational resources, `Tx` consumes. Gas is dependent on the transaction and is not precisely calculated until execution, but can be estimated by providing `auto` as the value for `--gas`. +* `--gas` refers to how much [gas](./gas-fees.md), which represents computational resources, `Tx` consumes. Gas is dependent on the transaction and is not precisely calculated until execution, but can be estimated by providing `auto` as the value for `--gas`. * `--gas-adjustment` (optional) can be used to scale `gas` up in order to avoid underestimating. For example, users can specify their gas adjustment as 1.5 to use 1.5 times the estimated gas. * `--gas-prices` specifies how much the user is willing pay per unit of gas, which can be one or multiple denominations of tokens. For example, `--gas-prices=0.025uatom, 0.025upho` means the user is willing to pay 0.025uatom AND 0.025upho per unit of gas. * `--fees` specifies how much in fees the user is willing to pay in total. @@ -262,4 +262,4 @@ in `[]byte` form, is stored in a block and appended to the blockchain. ## Next -Learn about [accounts, fees and gas](../accounts-fees-gas.md). +Learn about [accounts](../accounts.md). diff --git a/docs/building-modules/handler.md b/docs/building-modules/handler.md index d3e76572373f..afdb0d48f875 100644 --- a/docs/building-modules/handler.md +++ b/docs/building-modules/handler.md @@ -24,7 +24,7 @@ Let us break it down: - The [`Msg`](./messages-and-queries.md#messages) is the actual object being processed. - The [`Context`](../core/context.md) contains all the necessary information needed to process the `msg`, as well as a cache-wrapped copy of the latest state. If the `msg` is succesfully processed, the modified version of the temporary state contained in the `ctx` will be written to the main state. -- The [`Result`](https://github.com/cosmos/cosmos-sdk/blob/master/types/result.go#L14-L38) returned to `baseapp`, which contains (among other things) information on the execution of the `handler`, [`gas`](../basics/accounts-fees-gas.md#gas) consumption and [`events`](./events.md). +- The [`Result`](https://github.com/cosmos/cosmos-sdk/blob/master/types/result.go#L14-L38) returned to `baseapp`, which contains (among other things) information on the execution of the `handler`, [`gas`](../basics/gas-fees.md) consumption and [`events`](./events.md). ## Implementation of a module `handler`s diff --git a/docs/building-modules/module-interfaces.md b/docs/building-modules/module-interfaces.md index e4e80f90a86f..ff5a6564b751 100644 --- a/docs/building-modules/module-interfaces.md +++ b/docs/building-modules/module-interfaces.md @@ -139,7 +139,7 @@ Finally, the module also needs a `GetQueryCmd`, which aggregates all of the quer ### Flags -[Flags](../interfaces/cli.md#flags) are entered by the user and allow for command customizations. Examples include the [fees](../core/accounts-fees.md) or gas prices users are willing to pay for their transactions. +[Flags](../interfaces/cli.md#flags) are entered by the user and allow for command customizations. Examples include the [fees](../basics/gas-fees.md) or gas prices users are willing to pay for their transactions. The flags for a module are typically found in a `flags.go` file in the `./x/moduleName/client/cli` folder. Module developers can create a list of possible flags including the value type, default value, and a description displayed if the user uses a `help` command. In each transaction getter function, they can add flags to the commands and, optionally, mark flags as *required* so that an error is thrown if the user does not provide values for them. @@ -188,7 +188,7 @@ The `BaseReq` includes basic information that every request needs to have, simil `BaseReq` is a type defined in the SDK that encapsulates much of the transaction configurations similar to CLI command flags. Users must provide the information in the body of their requests. -* `From` indicates which [account](../core/accounts-fees.md) the transaction originates from. This account is used to sign the transaction. +* `From` indicates which [account](../basics/accounts.md) the transaction originates from. This account is used to sign the transaction. * `Memo` sends a memo along with the transaction. * `ChainID` specifies the unique identifier of the blockchain the transaction pertains to. * `AccountNumber` is an identifier for the account. @@ -196,7 +196,7 @@ The `BaseReq` includes basic information that every request needs to have, simil * `Gas` refers to how much [gas](../core/gas.md), which represents computational resources, Tx consumes. Gas is dependent on the transaction and is not precisely calculated until execution, but can be estimated by providing auto as the value for `Gas`. * `GasAdjustment` can be used to scale gas up in order to avoid underestimating. For example, users can specify their gas adjustment as 1.5 to use 1.5 times the estimated gas. * `GasPrices` specifies how much the user is willing pay per unit of gas, which can be one or multiple denominations of tokens. For example, --gas-prices=0.025uatom, 0.025upho means the user is willing to pay 0.025uatom AND 0.025upho per unit of gas. -* `Fees` specifies how much in [fees](../core/accounts-fees.md) the user is willing to pay in total. Note that the user only needs to provide either `gas-prices` or `fees`, but not both, because they can be derived from each other. +* `Fees` specifies how much in [fees](../basics/gas-fees.md) the user is willing to pay in total. Note that the user only needs to provide either `gas-prices` or `fees`, but not both, because they can be derived from each other. * `Simulate` instructs the application to ignore gas and simulate the transaction running without broadcasting. ### Request Handlers diff --git a/docs/core/baseapp.md b/docs/core/baseapp.md index ef2488e9daa5..7bab83533baa 100644 --- a/docs/core/baseapp.md +++ b/docs/core/baseapp.md @@ -246,10 +246,10 @@ Developers building on top of the Cosmos SDK need not implement the ABCI themsel 1. Extract the `message`s from the transaction. 2. Perform *stateless* checks by calling `ValidateBasic()` on each of the `messages`. This is done first, as *stateless* checks are less computationally expensive than *stateful* checks. If `ValidateBasic()` fail, `CheckTx` returns before running *stateful* checks, which saves resources. -3. Perform non-module related *stateful* checks on the account. This step is mainly about checking that the `message` signatures are valid, that enough fees are provided and that the sending account has enough funds to pay for said fees. Note that no precise [`gas`](./accounts-fees-gas.md#gas) counting occurs here, as `message`s are not processed. Usually, the [`anteHandler`](./accounts-fees-gas.md#antehandler) will check that the `gas` provided with the transaction is superior to a minimum reference gas amount based on the raw transaction size, in order to avoid spam with transactions that provide 0 gas. +3. Perform non-module related *stateful* checks on the [account](../basics/accounts.md). This step is mainly about checking that the `message` signatures are valid, that enough fees are provided and that the sending account has enough funds to pay for said fees. Note that no precise [`gas`](../basics/gas-fees.md) counting occurs here, as `message`s are not processed. Usually, the [`anteHandler`](./gas-fees.md#antehandler) will check that the `gas` provided with the transaction is superior to a minimum reference gas amount based on the raw transaction size, in order to avoid spam with transactions that provide 0 gas. 4. Ensure that a [`Route`](#message-routing) exists for each `message`, but do **not** actually process `message`s. `Message`s only need to be processed when the canonical state need to be updated, which happens during `DeliverTx`. -Steps 2. and 3. are performed by the [`anteHandler`](./accounts-fees-gas.md#antehandler) in the [`RunTx`](#runtx-antehandler-and-runmsgs) function, which `CheckTx` calls with the `runTxModeCheck` mode. During each step of `CheckTx`, a special [volatile state](#volatile-states) called `checkState` is updated. This state is used to keep track of the temporary changes triggered by the `CheckTx` calls of each transaction without modifying the [main canonical state](#main-state) . For example, when a transaction goes through `CheckTx`, the transaction's fees are deducted from the sender's account in `checkState`. If a second transaction is received from the same account before the first is processed, and the account has consumed all its funds in `checkState` during the first transaction, the second transaction will fail `CheckTx` and be rejected. In any case, the sender's account will not actually pay the fees until the transaction is actually included in a block, because `checkState` never gets committed to the main state. `checkState` is reset to the latest state of the main state each time a blocks gets [committed](#commit). +Steps 2. and 3. are performed by the [`anteHandler`](./gas-fees.md#antehandler) in the [`RunTx`](#runtx-antehandler-and-runmsgs) function, which `CheckTx` calls with the `runTxModeCheck` mode. During each step of `CheckTx`, a special [volatile state](#volatile-states) called `checkState` is updated. This state is used to keep track of the temporary changes triggered by the `CheckTx` calls of each transaction without modifying the [main canonical state](#main-state) . For example, when a transaction goes through `CheckTx`, the transaction's fees are deducted from the sender's account in `checkState`. If a second transaction is received from the same account before the first is processed, and the account has consumed all its funds in `checkState` during the first transaction, the second transaction will fail `CheckTx` and be rejected. In any case, the sender's account will not actually pay the fees until the transaction is actually included in a block, because `checkState` never gets committed to the main state. `checkState` is reset to the latest state of the main state each time a blocks gets [committed](#commit). `CheckTx` returns a response to the underlying consensus engine of type [`abci.ResponseCheckTx`](https://tendermint.com/docs/spec/abci/abci.html#checktx). The response contains: @@ -293,7 +293,7 @@ During step 5., each read/write to the store increases the value of `GasConsumed `RunTx` is called from `CheckTx`/`DeliverTx` to handle the transaction, with `runTxModeCheck` or `runTxModeDeliver` as parameter to differentiate between the two modes of execution. Note that when `RunTx` receives a transaction, it has already been decoded. -The first thing `RunTx` does upon being called is to retrieve the `context`'s `CacheMultiStore` by calling the `getContextForTx()` function with the appropriate mode (either `runTxModeCheck` or `runTxModeDeliver`). This `CacheMultiStore` is a cached version of the main store instantiated during `BeginBlock` for `DeliverTx` and during the `Commit` of the previous block for `CheckTx`. After that, two `defer func()` are called for [`gas`](./accounts-fees-gas.md#gas) management. They are executed when `runTx` returns and make sure `gas` is actually consumed, and will throw errors, if any. +The first thing `RunTx` does upon being called is to retrieve the `context`'s `CacheMultiStore` by calling the `getContextForTx()` function with the appropriate mode (either `runTxModeCheck` or `runTxModeDeliver`). This `CacheMultiStore` is a cached version of the main store instantiated during `BeginBlock` for `DeliverTx` and during the `Commit` of the previous block for `CheckTx`. After that, two `defer func()` are called for [`gas`](./gas-fees.md) management. They are executed when `runTx` returns and make sure `gas` is actually consumed, and will throw errors, if any. After that, `RunTx()` calls `ValidateBasic()` on each `message`in the `Tx`, which runs preliminary _stateless_ validity checks. If any `message` fails to pass `ValidateBasic()`, `RunTx()` returns with an error. @@ -327,7 +327,7 @@ The [`InitChain` ABCI message](https://tendermint.com/docs/app-dev/abci-spec.htm - [Consensus Parameters](https://tendermint.com/docs/spec/abci/apps.html#consensus-parameters) via `setConsensusParams`. - [`checkState` and `deliverState`](#volatile-states) via `setCheckState` and `setDeliverState`. -- The [block gas meter](../basics/accounts-fees-gas.md#block-gas-meter), with infinite gas to process genesis transactions. +- The [block gas meter](../basics/gas-fees.md#block-gas-meter), with infinite gas to process genesis transactions. Finally, the `InitChain(req abci.RequestInitChain)` method of `baseapp` calls the [`initChainer()`](../basics/app-anatomy.md#initchainer) of the application in order to initialize the main state of the application from the [`genesis file`](./genesis.md) and, if defined, call the [`InitGenesis`](../building-modules/genesis.md#initgenesis) function of each of the application's modules. @@ -335,8 +335,8 @@ Finally, the `InitChain(req abci.RequestInitChain)` method of `baseapp` calls th The [`BeginBlock` ABCI message](#https://tendermint.com/docs/app-dev/abci-spec.html#beginblock) is sent from the underlying Tendermint engine when a block proposal created by the correct proposer is received, before [`DeliverTx`](#delivertx) is run for each transaction in the block. It allows developers to have logic be executed at the beginning of each block. In the Cosmos SDK, the `BeginBlock(req abci.RequestBeginBlock)` method does the following: -- Initialize [`deliverState`](#volatile-states) with the latest header using the `req abci.RequestBeginBlock` passed as parameter via the [`setDeliverState`](https://github.com/cosmos/cosmos-sdk/blob/master/baseapp/baseapp.go#L283-L289) function. This function also resets the [main gas meter](../basics/accounts-fees-gas.md#main-gas-meter). -- Initialize the [block gas meter](../basics/accounts-fees-gas.md#block-gas-meter) with the `maxGas` limit. The `gas` consumed within the block cannot go above `maxGas`. This parameter is defined in the application's consensus parameters. +- Initialize [`deliverState`](#volatile-states) with the latest header using the `req abci.RequestBeginBlock` passed as parameter via the [`setDeliverState`](https://github.com/cosmos/cosmos-sdk/blob/master/baseapp/baseapp.go#L283-L289) function. This function also resets the [main gas meter](../basics/gas-fees.md#main-gas-meter). +- Initialize the [block gas meter](../basics/gas-fees.md#block-gas-meter) with the `maxGas` limit. The `gas` consumed within the block cannot go above `maxGas`. This parameter is defined in the application's consensus parameters. - Run the application's [`beginBlocker()`](../basics/app-anatomy.md#beginblocker-and-endblock), which mainly runs the [`BeginBlocker()`](../building-modules/beginblock-endblock.md#beginblock) method of each of the application's modules. - Set the [`VoteInfos`](https://tendermint.com/docs/app-dev/abci-spec.html#voteinfo) of the application, i.e. the list of validators whose *precommit* for the previous block was included by the proposer of the current block. This information is carried into the [`Context`](./context.md) so that it can be used during `DeliverTx` and `EndBlock`. diff --git a/docs/core/context.md b/docs/core/context.md index 8c170d591708..25af7bbfc1d7 100644 --- a/docs/core/context.md +++ b/docs/core/context.md @@ -51,9 +51,9 @@ respective `KVStore` using their unique `StoreKey`. - **Transaction Bytes:** The `[]byte` representation of a transaction being processed using the context. Every transaction is processed by various parts of the SDK and consensus engine (e.g. Tendermint) throughout its [lifecycle](../basics/tx-lifecycle.md), some of which to not have any understanding of transaction types. Thus, transactions are marshaled into the generic `[]byte` type using some kind of [encoding format](./encoding.md) such as [Amino](./amino.md). - **Logger:** A [Logger](https://github.com/tendermint/tendermint/blob/bc572217c07b90ad9cee851f193aaa8e9557cbc7/libs/log/logger.go) from the Tendermint libraries. Learn more about logs [here](https://tendermint.com/docs/tendermint-core/how-to-read-logs.html#how-to-read-logs). Modules call this method to create their own unique module-specific logger. - **VoteInfo:** A list of the ABCI type [`VoteInfo`](https://tendermint.com/docs/spec/abci/abci.html#voteinfo), which includes the name of a validator and a boolean indicating whether they have signed the block. -- **Gas Meters:** Specifically, a `gasMeter` for the transaction currently being processed using the context and a `blockGasMeter` for the entire block it belongs to. Users specify how much in fees they wish to pay for the execution of their transaction; these gas meters keep track of how much [gas](../basics/accounts-fees-gas.md) has been used in the transaction or block so far. If the gas meter runs out, execution halts. +- **Gas Meters:** Specifically, a `gasMeter` for the transaction currently being processed using the context and a `blockGasMeter` for the entire block it belongs to. Users specify how much in fees they wish to pay for the execution of their transaction; these gas meters keep track of how much [gas](../basics/gas-fees.md) has been used in the transaction or block so far. If the gas meter runs out, execution halts. - **CheckTx Mode:** A boolean value indicating whether a transaction should be processed in `CheckTx` or `DeliverTx` mode. -- **Min Gas Price:** The minimum [gas](../basics/accounts-fees-gas.md) price a node is willing to take in order to include a transaction in its block. This price is a local value configured by each node individually. +- **Min Gas Price:** The minimum [gas](../basics/gas-fees.md) price a node is willing to take in order to include a transaction in its block. This price is a local value configured by each node individually. - **Consensus Params:** The ABCI type [Consensus Parameters](https://tendermint.com/docs/spec/abci/apps.html#consensus-parameters), which enforce certain limits for the blockchain, such as maximum gas for a block. - **Event Manager:** The event manager allows any caller with access to a `Context` to emit [`Events`](https://github.com/cosmos/cosmos-sdk/blob/master/types/events.go). Modules may define module specific `Events` by defining various `Types` and `Attributes` or use the common definitions found in `types/`. Clients diff --git a/docs/core/node.md b/docs/core/node.md index 7c8102062de7..812eec3ac062 100644 --- a/docs/core/node.md +++ b/docs/core/node.md @@ -35,9 +35,9 @@ The `start` command is defined in the `/server` folder of the Cosmos SDK. It is appd start ``` -As a reminder, the full-node is composed of three conceptual layers: the networking layer, the consensus layer and the application layer. The first two are generally bundled together in an entity called the consensus engine, while the third is the state-machine defined with the help of the Cosmos SDK. Currently, the Cosmos SDK uses Tendermint as the default consensus engine, meaning the start command is implemented to boot up a Tendermint node. +As a reminder, the full-node is composed of three conceptual layers: the networking layer, the consensus layer and the application layer. The first two are generally bundled together in an entity called the consensus engine (Tendermint Core by default), while the third is the state-machine defined with the help of the Cosmos SDK. Currently, the Cosmos SDK uses Tendermint as the default consensus engine, meaning the start command is implemented to boot up a Tendermint node. -The flow of the `start` command is pretty straightforward. First, it retrieves the `config` from the `context` in order to open the `db`. This `db` contains the latest known state of the application (empty if the application is started from the first time). +The flow of the `start` command is pretty straightforward. First, it retrieves the `config` from the `context` in order to open the `db` (a [`leveldb`](https://github.com/syndtr/goleveldb) instance by default). This `db` contains the latest known state of the application (empty if the application is started from the first time. With the `db`, the `start` command creates a new instance of the application using the [application's constructor function](../basics/app-anatomy.md#constructor-function). diff --git a/docs/core/store.md b/docs/core/store.md index 3d68c40cf5a6..86c59322d7a8 100644 --- a/docs/core/store.md +++ b/docs/core/store.md @@ -374,7 +374,7 @@ This is the type used whenever an IAVL Store needs to be cache-wrapped (typicall ### `GasKv` Store -Cosmos SDK applications use [`gas`](../basics/accounts-fees-gas.md#fees-and-gas) to track resources usage and prevent spam. [`GasKv.Store`](https://github.com/cosmos/cosmos-sdk/blob/master/store/gaskv/store.go) is a `KVStore` wrapper that enables automatic gas consumption each time a read or write to the store is made. It is the solution of choice to track storage usage in Cosmos SDK applications. +Cosmos SDK applications use [`gas`](../basics/gas-fees.md) to track resources usage and prevent spam. [`GasKv.Store`](https://github.com/cosmos/cosmos-sdk/blob/master/store/gaskv/store.go) is a `KVStore` wrapper that enables automatic gas consumption each time a read or write to the store is made. It is the solution of choice to track storage usage in Cosmos SDK applications. ```go type Store struct { diff --git a/docs/interfaces/cli.md b/docs/interfaces/cli.md index ed15192968c5..4faa59cbc62a 100644 --- a/docs/interfaces/cli.md +++ b/docs/interfaces/cli.md @@ -242,8 +242,8 @@ appcli tx send 1000uatom --from --gas auto -g Here are the flags used: -* `--from` indicates which [account](../core/accounts-fees.md) the transaction originates from. This account is used to sign the transaction. -* `--gas` refers to how much [gas](../core/gas.md), which represents computational resources, Tx consumes. Gas is dependent on the computational needs of the transaction and is not precisely calculated until execution, but can be estimated by providing auto as the value for --gas. +* `--from` indicates which [account](../basics/accounts.md) the transaction originates from. This account is used to sign the transaction. +* `--gas` refers to how much [gas](../basics/gas-fees.md), which represents computational resources, Tx consumes. Gas is dependent on the computational needs of the transaction and is not precisely calculated until execution, but can be estimated by providing auto as the value for --gas. * `--gas-prices` specifies how much the user is willing pay per unit of gas, which can be one or multiple denominations of tokens. For example, --gas-prices=0.025uatom, 0.025upho means the user is willing to pay 0.025uatom AND 0.025upho per unit of gas. * `--generate-only` (optional) instructs the application to simply generate the unsigned transaction and output or write to a file. Without this flag, the transaction is created, signed, and broadcasted all in one command. diff --git a/docs/interfaces/query-lifecycle.md b/docs/interfaces/query-lifecycle.md index efbeadc81be3..6ccd612476a2 100644 --- a/docs/interfaces/query-lifecycle.md +++ b/docs/interfaces/query-lifecycle.md @@ -65,7 +65,7 @@ The first thing that is created in the execution of a CLI command is a `CLIConte * **Codec**: The [encoder/decoder](,./core/encoding.md) used by the application, used to marshal the parameters and query before making the Tendermint RPC request and unmarshal the returned response into a JSON object. * **Account Decoder**: The account decoder from the [`auth`](.../spec/auth) module, which translates `[]byte`s into accounts. * **RPC Client**: The [Tendermint RPC Client](https://github.com/tendermint/tendermint/blob/bc572217c07b90ad9cee851f193aaa8e9557cbc7/rpc/client/interface.go), or node, to which the request will be relayed to. -* **Keybase**: A [Key Manager](.//core/accounts-keys.md) used to sign transactions and handle other operations with keys. +* **Keybase**: A [Key Manager](../basics/accounts.md#keybase) used to sign transactions and handle other operations with keys. * **Output Writer**: A [Writer](https://golang.org/pkg/io/#Writer) used to output the response. * **Configurations**: The flags configured by the user for this command, including `--height`, specifying the height of the blockchain to query and `--indent`, which indicates to add an indent to the JSON response. @@ -80,7 +80,7 @@ At this point in the lifecycle, the user has created a CLI command or HTTP Reque #### Parse Arguments -In this case, `Query` contains an [address](../core/accounts-fees.md) `delegatorAddress` as its only argument. However, the request can only contain `[]byte`s, as it will be relayed to a consensus engine (e.g. Tendermint Core) of a full-node that has no inherent knowledge of the application types. Thus, the `codec` of `CLIContext` is used to marshal the address as the type [`QueryDelegatorParams`](https://github.com/cosmos/cosmos-sdk/blob/master/x/staking/types/querier.go#L30-L38). All query arguments have their own types that the application `codec` understands how to encode and decode. For example, the [`staking`](https://github.com/cosmos/cosmos-sdk/blob/master/docs/spec/staking) module also has [`QueryValidatorParams`](https://github.com/cosmos/cosmos-sdk/blob/master/x/staking/types/querier.go#L45-L53) and [`QueryBondsParams`](https://github.com/cosmos/cosmos-sdk/blob/master/x/staking/types/querier.go#L59-L69). The module [`querier`](.//building-modules/querier.md) declares these types and the application registers the `codec`s. +In this case, `Query` contains an [address](../basics/accounts.m#addresses) `delegatorAddress` as its only argument. However, the request can only contain `[]byte`s, as it will be relayed to a consensus engine (e.g. Tendermint Core) of a full-node that has no inherent knowledge of the application types. Thus, the `codec` of `CLIContext` is used to marshal the address as the type [`QueryDelegatorParams`](https://github.com/cosmos/cosmos-sdk/blob/master/x/staking/types/querier.go#L30-L38). All query arguments have their own types that the application `codec` understands how to encode and decode. For example, the [`staking`](https://github.com/cosmos/cosmos-sdk/blob/master/docs/spec/staking) module also has [`QueryValidatorParams`](https://github.com/cosmos/cosmos-sdk/blob/master/x/staking/types/querier.go#L45-L53) and [`QueryBondsParams`](https://github.com/cosmos/cosmos-sdk/blob/master/x/staking/types/querier.go#L59-L69). The module [`querier`](.//building-modules/querier.md) declares these types and the application registers the `codec`s. Here is what the code looks like for the CLI command: diff --git a/docs/interfaces/rest.md b/docs/interfaces/rest.md index 2b0e3ba2b633..298758377143 100644 --- a/docs/interfaces/rest.md +++ b/docs/interfaces/rest.md @@ -34,7 +34,7 @@ A REST Server is used to receive and route HTTP Requests, obtain the results fro * **Router:** A router for HTTP requests. A new router can be instantiated for an application and used to match routes based on path, request method, headers, etc. The SDK uses the [Gorilla Mux Router](https://github.com/gorilla/mux). * **CLIContext:** A [`CLIContext`](./query-lifecycle.md#clicontext) created for a user interaction. -* **Keybase:** A [Keybase](../core/keys-accounts.md) is a key manager. +* **Keybase:** A [Keybase](../basics/accounts.md#keybase) is a key manager. * **Logger:** A logger from Tendermint `Log`, a log package structured around key-value pairs that allows logging level to be set differently for different keys. The logger takes `Debug()`, `Info()`, and `Error()`s. * **Listener:** A [listener](https://golang.org/pkg/net/#Listener) from the net package. From 1cc5c19222e761e8a17ab736bd08128eb4b863f6 Mon Sep 17 00:00:00 2001 From: gamarin Date: Wed, 23 Oct 2019 12:22:02 +0200 Subject: [PATCH 127/196] add more permalinks --- docs/basics/app-anatomy.md | 4 ++-- docs/building-modules/handler.md | 2 +- docs/building-modules/messages-and-queries.md | 2 +- docs/building-modules/querier.md | 2 +- docs/interfaces/cli.md | 2 +- 5 files changed, 6 insertions(+), 6 deletions(-) diff --git a/docs/basics/app-anatomy.md b/docs/basics/app-anatomy.md index dba3e1bd7454..acd01e5b6112 100644 --- a/docs/basics/app-anatomy.md +++ b/docs/basics/app-anatomy.md @@ -193,7 +193,7 @@ To learn more about `keepers`, [click here](../building-modules/keeper.md). The `Querier` of a module is defined in a file called `querier.go`, and consists of: -- A **switch function** `NewQuerier` to route the query to the appropriate `querier` function. This function returns a `querier` function, and is is registered in the [`AppModule`](#application-module-interface) to be used in the application's module manager to initialize the [application's query router](../core/baseapp.md#query-routing). See an example of such a switch [here](https://github.com/cosmos/sdk-application-tutorial/blob/master/x/nameservice/querier.go#L21-L34). +- A **switch function** `NewQuerier` to route the query to the appropriate `querier` function. This function returns a `querier` function, and is is registered in the [`AppModule`](#application-module-interface) to be used in the application's module manager to initialize the [application's query router](../core/baseapp.md#query-routing). See an example of such a switch [here](https://github.com/cosmos/sdk-application-tutorial/blob/c6754a1e313eb1ed973c5c91dcc606f2fd288811/x/nameservice/internal/keeper/querier.go#L19-L32). - - **One querier function for each data type defined by the module that needs to be queryable**. Developers write the query processing logic in these functions. This generally involves calling [`keeper`](#keeper)'s methods to query the state and marshalling it to JSON. To learn more about `queriers`, [click here](../building-modules/querier.md). @@ -232,7 +232,7 @@ The main interface is the [Command-Line Interface](../interfaces/cli.md). The CL - **Transaction commands** are added by calling the `txCmd` function. Similar to `queryCmd`, the function returns a Cobra command that contains the tx commands defined in each of the application's modules, as well as lower level tx commands like transaction signing or broadcasting. Tx commands are called by using the command `appcli tx [tx]` of the CLI. - **A `registerRoutes` function**, which is called from the `main()` function when initializing the [application's light-client daemon (LCD)](../core/node.md#lcd) (i.e. `rest-server`). `registerRoutes` calls the `RegisterRoutes` function of each of the application's module, thereby registering the routes of the module to the lcd's router. The LCD can be started by running the following command `appcli rest-server`. -See an example of an application's main command-line file [here](https://github.com/cosmos/sdk-application-tutorial/blob/master/cmd/nscli/main.go). +See an example of an application's main command-line file [here](https://github.com/cosmos/sdk-application-tutorial/blob/c6754a1e313eb1ed973c5c91dcc606f2fd288811/cmd/nscli/main.go). To learn more about interfaces, [click here](../interfaces/intro.md). diff --git a/docs/building-modules/handler.md b/docs/building-modules/handler.md index afdb0d48f875..760f3a137b91 100644 --- a/docs/building-modules/handler.md +++ b/docs/building-modules/handler.md @@ -75,7 +75,7 @@ return sdk.Result{ } ``` -For a deeper look at `handler`s, see this [example implementation of a `handler` function](https://github.com/cosmos/sdk-application-tutorial/blob/master/x/nameservice/handler.go) from the nameservice tutorial. +For a deeper look at `handler`s, see this [example implementation of a `handler` function](https://github.com/cosmos/sdk-application-tutorial/blob/c6754a1e313eb1ed973c5c91dcc606f2fd288811/x/nameservice/handler.go) from the nameservice tutorial. ## Next diff --git a/docs/building-modules/messages-and-queries.md b/docs/building-modules/messages-and-queries.md index 7ebfaf2c76dd..0bea947e2bb8 100644 --- a/docs/building-modules/messages-and-queries.md +++ b/docs/building-modules/messages-and-queries.md @@ -60,7 +60,7 @@ The `path` for each `query` must be defined by the module developer in the modul - A [`querier`](./querier.md), to process the `query` once it has been [routed to the module](../core/baseapp.md#query-routing). - [Query commands](./module-interfaces.md#query-commands) in the module's CLI file, where the `path` for each `query` is specified. -- `query` return types. Typically defined in a file `internal/types/querier.go`, they specify the result type of each of the module's `queries`. These custom types must implement the `String()` method of [`fmt.Stringer`](https://golang.org/pkg/fmt/#Stringer). See an example of `query` return types from the [nameservice tutorial](https://github.com/cosmos/sdk-application-tutorial/blob/master/x/nameservice/internal/types/querier.go). +- `query` return types. Typically defined in a file `internal/types/querier.go`, they specify the result type of each of the module's `queries`. These custom types must implement the `String()` method of [`fmt.Stringer`](https://golang.org/pkg/fmt/#Stringer). See an example of `query` return types from the [nameservice tutorial](https://github.com/cosmos/sdk-application-tutorial/blob/c6754a1e313eb1ed973c5c91dcc606f2fd288811/x/nameservice/internal/types/querier.go). ## Next diff --git a/docs/building-modules/querier.md b/docs/building-modules/querier.md index 15e03b1a2666..ea6cfba984e1 100644 --- a/docs/building-modules/querier.md +++ b/docs/building-modules/querier.md @@ -50,7 +50,7 @@ This simple switch returns a `querier` function specific to the type of the rece The `querier` functions themselves are pretty straighforward. They generally fetch a value or values from the state using the [`keeper`](./keeper.md). Then, they marshall the value(s) using the [`codec`](../core/encoding.md) and return the `[]byte` obtained as result. -For a deeper look at `querier`s, see this [example implementation of a `querier` function](https://github.com/cosmos/sdk-application-tutorial/blob/master/x/nameservice/querier.go) from the nameservice tutorial. +For a deeper look at `querier`s, see this [example implementation of a `querier` function](https://github.com/cosmos/sdk-application-tutorial/blob/c6754a1e313eb1ed973c5c91dcc606f2fd288811/x/nameservice/internal/keeper/querier.go) from the nameservice tutorial. ## Next diff --git a/docs/interfaces/cli.md b/docs/interfaces/cli.md index 4faa59cbc62a..6141f3ea8a29 100644 --- a/docs/interfaces/cli.md +++ b/docs/interfaces/cli.md @@ -40,7 +40,7 @@ The `main.go` file needs to have a `main()` function that does the following to * **Add subcommands** for all the possible user interactions, including [transaction commands](#transaction-commands) and [query commands](#query-commands). * **Create an Executor** and [execute](https://godoc.org/github.com/spf13/cobra#Command.Execute) the root command. -An example of the `main()` function for the [nameservice tutorial](https://cosmos.network/docs/tutorial) CLI can be found [here](https://github.com/cosmos/sdk-application-tutorial/blob/master/cmd/nscli/main.go#L26-L67). The rest of the document will detail what needs to be implemented for each step and include smaller portions of code from the nameservice CLI `main.go` file. +An example of the `main()` function for the [nameservice tutorial](https://cosmos.network/docs/tutorial) CLI can be found [here](https://github.com/cosmos/sdk-application-tutorial/blob/c6754a1e313eb1ed973c5c91dcc606f2fd288811/cmd/nscli/main.go#L26-L67). The rest of the document will detail what needs to be implemented for each step and include smaller portions of code from the nameservice CLI `main.go` file. ## Commands From 0d4e30c116d7ddad8cf89ae01f900122f09e4be7 Mon Sep 17 00:00:00 2001 From: Denis Fadeev Date: Thu, 24 Oct 2019 21:36:07 +0500 Subject: [PATCH 128/196] update docs theme version (#5239) --- docs/.vuepress/components/PageHistory.vue | 18 - docs/.vuepress/config.js | 203 +- docs/.vuepress/enhanceApp.js | 8 - docs/.vuepress/public/logo-bw.svg | 8 + docs/.vuepress/public/logo.svg | 18 + docs/.vuepress/styles/index.styl | 3 + docs/_architecture/readme.md | 5 + docs/architecture/README.MD | 6 + docs/basics/readme.md | 6 + docs/building-modules/README.md | 7 +- docs/cn/README.md | 5 + docs/concepts/readme.md | 5 + docs/core/readme.md | 5 + docs/interfaces/readme.md | 5 + docs/intro/readme.md | 6 + docs/kr/README.md | 5 + docs/modules/readme.md | 5 + docs/package-lock.json | 4411 ++++++------- docs/package.json | 16 +- docs/post.sh | 7 + docs/pre.sh | 10 + docs/ru/readme.md | 7 +- docs/spec/README.md | 5 + docs/yarn.lock | 7285 --------------------- 24 files changed, 2238 insertions(+), 9821 deletions(-) delete mode 100644 docs/.vuepress/components/PageHistory.vue delete mode 100644 docs/.vuepress/enhanceApp.js create mode 100644 docs/.vuepress/public/logo-bw.svg create mode 100644 docs/.vuepress/public/logo.svg create mode 100644 docs/.vuepress/styles/index.styl create mode 100644 docs/_architecture/readme.md create mode 100644 docs/basics/readme.md create mode 100644 docs/concepts/readme.md create mode 100644 docs/core/readme.md create mode 100644 docs/interfaces/readme.md create mode 100644 docs/intro/readme.md create mode 100644 docs/modules/readme.md create mode 100755 docs/post.sh create mode 100755 docs/pre.sh delete mode 100644 docs/yarn.lock diff --git a/docs/.vuepress/components/PageHistory.vue b/docs/.vuepress/components/PageHistory.vue deleted file mode 100644 index 22f2a7bd50ce..000000000000 --- a/docs/.vuepress/components/PageHistory.vue +++ /dev/null @@ -1,18 +0,0 @@ - - - diff --git a/docs/.vuepress/config.js b/docs/.vuepress/config.js index 51592f1e9f8f..50273aefb9d3 100644 --- a/docs/.vuepress/config.js +++ b/docs/.vuepress/config.js @@ -1,95 +1,130 @@ -const glob = require("glob"); -const markdownIt = require("markdown-it"); -const meta = require("markdown-it-meta"); -const fs = require("fs"); -const _ = require("lodash"); - -const sidebar = (directory, array) => { - return array.map(i => { - const children = _.sortBy( - glob - .sync(`./${directory}/${i[1]}/*.md`) - .map(path => { - const md = new markdownIt(); - const file = fs.readFileSync(path, "utf8"); - md.use(meta); - md.render(file); - const order = md.meta.order; - return { path, order }; - }) - .filter(f => f.order !== false), - ["order", "path"] - ) - .map(f => f.path) - .filter(f => !f.match("readme")); - return { - title: i[0], - children - }; - }); -}; - module.exports = { + theme: "cosmos", title: "Cosmos SDK", - base: process.env.VUEPRESS_BASE || "/", - locales: { - "/": { - lang: "en-US" - }, - "/ru/": { - lang: "ru" - }, + markdown: { + anchor: { + permalinkSymbol: "" + } }, + base: process.env.VUEPRESS_BASE || "/", themeConfig: { repo: "cosmos/cosmos-sdk", docsDir: "docs", editLinks: true, - docsBranch: "master", - locales: { - "/": { - label: "English", - sidebar: sidebar("", [ - ["Intro", "intro"], - ["Basics", "basics"], - ["SDK Core", "core"], - ["About Modules", "modules"], - ["Using the SDK", "sdk"], - ["Interfaces", "interfaces"] - ]) - }, - "/ru/": { - label: "Русский", - sidebar: sidebar("ru", [ - ["Введение", "intro"], - ["Основы", "basics"], - ["SDK Core", "core"], - ["Модули", "modules"], - ["Используем SDK", "sdk"], - ["Интерфейсы", "interfaces"] - ]) - }, - '/kr/': { - label: '한국어', - sidebar: sidebar('kr', [ - ['소개', 'intro'], - ['기초', 'basics'], - ['SDK Core', 'core'], - ['모듈들', 'modules'], - ['프로그램 사용', 'sdk'], - ['인터페이스', 'interfaces'], - ]), - }, - '/cn/': { - label: '中文', - sidebar: sidebar('cn', [ - ['介绍', 'intro'], - ['基本', 'basics'], - ['SDK Core', 'core'], - ['模块', 'modules'], - ['使用该程序', 'sdk'], - ['接口', 'interfaces'], - ]), + logo: "/logo.svg", + label: "sdk", + sidebar: [ + { + title: "Resources", + children: [ + { + title: "Modules", + directory: true, + path: "/modules/" + }, + { + title: "Tutorials", + path: "https://github.com/cosmos/sdk-application-tutorial" + } + ] + } + ], + gutter: { + title: "Help & Support", + editLink: true, + children: [ + { + title: "Riot Chat", + text: "Chat with Tendermint developers on Riot Chat.", + highlighted: "500+ people chatting now" + }, + { + title: "Cosmos SDK Forum", + text: "Found an Issue?", + highlighted: + "Help us improve this page by suggesting edits on GitHub." + } + ] + }, + footer: { + logo: "/logo-bw.svg", + textLink: { + text: "cosmos.network", + url: "https://cosmos.network" }, + services: [ + { + service: "medium", + url: "https://blog.cosmos.network/" + }, + { + service: "twitter", + url: "https://twitter.com/cosmos" + }, + { + service: "linkedin", + url: "https://www.linkedin.com/company/tendermint/" + }, + { + service: "reddit", + url: "https://reddit.com/r/cosmosnetwork" + }, + { + service: "telegram", + url: "https://t.me/cosmosproject" + }, + { + service: "youtube", + url: "https://www.youtube.com/c/CosmosProject" + } + ], + smallprint: + "The development of the Cosmos project is led primarily by Tendermint Inc., the for-profit entity which also maintains this website. Funding for this development comes primarily from the Interchain Foundation, a Swiss non-profit.", + links: [ + { + title: "Documentation", + children: [ + { + title: "Cosmos SDK", + url: "https://cosmos.network/docs" + }, + { + title: "Cosmos Hub", + url: "https://hub.cosmos.network/" + } + ] + }, + { + title: "Community", + children: [ + { + title: "Cosmos blog", + url: "https://blog.cosmos.network/" + }, + { + title: "Forum", + url: "https://forum.cosmos.network/" + }, + { + title: "Chat", + url: "https://riot.im/app/#/room/#cosmos-sdk:matrix.org" + } + ] + }, + { + title: "Contributing", + children: [ + { + title: "Contributing to the docs", + url: "https://github.com/cosmos/cosmos-sdk/tree/master/docs" + }, + { + title: "Source code on GitHub", + url: "https://github.com/cosmos/cosmos-sdk/" + } + ] + } + ] } } }; diff --git a/docs/.vuepress/enhanceApp.js b/docs/.vuepress/enhanceApp.js deleted file mode 100644 index 6deeedeb0558..000000000000 --- a/docs/.vuepress/enhanceApp.js +++ /dev/null @@ -1,8 +0,0 @@ -import axios from 'axios' -import Vue from 'vue' - -Vue.use({ - install (Vue) { - Vue.prototype.$axios = axios.create() - } -}) \ No newline at end of file diff --git a/docs/.vuepress/public/logo-bw.svg b/docs/.vuepress/public/logo-bw.svg new file mode 100644 index 000000000000..e0dfe74053e2 --- /dev/null +++ b/docs/.vuepress/public/logo-bw.svg @@ -0,0 +1,8 @@ + + + + + + + + diff --git a/docs/.vuepress/public/logo.svg b/docs/.vuepress/public/logo.svg new file mode 100644 index 000000000000..9e8a005bd9c3 --- /dev/null +++ b/docs/.vuepress/public/logo.svg @@ -0,0 +1,18 @@ + + + + + + + + + + + + + + + + + + diff --git a/docs/.vuepress/styles/index.styl b/docs/.vuepress/styles/index.styl new file mode 100644 index 000000000000..66affa704b7b --- /dev/null +++ b/docs/.vuepress/styles/index.styl @@ -0,0 +1,3 @@ +:root + --accent-color #5064fb + --background #161931 \ No newline at end of file diff --git a/docs/_architecture/readme.md b/docs/_architecture/readme.md new file mode 100644 index 000000000000..f0c07cb68565 --- /dev/null +++ b/docs/_architecture/readme.md @@ -0,0 +1,5 @@ +--- +order: false +parent: + order: false +--- diff --git a/docs/architecture/README.MD b/docs/architecture/README.MD index d60980478252..1cc260211963 100644 --- a/docs/architecture/README.MD +++ b/docs/architecture/README.MD @@ -1,3 +1,9 @@ +--- +order: false +parent: + order: false +--- + # Architecture Decision Records (ADR) This is a location to record all high-level architecture decisions in the Cosmos-SDK. diff --git a/docs/basics/readme.md b/docs/basics/readme.md new file mode 100644 index 000000000000..1d13db5d1f5b --- /dev/null +++ b/docs/basics/readme.md @@ -0,0 +1,6 @@ +--- +order: false +parent: + order: 2 + title: Basics +--- diff --git a/docs/building-modules/README.md b/docs/building-modules/README.md index 5b5743671751..908825572708 100644 --- a/docs/building-modules/README.md +++ b/docs/building-modules/README.md @@ -1,4 +1,9 @@ -# Auth +--- +parent: + title: Building modules +--- + +# Auth The `x/auth` modules is used for accounts diff --git a/docs/cn/README.md b/docs/cn/README.md index e3bd9ce98876..bbd14a3109f3 100644 --- a/docs/cn/README.md +++ b/docs/cn/README.md @@ -1,3 +1,8 @@ +--- +parent: + order: false +--- + # Cosmos SDK 文档 ## 开始 diff --git a/docs/concepts/readme.md b/docs/concepts/readme.md new file mode 100644 index 000000000000..67a1891d2af6 --- /dev/null +++ b/docs/concepts/readme.md @@ -0,0 +1,5 @@ +--- +order: false +parent: + title: Concepts +--- diff --git a/docs/core/readme.md b/docs/core/readme.md new file mode 100644 index 000000000000..651ae8d4e000 --- /dev/null +++ b/docs/core/readme.md @@ -0,0 +1,5 @@ +--- +order: false +parent: + title: Core +--- diff --git a/docs/interfaces/readme.md b/docs/interfaces/readme.md new file mode 100644 index 000000000000..22828fd0f070 --- /dev/null +++ b/docs/interfaces/readme.md @@ -0,0 +1,5 @@ +--- +order: false +parent: + title: Interfaces +--- diff --git a/docs/intro/readme.md b/docs/intro/readme.md new file mode 100644 index 000000000000..7d93bf5f6f76 --- /dev/null +++ b/docs/intro/readme.md @@ -0,0 +1,6 @@ +--- +order: false +parent: + title: Introduction + order: 1 +--- diff --git a/docs/kr/README.md b/docs/kr/README.md index 5ac84b1455ee..86c60314bd7a 100755 --- a/docs/kr/README.md +++ b/docs/kr/README.md @@ -1,3 +1,8 @@ +--- +parent: + order: false +--- + # 코스모스 SDK 문서에 오신 걸 환영합니다! ::: warning diff --git a/docs/modules/readme.md b/docs/modules/readme.md new file mode 100644 index 000000000000..f0c07cb68565 --- /dev/null +++ b/docs/modules/readme.md @@ -0,0 +1,5 @@ +--- +order: false +parent: + order: false +--- diff --git a/docs/package-lock.json b/docs/package-lock.json index d9250fe97e81..35e058c30c62 100644 --- a/docs/package-lock.json +++ b/docs/package-lock.json @@ -5,54 +5,84 @@ "requires": true, "dependencies": { "@babel/code-frame": { - "version": "7.0.0", - "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.0.0.tgz", - "integrity": "sha512-OfC2uemaknXr87bdLUkWog7nYuliM9Ij5HUcajsVcMCpQrcLmtxRbVFTIqmcSkSeYRBFBRxs2FiUqFJDLdiebA==", - "dev": true, + "version": "7.5.5", + "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.5.5.tgz", + "integrity": "sha512-27d4lZoomVyo51VegxI20xZPuSHusqbQag/ztrBC7wegWoQ1nLREPVSKSW8byhTlzTKyNE4ifaTA6lCp7JjpFw==", "requires": { "@babel/highlight": "^7.0.0" } }, "@babel/core": { - "version": "7.4.5", - "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.4.5.tgz", - "integrity": "sha512-OvjIh6aqXtlsA8ujtGKfC7LYWksYSX8yQcM8Ay3LuvVeQ63lcOKgoZWVqcpFwkd29aYU9rVx7jxhfhiEDV9MZA==", - "dev": true, - "requires": { - "@babel/code-frame": "^7.0.0", - "@babel/generator": "^7.4.4", - "@babel/helpers": "^7.4.4", - "@babel/parser": "^7.4.5", - "@babel/template": "^7.4.4", - "@babel/traverse": "^7.4.5", - "@babel/types": "^7.4.4", + "version": "7.6.4", + "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.6.4.tgz", + "integrity": "sha512-Rm0HGw101GY8FTzpWSyRbki/jzq+/PkNQJ+nSulrdY6gFGOsNseCqD6KHRYe2E+EdzuBdr2pxCp6s4Uk6eJ+XQ==", + "requires": { + "@babel/code-frame": "^7.5.5", + "@babel/generator": "^7.6.4", + "@babel/helpers": "^7.6.2", + "@babel/parser": "^7.6.4", + "@babel/template": "^7.6.0", + "@babel/traverse": "^7.6.3", + "@babel/types": "^7.6.3", "convert-source-map": "^1.1.0", "debug": "^4.1.0", "json5": "^2.1.0", - "lodash": "^4.17.11", + "lodash": "^4.17.13", "resolve": "^1.3.2", "semver": "^5.4.1", "source-map": "^0.5.0" + }, + "dependencies": { + "debug": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.1.1.tgz", + "integrity": "sha512-pYAIzeRo8J6KPEaJ0VWOh5Pzkbw/RetuzehGM7QRRX5he4fPHx2rdKMB256ehJCkX+XRQm16eZLqLNS8RSZXZw==", + "requires": { + "ms": "^2.1.1" + } + }, + "json5": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/json5/-/json5-2.1.1.tgz", + "integrity": "sha512-l+3HXD0GEI3huGq1njuqtzYK8OYJyXMkOLtQ53pjWh89tvWS2h6l+1zMkYWqlb57+SiQodKZyvMEFb2X+KrFhQ==", + "requires": { + "minimist": "^1.2.0" + } + }, + "ms": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", + "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==" + }, + "source-map": { + "version": "0.5.7", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz", + "integrity": "sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w=" + } } }, "@babel/generator": { - "version": "7.4.4", - "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.4.4.tgz", - "integrity": "sha512-53UOLK6TVNqKxf7RUh8NE851EHRxOOeVXKbK2bivdb+iziMyk03Sr4eaE9OELCbyZAAafAKPDwF2TPUES5QbxQ==", - "dev": true, + "version": "7.6.4", + "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.6.4.tgz", + "integrity": "sha512-jsBuXkFoZxk0yWLyGI9llT9oiQ2FeTASmRFE32U+aaDTfoE92t78eroO7PTpU/OrYq38hlcDM6vbfLDaOLy+7w==", "requires": { - "@babel/types": "^7.4.4", + "@babel/types": "^7.6.3", "jsesc": "^2.5.1", - "lodash": "^4.17.11", - "source-map": "^0.5.0", - "trim-right": "^1.0.1" + "lodash": "^4.17.13", + "source-map": "^0.5.0" + }, + "dependencies": { + "source-map": { + "version": "0.5.7", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz", + "integrity": "sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w=" + } } }, "@babel/helper-annotate-as-pure": { "version": "7.0.0", "resolved": "https://registry.npmjs.org/@babel/helper-annotate-as-pure/-/helper-annotate-as-pure-7.0.0.tgz", "integrity": "sha512-3UYcJUj9kvSLbLbUIfQTqzcy5VX7GRZ/CCDrnOaZorFFM01aXp1+GJwuFGV4NDDoAS+mOUyHcO6UD/RfqOks3Q==", - "dev": true, "requires": { "@babel/types": "^7.0.0" } @@ -61,7 +91,6 @@ "version": "7.1.0", "resolved": "https://registry.npmjs.org/@babel/helper-builder-binary-assignment-operator-visitor/-/helper-builder-binary-assignment-operator-visitor-7.1.0.tgz", "integrity": "sha512-qNSR4jrmJ8M1VMM9tibvyRAHXQs2PmaksQF7c1CGJNipfe3D8p+wgNwgso/P2A2r2mdgBWAXljNWR0QRZAMW8w==", - "dev": true, "requires": { "@babel/helper-explode-assignable-expression": "^7.1.0", "@babel/types": "^7.0.0" @@ -71,7 +100,6 @@ "version": "7.4.4", "resolved": "https://registry.npmjs.org/@babel/helper-call-delegate/-/helper-call-delegate-7.4.4.tgz", "integrity": "sha512-l79boDFJ8S1c5hvQvG+rc+wHw6IuH7YldmRKsYtpbawsxURu/paVy57FZMomGK22/JckepaikOkY0MoAmdyOlQ==", - "dev": true, "requires": { "@babel/helper-hoist-variables": "^7.4.4", "@babel/traverse": "^7.4.4", @@ -79,35 +107,32 @@ } }, "@babel/helper-create-class-features-plugin": { - "version": "7.4.4", - "resolved": "https://registry.npmjs.org/@babel/helper-create-class-features-plugin/-/helper-create-class-features-plugin-7.4.4.tgz", - "integrity": "sha512-UbBHIa2qeAGgyiNR9RszVF7bUHEdgS4JAUNT8SiqrAN6YJVxlOxeLr5pBzb5kan302dejJ9nla4RyKcR1XT6XA==", - "dev": true, + "version": "7.6.0", + "resolved": "https://registry.npmjs.org/@babel/helper-create-class-features-plugin/-/helper-create-class-features-plugin-7.6.0.tgz", + "integrity": "sha512-O1QWBko4fzGju6VoVvrZg0RROCVifcLxiApnGP3OWfWzvxRZFCoBD81K5ur5e3bVY2Vf/5rIJm8cqPKn8HUJng==", "requires": { "@babel/helper-function-name": "^7.1.0", - "@babel/helper-member-expression-to-functions": "^7.0.0", + "@babel/helper-member-expression-to-functions": "^7.5.5", "@babel/helper-optimise-call-expression": "^7.0.0", "@babel/helper-plugin-utils": "^7.0.0", - "@babel/helper-replace-supers": "^7.4.4", + "@babel/helper-replace-supers": "^7.5.5", "@babel/helper-split-export-declaration": "^7.4.4" } }, "@babel/helper-define-map": { - "version": "7.4.4", - "resolved": "https://registry.npmjs.org/@babel/helper-define-map/-/helper-define-map-7.4.4.tgz", - "integrity": "sha512-IX3Ln8gLhZpSuqHJSnTNBWGDE9kdkTEWl21A/K7PQ00tseBwbqCHTvNLHSBd9M0R5rER4h5Rsvj9vw0R5SieBg==", - "dev": true, + "version": "7.5.5", + "resolved": "https://registry.npmjs.org/@babel/helper-define-map/-/helper-define-map-7.5.5.tgz", + "integrity": "sha512-fTfxx7i0B5NJqvUOBBGREnrqbTxRh7zinBANpZXAVDlsZxYdclDp467G1sQ8VZYMnAURY3RpBUAgOYT9GfzHBg==", "requires": { "@babel/helper-function-name": "^7.1.0", - "@babel/types": "^7.4.4", - "lodash": "^4.17.11" + "@babel/types": "^7.5.5", + "lodash": "^4.17.13" } }, "@babel/helper-explode-assignable-expression": { "version": "7.1.0", "resolved": "https://registry.npmjs.org/@babel/helper-explode-assignable-expression/-/helper-explode-assignable-expression-7.1.0.tgz", "integrity": "sha512-NRQpfHrJ1msCHtKjbzs9YcMmJZOg6mQMmGRB+hbamEdG5PNpaSm95275VD92DvJKuyl0s2sFiDmMZ+EnnvufqA==", - "dev": true, "requires": { "@babel/traverse": "^7.1.0", "@babel/types": "^7.0.0" @@ -117,7 +142,6 @@ "version": "7.1.0", "resolved": "https://registry.npmjs.org/@babel/helper-function-name/-/helper-function-name-7.1.0.tgz", "integrity": "sha512-A95XEoCpb3TO+KZzJ4S/5uW5fNe26DjBGqf1o9ucyLyCmi1dXq/B3c8iaWTfBk3VvetUxl16e8tIrd5teOCfGw==", - "dev": true, "requires": { "@babel/helper-get-function-arity": "^7.0.0", "@babel/template": "^7.1.0", @@ -128,7 +152,6 @@ "version": "7.0.0", "resolved": "https://registry.npmjs.org/@babel/helper-get-function-arity/-/helper-get-function-arity-7.0.0.tgz", "integrity": "sha512-r2DbJeg4svYvt3HOS74U4eWKsUAMRH01Z1ds1zx8KNTPtpTL5JAsdFv8BNyOpVqdFhHkkRDIg5B4AsxmkjAlmQ==", - "dev": true, "requires": { "@babel/types": "^7.0.0" } @@ -137,48 +160,43 @@ "version": "7.4.4", "resolved": "https://registry.npmjs.org/@babel/helper-hoist-variables/-/helper-hoist-variables-7.4.4.tgz", "integrity": "sha512-VYk2/H/BnYbZDDg39hr3t2kKyifAm1W6zHRfhx8jGjIHpQEBv9dry7oQ2f3+J703TLu69nYdxsovl0XYfcnK4w==", - "dev": true, "requires": { "@babel/types": "^7.4.4" } }, "@babel/helper-member-expression-to-functions": { - "version": "7.0.0", - "resolved": "https://registry.npmjs.org/@babel/helper-member-expression-to-functions/-/helper-member-expression-to-functions-7.0.0.tgz", - "integrity": "sha512-avo+lm/QmZlv27Zsi0xEor2fKcqWG56D5ae9dzklpIaY7cQMK5N8VSpaNVPPagiqmy7LrEjK1IWdGMOqPu5csg==", - "dev": true, + "version": "7.5.5", + "resolved": "https://registry.npmjs.org/@babel/helper-member-expression-to-functions/-/helper-member-expression-to-functions-7.5.5.tgz", + "integrity": "sha512-5qZ3D1uMclSNqYcXqiHoA0meVdv+xUEex9em2fqMnrk/scphGlGgg66zjMrPJESPwrFJ6sbfFQYUSa0Mz7FabA==", "requires": { - "@babel/types": "^7.0.0" + "@babel/types": "^7.5.5" } }, "@babel/helper-module-imports": { "version": "7.0.0", "resolved": "https://registry.npmjs.org/@babel/helper-module-imports/-/helper-module-imports-7.0.0.tgz", "integrity": "sha512-aP/hlLq01DWNEiDg4Jn23i+CXxW/owM4WpDLFUbpjxe4NS3BhLVZQ5i7E0ZrxuQ/vwekIeciyamgB1UIYxxM6A==", - "dev": true, "requires": { "@babel/types": "^7.0.0" } }, "@babel/helper-module-transforms": { - "version": "7.4.4", - "resolved": "https://registry.npmjs.org/@babel/helper-module-transforms/-/helper-module-transforms-7.4.4.tgz", - "integrity": "sha512-3Z1yp8TVQf+B4ynN7WoHPKS8EkdTbgAEy0nU0rs/1Kw4pDgmvYH3rz3aI11KgxKCba2cn7N+tqzV1mY2HMN96w==", - "dev": true, + "version": "7.5.5", + "resolved": "https://registry.npmjs.org/@babel/helper-module-transforms/-/helper-module-transforms-7.5.5.tgz", + "integrity": "sha512-jBeCvETKuJqeiaCdyaheF40aXnnU1+wkSiUs/IQg3tB85up1LyL8x77ClY8qJpuRJUcXQo+ZtdNESmZl4j56Pw==", "requires": { "@babel/helper-module-imports": "^7.0.0", "@babel/helper-simple-access": "^7.1.0", "@babel/helper-split-export-declaration": "^7.4.4", "@babel/template": "^7.4.4", - "@babel/types": "^7.4.4", - "lodash": "^4.17.11" + "@babel/types": "^7.5.5", + "lodash": "^4.17.13" } }, "@babel/helper-optimise-call-expression": { "version": "7.0.0", "resolved": "https://registry.npmjs.org/@babel/helper-optimise-call-expression/-/helper-optimise-call-expression-7.0.0.tgz", "integrity": "sha512-u8nd9NQePYNQV8iPWu/pLLYBqZBa4ZaY1YWRFMuxrid94wKI1QNt67NEZ7GAe5Kc/0LLScbim05xZFWkAdrj9g==", - "dev": true, "requires": { "@babel/types": "^7.0.0" } @@ -186,23 +204,20 @@ "@babel/helper-plugin-utils": { "version": "7.0.0", "resolved": "https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.0.0.tgz", - "integrity": "sha512-CYAOUCARwExnEixLdB6sDm2dIJ/YgEAKDM1MOeMeZu9Ld/bDgVo8aiWrXwcY7OBh+1Ea2uUcVRcxKk0GJvW7QA==", - "dev": true + "integrity": "sha512-CYAOUCARwExnEixLdB6sDm2dIJ/YgEAKDM1MOeMeZu9Ld/bDgVo8aiWrXwcY7OBh+1Ea2uUcVRcxKk0GJvW7QA==" }, "@babel/helper-regex": { - "version": "7.4.4", - "resolved": "https://registry.npmjs.org/@babel/helper-regex/-/helper-regex-7.4.4.tgz", - "integrity": "sha512-Y5nuB/kESmR3tKjU8Nkn1wMGEx1tjJX076HBMeL3XLQCu6vA/YRzuTW0bbb+qRnXvQGn+d6Rx953yffl8vEy7Q==", - "dev": true, + "version": "7.5.5", + "resolved": "https://registry.npmjs.org/@babel/helper-regex/-/helper-regex-7.5.5.tgz", + "integrity": "sha512-CkCYQLkfkiugbRDO8eZn6lRuR8kzZoGXCg3149iTk5se7g6qykSpy3+hELSwquhu+TgHn8nkLiBwHvNX8Hofcw==", "requires": { - "lodash": "^4.17.11" + "lodash": "^4.17.13" } }, "@babel/helper-remap-async-to-generator": { "version": "7.1.0", "resolved": "https://registry.npmjs.org/@babel/helper-remap-async-to-generator/-/helper-remap-async-to-generator-7.1.0.tgz", "integrity": "sha512-3fOK0L+Fdlg8S5al8u/hWE6vhufGSn0bN09xm2LXMy//REAF8kDCrYoOBKYmA8m5Nom+sV9LyLCwrFynA8/slg==", - "dev": true, "requires": { "@babel/helper-annotate-as-pure": "^7.0.0", "@babel/helper-wrap-function": "^7.1.0", @@ -212,22 +227,20 @@ } }, "@babel/helper-replace-supers": { - "version": "7.4.4", - "resolved": "https://registry.npmjs.org/@babel/helper-replace-supers/-/helper-replace-supers-7.4.4.tgz", - "integrity": "sha512-04xGEnd+s01nY1l15EuMS1rfKktNF+1CkKmHoErDppjAAZL+IUBZpzT748x262HF7fibaQPhbvWUl5HeSt1EXg==", - "dev": true, + "version": "7.5.5", + "resolved": "https://registry.npmjs.org/@babel/helper-replace-supers/-/helper-replace-supers-7.5.5.tgz", + "integrity": "sha512-XvRFWrNnlsow2u7jXDuH4jDDctkxbS7gXssrP4q2nUD606ukXHRvydj346wmNg+zAgpFx4MWf4+usfC93bElJg==", "requires": { - "@babel/helper-member-expression-to-functions": "^7.0.0", + "@babel/helper-member-expression-to-functions": "^7.5.5", "@babel/helper-optimise-call-expression": "^7.0.0", - "@babel/traverse": "^7.4.4", - "@babel/types": "^7.4.4" + "@babel/traverse": "^7.5.5", + "@babel/types": "^7.5.5" } }, "@babel/helper-simple-access": { "version": "7.1.0", "resolved": "https://registry.npmjs.org/@babel/helper-simple-access/-/helper-simple-access-7.1.0.tgz", "integrity": "sha512-Vk+78hNjRbsiu49zAPALxTb+JUQCz1aolpd8osOF16BGnLtseD21nbHgLPGUwrXEurZgiCOUmvs3ExTu4F5x6w==", - "dev": true, "requires": { "@babel/template": "^7.1.0", "@babel/types": "^7.0.0" @@ -237,7 +250,6 @@ "version": "7.4.4", "resolved": "https://registry.npmjs.org/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.4.4.tgz", "integrity": "sha512-Ro/XkzLf3JFITkW6b+hNxzZ1n5OQ80NvIUdmHspih1XAhtN3vPTuUFT4eQnela+2MaZ5ulH+iyP513KJrxbN7Q==", - "dev": true, "requires": { "@babel/types": "^7.4.4" } @@ -246,7 +258,6 @@ "version": "7.2.0", "resolved": "https://registry.npmjs.org/@babel/helper-wrap-function/-/helper-wrap-function-7.2.0.tgz", "integrity": "sha512-o9fP1BZLLSrYlxYEYyl2aS+Flun5gtjTIG8iln+XuEzQTs0PLagAGSXUcqruJwD5fM48jzIEggCKpIfWTcR7pQ==", - "dev": true, "requires": { "@babel/helper-function-name": "^7.1.0", "@babel/template": "^7.1.0", @@ -255,21 +266,19 @@ } }, "@babel/helpers": { - "version": "7.4.4", - "resolved": "https://registry.npmjs.org/@babel/helpers/-/helpers-7.4.4.tgz", - "integrity": "sha512-igczbR/0SeuPR8RFfC7tGrbdTbFL3QTvH6D+Z6zNxnTe//GyqmtHmDkzrqDmyZ3eSwPqB/LhyKoU5DXsp+Vp2A==", - "dev": true, + "version": "7.6.2", + "resolved": "https://registry.npmjs.org/@babel/helpers/-/helpers-7.6.2.tgz", + "integrity": "sha512-3/bAUL8zZxYs1cdX2ilEE0WobqbCmKWr/889lf2SS0PpDcpEIY8pb1CCyz0pEcX3pEb+MCbks1jIokz2xLtGTA==", "requires": { - "@babel/template": "^7.4.4", - "@babel/traverse": "^7.4.4", - "@babel/types": "^7.4.4" + "@babel/template": "^7.6.0", + "@babel/traverse": "^7.6.2", + "@babel/types": "^7.6.0" } }, "@babel/highlight": { - "version": "7.0.0", - "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.0.0.tgz", - "integrity": "sha512-UFMC4ZeFC48Tpvj7C8UgLvtkaUuovQX+5xNWrsIoMG8o2z+XFKjKaN9iVmS84dPwVN00W4wPmqvYoZF3EGAsfw==", - "dev": true, + "version": "7.5.0", + "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.5.0.tgz", + "integrity": "sha512-7dV4eu9gBxoM0dAnj/BCFDW9LFU0zvTrkq0ugM7pnHEgguOEeOz1so2ZghEdzviYzQEED0r4EAgpsBChKy1TRQ==", "requires": { "chalk": "^2.0.0", "esutils": "^2.0.2", @@ -277,16 +286,14 @@ } }, "@babel/parser": { - "version": "7.4.5", - "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.4.5.tgz", - "integrity": "sha512-9mUqkL1FF5T7f0WDFfAoDdiMVPWsdD1gZYzSnaXsxUCUqzuch/8of9G3VUSNiZmMBoRxT3neyVsqeiL/ZPcjew==", - "dev": true + "version": "7.6.4", + "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.6.4.tgz", + "integrity": "sha512-D8RHPW5qd0Vbyo3qb+YjO5nvUVRTXFLQ/FsDxJU2Nqz4uB5EnUN0ZQSEYpvTIbRuttig1XbHWU5oMeQwQSAA+A==" }, "@babel/plugin-proposal-async-generator-functions": { "version": "7.2.0", "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-async-generator-functions/-/plugin-proposal-async-generator-functions-7.2.0.tgz", "integrity": "sha512-+Dfo/SCQqrwx48ptLVGLdE39YtWRuKc/Y9I5Fy0P1DDBB9lsAHpjcEJQt+4IifuSOSTLBKJObJqMvaO1pIE8LQ==", - "dev": true, "requires": { "@babel/helper-plugin-utils": "^7.0.0", "@babel/helper-remap-async-to-generator": "^7.1.0", @@ -294,22 +301,20 @@ } }, "@babel/plugin-proposal-class-properties": { - "version": "7.4.4", - "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-class-properties/-/plugin-proposal-class-properties-7.4.4.tgz", - "integrity": "sha512-WjKTI8g8d5w1Bc9zgwSz2nfrsNQsXcCf9J9cdCvrJV6RF56yztwm4TmJC0MgJ9tvwO9gUA/mcYe89bLdGfiXFg==", - "dev": true, + "version": "7.5.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-class-properties/-/plugin-proposal-class-properties-7.5.5.tgz", + "integrity": "sha512-AF79FsnWFxjlaosgdi421vmYG6/jg79bVD0dpD44QdgobzHKuLZ6S3vl8la9qIeSwGi8i1fS0O1mfuDAAdo1/A==", "requires": { - "@babel/helper-create-class-features-plugin": "^7.4.4", + "@babel/helper-create-class-features-plugin": "^7.5.5", "@babel/helper-plugin-utils": "^7.0.0" } }, "@babel/plugin-proposal-decorators": { - "version": "7.4.4", - "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-decorators/-/plugin-proposal-decorators-7.4.4.tgz", - "integrity": "sha512-z7MpQz3XC/iQJWXH9y+MaWcLPNSMY9RQSthrLzak8R8hCj0fuyNk+Dzi9kfNe/JxxlWQ2g7wkABbgWjW36MTcw==", - "dev": true, + "version": "7.6.0", + "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-decorators/-/plugin-proposal-decorators-7.6.0.tgz", + "integrity": "sha512-ZSyYw9trQI50sES6YxREXKu+4b7MAg6Qx2cvyDDYjP2Hpzd3FleOUwC9cqn1+za8d0A2ZU8SHujxFao956efUg==", "requires": { - "@babel/helper-create-class-features-plugin": "^7.4.4", + "@babel/helper-create-class-features-plugin": "^7.6.0", "@babel/helper-plugin-utils": "^7.0.0", "@babel/plugin-syntax-decorators": "^7.2.0" } @@ -318,17 +323,15 @@ "version": "7.2.0", "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-json-strings/-/plugin-proposal-json-strings-7.2.0.tgz", "integrity": "sha512-MAFV1CA/YVmYwZG0fBQyXhmj0BHCB5egZHCKWIFVv/XCxAeVGIHfos3SwDck4LvCllENIAg7xMKOG5kH0dzyUg==", - "dev": true, "requires": { "@babel/helper-plugin-utils": "^7.0.0", "@babel/plugin-syntax-json-strings": "^7.2.0" } }, "@babel/plugin-proposal-object-rest-spread": { - "version": "7.4.4", - "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-object-rest-spread/-/plugin-proposal-object-rest-spread-7.4.4.tgz", - "integrity": "sha512-dMBG6cSPBbHeEBdFXeQ2QLc5gUpg4Vkaz8octD4aoW/ISO+jBOcsuxYL7bsb5WSu8RLP6boxrBIALEHgoHtO9g==", - "dev": true, + "version": "7.6.2", + "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-object-rest-spread/-/plugin-proposal-object-rest-spread-7.6.2.tgz", + "integrity": "sha512-LDBXlmADCsMZV1Y9OQwMc0MyGZ8Ta/zlD9N67BfQT8uYwkRswiu2hU6nJKrjrt/58aH/vqfQlR/9yId/7A2gWw==", "requires": { "@babel/helper-plugin-utils": "^7.0.0", "@babel/plugin-syntax-object-rest-spread": "^7.2.0" @@ -338,28 +341,25 @@ "version": "7.2.0", "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-optional-catch-binding/-/plugin-proposal-optional-catch-binding-7.2.0.tgz", "integrity": "sha512-mgYj3jCcxug6KUcX4OBoOJz3CMrwRfQELPQ5560F70YQUBZB7uac9fqaWamKR1iWUzGiK2t0ygzjTScZnVz75g==", - "dev": true, "requires": { "@babel/helper-plugin-utils": "^7.0.0", "@babel/plugin-syntax-optional-catch-binding": "^7.2.0" } }, "@babel/plugin-proposal-unicode-property-regex": { - "version": "7.4.4", - "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-unicode-property-regex/-/plugin-proposal-unicode-property-regex-7.4.4.tgz", - "integrity": "sha512-j1NwnOqMG9mFUOH58JTFsA/+ZYzQLUZ/drqWUqxCYLGeu2JFZL8YrNC9hBxKmWtAuOCHPcRpgv7fhap09Fb4kA==", - "dev": true, + "version": "7.6.2", + "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-unicode-property-regex/-/plugin-proposal-unicode-property-regex-7.6.2.tgz", + "integrity": "sha512-NxHETdmpeSCtiatMRYWVJo7266rrvAC3DTeG5exQBIH/fMIUK7ejDNznBbn3HQl/o9peymRRg7Yqkx6PdUXmMw==", "requires": { "@babel/helper-plugin-utils": "^7.0.0", "@babel/helper-regex": "^7.4.4", - "regexpu-core": "^4.5.4" + "regexpu-core": "^4.6.0" } }, "@babel/plugin-syntax-async-generators": { "version": "7.2.0", "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-async-generators/-/plugin-syntax-async-generators-7.2.0.tgz", "integrity": "sha512-1ZrIRBv2t0GSlcwVoQ6VgSLpLgiN/FVQUzt9znxo7v2Ov4jJrs8RY8tv0wvDmFN3qIdMKWrmMMW6yZ0G19MfGg==", - "dev": true, "requires": { "@babel/helper-plugin-utils": "^7.0.0" } @@ -368,7 +368,6 @@ "version": "7.2.0", "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-decorators/-/plugin-syntax-decorators-7.2.0.tgz", "integrity": "sha512-38QdqVoXdHUQfTpZo3rQwqQdWtCn5tMv4uV6r2RMfTqNBuv4ZBhz79SfaQWKTVmxHjeFv/DnXVC/+agHCklYWA==", - "dev": true, "requires": { "@babel/helper-plugin-utils": "^7.0.0" } @@ -377,7 +376,6 @@ "version": "7.2.0", "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-dynamic-import/-/plugin-syntax-dynamic-import-7.2.0.tgz", "integrity": "sha512-mVxuJ0YroI/h/tbFTPGZR8cv6ai+STMKNBq0f8hFxsxWjl94qqhsb+wXbpNMDPU3cfR1TIsVFzU3nXyZMqyK4w==", - "dev": true, "requires": { "@babel/helper-plugin-utils": "^7.0.0" } @@ -386,7 +384,6 @@ "version": "7.2.0", "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-json-strings/-/plugin-syntax-json-strings-7.2.0.tgz", "integrity": "sha512-5UGYnMSLRE1dqqZwug+1LISpA403HzlSfsg6P9VXU6TBjcSHeNlw4DxDx7LgpF+iKZoOG/+uzqoRHTdcUpiZNg==", - "dev": true, "requires": { "@babel/helper-plugin-utils": "^7.0.0" } @@ -395,7 +392,6 @@ "version": "7.2.0", "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-jsx/-/plugin-syntax-jsx-7.2.0.tgz", "integrity": "sha512-VyN4QANJkRW6lDBmENzRszvZf3/4AXaj9YR7GwrWeeN9tEBPuXbmDYVU9bYBN0D70zCWVwUy0HWq2553VCb6Hw==", - "dev": true, "requires": { "@babel/helper-plugin-utils": "^7.0.0" } @@ -404,7 +400,6 @@ "version": "7.2.0", "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-object-rest-spread/-/plugin-syntax-object-rest-spread-7.2.0.tgz", "integrity": "sha512-t0JKGgqk2We+9may3t0xDdmneaXmyxq0xieYcKHxIsrJO64n1OiMWNUtc5gQK1PA0NpdCRrtZp4z+IUaKugrSA==", - "dev": true, "requires": { "@babel/helper-plugin-utils": "^7.0.0" } @@ -413,7 +408,6 @@ "version": "7.2.0", "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-optional-catch-binding/-/plugin-syntax-optional-catch-binding-7.2.0.tgz", "integrity": "sha512-bDe4xKNhb0LI7IvZHiA13kff0KEfaGX/Hv4lMA9+7TEc63hMNvfKo6ZFpXhKuEp+II/q35Gc4NoMeDZyaUbj9w==", - "dev": true, "requires": { "@babel/helper-plugin-utils": "^7.0.0" } @@ -422,16 +416,14 @@ "version": "7.2.0", "resolved": "https://registry.npmjs.org/@babel/plugin-transform-arrow-functions/-/plugin-transform-arrow-functions-7.2.0.tgz", "integrity": "sha512-ER77Cax1+8/8jCB9fo4Ud161OZzWN5qawi4GusDuRLcDbDG+bIGYY20zb2dfAFdTRGzrfq2xZPvF0R64EHnimg==", - "dev": true, "requires": { "@babel/helper-plugin-utils": "^7.0.0" } }, "@babel/plugin-transform-async-to-generator": { - "version": "7.4.4", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-async-to-generator/-/plugin-transform-async-to-generator-7.4.4.tgz", - "integrity": "sha512-YiqW2Li8TXmzgbXw+STsSqPBPFnGviiaSp6CYOq55X8GQ2SGVLrXB6pNid8HkqkZAzOH6knbai3snhP7v0fNwA==", - "dev": true, + "version": "7.5.0", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-async-to-generator/-/plugin-transform-async-to-generator-7.5.0.tgz", + "integrity": "sha512-mqvkzwIGkq0bEF1zLRRiTdjfomZJDV33AH3oQzHVGkI2VzEmXLpKKOBvEVaFZBJdN0XTyH38s9j/Kiqr68dggg==", "requires": { "@babel/helper-module-imports": "^7.0.0", "@babel/helper-plugin-utils": "^7.0.0", @@ -442,33 +434,30 @@ "version": "7.2.0", "resolved": "https://registry.npmjs.org/@babel/plugin-transform-block-scoped-functions/-/plugin-transform-block-scoped-functions-7.2.0.tgz", "integrity": "sha512-ntQPR6q1/NKuphly49+QiQiTN0O63uOwjdD6dhIjSWBI5xlrbUFh720TIpzBhpnrLfv2tNH/BXvLIab1+BAI0w==", - "dev": true, "requires": { "@babel/helper-plugin-utils": "^7.0.0" } }, "@babel/plugin-transform-block-scoping": { - "version": "7.4.4", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-block-scoping/-/plugin-transform-block-scoping-7.4.4.tgz", - "integrity": "sha512-jkTUyWZcTrwxu5DD4rWz6rDB5Cjdmgz6z7M7RLXOJyCUkFBawssDGcGh8M/0FTSB87avyJI1HsTwUXp9nKA1PA==", - "dev": true, + "version": "7.6.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-block-scoping/-/plugin-transform-block-scoping-7.6.3.tgz", + "integrity": "sha512-7hvrg75dubcO3ZI2rjYTzUrEuh1E9IyDEhhB6qfcooxhDA33xx2MasuLVgdxzcP6R/lipAC6n9ub9maNW6RKdw==", "requires": { "@babel/helper-plugin-utils": "^7.0.0", - "lodash": "^4.17.11" + "lodash": "^4.17.13" } }, "@babel/plugin-transform-classes": { - "version": "7.4.4", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-classes/-/plugin-transform-classes-7.4.4.tgz", - "integrity": "sha512-/e44eFLImEGIpL9qPxSRat13I5QNRgBLu2hOQJCF7VLy/otSM/sypV1+XaIw5+502RX/+6YaSAPmldk+nhHDPw==", - "dev": true, + "version": "7.5.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-classes/-/plugin-transform-classes-7.5.5.tgz", + "integrity": "sha512-U2htCNK/6e9K7jGyJ++1p5XRU+LJjrwtoiVn9SzRlDT2KubcZ11OOwy3s24TjHxPgxNwonCYP7U2K51uVYCMDg==", "requires": { "@babel/helper-annotate-as-pure": "^7.0.0", - "@babel/helper-define-map": "^7.4.4", + "@babel/helper-define-map": "^7.5.5", "@babel/helper-function-name": "^7.1.0", "@babel/helper-optimise-call-expression": "^7.0.0", "@babel/helper-plugin-utils": "^7.0.0", - "@babel/helper-replace-supers": "^7.4.4", + "@babel/helper-replace-supers": "^7.5.5", "@babel/helper-split-export-declaration": "^7.4.4", "globals": "^11.1.0" } @@ -477,36 +466,32 @@ "version": "7.2.0", "resolved": "https://registry.npmjs.org/@babel/plugin-transform-computed-properties/-/plugin-transform-computed-properties-7.2.0.tgz", "integrity": "sha512-kP/drqTxY6Xt3NNpKiMomfgkNn4o7+vKxK2DDKcBG9sHj51vHqMBGy8wbDS/J4lMxnqs153/T3+DmCEAkC5cpA==", - "dev": true, "requires": { "@babel/helper-plugin-utils": "^7.0.0" } }, "@babel/plugin-transform-destructuring": { - "version": "7.4.4", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-destructuring/-/plugin-transform-destructuring-7.4.4.tgz", - "integrity": "sha512-/aOx+nW0w8eHiEHm+BTERB2oJn5D127iye/SUQl7NjHy0lf+j7h4MKMMSOwdazGq9OxgiNADncE+SRJkCxjZpQ==", - "dev": true, + "version": "7.6.0", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-destructuring/-/plugin-transform-destructuring-7.6.0.tgz", + "integrity": "sha512-2bGIS5P1v4+sWTCnKNDZDxbGvEqi0ijeqM/YqHtVGrvG2y0ySgnEEhXErvE9dA0bnIzY9bIzdFK0jFA46ASIIQ==", "requires": { "@babel/helper-plugin-utils": "^7.0.0" } }, "@babel/plugin-transform-dotall-regex": { - "version": "7.4.4", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-dotall-regex/-/plugin-transform-dotall-regex-7.4.4.tgz", - "integrity": "sha512-P05YEhRc2h53lZDjRPk/OektxCVevFzZs2Gfjd545Wde3k+yFDbXORgl2e0xpbq8mLcKJ7Idss4fAg0zORN/zg==", - "dev": true, + "version": "7.6.2", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-dotall-regex/-/plugin-transform-dotall-regex-7.6.2.tgz", + "integrity": "sha512-KGKT9aqKV+9YMZSkowzYoYEiHqgaDhGmPNZlZxX6UeHC4z30nC1J9IrZuGqbYFB1jaIGdv91ujpze0exiVK8bA==", "requires": { "@babel/helper-plugin-utils": "^7.0.0", "@babel/helper-regex": "^7.4.4", - "regexpu-core": "^4.5.4" + "regexpu-core": "^4.6.0" } }, "@babel/plugin-transform-duplicate-keys": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-duplicate-keys/-/plugin-transform-duplicate-keys-7.2.0.tgz", - "integrity": "sha512-q+yuxW4DsTjNceUiTzK0L+AfQ0zD9rWaTLiUqHA8p0gxx7lu1EylenfzjeIWNkPy6e/0VG/Wjw9uf9LueQwLOw==", - "dev": true, + "version": "7.5.0", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-duplicate-keys/-/plugin-transform-duplicate-keys-7.5.0.tgz", + "integrity": "sha512-igcziksHizyQPlX9gfSjHkE2wmoCH3evvD2qR5w29/Dk0SMKE/eOI7f1HhBdNhR/zxJDqrgpoDTq5YSLH/XMsQ==", "requires": { "@babel/helper-plugin-utils": "^7.0.0" } @@ -515,7 +500,6 @@ "version": "7.2.0", "resolved": "https://registry.npmjs.org/@babel/plugin-transform-exponentiation-operator/-/plugin-transform-exponentiation-operator-7.2.0.tgz", "integrity": "sha512-umh4hR6N7mu4Elq9GG8TOu9M0bakvlsREEC+ialrQN6ABS4oDQ69qJv1VtR3uxlKMCQMCvzk7vr17RHKcjx68A==", - "dev": true, "requires": { "@babel/helper-builder-binary-assignment-operator-visitor": "^7.1.0", "@babel/helper-plugin-utils": "^7.0.0" @@ -525,7 +509,6 @@ "version": "7.4.4", "resolved": "https://registry.npmjs.org/@babel/plugin-transform-for-of/-/plugin-transform-for-of-7.4.4.tgz", "integrity": "sha512-9T/5Dlr14Z9TIEXLXkt8T1DU7F24cbhwhMNUziN3hB1AXoZcdzPcTiKGRn/6iOymDqtTKWnr/BtRKN9JwbKtdQ==", - "dev": true, "requires": { "@babel/helper-plugin-utils": "^7.0.0" } @@ -534,7 +517,6 @@ "version": "7.4.4", "resolved": "https://registry.npmjs.org/@babel/plugin-transform-function-name/-/plugin-transform-function-name-7.4.4.tgz", "integrity": "sha512-iU9pv7U+2jC9ANQkKeNF6DrPy4GBa4NWQtl6dHB4Pb3izX2JOEvDTFarlNsBj/63ZEzNNIAMs3Qw4fNCcSOXJA==", - "dev": true, "requires": { "@babel/helper-function-name": "^7.1.0", "@babel/helper-plugin-utils": "^7.0.0" @@ -544,85 +526,79 @@ "version": "7.2.0", "resolved": "https://registry.npmjs.org/@babel/plugin-transform-literals/-/plugin-transform-literals-7.2.0.tgz", "integrity": "sha512-2ThDhm4lI4oV7fVQ6pNNK+sx+c/GM5/SaML0w/r4ZB7sAneD/piDJtwdKlNckXeyGK7wlwg2E2w33C/Hh+VFCg==", - "dev": true, "requires": { "@babel/helper-plugin-utils": "^7.0.0" } }, "@babel/plugin-transform-modules-amd": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-amd/-/plugin-transform-modules-amd-7.2.0.tgz", - "integrity": "sha512-mK2A8ucqz1qhrdqjS9VMIDfIvvT2thrEsIQzbaTdc5QFzhDjQv2CkJJ5f6BXIkgbmaoax3zBr2RyvV/8zeoUZw==", - "dev": true, + "version": "7.5.0", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-amd/-/plugin-transform-modules-amd-7.5.0.tgz", + "integrity": "sha512-n20UsQMKnWrltocZZm24cRURxQnWIvsABPJlw/fvoy9c6AgHZzoelAIzajDHAQrDpuKFFPPcFGd7ChsYuIUMpg==", "requires": { "@babel/helper-module-transforms": "^7.1.0", - "@babel/helper-plugin-utils": "^7.0.0" + "@babel/helper-plugin-utils": "^7.0.0", + "babel-plugin-dynamic-import-node": "^2.3.0" } }, "@babel/plugin-transform-modules-commonjs": { - "version": "7.4.4", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-commonjs/-/plugin-transform-modules-commonjs-7.4.4.tgz", - "integrity": "sha512-4sfBOJt58sEo9a2BQXnZq+Q3ZTSAUXyK3E30o36BOGnJ+tvJ6YSxF0PG6kERvbeISgProodWuI9UVG3/FMY6iw==", - "dev": true, + "version": "7.6.0", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-commonjs/-/plugin-transform-modules-commonjs-7.6.0.tgz", + "integrity": "sha512-Ma93Ix95PNSEngqomy5LSBMAQvYKVe3dy+JlVJSHEXZR5ASL9lQBedMiCyVtmTLraIDVRE3ZjTZvmXXD2Ozw3g==", "requires": { "@babel/helper-module-transforms": "^7.4.4", "@babel/helper-plugin-utils": "^7.0.0", - "@babel/helper-simple-access": "^7.1.0" + "@babel/helper-simple-access": "^7.1.0", + "babel-plugin-dynamic-import-node": "^2.3.0" } }, "@babel/plugin-transform-modules-systemjs": { - "version": "7.4.4", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-systemjs/-/plugin-transform-modules-systemjs-7.4.4.tgz", - "integrity": "sha512-MSiModfILQc3/oqnG7NrP1jHaSPryO6tA2kOMmAQApz5dayPxWiHqmq4sWH2xF5LcQK56LlbKByCd8Aah/OIkQ==", - "dev": true, + "version": "7.5.0", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-systemjs/-/plugin-transform-modules-systemjs-7.5.0.tgz", + "integrity": "sha512-Q2m56tyoQWmuNGxEtUyeEkm6qJYFqs4c+XyXH5RAuYxObRNz9Zgj/1g2GMnjYp2EUyEy7YTrxliGCXzecl/vJg==", "requires": { "@babel/helper-hoist-variables": "^7.4.4", - "@babel/helper-plugin-utils": "^7.0.0" + "@babel/helper-plugin-utils": "^7.0.0", + "babel-plugin-dynamic-import-node": "^2.3.0" } }, "@babel/plugin-transform-modules-umd": { "version": "7.2.0", "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-umd/-/plugin-transform-modules-umd-7.2.0.tgz", "integrity": "sha512-BV3bw6MyUH1iIsGhXlOK6sXhmSarZjtJ/vMiD9dNmpY8QXFFQTj+6v92pcfy1iqa8DeAfJFwoxcrS/TUZda6sw==", - "dev": true, "requires": { "@babel/helper-module-transforms": "^7.1.0", "@babel/helper-plugin-utils": "^7.0.0" } }, "@babel/plugin-transform-named-capturing-groups-regex": { - "version": "7.4.5", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-named-capturing-groups-regex/-/plugin-transform-named-capturing-groups-regex-7.4.5.tgz", - "integrity": "sha512-z7+2IsWafTBbjNsOxU/Iv5CvTJlr5w4+HGu1HovKYTtgJ362f7kBcQglkfmlspKKZ3bgrbSGvLfNx++ZJgCWsg==", - "dev": true, + "version": "7.6.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-named-capturing-groups-regex/-/plugin-transform-named-capturing-groups-regex-7.6.3.tgz", + "integrity": "sha512-jTkk7/uE6H2s5w6VlMHeWuH+Pcy2lmdwFoeWCVnvIrDUnB5gQqTVI8WfmEAhF2CDEarGrknZcmSFg1+bkfCoSw==", "requires": { - "regexp-tree": "^0.1.6" + "regexpu-core": "^4.6.0" } }, "@babel/plugin-transform-new-target": { "version": "7.4.4", "resolved": "https://registry.npmjs.org/@babel/plugin-transform-new-target/-/plugin-transform-new-target-7.4.4.tgz", "integrity": "sha512-r1z3T2DNGQwwe2vPGZMBNjioT2scgWzK9BCnDEh+46z8EEwXBq24uRzd65I7pjtugzPSj921aM15RpESgzsSuA==", - "dev": true, "requires": { "@babel/helper-plugin-utils": "^7.0.0" } }, "@babel/plugin-transform-object-super": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-object-super/-/plugin-transform-object-super-7.2.0.tgz", - "integrity": "sha512-VMyhPYZISFZAqAPVkiYb7dUe2AsVi2/wCT5+wZdsNO31FojQJa9ns40hzZ6U9f50Jlq4w6qwzdBB2uwqZ00ebg==", - "dev": true, + "version": "7.5.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-object-super/-/plugin-transform-object-super-7.5.5.tgz", + "integrity": "sha512-un1zJQAhSosGFBduPgN/YFNvWVpRuHKU7IHBglLoLZsGmruJPOo6pbInneflUdmq7YvSVqhpPs5zdBvLnteltQ==", "requires": { "@babel/helper-plugin-utils": "^7.0.0", - "@babel/helper-replace-supers": "^7.1.0" + "@babel/helper-replace-supers": "^7.5.5" } }, "@babel/plugin-transform-parameters": { "version": "7.4.4", "resolved": "https://registry.npmjs.org/@babel/plugin-transform-parameters/-/plugin-transform-parameters-7.4.4.tgz", "integrity": "sha512-oMh5DUO1V63nZcu/ZVLQFqiihBGo4OpxJxR1otF50GMeCLiRx5nUdtokd+u9SuVJrvvuIh9OosRFPP4pIPnwmw==", - "dev": true, "requires": { "@babel/helper-call-delegate": "^7.4.4", "@babel/helper-get-function-arity": "^7.0.0", @@ -633,16 +609,14 @@ "version": "7.4.5", "resolved": "https://registry.npmjs.org/@babel/plugin-transform-regenerator/-/plugin-transform-regenerator-7.4.5.tgz", "integrity": "sha512-gBKRh5qAaCWntnd09S8QC7r3auLCqq5DI6O0DlfoyDjslSBVqBibrMdsqO+Uhmx3+BlOmE/Kw1HFxmGbv0N9dA==", - "dev": true, "requires": { "regenerator-transform": "^0.14.0" } }, "@babel/plugin-transform-runtime": { - "version": "7.4.4", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-runtime/-/plugin-transform-runtime-7.4.4.tgz", - "integrity": "sha512-aMVojEjPszvau3NRg+TIH14ynZLvPewH4xhlCW1w6A3rkxTS1m4uwzRclYR9oS+rl/dr+kT+pzbfHuAWP/lc7Q==", - "dev": true, + "version": "7.6.2", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-runtime/-/plugin-transform-runtime-7.6.2.tgz", + "integrity": "sha512-cqULw/QB4yl73cS5Y0TZlQSjDvNkzDbu0FurTZyHlJpWE5T3PCMdnyV+xXoH1opr1ldyHODe3QAX3OMAii5NxA==", "requires": { "@babel/helper-module-imports": "^7.0.0", "@babel/helper-plugin-utils": "^7.0.0", @@ -654,16 +628,14 @@ "version": "7.2.0", "resolved": "https://registry.npmjs.org/@babel/plugin-transform-shorthand-properties/-/plugin-transform-shorthand-properties-7.2.0.tgz", "integrity": "sha512-QP4eUM83ha9zmYtpbnyjTLAGKQritA5XW/iG9cjtuOI8s1RuL/3V6a3DeSHfKutJQ+ayUfeZJPcnCYEQzaPQqg==", - "dev": true, "requires": { "@babel/helper-plugin-utils": "^7.0.0" } }, "@babel/plugin-transform-spread": { - "version": "7.2.2", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-spread/-/plugin-transform-spread-7.2.2.tgz", - "integrity": "sha512-KWfky/58vubwtS0hLqEnrWJjsMGaOeSBn90Ezn5Jeg9Z8KKHmELbP1yGylMlm5N6TPKeY9A2+UaSYLdxahg01w==", - "dev": true, + "version": "7.6.2", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-spread/-/plugin-transform-spread-7.6.2.tgz", + "integrity": "sha512-DpSvPFryKdK1x+EDJYCy28nmAaIMdxmhot62jAXF/o99iA33Zj2Lmcp3vDmz+MUh0LNYVPvfj5iC3feb3/+PFg==", "requires": { "@babel/helper-plugin-utils": "^7.0.0" } @@ -672,7 +644,6 @@ "version": "7.2.0", "resolved": "https://registry.npmjs.org/@babel/plugin-transform-sticky-regex/-/plugin-transform-sticky-regex-7.2.0.tgz", "integrity": "sha512-KKYCoGaRAf+ckH8gEL3JHUaFVyNHKe3ASNsZ+AlktgHevvxGigoIttrEJb8iKN03Q7Eazlv1s6cx2B2cQ3Jabw==", - "dev": true, "requires": { "@babel/helper-plugin-utils": "^7.0.0", "@babel/helper-regex": "^7.0.0" @@ -682,7 +653,6 @@ "version": "7.4.4", "resolved": "https://registry.npmjs.org/@babel/plugin-transform-template-literals/-/plugin-transform-template-literals-7.4.4.tgz", "integrity": "sha512-mQrEC4TWkhLN0z8ygIvEL9ZEToPhG5K7KDW3pzGqOfIGZ28Jb0POUkeWcoz8HnHvhFy6dwAT1j8OzqN8s804+g==", - "dev": true, "requires": { "@babel/helper-annotate-as-pure": "^7.0.0", "@babel/helper-plugin-utils": "^7.0.0" @@ -692,27 +662,24 @@ "version": "7.2.0", "resolved": "https://registry.npmjs.org/@babel/plugin-transform-typeof-symbol/-/plugin-transform-typeof-symbol-7.2.0.tgz", "integrity": "sha512-2LNhETWYxiYysBtrBTqL8+La0jIoQQnIScUJc74OYvUGRmkskNY4EzLCnjHBzdmb38wqtTaixpo1NctEcvMDZw==", - "dev": true, "requires": { "@babel/helper-plugin-utils": "^7.0.0" } }, "@babel/plugin-transform-unicode-regex": { - "version": "7.4.4", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-unicode-regex/-/plugin-transform-unicode-regex-7.4.4.tgz", - "integrity": "sha512-il+/XdNw01i93+M9J9u4T7/e/Ue/vWfNZE4IRUQjplu2Mqb/AFTDimkw2tdEdSH50wuQXZAbXSql0UphQke+vA==", - "dev": true, + "version": "7.6.2", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-unicode-regex/-/plugin-transform-unicode-regex-7.6.2.tgz", + "integrity": "sha512-orZI6cWlR3nk2YmYdb0gImrgCUwb5cBUwjf6Ks6dvNVvXERkwtJWOQaEOjPiu0Gu1Tq6Yq/hruCZZOOi9F34Dw==", "requires": { "@babel/helper-plugin-utils": "^7.0.0", "@babel/helper-regex": "^7.4.4", - "regexpu-core": "^4.5.4" + "regexpu-core": "^4.6.0" } }, "@babel/preset-env": { "version": "7.3.4", "resolved": "https://registry.npmjs.org/@babel/preset-env/-/preset-env-7.3.4.tgz", "integrity": "sha512-2mwqfYMK8weA0g0uBKOt4FE3iEodiHy9/CW0b+nWXcbL+pGzLx8ESYc+j9IIxr6LTDHWKgPm71i9smo02bw+gA==", - "dev": true, "requires": { "@babel/helper-module-imports": "^7.0.0", "@babel/helper-plugin-utils": "^7.0.0", @@ -760,68 +727,106 @@ } }, "@babel/runtime": { - "version": "7.4.5", - "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.4.5.tgz", - "integrity": "sha512-TuI4qpWZP6lGOGIuGWtp9sPluqYICmbk8T/1vpSysqJxRPkudh/ofFWyqdcMsDf2s7KvDL4/YHgKyvcS3g9CJQ==", - "dev": true, + "version": "7.6.3", + "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.6.3.tgz", + "integrity": "sha512-kq6anf9JGjW8Nt5rYfEuGRaEAaH1mkv3Bbu6rYvLOpPh/RusSJXuKPEAoZ7L7gybZkchE8+NV5g9vKF4AGAtsA==", "requires": { "regenerator-runtime": "^0.13.2" + }, + "dependencies": { + "regenerator-runtime": { + "version": "0.13.3", + "resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.13.3.tgz", + "integrity": "sha512-naKIZz2GQ8JWh///G7L3X6LaQUAMp2lvb1rvwwsURe/VXwD6VMfr+/1NuNw3ag8v2kY1aQ/go5SNn79O9JU7yw==" + } } }, "@babel/runtime-corejs2": { - "version": "7.4.5", - "resolved": "https://registry.npmjs.org/@babel/runtime-corejs2/-/runtime-corejs2-7.4.5.tgz", - "integrity": "sha512-5yLuwzvIDecKwYMzJtiarky4Fb5643H3Ao5jwX0HrMR5oM5mn2iHH9wSZonxwNK0oAjAFUQAiOd4jT7/9Y2jMQ==", - "dev": true, + "version": "7.6.3", + "resolved": "https://registry.npmjs.org/@babel/runtime-corejs2/-/runtime-corejs2-7.6.3.tgz", + "integrity": "sha512-nuA2o+rgX2+PrNTZ063ehncVcg7sn+tU71BB81SaWRVUbGwCOlb0+yQA1e0QqmzOfRSYOxfvf8cosYqFbJEiwQ==", "requires": { "core-js": "^2.6.5", "regenerator-runtime": "^0.13.2" + }, + "dependencies": { + "regenerator-runtime": { + "version": "0.13.3", + "resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.13.3.tgz", + "integrity": "sha512-naKIZz2GQ8JWh///G7L3X6LaQUAMp2lvb1rvwwsURe/VXwD6VMfr+/1NuNw3ag8v2kY1aQ/go5SNn79O9JU7yw==" + } } }, "@babel/template": { - "version": "7.4.4", - "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.4.4.tgz", - "integrity": "sha512-CiGzLN9KgAvgZsnivND7rkA+AeJ9JB0ciPOD4U59GKbQP2iQl+olF1l76kJOupqidozfZ32ghwBEJDhnk9MEcw==", - "dev": true, + "version": "7.6.0", + "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.6.0.tgz", + "integrity": "sha512-5AEH2EXD8euCk446b7edmgFdub/qfH1SN6Nii3+fyXP807QRx9Q73A2N5hNwRRslC2H9sNzaFhsPubkS4L8oNQ==", "requires": { "@babel/code-frame": "^7.0.0", - "@babel/parser": "^7.4.4", - "@babel/types": "^7.4.4" + "@babel/parser": "^7.6.0", + "@babel/types": "^7.6.0" } }, "@babel/traverse": { - "version": "7.4.5", - "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.4.5.tgz", - "integrity": "sha512-Vc+qjynwkjRmIFGxy0KYoPj4FdVDxLej89kMHFsWScq999uX+pwcX4v9mWRjW0KcAYTPAuVQl2LKP1wEVLsp+A==", - "dev": true, + "version": "7.6.3", + "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.6.3.tgz", + "integrity": "sha512-unn7P4LGsijIxaAJo/wpoU11zN+2IaClkQAxcJWBNCMS6cmVh802IyLHNkAjQ0iYnRS3nnxk5O3fuXW28IMxTw==", "requires": { - "@babel/code-frame": "^7.0.0", - "@babel/generator": "^7.4.4", + "@babel/code-frame": "^7.5.5", + "@babel/generator": "^7.6.3", "@babel/helper-function-name": "^7.1.0", "@babel/helper-split-export-declaration": "^7.4.4", - "@babel/parser": "^7.4.5", - "@babel/types": "^7.4.4", + "@babel/parser": "^7.6.3", + "@babel/types": "^7.6.3", "debug": "^4.1.0", "globals": "^11.1.0", - "lodash": "^4.17.11" + "lodash": "^4.17.13" + }, + "dependencies": { + "debug": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.1.1.tgz", + "integrity": "sha512-pYAIzeRo8J6KPEaJ0VWOh5Pzkbw/RetuzehGM7QRRX5he4fPHx2rdKMB256ehJCkX+XRQm16eZLqLNS8RSZXZw==", + "requires": { + "ms": "^2.1.1" + } + }, + "ms": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", + "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==" + } } }, "@babel/types": { - "version": "7.4.4", - "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.4.4.tgz", - "integrity": "sha512-dOllgYdnEFOebhkKCjzSVFqw/PmmB8pH6RGOWkY4GsboQNd47b1fBThBSwlHAq9alF9vc1M3+6oqR47R50L0tQ==", - "dev": true, + "version": "7.6.3", + "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.6.3.tgz", + "integrity": "sha512-CqbcpTxMcpuQTMhjI37ZHVgjBkysg5icREQIEZ0eG1yCNwg3oy+5AaLiOKmjsCj6nqOsa6Hf0ObjRVwokb7srA==", "requires": { "esutils": "^2.0.2", - "lodash": "^4.17.11", + "lodash": "^4.17.13", "to-fast-properties": "^2.0.0" + }, + "dependencies": { + "to-fast-properties": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/to-fast-properties/-/to-fast-properties-2.0.0.tgz", + "integrity": "sha1-3F5pjL0HkmW8c+A3doGk5Og/YW4=" + } + } + }, + "@cosmos-ui/vue": { + "version": "0.5.12", + "resolved": "https://registry.npmjs.org/@cosmos-ui/vue/-/vue-0.5.12.tgz", + "integrity": "sha512-xMGrZtwCBgu7XQyXEHPacUbxZDl4rw7eM9saLhBvBWGb2NBSBZR+L8LFg64QMsR68jFLHj4wnXXsIRcvIHF/Dw==", + "requires": { + "vue": "^2.6.10" } }, "@mrmlnc/readdir-enhanced": { "version": "2.2.1", "resolved": "https://registry.npmjs.org/@mrmlnc/readdir-enhanced/-/readdir-enhanced-2.2.1.tgz", "integrity": "sha512-bPHp6Ji8b41szTOcaP63VlnbbO5Ny6dwAATtY6JTjh5N2OLrb5Qk/Th5cRkRQhkWCt+EJsYrNB0MiL+Gpn6e3g==", - "dev": true, "requires": { "call-me-maybe": "^1.0.1", "glob-to-regexp": "^0.3.0" @@ -830,20 +835,30 @@ "@nodelib/fs.stat": { "version": "1.1.3", "resolved": "https://registry.npmjs.org/@nodelib/fs.stat/-/fs.stat-1.1.3.tgz", - "integrity": "sha512-shAmDyaQC4H92APFoIaVDHCx5bStIocgvbwQyxPRrbUY20V1EYTbSDchWbuwlMG3V17cprZhA6+78JfB+3DTPw==", - "dev": true + "integrity": "sha512-shAmDyaQC4H92APFoIaVDHCx5bStIocgvbwQyxPRrbUY20V1EYTbSDchWbuwlMG3V17cprZhA6+78JfB+3DTPw==" + }, + "@types/babel-types": { + "version": "7.0.7", + "resolved": "https://registry.npmjs.org/@types/babel-types/-/babel-types-7.0.7.tgz", + "integrity": "sha512-dBtBbrc+qTHy1WdfHYjBwRln4+LWqASWakLHsWHR2NWHIFkv4W3O070IGoGLEBrJBvct3r0L1BUPuvURi7kYUQ==" + }, + "@types/babylon": { + "version": "6.16.5", + "resolved": "https://registry.npmjs.org/@types/babylon/-/babylon-6.16.5.tgz", + "integrity": "sha512-xH2e58elpj1X4ynnKp9qSnWlsRTIs6n3tgLGNfwAGHwePw0mulHQllV34n0T25uYSu1k0hRKkWXF890B1yS47w==", + "requires": { + "@types/babel-types": "*" + } }, "@types/events": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/@types/events/-/events-3.0.0.tgz", - "integrity": "sha512-EaObqwIvayI5a8dCzhFrjKzVwKLxjoG9T6Ppd5CEo07LRKfQ8Yokw54r5+Wq7FaBQ+yXRvQAYPrHwya1/UFt9g==", - "dev": true + "integrity": "sha512-EaObqwIvayI5a8dCzhFrjKzVwKLxjoG9T6Ppd5CEo07LRKfQ8Yokw54r5+Wq7FaBQ+yXRvQAYPrHwya1/UFt9g==" }, "@types/glob": { "version": "7.1.1", "resolved": "https://registry.npmjs.org/@types/glob/-/glob-7.1.1.tgz", "integrity": "sha512-1Bh06cbWJUHMC97acuD6UMG29nMt0Aqz1vF3guLfG+kHHJhy3AyohZFFxYk2f7Q1SQIrNwvncxAE0N/9s70F2w==", - "dev": true, "requires": { "@types/events": "*", "@types/minimatch": "*", @@ -853,32 +868,27 @@ "@types/minimatch": { "version": "3.0.3", "resolved": "https://registry.npmjs.org/@types/minimatch/-/minimatch-3.0.3.tgz", - "integrity": "sha512-tHq6qdbT9U1IRSGf14CL0pUlULksvY9OZ+5eEgl1N7t+OA3tGvNpxJCzuKQlsNgCVwbAs670L1vcVQi8j9HjnA==", - "dev": true + "integrity": "sha512-tHq6qdbT9U1IRSGf14CL0pUlULksvY9OZ+5eEgl1N7t+OA3tGvNpxJCzuKQlsNgCVwbAs670L1vcVQi8j9HjnA==" }, "@types/node": { - "version": "12.0.10", - "resolved": "https://registry.npmjs.org/@types/node/-/node-12.0.10.tgz", - "integrity": "sha512-LcsGbPomWsad6wmMNv7nBLw7YYYyfdYcz6xryKYQhx89c3XXan+8Q6AJ43G5XDIaklaVkK3mE4fCb0SBvMiPSQ==", - "dev": true + "version": "12.11.6", + "resolved": "https://registry.npmjs.org/@types/node/-/node-12.11.6.tgz", + "integrity": "sha512-4uPUyY1Aofo1YzoypalYHNd2SnKYxH2b6LzXwpryZCJKA2XlagZSynXx5C8sfPH0r1cSltUpaVHV2q5sYXschQ==" }, "@types/q": { "version": "1.5.2", "resolved": "https://registry.npmjs.org/@types/q/-/q-1.5.2.tgz", - "integrity": "sha512-ce5d3q03Ex0sy4R14722Rmt6MT07Ua+k4FwDfdcToYJcMKNtRVQvJ6JCAPdAmAnbRb6CsX6aYb9m96NGod9uTw==", - "dev": true + "integrity": "sha512-ce5d3q03Ex0sy4R14722Rmt6MT07Ua+k4FwDfdcToYJcMKNtRVQvJ6JCAPdAmAnbRb6CsX6aYb9m96NGod9uTw==" }, "@vue/babel-helper-vue-jsx-merge-props": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/@vue/babel-helper-vue-jsx-merge-props/-/babel-helper-vue-jsx-merge-props-1.0.0.tgz", - "integrity": "sha512-6tyf5Cqm4m6v7buITuwS+jHzPlIPxbFzEhXR5JGZpbrvOcp1hiQKckd305/3C7C36wFekNTQSxAtgeM0j0yoUw==", - "dev": true + "integrity": "sha512-6tyf5Cqm4m6v7buITuwS+jHzPlIPxbFzEhXR5JGZpbrvOcp1hiQKckd305/3C7C36wFekNTQSxAtgeM0j0yoUw==" }, "@vue/babel-plugin-transform-vue-jsx": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/@vue/babel-plugin-transform-vue-jsx/-/babel-plugin-transform-vue-jsx-1.0.0.tgz", "integrity": "sha512-U+JNwVQSmaLKjO3lzCUC3cNXxprgezV1N+jOdqbP4xWNaqtWUCJnkjTVcgECM18A/AinDKPcUUeoyhU7yxUxXQ==", - "dev": true, "requires": { "@babel/helper-module-imports": "^7.0.0", "@babel/plugin-syntax-jsx": "^7.2.0", @@ -889,10 +899,9 @@ } }, "@vue/babel-preset-app": { - "version": "3.8.0", - "resolved": "https://registry.npmjs.org/@vue/babel-preset-app/-/babel-preset-app-3.8.0.tgz", - "integrity": "sha512-A2NBzIVdtNq52foc+P+yQ/7rSm2q2oPpn2FJVW4hFgaWVOL+HaOLCjWDEQyEeMbRZvyOVHMuom097u3p2H2Rfw==", - "dev": true, + "version": "3.12.1", + "resolved": "https://registry.npmjs.org/@vue/babel-preset-app/-/babel-preset-app-3.12.1.tgz", + "integrity": "sha512-Zjy5jQaikV1Pz+ri0YgXFS7q4/5wCxB5tRkDOEIt5+4105u0Feb/pvH20nVL6nx9GyXrECFfcm7Yxr/z++OaPQ==", "requires": { "@babel/helper-module-imports": "^7.0.0", "@babel/plugin-proposal-class-properties": "^7.0.0", @@ -910,24 +919,22 @@ } }, "@vue/babel-preset-jsx": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/@vue/babel-preset-jsx/-/babel-preset-jsx-1.0.0.tgz", - "integrity": "sha512-5CbDu/QHS+TtQNw5aYAffiMxBBB2Eo9+RJpS8X+6FJbdG5Rvc4TVipEqkrg0pJviWadNg7TEy0Uz4o7VNXeIZw==", - "dev": true, + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/@vue/babel-preset-jsx/-/babel-preset-jsx-1.1.1.tgz", + "integrity": "sha512-SeyndwQZc8MAOkhbJaC34ocTwcKekKkwrwnTMC3YF8VmGp5IQWW5gPIU66bqO9WFBXFA3J3ANsUbP2pj8q8KdQ==", "requires": { "@vue/babel-helper-vue-jsx-merge-props": "^1.0.0", "@vue/babel-plugin-transform-vue-jsx": "^1.0.0", "@vue/babel-sugar-functional-vue": "^1.0.0", "@vue/babel-sugar-inject-h": "^1.0.0", - "@vue/babel-sugar-v-model": "^1.0.0", - "@vue/babel-sugar-v-on": "^1.0.0" + "@vue/babel-sugar-v-model": "^1.1.1", + "@vue/babel-sugar-v-on": "^1.1.0" } }, "@vue/babel-sugar-functional-vue": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/@vue/babel-sugar-functional-vue/-/babel-sugar-functional-vue-1.0.0.tgz", "integrity": "sha512-XE/jNaaorTuhWayCz+QClk5AB9OV5HzrwbzEC6sIUY0J60A28ONQKeTwxfidW42egOkqNH/UU6eE3KLfmiDj0Q==", - "dev": true, "requires": { "@babel/plugin-syntax-jsx": "^7.2.0" } @@ -936,16 +943,14 @@ "version": "1.0.0", "resolved": "https://registry.npmjs.org/@vue/babel-sugar-inject-h/-/babel-sugar-inject-h-1.0.0.tgz", "integrity": "sha512-NxWU+DqtbZgfGvd25GPoFMj+rvyQ8ZA1pHj8vIeqRij+vx3sXoKkObjA9ulZunvWw5F6uG9xYy4ytpxab/X+Hg==", - "dev": true, "requires": { "@babel/plugin-syntax-jsx": "^7.2.0" } }, "@vue/babel-sugar-v-model": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/@vue/babel-sugar-v-model/-/babel-sugar-v-model-1.0.0.tgz", - "integrity": "sha512-Pfg2Al0io66P1eO6zUbRIgpyKCU2qTnumiE0lao/wA/uNdb7Dx5Tfd1W6tO5SsByETPnEs8i8+gawRIXX40rFw==", - "dev": true, + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/@vue/babel-sugar-v-model/-/babel-sugar-v-model-1.1.1.tgz", + "integrity": "sha512-qiPbdUTiqNQdhXzvWQMVfrYGHCiMmscY7j/cudLxdxWZ8AFhgPRVlniVgaWIT7A1iOjs92e8U6qVyqkf0d4ZrA==", "requires": { "@babel/plugin-syntax-jsx": "^7.2.0", "@vue/babel-helper-vue-jsx-merge-props": "^1.0.0", @@ -953,24 +958,36 @@ "camelcase": "^5.0.0", "html-tags": "^2.0.0", "svg-tags": "^1.0.0" + }, + "dependencies": { + "camelcase": { + "version": "5.3.1", + "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-5.3.1.tgz", + "integrity": "sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg==" + } } }, "@vue/babel-sugar-v-on": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/@vue/babel-sugar-v-on/-/babel-sugar-v-on-1.0.0.tgz", - "integrity": "sha512-2aqJaDLKdSSGlxZU+GjFERaSNUaa6DQreV+V/K4W/6Lxj8520/r1lChWEa/zuAoPD2Vhy0D2QrqqO+I0D6CkKw==", - "dev": true, + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@vue/babel-sugar-v-on/-/babel-sugar-v-on-1.1.0.tgz", + "integrity": "sha512-8DwAj/RLpmrDP4eZ3erJcKcyuLArLUYagNODTsSQrMdG5zmLJoFFtEjODfYRh/XxM2wXv9Wxe+HAB41FQxxwQA==", "requires": { "@babel/plugin-syntax-jsx": "^7.2.0", "@vue/babel-plugin-transform-vue-jsx": "^1.0.0", "camelcase": "^5.0.0" + }, + "dependencies": { + "camelcase": { + "version": "5.3.1", + "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-5.3.1.tgz", + "integrity": "sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg==" + } } }, "@vue/component-compiler-utils": { - "version": "2.6.0", - "resolved": "https://registry.npmjs.org/@vue/component-compiler-utils/-/component-compiler-utils-2.6.0.tgz", - "integrity": "sha512-IHjxt7LsOFYc0DkTncB7OXJL7UzwOLPPQCfEUNyxL2qt+tF12THV+EO33O1G2Uk4feMSWua3iD39Itszx0f0bw==", - "dev": true, + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/@vue/component-compiler-utils/-/component-compiler-utils-3.0.0.tgz", + "integrity": "sha512-am+04/0UX7ektcmvhYmrf84BDVAD8afFOf4asZjN84q8xzxFclbk5x0MtxuKGfp+zjN5WWPJn3fjFAWtDdIGSw==", "requires": { "consolidate": "^0.15.1", "hash-sum": "^1.0.2", @@ -986,14 +1003,12 @@ "cssesc": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/cssesc/-/cssesc-2.0.0.tgz", - "integrity": "sha512-MsCAG1z9lPdoO/IUMLSBWBSVxVtJ1395VGIQ+Fc2gNdkQ1hNDnQdw3YhA71WJCBW1vdwA0cAnk/DnW6bqoEUYg==", - "dev": true + "integrity": "sha512-MsCAG1z9lPdoO/IUMLSBWBSVxVtJ1395VGIQ+Fc2gNdkQ1hNDnQdw3YhA71WJCBW1vdwA0cAnk/DnW6bqoEUYg==" }, "lru-cache": { "version": "4.1.5", "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-4.1.5.tgz", "integrity": "sha512-sWZlbEP2OsHNkXrMl5GYk/jKk70MBng6UU4YI/qGDYbgf6YbP4EvmqISbXCoJiRKs+1bSpFHVgQxvJ17F2li5g==", - "dev": true, "requires": { "pseudomap": "^1.0.2", "yallist": "^2.1.2" @@ -1003,40 +1018,31 @@ "version": "5.0.0", "resolved": "https://registry.npmjs.org/postcss-selector-parser/-/postcss-selector-parser-5.0.0.tgz", "integrity": "sha512-w+zLE5Jhg6Liz8+rQOWEAwtwkyqpfnmsinXjXg6cY7YIONZZtgvE0v2O0uhQBs0peNomOJwWRKt6JBfTdTd3OQ==", - "dev": true, "requires": { "cssesc": "^2.0.0", "indexes-of": "^1.0.1", "uniq": "^1.0.1" } }, - "source-map": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", - "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", - "dev": true - }, "yallist": { "version": "2.1.2", "resolved": "https://registry.npmjs.org/yallist/-/yallist-2.1.2.tgz", - "integrity": "sha1-HBH5IY8HYImkfdUS+TxmmaaoHVI=", - "dev": true + "integrity": "sha1-HBH5IY8HYImkfdUS+TxmmaaoHVI=" } } }, "@vuepress/core": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/@vuepress/core/-/core-1.0.2.tgz", - "integrity": "sha512-PUMaxq44wEuqXHutcmxj6q9cCRS4kZ1nyBvvHr9AIuxJflgYDw/k8wxhYuZjsxVWhpJjsPywLGNRyLN88vJcqQ==", - "dev": true, + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/@vuepress/core/-/core-1.2.0.tgz", + "integrity": "sha512-ZIsUkQIF+h4Yk6q4okoRnRwRhcYePu/kNiL0WWPDGycjai8cFqFjLDP/tJjfTKXmn9A62j2ETjSwaiMxCtDkyw==", "requires": { "@babel/core": "^7.0.0", "@vue/babel-preset-app": "^3.1.1", - "@vuepress/markdown": "^1.0.2", - "@vuepress/markdown-loader": "^1.0.2", - "@vuepress/plugin-last-updated": "^1.0.2", - "@vuepress/plugin-register-components": "^1.0.2", - "@vuepress/shared-utils": "^1.0.2", + "@vuepress/markdown": "^1.2.0", + "@vuepress/markdown-loader": "^1.2.0", + "@vuepress/plugin-last-updated": "^1.2.0", + "@vuepress/plugin-register-components": "^1.2.0", + "@vuepress/shared-utils": "^1.2.0", "autoprefixer": "^9.5.1", "babel-loader": "^8.0.4", "cache-loader": "^3.0.0", @@ -1046,7 +1052,7 @@ "cross-spawn": "^6.0.5", "css-loader": "^2.1.1", "file-loader": "^3.0.1", - "js-yaml": "^3.11.0", + "js-yaml": "^3.13.1", "lru-cache": "^5.1.1", "mini-css-extract-plugin": "0.6.0", "optimize-css-assets-webpack-plugin": "^5.0.1", @@ -1055,13 +1061,13 @@ "postcss-safe-parser": "^4.0.1", "toml": "^3.0.0", "url-loader": "^1.0.1", - "vue": "^2.5.16", - "vue-loader": "^15.2.4", - "vue-router": "^3.0.2", - "vue-server-renderer": "^2.5.16", - "vue-template-compiler": "^2.5.16", + "vue": "^2.6.10", + "vue-loader": "^15.7.1", + "vue-router": "^3.1.3", + "vue-server-renderer": "^2.6.10", + "vue-template-compiler": "^2.6.10", "vuepress-html-webpack-plugin": "^3.2.0", - "vuepress-plugin-container": "^2.0.0", + "vuepress-plugin-container": "^2.0.2", "webpack": "^4.8.1", "webpack-chain": "^4.6.0", "webpack-dev-server": "^3.5.1", @@ -1070,78 +1076,84 @@ } }, "@vuepress/markdown": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/@vuepress/markdown/-/markdown-1.0.2.tgz", - "integrity": "sha512-ddl0FG11aeidjcFYYNU53xZ1WLEYb3g5/hijfSCEQKyMv+gDXy7Z3/uc4I4oH2UNtB2Wpo3pQoeKGY56edcBuA==", - "dev": true, + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/@vuepress/markdown/-/markdown-1.2.0.tgz", + "integrity": "sha512-RLRQmTu5wJbCO4Qv+J0K53o5Ew7nAGItLwWyzCbIUB6pRsya3kqSCViWQVlKlS53zFTmRHuAC9tJMRdzly3mCA==", "requires": { - "@vuepress/shared-utils": "^1.0.2", + "@vuepress/shared-utils": "^1.2.0", "markdown-it": "^8.4.1", "markdown-it-anchor": "^5.0.2", "markdown-it-chain": "^1.3.0", "markdown-it-emoji": "^1.4.0", "markdown-it-table-of-contents": "^0.4.0", "prismjs": "^1.13.0" + }, + "dependencies": { + "markdown-it": { + "version": "8.4.2", + "resolved": "https://registry.npmjs.org/markdown-it/-/markdown-it-8.4.2.tgz", + "integrity": "sha512-GcRz3AWTqSUphY3vsUqQSFMbgR38a4Lh3GWlHRh/7MRwz8mcu9n2IO7HOh+bXHrR9kOPDl5RNCaEsrneb+xhHQ==", + "requires": { + "argparse": "^1.0.7", + "entities": "~1.1.1", + "linkify-it": "^2.0.0", + "mdurl": "^1.0.1", + "uc.micro": "^1.0.5" + } + } } }, "@vuepress/markdown-loader": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/@vuepress/markdown-loader/-/markdown-loader-1.0.2.tgz", - "integrity": "sha512-ljD2mVDpeq0VvCHMHfemGW+0fhLmOMldtWIAYQ/I8LjLuV2qknAwjzZ4tEAqveaVIFMUBRP3V6d8YGIK9dr6kg==", - "dev": true, + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/@vuepress/markdown-loader/-/markdown-loader-1.2.0.tgz", + "integrity": "sha512-gOZzoHjfp/W6t+qKBRdbHS/9TwRnNuhY7V+yFzxofNONFHQULofIN/arG+ptYc2SuqJ541jqudNQW+ldHNMC2w==", "requires": { - "@vuepress/markdown": "^1.0.2", + "@vuepress/markdown": "^1.2.0", "loader-utils": "^1.1.0", "lru-cache": "^5.1.1" } }, "@vuepress/plugin-active-header-links": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/@vuepress/plugin-active-header-links/-/plugin-active-header-links-1.0.2.tgz", - "integrity": "sha512-Wo9NP55OOJ/vGFnYwStZcDBJMnf1gNDL159K7oiiEltuz8kjZBqmtsIjQXOzXFjA8voYh/RVL48Sr4eGCDd7LQ==", - "dev": true, + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/@vuepress/plugin-active-header-links/-/plugin-active-header-links-1.2.0.tgz", + "integrity": "sha512-vdi7l96pElJvEmcx6t9DWJNH25TIurS8acjN3+b7o4NzdaszFn5j6klN6WtI4Z+5BVDrxHP5W1F3Ebw8SZyupA==", "requires": { - "lodash.throttle": "^4.1.1" + "lodash.debounce": "^4.0.8" } }, "@vuepress/plugin-last-updated": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/@vuepress/plugin-last-updated/-/plugin-last-updated-1.0.2.tgz", - "integrity": "sha512-SwugVHcllUwy9WPqtWWM+hUEvH6SDPFJAHnpIs0kXJmaxIIipqF/9+CokT5QzxzGVHeYPU4YKtLadEIXdRcXsw==", - "dev": true, + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/@vuepress/plugin-last-updated/-/plugin-last-updated-1.2.0.tgz", + "integrity": "sha512-j4uZb/MXDyG+v9QCG3T/rkiaOhC/ib7NKCt1cjn3GOwvWTDmB5UZm9EBhUpbDNrBgxW+SaHOe3kMVNO8bGOTGw==", "requires": { "cross-spawn": "^6.0.5" } }, "@vuepress/plugin-nprogress": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/@vuepress/plugin-nprogress/-/plugin-nprogress-1.0.2.tgz", - "integrity": "sha512-degCJe2Z0eHbYblUGQXuDMIZSwH7twQcbWtkuH8goxXNilvtVxtWvBkUJouJ9RN3RuSk7EfPT171mrwq9yqbUg==", - "dev": true, + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/@vuepress/plugin-nprogress/-/plugin-nprogress-1.2.0.tgz", + "integrity": "sha512-0apt3Dp6XVCOkLViX6seKSEJgARihi+pX3/r8j8ndFp9Y+vmgLFZnQnGE5iKNi1ty+A6PZOK0RQcBjwTAU4pAw==", "requires": { "nprogress": "^0.2.0" } }, "@vuepress/plugin-register-components": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/@vuepress/plugin-register-components/-/plugin-register-components-1.0.2.tgz", - "integrity": "sha512-iqUq4kgNdVHba0cZJLv81DfB9ZsTdJY7gynN0NYHFwDEjsdOh1cRMgteuWa/mmK9XfopMO5oysD9WDhzCiIjfQ==", - "dev": true, + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/@vuepress/plugin-register-components/-/plugin-register-components-1.2.0.tgz", + "integrity": "sha512-C32b8sbGtDEX8I3SUUKS/w2rThiRFiKxmzNcJD996me7VY/4rgmZ8CxGtb6G9wByVoK0UdG1SOkrgOPdSCm80A==", "requires": { - "@vuepress/shared-utils": "^1.0.2" + "@vuepress/shared-utils": "^1.2.0" } }, "@vuepress/plugin-search": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/@vuepress/plugin-search/-/plugin-search-1.0.2.tgz", - "integrity": "sha512-LCFZLp+adppdHETIEARwQhczj+mdpa+D25qL9RNmYxzU9mF6qItYNLl57P6omGU2Vr8frAc+rWgjbi4cjkbCvQ==", - "dev": true + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/@vuepress/plugin-search/-/plugin-search-1.2.0.tgz", + "integrity": "sha512-QU3JfnMfImDAArbJOVH1q1iCDE5QrT99GLpNGo6KQYZWqY1TWAbgyf8C2hQdaI03co1lkU2Wn/iqzHJ5WHlueg==" }, "@vuepress/shared-utils": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/@vuepress/shared-utils/-/shared-utils-1.0.2.tgz", - "integrity": "sha512-QyNV76Dn0u2ooXbC3AXJZrQLuTNS4i8xSmJqZWsel2ooJKknXP3UIMIENcK1QFHnlIACznyV53u9hRAYBaZEWQ==", - "dev": true, + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/@vuepress/shared-utils/-/shared-utils-1.2.0.tgz", + "integrity": "sha512-wo5Ng2/xzsmIYCzvWxgLFlDBp7FkmJp2shAkbSurLNAh1vixhs0+LyDxsk01+m34ktJSp9rTUUsm6khw/Fvo0w==", "requires": { "chalk": "^2.3.2", "diacritics": "^1.3.0", @@ -1155,33 +1167,32 @@ }, "dependencies": { "semver": { - "version": "6.1.2", - "resolved": "https://registry.npmjs.org/semver/-/semver-6.1.2.tgz", - "integrity": "sha512-z4PqiCpomGtWj8633oeAdXm1Kn1W++3T8epkZYnwiVgIYIJ0QHszhInYSJTYxebByQH7KVCEAn8R9duzZW2PhQ==", - "dev": true + "version": "6.3.0", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", + "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==" } } }, "@vuepress/theme-default": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/@vuepress/theme-default/-/theme-default-1.0.2.tgz", - "integrity": "sha512-fawiYshvQWXyaEgMXcyqj7j0atHLysIA2AzFt4K6y29WaMfiIAPE9lsxymTzT4zkc/T6nRP/TqwiuUaOK12wkw==", - "dev": true, + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/@vuepress/theme-default/-/theme-default-1.2.0.tgz", + "integrity": "sha512-mJxAMYQQv4OrGFsArMlONu8RpCzPUVx81dumkyTT4ay5PXAWTj+WDeFQLOT3j0g9QrDJGnHhbiw2aS+R/0WUyQ==", "requires": { - "@vuepress/plugin-active-header-links": "^1.0.2", - "@vuepress/plugin-nprogress": "^1.0.2", - "@vuepress/plugin-search": "^1.0.2", + "@vuepress/plugin-active-header-links": "^1.2.0", + "@vuepress/plugin-nprogress": "^1.2.0", + "@vuepress/plugin-search": "^1.2.0", "docsearch.js": "^2.5.2", + "lodash": "^4.17.15", "stylus": "^0.54.5", "stylus-loader": "^3.0.2", - "vuepress-plugin-container": "^2.0.0" + "vuepress-plugin-container": "^2.0.2", + "vuepress-plugin-smooth-scroll": "^0.0.3" } }, "@webassemblyjs/ast": { "version": "1.8.5", "resolved": "https://registry.npmjs.org/@webassemblyjs/ast/-/ast-1.8.5.tgz", "integrity": "sha512-aJMfngIZ65+t71C3y2nBBg5FFG0Okt9m0XEgWZ7Ywgn1oMAT8cNwx00Uv1cQyHtidq0Xn94R4TAywO+LCQ+ZAQ==", - "dev": true, "requires": { "@webassemblyjs/helper-module-context": "1.8.5", "@webassemblyjs/helper-wasm-bytecode": "1.8.5", @@ -1191,26 +1202,22 @@ "@webassemblyjs/floating-point-hex-parser": { "version": "1.8.5", "resolved": "https://registry.npmjs.org/@webassemblyjs/floating-point-hex-parser/-/floating-point-hex-parser-1.8.5.tgz", - "integrity": "sha512-9p+79WHru1oqBh9ewP9zW95E3XAo+90oth7S5Re3eQnECGq59ly1Ri5tsIipKGpiStHsUYmY3zMLqtk3gTcOtQ==", - "dev": true + "integrity": "sha512-9p+79WHru1oqBh9ewP9zW95E3XAo+90oth7S5Re3eQnECGq59ly1Ri5tsIipKGpiStHsUYmY3zMLqtk3gTcOtQ==" }, "@webassemblyjs/helper-api-error": { "version": "1.8.5", "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-api-error/-/helper-api-error-1.8.5.tgz", - "integrity": "sha512-Za/tnzsvnqdaSPOUXHyKJ2XI7PDX64kWtURyGiJJZKVEdFOsdKUCPTNEVFZq3zJ2R0G5wc2PZ5gvdTRFgm81zA==", - "dev": true + "integrity": "sha512-Za/tnzsvnqdaSPOUXHyKJ2XI7PDX64kWtURyGiJJZKVEdFOsdKUCPTNEVFZq3zJ2R0G5wc2PZ5gvdTRFgm81zA==" }, "@webassemblyjs/helper-buffer": { "version": "1.8.5", "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-buffer/-/helper-buffer-1.8.5.tgz", - "integrity": "sha512-Ri2R8nOS0U6G49Q86goFIPNgjyl6+oE1abW1pS84BuhP1Qcr5JqMwRFT3Ah3ADDDYGEgGs1iyb1DGX+kAi/c/Q==", - "dev": true + "integrity": "sha512-Ri2R8nOS0U6G49Q86goFIPNgjyl6+oE1abW1pS84BuhP1Qcr5JqMwRFT3Ah3ADDDYGEgGs1iyb1DGX+kAi/c/Q==" }, "@webassemblyjs/helper-code-frame": { "version": "1.8.5", "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-code-frame/-/helper-code-frame-1.8.5.tgz", "integrity": "sha512-VQAadSubZIhNpH46IR3yWO4kZZjMxN1opDrzePLdVKAZ+DFjkGD/rf4v1jap744uPVU6yjL/smZbRIIJTOUnKQ==", - "dev": true, "requires": { "@webassemblyjs/wast-printer": "1.8.5" } @@ -1218,14 +1225,12 @@ "@webassemblyjs/helper-fsm": { "version": "1.8.5", "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-fsm/-/helper-fsm-1.8.5.tgz", - "integrity": "sha512-kRuX/saORcg8se/ft6Q2UbRpZwP4y7YrWsLXPbbmtepKr22i8Z4O3V5QE9DbZK908dh5Xya4Un57SDIKwB9eow==", - "dev": true + "integrity": "sha512-kRuX/saORcg8se/ft6Q2UbRpZwP4y7YrWsLXPbbmtepKr22i8Z4O3V5QE9DbZK908dh5Xya4Un57SDIKwB9eow==" }, "@webassemblyjs/helper-module-context": { "version": "1.8.5", "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-module-context/-/helper-module-context-1.8.5.tgz", "integrity": "sha512-/O1B236mN7UNEU4t9X7Pj38i4VoU8CcMHyy3l2cV/kIF4U5KoHXDVqcDuOs1ltkac90IM4vZdHc52t1x8Yfs3g==", - "dev": true, "requires": { "@webassemblyjs/ast": "1.8.5", "mamacro": "^0.0.3" @@ -1234,14 +1239,12 @@ "@webassemblyjs/helper-wasm-bytecode": { "version": "1.8.5", "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-wasm-bytecode/-/helper-wasm-bytecode-1.8.5.tgz", - "integrity": "sha512-Cu4YMYG3Ddl72CbmpjU/wbP6SACcOPVbHN1dI4VJNJVgFwaKf1ppeFJrwydOG3NDHxVGuCfPlLZNyEdIYlQ6QQ==", - "dev": true + "integrity": "sha512-Cu4YMYG3Ddl72CbmpjU/wbP6SACcOPVbHN1dI4VJNJVgFwaKf1ppeFJrwydOG3NDHxVGuCfPlLZNyEdIYlQ6QQ==" }, "@webassemblyjs/helper-wasm-section": { "version": "1.8.5", "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-wasm-section/-/helper-wasm-section-1.8.5.tgz", "integrity": "sha512-VV083zwR+VTrIWWtgIUpqfvVdK4ff38loRmrdDBgBT8ADXYsEZ5mPQ4Nde90N3UYatHdYoDIFb7oHzMncI02tA==", - "dev": true, "requires": { "@webassemblyjs/ast": "1.8.5", "@webassemblyjs/helper-buffer": "1.8.5", @@ -1253,7 +1256,6 @@ "version": "1.8.5", "resolved": "https://registry.npmjs.org/@webassemblyjs/ieee754/-/ieee754-1.8.5.tgz", "integrity": "sha512-aaCvQYrvKbY/n6wKHb/ylAJr27GglahUO89CcGXMItrOBqRarUMxWLJgxm9PJNuKULwN5n1csT9bYoMeZOGF3g==", - "dev": true, "requires": { "@xtuc/ieee754": "^1.2.0" } @@ -1262,7 +1264,6 @@ "version": "1.8.5", "resolved": "https://registry.npmjs.org/@webassemblyjs/leb128/-/leb128-1.8.5.tgz", "integrity": "sha512-plYUuUwleLIziknvlP8VpTgO4kqNaH57Y3JnNa6DLpu/sGcP6hbVdfdX5aHAV716pQBKrfuU26BJK29qY37J7A==", - "dev": true, "requires": { "@xtuc/long": "4.2.2" } @@ -1270,14 +1271,12 @@ "@webassemblyjs/utf8": { "version": "1.8.5", "resolved": "https://registry.npmjs.org/@webassemblyjs/utf8/-/utf8-1.8.5.tgz", - "integrity": "sha512-U7zgftmQriw37tfD934UNInokz6yTmn29inT2cAetAsaU9YeVCveWEwhKL1Mg4yS7q//NGdzy79nlXh3bT8Kjw==", - "dev": true + "integrity": "sha512-U7zgftmQriw37tfD934UNInokz6yTmn29inT2cAetAsaU9YeVCveWEwhKL1Mg4yS7q//NGdzy79nlXh3bT8Kjw==" }, "@webassemblyjs/wasm-edit": { "version": "1.8.5", "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-edit/-/wasm-edit-1.8.5.tgz", "integrity": "sha512-A41EMy8MWw5yvqj7MQzkDjU29K7UJq1VrX2vWLzfpRHt3ISftOXqrtojn7nlPsZ9Ijhp5NwuODuycSvfAO/26Q==", - "dev": true, "requires": { "@webassemblyjs/ast": "1.8.5", "@webassemblyjs/helper-buffer": "1.8.5", @@ -1293,7 +1292,6 @@ "version": "1.8.5", "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-gen/-/wasm-gen-1.8.5.tgz", "integrity": "sha512-BCZBT0LURC0CXDzj5FXSc2FPTsxwp3nWcqXQdOZE4U7h7i8FqtFK5Egia6f9raQLpEKT1VL7zr4r3+QX6zArWg==", - "dev": true, "requires": { "@webassemblyjs/ast": "1.8.5", "@webassemblyjs/helper-wasm-bytecode": "1.8.5", @@ -1306,7 +1304,6 @@ "version": "1.8.5", "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-opt/-/wasm-opt-1.8.5.tgz", "integrity": "sha512-HKo2mO/Uh9A6ojzu7cjslGaHaUU14LdLbGEKqTR7PBKwT6LdPtLLh9fPY33rmr5wcOMrsWDbbdCHq4hQUdd37Q==", - "dev": true, "requires": { "@webassemblyjs/ast": "1.8.5", "@webassemblyjs/helper-buffer": "1.8.5", @@ -1318,7 +1315,6 @@ "version": "1.8.5", "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-parser/-/wasm-parser-1.8.5.tgz", "integrity": "sha512-pi0SYE9T6tfcMkthwcgCpL0cM9nRYr6/6fjgDtL6q/ZqKHdMWvxitRi5JcZ7RI4SNJJYnYNaWy5UUrHQy998lw==", - "dev": true, "requires": { "@webassemblyjs/ast": "1.8.5", "@webassemblyjs/helper-api-error": "1.8.5", @@ -1332,7 +1328,6 @@ "version": "1.8.5", "resolved": "https://registry.npmjs.org/@webassemblyjs/wast-parser/-/wast-parser-1.8.5.tgz", "integrity": "sha512-daXC1FyKWHF1i11obK086QRlsMsY4+tIOKgBqI1lxAnkp9xe9YMcgOxm9kLe+ttjs5aWV2KKE1TWJCN57/Btsg==", - "dev": true, "requires": { "@webassemblyjs/ast": "1.8.5", "@webassemblyjs/floating-point-hex-parser": "1.8.5", @@ -1346,7 +1341,6 @@ "version": "1.8.5", "resolved": "https://registry.npmjs.org/@webassemblyjs/wast-printer/-/wast-printer-1.8.5.tgz", "integrity": "sha512-w0U0pD4EhlnvRyeJzBqaVSJAo9w/ce7/WPogeXLzGkO6hzhr4GnQIZ4W4uUt5b9ooAaXPtnXlj0gzsXEOUNYMg==", - "dev": true, "requires": { "@webassemblyjs/ast": "1.8.5", "@webassemblyjs/wast-parser": "1.8.5", @@ -1356,54 +1350,56 @@ "@xtuc/ieee754": { "version": "1.2.0", "resolved": "https://registry.npmjs.org/@xtuc/ieee754/-/ieee754-1.2.0.tgz", - "integrity": "sha512-DX8nKgqcGwsc0eJSqYt5lwP4DH5FlHnmuWWBRy7X0NcaGR0ZtuyeESgMwTYVEtxmsNGY+qit4QYT/MIYTOTPeA==", - "dev": true + "integrity": "sha512-DX8nKgqcGwsc0eJSqYt5lwP4DH5FlHnmuWWBRy7X0NcaGR0ZtuyeESgMwTYVEtxmsNGY+qit4QYT/MIYTOTPeA==" }, "@xtuc/long": { "version": "4.2.2", "resolved": "https://registry.npmjs.org/@xtuc/long/-/long-4.2.2.tgz", - "integrity": "sha512-NuHqBY1PB/D8xU6s/thBgOAiAP7HOYDQ32+BFZILJ8ivkUkAHQnWfn6WhL79Owj1qmUnoN/YPhktdIoucipkAQ==", - "dev": true + "integrity": "sha512-NuHqBY1PB/D8xU6s/thBgOAiAP7HOYDQ32+BFZILJ8ivkUkAHQnWfn6WhL79Owj1qmUnoN/YPhktdIoucipkAQ==" }, "abbrev": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/abbrev/-/abbrev-1.1.1.tgz", - "integrity": "sha512-nne9/IiQ/hzIhY6pdDnbBtz7DjPTKrY00P/zvPSm5pOFkl6xuGrGnXn/VtTNNfNtAfZ9/1RtehkszU9qcTii0Q==", - "dev": true + "integrity": "sha512-nne9/IiQ/hzIhY6pdDnbBtz7DjPTKrY00P/zvPSm5pOFkl6xuGrGnXn/VtTNNfNtAfZ9/1RtehkszU9qcTii0Q==" }, "accepts": { "version": "1.3.7", "resolved": "https://registry.npmjs.org/accepts/-/accepts-1.3.7.tgz", "integrity": "sha512-Il80Qs2WjYlJIBNzNkK6KYqlVMTbZLXgHx2oT0pU/fjRHyEp+PEfEPY0R3WCwAGVOtauxh1hOxNgIf5bv7dQpA==", - "dev": true, "requires": { "mime-types": "~2.1.24", "negotiator": "0.6.2" } }, "acorn": { - "version": "6.1.1", - "resolved": "https://registry.npmjs.org/acorn/-/acorn-6.1.1.tgz", - "integrity": "sha512-jPTiwtOxaHNaAPg/dmrJ/beuzLRnXtB0kQPQ8JpotKJgTB6rX6c8mlf315941pyjBSaPg8NHXS9fhP4u17DpGA==", - "dev": true + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-3.3.0.tgz", + "integrity": "sha1-ReN/s56No/JbruP/U2niu18iAXo=" }, - "acorn-dynamic-import": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/acorn-dynamic-import/-/acorn-dynamic-import-4.0.0.tgz", - "integrity": "sha512-d3OEjQV4ROpoflsnUA8HozoIR504TFxNivYEUi6uwz0IYhBkTDXGuWlNdMtybRt3nqVx/L6XqMt0FxkXuWKZhw==", - "dev": true + "acorn-globals": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/acorn-globals/-/acorn-globals-3.1.0.tgz", + "integrity": "sha1-/YJw9x+7SZawBPqIDuXUZXOnMb8=", + "requires": { + "acorn": "^4.0.4" + }, + "dependencies": { + "acorn": { + "version": "4.0.13", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-4.0.13.tgz", + "integrity": "sha1-EFSVrlNh1pe9GVyCUZLhrX8lN4c=" + } + } }, "agentkeepalive": { "version": "2.2.0", "resolved": "https://registry.npmjs.org/agentkeepalive/-/agentkeepalive-2.2.0.tgz", - "integrity": "sha1-xdG9SxKQCPEWPyNvhuX66iAm4u8=", - "dev": true + "integrity": "sha1-xdG9SxKQCPEWPyNvhuX66iAm4u8=" }, "ajv": { - "version": "6.10.0", - "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.10.0.tgz", - "integrity": "sha512-nffhOpkymDECQyR0mnsUtoCE8RlX38G0rYP+wgLWFyZuUyuuojSSvi/+euOiQBIn63whYwYVIIH1TvE3tu4OEg==", - "dev": true, + "version": "6.10.2", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.10.2.tgz", + "integrity": "sha512-TXtUUEYHuaTEbLZWIKUr5pmBuhDLy+8KYtPYdcV8qC+pOZL+NKqYwvWSRrVXHn+ZmRRAu8vJTAznH7Oag6RVRw==", "requires": { "fast-deep-equal": "^2.0.1", "fast-json-stable-stringify": "^2.0.0", @@ -1414,20 +1410,17 @@ "ajv-errors": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/ajv-errors/-/ajv-errors-1.0.1.tgz", - "integrity": "sha512-DCRfO/4nQ+89p/RK43i8Ezd41EqdGIU4ld7nGF8OQ14oc/we5rEntLCUa7+jrn3nn83BosfwZA0wb4pon2o8iQ==", - "dev": true + "integrity": "sha512-DCRfO/4nQ+89p/RK43i8Ezd41EqdGIU4ld7nGF8OQ14oc/we5rEntLCUa7+jrn3nn83BosfwZA0wb4pon2o8iQ==" }, "ajv-keywords": { - "version": "3.4.0", - "resolved": "https://registry.npmjs.org/ajv-keywords/-/ajv-keywords-3.4.0.tgz", - "integrity": "sha512-aUjdRFISbuFOl0EIZc+9e4FfZp0bDZgAdOOf30bJmw8VM9v84SHyVyxDfbWxpGYbdZD/9XoKxfHVNmxPkhwyGw==", - "dev": true + "version": "3.4.1", + "resolved": "https://registry.npmjs.org/ajv-keywords/-/ajv-keywords-3.4.1.tgz", + "integrity": "sha512-RO1ibKvd27e6FEShVFfPALuHI3WjSVNeK5FIsmme/LYRNxjKuNj+Dt7bucLa6NdSv3JcVTyMlm9kGR84z1XpaQ==" }, "algoliasearch": { - "version": "3.33.0", - "resolved": "https://registry.npmjs.org/algoliasearch/-/algoliasearch-3.33.0.tgz", - "integrity": "sha512-9DaVmOd7cvcZeYyV0BWAeJHVWJmgOL2DNUEBY/DTR4MzD1wCWs4Djl7LAlfvkGwGBdRHZCG+l0HA1572w3T8zg==", - "dev": true, + "version": "3.35.1", + "resolved": "https://registry.npmjs.org/algoliasearch/-/algoliasearch-3.35.1.tgz", + "integrity": "sha512-K4yKVhaHkXfJ/xcUnil04xiSrB8B8yHZoFEhWNpXg23eiCnqvTZw1tn/SqvdsANlYHLJlKl0qi3I/Q2Sqo7LwQ==", "requires": { "agentkeepalive": "^2.2.0", "debug": "^2.6.9", @@ -1450,7 +1443,6 @@ "version": "2.6.9", "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", - "dev": true, "requires": { "ms": "2.0.0" } @@ -1458,46 +1450,39 @@ "events": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/events/-/events-1.1.1.tgz", - "integrity": "sha1-nr23Y1rQmccNzEwqH1AEKI6L2SQ=", - "dev": true + "integrity": "sha1-nr23Y1rQmccNzEwqH1AEKI6L2SQ=" }, "isarray": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/isarray/-/isarray-2.0.4.tgz", - "integrity": "sha512-GMxXOiUirWg1xTKRipM0Ek07rX+ubx4nNVElTJdNLYmNO/2YrDkgJGw9CljXn+r4EWiDQg/8lsRdHyg2PJuUaA==", - "dev": true - }, - "ms": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", - "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=", - "dev": true + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/isarray/-/isarray-2.0.5.tgz", + "integrity": "sha512-xHjhDr3cNBK0BzdUJSPXZntQUx/mwMS5Rw4A7lPJ90XGAO6ISP/ePDNuo0vhqOZU+UD5JoodwCAAoZQd3FeAKw==" } } }, + "align-text": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/align-text/-/align-text-0.1.4.tgz", + "integrity": "sha1-DNkKVhCT810KmSVsIrcGlDP60Rc=", + "requires": { + "kind-of": "^3.0.2", + "longest": "^1.0.1", + "repeat-string": "^1.5.2" + } + }, "alphanum-sort": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/alphanum-sort/-/alphanum-sort-1.0.2.tgz", - "integrity": "sha1-l6ERlkmyEa0zaR2fn0hqjsn74KM=", - "dev": true - }, - "amdefine": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/amdefine/-/amdefine-1.0.1.tgz", - "integrity": "sha1-SlKCrBZHKek2Gbz9OtFR+BfOkfU=", - "dev": true + "integrity": "sha1-l6ERlkmyEa0zaR2fn0hqjsn74KM=" }, "ansi-colors": { "version": "3.2.4", "resolved": "https://registry.npmjs.org/ansi-colors/-/ansi-colors-3.2.4.tgz", - "integrity": "sha512-hHUXGagefjN2iRrID63xckIvotOXOojhQKWIPUZ4mNUZ9nLZW+7FMNoE1lOkEhNWYsx/7ysGIuJYCiMAA9FnrA==", - "dev": true + "integrity": "sha512-hHUXGagefjN2iRrID63xckIvotOXOojhQKWIPUZ4mNUZ9nLZW+7FMNoE1lOkEhNWYsx/7ysGIuJYCiMAA9FnrA==" }, "ansi-escapes": { - "version": "4.2.0", - "resolved": "https://registry.npmjs.org/ansi-escapes/-/ansi-escapes-4.2.0.tgz", - "integrity": "sha512-0+VX4uhi8m3aNbzoqKmkAVOEj6uQzcUHXoFPkKjhZPTpGRUBqVh930KbB6PS4zIyDZccphlLIYlu8nsjFzkXwg==", - "dev": true, + "version": "4.2.1", + "resolved": "https://registry.npmjs.org/ansi-escapes/-/ansi-escapes-4.2.1.tgz", + "integrity": "sha512-Cg3ymMAdN10wOk/VYfLV7KCQyv7EDirJ64500sU7n9UlmioEtDuU5Gd+hj73hXSU/ex7tHJSssmyftDdkMLO8Q==", "requires": { "type-fest": "^0.5.2" } @@ -1505,20 +1490,17 @@ "ansi-html": { "version": "0.0.7", "resolved": "https://registry.npmjs.org/ansi-html/-/ansi-html-0.0.7.tgz", - "integrity": "sha1-gTWEAhliqenm/QOflA0S9WynhZ4=", - "dev": true + "integrity": "sha1-gTWEAhliqenm/QOflA0S9WynhZ4=" }, "ansi-regex": { "version": "2.1.1", "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-2.1.1.tgz", - "integrity": "sha1-w7M6te42DYbg5ijwRorn7yfWVN8=", - "dev": true + "integrity": "sha1-w7M6te42DYbg5ijwRorn7yfWVN8=" }, "ansi-styles": { "version": "3.2.1", "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", - "dev": true, "requires": { "color-convert": "^1.9.0" } @@ -1527,7 +1509,6 @@ "version": "2.0.0", "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-2.0.0.tgz", "integrity": "sha512-5teOsQWABXHHBFP9y3skS5P3d/WfWXpv3FUpy+LorMrNYaT9pI4oLMQX7jzQ2KklNpGpWHzdCXTDT2Y3XGlZBw==", - "dev": true, "requires": { "micromatch": "^3.1.4", "normalize-path": "^2.1.1" @@ -1537,7 +1518,6 @@ "version": "2.1.1", "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-2.1.1.tgz", "integrity": "sha1-GrKLVW4Zg2Oowab35vogE3/mrtk=", - "dev": true, "requires": { "remove-trailing-separator": "^1.0.1" } @@ -1547,14 +1527,12 @@ "aproba": { "version": "1.2.0", "resolved": "https://registry.npmjs.org/aproba/-/aproba-1.2.0.tgz", - "integrity": "sha512-Y9J6ZjXtoYh8RnXVCMOU/ttDmk1aBjunq9vO0ta5x85WDQiQfUF9sIPBITdbiiIVcBo03Hi3jMxigBtsddlXRw==", - "dev": true + "integrity": "sha512-Y9J6ZjXtoYh8RnXVCMOU/ttDmk1aBjunq9vO0ta5x85WDQiQfUF9sIPBITdbiiIVcBo03Hi3jMxigBtsddlXRw==" }, "argparse": { "version": "1.0.10", "resolved": "https://registry.npmjs.org/argparse/-/argparse-1.0.10.tgz", "integrity": "sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg==", - "dev": true, "requires": { "sprintf-js": "~1.0.2" } @@ -1562,32 +1540,27 @@ "arr-diff": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/arr-diff/-/arr-diff-4.0.0.tgz", - "integrity": "sha1-1kYQdP6/7HHn4VI1dhoyml3HxSA=", - "dev": true + "integrity": "sha1-1kYQdP6/7HHn4VI1dhoyml3HxSA=" }, "arr-flatten": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/arr-flatten/-/arr-flatten-1.1.0.tgz", - "integrity": "sha512-L3hKV5R/p5o81R7O02IGnwpDmkp6E982XhtbuwSe3O4qOtMMMtodicASA1Cny2U+aCXcNpml+m4dPsvsJ3jatg==", - "dev": true + "integrity": "sha512-L3hKV5R/p5o81R7O02IGnwpDmkp6E982XhtbuwSe3O4qOtMMMtodicASA1Cny2U+aCXcNpml+m4dPsvsJ3jatg==" }, "arr-union": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/arr-union/-/arr-union-3.1.0.tgz", - "integrity": "sha1-45sJrqne+Gao8gbiiK9jkZuuOcQ=", - "dev": true + "integrity": "sha1-45sJrqne+Gao8gbiiK9jkZuuOcQ=" }, "array-flatten": { "version": "2.1.2", "resolved": "https://registry.npmjs.org/array-flatten/-/array-flatten-2.1.2.tgz", - "integrity": "sha512-hNfzcOV8W4NdualtqBFPyVO+54DSJuZGY9qT4pRroB6S9e3iiido2ISIC5h9R2sPJ8H3FHCIiEnsv1lPXO3KtQ==", - "dev": true + "integrity": "sha512-hNfzcOV8W4NdualtqBFPyVO+54DSJuZGY9qT4pRroB6S9e3iiido2ISIC5h9R2sPJ8H3FHCIiEnsv1lPXO3KtQ==" }, "array-union": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/array-union/-/array-union-1.0.2.tgz", "integrity": "sha1-mjRBDk9OPaI96jdb5b5w8kd47Dk=", - "dev": true, "requires": { "array-uniq": "^1.0.1" } @@ -1595,20 +1568,22 @@ "array-uniq": { "version": "1.0.3", "resolved": "https://registry.npmjs.org/array-uniq/-/array-uniq-1.0.3.tgz", - "integrity": "sha1-r2rId6Jcx/dOBYiUdThY39sk/bY=", - "dev": true + "integrity": "sha1-r2rId6Jcx/dOBYiUdThY39sk/bY=" }, "array-unique": { "version": "0.3.2", "resolved": "https://registry.npmjs.org/array-unique/-/array-unique-0.3.2.tgz", - "integrity": "sha1-qJS3XUvE9s1nnvMkSp/Y9Gri1Cg=", - "dev": true + "integrity": "sha1-qJS3XUvE9s1nnvMkSp/Y9Gri1Cg=" + }, + "asap": { + "version": "2.0.6", + "resolved": "https://registry.npmjs.org/asap/-/asap-2.0.6.tgz", + "integrity": "sha1-5QNHYR1+aQlDIIu9r+vLwvuGbUY=" }, "asn1": { "version": "0.2.4", "resolved": "https://registry.npmjs.org/asn1/-/asn1-0.2.4.tgz", "integrity": "sha512-jxwzQpLQjSmWXgwaCZE9Nz+glAG01yF1QnWgbhGwHI5A6FRIEY6IVqtHhIepHqI7/kyEyQEagBC5mBEFlIYvdg==", - "dev": true, "requires": { "safer-buffer": "~2.1.0" } @@ -1617,7 +1592,6 @@ "version": "4.10.1", "resolved": "https://registry.npmjs.org/asn1.js/-/asn1.js-4.10.1.tgz", "integrity": "sha512-p32cOF5q0Zqs9uBiONKYLm6BClCoBCM5O9JfeUSlnQLBTxYdTK+pW+nXflm8UkKd2UYlEbYz5qEi0JuZR9ckSw==", - "dev": true, "requires": { "bn.js": "^4.0.0", "inherits": "^2.0.1", @@ -1628,7 +1602,6 @@ "version": "1.5.0", "resolved": "https://registry.npmjs.org/assert/-/assert-1.5.0.tgz", "integrity": "sha512-EDsgawzwoun2CZkCgtxJbv392v4nbk9XDD06zI+kQYoBM/3RBWLlEyJARDOmhAAosBjWACEkKL6S+lIZtcAubA==", - "dev": true, "requires": { "object-assign": "^4.1.1", "util": "0.10.3" @@ -1637,14 +1610,12 @@ "inherits": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.1.tgz", - "integrity": "sha1-sX0I0ya0Qj5Wjv9xn5GwscvfafE=", - "dev": true + "integrity": "sha1-sX0I0ya0Qj5Wjv9xn5GwscvfafE=" }, "util": { "version": "0.10.3", "resolved": "https://registry.npmjs.org/util/-/util-0.10.3.tgz", "integrity": "sha1-evsa/lCAUkZInj23/g7TeTNqwPk=", - "dev": true, "requires": { "inherits": "2.0.1" } @@ -1654,117 +1625,77 @@ "assert-plus": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/assert-plus/-/assert-plus-1.0.0.tgz", - "integrity": "sha1-8S4PPF13sLHN2RRpQuTpbB5N1SU=", - "dev": true + "integrity": "sha1-8S4PPF13sLHN2RRpQuTpbB5N1SU=" }, "assign-symbols": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/assign-symbols/-/assign-symbols-1.0.0.tgz", - "integrity": "sha1-WWZ/QfrdTyDMvCu5a41Pf3jsA2c=", - "dev": true + "integrity": "sha1-WWZ/QfrdTyDMvCu5a41Pf3jsA2c=" }, "async": { - "version": "1.5.2", - "resolved": "https://registry.npmjs.org/async/-/async-1.5.2.tgz", - "integrity": "sha1-7GphrlZIDAw8skHJVhjiCJL5Zyo=", - "dev": true + "version": "2.6.3", + "resolved": "https://registry.npmjs.org/async/-/async-2.6.3.tgz", + "integrity": "sha512-zflvls11DCy+dQWzTW2dzuilv8Z5X/pjfmZOWba6TNIVDm+2UDaJmXSOXlasHKfNBs8oo3M0aT50fDEWfKZjXg==", + "requires": { + "lodash": "^4.17.14" + } }, "async-each": { "version": "1.0.3", "resolved": "https://registry.npmjs.org/async-each/-/async-each-1.0.3.tgz", - "integrity": "sha512-z/WhQ5FPySLdvREByI2vZiTWwCnF0moMJ1hK9YQwDTHKh6I7/uSckMetoRGb5UBZPC1z0jlw+n/XCgjeH7y1AQ==", - "dev": true + "integrity": "sha512-z/WhQ5FPySLdvREByI2vZiTWwCnF0moMJ1hK9YQwDTHKh6I7/uSckMetoRGb5UBZPC1z0jlw+n/XCgjeH7y1AQ==" + }, + "async-limiter": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/async-limiter/-/async-limiter-1.0.1.tgz", + "integrity": "sha512-csOlWGAcRFJaI6m+F2WKdnMKr4HhdhFVBk0H/QbJFMCr+uO2kwohwXQPxw/9OCxp05r5ghVBFSyioixx3gfkNQ==" }, "asynckit": { "version": "0.4.0", "resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz", - "integrity": "sha1-x57Zf380y48robyXkLzDZkdLS3k=", - "dev": true + "integrity": "sha1-x57Zf380y48robyXkLzDZkdLS3k=" }, "atob": { "version": "2.1.2", "resolved": "https://registry.npmjs.org/atob/-/atob-2.1.2.tgz", - "integrity": "sha512-Wm6ukoaOGJi/73p/cl2GvLjTI5JM1k/O14isD73YML8StrH/7/lRFgmg8nICZgD3bZZvjwCGxtMOD3wWNAu8cg==", - "dev": true + "integrity": "sha512-Wm6ukoaOGJi/73p/cl2GvLjTI5JM1k/O14isD73YML8StrH/7/lRFgmg8nICZgD3bZZvjwCGxtMOD3wWNAu8cg==" }, "autocomplete.js": { "version": "0.36.0", "resolved": "https://registry.npmjs.org/autocomplete.js/-/autocomplete.js-0.36.0.tgz", "integrity": "sha512-jEwUXnVMeCHHutUt10i/8ZiRaCb0Wo+ZyKxeGsYwBDtw6EJHqEeDrq4UwZRD8YBSvp3g6klP678il2eeiVXN2Q==", - "dev": true, "requires": { "immediate": "^3.2.3" } }, "autoprefixer": { - "version": "9.6.0", - "resolved": "https://registry.npmjs.org/autoprefixer/-/autoprefixer-9.6.0.tgz", - "integrity": "sha512-kuip9YilBqhirhHEGHaBTZKXL//xxGnzvsD0FtBQa6z+A69qZD6s/BAX9VzDF1i9VKDquTJDQaPLSEhOnL6FvQ==", - "dev": true, + "version": "9.7.0", + "resolved": "https://registry.npmjs.org/autoprefixer/-/autoprefixer-9.7.0.tgz", + "integrity": "sha512-j2IRvaCfrUxIiZun9ba4mhJ2omhw4OY88/yVzLO+lHhGBumAAK72PgM6gkbSN8iregPOn1ZlxGkmZh2CQ7X4AQ==", "requires": { - "browserslist": "^4.6.1", - "caniuse-lite": "^1.0.30000971", + "browserslist": "^4.7.2", + "caniuse-lite": "^1.0.30001004", "chalk": "^2.4.2", "normalize-range": "^0.1.2", "num2fraction": "^1.2.2", - "postcss": "^7.0.16", - "postcss-value-parser": "^3.3.1" + "postcss": "^7.0.19", + "postcss-value-parser": "^4.0.2" } }, "aws-sign2": { "version": "0.7.0", "resolved": "https://registry.npmjs.org/aws-sign2/-/aws-sign2-0.7.0.tgz", - "integrity": "sha1-tG6JCTSpWR8tL2+G1+ap8bP+dqg=", - "dev": true + "integrity": "sha1-tG6JCTSpWR8tL2+G1+ap8bP+dqg=" }, "aws4": { "version": "1.8.0", "resolved": "https://registry.npmjs.org/aws4/-/aws4-1.8.0.tgz", - "integrity": "sha512-ReZxvNHIOv88FlT7rxcXIIC0fPt4KZqZbOlivyWtXLt8ESx84zd3kMC6iK5jVeS2qt+g7ftS7ye4fi06X5rtRQ==", - "dev": true - }, - "axios": { - "version": "0.19.0", - "resolved": "https://registry.npmjs.org/axios/-/axios-0.19.0.tgz", - "integrity": "sha512-1uvKqKQta3KBxIz14F2v06AEHZ/dIoeKfbTRkK1E5oqjDnuEerLmYTgJB5AiQZHJcljpg1TuRzdjDR06qNk0DQ==", - "requires": { - "follow-redirects": "1.5.10", - "is-buffer": "^2.0.2" - }, - "dependencies": { - "debug": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/debug/-/debug-3.1.0.tgz", - "integrity": "sha512-OX8XqP7/1a9cqkxYw2yXss15f26NKWBpDXQd0/uK/KPqdQhxbPa994hnzjcE2VqQpDslf55723cKPUOGSmMY3g==", - "requires": { - "ms": "2.0.0" - } - }, - "follow-redirects": { - "version": "1.5.10", - "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.5.10.tgz", - "integrity": "sha512-0V5l4Cizzvqt5D44aTXbFZz+FtyXV1vrDN6qrelxtfYQKW0KO0W2T/hkE8xvGa/540LkZlkaUjO4ailYTFtHVQ==", - "requires": { - "debug": "=3.1.0" - } - }, - "is-buffer": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/is-buffer/-/is-buffer-2.0.3.tgz", - "integrity": "sha512-U15Q7MXTuZlrbymiz95PJpZxu8IlipAp4dtS3wOdgPXx3mqBnslrWU14kxfHB+Py/+2PVKSr37dMAgM2A4uArw==" - }, - "ms": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", - "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=" - } - } + "integrity": "sha512-ReZxvNHIOv88FlT7rxcXIIC0fPt4KZqZbOlivyWtXLt8ESx84zd3kMC6iK5jVeS2qt+g7ftS7ye4fi06X5rtRQ==" }, "babel-loader": { "version": "8.0.6", "resolved": "https://registry.npmjs.org/babel-loader/-/babel-loader-8.0.6.tgz", "integrity": "sha512-4BmWKtBOBm13uoUwd08UwjZlaw3O9GWf456R9j+5YykFZ6LUIjIKLc0zEZf+hauxPOJs96C8k6FvYD09vWzhYw==", - "dev": true, "requires": { "find-cache-dir": "^2.0.0", "loader-utils": "^1.0.2", @@ -1776,7 +1707,6 @@ "version": "2.3.0", "resolved": "https://registry.npmjs.org/babel-plugin-dynamic-import-node/-/babel-plugin-dynamic-import-node-2.3.0.tgz", "integrity": "sha512-o6qFkpeQEBxcqt0XYlWzAVxNCSCZdUgcR8IRlhD/8DylxjjO4foPcvTW0GGKa/cVt3rvxZ7o5ippJ+/0nvLhlQ==", - "dev": true, "requires": { "object.assign": "^4.1.0" } @@ -1785,7 +1715,6 @@ "version": "3.2.0", "resolved": "https://registry.npmjs.org/babel-plugin-module-resolver/-/babel-plugin-module-resolver-3.2.0.tgz", "integrity": "sha512-tjR0GvSndzPew/Iayf4uICWZqjBwnlMWjSx6brryfQ81F9rxBVqwDJtFCV8oOs0+vJeefK9TmdZtkIFdFe1UnA==", - "dev": true, "requires": { "find-babel-config": "^1.1.0", "glob": "^7.1.2", @@ -1794,17 +1723,40 @@ "resolve": "^1.4.0" } }, + "babel-runtime": { + "version": "6.26.0", + "resolved": "https://registry.npmjs.org/babel-runtime/-/babel-runtime-6.26.0.tgz", + "integrity": "sha1-llxwWGaOgrVde/4E/yM3vItWR/4=", + "requires": { + "core-js": "^2.4.0", + "regenerator-runtime": "^0.11.0" + } + }, + "babel-types": { + "version": "6.26.0", + "resolved": "https://registry.npmjs.org/babel-types/-/babel-types-6.26.0.tgz", + "integrity": "sha1-o7Bz+Uq0nrb6Vc1lInozQ4BjJJc=", + "requires": { + "babel-runtime": "^6.26.0", + "esutils": "^2.0.2", + "lodash": "^4.17.4", + "to-fast-properties": "^1.0.3" + } + }, + "babylon": { + "version": "6.18.0", + "resolved": "https://registry.npmjs.org/babylon/-/babylon-6.18.0.tgz", + "integrity": "sha512-q/UEjfGJ2Cm3oKV71DJz9d25TPnq5rhBVL2Q4fA5wcC3jcrdn7+SssEybFIxwAvvP+YCsCYNKughoF33GxgycQ==" + }, "balanced-match": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.0.tgz", - "integrity": "sha1-ibTRmasr7kneFk6gK4nORi1xt2c=", - "dev": true + "integrity": "sha1-ibTRmasr7kneFk6gK4nORi1xt2c=" }, "base": { "version": "0.11.2", "resolved": "https://registry.npmjs.org/base/-/base-0.11.2.tgz", "integrity": "sha512-5T6P4xPgpp0YDFvSWwEZ4NoE3aM4QBQXDzmVbraCkFj8zHM+mba8SyqB5DbZWyR7mYHo6Y7BdQo3MoA4m0TeQg==", - "dev": true, "requires": { "cache-base": "^1.0.1", "class-utils": "^0.3.5", @@ -1819,7 +1771,6 @@ "version": "1.0.0", "resolved": "https://registry.npmjs.org/define-property/-/define-property-1.0.0.tgz", "integrity": "sha1-dp66rz9KY6rTr56NMEybvnm/sOY=", - "dev": true, "requires": { "is-descriptor": "^1.0.0" } @@ -1828,7 +1779,6 @@ "version": "1.0.0", "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-1.0.0.tgz", "integrity": "sha512-m5hnHTkcVsPfqx3AKlyttIPb7J+XykHvJP2B9bZDjlhLIoEq4XoK64Vg7boZlVWYK6LUY94dYPEE7Lh0ZkZKcQ==", - "dev": true, "requires": { "kind-of": "^6.0.0" } @@ -1837,7 +1787,6 @@ "version": "1.0.0", "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-1.0.0.tgz", "integrity": "sha512-jbRXy1FmtAoCjQkVmIVYwuuqDFUbaOeDjmed1tOGPrsMhtJA4rD9tkgA0F1qJ3gRFRXcHYVkdeaP50Q5rE/jLQ==", - "dev": true, "requires": { "kind-of": "^6.0.0" } @@ -1846,32 +1795,33 @@ "version": "1.0.2", "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-1.0.2.tgz", "integrity": "sha512-2eis5WqQGV7peooDyLmNEPUrps9+SXX5c9pL3xEB+4e9HnGuDa7mB7kHxHw4CbqS9k1T2hOH3miL8n8WtiYVtg==", - "dev": true, "requires": { "is-accessor-descriptor": "^1.0.0", "is-data-descriptor": "^1.0.0", "kind-of": "^6.0.2" } + }, + "kind-of": { + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.2.tgz", + "integrity": "sha512-s5kLOcnH0XqDO+FvuaLX8DDjZ18CGFk7VygH40QoKPUQhW4e2rvM0rwUq0t8IQDOwYSeLK01U90OjzBTme2QqA==" } } }, "base64-js": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/base64-js/-/base64-js-1.3.0.tgz", - "integrity": "sha512-ccav/yGvoa80BQDljCxsmmQ3Xvx60/UpBIij5QN21W3wBi/hhIC9OoO+KLpu9IJTS9j4DRVJ3aDDF9cMSoa2lw==", - "dev": true + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/base64-js/-/base64-js-1.3.1.tgz", + "integrity": "sha512-mLQ4i2QO1ytvGWFWmcngKO//JXAQueZvwEKtjgQFM4jIK0kU+ytMfplL8j+n5mspOfjHwoAg+9yhb7BwAHm36g==" }, "batch": { "version": "0.6.1", "resolved": "https://registry.npmjs.org/batch/-/batch-0.6.1.tgz", - "integrity": "sha1-3DQxT05nkxgJP8dgJyUl+UvyXBY=", - "dev": true + "integrity": "sha1-3DQxT05nkxgJP8dgJyUl+UvyXBY=" }, "bcrypt-pbkdf": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/bcrypt-pbkdf/-/bcrypt-pbkdf-1.0.2.tgz", "integrity": "sha1-pDAdOJtqQ/m2f/PKEaP2Y342Dp4=", - "dev": true, "requires": { "tweetnacl": "^0.14.3" } @@ -1879,32 +1829,27 @@ "big.js": { "version": "5.2.2", "resolved": "https://registry.npmjs.org/big.js/-/big.js-5.2.2.tgz", - "integrity": "sha512-vyL2OymJxmarO8gxMr0mhChsO9QGwhynfuu4+MHTAW6czfq9humCB7rKpUjDd9YUiDPU4mzpyupFSvOClAwbmQ==", - "dev": true + "integrity": "sha512-vyL2OymJxmarO8gxMr0mhChsO9QGwhynfuu4+MHTAW6czfq9humCB7rKpUjDd9YUiDPU4mzpyupFSvOClAwbmQ==" }, "binary-extensions": { "version": "1.13.1", "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-1.13.1.tgz", - "integrity": "sha512-Un7MIEDdUC5gNpcGDV97op1Ywk748MpHcFTHoYs6qnj1Z3j7I53VG3nwZhKzoBZmbdRNnb6WRdFlwl7tSDuZGw==", - "dev": true + "integrity": "sha512-Un7MIEDdUC5gNpcGDV97op1Ywk748MpHcFTHoYs6qnj1Z3j7I53VG3nwZhKzoBZmbdRNnb6WRdFlwl7tSDuZGw==" }, "bluebird": { - "version": "3.5.5", - "resolved": "https://registry.npmjs.org/bluebird/-/bluebird-3.5.5.tgz", - "integrity": "sha512-5am6HnnfN+urzt4yfg7IgTbotDjIT/u8AJpEt0sIU9FtXfVeezXAPKswrG+xKUCOYAINpSdgZVDU6QFh+cuH3w==", - "dev": true + "version": "3.7.1", + "resolved": "https://registry.npmjs.org/bluebird/-/bluebird-3.7.1.tgz", + "integrity": "sha512-DdmyoGCleJnkbp3nkbxTLJ18rjDsE4yCggEwKNXkeV123sPNfOCYeDoeuOY+F2FrSjO1YXcTU+dsy96KMy+gcg==" }, "bn.js": { "version": "4.11.8", "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.11.8.tgz", - "integrity": "sha512-ItfYfPLkWHUjckQCk8xC+LwxgK8NYcXywGigJgSwOP8Y2iyWT4f2vsZnoOXTTbo+o5yXmIUJ4gn5538SO5S3gA==", - "dev": true + "integrity": "sha512-ItfYfPLkWHUjckQCk8xC+LwxgK8NYcXywGigJgSwOP8Y2iyWT4f2vsZnoOXTTbo+o5yXmIUJ4gn5538SO5S3gA==" }, "body-parser": { "version": "1.19.0", "resolved": "https://registry.npmjs.org/body-parser/-/body-parser-1.19.0.tgz", "integrity": "sha512-dhEPs72UPbDnAQJ9ZKMNTP6ptJaionhP5cBb541nXPlW60Jepo9RV/a4fX4XWW9CuFNK22krhrj1+rgzifNCsw==", - "dev": true, "requires": { "bytes": "3.1.0", "content-type": "~1.0.4", @@ -1921,23 +1866,15 @@ "bytes": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/bytes/-/bytes-3.1.0.tgz", - "integrity": "sha512-zauLjrfCG+xvoyaqLoV8bLVXXNGC4JqlxFCutSDWA6fJrTo2ZuvLYTqZ7aHBLZSMOopbzwv8f+wZcVzfVTI2Dg==", - "dev": true + "integrity": "sha512-zauLjrfCG+xvoyaqLoV8bLVXXNGC4JqlxFCutSDWA6fJrTo2ZuvLYTqZ7aHBLZSMOopbzwv8f+wZcVzfVTI2Dg==" }, "debug": { "version": "2.6.9", "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", - "dev": true, "requires": { "ms": "2.0.0" } - }, - "ms": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", - "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=", - "dev": true } } }, @@ -1945,7 +1882,6 @@ "version": "3.5.0", "resolved": "https://registry.npmjs.org/bonjour/-/bonjour-3.5.0.tgz", "integrity": "sha1-jokKGD2O6aI5OzhExpGkK897yfU=", - "dev": true, "requires": { "array-flatten": "^2.1.0", "deep-equal": "^1.0.1", @@ -1958,14 +1894,12 @@ "boolbase": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/boolbase/-/boolbase-1.0.0.tgz", - "integrity": "sha1-aN/1++YMUes3cl6p4+0xDcwed24=", - "dev": true + "integrity": "sha1-aN/1++YMUes3cl6p4+0xDcwed24=" }, "brace-expansion": { "version": "1.1.11", "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", - "dev": true, "requires": { "balanced-match": "^1.0.0", "concat-map": "0.0.1" @@ -1975,7 +1909,6 @@ "version": "2.3.2", "resolved": "https://registry.npmjs.org/braces/-/braces-2.3.2.tgz", "integrity": "sha512-aNdbnj9P8PjdXU4ybaWLK2IF3jc/EoDYbC7AazW6to3TRsfXxscC9UXOB5iDiEQrkyIbWp2SLQda4+QAa7nc3w==", - "dev": true, "requires": { "arr-flatten": "^1.1.0", "array-unique": "^0.3.2", @@ -1993,7 +1926,6 @@ "version": "2.0.1", "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", - "dev": true, "requires": { "is-extendable": "^0.1.0" } @@ -2003,14 +1935,12 @@ "brorand": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/brorand/-/brorand-1.1.0.tgz", - "integrity": "sha1-EsJe/kCkXjwyPrhnWgoM5XsiNx8=", - "dev": true + "integrity": "sha1-EsJe/kCkXjwyPrhnWgoM5XsiNx8=" }, "browserify-aes": { "version": "1.2.0", "resolved": "https://registry.npmjs.org/browserify-aes/-/browserify-aes-1.2.0.tgz", "integrity": "sha512-+7CHXqGuspUn/Sl5aO7Ea0xWGAtETPXNSAjHo48JfLdPWcMng33Xe4znFvQweqc/uzk5zSOI3H52CYnjCfb5hA==", - "dev": true, "requires": { "buffer-xor": "^1.0.3", "cipher-base": "^1.0.0", @@ -2024,7 +1954,6 @@ "version": "1.0.1", "resolved": "https://registry.npmjs.org/browserify-cipher/-/browserify-cipher-1.0.1.tgz", "integrity": "sha512-sPhkz0ARKbf4rRQt2hTpAHqn47X3llLkUGn+xEJzLjwY8LRs2p0v7ljvI5EyoRO/mexrNunNECisZs+gw2zz1w==", - "dev": true, "requires": { "browserify-aes": "^1.0.4", "browserify-des": "^1.0.0", @@ -2035,7 +1964,6 @@ "version": "1.0.2", "resolved": "https://registry.npmjs.org/browserify-des/-/browserify-des-1.0.2.tgz", "integrity": "sha512-BioO1xf3hFwz4kc6iBhI3ieDFompMhrMlnDFC4/0/vd5MokpuAc3R+LYbwTA9A5Yc9pq9UYPqffKpW2ObuwX5A==", - "dev": true, "requires": { "cipher-base": "^1.0.1", "des.js": "^1.0.0", @@ -2047,7 +1975,6 @@ "version": "4.0.1", "resolved": "https://registry.npmjs.org/browserify-rsa/-/browserify-rsa-4.0.1.tgz", "integrity": "sha1-IeCr+vbyApzy+vsTNWenAdQTVSQ=", - "dev": true, "requires": { "bn.js": "^4.1.0", "randombytes": "^2.0.1" @@ -2057,7 +1984,6 @@ "version": "4.0.4", "resolved": "https://registry.npmjs.org/browserify-sign/-/browserify-sign-4.0.4.tgz", "integrity": "sha1-qk62jl17ZYuqa/alfmMMvXqT0pg=", - "dev": true, "requires": { "bn.js": "^4.1.1", "browserify-rsa": "^4.0.0", @@ -2072,27 +1998,24 @@ "version": "0.2.0", "resolved": "https://registry.npmjs.org/browserify-zlib/-/browserify-zlib-0.2.0.tgz", "integrity": "sha512-Z942RysHXmJrhqk88FmKBVq/v5tqmSkDz7p54G/MGyjMnCFFnC79XWNbg+Vta8W6Wb2qtSZTSxIGkJrRpCFEiA==", - "dev": true, "requires": { "pako": "~1.0.5" } }, "browserslist": { - "version": "4.6.3", - "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.6.3.tgz", - "integrity": "sha512-CNBqTCq22RKM8wKJNowcqihHJ4SkI8CGeK7KOR9tPboXUuS5Zk5lQgzzTbs4oxD8x+6HUshZUa2OyNI9lR93bQ==", - "dev": true, + "version": "4.7.2", + "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.7.2.tgz", + "integrity": "sha512-uZavT/gZXJd2UTi9Ov7/Z340WOSQ3+m1iBVRUknf+okKxonL9P83S3ctiBDtuRmRu8PiCHjqyueqQ9HYlJhxiw==", "requires": { - "caniuse-lite": "^1.0.30000975", - "electron-to-chromium": "^1.3.164", - "node-releases": "^1.1.23" + "caniuse-lite": "^1.0.30001004", + "electron-to-chromium": "^1.3.295", + "node-releases": "^1.1.38" } }, "buffer": { "version": "4.9.1", "resolved": "https://registry.npmjs.org/buffer/-/buffer-4.9.1.tgz", "integrity": "sha1-bRu2AbB6TvztlwlBMgkwJ8lbwpg=", - "dev": true, "requires": { "base64-js": "^1.0.2", "ieee754": "^1.1.4", @@ -2102,50 +2025,42 @@ "buffer-from": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/buffer-from/-/buffer-from-1.1.1.tgz", - "integrity": "sha512-MQcXEUbCKtEo7bhqEs6560Hyd4XaovZlO/k9V3hjVUF/zwW7KBVdSK4gIt/bzwS9MbR5qob+F5jusZsb0YQK2A==", - "dev": true + "integrity": "sha512-MQcXEUbCKtEo7bhqEs6560Hyd4XaovZlO/k9V3hjVUF/zwW7KBVdSK4gIt/bzwS9MbR5qob+F5jusZsb0YQK2A==" }, "buffer-indexof": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/buffer-indexof/-/buffer-indexof-1.1.1.tgz", - "integrity": "sha512-4/rOEg86jivtPTeOUUT61jJO1Ya1TrR/OkqCSZDyq84WJh3LuuiphBYJN+fm5xufIk4XAFcEwte/8WzC8If/1g==", - "dev": true + "integrity": "sha512-4/rOEg86jivtPTeOUUT61jJO1Ya1TrR/OkqCSZDyq84WJh3LuuiphBYJN+fm5xufIk4XAFcEwte/8WzC8If/1g==" }, "buffer-json": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/buffer-json/-/buffer-json-2.0.0.tgz", - "integrity": "sha512-+jjPFVqyfF1esi9fvfUs3NqM0pH1ziZ36VP4hmA/y/Ssfo/5w5xHKfTw9BwQjoJ1w/oVtpLomqwUHKdefGyuHw==", - "dev": true + "integrity": "sha512-+jjPFVqyfF1esi9fvfUs3NqM0pH1ziZ36VP4hmA/y/Ssfo/5w5xHKfTw9BwQjoJ1w/oVtpLomqwUHKdefGyuHw==" }, "buffer-xor": { "version": "1.0.3", "resolved": "https://registry.npmjs.org/buffer-xor/-/buffer-xor-1.0.3.tgz", - "integrity": "sha1-JuYe0UIvtw3ULm42cp7VHYVf6Nk=", - "dev": true + "integrity": "sha1-JuYe0UIvtw3ULm42cp7VHYVf6Nk=" }, "builtin-status-codes": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/builtin-status-codes/-/builtin-status-codes-3.0.0.tgz", - "integrity": "sha1-hZgoeOIbmOHGZCXgPQF0eI9Wnug=", - "dev": true + "integrity": "sha1-hZgoeOIbmOHGZCXgPQF0eI9Wnug=" }, "bytes": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/bytes/-/bytes-3.0.0.tgz", - "integrity": "sha1-0ygVQE1olpn4Wk6k+odV3ROpYEg=", - "dev": true + "integrity": "sha1-0ygVQE1olpn4Wk6k+odV3ROpYEg=" }, "cac": { - "version": "6.5.2", - "resolved": "https://registry.npmjs.org/cac/-/cac-6.5.2.tgz", - "integrity": "sha512-8JdiD9/ZLsG418j/chyZQ3VWuhFELSGlH4EUxzNKgIH8wK8dO0j5Pqu6Pk7B/RP3kX9aasyQhPrrUjYO5e0w7w==", - "dev": true + "version": "6.5.3", + "resolved": "https://registry.npmjs.org/cac/-/cac-6.5.3.tgz", + "integrity": "sha512-wZfzSWVXuue1H3J7TDNjbzg4KTqPXCmh7F3QIzEYXfnhMCcOUrx99M7rpO2UDVJA9dqv3butGj2nHvCV47CmPg==" }, "cacache": { "version": "11.3.3", "resolved": "https://registry.npmjs.org/cacache/-/cacache-11.3.3.tgz", "integrity": "sha512-p8WcneCytvzPxhDvYp31PD039vi77I12W+/KfR9S8AZbaiARFBCpsPJS+9uhWfeBfeAtW7o/4vt3MUqLkbY6nA==", - "dev": true, "requires": { "bluebird": "^3.5.5", "chownr": "^1.1.1", @@ -2167,7 +2082,6 @@ "version": "1.0.1", "resolved": "https://registry.npmjs.org/cache-base/-/cache-base-1.0.1.tgz", "integrity": "sha512-AKcdTnFSWATd5/GCPRxr2ChwIJ85CeyrEyjRHlKxQ56d4XJMGym0uAiKn0xbLOGOl3+yRpOTi484dVCEc5AUzQ==", - "dev": true, "requires": { "collection-visit": "^1.0.0", "component-emitter": "^1.2.1", @@ -2184,7 +2098,6 @@ "version": "3.0.1", "resolved": "https://registry.npmjs.org/cache-loader/-/cache-loader-3.0.1.tgz", "integrity": "sha512-HzJIvGiGqYsFUrMjAJNDbVZoG7qQA+vy9AIoKs7s9DscNfki0I589mf2w6/tW+kkFH3zyiknoWV5Jdynu6b/zw==", - "dev": true, "requires": { "buffer-json": "^2.0.0", "find-cache-dir": "^2.1.0", @@ -2197,14 +2110,12 @@ "call-me-maybe": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/call-me-maybe/-/call-me-maybe-1.0.1.tgz", - "integrity": "sha1-JtII6onje1y95gJQoV8DHBak1ms=", - "dev": true + "integrity": "sha1-JtII6onje1y95gJQoV8DHBak1ms=" }, "caller-callsite": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/caller-callsite/-/caller-callsite-2.0.0.tgz", "integrity": "sha1-hH4PzgoiN1CpoCfFSzNzGtMVQTQ=", - "dev": true, "requires": { "callsites": "^2.0.0" } @@ -2213,7 +2124,6 @@ "version": "2.0.0", "resolved": "https://registry.npmjs.org/caller-path/-/caller-path-2.0.0.tgz", "integrity": "sha1-Ro+DBE42mrIBD6xfBs7uFbsssfQ=", - "dev": true, "requires": { "caller-callsite": "^2.0.0" } @@ -2221,30 +2131,26 @@ "callsites": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/callsites/-/callsites-2.0.0.tgz", - "integrity": "sha1-BuuE8A7qQT2oav/vrL/7Ngk7PFA=", - "dev": true + "integrity": "sha1-BuuE8A7qQT2oav/vrL/7Ngk7PFA=" }, "camel-case": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/camel-case/-/camel-case-3.0.0.tgz", "integrity": "sha1-yjw2iKTpzzpM2nd9xNy8cTJJz3M=", - "dev": true, "requires": { "no-case": "^2.2.0", "upper-case": "^1.1.1" } }, "camelcase": { - "version": "5.3.1", - "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-5.3.1.tgz", - "integrity": "sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg==", - "dev": true + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-1.2.1.tgz", + "integrity": "sha1-m7UwTS4LVmmLLHWLCKPqqdqlijk=" }, "caniuse-api": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/caniuse-api/-/caniuse-api-3.0.0.tgz", "integrity": "sha512-bsTwuIg/BZZK/vreVTYYbSWoe2F+71P7K5QGEX+pT250DZbfU1MQ5prOKpPR+LL6uWKK3KMwMCAS74QB3Um1uw==", - "dev": true, "requires": { "browserslist": "^4.0.0", "caniuse-lite": "^1.0.0", @@ -2253,33 +2159,46 @@ } }, "caniuse-lite": { - "version": "1.0.30000978", - "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30000978.tgz", - "integrity": "sha512-H6gK6kxUzG6oAwg/Jal279z8pHw0BzrpZfwo/CA9FFm/vA0l8IhDfkZtepyJNE2Y4V6Dp3P3ubz6czby1/Mgsw==", - "dev": true + "version": "1.0.30001004", + "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001004.tgz", + "integrity": "sha512-3nfOR4O8Wa2RWoYfJkMtwRVOsK96TQ+eq57wd0iKaEWl8dwG4hKZ/g0MVBfCvysFvMLi9fQGR/DvozMdkEPl3g==" }, "caseless": { "version": "0.12.0", "resolved": "https://registry.npmjs.org/caseless/-/caseless-0.12.0.tgz", - "integrity": "sha1-G2gcIf+EAzyCZUMJBolCDRhxUdw=", - "dev": true + "integrity": "sha1-G2gcIf+EAzyCZUMJBolCDRhxUdw=" + }, + "center-align": { + "version": "0.1.3", + "resolved": "https://registry.npmjs.org/center-align/-/center-align-0.1.3.tgz", + "integrity": "sha1-qg0yYptu6XIgBBHL1EYckHvCt60=", + "requires": { + "align-text": "^0.1.3", + "lazy-cache": "^1.0.3" + } }, "chalk": { "version": "2.4.2", "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", - "dev": true, "requires": { "ansi-styles": "^3.2.1", "escape-string-regexp": "^1.0.5", "supports-color": "^5.3.0" } }, + "character-parser": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/character-parser/-/character-parser-2.2.0.tgz", + "integrity": "sha1-x84o821LzZdE5f/CxfzeHHMmH8A=", + "requires": { + "is-regex": "^1.0.3" + } + }, "chokidar": { - "version": "2.1.6", - "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-2.1.6.tgz", - "integrity": "sha512-V2jUo67OKkc6ySiRpJrjlpJKl9kDuG+Xb8VgsGzb+aEouhgS1D0weyPU4lEzdAcsCAvrih2J2BqyXqHWvVLw5g==", - "dev": true, + "version": "2.1.8", + "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-2.1.8.tgz", + "integrity": "sha512-ZmZUazfOzf0Nve7duiCKD23PFSCs4JPoYyccjUFF3aQkQadqBhfzhjkwBH2mNOG9cTBwhamM37EIsIkZw3nRgg==", "requires": { "anymatch": "^2.0.0", "async-each": "^1.0.1", @@ -2296,16 +2215,14 @@ } }, "chownr": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/chownr/-/chownr-1.1.1.tgz", - "integrity": "sha512-j38EvO5+LHX84jlo6h4UzmOwi0UgW61WRyPtJz4qaadK5eY3BTS5TY/S1Stc3Uk2lIM6TPevAlULiEJwie860g==", - "dev": true + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/chownr/-/chownr-1.1.3.tgz", + "integrity": "sha512-i70fVHhmV3DtTl6nqvZOnIjbY0Pe4kAUjwHj8z0zAdgBtYrJyYwLKCCuRBQ5ppkyL0AkN7HKRnETdmdp1zqNXw==" }, "chrome-trace-event": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/chrome-trace-event/-/chrome-trace-event-1.0.2.tgz", "integrity": "sha512-9e/zx1jw7B4CO+c/RXoCsfg/x1AfUBioy4owYH0bJprEYAx5hRFLRhWBqHAG57D0ZM4H7vxbP7bPe0VwhQRYDQ==", - "dev": true, "requires": { "tslib": "^1.9.0" } @@ -2313,14 +2230,12 @@ "ci-info": { "version": "1.6.0", "resolved": "https://registry.npmjs.org/ci-info/-/ci-info-1.6.0.tgz", - "integrity": "sha512-vsGdkwSCDpWmP80ncATX7iea5DWQemg1UgCW5J8tqjU3lYw4FBYuj89J0CTVomA7BEfvSZd84GmHko+MxFQU2A==", - "dev": true + "integrity": "sha512-vsGdkwSCDpWmP80ncATX7iea5DWQemg1UgCW5J8tqjU3lYw4FBYuj89J0CTVomA7BEfvSZd84GmHko+MxFQU2A==" }, "cipher-base": { "version": "1.0.4", "resolved": "https://registry.npmjs.org/cipher-base/-/cipher-base-1.0.4.tgz", "integrity": "sha512-Kkht5ye6ZGmwv40uUDZztayT2ThLQGfnj/T71N/XzeZeo3nf8foyW7zGTsPYkEya3m5f3cAypH+qe7YOrM1U2Q==", - "dev": true, "requires": { "inherits": "^2.0.1", "safe-buffer": "^5.0.1" @@ -2330,7 +2245,6 @@ "version": "0.3.6", "resolved": "https://registry.npmjs.org/class-utils/-/class-utils-0.3.6.tgz", "integrity": "sha512-qOhPa/Fj7s6TY8H8esGu5QNpMMQxz79h+urzrNYN6mn+9BnxlDGf5QZ+XeCDsxSjPqsSR56XOZOJmpeurnLMeg==", - "dev": true, "requires": { "arr-union": "^3.1.0", "define-property": "^0.2.5", @@ -2342,7 +2256,6 @@ "version": "0.2.5", "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz", "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=", - "dev": true, "requires": { "is-descriptor": "^0.1.0" } @@ -2353,24 +2266,14 @@ "version": "4.2.1", "resolved": "https://registry.npmjs.org/clean-css/-/clean-css-4.2.1.tgz", "integrity": "sha512-4ZxI6dy4lrY6FHzfiy1aEOXgu4LIsW2MhwG0VBKdcoGoH/XLFgaHSdLTGr4O8Be6A8r3MOphEiI8Gc1n0ecf3g==", - "dev": true, "requires": { "source-map": "~0.6.0" - }, - "dependencies": { - "source-map": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", - "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", - "dev": true - } } }, "clipboard": { "version": "2.0.4", "resolved": "https://registry.npmjs.org/clipboard/-/clipboard-2.0.4.tgz", "integrity": "sha512-Vw26VSLRpJfBofiVaFb/I8PVfdI1OxKcYShe6fm0sP/DtmiWQNCjhM/okTvdCo0G+lMMm1rMYbk4IK4x1X+kgQ==", - "dev": true, "optional": true, "requires": { "good-listener": "^1.2.2", @@ -2379,38 +2282,19 @@ } }, "cliui": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/cliui/-/cliui-4.1.0.tgz", - "integrity": "sha512-4FG+RSG9DL7uEwRUZXZn3SS34DiDPfzP0VOiEwtUWlE+AR2EIg+hSyvrIgUUfhdgR/UkAeW2QHgeP+hWrXs7jQ==", - "dev": true, + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/cliui/-/cliui-2.1.0.tgz", + "integrity": "sha1-S0dXYP+AJkx2LDoXGQMukcf+oNE=", "requires": { - "string-width": "^2.1.1", - "strip-ansi": "^4.0.0", - "wrap-ansi": "^2.0.0" - }, - "dependencies": { - "ansi-regex": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-3.0.0.tgz", - "integrity": "sha1-7QMXwyIGT3lGbAKWa922Bas32Zg=", - "dev": true - }, - "strip-ansi": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-4.0.0.tgz", - "integrity": "sha1-qEeQIusaw2iocTibY1JixQXuNo8=", - "dev": true, - "requires": { - "ansi-regex": "^3.0.0" - } - } + "center-align": "^0.1.1", + "right-align": "^0.1.1", + "wordwrap": "0.0.2" } }, "coa": { "version": "2.0.2", "resolved": "https://registry.npmjs.org/coa/-/coa-2.0.2.tgz", "integrity": "sha512-q5/jG+YQnSy4nRTV4F7lPepBJZ8qBNJJDBuJdoejDyLXgmL7IEo+Le2JDZudFTFt7mrCqIRaSjws4ygRCTCAXA==", - "dev": true, "requires": { "@types/q": "^1.5.1", "chalk": "^2.4.1", @@ -2420,14 +2304,12 @@ "code-point-at": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/code-point-at/-/code-point-at-1.1.0.tgz", - "integrity": "sha1-DQcLTQQ6W+ozovGkDi7bPZpMz3c=", - "dev": true + "integrity": "sha1-DQcLTQQ6W+ozovGkDi7bPZpMz3c=" }, "collection-visit": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/collection-visit/-/collection-visit-1.0.0.tgz", "integrity": "sha1-S8A3PBZLwykbTTaMgpzxqApZ3KA=", - "dev": true, "requires": { "map-visit": "^1.0.0", "object-visit": "^1.0.0" @@ -2437,7 +2319,6 @@ "version": "3.1.2", "resolved": "https://registry.npmjs.org/color/-/color-3.1.2.tgz", "integrity": "sha512-vXTJhHebByxZn3lDvDJYw4lR5+uB3vuoHsuYA5AKuxRVn5wzzIfQKGLBmgdVRHKTJYeK5rvJcHnrd0Li49CFpg==", - "dev": true, "requires": { "color-convert": "^1.9.1", "color-string": "^1.5.2" @@ -2447,7 +2328,6 @@ "version": "1.9.3", "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", - "dev": true, "requires": { "color-name": "1.1.3" } @@ -2455,14 +2335,12 @@ "color-name": { "version": "1.1.3", "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", - "integrity": "sha1-p9BVi9icQveV3UIyj3QIMcpTvCU=", - "dev": true + "integrity": "sha1-p9BVi9icQveV3UIyj3QIMcpTvCU=" }, "color-string": { "version": "1.5.3", "resolved": "https://registry.npmjs.org/color-string/-/color-string-1.5.3.tgz", "integrity": "sha512-dC2C5qeWoYkxki5UAXapdjqO672AM4vZuPGRQfO8b5HKuKGBbKWpITyDYN7TOFKvRW7kOgAn3746clDBMDJyQw==", - "dev": true, "requires": { "color-name": "^1.0.0", "simple-swizzle": "^0.2.2" @@ -2472,7 +2350,6 @@ "version": "1.0.8", "resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.8.tgz", "integrity": "sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==", - "dev": true, "requires": { "delayed-stream": "~1.0.0" } @@ -2480,26 +2357,22 @@ "commander": { "version": "2.17.1", "resolved": "https://registry.npmjs.org/commander/-/commander-2.17.1.tgz", - "integrity": "sha512-wPMUt6FnH2yzG95SA6mzjQOEKUU3aLaDEmzs1ti+1E9h+CsrZghRlqEM/EJ4KscsQVG8uNN4uVreUeT8+drlgg==", - "dev": true + "integrity": "sha512-wPMUt6FnH2yzG95SA6mzjQOEKUU3aLaDEmzs1ti+1E9h+CsrZghRlqEM/EJ4KscsQVG8uNN4uVreUeT8+drlgg==" }, "commondir": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/commondir/-/commondir-1.0.1.tgz", - "integrity": "sha1-3dgA2gxmEnOTzKWVDqloo6rxJTs=", - "dev": true + "integrity": "sha1-3dgA2gxmEnOTzKWVDqloo6rxJTs=" }, "component-emitter": { "version": "1.3.0", "resolved": "https://registry.npmjs.org/component-emitter/-/component-emitter-1.3.0.tgz", - "integrity": "sha512-Rd3se6QB+sO1TwqZjscQrurpEPIfO0/yYnSin6Q/rD3mOutHvUrCAhJub3r90uNb+SESBuE0QYoB90YdfatsRg==", - "dev": true + "integrity": "sha512-Rd3se6QB+sO1TwqZjscQrurpEPIfO0/yYnSin6Q/rD3mOutHvUrCAhJub3r90uNb+SESBuE0QYoB90YdfatsRg==" }, "compressible": { "version": "2.0.17", "resolved": "https://registry.npmjs.org/compressible/-/compressible-2.0.17.tgz", "integrity": "sha512-BGHeLCK1GV7j1bSmQQAi26X+GgWcTjLr/0tzSvMCl3LH1w1IJ4PFSPoV5316b30cneTziC+B1a+3OjoSUcQYmw==", - "dev": true, "requires": { "mime-db": ">= 1.40.0 < 2" } @@ -2508,7 +2381,6 @@ "version": "1.7.4", "resolved": "https://registry.npmjs.org/compression/-/compression-1.7.4.tgz", "integrity": "sha512-jaSIDzP9pZVS4ZfQ+TzvtiWhdpFhE2RDHz8QJkpX9SIpLq88VueF5jJw6t+6CUQcAoA6t+x89MLrWAqpfDE8iQ==", - "dev": true, "requires": { "accepts": "~1.3.5", "bytes": "3.0.0", @@ -2523,30 +2395,21 @@ "version": "2.6.9", "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", - "dev": true, "requires": { "ms": "2.0.0" } - }, - "ms": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", - "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=", - "dev": true } } }, "concat-map": { "version": "0.0.1", "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", - "integrity": "sha1-2Klr13/Wjfd5OnMDajug1UBdR3s=", - "dev": true + "integrity": "sha1-2Klr13/Wjfd5OnMDajug1UBdR3s=" }, "concat-stream": { "version": "1.6.2", "resolved": "https://registry.npmjs.org/concat-stream/-/concat-stream-1.6.2.tgz", "integrity": "sha512-27HBghJxjiZtIk3Ycvn/4kbJk/1uZuJFfuPEns6LaEvpvG1f0hTea8lilrouyo9mVc2GWdcEZ8OLoGmSADlrCw==", - "dev": true, "requires": { "buffer-from": "^1.0.0", "inherits": "^2.0.3", @@ -2557,20 +2420,17 @@ "connect-history-api-fallback": { "version": "1.6.0", "resolved": "https://registry.npmjs.org/connect-history-api-fallback/-/connect-history-api-fallback-1.6.0.tgz", - "integrity": "sha512-e54B99q/OUoH64zYYRf3HBP5z24G38h5D3qXu23JGRoigpX5Ss4r9ZnDk3g0Z8uQC2x2lPaJ+UlWBc1ZWBWdLg==", - "dev": true + "integrity": "sha512-e54B99q/OUoH64zYYRf3HBP5z24G38h5D3qXu23JGRoigpX5Ss4r9ZnDk3g0Z8uQC2x2lPaJ+UlWBc1ZWBWdLg==" }, "consola": { - "version": "2.9.0", - "resolved": "https://registry.npmjs.org/consola/-/consola-2.9.0.tgz", - "integrity": "sha512-34Iue+LRcWbndFIfZc5boNizWlsrRjqIBJZTe591vImgbnq7nx2EzlrLtANj9TH2Fxm7puFJBJAOk5BhvZOddQ==", - "dev": true + "version": "2.10.1", + "resolved": "https://registry.npmjs.org/consola/-/consola-2.10.1.tgz", + "integrity": "sha512-4sxpH6SGFYLADfUip4vuY65f/gEogrzJoniVhNUYkJHtng0l8ZjnDCqxxrSVRHOHwKxsy8Vm5ONZh1wOR3/l/w==" }, "console-browserify": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/console-browserify/-/console-browserify-1.1.0.tgz", "integrity": "sha1-8CQcRXMKn8YyOyBtvzjtx0HQuxA=", - "dev": true, "requires": { "date-now": "^0.1.4" } @@ -2579,22 +2439,30 @@ "version": "0.15.1", "resolved": "https://registry.npmjs.org/consolidate/-/consolidate-0.15.1.tgz", "integrity": "sha512-DW46nrsMJgy9kqAbPt5rKaCr7uFtpo4mSUvLHIUbJEjm0vo+aY5QLwBUq3FK4tRnJr/X0Psc0C4jf/h+HtXSMw==", - "dev": true, "requires": { "bluebird": "^3.1.1" } }, + "constantinople": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/constantinople/-/constantinople-3.1.2.tgz", + "integrity": "sha512-yePcBqEFhLOqSBtwYOGGS1exHo/s1xjekXiinh4itpNQGCu4KA1euPh1fg07N2wMITZXQkBz75Ntdt1ctGZouw==", + "requires": { + "@types/babel-types": "^7.0.0", + "@types/babylon": "^6.16.2", + "babel-types": "^6.26.0", + "babylon": "^6.18.0" + } + }, "constants-browserify": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/constants-browserify/-/constants-browserify-1.0.0.tgz", - "integrity": "sha1-wguW2MYXdIqvHBYCF2DNJ/y4y3U=", - "dev": true + "integrity": "sha1-wguW2MYXdIqvHBYCF2DNJ/y4y3U=" }, "content-disposition": { "version": "0.5.3", "resolved": "https://registry.npmjs.org/content-disposition/-/content-disposition-0.5.3.tgz", "integrity": "sha512-ExO0774ikEObIAEV9kDo50o+79VCUdEB6n6lzKgGwupcVeRlhrj3qGAfwq8G6uBJjkqLrhT0qEYFcWng8z1z0g==", - "dev": true, "requires": { "safe-buffer": "5.1.2" } @@ -2602,14 +2470,12 @@ "content-type": { "version": "1.0.4", "resolved": "https://registry.npmjs.org/content-type/-/content-type-1.0.4.tgz", - "integrity": "sha512-hIP3EEPs8tB9AT1L+NUqtwOAps4mk2Zob89MWXMHjHWg9milF/j4osnnQLXBCBFBk/tvIG/tUc9mOUJiPBhPXA==", - "dev": true + "integrity": "sha512-hIP3EEPs8tB9AT1L+NUqtwOAps4mk2Zob89MWXMHjHWg9milF/j4osnnQLXBCBFBk/tvIG/tUc9mOUJiPBhPXA==" }, "convert-source-map": { "version": "1.6.0", "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-1.6.0.tgz", "integrity": "sha512-eFu7XigvxdZ1ETfbgPBohgyQ/Z++C0eEhTor0qRwBw9unw+L0/6V8wkSuGgzdThkiS5lSpdptOQPD8Ak40a+7A==", - "dev": true, "requires": { "safe-buffer": "~5.1.1" } @@ -2617,20 +2483,17 @@ "cookie": { "version": "0.4.0", "resolved": "https://registry.npmjs.org/cookie/-/cookie-0.4.0.tgz", - "integrity": "sha512-+Hp8fLp57wnUSt0tY0tHEXh4voZRDnoIrZPqlo3DPiI4y9lwg/jqx+1Om94/W6ZaPDOUbnjOt/99w66zk+l1Xg==", - "dev": true + "integrity": "sha512-+Hp8fLp57wnUSt0tY0tHEXh4voZRDnoIrZPqlo3DPiI4y9lwg/jqx+1Om94/W6ZaPDOUbnjOt/99w66zk+l1Xg==" }, "cookie-signature": { "version": "1.0.6", "resolved": "https://registry.npmjs.org/cookie-signature/-/cookie-signature-1.0.6.tgz", - "integrity": "sha1-4wOogrNCzD7oylE6eZmXNNqzriw=", - "dev": true + "integrity": "sha1-4wOogrNCzD7oylE6eZmXNNqzriw=" }, "copy-concurrently": { "version": "1.0.5", "resolved": "https://registry.npmjs.org/copy-concurrently/-/copy-concurrently-1.0.5.tgz", "integrity": "sha512-f2domd9fsVDFtaFcbaRZuYXwtdmnzqbADSwhSWYxYB/Q8zsdUUFMXVRwXGDMWmbEzAn1kdRrtI1T/KTFOL4X2A==", - "dev": true, "requires": { "aproba": "^1.1.1", "fs-write-stream-atomic": "^1.0.8", @@ -2643,16 +2506,14 @@ "copy-descriptor": { "version": "0.1.1", "resolved": "https://registry.npmjs.org/copy-descriptor/-/copy-descriptor-0.1.1.tgz", - "integrity": "sha1-Z29us8OZl8LuGsOpJP1hJHSPV40=", - "dev": true + "integrity": "sha1-Z29us8OZl8LuGsOpJP1hJHSPV40=" }, "copy-webpack-plugin": { - "version": "5.0.3", - "resolved": "https://registry.npmjs.org/copy-webpack-plugin/-/copy-webpack-plugin-5.0.3.tgz", - "integrity": "sha512-PlZRs9CUMnAVylZq+vg2Juew662jWtwOXOqH4lbQD9ZFhRG9R7tVStOgHt21CBGVq7k5yIJaz8TXDLSjV+Lj8Q==", - "dev": true, + "version": "5.0.4", + "resolved": "https://registry.npmjs.org/copy-webpack-plugin/-/copy-webpack-plugin-5.0.4.tgz", + "integrity": "sha512-YBuYGpSzoCHSSDGyHy6VJ7SHojKp6WHT4D7ItcQFNAYx2hrwkMe56e97xfVR0/ovDuMTrMffXUiltvQljtAGeg==", "requires": { - "cacache": "^11.3.2", + "cacache": "^11.3.3", "find-cache-dir": "^2.1.0", "glob-parent": "^3.1.0", "globby": "^7.1.1", @@ -2670,7 +2531,6 @@ "version": "7.1.1", "resolved": "https://registry.npmjs.org/globby/-/globby-7.1.1.tgz", "integrity": "sha1-+yzP+UAfhgCUXfral0QMypcrhoA=", - "dev": true, "requires": { "array-union": "^1.0.1", "dir-glob": "^2.0.0", @@ -2683,14 +2543,12 @@ "ignore": { "version": "3.3.10", "resolved": "https://registry.npmjs.org/ignore/-/ignore-3.3.10.tgz", - "integrity": "sha512-Pgs951kaMm5GXP7MOvxERINe3gsaVjUWFm+UZPSq9xYriQAksyhg0csnS0KXSNRD5NmNdapXEpjxG49+AKh/ug==", - "dev": true + "integrity": "sha512-Pgs951kaMm5GXP7MOvxERINe3gsaVjUWFm+UZPSq9xYriQAksyhg0csnS0KXSNRD5NmNdapXEpjxG49+AKh/ug==" }, "p-limit": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.2.0.tgz", - "integrity": "sha512-pZbTJpoUsCzV48Mc9Nh51VbwO0X9cuPFE8gYwx9BTCt9SF8/b7Zljd2fVgOxhIF/HDTKgpVzs+GPhyKfjLLFRQ==", - "dev": true, + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.2.1.tgz", + "integrity": "sha512-85Tk+90UCVWvbDavCLKPOLC9vvY8OwEX/RtKF+/1OADJMVlFfEHOiMTPVyxg7mk/dKa+ipdHm0OUkTvCpMTuwg==", "requires": { "p-try": "^2.0.0" } @@ -2698,40 +2556,34 @@ "p-try": { "version": "2.2.0", "resolved": "https://registry.npmjs.org/p-try/-/p-try-2.2.0.tgz", - "integrity": "sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ==", - "dev": true + "integrity": "sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ==" }, "pify": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/pify/-/pify-3.0.0.tgz", - "integrity": "sha1-5aSs0sEB/fPZpNB/DbxNtJ3SgXY=", - "dev": true + "integrity": "sha1-5aSs0sEB/fPZpNB/DbxNtJ3SgXY=" }, "slash": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/slash/-/slash-1.0.0.tgz", - "integrity": "sha1-xB8vbDn8FtHNF61LXYlhFK5HDVU=", - "dev": true + "integrity": "sha1-xB8vbDn8FtHNF61LXYlhFK5HDVU=" } } }, "core-js": { - "version": "2.6.9", - "resolved": "https://registry.npmjs.org/core-js/-/core-js-2.6.9.tgz", - "integrity": "sha512-HOpZf6eXmnl7la+cUdMnLvUxKNqLUzJvgIziQ0DiF3JwSImNphIqdGqzj6hIKyX04MmV0poclQ7+wjWvxQyR2A==", - "dev": true + "version": "2.6.10", + "resolved": "https://registry.npmjs.org/core-js/-/core-js-2.6.10.tgz", + "integrity": "sha512-I39t74+4t+zau64EN1fE5v2W31Adtc/REhzWN+gWRRXg6WH5qAsZm62DHpQ1+Yhe4047T55jvzz7MUqF/dBBlA==" }, "core-util-is": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.2.tgz", - "integrity": "sha1-tf1UIgqivFq1eqtxQMlAdUUDwac=", - "dev": true + "integrity": "sha1-tf1UIgqivFq1eqtxQMlAdUUDwac=" }, "cosmiconfig": { "version": "5.2.1", "resolved": "https://registry.npmjs.org/cosmiconfig/-/cosmiconfig-5.2.1.tgz", "integrity": "sha512-H65gsXo1SKjf8zmrJ67eJk8aIRKV5ff2D4uKZIBZShbhGSpEmsQOPW/SKMKYhSTrqR7ufy6RP69rPogdaPh/kA==", - "dev": true, "requires": { "import-fresh": "^2.0.0", "is-directory": "^0.3.1", @@ -2743,7 +2595,6 @@ "version": "4.0.3", "resolved": "https://registry.npmjs.org/create-ecdh/-/create-ecdh-4.0.3.tgz", "integrity": "sha512-GbEHQPMOswGpKXM9kCWVrremUcBmjteUaQ01T9rkKCPDXfUHX0IoP9LpHYo2NPFampa4e+/pFDc3jQdxrxQLaw==", - "dev": true, "requires": { "bn.js": "^4.1.0", "elliptic": "^6.0.0" @@ -2753,7 +2604,6 @@ "version": "1.2.0", "resolved": "https://registry.npmjs.org/create-hash/-/create-hash-1.2.0.tgz", "integrity": "sha512-z00bCGNHDG8mHAkP7CtT1qVu+bFQUPjYq/4Iv3C3kWjTFV10zIjfSoeqXo9Asws8gwSHDGj/hl2u4OGIjapeCg==", - "dev": true, "requires": { "cipher-base": "^1.0.1", "inherits": "^2.0.1", @@ -2766,7 +2616,6 @@ "version": "1.1.7", "resolved": "https://registry.npmjs.org/create-hmac/-/create-hmac-1.1.7.tgz", "integrity": "sha512-MJG9liiZ+ogc4TzUwuvbER1JRdgvUFSB5+VR/g5h82fGaIRWMWddtKBHi7/sVhfjQZ6SehlyhvQYrcYkaUIpLg==", - "dev": true, "requires": { "cipher-base": "^1.0.3", "create-hash": "^1.1.0", @@ -2780,7 +2629,6 @@ "version": "6.0.5", "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-6.0.5.tgz", "integrity": "sha512-eTVLrBSt7fjbDygz805pMnstIs2VTBNkRm0qxZd+M7A5XDdxVRWO5MxGBXZhjY4cqLYLdtrGqRf8mBPmzwSpWQ==", - "dev": true, "requires": { "nice-try": "^1.0.4", "path-key": "^2.0.1", @@ -2793,7 +2641,6 @@ "version": "3.12.0", "resolved": "https://registry.npmjs.org/crypto-browserify/-/crypto-browserify-3.12.0.tgz", "integrity": "sha512-fz4spIh+znjO2VjL+IdhEpRJ3YN6sMzITSBijk6FK2UvTqruSQW+/cCZTSNsMiZNvUeq0CqurF+dAbyiGOY6Wg==", - "dev": true, "requires": { "browserify-cipher": "^1.0.0", "browserify-sign": "^4.0.0", @@ -2808,17 +2655,26 @@ "randomfill": "^1.0.3" } }, - "css-color-names": { - "version": "0.0.4", - "resolved": "https://registry.npmjs.org/css-color-names/-/css-color-names-0.0.4.tgz", - "integrity": "sha1-gIrcLnnPhHOAabZGyyDsJ762KeA=", - "dev": true + "css": { + "version": "2.2.4", + "resolved": "https://registry.npmjs.org/css/-/css-2.2.4.tgz", + "integrity": "sha512-oUnjmWpy0niI3x/mPL8dVEI1l7MnG3+HHyRPHf+YFSbK+svOhXpmSOcDURUh2aOCgl2grzrOPt1nHLuCVFULLw==", + "requires": { + "inherits": "^2.0.3", + "source-map": "^0.6.1", + "source-map-resolve": "^0.5.2", + "urix": "^0.1.0" + } + }, + "css-color-names": { + "version": "0.0.4", + "resolved": "https://registry.npmjs.org/css-color-names/-/css-color-names-0.0.4.tgz", + "integrity": "sha1-gIrcLnnPhHOAabZGyyDsJ762KeA=" }, "css-declaration-sorter": { "version": "4.0.1", "resolved": "https://registry.npmjs.org/css-declaration-sorter/-/css-declaration-sorter-4.0.1.tgz", "integrity": "sha512-BcxQSKTSEEQUftYpBVnsH4SF05NTuBokb19/sBt6asXGKZ/6VP7PLG1CBCkFDYOnhXhPh0jMhO6xZ71oYHXHBA==", - "dev": true, "requires": { "postcss": "^7.0.1", "timsort": "^0.3.0" @@ -2828,7 +2684,6 @@ "version": "2.1.1", "resolved": "https://registry.npmjs.org/css-loader/-/css-loader-2.1.1.tgz", "integrity": "sha512-OcKJU/lt232vl1P9EEDamhoO9iKY3tIjY5GU+XDLblAykTdgs6Ux9P1hTHve8nFKy5KPpOXOsVI/hIwi3841+w==", - "dev": true, "requires": { "camelcase": "^5.2.0", "icss-utils": "^4.1.0", @@ -2841,19 +2696,32 @@ "postcss-modules-values": "^2.0.0", "postcss-value-parser": "^3.3.0", "schema-utils": "^1.0.0" + }, + "dependencies": { + "camelcase": { + "version": "5.3.1", + "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-5.3.1.tgz", + "integrity": "sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg==" + }, + "postcss-value-parser": { + "version": "3.3.1", + "resolved": "https://registry.npmjs.org/postcss-value-parser/-/postcss-value-parser-3.3.1.tgz", + "integrity": "sha512-pISE66AbVkp4fDQ7VHBwRNXzAAKJjw4Vw7nWI/+Q3vuly7SNfgYXvm6i5IgFylHGK5sP/xHAbB7N49OS4gWNyQ==" + } } }, "css-parse": { - "version": "1.7.0", - "resolved": "https://registry.npmjs.org/css-parse/-/css-parse-1.7.0.tgz", - "integrity": "sha1-Mh9s9zeCpv91ERE5D8BeLGV9jJs=", - "dev": true + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/css-parse/-/css-parse-2.0.0.tgz", + "integrity": "sha1-pGjuZnwW2BzPBcWMONKpfHgNv9Q=", + "requires": { + "css": "^2.0.0" + } }, "css-select": { "version": "2.0.2", "resolved": "https://registry.npmjs.org/css-select/-/css-select-2.0.2.tgz", "integrity": "sha512-dSpYaDVoWaELjvZ3mS6IKZM/y2PMPa/XYoEfYNZePL4U/XgyxZNroHEHReDx/d+VgXh9VbCTtFqLkFbmeqeaRQ==", - "dev": true, "requires": { "boolbase": "^1.0.0", "css-what": "^2.1.2", @@ -2864,48 +2732,43 @@ "css-select-base-adapter": { "version": "0.1.1", "resolved": "https://registry.npmjs.org/css-select-base-adapter/-/css-select-base-adapter-0.1.1.tgz", - "integrity": "sha512-jQVeeRG70QI08vSTwf1jHxp74JoZsr2XSgETae8/xC8ovSnL2WF87GTLO86Sbwdt2lK4Umg4HnnwMO4YF3Ce7w==", - "dev": true + "integrity": "sha512-jQVeeRG70QI08vSTwf1jHxp74JoZsr2XSgETae8/xC8ovSnL2WF87GTLO86Sbwdt2lK4Umg4HnnwMO4YF3Ce7w==" }, "css-tree": { - "version": "1.0.0-alpha.28", - "resolved": "https://registry.npmjs.org/css-tree/-/css-tree-1.0.0-alpha.28.tgz", - "integrity": "sha512-joNNW1gCp3qFFzj4St6zk+Wh/NBv0vM5YbEreZk0SD4S23S+1xBKb6cLDg2uj4P4k/GUMlIm6cKIDqIG+vdt0w==", - "dev": true, + "version": "1.0.0-alpha.33", + "resolved": "https://registry.npmjs.org/css-tree/-/css-tree-1.0.0-alpha.33.tgz", + "integrity": "sha512-SPt57bh5nQnpsTBsx/IXbO14sRc9xXu5MtMAVuo0BaQQmyf0NupNPPSoMaqiAF5tDFafYsTkfeH4Q/HCKXkg4w==", "requires": { - "mdn-data": "~1.1.0", + "mdn-data": "2.0.4", "source-map": "^0.5.3" + }, + "dependencies": { + "source-map": { + "version": "0.5.7", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz", + "integrity": "sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w=" + } } }, "css-unit-converter": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/css-unit-converter/-/css-unit-converter-1.1.1.tgz", - "integrity": "sha1-2bkoGtz9jO2TW9urqDeGiX9k6ZY=", - "dev": true - }, - "css-url-regex": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/css-url-regex/-/css-url-regex-1.1.0.tgz", - "integrity": "sha1-g4NCMMyfdMRX3lnuvRVD/uuDt+w=", - "dev": true + "integrity": "sha1-2bkoGtz9jO2TW9urqDeGiX9k6ZY=" }, "css-what": { "version": "2.1.3", "resolved": "https://registry.npmjs.org/css-what/-/css-what-2.1.3.tgz", - "integrity": "sha512-a+EPoD+uZiNfh+5fxw2nO9QwFa6nJe2Or35fGY6Ipw1R3R4AGz1d1TEZrCegvw2YTmZ0jXirGYlzxxpYSHwpEg==", - "dev": true + "integrity": "sha512-a+EPoD+uZiNfh+5fxw2nO9QwFa6nJe2Or35fGY6Ipw1R3R4AGz1d1TEZrCegvw2YTmZ0jXirGYlzxxpYSHwpEg==" }, "cssesc": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/cssesc/-/cssesc-3.0.0.tgz", - "integrity": "sha512-/Tb/JcjK111nNScGob5MNtsntNM1aCNUDipB/TkwZFhyDrrE47SOx/18wF2bbjgc3ZzCSKW1T5nt5EbFoAz/Vg==", - "dev": true + "integrity": "sha512-/Tb/JcjK111nNScGob5MNtsntNM1aCNUDipB/TkwZFhyDrrE47SOx/18wF2bbjgc3ZzCSKW1T5nt5EbFoAz/Vg==" }, "cssnano": { "version": "4.1.10", "resolved": "https://registry.npmjs.org/cssnano/-/cssnano-4.1.10.tgz", "integrity": "sha512-5wny+F6H4/8RgNlaqab4ktc3e0/blKutmq8yNlBFXA//nSFFAqAngjNVRzUvCgYROULmZZUoosL/KSoZo5aUaQ==", - "dev": true, "requires": { "cosmiconfig": "^5.0.0", "cssnano-preset-default": "^4.0.7", @@ -2917,7 +2780,6 @@ "version": "4.0.7", "resolved": "https://registry.npmjs.org/cssnano-preset-default/-/cssnano-preset-default-4.0.7.tgz", "integrity": "sha512-x0YHHx2h6p0fCl1zY9L9roD7rnlltugGu7zXSKQx6k2rYw0Hi3IqxcoAGF7u9Q5w1nt7vK0ulxV8Lo+EvllGsA==", - "dev": true, "requires": { "css-declaration-sorter": "^4.0.1", "cssnano-util-raw-cache": "^4.0.1", @@ -2954,20 +2816,17 @@ "cssnano-util-get-arguments": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/cssnano-util-get-arguments/-/cssnano-util-get-arguments-4.0.0.tgz", - "integrity": "sha1-7ToIKZ8h11dBsg87gfGU7UnMFQ8=", - "dev": true + "integrity": "sha1-7ToIKZ8h11dBsg87gfGU7UnMFQ8=" }, "cssnano-util-get-match": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/cssnano-util-get-match/-/cssnano-util-get-match-4.0.0.tgz", - "integrity": "sha1-wOTKB/U4a7F+xeUiULT1lhNlFW0=", - "dev": true + "integrity": "sha1-wOTKB/U4a7F+xeUiULT1lhNlFW0=" }, "cssnano-util-raw-cache": { "version": "4.0.1", "resolved": "https://registry.npmjs.org/cssnano-util-raw-cache/-/cssnano-util-raw-cache-4.0.1.tgz", "integrity": "sha512-qLuYtWK2b2Dy55I8ZX3ky1Z16WYsx544Q0UWViebptpwn/xDBmog2TLg4f+DBMg1rJ6JDWtn96WHbOKDWt1WQA==", - "dev": true, "requires": { "postcss": "^7.0.0" } @@ -2975,14 +2834,12 @@ "cssnano-util-same-parent": { "version": "4.0.1", "resolved": "https://registry.npmjs.org/cssnano-util-same-parent/-/cssnano-util-same-parent-4.0.1.tgz", - "integrity": "sha512-WcKx5OY+KoSIAxBW6UBBRay1U6vkYheCdjyVNDm85zt5K9mHoGOfsOsqIszfAqrQQFIIKgjh2+FDgIj/zsl21Q==", - "dev": true + "integrity": "sha512-WcKx5OY+KoSIAxBW6UBBRay1U6vkYheCdjyVNDm85zt5K9mHoGOfsOsqIszfAqrQQFIIKgjh2+FDgIj/zsl21Q==" }, "csso": { "version": "3.5.1", "resolved": "https://registry.npmjs.org/csso/-/csso-3.5.1.tgz", "integrity": "sha512-vrqULLffYU1Q2tLdJvaCYbONStnfkfimRxXNaGjxMldI0C7JPBC4rB1RyjhfdZ4m1frm8pM9uRPKH3d2knZ8gg==", - "dev": true, "requires": { "css-tree": "1.0.0-alpha.29" }, @@ -2991,25 +2848,32 @@ "version": "1.0.0-alpha.29", "resolved": "https://registry.npmjs.org/css-tree/-/css-tree-1.0.0-alpha.29.tgz", "integrity": "sha512-sRNb1XydwkW9IOci6iB2xmy8IGCj6r/fr+JWitvJ2JxQRPzN3T4AGGVWCMlVmVwM1gtgALJRmGIlWv5ppnGGkg==", - "dev": true, "requires": { "mdn-data": "~1.1.0", "source-map": "^0.5.3" } + }, + "mdn-data": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/mdn-data/-/mdn-data-1.1.4.tgz", + "integrity": "sha512-FSYbp3lyKjyj3E7fMl6rYvUdX0FBXaluGqlFoYESWQlyUTq8R+wp0rkFxoYFqZlHCvsUXGjyJmLQSnXToYhOSA==" + }, + "source-map": { + "version": "0.5.7", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz", + "integrity": "sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w=" } } }, "cyclist": { - "version": "0.2.2", - "resolved": "https://registry.npmjs.org/cyclist/-/cyclist-0.2.2.tgz", - "integrity": "sha1-GzN5LhHpFKL9bW7WRHRkRE5fpkA=", - "dev": true + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/cyclist/-/cyclist-1.0.1.tgz", + "integrity": "sha1-WW6WmP0MgOEgOMK4LW6xs1tiJNk=" }, "dashdash": { "version": "1.14.1", "resolved": "https://registry.npmjs.org/dashdash/-/dashdash-1.14.1.tgz", "integrity": "sha1-hTz6D3y+L+1d4gMmuN1YEDX24vA=", - "dev": true, "requires": { "assert-plus": "^1.0.0" } @@ -3017,53 +2881,53 @@ "date-now": { "version": "0.1.4", "resolved": "https://registry.npmjs.org/date-now/-/date-now-0.1.4.tgz", - "integrity": "sha1-6vQ5/U1ISK105cx9vvIAZyueNFs=", - "dev": true + "integrity": "sha1-6vQ5/U1ISK105cx9vvIAZyueNFs=" }, "de-indent": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/de-indent/-/de-indent-1.0.2.tgz", - "integrity": "sha1-sgOOhG3DO6pXlhKNCAS0VbjB4h0=", - "dev": true + "integrity": "sha1-sgOOhG3DO6pXlhKNCAS0VbjB4h0=" }, "debug": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/debug/-/debug-4.1.1.tgz", - "integrity": "sha512-pYAIzeRo8J6KPEaJ0VWOh5Pzkbw/RetuzehGM7QRRX5he4fPHx2rdKMB256ehJCkX+XRQm16eZLqLNS8RSZXZw==", - "dev": true, + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/debug/-/debug-3.1.0.tgz", + "integrity": "sha512-OX8XqP7/1a9cqkxYw2yXss15f26NKWBpDXQd0/uK/KPqdQhxbPa994hnzjcE2VqQpDslf55723cKPUOGSmMY3g==", "requires": { - "ms": "^2.1.1" + "ms": "2.0.0" } }, "decamelize": { "version": "1.2.0", "resolved": "https://registry.npmjs.org/decamelize/-/decamelize-1.2.0.tgz", - "integrity": "sha1-9lNNFRSCabIDUue+4m9QH5oZEpA=", - "dev": true + "integrity": "sha1-9lNNFRSCabIDUue+4m9QH5oZEpA=" }, "decode-uri-component": { "version": "0.2.0", "resolved": "https://registry.npmjs.org/decode-uri-component/-/decode-uri-component-0.2.0.tgz", - "integrity": "sha1-6zkTMzRYd1y4TNGh+uBiEGu4dUU=", - "dev": true + "integrity": "sha1-6zkTMzRYd1y4TNGh+uBiEGu4dUU=" }, "deep-equal": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/deep-equal/-/deep-equal-1.0.1.tgz", - "integrity": "sha1-9dJgKStmDghO/0zbyfCK0yR0SLU=", - "dev": true + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/deep-equal/-/deep-equal-1.1.0.tgz", + "integrity": "sha512-ZbfWJq/wN1Z273o7mUSjILYqehAktR2NVoSrOukDkU9kg2v/Uv89yU4Cvz8seJeAmtN5oqiefKq8FPuXOboqLw==", + "requires": { + "is-arguments": "^1.0.4", + "is-date-object": "^1.0.1", + "is-regex": "^1.0.4", + "object-is": "^1.0.1", + "object-keys": "^1.1.1", + "regexp.prototype.flags": "^1.2.0" + } }, "deepmerge": { "version": "1.5.2", "resolved": "https://registry.npmjs.org/deepmerge/-/deepmerge-1.5.2.tgz", - "integrity": "sha512-95k0GDqvBjZavkuvzx/YqVLv/6YYa17fz6ILMSf7neqQITCPbnfEnQvEgMPNjH4kgobe7+WIL0yJEHku+H3qtQ==", - "dev": true + "integrity": "sha512-95k0GDqvBjZavkuvzx/YqVLv/6YYa17fz6ILMSf7neqQITCPbnfEnQvEgMPNjH4kgobe7+WIL0yJEHku+H3qtQ==" }, "default-gateway": { "version": "4.2.0", "resolved": "https://registry.npmjs.org/default-gateway/-/default-gateway-4.2.0.tgz", "integrity": "sha512-h6sMrVB1VMWVrW13mSc6ia/DwYYw5MN6+exNu1OaJeFac5aSAvwM7lZ0NVfTABuSkQelr4h5oebg3KB1XPdjgA==", - "dev": true, "requires": { "execa": "^1.0.0", "ip-regex": "^2.1.0" @@ -3073,7 +2937,6 @@ "version": "1.1.3", "resolved": "https://registry.npmjs.org/define-properties/-/define-properties-1.1.3.tgz", "integrity": "sha512-3MqfYKj2lLzdMSf8ZIZE/V+Zuy+BgD6f164e8K2w7dgnpKArBDerGYpM46IYYcjnkdPNMjPk9A6VFB8+3SKlXQ==", - "dev": true, "requires": { "object-keys": "^1.0.12" } @@ -3082,7 +2945,6 @@ "version": "2.0.2", "resolved": "https://registry.npmjs.org/define-property/-/define-property-2.0.2.tgz", "integrity": "sha512-jwK2UV4cnPpbcG7+VRARKTZPUWowwXA8bzH5NP6ud0oeAxyYPuGZUAC7hMugpCdz4BeSZl2Dl9k66CHJ/46ZYQ==", - "dev": true, "requires": { "is-descriptor": "^1.0.2", "isobject": "^3.0.1" @@ -3092,7 +2954,6 @@ "version": "1.0.0", "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-1.0.0.tgz", "integrity": "sha512-m5hnHTkcVsPfqx3AKlyttIPb7J+XykHvJP2B9bZDjlhLIoEq4XoK64Vg7boZlVWYK6LUY94dYPEE7Lh0ZkZKcQ==", - "dev": true, "requires": { "kind-of": "^6.0.0" } @@ -3101,7 +2962,6 @@ "version": "1.0.0", "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-1.0.0.tgz", "integrity": "sha512-jbRXy1FmtAoCjQkVmIVYwuuqDFUbaOeDjmed1tOGPrsMhtJA4rD9tkgA0F1qJ3gRFRXcHYVkdeaP50Q5rE/jLQ==", - "dev": true, "requires": { "kind-of": "^6.0.0" } @@ -3110,12 +2970,16 @@ "version": "1.0.2", "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-1.0.2.tgz", "integrity": "sha512-2eis5WqQGV7peooDyLmNEPUrps9+SXX5c9pL3xEB+4e9HnGuDa7mB7kHxHw4CbqS9k1T2hOH3miL8n8WtiYVtg==", - "dev": true, "requires": { "is-accessor-descriptor": "^1.0.0", "is-data-descriptor": "^1.0.0", "kind-of": "^6.0.2" } + }, + "kind-of": { + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.2.tgz", + "integrity": "sha512-s5kLOcnH0XqDO+FvuaLX8DDjZ18CGFk7VygH40QoKPUQhW4e2rvM0rwUq0t8IQDOwYSeLK01U90OjzBTme2QqA==" } } }, @@ -3123,7 +2987,6 @@ "version": "4.1.1", "resolved": "https://registry.npmjs.org/del/-/del-4.1.1.tgz", "integrity": "sha512-QwGuEUouP2kVwQenAsOof5Fv8K9t3D8Ca8NxcXKrIpEHjTXK5J2nXLdP+ALI1cgv8wj7KuwBhTwBkOZSJKM5XQ==", - "dev": true, "requires": { "@types/glob": "^7.1.1", "globby": "^6.1.0", @@ -3138,7 +3001,6 @@ "version": "6.1.0", "resolved": "https://registry.npmjs.org/globby/-/globby-6.1.0.tgz", "integrity": "sha1-9abXDoOV4hyFj7BInWTfAkJNUGw=", - "dev": true, "requires": { "array-union": "^1.0.1", "glob": "^7.0.3", @@ -3150,8 +3012,7 @@ "pify": { "version": "2.3.0", "resolved": "https://registry.npmjs.org/pify/-/pify-2.3.0.tgz", - "integrity": "sha1-7RQaasBDqEnqWISY59yosVMw6Qw=", - "dev": true + "integrity": "sha1-7RQaasBDqEnqWISY59yosVMw6Qw=" } } } @@ -3160,27 +3021,23 @@ "delayed-stream": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz", - "integrity": "sha1-3zrhmayt+31ECqrgsp4icrJOxhk=", - "dev": true + "integrity": "sha1-3zrhmayt+31ECqrgsp4icrJOxhk=" }, "delegate": { "version": "3.2.0", "resolved": "https://registry.npmjs.org/delegate/-/delegate-3.2.0.tgz", "integrity": "sha512-IofjkYBZaZivn0V8nnsMJGBr4jVLxHDheKSW88PyxS5QC4Vo9ZbZVvhzlSxY87fVq3STR6r+4cGepyHkcWOQSw==", - "dev": true, "optional": true }, "depd": { "version": "1.1.2", "resolved": "https://registry.npmjs.org/depd/-/depd-1.1.2.tgz", - "integrity": "sha1-m81S4UwJd2PnSbJ0xDRu0uVgtak=", - "dev": true + "integrity": "sha1-m81S4UwJd2PnSbJ0xDRu0uVgtak=" }, "des.js": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/des.js/-/des.js-1.0.0.tgz", "integrity": "sha1-wHTS4qpqipoH29YfmhXCzYPsjsw=", - "dev": true, "requires": { "inherits": "^2.0.1", "minimalistic-assert": "^1.0.0" @@ -3189,26 +3046,22 @@ "destroy": { "version": "1.0.4", "resolved": "https://registry.npmjs.org/destroy/-/destroy-1.0.4.tgz", - "integrity": "sha1-l4hXRCxEdJ5CBmE+N5RiBYJqvYA=", - "dev": true + "integrity": "sha1-l4hXRCxEdJ5CBmE+N5RiBYJqvYA=" }, "detect-node": { "version": "2.0.4", "resolved": "https://registry.npmjs.org/detect-node/-/detect-node-2.0.4.tgz", - "integrity": "sha512-ZIzRpLJrOj7jjP2miAtgqIfmzbxa4ZOr5jJc601zklsfEx9oTzmmj2nVpIPRpNlRTIh8lc1kyViIY7BWSGNmKw==", - "dev": true + "integrity": "sha512-ZIzRpLJrOj7jjP2miAtgqIfmzbxa4ZOr5jJc601zklsfEx9oTzmmj2nVpIPRpNlRTIh8lc1kyViIY7BWSGNmKw==" }, "diacritics": { "version": "1.3.0", "resolved": "https://registry.npmjs.org/diacritics/-/diacritics-1.3.0.tgz", - "integrity": "sha1-PvqHMj67hj5mls67AILUj/PW96E=", - "dev": true + "integrity": "sha1-PvqHMj67hj5mls67AILUj/PW96E=" }, "diffie-hellman": { "version": "5.0.3", "resolved": "https://registry.npmjs.org/diffie-hellman/-/diffie-hellman-5.0.3.tgz", "integrity": "sha512-kqag/Nl+f3GwyK25fhUMYj81BUOrZ9IuJsjIcDE5icNM9FJHAVm3VcUDxdLPoQtTuUylWm6ZIknYJwwaPxsUzg==", - "dev": true, "requires": { "bn.js": "^4.1.0", "miller-rabin": "^4.0.0", @@ -3219,7 +3072,6 @@ "version": "2.2.2", "resolved": "https://registry.npmjs.org/dir-glob/-/dir-glob-2.2.2.tgz", "integrity": "sha512-f9LBi5QWzIW3I6e//uxZoLBlUt9kcp66qo0sSCxL6YZKc75R1c4MFCoe/LaZiBGmgujvQdxc5Bn3QhfyvK5Hsw==", - "dev": true, "requires": { "path-type": "^3.0.0" } @@ -3227,14 +3079,12 @@ "dns-equal": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/dns-equal/-/dns-equal-1.0.0.tgz", - "integrity": "sha1-s55/HabrCnW6nBcySzR1PEfgZU0=", - "dev": true + "integrity": "sha1-s55/HabrCnW6nBcySzR1PEfgZU0=" }, "dns-packet": { "version": "1.3.1", "resolved": "https://registry.npmjs.org/dns-packet/-/dns-packet-1.3.1.tgz", "integrity": "sha512-0UxfQkMhYAUaZI+xrNZOz/as5KgDU0M/fQ9b6SpkyLbk3GEswDi6PADJVaYJradtRVsRIlF1zLyOodbcTCDzUg==", - "dev": true, "requires": { "ip": "^1.1.0", "safe-buffer": "^5.0.1" @@ -3244,7 +3094,6 @@ "version": "2.0.2", "resolved": "https://registry.npmjs.org/dns-txt/-/dns-txt-2.0.2.tgz", "integrity": "sha1-uR2Ab10nGI5Ks+fRB9iBocxGQrY=", - "dev": true, "requires": { "buffer-indexof": "^1.0.0" } @@ -3253,7 +3102,6 @@ "version": "2.6.3", "resolved": "https://registry.npmjs.org/docsearch.js/-/docsearch.js-2.6.3.tgz", "integrity": "sha512-GN+MBozuyz664ycpZY0ecdQE0ND/LSgJKhTLA0/v3arIS3S1Rpf2OJz6A35ReMsm91V5apcmzr5/kM84cvUg+A==", - "dev": true, "requires": { "algoliasearch": "^3.24.5", "autocomplete.js": "0.36.0", @@ -3264,48 +3112,59 @@ "zepto": "^1.2.0" } }, + "doctypes": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/doctypes/-/doctypes-1.1.0.tgz", + "integrity": "sha1-6oCxBqh1OHdOijpKWv4pPeSJ4Kk=" + }, "dom-converter": { "version": "0.2.0", "resolved": "https://registry.npmjs.org/dom-converter/-/dom-converter-0.2.0.tgz", "integrity": "sha512-gd3ypIPfOMr9h5jIKq8E3sHOTCjeirnl0WK5ZdS1AW0Odt0b1PaWaHdJ4Qk4klv+YB9aJBS7mESXjFoDQPu6DA==", - "dev": true, "requires": { "utila": "~0.4" } }, "dom-serializer": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/dom-serializer/-/dom-serializer-0.1.1.tgz", - "integrity": "sha512-l0IU0pPzLWSHBcieZbpOKgkIn3ts3vAh7ZuFyXNwJxJXk/c4Gwj9xaTJwIDVQCXawWD0qb3IzMGH5rglQaO0XA==", - "dev": true, + "version": "0.2.1", + "resolved": "https://registry.npmjs.org/dom-serializer/-/dom-serializer-0.2.1.tgz", + "integrity": "sha512-sK3ujri04WyjwQXVoK4PU3y8ula1stq10GJZpqHIUgoGZdsGzAGu65BnU3d08aTVSvO7mGPZUc0wTEDL+qGE0Q==", "requires": { - "domelementtype": "^1.3.0", - "entities": "^1.1.1" + "domelementtype": "^2.0.1", + "entities": "^2.0.0" + }, + "dependencies": { + "domelementtype": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/domelementtype/-/domelementtype-2.0.1.tgz", + "integrity": "sha512-5HOHUDsYZWV8FGWN0Njbr/Rn7f/eWSQi1v7+HsUVwXgn8nWWlL64zKDkS0n8ZmQ3mlWOMuXOnR+7Nx/5tMO5AQ==" + }, + "entities": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/entities/-/entities-2.0.0.tgz", + "integrity": "sha512-D9f7V0JSRwIxlRI2mjMqufDrRDnx8p+eEOz7aUM9SuvF8gsBzra0/6tbjl1m8eQHrZlYj6PxqE00hZ1SAIKPLw==" + } } }, "dom-walk": { "version": "0.1.1", "resolved": "https://registry.npmjs.org/dom-walk/-/dom-walk-0.1.1.tgz", - "integrity": "sha1-ZyIm3HTI95mtNTB9+TaroRrNYBg=", - "dev": true + "integrity": "sha1-ZyIm3HTI95mtNTB9+TaroRrNYBg=" }, "domain-browser": { "version": "1.2.0", "resolved": "https://registry.npmjs.org/domain-browser/-/domain-browser-1.2.0.tgz", - "integrity": "sha512-jnjyiM6eRyZl2H+W8Q/zLMA481hzi0eszAaBUzIVnmYVDBbnLxVNnfu1HgEBvCbL+71FrxMl3E6lpKH7Ge3OXA==", - "dev": true + "integrity": "sha512-jnjyiM6eRyZl2H+W8Q/zLMA481hzi0eszAaBUzIVnmYVDBbnLxVNnfu1HgEBvCbL+71FrxMl3E6lpKH7Ge3OXA==" }, "domelementtype": { "version": "1.3.1", "resolved": "https://registry.npmjs.org/domelementtype/-/domelementtype-1.3.1.tgz", - "integrity": "sha512-BSKB+TSpMpFI/HOxCNr1O8aMOTZ8hT3pM3GQ0w/mWRmkhEDSFJkkyzz4XQsBV44BChwGkrDfMyjVD0eA2aFV3w==", - "dev": true + "integrity": "sha512-BSKB+TSpMpFI/HOxCNr1O8aMOTZ8hT3pM3GQ0w/mWRmkhEDSFJkkyzz4XQsBV44BChwGkrDfMyjVD0eA2aFV3w==" }, "domhandler": { "version": "2.4.2", "resolved": "https://registry.npmjs.org/domhandler/-/domhandler-2.4.2.tgz", "integrity": "sha512-JiK04h0Ht5u/80fdLMCEmV4zkNh2BcoMFBmZ/91WtYZ8qVXSKjiw7fXMgFPnHcSZgOo3XdinHvmnDUeMf5R4wA==", - "dev": true, "requires": { "domelementtype": "1" } @@ -3314,7 +3173,6 @@ "version": "1.7.0", "resolved": "https://registry.npmjs.org/domutils/-/domutils-1.7.0.tgz", "integrity": "sha512-Lgd2XcJ/NjEw+7tFvfKxOzCYKZsdct5lczQ2ZaQY8Djz7pfAD3Gbp8ySJWtreII/vDlMVmxwa6pHmdxIYgttDg==", - "dev": true, "requires": { "dom-serializer": "0", "domelementtype": "1" @@ -3324,7 +3182,6 @@ "version": "4.2.0", "resolved": "https://registry.npmjs.org/dot-prop/-/dot-prop-4.2.0.tgz", "integrity": "sha512-tUMXrxlExSW6U2EXiiKGSBVdYgtV8qlHL+C10TsW4PURY/ic+eaysnSkwB4kA/mBlCyy/IKDJ+Lc3wbWeaXtuQ==", - "dev": true, "requires": { "is-obj": "^1.0.0" } @@ -3333,7 +3190,6 @@ "version": "3.7.1", "resolved": "https://registry.npmjs.org/duplexify/-/duplexify-3.7.1.tgz", "integrity": "sha512-07z8uv2wMyS51kKhD1KsdXJg5WQ6t93RneqRxUHnskXVtlYYkLqM0gqStQZ3pj073g687jPCHrqNfCzawLYh5g==", - "dev": true, "requires": { "end-of-stream": "^1.0.0", "inherits": "^2.0.1", @@ -3345,7 +3201,6 @@ "version": "0.1.2", "resolved": "https://registry.npmjs.org/ecc-jsbn/-/ecc-jsbn-0.1.2.tgz", "integrity": "sha1-OoOpBOVDUyh4dMVkt1SThoSamMk=", - "dev": true, "requires": { "jsbn": "~0.1.0", "safer-buffer": "^2.1.0" @@ -3354,20 +3209,17 @@ "ee-first": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/ee-first/-/ee-first-1.1.1.tgz", - "integrity": "sha1-WQxhFWsK4vTwJVcyoViyZrxWsh0=", - "dev": true + "integrity": "sha1-WQxhFWsK4vTwJVcyoViyZrxWsh0=" }, "electron-to-chromium": { - "version": "1.3.175", - "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.3.175.tgz", - "integrity": "sha512-cQ0o7phcPA0EYkN4juZy/rq4XVxl/1ywQnytDT9hZTC0cHfaOBqWK2XlWp9Mk8xRGntgnmxlHTOux4HLb2ZNnA==", - "dev": true + "version": "1.3.295", + "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.3.295.tgz", + "integrity": "sha512-KxlGE9GcZTv7xGwYJGMEABHJq2JuTMNF7jD8NwHk6sBY226mW+Dyp9kZmA2Od9tKHMCS7ltPnqFg+zq3jTWN7Q==" }, "elliptic": { - "version": "6.5.0", - "resolved": "https://registry.npmjs.org/elliptic/-/elliptic-6.5.0.tgz", - "integrity": "sha512-eFOJTMyCYb7xtE/caJ6JJu+bhi67WCYNbkGSknu20pmM8Ke/bqOfdnZWxyoGN26JgfxTbXrsCkEw4KheCT/KGg==", - "dev": true, + "version": "6.5.1", + "resolved": "https://registry.npmjs.org/elliptic/-/elliptic-6.5.1.tgz", + "integrity": "sha512-xvJINNLbTeWQjrl6X+7eQCrIy/YPv5XCpKW6kB5mKvtnGILoLDcySuwomfdzt0BMdLNVnuRNTuzKNHj0bva1Cg==", "requires": { "bn.js": "^4.4.0", "brorand": "^1.0.1", @@ -3381,68 +3233,70 @@ "emoji-regex": { "version": "7.0.3", "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-7.0.3.tgz", - "integrity": "sha512-CwBLREIQ7LvYFB0WyRvwhq5N5qPhc6PMjD6bYggFlI5YyDgl+0vxq5VHbMOFqLg7hfWzmu8T5Z1QofhmTIhItA==", - "dev": true + "integrity": "sha512-CwBLREIQ7LvYFB0WyRvwhq5N5qPhc6PMjD6bYggFlI5YyDgl+0vxq5VHbMOFqLg7hfWzmu8T5Z1QofhmTIhItA==" }, "emojis-list": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/emojis-list/-/emojis-list-2.1.0.tgz", - "integrity": "sha1-TapNnbAPmBmIDHn6RXrlsJof04k=", - "dev": true + "integrity": "sha1-TapNnbAPmBmIDHn6RXrlsJof04k=" }, "encodeurl": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/encodeurl/-/encodeurl-1.0.2.tgz", - "integrity": "sha1-rT/0yG7C0CkyL1oCw6mmBslbP1k=", - "dev": true + "integrity": "sha1-rT/0yG7C0CkyL1oCw6mmBslbP1k=" }, "end-of-stream": { - "version": "1.4.1", - "resolved": "https://registry.npmjs.org/end-of-stream/-/end-of-stream-1.4.1.tgz", - "integrity": "sha512-1MkrZNvWTKCaigbn+W15elq2BB/L22nqrSY5DKlo3X6+vclJm8Bb5djXJBmEX6fS3+zCh/F4VBK5Z2KxJt4s2Q==", - "dev": true, + "version": "1.4.4", + "resolved": "https://registry.npmjs.org/end-of-stream/-/end-of-stream-1.4.4.tgz", + "integrity": "sha512-+uw1inIHVPQoaVuHzRyXd21icM+cnt4CzD5rW+NC1wjOUSTOs+Te7FOv7AhN7vS9x/oIyhLP5PR1H+phQAHu5Q==", "requires": { "once": "^1.4.0" } }, "enhanced-resolve": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/enhanced-resolve/-/enhanced-resolve-4.1.0.tgz", - "integrity": "sha512-F/7vkyTtyc/llOIn8oWclcB25KdRaiPBpZYDgJHgh/UHtpgT2p2eldQgtQnLtUvfMKPKxbRaQM/hHkvLHt1Vng==", - "dev": true, + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/enhanced-resolve/-/enhanced-resolve-4.1.1.tgz", + "integrity": "sha512-98p2zE+rL7/g/DzMHMTF4zZlCgeVdJ7yr6xzEpJRYwFYrGi9ANdn5DnJURg6RpBkyk60XYDnWIv51VfIhfNGuA==", "requires": { "graceful-fs": "^4.1.2", - "memory-fs": "^0.4.0", + "memory-fs": "^0.5.0", "tapable": "^1.0.0" + }, + "dependencies": { + "memory-fs": { + "version": "0.5.0", + "resolved": "https://registry.npmjs.org/memory-fs/-/memory-fs-0.5.0.tgz", + "integrity": "sha512-jA0rdU5KoQMC0e6ppoNRtpp6vjFq6+NY7r8hywnC7V+1Xj/MtHwGIbB1QaK/dunyjWteJzmkpd7ooeWg10T7GA==", + "requires": { + "errno": "^0.1.3", + "readable-stream": "^2.0.1" + } + } } }, "entities": { "version": "1.1.2", "resolved": "https://registry.npmjs.org/entities/-/entities-1.1.2.tgz", - "integrity": "sha512-f2LZMYl1Fzu7YSBKg+RoROelpOaNrcGmE9AZubeDfrCEia483oW4MI4VyFd5VNHIgQ/7qm1I0wUHK1eJnn2y2w==", - "dev": true + "integrity": "sha512-f2LZMYl1Fzu7YSBKg+RoROelpOaNrcGmE9AZubeDfrCEia483oW4MI4VyFd5VNHIgQ/7qm1I0wUHK1eJnn2y2w==" }, "envify": { "version": "4.1.0", "resolved": "https://registry.npmjs.org/envify/-/envify-4.1.0.tgz", "integrity": "sha512-IKRVVoAYr4pIx4yIWNsz9mOsboxlNXiu7TNBnem/K/uTHdkyzXWDzHCK7UTolqBbgaBz0tQHsD3YNls0uIIjiw==", - "dev": true, "requires": { "esprima": "^4.0.0", "through": "~2.3.4" } }, "envinfo": { - "version": "7.3.1", - "resolved": "https://registry.npmjs.org/envinfo/-/envinfo-7.3.1.tgz", - "integrity": "sha512-GvXiDTqLYrORVSCuJCsWHPXF5BFvoWMQA9xX4YVjPT1jyS3aZEHUBwjzxU/6LTPF9ReHgVEbX7IEN5UvSXHw/A==", - "dev": true + "version": "7.4.0", + "resolved": "https://registry.npmjs.org/envinfo/-/envinfo-7.4.0.tgz", + "integrity": "sha512-FdDfnWnCVjxTTpWE3d6Jgh5JDIA3Cw7LCgpM/pI7kK1ORkjaqI2r6NqQ+ln2j0dfpgxY00AWieSvtkiZQKIItA==" }, "errno": { "version": "0.1.7", "resolved": "https://registry.npmjs.org/errno/-/errno-0.1.7.tgz", "integrity": "sha512-MfrRBDWzIWifgq6tJj60gkAwtLNb6sQPlcFrSOflcP1aFmmruKQ2wRnze/8V6kgyz7H3FF8Npzv78mZ7XLLflg==", - "dev": true, "requires": { "prr": "~1.0.1" } @@ -3451,30 +3305,31 @@ "version": "1.3.2", "resolved": "https://registry.npmjs.org/error-ex/-/error-ex-1.3.2.tgz", "integrity": "sha512-7dFHNmqeFSEt2ZBsCriorKnn3Z2pj+fd9kmI6QoWw4//DL+icEBfc0U7qJCisqrTsKTjw4fNFy2pW9OqStD84g==", - "dev": true, "requires": { "is-arrayish": "^0.2.1" } }, "es-abstract": { - "version": "1.13.0", - "resolved": "https://registry.npmjs.org/es-abstract/-/es-abstract-1.13.0.tgz", - "integrity": "sha512-vDZfg/ykNxQVwup/8E1BZhVzFfBxs9NqMzGcvIJrqg5k2/5Za2bWo40dK2J1pgLngZ7c+Shh8lwYtLGyrwPutg==", - "dev": true, + "version": "1.16.0", + "resolved": "https://registry.npmjs.org/es-abstract/-/es-abstract-1.16.0.tgz", + "integrity": "sha512-xdQnfykZ9JMEiasTAJZJdMWCQ1Vm00NBw79/AWi7ELfZuuPCSOMDZbT9mkOfSctVtfhb+sAAzrm+j//GjjLHLg==", "requires": { "es-to-primitive": "^1.2.0", "function-bind": "^1.1.1", "has": "^1.0.3", + "has-symbols": "^1.0.0", "is-callable": "^1.1.4", "is-regex": "^1.0.4", - "object-keys": "^1.0.12" + "object-inspect": "^1.6.0", + "object-keys": "^1.1.1", + "string.prototype.trimleft": "^2.1.0", + "string.prototype.trimright": "^2.1.0" } }, "es-to-primitive": { "version": "1.2.0", "resolved": "https://registry.npmjs.org/es-to-primitive/-/es-to-primitive-1.2.0.tgz", "integrity": "sha512-qZryBOJjV//LaxLTV6UC//WewneB3LcXOL9NP++ozKVXsIIIpm/2c13UDiD9Jp2eThsecw9m3jPqDwTyobcdbg==", - "dev": true, "requires": { "is-callable": "^1.1.4", "is-date-object": "^1.0.1", @@ -3484,26 +3339,22 @@ "es6-promise": { "version": "4.2.8", "resolved": "https://registry.npmjs.org/es6-promise/-/es6-promise-4.2.8.tgz", - "integrity": "sha512-HJDGx5daxeIvxdBxvG2cb9g4tEvwIk3i8+nhX0yGrYmZUzbkdg8QbDevheDB8gd0//uPj4c1EQua8Q+MViT0/w==", - "dev": true + "integrity": "sha512-HJDGx5daxeIvxdBxvG2cb9g4tEvwIk3i8+nhX0yGrYmZUzbkdg8QbDevheDB8gd0//uPj4c1EQua8Q+MViT0/w==" }, "escape-html": { "version": "1.0.3", "resolved": "https://registry.npmjs.org/escape-html/-/escape-html-1.0.3.tgz", - "integrity": "sha1-Aljq5NPQwJdN4cFpGI7wBR0dGYg=", - "dev": true + "integrity": "sha1-Aljq5NPQwJdN4cFpGI7wBR0dGYg=" }, "escape-string-regexp": { "version": "1.0.5", "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", - "integrity": "sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ=", - "dev": true + "integrity": "sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ=" }, "eslint-scope": { "version": "4.0.3", "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-4.0.3.tgz", "integrity": "sha512-p7VutNr1O/QrxysMo3E45FjYDTeXBy0iTltPFNSqKAIfjDSXC+4dj+qfyuD8bfAXrW/y6lW3O76VaYNPKfpKrg==", - "dev": true, "requires": { "esrecurse": "^4.1.0", "estraverse": "^4.1.1" @@ -3512,53 +3363,45 @@ "esprima": { "version": "4.0.1", "resolved": "https://registry.npmjs.org/esprima/-/esprima-4.0.1.tgz", - "integrity": "sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A==", - "dev": true + "integrity": "sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A==" }, "esrecurse": { "version": "4.2.1", "resolved": "https://registry.npmjs.org/esrecurse/-/esrecurse-4.2.1.tgz", "integrity": "sha512-64RBB++fIOAXPw3P9cy89qfMlvZEXZkqqJkjqqXIvzP5ezRZjW+lPWjw35UX/3EhUPFYbg5ER4JYgDw4007/DQ==", - "dev": true, "requires": { "estraverse": "^4.1.0" } }, "estraverse": { - "version": "4.2.0", - "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-4.2.0.tgz", - "integrity": "sha1-De4/7TH81GlhjOc0IJn8GvoL2xM=", - "dev": true + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-4.3.0.tgz", + "integrity": "sha512-39nnKffWz8xN1BU/2c79n9nB9HDzo0niYUqx6xyqUnyoAnQyyWpOTdZEeiCch8BBu515t4wp9ZmgVfVhn9EBpw==" }, "esutils": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/esutils/-/esutils-2.0.2.tgz", - "integrity": "sha1-Cr9PHKpbyx96nYrMbepPqqBLrJs=", - "dev": true + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/esutils/-/esutils-2.0.3.tgz", + "integrity": "sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==" }, "etag": { "version": "1.8.1", "resolved": "https://registry.npmjs.org/etag/-/etag-1.8.1.tgz", - "integrity": "sha1-Qa4u62XvpiJorr/qg6x9eSmbCIc=", - "dev": true + "integrity": "sha1-Qa4u62XvpiJorr/qg6x9eSmbCIc=" }, "eventemitter3": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/eventemitter3/-/eventemitter3-3.1.2.tgz", - "integrity": "sha512-tvtQIeLVHjDkJYnzf2dgVMxfuSGJeM/7UCG17TT4EumTfNtF+0nebF/4zWOIkCreAbtNqhGEboB6BWrwqNaw4Q==", - "dev": true + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/eventemitter3/-/eventemitter3-4.0.0.tgz", + "integrity": "sha512-qerSRB0p+UDEssxTtm6EDKcE7W4OaoisfIMl4CngyEhjpYglocpNg6UEqCvemdGhosAsg4sO2dXJOdyBifPGCg==" }, "events": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/events/-/events-3.0.0.tgz", - "integrity": "sha512-Dc381HFWJzEOhQ+d8pkNon++bk9h6cdAoAj4iE6Q4y6xgTzySWXlKn05/TVNpjnfRqi/X0EpJEJohPjNI3zpVA==", - "dev": true + "integrity": "sha512-Dc381HFWJzEOhQ+d8pkNon++bk9h6cdAoAj4iE6Q4y6xgTzySWXlKn05/TVNpjnfRqi/X0EpJEJohPjNI3zpVA==" }, "eventsource": { "version": "1.0.7", "resolved": "https://registry.npmjs.org/eventsource/-/eventsource-1.0.7.tgz", "integrity": "sha512-4Ln17+vVT0k8aWq+t/bF5arcS3EpT9gYtW66EPacdj/mAFevznsnyoHLPy2BA8gbIQeIHoPsvwmfBftfcG//BQ==", - "dev": true, "requires": { "original": "^1.0.0" } @@ -3567,7 +3410,6 @@ "version": "1.0.3", "resolved": "https://registry.npmjs.org/evp_bytestokey/-/evp_bytestokey-1.0.3.tgz", "integrity": "sha512-/f2Go4TognH/KvCISP7OUsHn85hT9nUkxxA9BEWxFn+Oj9o8ZNLm/40hdlgSLyuOimsrTKLUMEorQexp/aPQeA==", - "dev": true, "requires": { "md5.js": "^1.3.4", "safe-buffer": "^5.1.1" @@ -3577,7 +3419,6 @@ "version": "1.0.0", "resolved": "https://registry.npmjs.org/execa/-/execa-1.0.0.tgz", "integrity": "sha512-adbxcyWV46qiHyvSp50TKt05tB4tK3HcmF7/nxfAdhnox83seTDbwnaqKO4sXRy7roHAIFqJP/Rw/AuEbX61LA==", - "dev": true, "requires": { "cross-spawn": "^6.0.0", "get-stream": "^4.0.0", @@ -3592,7 +3433,6 @@ "version": "2.1.4", "resolved": "https://registry.npmjs.org/expand-brackets/-/expand-brackets-2.1.4.tgz", "integrity": "sha1-t3c14xXOMPa27/D4OwQVGiJEliI=", - "dev": true, "requires": { "debug": "^2.3.3", "define-property": "^0.2.5", @@ -3607,7 +3447,6 @@ "version": "2.6.9", "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", - "dev": true, "requires": { "ms": "2.0.0" } @@ -3616,7 +3455,6 @@ "version": "0.2.5", "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz", "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=", - "dev": true, "requires": { "is-descriptor": "^0.1.0" } @@ -3625,16 +3463,9 @@ "version": "2.0.1", "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", - "dev": true, "requires": { "is-extendable": "^0.1.0" } - }, - "ms": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", - "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=", - "dev": true } } }, @@ -3642,7 +3473,6 @@ "version": "4.17.1", "resolved": "https://registry.npmjs.org/express/-/express-4.17.1.tgz", "integrity": "sha512-mHJ9O79RqluphRrcw2X/GTh3k9tVv8YcoyY4Kkh4WDMUYKRZUq0h1o0w2rrrxBqM7VoeUVqgb27xlEMXTnYt4g==", - "dev": true, "requires": { "accepts": "~1.3.7", "array-flatten": "1.1.1", @@ -3679,37 +3509,27 @@ "array-flatten": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/array-flatten/-/array-flatten-1.1.1.tgz", - "integrity": "sha1-ml9pkFGx5wczKPKgCJaLZOopVdI=", - "dev": true + "integrity": "sha1-ml9pkFGx5wczKPKgCJaLZOopVdI=" }, "debug": { "version": "2.6.9", "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", - "dev": true, "requires": { "ms": "2.0.0" } - }, - "ms": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", - "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=", - "dev": true } } }, "extend": { "version": "3.0.2", "resolved": "https://registry.npmjs.org/extend/-/extend-3.0.2.tgz", - "integrity": "sha512-fjquC59cD7CyW6urNXK0FBufkZcoiGG80wTuPujX590cB5Ttln20E2UB4S/WARVqhXffZl2LNgS+gQdPIIim/g==", - "dev": true + "integrity": "sha512-fjquC59cD7CyW6urNXK0FBufkZcoiGG80wTuPujX590cB5Ttln20E2UB4S/WARVqhXffZl2LNgS+gQdPIIim/g==" }, "extend-shallow": { "version": "3.0.2", "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-3.0.2.tgz", "integrity": "sha1-Jqcarwc7OfshJxcnRhMcJwQCjbg=", - "dev": true, "requires": { "assign-symbols": "^1.0.0", "is-extendable": "^1.0.1" @@ -3719,7 +3539,6 @@ "version": "1.0.1", "resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-1.0.1.tgz", "integrity": "sha512-arnXMxT1hhoKo9k1LZdmlNyJdDDfy2v0fXjFlmok4+i8ul/6WlbVge9bhM74OpNPQPMGUToDtz+KXa1PneJxOA==", - "dev": true, "requires": { "is-plain-object": "^2.0.4" } @@ -3730,7 +3549,6 @@ "version": "2.0.4", "resolved": "https://registry.npmjs.org/extglob/-/extglob-2.0.4.tgz", "integrity": "sha512-Nmb6QXkELsuBr24CJSkilo6UHHgbekK5UiZgfE6UHD3Eb27YC6oD+bhcT+tJ6cl8dmsgdQxnWlcry8ksBIBLpw==", - "dev": true, "requires": { "array-unique": "^0.3.2", "define-property": "^1.0.0", @@ -3746,7 +3564,6 @@ "version": "1.0.0", "resolved": "https://registry.npmjs.org/define-property/-/define-property-1.0.0.tgz", "integrity": "sha1-dp66rz9KY6rTr56NMEybvnm/sOY=", - "dev": true, "requires": { "is-descriptor": "^1.0.0" } @@ -3755,7 +3572,6 @@ "version": "2.0.1", "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", - "dev": true, "requires": { "is-extendable": "^0.1.0" } @@ -3764,7 +3580,6 @@ "version": "1.0.0", "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-1.0.0.tgz", "integrity": "sha512-m5hnHTkcVsPfqx3AKlyttIPb7J+XykHvJP2B9bZDjlhLIoEq4XoK64Vg7boZlVWYK6LUY94dYPEE7Lh0ZkZKcQ==", - "dev": true, "requires": { "kind-of": "^6.0.0" } @@ -3773,7 +3588,6 @@ "version": "1.0.0", "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-1.0.0.tgz", "integrity": "sha512-jbRXy1FmtAoCjQkVmIVYwuuqDFUbaOeDjmed1tOGPrsMhtJA4rD9tkgA0F1qJ3gRFRXcHYVkdeaP50Q5rE/jLQ==", - "dev": true, "requires": { "kind-of": "^6.0.0" } @@ -3782,32 +3596,33 @@ "version": "1.0.2", "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-1.0.2.tgz", "integrity": "sha512-2eis5WqQGV7peooDyLmNEPUrps9+SXX5c9pL3xEB+4e9HnGuDa7mB7kHxHw4CbqS9k1T2hOH3miL8n8WtiYVtg==", - "dev": true, "requires": { "is-accessor-descriptor": "^1.0.0", "is-data-descriptor": "^1.0.0", "kind-of": "^6.0.2" } + }, + "kind-of": { + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.2.tgz", + "integrity": "sha512-s5kLOcnH0XqDO+FvuaLX8DDjZ18CGFk7VygH40QoKPUQhW4e2rvM0rwUq0t8IQDOwYSeLK01U90OjzBTme2QqA==" } } }, "extsprintf": { "version": "1.3.0", "resolved": "https://registry.npmjs.org/extsprintf/-/extsprintf-1.3.0.tgz", - "integrity": "sha1-lpGEQOMEGnpBT4xS48V06zw+HgU=", - "dev": true + "integrity": "sha1-lpGEQOMEGnpBT4xS48V06zw+HgU=" }, "fast-deep-equal": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-2.0.1.tgz", - "integrity": "sha1-ewUhjd+WZ79/Nwv3/bLLFf3Qqkk=", - "dev": true + "integrity": "sha1-ewUhjd+WZ79/Nwv3/bLLFf3Qqkk=" }, "fast-glob": { "version": "2.2.7", "resolved": "https://registry.npmjs.org/fast-glob/-/fast-glob-2.2.7.tgz", "integrity": "sha512-g1KuQwHOZAmOZMuBtHdxDtju+T2RT8jgCC9aANsbpdiDDTSnjgfuVsIBNKbUeJI3oKMRExcfNDtJl4OhbffMsw==", - "dev": true, "requires": { "@mrmlnc/readdir-enhanced": "^2.2.1", "@nodelib/fs.stat": "^1.1.2", @@ -3820,14 +3635,12 @@ "fast-json-stable-stringify": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.0.0.tgz", - "integrity": "sha1-1RQsDK7msRifh9OnYREGT4bIu/I=", - "dev": true + "integrity": "sha1-1RQsDK7msRifh9OnYREGT4bIu/I=" }, "faye-websocket": { "version": "0.10.0", "resolved": "https://registry.npmjs.org/faye-websocket/-/faye-websocket-0.10.0.tgz", "integrity": "sha1-TkkvjQTftviQA1B/btvy1QHnxvQ=", - "dev": true, "requires": { "websocket-driver": ">=0.5.1" } @@ -3835,14 +3648,12 @@ "figgy-pudding": { "version": "3.5.1", "resolved": "https://registry.npmjs.org/figgy-pudding/-/figgy-pudding-3.5.1.tgz", - "integrity": "sha512-vNKxJHTEKNThjfrdJwHc7brvM6eVevuO5nTj6ez8ZQ1qbXTvGthucRF7S4vf2cr71QVnT70V34v0S1DyQsti0w==", - "dev": true + "integrity": "sha512-vNKxJHTEKNThjfrdJwHc7brvM6eVevuO5nTj6ez8ZQ1qbXTvGthucRF7S4vf2cr71QVnT70V34v0S1DyQsti0w==" }, "figures": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/figures/-/figures-3.0.0.tgz", - "integrity": "sha512-HKri+WoWoUgr83pehn/SIgLOMZ9nAWC6dcGj26RY2R4F50u4+RTUz0RCrUlOV3nKRAICW1UGzyb+kcX2qK1S/g==", - "dev": true, + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/figures/-/figures-3.1.0.tgz", + "integrity": "sha512-ravh8VRXqHuMvZt/d8GblBeqDMkdJMBdv/2KntFH+ra5MXkO7nxNKpzQ3n6QD/2da1kH0aWmNISdvhM7gl2gVg==", "requires": { "escape-string-regexp": "^1.0.5" } @@ -3851,7 +3662,6 @@ "version": "3.0.1", "resolved": "https://registry.npmjs.org/file-loader/-/file-loader-3.0.1.tgz", "integrity": "sha512-4sNIOXgtH/9WZq4NvlfU3Opn5ynUsqBwSLyM+I7UOwdGigTBYfVVQEwe/msZNX/j4pCJTIM14Fsw66Svo1oVrw==", - "dev": true, "requires": { "loader-utils": "^1.0.2", "schema-utils": "^1.0.0" @@ -3861,7 +3671,6 @@ "version": "4.0.0", "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-4.0.0.tgz", "integrity": "sha1-1USBHUKPmOsGpj3EAtJAPDKMOPc=", - "dev": true, "requires": { "extend-shallow": "^2.0.1", "is-number": "^3.0.0", @@ -3873,7 +3682,6 @@ "version": "2.0.1", "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", - "dev": true, "requires": { "is-extendable": "^0.1.0" } @@ -3884,7 +3692,6 @@ "version": "1.1.2", "resolved": "https://registry.npmjs.org/finalhandler/-/finalhandler-1.1.2.tgz", "integrity": "sha512-aAWcW57uxVNrQZqFXjITpW3sIUQmHGG3qSb9mUah9MgMC4NeWhNOlNjXEYq3HjRAvL6arUviZGGJsBg6z0zsWA==", - "dev": true, "requires": { "debug": "2.6.9", "encodeurl": "~1.0.2", @@ -3899,16 +3706,9 @@ "version": "2.6.9", "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", - "dev": true, "requires": { "ms": "2.0.0" } - }, - "ms": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", - "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=", - "dev": true } } }, @@ -3916,7 +3716,6 @@ "version": "1.2.0", "resolved": "https://registry.npmjs.org/find-babel-config/-/find-babel-config-1.2.0.tgz", "integrity": "sha512-jB2CHJeqy6a820ssiqwrKMeyC6nNdmrcgkKWJWmpoxpE8RKciYJXCcXRq1h2AzCo5I5BJeN2tkGEO3hLTuePRA==", - "dev": true, "requires": { "json5": "^0.5.1", "path-exists": "^3.0.0" @@ -3925,8 +3724,7 @@ "json5": { "version": "0.5.1", "resolved": "https://registry.npmjs.org/json5/-/json5-0.5.1.tgz", - "integrity": "sha1-Hq3nrMASA0rYTiOWdn6tn6VJWCE=", - "dev": true + "integrity": "sha1-Hq3nrMASA0rYTiOWdn6tn6VJWCE=" } } }, @@ -3934,7 +3732,6 @@ "version": "2.1.0", "resolved": "https://registry.npmjs.org/find-cache-dir/-/find-cache-dir-2.1.0.tgz", "integrity": "sha512-Tq6PixE0w/VMFfCgbONnkiQIVol/JJL7nRMi20fqzA4NRs9AfeqMGeRdPi3wIhYkxjeBaWh2rxwapn5Tu3IqOQ==", - "dev": true, "requires": { "commondir": "^1.0.1", "make-dir": "^2.0.0", @@ -3945,7 +3742,6 @@ "version": "2.1.0", "resolved": "https://registry.npmjs.org/find-up/-/find-up-2.1.0.tgz", "integrity": "sha1-RdG35QbHF93UgndaK3eSCjwMV6c=", - "dev": true, "requires": { "locate-path": "^2.0.0" } @@ -3954,55 +3750,38 @@ "version": "1.1.1", "resolved": "https://registry.npmjs.org/flush-write-stream/-/flush-write-stream-1.1.1.tgz", "integrity": "sha512-3Z4XhFZ3992uIq0XOqb9AreonueSYphE6oYbpt5+3u06JWklbsPkNv3ZKkP9Bz/r+1MWCaMoSQ28P85+1Yc77w==", - "dev": true, "requires": { "inherits": "^2.0.3", "readable-stream": "^2.3.6" } }, "follow-redirects": { - "version": "1.7.0", - "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.7.0.tgz", - "integrity": "sha512-m/pZQy4Gj287eNy94nivy5wchN3Kp+Q5WgUPNy5lJSZ3sgkVKSYV/ZChMAQVIgx1SqfZ2zBZtPA2YlXIWxxJOQ==", - "dev": true, + "version": "1.9.0", + "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.9.0.tgz", + "integrity": "sha512-CRcPzsSIbXyVDl0QI01muNDu69S8trU4jArW9LpOt2WtC6LyUJetcIrmfHsRBx7/Jb6GHJUiuqyYxPooFfNt6A==", "requires": { - "debug": "^3.2.6" - }, - "dependencies": { - "debug": { - "version": "3.2.6", - "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.6.tgz", - "integrity": "sha512-mel+jf7nrtEl5Pn1Qx46zARXKDpBbvzezse7p7LqINmdoIk8PYP5SySaxEmYv6TZ0JyEKA1hsCId6DIhgITtWQ==", - "dev": true, - "requires": { - "ms": "^2.1.1" - } - } + "debug": "^3.0.0" } }, "for-in": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/for-in/-/for-in-1.0.2.tgz", - "integrity": "sha1-gQaNKVqBQuwKxybG4iAMMPttXoA=", - "dev": true + "integrity": "sha1-gQaNKVqBQuwKxybG4iAMMPttXoA=" }, "foreach": { "version": "2.0.5", "resolved": "https://registry.npmjs.org/foreach/-/foreach-2.0.5.tgz", - "integrity": "sha1-C+4AUBiusmDQo6865ljdATbsG5k=", - "dev": true + "integrity": "sha1-C+4AUBiusmDQo6865ljdATbsG5k=" }, "forever-agent": { "version": "0.6.1", "resolved": "https://registry.npmjs.org/forever-agent/-/forever-agent-0.6.1.tgz", - "integrity": "sha1-+8cfDEGt6zf5bFd60e1C2P2sypE=", - "dev": true + "integrity": "sha1-+8cfDEGt6zf5bFd60e1C2P2sypE=" }, "form-data": { "version": "2.3.3", "resolved": "https://registry.npmjs.org/form-data/-/form-data-2.3.3.tgz", "integrity": "sha512-1lLKB2Mu3aGP1Q/2eCOx0fNbRMe7XdwktwOruhfqqd0rIJWwN4Dh+E3hrPSlDCXnSR7UtZ1N38rVXm+6+MEhJQ==", - "dev": true, "requires": { "asynckit": "^0.4.0", "combined-stream": "^1.0.6", @@ -4012,14 +3791,12 @@ "forwarded": { "version": "0.1.2", "resolved": "https://registry.npmjs.org/forwarded/-/forwarded-0.1.2.tgz", - "integrity": "sha1-mMI9qxF1ZXuMBXPozszZGw/xjIQ=", - "dev": true + "integrity": "sha1-mMI9qxF1ZXuMBXPozszZGw/xjIQ=" }, "fragment-cache": { "version": "0.2.1", "resolved": "https://registry.npmjs.org/fragment-cache/-/fragment-cache-0.2.1.tgz", "integrity": "sha1-QpD60n8T6Jvn8zeZxrxaCr//DRk=", - "dev": true, "requires": { "map-cache": "^0.2.2" } @@ -4027,14 +3804,12 @@ "fresh": { "version": "0.5.2", "resolved": "https://registry.npmjs.org/fresh/-/fresh-0.5.2.tgz", - "integrity": "sha1-PYyt2Q2XZWn6g1qx+OSyOhBWBac=", - "dev": true + "integrity": "sha1-PYyt2Q2XZWn6g1qx+OSyOhBWBac=" }, "from2": { "version": "2.3.0", "resolved": "https://registry.npmjs.org/from2/-/from2-2.3.0.tgz", "integrity": "sha1-i/tVAr3kpNNs/e6gB/zKIdfjgq8=", - "dev": true, "requires": { "inherits": "^2.0.1", "readable-stream": "^2.0.0" @@ -4044,7 +3819,6 @@ "version": "7.0.1", "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-7.0.1.tgz", "integrity": "sha512-YJDaCJZEnBmcbw13fvdAM9AwNOJwOzrE4pqMqBq5nFiEqXUqHwlK4B+3pUw6JNvfSPtX05xFHtYy/1ni01eGCw==", - "dev": true, "requires": { "graceful-fs": "^4.1.2", "jsonfile": "^4.0.0", @@ -4055,7 +3829,6 @@ "version": "1.0.10", "resolved": "https://registry.npmjs.org/fs-write-stream-atomic/-/fs-write-stream-atomic-1.0.10.tgz", "integrity": "sha1-tH31NJPvkR33VzHnCp3tAYnbQMk=", - "dev": true, "requires": { "graceful-fs": "^4.1.2", "iferr": "^0.1.5", @@ -4066,14 +3839,12 @@ "fs.realpath": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", - "integrity": "sha1-FQStJSMVjKpA20onh8sBQRmU6k8=", - "dev": true + "integrity": "sha1-FQStJSMVjKpA20onh8sBQRmU6k8=" }, "fsevents": { "version": "1.2.9", "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-1.2.9.tgz", "integrity": "sha512-oeyj2H3EjjonWcFjD5NvZNE9Rqe4UW+nQBU2HNeKw0koVLEFIhtyETyAakeAM3de7Z/SW5kcA+fZUait9EApnw==", - "dev": true, "optional": true, "requires": { "nan": "^2.12.1", @@ -4083,25 +3854,21 @@ "abbrev": { "version": "1.1.1", "bundled": true, - "dev": true, "optional": true }, "ansi-regex": { "version": "2.1.1", "bundled": true, - "dev": true, "optional": true }, "aproba": { "version": "1.2.0", "bundled": true, - "dev": true, "optional": true }, "are-we-there-yet": { "version": "1.1.5", "bundled": true, - "dev": true, "optional": true, "requires": { "delegates": "^1.0.0", @@ -4111,13 +3878,11 @@ "balanced-match": { "version": "1.0.0", "bundled": true, - "dev": true, "optional": true }, "brace-expansion": { "version": "1.1.11", "bundled": true, - "dev": true, "optional": true, "requires": { "balanced-match": "^1.0.0", @@ -4127,37 +3892,31 @@ "chownr": { "version": "1.1.1", "bundled": true, - "dev": true, "optional": true }, "code-point-at": { "version": "1.1.0", "bundled": true, - "dev": true, "optional": true }, "concat-map": { "version": "0.0.1", "bundled": true, - "dev": true, "optional": true }, "console-control-strings": { "version": "1.1.0", "bundled": true, - "dev": true, "optional": true }, "core-util-is": { "version": "1.0.2", "bundled": true, - "dev": true, "optional": true }, "debug": { "version": "4.1.1", "bundled": true, - "dev": true, "optional": true, "requires": { "ms": "^2.1.1" @@ -4166,25 +3925,21 @@ "deep-extend": { "version": "0.6.0", "bundled": true, - "dev": true, "optional": true }, "delegates": { "version": "1.0.0", "bundled": true, - "dev": true, "optional": true }, "detect-libc": { "version": "1.0.3", "bundled": true, - "dev": true, "optional": true }, "fs-minipass": { "version": "1.2.5", "bundled": true, - "dev": true, "optional": true, "requires": { "minipass": "^2.2.1" @@ -4193,13 +3948,11 @@ "fs.realpath": { "version": "1.0.0", "bundled": true, - "dev": true, "optional": true }, "gauge": { "version": "2.7.4", "bundled": true, - "dev": true, "optional": true, "requires": { "aproba": "^1.0.3", @@ -4215,7 +3968,6 @@ "glob": { "version": "7.1.3", "bundled": true, - "dev": true, "optional": true, "requires": { "fs.realpath": "^1.0.0", @@ -4229,13 +3981,11 @@ "has-unicode": { "version": "2.0.1", "bundled": true, - "dev": true, "optional": true }, "iconv-lite": { "version": "0.4.24", "bundled": true, - "dev": true, "optional": true, "requires": { "safer-buffer": ">= 2.1.2 < 3" @@ -4244,7 +3994,6 @@ "ignore-walk": { "version": "3.0.1", "bundled": true, - "dev": true, "optional": true, "requires": { "minimatch": "^3.0.4" @@ -4253,7 +4002,6 @@ "inflight": { "version": "1.0.6", "bundled": true, - "dev": true, "optional": true, "requires": { "once": "^1.3.0", @@ -4263,19 +4011,16 @@ "inherits": { "version": "2.0.3", "bundled": true, - "dev": true, "optional": true }, "ini": { "version": "1.3.5", "bundled": true, - "dev": true, "optional": true }, "is-fullwidth-code-point": { "version": "1.0.0", "bundled": true, - "dev": true, "optional": true, "requires": { "number-is-nan": "^1.0.0" @@ -4284,13 +4029,11 @@ "isarray": { "version": "1.0.0", "bundled": true, - "dev": true, "optional": true }, "minimatch": { "version": "3.0.4", "bundled": true, - "dev": true, "optional": true, "requires": { "brace-expansion": "^1.1.7" @@ -4299,13 +4042,11 @@ "minimist": { "version": "0.0.8", "bundled": true, - "dev": true, "optional": true }, "minipass": { "version": "2.3.5", "bundled": true, - "dev": true, "optional": true, "requires": { "safe-buffer": "^5.1.2", @@ -4315,7 +4056,6 @@ "minizlib": { "version": "1.2.1", "bundled": true, - "dev": true, "optional": true, "requires": { "minipass": "^2.2.1" @@ -4324,7 +4064,6 @@ "mkdirp": { "version": "0.5.1", "bundled": true, - "dev": true, "optional": true, "requires": { "minimist": "0.0.8" @@ -4333,13 +4072,11 @@ "ms": { "version": "2.1.1", "bundled": true, - "dev": true, "optional": true }, "needle": { "version": "2.3.0", "bundled": true, - "dev": true, "optional": true, "requires": { "debug": "^4.1.0", @@ -4350,7 +4087,6 @@ "node-pre-gyp": { "version": "0.12.0", "bundled": true, - "dev": true, "optional": true, "requires": { "detect-libc": "^1.0.2", @@ -4368,7 +4104,6 @@ "nopt": { "version": "4.0.1", "bundled": true, - "dev": true, "optional": true, "requires": { "abbrev": "1", @@ -4378,13 +4113,11 @@ "npm-bundled": { "version": "1.0.6", "bundled": true, - "dev": true, "optional": true }, "npm-packlist": { "version": "1.4.1", "bundled": true, - "dev": true, "optional": true, "requires": { "ignore-walk": "^3.0.1", @@ -4394,7 +4127,6 @@ "npmlog": { "version": "4.1.2", "bundled": true, - "dev": true, "optional": true, "requires": { "are-we-there-yet": "~1.1.2", @@ -4406,19 +4138,16 @@ "number-is-nan": { "version": "1.0.1", "bundled": true, - "dev": true, "optional": true }, "object-assign": { "version": "4.1.1", "bundled": true, - "dev": true, "optional": true }, "once": { "version": "1.4.0", "bundled": true, - "dev": true, "optional": true, "requires": { "wrappy": "1" @@ -4427,19 +4156,16 @@ "os-homedir": { "version": "1.0.2", "bundled": true, - "dev": true, "optional": true }, "os-tmpdir": { "version": "1.0.2", "bundled": true, - "dev": true, "optional": true }, "osenv": { "version": "0.1.5", "bundled": true, - "dev": true, "optional": true, "requires": { "os-homedir": "^1.0.0", @@ -4449,19 +4175,16 @@ "path-is-absolute": { "version": "1.0.1", "bundled": true, - "dev": true, "optional": true }, "process-nextick-args": { "version": "2.0.0", "bundled": true, - "dev": true, "optional": true }, "rc": { "version": "1.2.8", "bundled": true, - "dev": true, "optional": true, "requires": { "deep-extend": "^0.6.0", @@ -4473,7 +4196,6 @@ "minimist": { "version": "1.2.0", "bundled": true, - "dev": true, "optional": true } } @@ -4481,7 +4203,6 @@ "readable-stream": { "version": "2.3.6", "bundled": true, - "dev": true, "optional": true, "requires": { "core-util-is": "~1.0.0", @@ -4496,7 +4217,6 @@ "rimraf": { "version": "2.6.3", "bundled": true, - "dev": true, "optional": true, "requires": { "glob": "^7.1.3" @@ -4505,43 +4225,36 @@ "safe-buffer": { "version": "5.1.2", "bundled": true, - "dev": true, "optional": true }, "safer-buffer": { "version": "2.1.2", "bundled": true, - "dev": true, "optional": true }, "sax": { "version": "1.2.4", "bundled": true, - "dev": true, "optional": true }, "semver": { "version": "5.7.0", "bundled": true, - "dev": true, "optional": true }, "set-blocking": { "version": "2.0.0", "bundled": true, - "dev": true, "optional": true }, "signal-exit": { "version": "3.0.2", "bundled": true, - "dev": true, "optional": true }, "string-width": { "version": "1.0.2", "bundled": true, - "dev": true, "optional": true, "requires": { "code-point-at": "^1.0.0", @@ -4552,7 +4265,6 @@ "string_decoder": { "version": "1.1.1", "bundled": true, - "dev": true, "optional": true, "requires": { "safe-buffer": "~5.1.0" @@ -4561,7 +4273,6 @@ "strip-ansi": { "version": "3.0.1", "bundled": true, - "dev": true, "optional": true, "requires": { "ansi-regex": "^2.0.0" @@ -4570,13 +4281,11 @@ "strip-json-comments": { "version": "2.0.1", "bundled": true, - "dev": true, "optional": true }, "tar": { "version": "4.4.8", "bundled": true, - "dev": true, "optional": true, "requires": { "chownr": "^1.1.1", @@ -4591,13 +4300,11 @@ "util-deprecate": { "version": "1.0.2", "bundled": true, - "dev": true, "optional": true }, "wide-align": { "version": "1.1.3", "bundled": true, - "dev": true, "optional": true, "requires": { "string-width": "^1.0.2 || 2" @@ -4606,13 +4313,11 @@ "wrappy": { "version": "1.0.2", "bundled": true, - "dev": true, "optional": true }, "yallist": { "version": "3.0.3", "bundled": true, - "dev": true, "optional": true } } @@ -4620,20 +4325,17 @@ "function-bind": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.1.tgz", - "integrity": "sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A==", - "dev": true + "integrity": "sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A==" }, "get-caller-file": { "version": "1.0.3", "resolved": "https://registry.npmjs.org/get-caller-file/-/get-caller-file-1.0.3.tgz", - "integrity": "sha512-3t6rVToeoZfYSGd8YoLFR2DJkiQrIiUrGcjvFX2mDw3bn6k2OtwHN0TNCLbBO+w8qTvimhDkv+LSscbJY1vE6w==", - "dev": true + "integrity": "sha512-3t6rVToeoZfYSGd8YoLFR2DJkiQrIiUrGcjvFX2mDw3bn6k2OtwHN0TNCLbBO+w8qTvimhDkv+LSscbJY1vE6w==" }, "get-stream": { "version": "4.1.0", "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-4.1.0.tgz", "integrity": "sha512-GMat4EJ5161kIy2HevLlr4luNjBgvmj413KaQA7jt4V8B4RDsfpHk7WQ9GVqfYyyx8OS/L66Kox+rJRNklLK7w==", - "dev": true, "requires": { "pump": "^3.0.0" } @@ -4641,23 +4343,20 @@ "get-value": { "version": "2.0.6", "resolved": "https://registry.npmjs.org/get-value/-/get-value-2.0.6.tgz", - "integrity": "sha1-3BXKHGcjh8p2vTesCjlbogQqLCg=", - "dev": true + "integrity": "sha1-3BXKHGcjh8p2vTesCjlbogQqLCg=" }, "getpass": { "version": "0.1.7", "resolved": "https://registry.npmjs.org/getpass/-/getpass-0.1.7.tgz", "integrity": "sha1-Xv+OPmhNVprkyysSgmBOi6YhSfo=", - "dev": true, "requires": { "assert-plus": "^1.0.0" } }, "glob": { - "version": "7.1.4", - "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.4.tgz", - "integrity": "sha512-hkLPepehmnKk41pUGm3sYxoFs/umurYfYJCerbXEyFIWcAzvpipAgVkBqqT9RBKMGjnq6kMuyYwha6csxbiM1A==", - "dev": true, + "version": "7.1.5", + "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.5.tgz", + "integrity": "sha512-J9dlskqUXK1OeTOYBEn5s8aMukWMwWfs+rPTn/jn50Ux4MNXVhubL1wu/j2t+H4NVI+cXEcCaYellqaPVGXNqQ==", "requires": { "fs.realpath": "^1.0.0", "inflight": "^1.0.4", @@ -4671,7 +4370,6 @@ "version": "3.1.0", "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-3.1.0.tgz", "integrity": "sha1-nmr2KZ2NO9K9QEMIMr0RPfkGxa4=", - "dev": true, "requires": { "is-glob": "^3.1.0", "path-dirname": "^1.0.0" @@ -4681,7 +4379,6 @@ "version": "3.1.0", "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-3.1.0.tgz", "integrity": "sha1-e6WuJCF4BKxwcHuWkiVnSGzD6Eo=", - "dev": true, "requires": { "is-extglob": "^2.1.0" } @@ -4691,14 +4388,12 @@ "glob-to-regexp": { "version": "0.3.0", "resolved": "https://registry.npmjs.org/glob-to-regexp/-/glob-to-regexp-0.3.0.tgz", - "integrity": "sha1-jFoUlNIGbFcMw7/kSWF1rMTVAqs=", - "dev": true + "integrity": "sha1-jFoUlNIGbFcMw7/kSWF1rMTVAqs=" }, "global": { "version": "4.4.0", "resolved": "https://registry.npmjs.org/global/-/global-4.4.0.tgz", "integrity": "sha512-wv/LAoHdRE3BeTGz53FAamhGlPLhlssK45usmGFThIi4XqnBmjKQ16u+RNbP7WvigRZDxUsM0J3gcQ5yicaL0w==", - "dev": true, "requires": { "min-document": "^2.19.0", "process": "^0.11.10" @@ -4707,14 +4402,12 @@ "globals": { "version": "11.12.0", "resolved": "https://registry.npmjs.org/globals/-/globals-11.12.0.tgz", - "integrity": "sha512-WOBp/EEGUiIsJSp7wcv/y6MO+lV9UoncWqxuFfm8eBwzWNgyfBd6Gz+IeKQ9jCmyhoH99g15M3T+QaVHFjizVA==", - "dev": true + "integrity": "sha512-WOBp/EEGUiIsJSp7wcv/y6MO+lV9UoncWqxuFfm8eBwzWNgyfBd6Gz+IeKQ9jCmyhoH99g15M3T+QaVHFjizVA==" }, "globby": { "version": "9.2.0", "resolved": "https://registry.npmjs.org/globby/-/globby-9.2.0.tgz", "integrity": "sha512-ollPHROa5mcxDEkwg6bPt3QbEf4pDQSNtd6JPL1YvOvAo/7/0VAm9TccUeoTmarjPw4pfUthSCqcyfNB1I3ZSg==", - "dev": true, "requires": { "@types/glob": "^7.1.1", "array-union": "^1.0.2", @@ -4730,47 +4423,48 @@ "version": "1.2.2", "resolved": "https://registry.npmjs.org/good-listener/-/good-listener-1.2.2.tgz", "integrity": "sha1-1TswzfkxPf+33JoNR3CWqm0UXFA=", - "dev": true, "optional": true, "requires": { "delegate": "^3.1.2" } }, "graceful-fs": { - "version": "4.2.0", - "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.0.tgz", - "integrity": "sha512-jpSvDPV4Cq/bgtpndIWbI5hmYxhQGHPC4d4cqBPb4DLniCfhJokdXhwhaDuLBGLQdvvRum/UiX6ECVIPvDXqdg==", - "dev": true + "version": "4.2.3", + "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.3.tgz", + "integrity": "sha512-a30VEBm4PEdx1dRB7MFK7BejejvCvBronbLjht+sHuGYj8PHs7M/5Z+rt5lw551vZ7yfTCj4Vuyy3mSJytDWRQ==" }, "gray-matter": { "version": "4.0.2", "resolved": "https://registry.npmjs.org/gray-matter/-/gray-matter-4.0.2.tgz", "integrity": "sha512-7hB/+LxrOjq/dd8APlK0r24uL/67w7SkYnfwhNFwg/VDIGWGmduTDYf3WNstLW2fbbmRwrDGCVSJ2isuf2+4Hw==", - "dev": true, "requires": { "js-yaml": "^3.11.0", "kind-of": "^6.0.2", "section-matter": "^1.0.0", "strip-bom-string": "^1.0.0" + }, + "dependencies": { + "kind-of": { + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.2.tgz", + "integrity": "sha512-s5kLOcnH0XqDO+FvuaLX8DDjZ18CGFk7VygH40QoKPUQhW4e2rvM0rwUq0t8IQDOwYSeLK01U90OjzBTme2QqA==" + } } }, "handle-thing": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/handle-thing/-/handle-thing-2.0.0.tgz", - "integrity": "sha512-d4sze1JNC454Wdo2fkuyzCr6aHcbL6PGGuFAz0Li/NcOm1tCHGnWDRmJP85dh9IhQErTc2svWFEX5xHIOo//kQ==", - "dev": true + "integrity": "sha512-d4sze1JNC454Wdo2fkuyzCr6aHcbL6PGGuFAz0Li/NcOm1tCHGnWDRmJP85dh9IhQErTc2svWFEX5xHIOo//kQ==" }, "har-schema": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/har-schema/-/har-schema-2.0.0.tgz", - "integrity": "sha1-qUwiJOvKwEeCoNkDVSHyRzW37JI=", - "dev": true + "integrity": "sha1-qUwiJOvKwEeCoNkDVSHyRzW37JI=" }, "har-validator": { "version": "5.1.3", "resolved": "https://registry.npmjs.org/har-validator/-/har-validator-5.1.3.tgz", "integrity": "sha512-sNvOCzEQNr/qrvJgc3UG/kD4QtlHycrzwS+6mfTrrSq97BvaYcPZZI1ZSqGSPR73Cxn4LKTD4PttRwfU7jWq5g==", - "dev": true, "requires": { "ajv": "^6.5.5", "har-schema": "^2.0.0" @@ -4780,7 +4474,6 @@ "version": "1.0.3", "resolved": "https://registry.npmjs.org/has/-/has-1.0.3.tgz", "integrity": "sha512-f2dvO0VU6Oej7RkWJGrehjbzMAjFp5/VKPp5tTpWIV4JHHZK1/BxbFRtf/siA2SWTe09caDmVtYYzWEIbBS4zw==", - "dev": true, "requires": { "function-bind": "^1.1.1" } @@ -4789,7 +4482,6 @@ "version": "2.0.0", "resolved": "https://registry.npmjs.org/has-ansi/-/has-ansi-2.0.0.tgz", "integrity": "sha1-NPUEnOHs3ysGSa8+8k5F7TVBbZE=", - "dev": true, "requires": { "ansi-regex": "^2.0.0" } @@ -4797,20 +4489,17 @@ "has-flag": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", - "integrity": "sha1-tdRU3CGZriJWmfNGfloH87lVuv0=", - "dev": true + "integrity": "sha1-tdRU3CGZriJWmfNGfloH87lVuv0=" }, "has-symbols": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.0.0.tgz", - "integrity": "sha1-uhqPGvKg/DllD1yFA2dwQSIGO0Q=", - "dev": true + "integrity": "sha1-uhqPGvKg/DllD1yFA2dwQSIGO0Q=" }, "has-value": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/has-value/-/has-value-1.0.0.tgz", "integrity": "sha1-GLKB2lhbHFxR3vJMkw7SmgvmsXc=", - "dev": true, "requires": { "get-value": "^2.0.6", "has-values": "^1.0.0", @@ -4821,7 +4510,6 @@ "version": "1.0.0", "resolved": "https://registry.npmjs.org/has-values/-/has-values-1.0.0.tgz", "integrity": "sha1-lbC2P+whRmGab+V/51Yo1aOe/k8=", - "dev": true, "requires": { "is-number": "^3.0.0", "kind-of": "^4.0.0" @@ -4831,7 +4519,6 @@ "version": "4.0.0", "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-4.0.0.tgz", "integrity": "sha1-IIE989cSkosgc3hpGkUGb65y3Vc=", - "dev": true, "requires": { "is-buffer": "^1.1.5" } @@ -4842,7 +4529,6 @@ "version": "3.0.4", "resolved": "https://registry.npmjs.org/hash-base/-/hash-base-3.0.4.tgz", "integrity": "sha1-X8hoaEfs1zSZQDMZprCj8/auSRg=", - "dev": true, "requires": { "inherits": "^2.0.1", "safe-buffer": "^5.0.1" @@ -4851,14 +4537,12 @@ "hash-sum": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/hash-sum/-/hash-sum-1.0.2.tgz", - "integrity": "sha1-M7QHd3VMZDJXPBIMw4CLvRDUfwQ=", - "dev": true + "integrity": "sha1-M7QHd3VMZDJXPBIMw4CLvRDUfwQ=" }, "hash.js": { "version": "1.1.7", "resolved": "https://registry.npmjs.org/hash.js/-/hash.js-1.1.7.tgz", "integrity": "sha512-taOaskGt4z4SOANNseOviYDvjEJinIkRgmp7LbKP2YTTmVxWBl87s/uzK9r+44BclBSp2X7K1hqeNfz9JbBeXA==", - "dev": true, "requires": { "inherits": "^2.0.3", "minimalistic-assert": "^1.0.1" @@ -4867,20 +4551,17 @@ "he": { "version": "1.2.0", "resolved": "https://registry.npmjs.org/he/-/he-1.2.0.tgz", - "integrity": "sha512-F/1DnUGPopORZi0ni+CvrCgHQ5FyEAHRLSApuYWMmrbSwoN2Mn/7k+Gl38gJnR7yyDZk6WLXwiGod1JOWNDKGw==", - "dev": true + "integrity": "sha512-F/1DnUGPopORZi0ni+CvrCgHQ5FyEAHRLSApuYWMmrbSwoN2Mn/7k+Gl38gJnR7yyDZk6WLXwiGod1JOWNDKGw==" }, "hex-color-regex": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/hex-color-regex/-/hex-color-regex-1.1.0.tgz", - "integrity": "sha512-l9sfDFsuqtOqKDsQdqrMRk0U85RZc0RtOR9yPI7mRVOa4FsR/BVnZ0shmQRM96Ji99kYZP/7hn1cedc1+ApsTQ==", - "dev": true + "integrity": "sha512-l9sfDFsuqtOqKDsQdqrMRk0U85RZc0RtOR9yPI7mRVOa4FsR/BVnZ0shmQRM96Ji99kYZP/7hn1cedc1+ApsTQ==" }, "hmac-drbg": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/hmac-drbg/-/hmac-drbg-1.0.1.tgz", "integrity": "sha1-0nRXAQJabHdabFRXk+1QL8DGSaE=", - "dev": true, "requires": { "hash.js": "^1.0.3", "minimalistic-assert": "^1.0.0", @@ -4891,7 +4572,6 @@ "version": "3.0.2", "resolved": "https://registry.npmjs.org/hogan.js/-/hogan.js-3.0.2.tgz", "integrity": "sha1-TNnhq9QpQUbnZ55B14mHMrAse/0=", - "dev": true, "requires": { "mkdirp": "0.3.0", "nopt": "1.0.10" @@ -4900,8 +4580,7 @@ "mkdirp": { "version": "0.3.0", "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.3.0.tgz", - "integrity": "sha1-G79asbqCevI1dRQ0kEJkVfSB/h4=", - "dev": true + "integrity": "sha1-G79asbqCevI1dRQ0kEJkVfSB/h4=" } } }, @@ -4909,7 +4588,6 @@ "version": "2.1.6", "resolved": "https://registry.npmjs.org/hpack.js/-/hpack.js-2.1.6.tgz", "integrity": "sha1-h3dMCUnlE/QuhFdbPEVoH63ioLI=", - "dev": true, "requires": { "inherits": "^2.0.1", "obuf": "^1.0.0", @@ -4920,32 +4598,27 @@ "hsl-regex": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/hsl-regex/-/hsl-regex-1.0.0.tgz", - "integrity": "sha1-1JMwx4ntgZ4nakwNJy3/owsY/m4=", - "dev": true + "integrity": "sha1-1JMwx4ntgZ4nakwNJy3/owsY/m4=" }, "hsla-regex": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/hsla-regex/-/hsla-regex-1.0.0.tgz", - "integrity": "sha1-wc56MWjIxmFAM6S194d/OyJfnDg=", - "dev": true + "integrity": "sha1-wc56MWjIxmFAM6S194d/OyJfnDg=" }, "html-comment-regex": { "version": "1.1.2", "resolved": "https://registry.npmjs.org/html-comment-regex/-/html-comment-regex-1.1.2.tgz", - "integrity": "sha512-P+M65QY2JQ5Y0G9KKdlDpo0zK+/OHptU5AaBwUfAIDJZk1MYf32Frm84EcOytfJE0t5JvkAnKlmjsXDnWzCJmQ==", - "dev": true + "integrity": "sha512-P+M65QY2JQ5Y0G9KKdlDpo0zK+/OHptU5AaBwUfAIDJZk1MYf32Frm84EcOytfJE0t5JvkAnKlmjsXDnWzCJmQ==" }, "html-entities": { "version": "1.2.1", "resolved": "https://registry.npmjs.org/html-entities/-/html-entities-1.2.1.tgz", - "integrity": "sha1-DfKTUfByEWNRXfueVUPl9u7VFi8=", - "dev": true + "integrity": "sha1-DfKTUfByEWNRXfueVUPl9u7VFi8=" }, "html-minifier": { "version": "3.5.21", "resolved": "https://registry.npmjs.org/html-minifier/-/html-minifier-3.5.21.tgz", "integrity": "sha512-LKUKwuJDhxNa3uf/LPR/KVjm/l3rBqtYeCOAekvG8F1vItxMUpueGd94i/asDDr8/1u7InxzFA5EeGjhhG5mMA==", - "dev": true, "requires": { "camel-case": "3.0.x", "clean-css": "4.2.x", @@ -4954,19 +4627,35 @@ "param-case": "2.1.x", "relateurl": "0.2.x", "uglify-js": "3.4.x" + }, + "dependencies": { + "uglify-js": { + "version": "3.4.10", + "resolved": "https://registry.npmjs.org/uglify-js/-/uglify-js-3.4.10.tgz", + "integrity": "sha512-Y2VsbPVs0FIshJztycsO2SfPk7/KAF/T72qzv9u5EpQ4kB2hQoHlhNQTsNyy6ul7lQtqJN/AoWeS23OzEiEFxw==", + "requires": { + "commander": "~2.19.0", + "source-map": "~0.6.1" + }, + "dependencies": { + "commander": { + "version": "2.19.0", + "resolved": "https://registry.npmjs.org/commander/-/commander-2.19.0.tgz", + "integrity": "sha512-6tvAOO+D6OENvRAh524Dh9jcfKTYDQAqvqezbCW82xj5X0pSrcpxtvRKHLG0yBY6SD7PSDrJaj+0AiOcKVd1Xg==" + } + } + } } }, "html-tags": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/html-tags/-/html-tags-2.0.0.tgz", - "integrity": "sha1-ELMKOGCF9Dzt41PMj6fLDe7qZos=", - "dev": true + "integrity": "sha1-ELMKOGCF9Dzt41PMj6fLDe7qZos=" }, "htmlparser2": { "version": "3.10.1", "resolved": "https://registry.npmjs.org/htmlparser2/-/htmlparser2-3.10.1.tgz", "integrity": "sha512-IgieNijUMbkDovyoKObU1DUhm1iwNYE/fuifEoEHfd1oZKZDaONBSkal7Y01shxsM49R4XaMdGez3WnF9UfiCQ==", - "dev": true, "requires": { "domelementtype": "^1.3.1", "domhandler": "^2.3.0", @@ -4980,7 +4669,6 @@ "version": "3.4.0", "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.4.0.tgz", "integrity": "sha512-jItXPLmrSR8jmTRmRWJXCnGJsfy85mB3Wd/uINMXA65yrnFo0cPClFIUWzo2najVNSl+mx7/4W8ttlLWJe99pQ==", - "dev": true, "requires": { "inherits": "^2.0.3", "string_decoder": "^1.1.1", @@ -4992,14 +4680,12 @@ "http-deceiver": { "version": "1.2.7", "resolved": "https://registry.npmjs.org/http-deceiver/-/http-deceiver-1.2.7.tgz", - "integrity": "sha1-+nFolEq5pRnTN8sL7HKE3D5yPYc=", - "dev": true + "integrity": "sha1-+nFolEq5pRnTN8sL7HKE3D5yPYc=" }, "http-errors": { "version": "1.7.2", "resolved": "https://registry.npmjs.org/http-errors/-/http-errors-1.7.2.tgz", "integrity": "sha512-uUQBt3H/cSIVfch6i1EuPNy/YsRSOUBXTVfZ+yR7Zjez3qjBz6i9+i4zjNaoqcoFVI4lQJ5plg63TvGfRSDCRg==", - "dev": true, "requires": { "depd": "~1.1.2", "inherits": "2.0.3", @@ -5011,24 +4697,21 @@ "inherits": { "version": "2.0.3", "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.3.tgz", - "integrity": "sha1-Yzwsg+PaQqUC9SRmAiSA9CCCYd4=", - "dev": true + "integrity": "sha1-Yzwsg+PaQqUC9SRmAiSA9CCCYd4=" } } }, "http-parser-js": { "version": "0.4.10", "resolved": "https://registry.npmjs.org/http-parser-js/-/http-parser-js-0.4.10.tgz", - "integrity": "sha1-ksnBN0w1CF912zWexWzCV8u5P6Q=", - "dev": true + "integrity": "sha1-ksnBN0w1CF912zWexWzCV8u5P6Q=" }, "http-proxy": { - "version": "1.17.0", - "resolved": "https://registry.npmjs.org/http-proxy/-/http-proxy-1.17.0.tgz", - "integrity": "sha512-Taqn+3nNvYRfJ3bGvKfBSRwy1v6eePlm3oc/aWVxZp57DQr5Eq3xhKJi7Z4hZpS8PC3H4qI+Yly5EmFacGuA/g==", - "dev": true, + "version": "1.18.0", + "resolved": "https://registry.npmjs.org/http-proxy/-/http-proxy-1.18.0.tgz", + "integrity": "sha512-84I2iJM/n1d4Hdgc6y2+qY5mDaz2PUVjlg9znE9byl+q0uC3DeByqBGReQu5tpLK0TAqTIXScRUV+dg7+bUPpQ==", "requires": { - "eventemitter3": "^3.0.0", + "eventemitter3": "^4.0.0", "follow-redirects": "^1.0.0", "requires-port": "^1.0.0" } @@ -5037,7 +4720,6 @@ "version": "0.19.1", "resolved": "https://registry.npmjs.org/http-proxy-middleware/-/http-proxy-middleware-0.19.1.tgz", "integrity": "sha512-yHYTgWMQO8VvwNS22eLLloAkvungsKdKTLO8AJlftYIKNfJr3GK3zK0ZCfzDDGUBttdGc8xFy1mCitvNKQtC3Q==", - "dev": true, "requires": { "http-proxy": "^1.17.0", "is-glob": "^4.0.0", @@ -5049,7 +4731,6 @@ "version": "1.2.0", "resolved": "https://registry.npmjs.org/http-signature/-/http-signature-1.2.0.tgz", "integrity": "sha1-muzZJRFHcvPZW2WmCruPfBj7rOE=", - "dev": true, "requires": { "assert-plus": "^1.0.0", "jsprim": "^1.2.2", @@ -5059,14 +4740,12 @@ "https-browserify": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/https-browserify/-/https-browserify-1.0.0.tgz", - "integrity": "sha1-7AbBDgo0wPL68Zn3/X/Hj//QPHM=", - "dev": true + "integrity": "sha1-7AbBDgo0wPL68Zn3/X/Hj//QPHM=" }, "iconv-lite": { "version": "0.4.24", "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.24.tgz", "integrity": "sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA==", - "dev": true, "requires": { "safer-buffer": ">= 2.1.2 < 3" } @@ -5074,14 +4753,12 @@ "icss-replace-symbols": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/icss-replace-symbols/-/icss-replace-symbols-1.1.0.tgz", - "integrity": "sha1-Bupvg2ead0njhs/h/oEq5dsiPe0=", - "dev": true + "integrity": "sha1-Bupvg2ead0njhs/h/oEq5dsiPe0=" }, "icss-utils": { "version": "4.1.1", "resolved": "https://registry.npmjs.org/icss-utils/-/icss-utils-4.1.1.tgz", "integrity": "sha512-4aFq7wvWyMHKgxsH8QQtGpvbASCf+eM3wPRLI6R+MgAnTCZ6STYsRvttLvRWK0Nfif5piF394St3HeJDaljGPA==", - "dev": true, "requires": { "postcss": "^7.0.14" } @@ -5089,32 +4766,27 @@ "ieee754": { "version": "1.1.13", "resolved": "https://registry.npmjs.org/ieee754/-/ieee754-1.1.13.tgz", - "integrity": "sha512-4vf7I2LYV/HaWerSo3XmlMkp5eZ83i+/CDluXi/IGTs/O1sejBNhTtnxzmRZfvOUqj7lZjqHkeTvpgSFDlWZTg==", - "dev": true + "integrity": "sha512-4vf7I2LYV/HaWerSo3XmlMkp5eZ83i+/CDluXi/IGTs/O1sejBNhTtnxzmRZfvOUqj7lZjqHkeTvpgSFDlWZTg==" }, "iferr": { "version": "0.1.5", "resolved": "https://registry.npmjs.org/iferr/-/iferr-0.1.5.tgz", - "integrity": "sha1-xg7taebY/bazEEofy8ocGS3FtQE=", - "dev": true + "integrity": "sha1-xg7taebY/bazEEofy8ocGS3FtQE=" }, "ignore": { "version": "4.0.6", "resolved": "https://registry.npmjs.org/ignore/-/ignore-4.0.6.tgz", - "integrity": "sha512-cyFDKrqc/YdcWFniJhzI42+AzS+gNwmUzOSFcRCQYwySuBBBy/KjuxWLZ/FHEH6Moq1NizMOBWyTcv8O4OZIMg==", - "dev": true + "integrity": "sha512-cyFDKrqc/YdcWFniJhzI42+AzS+gNwmUzOSFcRCQYwySuBBBy/KjuxWLZ/FHEH6Moq1NizMOBWyTcv8O4OZIMg==" }, "immediate": { "version": "3.2.3", "resolved": "https://registry.npmjs.org/immediate/-/immediate-3.2.3.tgz", - "integrity": "sha1-0UD6j2FGWb1lQSMwl92qwlzdmRw=", - "dev": true + "integrity": "sha1-0UD6j2FGWb1lQSMwl92qwlzdmRw=" }, "import-cwd": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/import-cwd/-/import-cwd-2.1.0.tgz", "integrity": "sha1-qmzzbnInYShcs3HsZRn1PiQ1sKk=", - "dev": true, "requires": { "import-from": "^2.1.0" } @@ -5123,7 +4795,6 @@ "version": "2.0.0", "resolved": "https://registry.npmjs.org/import-fresh/-/import-fresh-2.0.0.tgz", "integrity": "sha1-2BNVwVYS04bGH53dOSLUMEgipUY=", - "dev": true, "requires": { "caller-path": "^2.0.0", "resolve-from": "^3.0.0" @@ -5133,7 +4804,6 @@ "version": "2.1.0", "resolved": "https://registry.npmjs.org/import-from/-/import-from-2.1.0.tgz", "integrity": "sha1-M1238qev/VOqpHHUuAId7ja387E=", - "dev": true, "requires": { "resolve-from": "^3.0.0" } @@ -5142,7 +4812,6 @@ "version": "2.0.0", "resolved": "https://registry.npmjs.org/import-local/-/import-local-2.0.0.tgz", "integrity": "sha512-b6s04m3O+s3CGSbqDIyP4R6aAwAeYlVq9+WUWep6iHa8ETRf9yei1U48C5MmfJmV9AiLYYBKPMq/W+/WRpQmCQ==", - "dev": true, "requires": { "pkg-dir": "^3.0.0", "resolve-cwd": "^2.0.0" @@ -5151,20 +4820,22 @@ "imurmurhash": { "version": "0.1.4", "resolved": "https://registry.npmjs.org/imurmurhash/-/imurmurhash-0.1.4.tgz", - "integrity": "sha1-khi5srkoojixPcT7a21XbyMUU+o=", - "dev": true + "integrity": "sha1-khi5srkoojixPcT7a21XbyMUU+o=" }, "indexes-of": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/indexes-of/-/indexes-of-1.0.1.tgz", - "integrity": "sha1-8w9xbI4r00bHtn0985FVZqfAVgc=", - "dev": true + "integrity": "sha1-8w9xbI4r00bHtn0985FVZqfAVgc=" + }, + "infer-owner": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/infer-owner/-/infer-owner-1.0.4.tgz", + "integrity": "sha512-IClj+Xz94+d7irH5qRyfJonOdfTzuDaifE6ZPWfx0N0+/ATZCbuTPq2prFl526urkQd90WyUKIh1DfBQ2hMz9A==" }, "inflight": { "version": "1.0.6", "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", "integrity": "sha1-Sb1jMdfQLQwJvJEKEHW6gWW1bfk=", - "dev": true, "requires": { "once": "^1.3.0", "wrappy": "1" @@ -5173,14 +4844,12 @@ "inherits": { "version": "2.0.4", "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", - "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==", - "dev": true + "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==" }, "internal-ip": { "version": "4.3.0", "resolved": "https://registry.npmjs.org/internal-ip/-/internal-ip-4.3.0.tgz", "integrity": "sha512-S1zBo1D6zcsyuC6PMmY5+55YMILQ9av8lotMx447Bq6SAgo/sDK6y6uUKmuYhW7eacnIhFfsPmCNYdDzsnnDCg==", - "dev": true, "requires": { "default-gateway": "^4.2.0", "ipaddr.js": "^1.9.0" @@ -5190,7 +4859,6 @@ "version": "2.2.4", "resolved": "https://registry.npmjs.org/invariant/-/invariant-2.2.4.tgz", "integrity": "sha512-phJfQVBuaJM5raOpJjSfkiD6BpbCE4Ns//LaXl6wGYtUBY83nWS6Rf9tXm2e8VaK60JEjYldbPif/A2B1C2gNA==", - "dev": true, "requires": { "loose-envify": "^1.0.0" } @@ -5198,64 +4866,50 @@ "invert-kv": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/invert-kv/-/invert-kv-2.0.0.tgz", - "integrity": "sha512-wPVv/y/QQ/Uiirj/vh3oP+1Ww+AWehmi1g5fFWGPF6IpCBCDVrhgHRMvrLfdYcwDh3QJbGXDW4JAuzxElLSqKA==", - "dev": true + "integrity": "sha512-wPVv/y/QQ/Uiirj/vh3oP+1Ww+AWehmi1g5fFWGPF6IpCBCDVrhgHRMvrLfdYcwDh3QJbGXDW4JAuzxElLSqKA==" }, "ip": { "version": "1.1.5", "resolved": "https://registry.npmjs.org/ip/-/ip-1.1.5.tgz", - "integrity": "sha1-vd7XARQpCCjAoDnnLvJfWq7ENUo=", - "dev": true + "integrity": "sha1-vd7XARQpCCjAoDnnLvJfWq7ENUo=" }, "ip-regex": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/ip-regex/-/ip-regex-2.1.0.tgz", - "integrity": "sha1-+ni/XS5pE8kRzp+BnuUUa7bYROk=", - "dev": true + "integrity": "sha1-+ni/XS5pE8kRzp+BnuUUa7bYROk=" }, "ipaddr.js": { "version": "1.9.0", "resolved": "https://registry.npmjs.org/ipaddr.js/-/ipaddr.js-1.9.0.tgz", - "integrity": "sha512-M4Sjn6N/+O6/IXSJseKqHoFc+5FdGJ22sXqnjTpdZweHK64MzEPAyQZyEU3R/KRv2GLoa7nNtg/C2Ev6m7z+eA==", - "dev": true + "integrity": "sha512-M4Sjn6N/+O6/IXSJseKqHoFc+5FdGJ22sXqnjTpdZweHK64MzEPAyQZyEU3R/KRv2GLoa7nNtg/C2Ev6m7z+eA==" }, "is-absolute-url": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/is-absolute-url/-/is-absolute-url-2.1.0.tgz", - "integrity": "sha1-UFMN+4T8yap9vnhS6Do3uTufKqY=", - "dev": true + "integrity": "sha1-UFMN+4T8yap9vnhS6Do3uTufKqY=" }, "is-accessor-descriptor": { "version": "0.1.6", "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-0.1.6.tgz", "integrity": "sha1-qeEss66Nh2cn7u84Q/igiXtcmNY=", - "dev": true, "requires": { "kind-of": "^3.0.2" - }, - "dependencies": { - "kind-of": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", - "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", - "dev": true, - "requires": { - "is-buffer": "^1.1.5" - } - } } }, + "is-arguments": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/is-arguments/-/is-arguments-1.0.4.tgz", + "integrity": "sha512-xPh0Rmt8NE65sNzvyUmWgI1tz3mKq74lGA0mL8LYZcoIzKOzDh6HmrYm3d18k60nHerC8A9Km8kYu87zfSFnLA==" + }, "is-arrayish": { "version": "0.2.1", "resolved": "https://registry.npmjs.org/is-arrayish/-/is-arrayish-0.2.1.tgz", - "integrity": "sha1-d8mYQFJ6qOyxqLppe4BkWnqSap0=", - "dev": true + "integrity": "sha1-d8mYQFJ6qOyxqLppe4BkWnqSap0=" }, "is-binary-path": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/is-binary-path/-/is-binary-path-1.0.1.tgz", "integrity": "sha1-dfFmQrSA8YenEcgUFh/TpKdlWJg=", - "dev": true, "requires": { "binary-extensions": "^1.0.0" } @@ -5263,20 +4917,17 @@ "is-buffer": { "version": "1.1.6", "resolved": "https://registry.npmjs.org/is-buffer/-/is-buffer-1.1.6.tgz", - "integrity": "sha512-NcdALwpXkTm5Zvvbk7owOUSvVvBKDgKP5/ewfXEznmQFfs4ZRmanOeKBTjRVjka3QFoN6XJ+9F3USqfHqTaU5w==", - "dev": true + "integrity": "sha512-NcdALwpXkTm5Zvvbk7owOUSvVvBKDgKP5/ewfXEznmQFfs4ZRmanOeKBTjRVjka3QFoN6XJ+9F3USqfHqTaU5w==" }, "is-callable": { "version": "1.1.4", "resolved": "https://registry.npmjs.org/is-callable/-/is-callable-1.1.4.tgz", - "integrity": "sha512-r5p9sxJjYnArLjObpjA4xu5EKI3CuKHkJXMhT7kwbpUyIFD1n5PMAsoPvWnvtZiNz7LjkYDRZhd7FlI0eMijEA==", - "dev": true + "integrity": "sha512-r5p9sxJjYnArLjObpjA4xu5EKI3CuKHkJXMhT7kwbpUyIFD1n5PMAsoPvWnvtZiNz7LjkYDRZhd7FlI0eMijEA==" }, "is-color-stop": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/is-color-stop/-/is-color-stop-1.1.0.tgz", "integrity": "sha1-z/9HGu5N1cnhWFmPvhKWe1za00U=", - "dev": true, "requires": { "css-color-names": "^0.0.4", "hex-color-regex": "^1.1.0", @@ -5290,33 +4941,19 @@ "version": "0.1.4", "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-0.1.4.tgz", "integrity": "sha1-C17mSDiOLIYCgueT8YVv7D8wG1Y=", - "dev": true, "requires": { "kind-of": "^3.0.2" - }, - "dependencies": { - "kind-of": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", - "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", - "dev": true, - "requires": { - "is-buffer": "^1.1.5" - } - } } }, "is-date-object": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/is-date-object/-/is-date-object-1.0.1.tgz", - "integrity": "sha1-mqIOtq7rv/d/vTPnTKAbM1gdOhY=", - "dev": true + "integrity": "sha1-mqIOtq7rv/d/vTPnTKAbM1gdOhY=" }, "is-descriptor": { "version": "0.1.6", "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-0.1.6.tgz", "integrity": "sha512-avDYr0SB3DwO9zsMov0gKCESFYqCnE4hq/4z3TdUlukEy5t9C0YRq7HLrsN52NAcqXKaepeCD0n+B0arnVG3Hg==", - "dev": true, "requires": { "is-accessor-descriptor": "^0.1.6", "is-data-descriptor": "^0.1.4", @@ -5326,40 +4963,50 @@ "kind-of": { "version": "5.1.0", "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-5.1.0.tgz", - "integrity": "sha512-NGEErnH6F2vUuXDh+OlbcKW7/wOcfdRHaZ7VWtqCztfHri/++YKmP51OdWeGPuqCOba6kk2OTe5d02VmTB80Pw==", - "dev": true + "integrity": "sha512-NGEErnH6F2vUuXDh+OlbcKW7/wOcfdRHaZ7VWtqCztfHri/++YKmP51OdWeGPuqCOba6kk2OTe5d02VmTB80Pw==" } } }, "is-directory": { "version": "0.3.1", "resolved": "https://registry.npmjs.org/is-directory/-/is-directory-0.3.1.tgz", - "integrity": "sha1-YTObbyR1/Hcv2cnYP1yFddwVSuE=", - "dev": true + "integrity": "sha1-YTObbyR1/Hcv2cnYP1yFddwVSuE=" + }, + "is-expression": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/is-expression/-/is-expression-3.0.0.tgz", + "integrity": "sha1-Oayqa+f9HzRx3ELHQW5hwkMXrJ8=", + "requires": { + "acorn": "~4.0.2", + "object-assign": "^4.0.1" + }, + "dependencies": { + "acorn": { + "version": "4.0.13", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-4.0.13.tgz", + "integrity": "sha1-EFSVrlNh1pe9GVyCUZLhrX8lN4c=" + } + } }, "is-extendable": { "version": "0.1.1", "resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-0.1.1.tgz", - "integrity": "sha1-YrEQ4omkcUGOPsNqYX1HLjAd/Ik=", - "dev": true + "integrity": "sha1-YrEQ4omkcUGOPsNqYX1HLjAd/Ik=" }, "is-extglob": { "version": "2.1.1", "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz", - "integrity": "sha1-qIwCU1eR8C7TfHahueqXc8gz+MI=", - "dev": true + "integrity": "sha1-qIwCU1eR8C7TfHahueqXc8gz+MI=" }, "is-fullwidth-code-point": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz", - "integrity": "sha1-o7MKXE8ZkYMWeqq5O+764937ZU8=", - "dev": true + "integrity": "sha1-o7MKXE8ZkYMWeqq5O+764937ZU8=" }, "is-glob": { "version": "4.0.1", "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.1.tgz", "integrity": "sha512-5G0tKtBTFImOqDnLB2hG6Bp2qcKEFduo4tZu9MT/H6NQv/ghhy30o55ufafxJ/LdH79LLs2Kfrn85TLKyA7BUg==", - "dev": true, "requires": { "is-extglob": "^2.1.1" } @@ -5368,39 +5015,24 @@ "version": "3.0.0", "resolved": "https://registry.npmjs.org/is-number/-/is-number-3.0.0.tgz", "integrity": "sha1-JP1iAaR4LPUFYcgQJ2r8fRLXEZU=", - "dev": true, "requires": { "kind-of": "^3.0.2" - }, - "dependencies": { - "kind-of": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", - "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", - "dev": true, - "requires": { - "is-buffer": "^1.1.5" - } - } } }, "is-obj": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/is-obj/-/is-obj-1.0.1.tgz", - "integrity": "sha1-PkcprB9f3gJc19g6iW2rn09n2w8=", - "dev": true + "integrity": "sha1-PkcprB9f3gJc19g6iW2rn09n2w8=" }, "is-path-cwd": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/is-path-cwd/-/is-path-cwd-2.1.0.tgz", - "integrity": "sha512-Sc5j3/YnM8tDeyCsVeKlm/0p95075DyLmDEIkSgQ7mXkrOX+uTCtmQFm0CYzVyJwcCCmO3k8qfJt17SxQwB5Zw==", - "dev": true + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/is-path-cwd/-/is-path-cwd-2.2.0.tgz", + "integrity": "sha512-w942bTcih8fdJPJmQHFzkS76NEP8Kzzvmw92cXsazb8intwLqPibPPdXf4ANdKV3rYMuuQYGIWtvz9JilB3NFQ==" }, "is-path-in-cwd": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/is-path-in-cwd/-/is-path-in-cwd-2.1.0.tgz", "integrity": "sha512-rNocXHgipO+rvnP6dk3zI20RpOtrAM/kzbB258Uw5BWr3TpXi861yzjo16Dn4hUox07iw5AyeMLHWsujkjzvRQ==", - "dev": true, "requires": { "is-path-inside": "^2.1.0" } @@ -5409,7 +5041,6 @@ "version": "2.1.0", "resolved": "https://registry.npmjs.org/is-path-inside/-/is-path-inside-2.1.0.tgz", "integrity": "sha512-wiyhTzfDWsvwAW53OBWF5zuvaOGlZ6PwYxAbPVDhpm+gM09xKQGjBq/8uYN12aDvMxnAnq3dxTyoSoRNmg5YFg==", - "dev": true, "requires": { "path-is-inside": "^1.0.2" } @@ -5417,23 +5048,25 @@ "is-plain-obj": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/is-plain-obj/-/is-plain-obj-1.1.0.tgz", - "integrity": "sha1-caUMhCnfync8kqOQpKA7OfzVHT4=", - "dev": true + "integrity": "sha1-caUMhCnfync8kqOQpKA7OfzVHT4=" }, "is-plain-object": { "version": "2.0.4", "resolved": "https://registry.npmjs.org/is-plain-object/-/is-plain-object-2.0.4.tgz", "integrity": "sha512-h5PpgXkWitc38BBMYawTYMWJHFZJVnBquFE57xFpjB8pJFiF6gZ+bU+WyI/yqXiFR5mdLsgYNaPe8uao6Uv9Og==", - "dev": true, "requires": { "isobject": "^3.0.1" } }, + "is-promise": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/is-promise/-/is-promise-2.1.0.tgz", + "integrity": "sha1-eaKp7OfwlugPNtKy87wWwf9L8/o=" + }, "is-regex": { "version": "1.0.4", "resolved": "https://registry.npmjs.org/is-regex/-/is-regex-1.0.4.tgz", "integrity": "sha1-VRdIm1RwkbCTDglWVM7SXul+lJE=", - "dev": true, "requires": { "has": "^1.0.1" } @@ -5441,20 +5074,17 @@ "is-resolvable": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/is-resolvable/-/is-resolvable-1.1.0.tgz", - "integrity": "sha512-qgDYXFSR5WvEfuS5dMj6oTMEbrrSaM0CrFk2Yiq/gXnBvD9pMa2jGXxyhGLfvhZpuMZe18CJpFxAt3CRs42NMg==", - "dev": true + "integrity": "sha512-qgDYXFSR5WvEfuS5dMj6oTMEbrrSaM0CrFk2Yiq/gXnBvD9pMa2jGXxyhGLfvhZpuMZe18CJpFxAt3CRs42NMg==" }, "is-stream": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-1.1.0.tgz", - "integrity": "sha1-EtSj3U5o4Lec6428hBc66A2RykQ=", - "dev": true + "integrity": "sha1-EtSj3U5o4Lec6428hBc66A2RykQ=" }, "is-svg": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/is-svg/-/is-svg-3.0.0.tgz", "integrity": "sha512-gi4iHK53LR2ujhLVVj+37Ykh9GLqYHX6JOVXbLAucaG/Cqw9xwdFOjDM2qeifLs1sF1npXXFvDu0r5HNgCMrzQ==", - "dev": true, "requires": { "html-comment-regex": "^1.1.0" } @@ -5463,7 +5093,6 @@ "version": "1.0.2", "resolved": "https://registry.npmjs.org/is-symbol/-/is-symbol-1.0.2.tgz", "integrity": "sha512-HS8bZ9ox60yCJLH9snBpIwv9pYUAkcuLhSA1oero1UB5y9aiQpRA8y2ex945AOtCZL1lJDeIk3G5LthswI46Lw==", - "dev": true, "requires": { "has-symbols": "^1.0.0" } @@ -5471,68 +5100,62 @@ "is-typedarray": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/is-typedarray/-/is-typedarray-1.0.0.tgz", - "integrity": "sha1-5HnICFjfDBsR3dppQPlgEfzaSpo=", - "dev": true + "integrity": "sha1-5HnICFjfDBsR3dppQPlgEfzaSpo=" }, "is-windows": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/is-windows/-/is-windows-1.0.2.tgz", - "integrity": "sha512-eXK1UInq2bPmjyX6e3VHIzMLobc4J94i4AWn+Hpq3OU5KkrRC96OAcR3PRJ/pGu6m8TRnBHP9dkXQVsT/COVIA==", - "dev": true + "integrity": "sha512-eXK1UInq2bPmjyX6e3VHIzMLobc4J94i4AWn+Hpq3OU5KkrRC96OAcR3PRJ/pGu6m8TRnBHP9dkXQVsT/COVIA==" }, "is-wsl": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/is-wsl/-/is-wsl-1.1.0.tgz", - "integrity": "sha1-HxbkqiKwTRM2tmGIpmrzxgDDpm0=", - "dev": true + "integrity": "sha1-HxbkqiKwTRM2tmGIpmrzxgDDpm0=" }, "isarray": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", - "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=", - "dev": true + "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=" }, "isexe": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", - "integrity": "sha1-6PvzdNxVb/iUehDcsFctYz8s+hA=", - "dev": true + "integrity": "sha1-6PvzdNxVb/iUehDcsFctYz8s+hA=" }, "isobject": { "version": "3.0.1", "resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz", - "integrity": "sha1-TkMekrEalzFjaqH5yNHMvP2reN8=", - "dev": true + "integrity": "sha1-TkMekrEalzFjaqH5yNHMvP2reN8=" }, "isstream": { "version": "0.1.2", "resolved": "https://registry.npmjs.org/isstream/-/isstream-0.1.2.tgz", - "integrity": "sha1-R+Y/evVa+m+S4VAOaQ64uFKcCZo=", - "dev": true + "integrity": "sha1-R+Y/evVa+m+S4VAOaQ64uFKcCZo=" }, "javascript-stringify": { "version": "1.6.0", "resolved": "https://registry.npmjs.org/javascript-stringify/-/javascript-stringify-1.6.0.tgz", - "integrity": "sha1-FC0RHzpuPa6PSpr9d9RYVbWpzOM=", - "dev": true + "integrity": "sha1-FC0RHzpuPa6PSpr9d9RYVbWpzOM=" }, "js-levenshtein": { "version": "1.1.6", "resolved": "https://registry.npmjs.org/js-levenshtein/-/js-levenshtein-1.1.6.tgz", - "integrity": "sha512-X2BB11YZtrRqY4EnQcLX5Rh373zbK4alC1FW7D7MBhL2gtcC17cTnr6DmfHZeS0s2rTHjUTMMHfG7gO8SSdw+g==", - "dev": true + "integrity": "sha512-X2BB11YZtrRqY4EnQcLX5Rh373zbK4alC1FW7D7MBhL2gtcC17cTnr6DmfHZeS0s2rTHjUTMMHfG7gO8SSdw+g==" + }, + "js-stringify": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/js-stringify/-/js-stringify-1.0.2.tgz", + "integrity": "sha1-Fzb939lyTyijaCrcYjCufk6Weds=" }, "js-tokens": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz", - "integrity": "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==", - "dev": true + "integrity": "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==" }, "js-yaml": { "version": "3.13.1", "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.13.1.tgz", "integrity": "sha512-YfbcO7jXDdyj0DGxYVSlSeQNHbD7XPWvrVWeVUujrQEoZzWJIRrCPoyk6kL6IAjAG2IolMK4T0hNUe0HOUs5Jw==", - "dev": true, "requires": { "argparse": "^1.0.7", "esprima": "^4.0.0" @@ -5541,50 +5164,42 @@ "jsbn": { "version": "0.1.1", "resolved": "https://registry.npmjs.org/jsbn/-/jsbn-0.1.1.tgz", - "integrity": "sha1-peZUwuWi3rXyAdls77yoDA7y9RM=", - "dev": true + "integrity": "sha1-peZUwuWi3rXyAdls77yoDA7y9RM=" }, "jsesc": { "version": "2.5.2", "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-2.5.2.tgz", - "integrity": "sha512-OYu7XEzjkCQ3C5Ps3QIZsQfNpqoJyZZA99wd9aWd05NCtC5pWOkShK2mkL6HXQR6/Cy2lbNdPlZBpuQHXE63gA==", - "dev": true + "integrity": "sha512-OYu7XEzjkCQ3C5Ps3QIZsQfNpqoJyZZA99wd9aWd05NCtC5pWOkShK2mkL6HXQR6/Cy2lbNdPlZBpuQHXE63gA==" }, "json-parse-better-errors": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/json-parse-better-errors/-/json-parse-better-errors-1.0.2.tgz", - "integrity": "sha512-mrqyZKfX5EhL7hvqcV6WG1yYjnjeuYDzDhhcAAUrq8Po85NBQBJP+ZDUT75qZQ98IkUoBqdkExkukOU7Ts2wrw==", - "dev": true + "integrity": "sha512-mrqyZKfX5EhL7hvqcV6WG1yYjnjeuYDzDhhcAAUrq8Po85NBQBJP+ZDUT75qZQ98IkUoBqdkExkukOU7Ts2wrw==" }, "json-schema": { "version": "0.2.3", "resolved": "https://registry.npmjs.org/json-schema/-/json-schema-0.2.3.tgz", - "integrity": "sha1-tIDIkuWaLwWVTOcnvT8qTogvnhM=", - "dev": true + "integrity": "sha1-tIDIkuWaLwWVTOcnvT8qTogvnhM=" }, "json-schema-traverse": { "version": "0.4.1", "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz", - "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==", - "dev": true + "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==" }, "json-stringify-safe": { "version": "5.0.1", "resolved": "https://registry.npmjs.org/json-stringify-safe/-/json-stringify-safe-5.0.1.tgz", - "integrity": "sha1-Epai1Y/UXxmg9s4B1lcB4sc1tus=", - "dev": true + "integrity": "sha1-Epai1Y/UXxmg9s4B1lcB4sc1tus=" }, "json3": { "version": "3.3.3", "resolved": "https://registry.npmjs.org/json3/-/json3-3.3.3.tgz", - "integrity": "sha512-c7/8mbUsKigAbLkD5B010BK4D9LZm7A1pNItkEwiUZRpIN66exu/e7YQWysGun+TRKaJp8MhemM+VkfWv42aCA==", - "dev": true + "integrity": "sha512-c7/8mbUsKigAbLkD5B010BK4D9LZm7A1pNItkEwiUZRpIN66exu/e7YQWysGun+TRKaJp8MhemM+VkfWv42aCA==" }, "json5": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/json5/-/json5-2.1.0.tgz", - "integrity": "sha512-8Mh9h6xViijj36g7Dxi+Y4S6hNGV96vcJZr/SrlHh1LR/pEn/8j/+qIBbs44YKl69Lrfctp4QD+AdWLTMqEZAQ==", - "dev": true, + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/json5/-/json5-1.0.1.tgz", + "integrity": "sha512-aKS4WQjPenRxiQsC93MNfjx+nbF4PAdYzmd/1JIj8HYzqfbu86beTuNgXDzPknWk0n0uARlyewZo4s++ES36Ow==", "requires": { "minimist": "^1.2.0" } @@ -5593,7 +5208,6 @@ "version": "4.0.0", "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-4.0.0.tgz", "integrity": "sha1-h3Gq4HmbZAdrdmQPygWPnBDjPss=", - "dev": true, "requires": { "graceful-fs": "^4.1.6" } @@ -5602,7 +5216,6 @@ "version": "1.4.1", "resolved": "https://registry.npmjs.org/jsprim/-/jsprim-1.4.1.tgz", "integrity": "sha1-MT5mvB5cwG5Di8G3SZwuXFastqI=", - "dev": true, "requires": { "assert-plus": "1.0.0", "extsprintf": "1.3.0", @@ -5610,42 +5223,54 @@ "verror": "1.10.0" } }, + "jstransformer": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/jstransformer/-/jstransformer-1.0.0.tgz", + "integrity": "sha1-7Yvwkh4vPx7U1cGkT2hwntJHIsM=", + "requires": { + "is-promise": "^2.0.0", + "promise": "^7.0.1" + } + }, "killable": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/killable/-/killable-1.0.1.tgz", - "integrity": "sha512-LzqtLKlUwirEUyl/nicirVmNiPvYs7l5n8wOPP7fyJVpUPkvCnW/vuiXGpylGUlnPDnB7311rARzAt3Mhswpjg==", - "dev": true + "integrity": "sha512-LzqtLKlUwirEUyl/nicirVmNiPvYs7l5n8wOPP7fyJVpUPkvCnW/vuiXGpylGUlnPDnB7311rARzAt3Mhswpjg==" }, "kind-of": { - "version": "6.0.2", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.2.tgz", - "integrity": "sha512-s5kLOcnH0XqDO+FvuaLX8DDjZ18CGFk7VygH40QoKPUQhW4e2rvM0rwUq0t8IQDOwYSeLK01U90OjzBTme2QqA==", - "dev": true + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", + "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", + "requires": { + "is-buffer": "^1.1.5" + } }, "last-call-webpack-plugin": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/last-call-webpack-plugin/-/last-call-webpack-plugin-3.0.0.tgz", "integrity": "sha512-7KI2l2GIZa9p2spzPIVZBYyNKkN+e/SQPpnjlTiPhdbDW3F86tdKKELxKpzJ5sgU19wQWsACULZmpTPYHeWO5w==", - "dev": true, "requires": { "lodash": "^4.17.5", "webpack-sources": "^1.1.0" } }, + "lazy-cache": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/lazy-cache/-/lazy-cache-1.0.4.tgz", + "integrity": "sha1-odePw6UEdMuAhF07O24dpJpEbo4=" + }, "lcid": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/lcid/-/lcid-2.0.0.tgz", "integrity": "sha512-avPEb8P8EGnwXKClwsNUgryVjllcRqtMYa49NTsbQagYuT1DcXnl1915oxWjoyGrXR6zH/Y0Zc96xWsPcoDKeA==", - "dev": true, "requires": { "invert-kv": "^2.0.0" } }, "linkify-it": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/linkify-it/-/linkify-it-2.1.0.tgz", - "integrity": "sha512-4REs8/062kV2DSHxNfq5183zrqXMl7WP0WzABH9IeJI+NLm429FgE1PDecltYfnOoFDFlZGh2T8PfZn0r+GTRg==", - "dev": true, + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/linkify-it/-/linkify-it-2.2.0.tgz", + "integrity": "sha512-GnAl/knGn+i1U/wjBz3akz2stz+HrHLsxMwHQGofCDfPvlf+gDKN58UtfmUquTY4/MXeE2x7k19KQmeoZi94Iw==", "requires": { "uc.micro": "^1.0.1" } @@ -5653,119 +5278,98 @@ "load-script": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/load-script/-/load-script-1.0.0.tgz", - "integrity": "sha1-BJGTngvuVkPuSUp+PaPSuscMbKQ=", - "dev": true + "integrity": "sha1-BJGTngvuVkPuSUp+PaPSuscMbKQ=" }, "loader-runner": { "version": "2.4.0", "resolved": "https://registry.npmjs.org/loader-runner/-/loader-runner-2.4.0.tgz", - "integrity": "sha512-Jsmr89RcXGIwivFY21FcRrisYZfvLMTWx5kOLc+JTxtpBOG6xML0vzbc6SEQG2FO9/4Fc3wW4LVcB5DmGflaRw==", - "dev": true + "integrity": "sha512-Jsmr89RcXGIwivFY21FcRrisYZfvLMTWx5kOLc+JTxtpBOG6xML0vzbc6SEQG2FO9/4Fc3wW4LVcB5DmGflaRw==" }, "loader-utils": { "version": "1.2.3", "resolved": "https://registry.npmjs.org/loader-utils/-/loader-utils-1.2.3.tgz", "integrity": "sha512-fkpz8ejdnEMG3s37wGL07iSBDg99O9D5yflE9RGNH3hRdx9SOwYfnGYdZOUIZitN8E+E2vkq3MUMYMvPYl5ZZA==", - "dev": true, "requires": { "big.js": "^5.2.2", "emojis-list": "^2.0.0", "json5": "^1.0.1" - }, - "dependencies": { - "json5": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/json5/-/json5-1.0.1.tgz", - "integrity": "sha512-aKS4WQjPenRxiQsC93MNfjx+nbF4PAdYzmd/1JIj8HYzqfbu86beTuNgXDzPknWk0n0uARlyewZo4s++ES36Ow==", - "dev": true, - "requires": { - "minimist": "^1.2.0" - } - } } }, "locate-path": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-2.0.0.tgz", "integrity": "sha1-K1aLJl7slExtnA3pw9u7ygNUzY4=", - "dev": true, "requires": { "p-locate": "^2.0.0", "path-exists": "^3.0.0" } }, "lodash": { - "version": "4.17.11", - "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.11.tgz", - "integrity": "sha512-cQKh8igo5QUhZ7lg38DYWAxMvjSAKG0A8wGSVimP07SIUEK2UO+arSRKbRZWtelMtN5V0Hkwh5ryOto/SshYIg==", - "dev": true + "version": "4.17.15", + "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.15.tgz", + "integrity": "sha512-8xOcRHvCjnocdS5cpwXQXVzmmh5e5+saE2QGoeQmbKmRS6J3VQppPOIt0MnmE+4xlZoumy0GPG0D0MVIQbNA1A==" }, "lodash._reinterpolate": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/lodash._reinterpolate/-/lodash._reinterpolate-3.0.0.tgz", - "integrity": "sha1-DM8tiRZq8Ds2Y8eWU4t1rG4RTZ0=", - "dev": true + "integrity": "sha1-DM8tiRZq8Ds2Y8eWU4t1rG4RTZ0=" }, "lodash.clonedeep": { "version": "4.5.0", "resolved": "https://registry.npmjs.org/lodash.clonedeep/-/lodash.clonedeep-4.5.0.tgz", - "integrity": "sha1-4j8/nE+Pvd6HJSnBBxhXoIblzO8=", - "dev": true + "integrity": "sha1-4j8/nE+Pvd6HJSnBBxhXoIblzO8=" + }, + "lodash.debounce": { + "version": "4.0.8", + "resolved": "https://registry.npmjs.org/lodash.debounce/-/lodash.debounce-4.0.8.tgz", + "integrity": "sha1-gteb/zCmfEAF/9XiUVMArZyk168=" }, "lodash.kebabcase": { "version": "4.1.1", "resolved": "https://registry.npmjs.org/lodash.kebabcase/-/lodash.kebabcase-4.1.1.tgz", - "integrity": "sha1-hImxyw0p/4gZXM7KRI/21swpXDY=", - "dev": true + "integrity": "sha1-hImxyw0p/4gZXM7KRI/21swpXDY=" }, "lodash.memoize": { "version": "4.1.2", "resolved": "https://registry.npmjs.org/lodash.memoize/-/lodash.memoize-4.1.2.tgz", - "integrity": "sha1-vMbEmkKihA7Zl/Mj6tpezRguC/4=", - "dev": true + "integrity": "sha1-vMbEmkKihA7Zl/Mj6tpezRguC/4=" }, "lodash.template": { - "version": "4.4.0", - "resolved": "https://registry.npmjs.org/lodash.template/-/lodash.template-4.4.0.tgz", - "integrity": "sha1-5zoDhcg1VZF0bgILmWecaQ5o+6A=", - "dev": true, + "version": "4.5.0", + "resolved": "https://registry.npmjs.org/lodash.template/-/lodash.template-4.5.0.tgz", + "integrity": "sha512-84vYFxIkmidUiFxidA/KjjH9pAycqW+h980j7Fuz5qxRtO9pgB7MDFTdys1N7A5mcucRiDyEq4fusljItR1T/A==", "requires": { - "lodash._reinterpolate": "~3.0.0", + "lodash._reinterpolate": "^3.0.0", "lodash.templatesettings": "^4.0.0" } }, "lodash.templatesettings": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/lodash.templatesettings/-/lodash.templatesettings-4.1.0.tgz", - "integrity": "sha1-K01OlbpEDZFf8IvImeRVNmZxMxY=", - "dev": true, + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/lodash.templatesettings/-/lodash.templatesettings-4.2.0.tgz", + "integrity": "sha512-stgLz+i3Aa9mZgnjr/O+v9ruKZsPsndy7qPZOchbqk2cnTU1ZaldKK+v7m54WoKIyxiuMZTKT2H81F8BeAc3ZQ==", "requires": { - "lodash._reinterpolate": "~3.0.0" + "lodash._reinterpolate": "^3.0.0" } }, - "lodash.throttle": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/lodash.throttle/-/lodash.throttle-4.1.1.tgz", - "integrity": "sha1-wj6RtxAkKscMN/HhzaknTMOb8vQ=", - "dev": true - }, "lodash.uniq": { "version": "4.5.0", "resolved": "https://registry.npmjs.org/lodash.uniq/-/lodash.uniq-4.5.0.tgz", - "integrity": "sha1-0CJTc662Uq3BvILklFM5qEJ1R3M=", - "dev": true + "integrity": "sha1-0CJTc662Uq3BvILklFM5qEJ1R3M=" }, "loglevel": { - "version": "1.6.3", - "resolved": "https://registry.npmjs.org/loglevel/-/loglevel-1.6.3.tgz", - "integrity": "sha512-LoEDv5pgpvWgPF4kNYuIp0qqSJVWak/dML0RY74xlzMZiT9w77teNAwKYKWBTYjlokMirg+o3jBwp+vlLrcfAA==", - "dev": true + "version": "1.6.4", + "resolved": "https://registry.npmjs.org/loglevel/-/loglevel-1.6.4.tgz", + "integrity": "sha512-p0b6mOGKcGa+7nnmKbpzR6qloPbrgLcnio++E+14Vo/XffOGwZtRpUhr8dTH/x2oCMmEoIU0Zwm3ZauhvYD17g==" + }, + "longest": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/longest/-/longest-1.0.1.tgz", + "integrity": "sha1-MKCy2jj3N3DoKUoNIuZiXtd9AJc=" }, "loose-envify": { "version": "1.4.0", "resolved": "https://registry.npmjs.org/loose-envify/-/loose-envify-1.4.0.tgz", "integrity": "sha512-lyuxPGr/Wfhrlem2CL/UcnUc1zcqKAImBDzukY7Y5F/yQiNdko6+fRLevlw1HgMySw7f611UIY408EtxRSoK3Q==", - "dev": true, "requires": { "js-tokens": "^3.0.0 || ^4.0.0" } @@ -5773,14 +5377,12 @@ "lower-case": { "version": "1.1.4", "resolved": "https://registry.npmjs.org/lower-case/-/lower-case-1.1.4.tgz", - "integrity": "sha1-miyr0bno4K6ZOkv31YdcOcQujqw=", - "dev": true + "integrity": "sha1-miyr0bno4K6ZOkv31YdcOcQujqw=" }, "lru-cache": { "version": "5.1.1", "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-5.1.1.tgz", "integrity": "sha512-KpNARQA3Iwv+jTA0utUVVbrh+Jlrr1Fv0e56GGzAFOXN7dk/FviaDW8LHmK52DlcH4WP2n6gI8vN1aesBFgo9w==", - "dev": true, "requires": { "yallist": "^3.0.2" } @@ -5789,7 +5391,6 @@ "version": "2.1.0", "resolved": "https://registry.npmjs.org/make-dir/-/make-dir-2.1.0.tgz", "integrity": "sha512-LS9X+dc8KLxXCb8dni79fLIIUA5VyZoyjSMCwTluaXA0o27cCK0bhXkpgw+sTXVpPy/lSO57ilRixqk0vDmtRA==", - "dev": true, "requires": { "pify": "^4.0.1", "semver": "^5.6.0" @@ -5798,14 +5399,12 @@ "mamacro": { "version": "0.0.3", "resolved": "https://registry.npmjs.org/mamacro/-/mamacro-0.0.3.tgz", - "integrity": "sha512-qMEwh+UujcQ+kbz3T6V+wAmO2U8veoq2w+3wY8MquqwVA3jChfwY+Tk52GZKDfACEPjuZ7r2oJLejwpt8jtwTA==", - "dev": true + "integrity": "sha512-qMEwh+UujcQ+kbz3T6V+wAmO2U8veoq2w+3wY8MquqwVA3jChfwY+Tk52GZKDfACEPjuZ7r2oJLejwpt8jtwTA==" }, "map-age-cleaner": { "version": "0.1.3", "resolved": "https://registry.npmjs.org/map-age-cleaner/-/map-age-cleaner-0.1.3.tgz", "integrity": "sha512-bJzx6nMoP6PDLPBFmg7+xRKeFZvFboMrGlxmNj9ClvX53KrmvM5bXFXEWjbz4cz1AFn+jWJ9z/DJSz7hrs0w3w==", - "dev": true, "requires": { "p-defer": "^1.0.0" } @@ -5813,23 +5412,20 @@ "map-cache": { "version": "0.2.2", "resolved": "https://registry.npmjs.org/map-cache/-/map-cache-0.2.2.tgz", - "integrity": "sha1-wyq9C9ZSXZsFFkW7TyasXcmKDb8=", - "dev": true + "integrity": "sha1-wyq9C9ZSXZsFFkW7TyasXcmKDb8=" }, "map-visit": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/map-visit/-/map-visit-1.0.0.tgz", "integrity": "sha1-7Nyo8TFE5mDxtb1B8S80edmN+48=", - "dev": true, "requires": { "object-visit": "^1.0.0" } }, "markdown-it": { - "version": "8.4.2", - "resolved": "https://registry.npmjs.org/markdown-it/-/markdown-it-8.4.2.tgz", - "integrity": "sha512-GcRz3AWTqSUphY3vsUqQSFMbgR38a4Lh3GWlHRh/7MRwz8mcu9n2IO7HOh+bXHrR9kOPDl5RNCaEsrneb+xhHQ==", - "dev": true, + "version": "9.1.0", + "resolved": "https://registry.npmjs.org/markdown-it/-/markdown-it-9.1.0.tgz", + "integrity": "sha512-xHKG4C8iPriyfu/jc2hsCC045fKrMQ0VexX2F1FGYiRxDxqMB2aAhF8WauJ3fltn2kb90moGBkiiEdooGIg55w==", "requires": { "argparse": "^1.0.7", "entities": "~1.1.1", @@ -5839,16 +5435,14 @@ } }, "markdown-it-anchor": { - "version": "5.2.4", - "resolved": "https://registry.npmjs.org/markdown-it-anchor/-/markdown-it-anchor-5.2.4.tgz", - "integrity": "sha512-n8zCGjxA3T+Mx1pG8HEgbJbkB8JFUuRkeTZQuIM8iPY6oQ8sWOPRZJDFC9a/pNg2QkHEjjGkhBEl/RSyzaDZ3A==", - "dev": true + "version": "5.2.5", + "resolved": "https://registry.npmjs.org/markdown-it-anchor/-/markdown-it-anchor-5.2.5.tgz", + "integrity": "sha512-xLIjLQmtym3QpoY9llBgApknl7pxAcN3WDRc2d3rwpl+/YvDZHPmKscGs+L6E05xf2KrCXPBvosWt7MZukwSpQ==" }, "markdown-it-chain": { "version": "1.3.0", "resolved": "https://registry.npmjs.org/markdown-it-chain/-/markdown-it-chain-1.3.0.tgz", "integrity": "sha512-XClV8I1TKy8L2qsT9iX3qiV+50ZtcInGXI80CA+DP62sMs7hXlyV/RM3hfwy5O3Ad0sJm9xIwQELgANfESo8mQ==", - "dev": true, "requires": { "webpack-chain": "^4.9.0" } @@ -5856,35 +5450,22 @@ "markdown-it-container": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/markdown-it-container/-/markdown-it-container-2.0.0.tgz", - "integrity": "sha1-ABm0P9Au7+zi8ZYKKJX7qBpARpU=", - "dev": true + "integrity": "sha1-ABm0P9Au7+zi8ZYKKJX7qBpARpU=" }, "markdown-it-emoji": { "version": "1.4.0", "resolved": "https://registry.npmjs.org/markdown-it-emoji/-/markdown-it-emoji-1.4.0.tgz", - "integrity": "sha1-m+4OmpkKljupbfaYDE/dsF37Tcw=", - "dev": true - }, - "markdown-it-meta": { - "version": "0.0.1", - "resolved": "https://registry.npmjs.org/markdown-it-meta/-/markdown-it-meta-0.0.1.tgz", - "integrity": "sha1-11to8RVlnK9WjkrUPLRgpHEkjDk=", - "dev": true, - "requires": { - "js-yaml": "^3.8.1" - } + "integrity": "sha1-m+4OmpkKljupbfaYDE/dsF37Tcw=" }, "markdown-it-table-of-contents": { "version": "0.4.4", "resolved": "https://registry.npmjs.org/markdown-it-table-of-contents/-/markdown-it-table-of-contents-0.4.4.tgz", - "integrity": "sha512-TAIHTHPwa9+ltKvKPWulm/beozQU41Ab+FIefRaQV1NRnpzwcV9QOe6wXQS5WLivm5Q/nlo0rl6laGkMDZE7Gw==", - "dev": true + "integrity": "sha512-TAIHTHPwa9+ltKvKPWulm/beozQU41Ab+FIefRaQV1NRnpzwcV9QOe6wXQS5WLivm5Q/nlo0rl6laGkMDZE7Gw==" }, "md5.js": { "version": "1.3.5", "resolved": "https://registry.npmjs.org/md5.js/-/md5.js-1.3.5.tgz", "integrity": "sha512-xitP+WxNPcTTOgnTJcrhM0xvdPepipPSf3I8EIpGKeFLjt3PlJLIDG3u8EX53ZIubkb+5U2+3rELYpEhHhzdkg==", - "dev": true, "requires": { "hash-base": "^3.0.0", "inherits": "^2.0.1", @@ -5892,28 +5473,24 @@ } }, "mdn-data": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/mdn-data/-/mdn-data-1.1.4.tgz", - "integrity": "sha512-FSYbp3lyKjyj3E7fMl6rYvUdX0FBXaluGqlFoYESWQlyUTq8R+wp0rkFxoYFqZlHCvsUXGjyJmLQSnXToYhOSA==", - "dev": true + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/mdn-data/-/mdn-data-2.0.4.tgz", + "integrity": "sha512-iV3XNKw06j5Q7mi6h+9vbx23Tv7JkjEVgKHW4pimwyDGWm0OIQntJJ+u1C6mg6mK1EaTv42XQ7w76yuzH7M2cA==" }, "mdurl": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/mdurl/-/mdurl-1.0.1.tgz", - "integrity": "sha1-/oWy7HWlkDfyrf7BAP1sYBdhFS4=", - "dev": true + "integrity": "sha1-/oWy7HWlkDfyrf7BAP1sYBdhFS4=" }, "media-typer": { "version": "0.3.0", "resolved": "https://registry.npmjs.org/media-typer/-/media-typer-0.3.0.tgz", - "integrity": "sha1-hxDXrwqmJvj/+hzgAWhUUmMlV0g=", - "dev": true + "integrity": "sha1-hxDXrwqmJvj/+hzgAWhUUmMlV0g=" }, "mem": { "version": "4.3.0", "resolved": "https://registry.npmjs.org/mem/-/mem-4.3.0.tgz", "integrity": "sha512-qX2bG48pTqYRVmDB37rn/6PT7LcR8T7oAX3bf99u1Tt1nzxYfxkgqDwUwolPlXweM0XzBOBFzSx4kfp7KP1s/w==", - "dev": true, "requires": { "map-age-cleaner": "^0.1.1", "mimic-fn": "^2.0.0", @@ -5924,7 +5501,6 @@ "version": "0.4.1", "resolved": "https://registry.npmjs.org/memory-fs/-/memory-fs-0.4.1.tgz", "integrity": "sha1-OpoguEYlI+RHz7x+i7gO1me/xVI=", - "dev": true, "requires": { "errno": "^0.1.3", "readable-stream": "^2.0.1" @@ -5933,43 +5509,30 @@ "merge-descriptors": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/merge-descriptors/-/merge-descriptors-1.0.1.tgz", - "integrity": "sha1-sAqqVW3YtEVoFQ7J0blT8/kMu2E=", - "dev": true + "integrity": "sha1-sAqqVW3YtEVoFQ7J0blT8/kMu2E=" }, "merge-source-map": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/merge-source-map/-/merge-source-map-1.1.0.tgz", "integrity": "sha512-Qkcp7P2ygktpMPh2mCQZaf3jhN6D3Z/qVZHSdWvQ+2Ef5HgRAPBO57A77+ENm0CPx2+1Ce/MYKi3ymqdfuqibw==", - "dev": true, "requires": { "source-map": "^0.6.1" - }, - "dependencies": { - "source-map": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", - "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", - "dev": true - } } }, "merge2": { - "version": "1.2.3", - "resolved": "https://registry.npmjs.org/merge2/-/merge2-1.2.3.tgz", - "integrity": "sha512-gdUU1Fwj5ep4kplwcmftruWofEFt6lfpkkr3h860CXbAB9c3hGb55EOL2ali0Td5oebvW0E1+3Sr+Ur7XfKpRA==", - "dev": true + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/merge2/-/merge2-1.3.0.tgz", + "integrity": "sha512-2j4DAdlBOkiSZIsaXk4mTE3sRS02yBHAtfy127xRV3bQUFqXkjHCHLW6Scv7DwNRbIWNHH8zpnz9zMaKXIdvYw==" }, "methods": { "version": "1.1.2", "resolved": "https://registry.npmjs.org/methods/-/methods-1.1.2.tgz", - "integrity": "sha1-VSmk1nZUE07cxSZmVoNbD4Ua/O4=", - "dev": true + "integrity": "sha1-VSmk1nZUE07cxSZmVoNbD4Ua/O4=" }, "micromatch": { "version": "3.1.10", "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-3.1.10.tgz", "integrity": "sha512-MWikgl9n9M3w+bpsY3He8L+w9eF9338xRl8IAO5viDizwSzziFEyUzo2xrrloB64ADbTf8uA8vRqqttDTOmccg==", - "dev": true, "requires": { "arr-diff": "^4.0.0", "array-unique": "^0.3.2", @@ -5984,13 +5547,19 @@ "regex-not": "^1.0.0", "snapdragon": "^0.8.1", "to-regex": "^3.0.2" + }, + "dependencies": { + "kind-of": { + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.2.tgz", + "integrity": "sha512-s5kLOcnH0XqDO+FvuaLX8DDjZ18CGFk7VygH40QoKPUQhW4e2rvM0rwUq0t8IQDOwYSeLK01U90OjzBTme2QqA==" + } } }, "miller-rabin": { "version": "4.0.1", "resolved": "https://registry.npmjs.org/miller-rabin/-/miller-rabin-4.0.1.tgz", "integrity": "sha512-115fLhvZVqWwHPbClyntxEVfVDfl9DLLTuJvq3g2O/Oxi8AiNouAHvDSzHS0viUJc+V5vm3eq91Xwqn9dp4jRA==", - "dev": true, "requires": { "bn.js": "^4.0.0", "brorand": "^1.0.1" @@ -5999,20 +5568,17 @@ "mime": { "version": "2.4.4", "resolved": "https://registry.npmjs.org/mime/-/mime-2.4.4.tgz", - "integrity": "sha512-LRxmNwziLPT828z+4YkNzloCFC2YM4wrB99k+AV5ZbEyfGNWfG8SO1FUXLmLDBSo89NrJZ4DIWeLjy1CHGhMGA==", - "dev": true + "integrity": "sha512-LRxmNwziLPT828z+4YkNzloCFC2YM4wrB99k+AV5ZbEyfGNWfG8SO1FUXLmLDBSo89NrJZ4DIWeLjy1CHGhMGA==" }, "mime-db": { "version": "1.40.0", "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.40.0.tgz", - "integrity": "sha512-jYdeOMPy9vnxEqFRRo6ZvTZ8d9oPb+k18PKoYNYUe2stVEBPPwsln/qWzdbmaIvnhZ9v2P+CuecK+fpUfsV2mA==", - "dev": true + "integrity": "sha512-jYdeOMPy9vnxEqFRRo6ZvTZ8d9oPb+k18PKoYNYUe2stVEBPPwsln/qWzdbmaIvnhZ9v2P+CuecK+fpUfsV2mA==" }, "mime-types": { "version": "2.1.24", "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.24.tgz", "integrity": "sha512-WaFHS3MCl5fapm3oLxU4eYDw77IQM2ACcxQ9RIxfaC3ooc6PFuBMGZZsYpvoXS5D5QTWPieo1jjLdAm3TBP3cQ==", - "dev": true, "requires": { "mime-db": "1.40.0" } @@ -6020,14 +5586,12 @@ "mimic-fn": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/mimic-fn/-/mimic-fn-2.1.0.tgz", - "integrity": "sha512-OqbOk5oEQeAZ8WXWydlu9HJjz9WVdEIvamMCcXmuqUYjTknH/sqsWvhQ3vgwKFRR1HpjvNBKQ37nbJgYzGqGcg==", - "dev": true + "integrity": "sha512-OqbOk5oEQeAZ8WXWydlu9HJjz9WVdEIvamMCcXmuqUYjTknH/sqsWvhQ3vgwKFRR1HpjvNBKQ37nbJgYzGqGcg==" }, "min-document": { "version": "2.19.0", "resolved": "https://registry.npmjs.org/min-document/-/min-document-2.19.0.tgz", "integrity": "sha1-e9KC4/WELtKVu3SM3Z8f+iyCRoU=", - "dev": true, "requires": { "dom-walk": "^0.1.0" } @@ -6036,7 +5600,6 @@ "version": "0.6.0", "resolved": "https://registry.npmjs.org/mini-css-extract-plugin/-/mini-css-extract-plugin-0.6.0.tgz", "integrity": "sha512-79q5P7YGI6rdnVyIAV4NXpBQJFWdkzJxCim3Kog4078fM0piAaFlwocqbejdWtLW1cEzCexPrh6EdyFsPgVdAw==", - "dev": true, "requires": { "loader-utils": "^1.1.0", "normalize-url": "^2.0.1", @@ -6047,20 +5610,17 @@ "minimalistic-assert": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/minimalistic-assert/-/minimalistic-assert-1.0.1.tgz", - "integrity": "sha512-UtJcAD4yEaGtjPezWuO9wC4nwUnVH/8/Im3yEHQP4b67cXlD/Qr9hdITCU1xDbSEXg2XKNaP8jsReV7vQd00/A==", - "dev": true + "integrity": "sha512-UtJcAD4yEaGtjPezWuO9wC4nwUnVH/8/Im3yEHQP4b67cXlD/Qr9hdITCU1xDbSEXg2XKNaP8jsReV7vQd00/A==" }, "minimalistic-crypto-utils": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/minimalistic-crypto-utils/-/minimalistic-crypto-utils-1.0.1.tgz", - "integrity": "sha1-9sAMHAsIIkblxNmd+4x8CDsrWCo=", - "dev": true + "integrity": "sha1-9sAMHAsIIkblxNmd+4x8CDsrWCo=" }, "minimatch": { "version": "3.0.4", "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.4.tgz", "integrity": "sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA==", - "dev": true, "requires": { "brace-expansion": "^1.1.7" } @@ -6068,14 +5628,12 @@ "minimist": { "version": "1.2.0", "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.0.tgz", - "integrity": "sha1-o1AIsg9BOD7sH7kU9M1d95omQoQ=", - "dev": true + "integrity": "sha1-o1AIsg9BOD7sH7kU9M1d95omQoQ=" }, "mississippi": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/mississippi/-/mississippi-3.0.0.tgz", "integrity": "sha512-x471SsVjUtBRtcvd4BzKE9kFC+/2TeWgKCgw0bZcw1b9l2X3QX5vCWgF+KaZaYm87Ss//rHnWryupDrgLvmSkA==", - "dev": true, "requires": { "concat-stream": "^1.5.0", "duplexify": "^3.4.2", @@ -6093,7 +5651,6 @@ "version": "1.3.2", "resolved": "https://registry.npmjs.org/mixin-deep/-/mixin-deep-1.3.2.tgz", "integrity": "sha512-WRoDn//mXBiJ1H40rqa3vH0toePwSsGb45iInWlTySa+Uu4k3tYUSxa2v1KqAiLtvlrSzaExqS1gtk96A9zvEA==", - "dev": true, "requires": { "for-in": "^1.0.2", "is-extendable": "^1.0.1" @@ -6103,7 +5660,6 @@ "version": "1.0.1", "resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-1.0.1.tgz", "integrity": "sha512-arnXMxT1hhoKo9k1LZdmlNyJdDDfy2v0fXjFlmok4+i8ul/6WlbVge9bhM74OpNPQPMGUToDtz+KXa1PneJxOA==", - "dev": true, "requires": { "is-plain-object": "^2.0.4" } @@ -6114,7 +5670,6 @@ "version": "0.5.1", "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.1.tgz", "integrity": "sha1-MAV0OOrGz3+MR2fzhkjWaX11yQM=", - "dev": true, "requires": { "minimist": "0.0.8" }, @@ -6122,8 +5677,7 @@ "minimist": { "version": "0.0.8", "resolved": "https://registry.npmjs.org/minimist/-/minimist-0.0.8.tgz", - "integrity": "sha1-hX/Kv8M5fSYluCKCYuhqp6ARsF0=", - "dev": true + "integrity": "sha1-hX/Kv8M5fSYluCKCYuhqp6ARsF0=" } } }, @@ -6131,7 +5685,6 @@ "version": "1.0.1", "resolved": "https://registry.npmjs.org/move-concurrently/-/move-concurrently-1.0.1.tgz", "integrity": "sha1-viwAX9oy4LKa8fBdfEszIUxwH5I=", - "dev": true, "requires": { "aproba": "^1.1.1", "copy-concurrently": "^1.0.0", @@ -6142,16 +5695,14 @@ } }, "ms": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", - "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", - "dev": true + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=" }, "multicast-dns": { "version": "6.2.3", "resolved": "https://registry.npmjs.org/multicast-dns/-/multicast-dns-6.2.3.tgz", "integrity": "sha512-ji6J5enbMyGRHIAkAOu3WdV8nggqviKCEKtXcOqfphZZtQrmHKycfynJ2V7eVPUA4NhJ6V7Wf4TmGbTwKE9B6g==", - "dev": true, "requires": { "dns-packet": "^1.3.1", "thunky": "^1.0.2" @@ -6160,21 +5711,18 @@ "multicast-dns-service-types": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/multicast-dns-service-types/-/multicast-dns-service-types-1.1.0.tgz", - "integrity": "sha1-iZ8R2WhuXgXLkbNdXw5jt3PPyQE=", - "dev": true + "integrity": "sha1-iZ8R2WhuXgXLkbNdXw5jt3PPyQE=" }, "nan": { "version": "2.14.0", "resolved": "https://registry.npmjs.org/nan/-/nan-2.14.0.tgz", "integrity": "sha512-INOFj37C7k3AfaNTtX8RhsTw7qRy7eLET14cROi9+5HAVbbHuIWUHEauBv5qT4Av2tWasiTY1Jw6puUNqRJXQg==", - "dev": true, "optional": true }, "nanomatch": { "version": "1.2.13", "resolved": "https://registry.npmjs.org/nanomatch/-/nanomatch-1.2.13.tgz", "integrity": "sha512-fpoe2T0RbHwBTBUOftAfBPaDEi06ufaUai0mE6Yn1kacc3SnTErfb/h+X94VXzI64rKFHYImXSvdwGGCmwOqCA==", - "dev": true, "requires": { "arr-diff": "^4.0.0", "array-unique": "^0.3.2", @@ -6187,46 +5735,47 @@ "regex-not": "^1.0.0", "snapdragon": "^0.8.1", "to-regex": "^3.0.1" + }, + "dependencies": { + "kind-of": { + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.2.tgz", + "integrity": "sha512-s5kLOcnH0XqDO+FvuaLX8DDjZ18CGFk7VygH40QoKPUQhW4e2rvM0rwUq0t8IQDOwYSeLK01U90OjzBTme2QqA==" + } } }, "negotiator": { "version": "0.6.2", "resolved": "https://registry.npmjs.org/negotiator/-/negotiator-0.6.2.tgz", - "integrity": "sha512-hZXc7K2e+PgeI1eDBe/10Ard4ekbfrrqG8Ep+8Jmf4JID2bNg7NvCPOZN+kfF574pFQI7mum2AUqDidoKqcTOw==", - "dev": true + "integrity": "sha512-hZXc7K2e+PgeI1eDBe/10Ard4ekbfrrqG8Ep+8Jmf4JID2bNg7NvCPOZN+kfF574pFQI7mum2AUqDidoKqcTOw==" }, "neo-async": { "version": "2.6.1", "resolved": "https://registry.npmjs.org/neo-async/-/neo-async-2.6.1.tgz", - "integrity": "sha512-iyam8fBuCUpWeKPGpaNMetEocMt364qkCsfL9JuhjXX6dRnguRVOfk2GZaDpPjcOKiiXCPINZC1GczQ7iTq3Zw==", - "dev": true + "integrity": "sha512-iyam8fBuCUpWeKPGpaNMetEocMt364qkCsfL9JuhjXX6dRnguRVOfk2GZaDpPjcOKiiXCPINZC1GczQ7iTq3Zw==" }, "nice-try": { "version": "1.0.5", "resolved": "https://registry.npmjs.org/nice-try/-/nice-try-1.0.5.tgz", - "integrity": "sha512-1nh45deeb5olNY7eX82BkPO7SSxR5SSYJiPTrTdFUVYwAl8CKMA5N9PjTYkHiRjisVcxcQ1HXdLhx2qxxJzLNQ==", - "dev": true + "integrity": "sha512-1nh45deeb5olNY7eX82BkPO7SSxR5SSYJiPTrTdFUVYwAl8CKMA5N9PjTYkHiRjisVcxcQ1HXdLhx2qxxJzLNQ==" }, "no-case": { "version": "2.3.2", "resolved": "https://registry.npmjs.org/no-case/-/no-case-2.3.2.tgz", "integrity": "sha512-rmTZ9kz+f3rCvK2TD1Ue/oZlns7OGoIWP4fc3llxxRXlOkHKoWPPWJOfFYpITabSow43QJbRIoHQXtt10VldyQ==", - "dev": true, "requires": { "lower-case": "^1.1.1" } }, "node-forge": { - "version": "0.7.5", - "resolved": "https://registry.npmjs.org/node-forge/-/node-forge-0.7.5.tgz", - "integrity": "sha512-MmbQJ2MTESTjt3Gi/3yG1wGpIMhUfcIypUCGtTizFR9IiccFwxSpfp0vtIZlkFclEqERemxfnSdZEMR9VqqEFQ==", - "dev": true + "version": "0.9.0", + "resolved": "https://registry.npmjs.org/node-forge/-/node-forge-0.9.0.tgz", + "integrity": "sha512-7ASaDa3pD+lJ3WvXFsxekJQelBKRpne+GOVbLbtHYdd7pFspyeuJHnWfLplGf3SwKGbfs/aYl5V/JCIaHVUKKQ==" }, "node-libs-browser": { "version": "2.2.1", "resolved": "https://registry.npmjs.org/node-libs-browser/-/node-libs-browser-2.2.1.tgz", "integrity": "sha512-h/zcD8H9kaDZ9ALUWwlBUDo6TKF8a7qBSCSEGfjTVIYeqsioSKaAX+BN7NgiMGp6iSIXZ3PxgCu8KS3b71YK5Q==", - "dev": true, "requires": { "assert": "^1.1.1", "browserify-zlib": "^0.2.0", @@ -6256,25 +5805,29 @@ "punycode": { "version": "1.4.1", "resolved": "https://registry.npmjs.org/punycode/-/punycode-1.4.1.tgz", - "integrity": "sha1-wNWmOycYgArY4esPpSachN1BhF4=", - "dev": true + "integrity": "sha1-wNWmOycYgArY4esPpSachN1BhF4=" } } }, "node-releases": { - "version": "1.1.23", - "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-1.1.23.tgz", - "integrity": "sha512-uq1iL79YjfYC0WXoHbC/z28q/9pOl8kSHaXdWmAAc8No+bDwqkZbzIJz55g/MUsPgSGm9LZ7QSUbzTcH5tz47w==", - "dev": true, + "version": "1.1.38", + "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-1.1.38.tgz", + "integrity": "sha512-/5NZAaOyTj134Oy5Cp/J8mso8OD/D9CSuL+6TOXXsTKO8yjc5e4up75SRPCganCjwFKMj2jbp5tR0dViVdox7g==", "requires": { - "semver": "^5.3.0" + "semver": "^6.3.0" + }, + "dependencies": { + "semver": { + "version": "6.3.0", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", + "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==" + } } }, "nopt": { "version": "1.0.10", "resolved": "https://registry.npmjs.org/nopt/-/nopt-1.0.10.tgz", "integrity": "sha1-bd0hvSoxQXuScn3Vhfim83YI6+4=", - "dev": true, "requires": { "abbrev": "1" } @@ -6282,20 +5835,17 @@ "normalize-path": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-3.0.0.tgz", - "integrity": "sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==", - "dev": true + "integrity": "sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==" }, "normalize-range": { "version": "0.1.2", "resolved": "https://registry.npmjs.org/normalize-range/-/normalize-range-0.1.2.tgz", - "integrity": "sha1-LRDAa9/TEuqXd2laTShDlFa3WUI=", - "dev": true + "integrity": "sha1-LRDAa9/TEuqXd2laTShDlFa3WUI=" }, "normalize-url": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/normalize-url/-/normalize-url-2.0.1.tgz", "integrity": "sha512-D6MUW4K/VzoJ4rJ01JFKxDrtY1v9wrgzCX5f2qj/lzH1m/lW6MhUZFKerVsnyjOhOsYzI9Kqqak+10l4LvLpMw==", - "dev": true, "requires": { "prepend-http": "^2.0.0", "query-string": "^5.0.1", @@ -6306,7 +5856,6 @@ "version": "2.0.2", "resolved": "https://registry.npmjs.org/npm-run-path/-/npm-run-path-2.0.2.tgz", "integrity": "sha1-NakjLfo11wZ7TLLd8jV7GHFTbF8=", - "dev": true, "requires": { "path-key": "^2.0.0" } @@ -6314,14 +5863,12 @@ "nprogress": { "version": "0.2.0", "resolved": "https://registry.npmjs.org/nprogress/-/nprogress-0.2.0.tgz", - "integrity": "sha1-y480xTIT2JVyP8urkH6UIq28r7E=", - "dev": true + "integrity": "sha1-y480xTIT2JVyP8urkH6UIq28r7E=" }, "nth-check": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/nth-check/-/nth-check-1.0.2.tgz", "integrity": "sha512-WeBOdju8SnzPN5vTUJYxYUxLeXpCaVP5i5e0LF8fg7WORF2Wd7wFX/pk0tYZk7s8T+J7VLy0Da6J1+wCT0AtHg==", - "dev": true, "requires": { "boolbase": "~1.0.0" } @@ -6329,32 +5876,27 @@ "num2fraction": { "version": "1.2.2", "resolved": "https://registry.npmjs.org/num2fraction/-/num2fraction-1.2.2.tgz", - "integrity": "sha1-b2gragJ6Tp3fpFZM0lidHU5mnt4=", - "dev": true + "integrity": "sha1-b2gragJ6Tp3fpFZM0lidHU5mnt4=" }, "number-is-nan": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/number-is-nan/-/number-is-nan-1.0.1.tgz", - "integrity": "sha1-CXtgK1NCKlIsGvuHkDGDNpQaAR0=", - "dev": true + "integrity": "sha1-CXtgK1NCKlIsGvuHkDGDNpQaAR0=" }, "oauth-sign": { "version": "0.9.0", "resolved": "https://registry.npmjs.org/oauth-sign/-/oauth-sign-0.9.0.tgz", - "integrity": "sha512-fexhUFFPTGV8ybAtSIGbV6gOkSv8UtRbDBnAyLQw4QPKkgNlsH2ByPGtMUqdWkos6YCRmAqViwgZrJc/mRDzZQ==", - "dev": true + "integrity": "sha512-fexhUFFPTGV8ybAtSIGbV6gOkSv8UtRbDBnAyLQw4QPKkgNlsH2ByPGtMUqdWkos6YCRmAqViwgZrJc/mRDzZQ==" }, "object-assign": { "version": "4.1.1", "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz", - "integrity": "sha1-IQmtx5ZYh8/AXLvUQsrIv7s2CGM=", - "dev": true + "integrity": "sha1-IQmtx5ZYh8/AXLvUQsrIv7s2CGM=" }, "object-copy": { "version": "0.1.0", "resolved": "https://registry.npmjs.org/object-copy/-/object-copy-0.1.0.tgz", "integrity": "sha1-fn2Fi3gb18mRpBupde04EnVOmYw=", - "dev": true, "requires": { "copy-descriptor": "^0.1.0", "define-property": "^0.2.5", @@ -6365,33 +5907,31 @@ "version": "0.2.5", "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz", "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=", - "dev": true, "requires": { "is-descriptor": "^0.1.0" } - }, - "kind-of": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", - "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", - "dev": true, - "requires": { - "is-buffer": "^1.1.5" - } } } }, + "object-inspect": { + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.6.0.tgz", + "integrity": "sha512-GJzfBZ6DgDAmnuaM3104jR4s1Myxr3Y3zfIyN4z3UdqN69oSRacNK8UhnobDdC+7J2AHCjGwxQubNJfE70SXXQ==" + }, + "object-is": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/object-is/-/object-is-1.0.1.tgz", + "integrity": "sha1-CqYOyZiaCz7Xlc9NBvYs8a1lObY=" + }, "object-keys": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/object-keys/-/object-keys-1.1.1.tgz", - "integrity": "sha512-NuAESUOUMrlIXOfHKzD6bpPu3tYt3xvjNdRIQ+FeT0lNb4K8WR70CaDxhuNguS2XG+GjkyMwOzsN5ZktImfhLA==", - "dev": true + "integrity": "sha512-NuAESUOUMrlIXOfHKzD6bpPu3tYt3xvjNdRIQ+FeT0lNb4K8WR70CaDxhuNguS2XG+GjkyMwOzsN5ZktImfhLA==" }, "object-visit": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/object-visit/-/object-visit-1.0.1.tgz", "integrity": "sha1-95xEk68MU3e1n+OdOV5BBC3QRbs=", - "dev": true, "requires": { "isobject": "^3.0.0" } @@ -6400,7 +5940,6 @@ "version": "4.1.0", "resolved": "https://registry.npmjs.org/object.assign/-/object.assign-4.1.0.tgz", "integrity": "sha512-exHJeq6kBKj58mqGyTQ9DFvrZC/eR6OwxzoM9YRoGBqrXYonaFyGiFMuc9VZrXf7DarreEwMpurG3dd+CNyW5w==", - "dev": true, "requires": { "define-properties": "^1.1.2", "function-bind": "^1.1.1", @@ -6412,7 +5951,6 @@ "version": "2.0.3", "resolved": "https://registry.npmjs.org/object.getownpropertydescriptors/-/object.getownpropertydescriptors-2.0.3.tgz", "integrity": "sha1-h1jIRvW0B62rDyNuCYbxSwUcqhY=", - "dev": true, "requires": { "define-properties": "^1.1.2", "es-abstract": "^1.5.1" @@ -6422,7 +5960,6 @@ "version": "1.3.0", "resolved": "https://registry.npmjs.org/object.pick/-/object.pick-1.3.0.tgz", "integrity": "sha1-h6EKxMFpS9Lhy/U1kaZhQftd10c=", - "dev": true, "requires": { "isobject": "^3.0.1" } @@ -6431,7 +5968,6 @@ "version": "1.1.0", "resolved": "https://registry.npmjs.org/object.values/-/object.values-1.1.0.tgz", "integrity": "sha512-8mf0nKLAoFX6VlNVdhGj31SVYpaNFtUnuoOXWyFEstsWRgU837AK+JYM0iAxwkSzGRbwn8cbFmgbyxj1j4VbXg==", - "dev": true, "requires": { "define-properties": "^1.1.3", "es-abstract": "^1.12.0", @@ -6442,14 +5978,12 @@ "obuf": { "version": "1.1.2", "resolved": "https://registry.npmjs.org/obuf/-/obuf-1.1.2.tgz", - "integrity": "sha512-PX1wu0AmAdPqOL1mWhqmlOd8kOIZQwGZw6rh7uby9fTc5lhaOWFLX3I6R1hrF9k3zUY40e6igsLGkDXK92LJNg==", - "dev": true + "integrity": "sha512-PX1wu0AmAdPqOL1mWhqmlOd8kOIZQwGZw6rh7uby9fTc5lhaOWFLX3I6R1hrF9k3zUY40e6igsLGkDXK92LJNg==" }, "on-finished": { "version": "2.3.0", "resolved": "https://registry.npmjs.org/on-finished/-/on-finished-2.3.0.tgz", "integrity": "sha1-IPEzZIGwg811M3mSoWlxqi2QaUc=", - "dev": true, "requires": { "ee-first": "1.1.1" } @@ -6457,34 +5991,35 @@ "on-headers": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/on-headers/-/on-headers-1.0.2.tgz", - "integrity": "sha512-pZAE+FJLoyITytdqK0U5s+FIpjN0JP3OzFi/u8Rx+EV5/W+JTWGXG8xFzevE7AjBfDqHv/8vL8qQsIhHnqRkrA==", - "dev": true + "integrity": "sha512-pZAE+FJLoyITytdqK0U5s+FIpjN0JP3OzFi/u8Rx+EV5/W+JTWGXG8xFzevE7AjBfDqHv/8vL8qQsIhHnqRkrA==" }, "once": { "version": "1.4.0", "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", "integrity": "sha1-WDsap3WWHUsROsF9nFC6753Xa9E=", - "dev": true, "requires": { "wrappy": "1" } }, + "opencollective-postinstall": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/opencollective-postinstall/-/opencollective-postinstall-2.0.2.tgz", + "integrity": "sha512-pVOEP16TrAO2/fjej1IdOyupJY8KDUM1CvsaScRbw6oddvpQoOfGk4ywha0HKKVAD6RkW4x6Q+tNBwhf3Bgpuw==" + }, "opn": { "version": "5.5.0", "resolved": "https://registry.npmjs.org/opn/-/opn-5.5.0.tgz", "integrity": "sha512-PqHpggC9bLV0VeWcdKhkpxY+3JTzetLSqTCWL/z/tFIbI6G8JCjondXklT1JinczLz2Xib62sSp0T/gKT4KksA==", - "dev": true, "requires": { "is-wsl": "^1.1.0" } }, "optimize-css-assets-webpack-plugin": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/optimize-css-assets-webpack-plugin/-/optimize-css-assets-webpack-plugin-5.0.1.tgz", - "integrity": "sha512-Rqm6sSjWtx9FchdP0uzTQDc7GXDKnwVEGoSxjezPkzMewx7gEWE9IMUYKmigTRC4U3RaNSwYVnUDLuIdtTpm0A==", - "dev": true, + "version": "5.0.3", + "resolved": "https://registry.npmjs.org/optimize-css-assets-webpack-plugin/-/optimize-css-assets-webpack-plugin-5.0.3.tgz", + "integrity": "sha512-q9fbvCRS6EYtUKKSwI87qm2IxlyJK5b4dygW1rKUBT6mMDhdG5e5bZT63v6tnJR9F9FB/H5a0HTmtw+laUBxKA==", "requires": { - "cssnano": "^4.1.0", + "cssnano": "^4.1.10", "last-call-webpack-plugin": "^3.0.0" } }, @@ -6492,7 +6027,6 @@ "version": "1.0.2", "resolved": "https://registry.npmjs.org/original/-/original-1.0.2.tgz", "integrity": "sha512-hyBVl6iqqUOJ8FqRe+l/gS8H+kKYjrEndd5Pm1MfBtsEKA038HkkdbAl/72EAXGyonD/PFsvmVG+EvcIpliMBg==", - "dev": true, "requires": { "url-parse": "^1.4.3" } @@ -6500,14 +6034,12 @@ "os-browserify": { "version": "0.3.0", "resolved": "https://registry.npmjs.org/os-browserify/-/os-browserify-0.3.0.tgz", - "integrity": "sha1-hUNzx/XCMVkU/Jv8a9gjj92h7Cc=", - "dev": true + "integrity": "sha1-hUNzx/XCMVkU/Jv8a9gjj92h7Cc=" }, "os-locale": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/os-locale/-/os-locale-3.1.0.tgz", "integrity": "sha512-Z8l3R4wYWM40/52Z+S265okfFj8Kt2cC2MKY+xNi3kFs+XGI7WXu/I309QQQYbRW4ijiZ+yxs9pqEhJh0DqW3Q==", - "dev": true, "requires": { "execa": "^1.0.0", "lcid": "^2.0.0", @@ -6517,26 +6049,22 @@ "p-defer": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/p-defer/-/p-defer-1.0.0.tgz", - "integrity": "sha1-n26xgvbJqozXQwBKfU+WsZaw+ww=", - "dev": true + "integrity": "sha1-n26xgvbJqozXQwBKfU+WsZaw+ww=" }, "p-finally": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/p-finally/-/p-finally-1.0.0.tgz", - "integrity": "sha1-P7z7FbiZpEEjs0ttzBi3JDNqLK4=", - "dev": true + "integrity": "sha1-P7z7FbiZpEEjs0ttzBi3JDNqLK4=" }, "p-is-promise": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/p-is-promise/-/p-is-promise-2.1.0.tgz", - "integrity": "sha512-Y3W0wlRPK8ZMRbNq97l4M5otioeA5lm1z7bkNkxCka8HSPjR0xRWmpCmc9utiaLP9Jb1eD8BgeIxTW4AIF45Pg==", - "dev": true + "integrity": "sha512-Y3W0wlRPK8ZMRbNq97l4M5otioeA5lm1z7bkNkxCka8HSPjR0xRWmpCmc9utiaLP9Jb1eD8BgeIxTW4AIF45Pg==" }, "p-limit": { "version": "1.3.0", "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-1.3.0.tgz", "integrity": "sha512-vvcXsLAJ9Dr5rQOPk7toZQZJApBl2K4J6dANSsEuh6QI41JYcsS/qhTGa9ErIUUgK3WNQoJYvylxvjqmiqEA9Q==", - "dev": true, "requires": { "p-try": "^1.0.0" } @@ -6545,7 +6073,6 @@ "version": "2.0.0", "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-2.0.0.tgz", "integrity": "sha1-IKAQOyIqcMj9OcwuWAaA893l7EM=", - "dev": true, "requires": { "p-limit": "^1.1.0" } @@ -6553,14 +6080,12 @@ "p-map": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/p-map/-/p-map-2.1.0.tgz", - "integrity": "sha512-y3b8Kpd8OAN444hxfBbFfj1FY/RjtTd8tzYwhUqNYXx0fXx2iX4maP4Qr6qhIKbQXI02wTLAda4fYUbDagTUFw==", - "dev": true + "integrity": "sha512-y3b8Kpd8OAN444hxfBbFfj1FY/RjtTd8tzYwhUqNYXx0fXx2iX4maP4Qr6qhIKbQXI02wTLAda4fYUbDagTUFw==" }, "p-retry": { "version": "3.0.1", "resolved": "https://registry.npmjs.org/p-retry/-/p-retry-3.0.1.tgz", "integrity": "sha512-XE6G4+YTTkT2a0UWb2kjZe8xNwf8bIbnqpc/IS/idOBVhyves0mK5OJgeocjx7q5pvX/6m23xuzVPYT1uGM73w==", - "dev": true, "requires": { "retry": "^0.12.0" } @@ -6568,22 +6093,19 @@ "p-try": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/p-try/-/p-try-1.0.0.tgz", - "integrity": "sha1-y8ec26+P1CKOE/Yh8rGiN8GyB7M=", - "dev": true + "integrity": "sha1-y8ec26+P1CKOE/Yh8rGiN8GyB7M=" }, "pako": { "version": "1.0.10", "resolved": "https://registry.npmjs.org/pako/-/pako-1.0.10.tgz", - "integrity": "sha512-0DTvPVU3ed8+HNXOu5Bs+o//Mbdj9VNQMUOe9oKCwh8l0GNwpTDMKCWbRjgtD291AWnkAgkqA/LOnQS8AmS1tw==", - "dev": true + "integrity": "sha512-0DTvPVU3ed8+HNXOu5Bs+o//Mbdj9VNQMUOe9oKCwh8l0GNwpTDMKCWbRjgtD291AWnkAgkqA/LOnQS8AmS1tw==" }, "parallel-transform": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/parallel-transform/-/parallel-transform-1.1.0.tgz", - "integrity": "sha1-1BDwZbBdojCB/NEPKIVMKb2jOwY=", - "dev": true, + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/parallel-transform/-/parallel-transform-1.2.0.tgz", + "integrity": "sha512-P2vSmIu38uIlvdcU7fDkyrxj33gTUy/ABO5ZUbGowxNCopBq/OoD42bP4UmMrJoPyk4Uqf0mu3mtWBhHCZD8yg==", "requires": { - "cyclist": "~0.2.2", + "cyclist": "^1.0.1", "inherits": "^2.0.3", "readable-stream": "^2.1.5" } @@ -6592,16 +6114,14 @@ "version": "2.1.1", "resolved": "https://registry.npmjs.org/param-case/-/param-case-2.1.1.tgz", "integrity": "sha1-35T9jPZTHs915r75oIWPvHK+Ikc=", - "dev": true, "requires": { "no-case": "^2.2.0" } }, "parse-asn1": { - "version": "5.1.4", - "resolved": "https://registry.npmjs.org/parse-asn1/-/parse-asn1-5.1.4.tgz", - "integrity": "sha512-Qs5duJcuvNExRfFZ99HDD3z4mAi3r9Wl/FOjEOijlxwCZs7E7mW2vjTpgQ4J8LpTF8x5v+1Vn5UQFejmWT11aw==", - "dev": true, + "version": "5.1.5", + "resolved": "https://registry.npmjs.org/parse-asn1/-/parse-asn1-5.1.5.tgz", + "integrity": "sha512-jkMYn1dcJqF6d5CpU689bq7w/b5ALS9ROVSpQDPrZsqqesUJii9qutvoT5ltGedNXMO2e16YUWIghG9KxaViTQ==", "requires": { "asn1.js": "^4.0.0", "browserify-aes": "^1.0.0", @@ -6615,7 +6135,6 @@ "version": "4.0.0", "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-4.0.0.tgz", "integrity": "sha1-vjX1Qlvh9/bHRxhPmKeIy5lHfuA=", - "dev": true, "requires": { "error-ex": "^1.3.1", "json-parse-better-errors": "^1.0.1" @@ -6624,68 +6143,57 @@ "parseurl": { "version": "1.3.3", "resolved": "https://registry.npmjs.org/parseurl/-/parseurl-1.3.3.tgz", - "integrity": "sha512-CiyeOxFT/JZyN5m0z9PfXw4SCBJ6Sygz1Dpl0wqjlhDEGGBP1GnsUVEL0p63hoG1fcj3fHynXi9NYO4nWOL+qQ==", - "dev": true + "integrity": "sha512-CiyeOxFT/JZyN5m0z9PfXw4SCBJ6Sygz1Dpl0wqjlhDEGGBP1GnsUVEL0p63hoG1fcj3fHynXi9NYO4nWOL+qQ==" }, "pascalcase": { "version": "0.1.1", "resolved": "https://registry.npmjs.org/pascalcase/-/pascalcase-0.1.1.tgz", - "integrity": "sha1-s2PlXoAGym/iF4TS2yK9FdeRfxQ=", - "dev": true + "integrity": "sha1-s2PlXoAGym/iF4TS2yK9FdeRfxQ=" }, "path-browserify": { "version": "0.0.1", "resolved": "https://registry.npmjs.org/path-browserify/-/path-browserify-0.0.1.tgz", - "integrity": "sha512-BapA40NHICOS+USX9SN4tyhq+A2RrN/Ws5F0Z5aMHDp98Fl86lX8Oti8B7uN93L4Ifv4fHOEA+pQw87gmMO/lQ==", - "dev": true + "integrity": "sha512-BapA40NHICOS+USX9SN4tyhq+A2RrN/Ws5F0Z5aMHDp98Fl86lX8Oti8B7uN93L4Ifv4fHOEA+pQw87gmMO/lQ==" }, "path-dirname": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/path-dirname/-/path-dirname-1.0.2.tgz", - "integrity": "sha1-zDPSTVJeCZpTiMAzbG4yuRYGCeA=", - "dev": true + "integrity": "sha1-zDPSTVJeCZpTiMAzbG4yuRYGCeA=" }, "path-exists": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-3.0.0.tgz", - "integrity": "sha1-zg6+ql94yxiSXqfYENe1mwEP1RU=", - "dev": true + "integrity": "sha1-zg6+ql94yxiSXqfYENe1mwEP1RU=" }, "path-is-absolute": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz", - "integrity": "sha1-F0uSaHNVNP+8es5r9TpanhtcX18=", - "dev": true + "integrity": "sha1-F0uSaHNVNP+8es5r9TpanhtcX18=" }, "path-is-inside": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/path-is-inside/-/path-is-inside-1.0.2.tgz", - "integrity": "sha1-NlQX3t5EQw0cEa9hAn+s8HS9/FM=", - "dev": true + "integrity": "sha1-NlQX3t5EQw0cEa9hAn+s8HS9/FM=" }, "path-key": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/path-key/-/path-key-2.0.1.tgz", - "integrity": "sha1-QRyttXTFoUDTpLGRDUDYDMn0C0A=", - "dev": true + "integrity": "sha1-QRyttXTFoUDTpLGRDUDYDMn0C0A=" }, "path-parse": { "version": "1.0.6", "resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.6.tgz", - "integrity": "sha512-GSmOT2EbHrINBf9SR7CDELwlJ8AENk3Qn7OikK4nFYAu3Ote2+JYNVvkpAEQm3/TLNEJFD/xZJjzyxg3KBWOzw==", - "dev": true + "integrity": "sha512-GSmOT2EbHrINBf9SR7CDELwlJ8AENk3Qn7OikK4nFYAu3Ote2+JYNVvkpAEQm3/TLNEJFD/xZJjzyxg3KBWOzw==" }, "path-to-regexp": { "version": "0.1.7", "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-0.1.7.tgz", - "integrity": "sha1-32BBeABfUi8V60SQ5yR6G/qmf4w=", - "dev": true + "integrity": "sha1-32BBeABfUi8V60SQ5yR6G/qmf4w=" }, "path-type": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/path-type/-/path-type-3.0.0.tgz", "integrity": "sha512-T2ZUsdZFHgA3u4e5PfPbjd7HDDpxPnQb5jN0SrDsjNSuVXHJqtwTnWqG0B1jZrgmJ/7lj1EmVIByWt1gxGkWvg==", - "dev": true, "requires": { "pify": "^3.0.0" }, @@ -6693,8 +6201,7 @@ "pify": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/pify/-/pify-3.0.0.tgz", - "integrity": "sha1-5aSs0sEB/fPZpNB/DbxNtJ3SgXY=", - "dev": true + "integrity": "sha1-5aSs0sEB/fPZpNB/DbxNtJ3SgXY=" } } }, @@ -6702,7 +6209,6 @@ "version": "3.0.17", "resolved": "https://registry.npmjs.org/pbkdf2/-/pbkdf2-3.0.17.tgz", "integrity": "sha512-U/il5MsrZp7mGg3mSQfn742na2T+1/vHDCG5/iTI3X9MKUuYUZVLQhyRsg06mCgDBTd57TxzgZt7P+fYfjRLtA==", - "dev": true, "requires": { "create-hash": "^1.1.2", "create-hmac": "^1.1.4", @@ -6714,26 +6220,22 @@ "performance-now": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/performance-now/-/performance-now-2.1.0.tgz", - "integrity": "sha1-Ywn04OX6kT7BxpMHrjZLSzd8nns=", - "dev": true + "integrity": "sha1-Ywn04OX6kT7BxpMHrjZLSzd8nns=" }, "pify": { "version": "4.0.1", "resolved": "https://registry.npmjs.org/pify/-/pify-4.0.1.tgz", - "integrity": "sha512-uB80kBFb/tfd68bVleG9T5GGsGPjJrLAUpR5PZIrhBnIaRTQRjqdJSsIKkOP6OAIFbj7GOrcudc5pNjZ+geV2g==", - "dev": true + "integrity": "sha512-uB80kBFb/tfd68bVleG9T5GGsGPjJrLAUpR5PZIrhBnIaRTQRjqdJSsIKkOP6OAIFbj7GOrcudc5pNjZ+geV2g==" }, "pinkie": { "version": "2.0.4", "resolved": "https://registry.npmjs.org/pinkie/-/pinkie-2.0.4.tgz", - "integrity": "sha1-clVrgM+g1IqXToDnckjoDtT3+HA=", - "dev": true + "integrity": "sha1-clVrgM+g1IqXToDnckjoDtT3+HA=" }, "pinkie-promise": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/pinkie-promise/-/pinkie-promise-2.0.1.tgz", "integrity": "sha1-ITXW36ejWMBprJsXh3YogihFD/o=", - "dev": true, "requires": { "pinkie": "^2.0.0" } @@ -6742,7 +6244,6 @@ "version": "3.0.0", "resolved": "https://registry.npmjs.org/pkg-dir/-/pkg-dir-3.0.0.tgz", "integrity": "sha512-/E57AYkoeQ25qkxMj5PBOVgF8Kiu/h7cYS30Z5+R7WaiCCBfLq58ZI/dSeaEKb9WVJV5n/03QwrN3IeWIFllvw==", - "dev": true, "requires": { "find-up": "^3.0.0" }, @@ -6751,7 +6252,6 @@ "version": "3.0.0", "resolved": "https://registry.npmjs.org/find-up/-/find-up-3.0.0.tgz", "integrity": "sha512-1yD6RmLI1XBfxugvORwlck6f75tYL+iR0jqwsOrOxMZyGYqUuDhJ0l4AXdO1iX/FTs9cBAMEk1gWSEx1kSbylg==", - "dev": true, "requires": { "locate-path": "^3.0.0" } @@ -6760,17 +6260,15 @@ "version": "3.0.0", "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-3.0.0.tgz", "integrity": "sha512-7AO748wWnIhNqAuaty2ZWHkQHRSNfPVIsPIfwEOWO22AmaoVrWavlOcMR5nzTLNYvp36X220/maaRsrec1G65A==", - "dev": true, "requires": { "p-locate": "^3.0.0", "path-exists": "^3.0.0" } }, "p-limit": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.2.0.tgz", - "integrity": "sha512-pZbTJpoUsCzV48Mc9Nh51VbwO0X9cuPFE8gYwx9BTCt9SF8/b7Zljd2fVgOxhIF/HDTKgpVzs+GPhyKfjLLFRQ==", - "dev": true, + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.2.1.tgz", + "integrity": "sha512-85Tk+90UCVWvbDavCLKPOLC9vvY8OwEX/RtKF+/1OADJMVlFfEHOiMTPVyxg7mk/dKa+ipdHm0OUkTvCpMTuwg==", "requires": { "p-try": "^2.0.0" } @@ -6779,7 +6277,6 @@ "version": "3.0.0", "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-3.0.0.tgz", "integrity": "sha512-x+12w/To+4GFfgJhBEpiDcLozRJGegY+Ei7/z0tSLkMmxGZNybVMSfWj9aJn8Z5Fc7dBUNJOOVgPv2H7IwulSQ==", - "dev": true, "requires": { "p-limit": "^2.0.0" } @@ -6787,8 +6284,7 @@ "p-try": { "version": "2.2.0", "resolved": "https://registry.npmjs.org/p-try/-/p-try-2.2.0.tgz", - "integrity": "sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ==", - "dev": true + "integrity": "sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ==" } } }, @@ -6796,67 +6292,54 @@ "version": "2.0.0", "resolved": "https://registry.npmjs.org/pkg-up/-/pkg-up-2.0.0.tgz", "integrity": "sha1-yBmscoBZpGHKscOImivjxJoATX8=", - "dev": true, "requires": { "find-up": "^2.1.0" } }, "portfinder": { - "version": "1.0.20", - "resolved": "https://registry.npmjs.org/portfinder/-/portfinder-1.0.20.tgz", - "integrity": "sha512-Yxe4mTyDzTd59PZJY4ojZR8F+E5e97iq2ZOHPz3HDgSvYC5siNad2tLooQ5y5QHyQhc3xVqvyk/eNA3wuoa7Sw==", - "dev": true, + "version": "1.0.25", + "resolved": "https://registry.npmjs.org/portfinder/-/portfinder-1.0.25.tgz", + "integrity": "sha512-6ElJnHBbxVA1XSLgBp7G1FiCkQdlqGzuF7DswL5tcea+E8UpuvPU7beVAjjRwCioTS9ZluNbu+ZyRvgTsmqEBg==", "requires": { - "async": "^1.5.2", - "debug": "^2.2.0", - "mkdirp": "0.5.x" + "async": "^2.6.2", + "debug": "^3.1.1", + "mkdirp": "^0.5.1" }, "dependencies": { "debug": { - "version": "2.6.9", - "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", - "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", - "dev": true, + "version": "3.2.6", + "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.6.tgz", + "integrity": "sha512-mel+jf7nrtEl5Pn1Qx46zARXKDpBbvzezse7p7LqINmdoIk8PYP5SySaxEmYv6TZ0JyEKA1hsCId6DIhgITtWQ==", "requires": { - "ms": "2.0.0" + "ms": "^2.1.1" } }, "ms": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", - "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=", - "dev": true + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", + "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==" } } }, "posix-character-classes": { "version": "0.1.1", "resolved": "https://registry.npmjs.org/posix-character-classes/-/posix-character-classes-0.1.1.tgz", - "integrity": "sha1-AerA/jta9xoqbAL+q7jB/vfgDqs=", - "dev": true + "integrity": "sha1-AerA/jta9xoqbAL+q7jB/vfgDqs=" }, "postcss": { - "version": "7.0.17", - "resolved": "https://registry.npmjs.org/postcss/-/postcss-7.0.17.tgz", - "integrity": "sha512-546ZowA+KZ3OasvQZHsbuEpysvwTZNGJv9EfyCQdsIDltPSWHAeTQ5fQy/Npi2ZDtLI3zs7Ps/p6wThErhm9fQ==", - "dev": true, + "version": "7.0.20", + "resolved": "https://registry.npmjs.org/postcss/-/postcss-7.0.20.tgz", + "integrity": "sha512-VOdO3a5nHVftPSEbG1zaG320b4mH5KAflH+pIeVAF5/hlw6YumELSgHZQBekjg29Oj4qw7XAyp9tIEBpeNWcyg==", "requires": { "chalk": "^2.4.2", "source-map": "^0.6.1", "supports-color": "^6.1.0" }, "dependencies": { - "source-map": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", - "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", - "dev": true - }, "supports-color": { "version": "6.1.0", "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-6.1.0.tgz", "integrity": "sha512-qe1jfm1Mg7Nq/NSh6XE24gPXROEVsWHxC1LIx//XNlD9iw7YZQGjZNjYN7xGaEG6iKdA8EtNFW6R0gjnVXp+wQ==", - "dev": true, "requires": { "has-flag": "^3.0.0" } @@ -6867,7 +6350,6 @@ "version": "7.0.1", "resolved": "https://registry.npmjs.org/postcss-calc/-/postcss-calc-7.0.1.tgz", "integrity": "sha512-oXqx0m6tb4N3JGdmeMSc/i91KppbYsFZKdH0xMOqK8V1rJlzrKlTdokz8ozUXLVejydRN6u2IddxpcijRj2FqQ==", - "dev": true, "requires": { "css-unit-converter": "^1.1.1", "postcss": "^7.0.5", @@ -6878,19 +6360,22 @@ "cssesc": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/cssesc/-/cssesc-2.0.0.tgz", - "integrity": "sha512-MsCAG1z9lPdoO/IUMLSBWBSVxVtJ1395VGIQ+Fc2gNdkQ1hNDnQdw3YhA71WJCBW1vdwA0cAnk/DnW6bqoEUYg==", - "dev": true + "integrity": "sha512-MsCAG1z9lPdoO/IUMLSBWBSVxVtJ1395VGIQ+Fc2gNdkQ1hNDnQdw3YhA71WJCBW1vdwA0cAnk/DnW6bqoEUYg==" }, "postcss-selector-parser": { "version": "5.0.0", "resolved": "https://registry.npmjs.org/postcss-selector-parser/-/postcss-selector-parser-5.0.0.tgz", "integrity": "sha512-w+zLE5Jhg6Liz8+rQOWEAwtwkyqpfnmsinXjXg6cY7YIONZZtgvE0v2O0uhQBs0peNomOJwWRKt6JBfTdTd3OQ==", - "dev": true, "requires": { "cssesc": "^2.0.0", "indexes-of": "^1.0.1", "uniq": "^1.0.1" } + }, + "postcss-value-parser": { + "version": "3.3.1", + "resolved": "https://registry.npmjs.org/postcss-value-parser/-/postcss-value-parser-3.3.1.tgz", + "integrity": "sha512-pISE66AbVkp4fDQ7VHBwRNXzAAKJjw4Vw7nWI/+Q3vuly7SNfgYXvm6i5IgFylHGK5sP/xHAbB7N49OS4gWNyQ==" } } }, @@ -6898,30 +6383,41 @@ "version": "4.0.3", "resolved": "https://registry.npmjs.org/postcss-colormin/-/postcss-colormin-4.0.3.tgz", "integrity": "sha512-WyQFAdDZpExQh32j0U0feWisZ0dmOtPl44qYmJKkq9xFWY3p+4qnRzCHeNrkeRhwPHz9bQ3mo0/yVkaply0MNw==", - "dev": true, "requires": { "browserslist": "^4.0.0", "color": "^3.0.0", "has": "^1.0.0", "postcss": "^7.0.0", "postcss-value-parser": "^3.0.0" + }, + "dependencies": { + "postcss-value-parser": { + "version": "3.3.1", + "resolved": "https://registry.npmjs.org/postcss-value-parser/-/postcss-value-parser-3.3.1.tgz", + "integrity": "sha512-pISE66AbVkp4fDQ7VHBwRNXzAAKJjw4Vw7nWI/+Q3vuly7SNfgYXvm6i5IgFylHGK5sP/xHAbB7N49OS4gWNyQ==" + } } }, "postcss-convert-values": { "version": "4.0.1", "resolved": "https://registry.npmjs.org/postcss-convert-values/-/postcss-convert-values-4.0.1.tgz", "integrity": "sha512-Kisdo1y77KUC0Jmn0OXU/COOJbzM8cImvw1ZFsBgBgMgb1iL23Zs/LXRe3r+EZqM3vGYKdQ2YJVQ5VkJI+zEJQ==", - "dev": true, "requires": { "postcss": "^7.0.0", "postcss-value-parser": "^3.0.0" + }, + "dependencies": { + "postcss-value-parser": { + "version": "3.3.1", + "resolved": "https://registry.npmjs.org/postcss-value-parser/-/postcss-value-parser-3.3.1.tgz", + "integrity": "sha512-pISE66AbVkp4fDQ7VHBwRNXzAAKJjw4Vw7nWI/+Q3vuly7SNfgYXvm6i5IgFylHGK5sP/xHAbB7N49OS4gWNyQ==" + } } }, "postcss-discard-comments": { "version": "4.0.2", "resolved": "https://registry.npmjs.org/postcss-discard-comments/-/postcss-discard-comments-4.0.2.tgz", "integrity": "sha512-RJutN259iuRf3IW7GZyLM5Sw4GLTOH8FmsXBnv8Ab/Tc2k4SR4qbV4DNbyyY4+Sjo362SyDmW2DQ7lBSChrpkg==", - "dev": true, "requires": { "postcss": "^7.0.0" } @@ -6930,7 +6426,6 @@ "version": "4.0.2", "resolved": "https://registry.npmjs.org/postcss-discard-duplicates/-/postcss-discard-duplicates-4.0.2.tgz", "integrity": "sha512-ZNQfR1gPNAiXZhgENFfEglF93pciw0WxMkJeVmw8eF+JZBbMD7jp6C67GqJAXVZP2BWbOztKfbsdmMp/k8c6oQ==", - "dev": true, "requires": { "postcss": "^7.0.0" } @@ -6939,7 +6434,6 @@ "version": "4.0.1", "resolved": "https://registry.npmjs.org/postcss-discard-empty/-/postcss-discard-empty-4.0.1.tgz", "integrity": "sha512-B9miTzbznhDjTfjvipfHoqbWKwd0Mj+/fL5s1QOz06wufguil+Xheo4XpOnc4NqKYBCNqqEzgPv2aPBIJLox0w==", - "dev": true, "requires": { "postcss": "^7.0.0" } @@ -6948,7 +6442,6 @@ "version": "4.0.1", "resolved": "https://registry.npmjs.org/postcss-discard-overridden/-/postcss-discard-overridden-4.0.1.tgz", "integrity": "sha512-IYY2bEDD7g1XM1IDEsUT4//iEYCxAmP5oDSFMVU/JVvT7gh+l4fmjciLqGgwjdWpQIdb0Che2VX00QObS5+cTg==", - "dev": true, "requires": { "postcss": "^7.0.0" } @@ -6957,7 +6450,6 @@ "version": "2.1.0", "resolved": "https://registry.npmjs.org/postcss-load-config/-/postcss-load-config-2.1.0.tgz", "integrity": "sha512-4pV3JJVPLd5+RueiVVB+gFOAa7GWc25XQcMp86Zexzke69mKf6Nx9LRcQywdz7yZI9n1udOxmLuAwTBypypF8Q==", - "dev": true, "requires": { "cosmiconfig": "^5.0.0", "import-cwd": "^2.0.0" @@ -6967,7 +6459,6 @@ "version": "3.0.0", "resolved": "https://registry.npmjs.org/postcss-loader/-/postcss-loader-3.0.0.tgz", "integrity": "sha512-cLWoDEY5OwHcAjDnkyRQzAXfs2jrKjXpO/HQFcc5b5u/r7aa471wdmChmwfnv7x2u840iat/wi0lQ5nbRgSkUA==", - "dev": true, "requires": { "loader-utils": "^1.1.0", "postcss": "^7.0.0", @@ -6979,19 +6470,24 @@ "version": "4.0.11", "resolved": "https://registry.npmjs.org/postcss-merge-longhand/-/postcss-merge-longhand-4.0.11.tgz", "integrity": "sha512-alx/zmoeXvJjp7L4mxEMjh8lxVlDFX1gqWHzaaQewwMZiVhLo42TEClKaeHbRf6J7j82ZOdTJ808RtN0ZOZwvw==", - "dev": true, "requires": { "css-color-names": "0.0.4", "postcss": "^7.0.0", "postcss-value-parser": "^3.0.0", "stylehacks": "^4.0.0" + }, + "dependencies": { + "postcss-value-parser": { + "version": "3.3.1", + "resolved": "https://registry.npmjs.org/postcss-value-parser/-/postcss-value-parser-3.3.1.tgz", + "integrity": "sha512-pISE66AbVkp4fDQ7VHBwRNXzAAKJjw4Vw7nWI/+Q3vuly7SNfgYXvm6i5IgFylHGK5sP/xHAbB7N49OS4gWNyQ==" + } } }, "postcss-merge-rules": { "version": "4.0.3", "resolved": "https://registry.npmjs.org/postcss-merge-rules/-/postcss-merge-rules-4.0.3.tgz", "integrity": "sha512-U7e3r1SbvYzO0Jr3UT/zKBVgYYyhAz0aitvGIYOYK5CPmkNih+WDSsS5tvPrJ8YMQYlEMvsZIiqmn7HdFUaeEQ==", - "dev": true, "requires": { "browserslist": "^4.0.0", "caniuse-api": "^3.0.0", @@ -7005,7 +6501,6 @@ "version": "3.1.1", "resolved": "https://registry.npmjs.org/postcss-selector-parser/-/postcss-selector-parser-3.1.1.tgz", "integrity": "sha1-T4dfSvsMllc9XPTXQBGu4lCn6GU=", - "dev": true, "requires": { "dot-prop": "^4.1.1", "indexes-of": "^1.0.1", @@ -7018,29 +6513,40 @@ "version": "4.0.2", "resolved": "https://registry.npmjs.org/postcss-minify-font-values/-/postcss-minify-font-values-4.0.2.tgz", "integrity": "sha512-j85oO6OnRU9zPf04+PZv1LYIYOprWm6IA6zkXkrJXyRveDEuQggG6tvoy8ir8ZwjLxLuGfNkCZEQG7zan+Hbtg==", - "dev": true, "requires": { "postcss": "^7.0.0", "postcss-value-parser": "^3.0.0" + }, + "dependencies": { + "postcss-value-parser": { + "version": "3.3.1", + "resolved": "https://registry.npmjs.org/postcss-value-parser/-/postcss-value-parser-3.3.1.tgz", + "integrity": "sha512-pISE66AbVkp4fDQ7VHBwRNXzAAKJjw4Vw7nWI/+Q3vuly7SNfgYXvm6i5IgFylHGK5sP/xHAbB7N49OS4gWNyQ==" + } } }, "postcss-minify-gradients": { "version": "4.0.2", "resolved": "https://registry.npmjs.org/postcss-minify-gradients/-/postcss-minify-gradients-4.0.2.tgz", "integrity": "sha512-qKPfwlONdcf/AndP1U8SJ/uzIJtowHlMaSioKzebAXSG4iJthlWC9iSWznQcX4f66gIWX44RSA841HTHj3wK+Q==", - "dev": true, "requires": { "cssnano-util-get-arguments": "^4.0.0", "is-color-stop": "^1.0.0", "postcss": "^7.0.0", "postcss-value-parser": "^3.0.0" + }, + "dependencies": { + "postcss-value-parser": { + "version": "3.3.1", + "resolved": "https://registry.npmjs.org/postcss-value-parser/-/postcss-value-parser-3.3.1.tgz", + "integrity": "sha512-pISE66AbVkp4fDQ7VHBwRNXzAAKJjw4Vw7nWI/+Q3vuly7SNfgYXvm6i5IgFylHGK5sP/xHAbB7N49OS4gWNyQ==" + } } }, "postcss-minify-params": { "version": "4.0.2", "resolved": "https://registry.npmjs.org/postcss-minify-params/-/postcss-minify-params-4.0.2.tgz", "integrity": "sha512-G7eWyzEx0xL4/wiBBJxJOz48zAKV2WG3iZOqVhPet/9geefm/Px5uo1fzlHu+DOjT+m0Mmiz3jkQzVHe6wxAWg==", - "dev": true, "requires": { "alphanum-sort": "^1.0.0", "browserslist": "^4.0.0", @@ -7048,13 +6554,19 @@ "postcss": "^7.0.0", "postcss-value-parser": "^3.0.0", "uniqs": "^2.0.0" + }, + "dependencies": { + "postcss-value-parser": { + "version": "3.3.1", + "resolved": "https://registry.npmjs.org/postcss-value-parser/-/postcss-value-parser-3.3.1.tgz", + "integrity": "sha512-pISE66AbVkp4fDQ7VHBwRNXzAAKJjw4Vw7nWI/+Q3vuly7SNfgYXvm6i5IgFylHGK5sP/xHAbB7N49OS4gWNyQ==" + } } }, "postcss-minify-selectors": { "version": "4.0.2", "resolved": "https://registry.npmjs.org/postcss-minify-selectors/-/postcss-minify-selectors-4.0.2.tgz", "integrity": "sha512-D5S1iViljXBj9kflQo4YutWnJmwm8VvIsU1GeXJGiG9j8CIg9zs4voPMdQDUmIxetUOh60VilsNzCiAFTOqu3g==", - "dev": true, "requires": { "alphanum-sort": "^1.0.0", "has": "^1.0.0", @@ -7066,7 +6578,6 @@ "version": "3.1.1", "resolved": "https://registry.npmjs.org/postcss-selector-parser/-/postcss-selector-parser-3.1.1.tgz", "integrity": "sha1-T4dfSvsMllc9XPTXQBGu4lCn6GU=", - "dev": true, "requires": { "dot-prop": "^4.1.1", "indexes-of": "^1.0.1", @@ -7079,7 +6590,6 @@ "version": "2.0.0", "resolved": "https://registry.npmjs.org/postcss-modules-extract-imports/-/postcss-modules-extract-imports-2.0.0.tgz", "integrity": "sha512-LaYLDNS4SG8Q5WAWqIJgdHPJrDDr/Lv775rMBFUbgjTz6j34lUznACHcdRWroPvXANP2Vj7yNK57vp9eFqzLWQ==", - "dev": true, "requires": { "postcss": "^7.0.5" } @@ -7088,18 +6598,23 @@ "version": "2.0.6", "resolved": "https://registry.npmjs.org/postcss-modules-local-by-default/-/postcss-modules-local-by-default-2.0.6.tgz", "integrity": "sha512-oLUV5YNkeIBa0yQl7EYnxMgy4N6noxmiwZStaEJUSe2xPMcdNc8WmBQuQCx18H5psYbVxz8zoHk0RAAYZXP9gA==", - "dev": true, "requires": { "postcss": "^7.0.6", "postcss-selector-parser": "^6.0.0", "postcss-value-parser": "^3.3.1" + }, + "dependencies": { + "postcss-value-parser": { + "version": "3.3.1", + "resolved": "https://registry.npmjs.org/postcss-value-parser/-/postcss-value-parser-3.3.1.tgz", + "integrity": "sha512-pISE66AbVkp4fDQ7VHBwRNXzAAKJjw4Vw7nWI/+Q3vuly7SNfgYXvm6i5IgFylHGK5sP/xHAbB7N49OS4gWNyQ==" + } } }, "postcss-modules-scope": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/postcss-modules-scope/-/postcss-modules-scope-2.1.0.tgz", "integrity": "sha512-91Rjps0JnmtUB0cujlc8KIKCsJXWjzuxGeT/+Q2i2HXKZ7nBUeF9YQTZZTNvHVoNYj1AthsjnGLtqDUE0Op79A==", - "dev": true, "requires": { "postcss": "^7.0.6", "postcss-selector-parser": "^6.0.0" @@ -7109,7 +6624,6 @@ "version": "2.0.0", "resolved": "https://registry.npmjs.org/postcss-modules-values/-/postcss-modules-values-2.0.0.tgz", "integrity": "sha512-Ki7JZa7ff1N3EIMlPnGTZfUMe69FFwiQPnVSXC9mnn3jozCRBYIxiZd44yJOV2AmabOo4qFf8s0dC/+lweG7+w==", - "dev": true, "requires": { "icss-replace-symbols": "^1.1.0", "postcss": "^7.0.6" @@ -7119,7 +6633,6 @@ "version": "4.0.1", "resolved": "https://registry.npmjs.org/postcss-normalize-charset/-/postcss-normalize-charset-4.0.1.tgz", "integrity": "sha512-gMXCrrlWh6G27U0hF3vNvR3w8I1s2wOBILvA87iNXaPvSNo5uZAMYsZG7XjCUf1eVxuPfyL4TJ7++SGZLc9A3g==", - "dev": true, "requires": { "postcss": "^7.0.0" } @@ -7128,75 +6641,110 @@ "version": "4.0.2", "resolved": "https://registry.npmjs.org/postcss-normalize-display-values/-/postcss-normalize-display-values-4.0.2.tgz", "integrity": "sha512-3F2jcsaMW7+VtRMAqf/3m4cPFhPD3EFRgNs18u+k3lTJJlVe7d0YPO+bnwqo2xg8YiRpDXJI2u8A0wqJxMsQuQ==", - "dev": true, "requires": { "cssnano-util-get-match": "^4.0.0", "postcss": "^7.0.0", "postcss-value-parser": "^3.0.0" + }, + "dependencies": { + "postcss-value-parser": { + "version": "3.3.1", + "resolved": "https://registry.npmjs.org/postcss-value-parser/-/postcss-value-parser-3.3.1.tgz", + "integrity": "sha512-pISE66AbVkp4fDQ7VHBwRNXzAAKJjw4Vw7nWI/+Q3vuly7SNfgYXvm6i5IgFylHGK5sP/xHAbB7N49OS4gWNyQ==" + } } }, "postcss-normalize-positions": { "version": "4.0.2", "resolved": "https://registry.npmjs.org/postcss-normalize-positions/-/postcss-normalize-positions-4.0.2.tgz", "integrity": "sha512-Dlf3/9AxpxE+NF1fJxYDeggi5WwV35MXGFnnoccP/9qDtFrTArZ0D0R+iKcg5WsUd8nUYMIl8yXDCtcrT8JrdA==", - "dev": true, "requires": { "cssnano-util-get-arguments": "^4.0.0", "has": "^1.0.0", "postcss": "^7.0.0", "postcss-value-parser": "^3.0.0" + }, + "dependencies": { + "postcss-value-parser": { + "version": "3.3.1", + "resolved": "https://registry.npmjs.org/postcss-value-parser/-/postcss-value-parser-3.3.1.tgz", + "integrity": "sha512-pISE66AbVkp4fDQ7VHBwRNXzAAKJjw4Vw7nWI/+Q3vuly7SNfgYXvm6i5IgFylHGK5sP/xHAbB7N49OS4gWNyQ==" + } } }, "postcss-normalize-repeat-style": { "version": "4.0.2", "resolved": "https://registry.npmjs.org/postcss-normalize-repeat-style/-/postcss-normalize-repeat-style-4.0.2.tgz", "integrity": "sha512-qvigdYYMpSuoFs3Is/f5nHdRLJN/ITA7huIoCyqqENJe9PvPmLhNLMu7QTjPdtnVf6OcYYO5SHonx4+fbJE1+Q==", - "dev": true, "requires": { "cssnano-util-get-arguments": "^4.0.0", "cssnano-util-get-match": "^4.0.0", "postcss": "^7.0.0", "postcss-value-parser": "^3.0.0" + }, + "dependencies": { + "postcss-value-parser": { + "version": "3.3.1", + "resolved": "https://registry.npmjs.org/postcss-value-parser/-/postcss-value-parser-3.3.1.tgz", + "integrity": "sha512-pISE66AbVkp4fDQ7VHBwRNXzAAKJjw4Vw7nWI/+Q3vuly7SNfgYXvm6i5IgFylHGK5sP/xHAbB7N49OS4gWNyQ==" + } } }, "postcss-normalize-string": { "version": "4.0.2", "resolved": "https://registry.npmjs.org/postcss-normalize-string/-/postcss-normalize-string-4.0.2.tgz", "integrity": "sha512-RrERod97Dnwqq49WNz8qo66ps0swYZDSb6rM57kN2J+aoyEAJfZ6bMx0sx/F9TIEX0xthPGCmeyiam/jXif0eA==", - "dev": true, "requires": { "has": "^1.0.0", "postcss": "^7.0.0", "postcss-value-parser": "^3.0.0" + }, + "dependencies": { + "postcss-value-parser": { + "version": "3.3.1", + "resolved": "https://registry.npmjs.org/postcss-value-parser/-/postcss-value-parser-3.3.1.tgz", + "integrity": "sha512-pISE66AbVkp4fDQ7VHBwRNXzAAKJjw4Vw7nWI/+Q3vuly7SNfgYXvm6i5IgFylHGK5sP/xHAbB7N49OS4gWNyQ==" + } } }, "postcss-normalize-timing-functions": { "version": "4.0.2", "resolved": "https://registry.npmjs.org/postcss-normalize-timing-functions/-/postcss-normalize-timing-functions-4.0.2.tgz", "integrity": "sha512-acwJY95edP762e++00Ehq9L4sZCEcOPyaHwoaFOhIwWCDfik6YvqsYNxckee65JHLKzuNSSmAdxwD2Cud1Z54A==", - "dev": true, "requires": { "cssnano-util-get-match": "^4.0.0", "postcss": "^7.0.0", "postcss-value-parser": "^3.0.0" + }, + "dependencies": { + "postcss-value-parser": { + "version": "3.3.1", + "resolved": "https://registry.npmjs.org/postcss-value-parser/-/postcss-value-parser-3.3.1.tgz", + "integrity": "sha512-pISE66AbVkp4fDQ7VHBwRNXzAAKJjw4Vw7nWI/+Q3vuly7SNfgYXvm6i5IgFylHGK5sP/xHAbB7N49OS4gWNyQ==" + } } }, "postcss-normalize-unicode": { "version": "4.0.1", "resolved": "https://registry.npmjs.org/postcss-normalize-unicode/-/postcss-normalize-unicode-4.0.1.tgz", "integrity": "sha512-od18Uq2wCYn+vZ/qCOeutvHjB5jm57ToxRaMeNuf0nWVHaP9Hua56QyMF6fs/4FSUnVIw0CBPsU0K4LnBPwYwg==", - "dev": true, "requires": { "browserslist": "^4.0.0", "postcss": "^7.0.0", "postcss-value-parser": "^3.0.0" + }, + "dependencies": { + "postcss-value-parser": { + "version": "3.3.1", + "resolved": "https://registry.npmjs.org/postcss-value-parser/-/postcss-value-parser-3.3.1.tgz", + "integrity": "sha512-pISE66AbVkp4fDQ7VHBwRNXzAAKJjw4Vw7nWI/+Q3vuly7SNfgYXvm6i5IgFylHGK5sP/xHAbB7N49OS4gWNyQ==" + } } }, "postcss-normalize-url": { "version": "4.0.1", "resolved": "https://registry.npmjs.org/postcss-normalize-url/-/postcss-normalize-url-4.0.1.tgz", "integrity": "sha512-p5oVaF4+IHwu7VpMan/SSpmpYxcJMtkGppYf0VbdH5B6hN8YNmVyJLuY9FmLQTzY3fag5ESUUHDqM+heid0UVA==", - "dev": true, "requires": { "is-absolute-url": "^2.0.0", "normalize-url": "^3.0.0", @@ -7207,8 +6755,12 @@ "normalize-url": { "version": "3.3.0", "resolved": "https://registry.npmjs.org/normalize-url/-/normalize-url-3.3.0.tgz", - "integrity": "sha512-U+JJi7duF1o+u2pynbp2zXDW2/PADgC30f0GsHZtRh+HOcXHnw137TrNlyxxRvWW5fjKd3bcLHPxofWuCjaeZg==", - "dev": true + "integrity": "sha512-U+JJi7duF1o+u2pynbp2zXDW2/PADgC30f0GsHZtRh+HOcXHnw137TrNlyxxRvWW5fjKd3bcLHPxofWuCjaeZg==" + }, + "postcss-value-parser": { + "version": "3.3.1", + "resolved": "https://registry.npmjs.org/postcss-value-parser/-/postcss-value-parser-3.3.1.tgz", + "integrity": "sha512-pISE66AbVkp4fDQ7VHBwRNXzAAKJjw4Vw7nWI/+Q3vuly7SNfgYXvm6i5IgFylHGK5sP/xHAbB7N49OS4gWNyQ==" } } }, @@ -7216,28 +6768,39 @@ "version": "4.0.2", "resolved": "https://registry.npmjs.org/postcss-normalize-whitespace/-/postcss-normalize-whitespace-4.0.2.tgz", "integrity": "sha512-tO8QIgrsI3p95r8fyqKV+ufKlSHh9hMJqACqbv2XknufqEDhDvbguXGBBqxw9nsQoXWf0qOqppziKJKHMD4GtA==", - "dev": true, "requires": { "postcss": "^7.0.0", "postcss-value-parser": "^3.0.0" + }, + "dependencies": { + "postcss-value-parser": { + "version": "3.3.1", + "resolved": "https://registry.npmjs.org/postcss-value-parser/-/postcss-value-parser-3.3.1.tgz", + "integrity": "sha512-pISE66AbVkp4fDQ7VHBwRNXzAAKJjw4Vw7nWI/+Q3vuly7SNfgYXvm6i5IgFylHGK5sP/xHAbB7N49OS4gWNyQ==" + } } }, "postcss-ordered-values": { "version": "4.1.2", "resolved": "https://registry.npmjs.org/postcss-ordered-values/-/postcss-ordered-values-4.1.2.tgz", "integrity": "sha512-2fCObh5UanxvSxeXrtLtlwVThBvHn6MQcu4ksNT2tsaV2Fg76R2CV98W7wNSlX+5/pFwEyaDwKLLoEV7uRybAw==", - "dev": true, "requires": { "cssnano-util-get-arguments": "^4.0.0", "postcss": "^7.0.0", "postcss-value-parser": "^3.0.0" + }, + "dependencies": { + "postcss-value-parser": { + "version": "3.3.1", + "resolved": "https://registry.npmjs.org/postcss-value-parser/-/postcss-value-parser-3.3.1.tgz", + "integrity": "sha512-pISE66AbVkp4fDQ7VHBwRNXzAAKJjw4Vw7nWI/+Q3vuly7SNfgYXvm6i5IgFylHGK5sP/xHAbB7N49OS4gWNyQ==" + } } }, "postcss-reduce-initial": { "version": "4.0.3", "resolved": "https://registry.npmjs.org/postcss-reduce-initial/-/postcss-reduce-initial-4.0.3.tgz", "integrity": "sha512-gKWmR5aUulSjbzOfD9AlJiHCGH6AEVLaM0AV+aSioxUDd16qXP1PCh8d1/BGVvpdWn8k/HiK7n6TjeoXN1F7DA==", - "dev": true, "requires": { "browserslist": "^4.0.0", "caniuse-api": "^3.0.0", @@ -7249,19 +6812,24 @@ "version": "4.0.2", "resolved": "https://registry.npmjs.org/postcss-reduce-transforms/-/postcss-reduce-transforms-4.0.2.tgz", "integrity": "sha512-EEVig1Q2QJ4ELpJXMZR8Vt5DQx8/mo+dGWSR7vWXqcob2gQLyQGsionYcGKATXvQzMPn6DSN1vTN7yFximdIAg==", - "dev": true, "requires": { "cssnano-util-get-match": "^4.0.0", "has": "^1.0.0", "postcss": "^7.0.0", "postcss-value-parser": "^3.0.0" + }, + "dependencies": { + "postcss-value-parser": { + "version": "3.3.1", + "resolved": "https://registry.npmjs.org/postcss-value-parser/-/postcss-value-parser-3.3.1.tgz", + "integrity": "sha512-pISE66AbVkp4fDQ7VHBwRNXzAAKJjw4Vw7nWI/+Q3vuly7SNfgYXvm6i5IgFylHGK5sP/xHAbB7N49OS4gWNyQ==" + } } }, "postcss-safe-parser": { "version": "4.0.1", "resolved": "https://registry.npmjs.org/postcss-safe-parser/-/postcss-safe-parser-4.0.1.tgz", "integrity": "sha512-xZsFA3uX8MO3yAda03QrG3/Eg1LN3EPfjjf07vke/46HERLZyHrTsQ9E1r1w1W//fWEhtYNndo2hQplN2cVpCQ==", - "dev": true, "requires": { "postcss": "^7.0.0" } @@ -7270,7 +6838,6 @@ "version": "6.0.2", "resolved": "https://registry.npmjs.org/postcss-selector-parser/-/postcss-selector-parser-6.0.2.tgz", "integrity": "sha512-36P2QR59jDTOAiIkqEprfJDsoNrvwFei3eCqKd1Y0tUsBimsq39BLp7RD+JWny3WgB1zGhJX8XVePwm9k4wdBg==", - "dev": true, "requires": { "cssesc": "^3.0.0", "indexes-of": "^1.0.1", @@ -7281,19 +6848,24 @@ "version": "4.0.2", "resolved": "https://registry.npmjs.org/postcss-svgo/-/postcss-svgo-4.0.2.tgz", "integrity": "sha512-C6wyjo3VwFm0QgBy+Fu7gCYOkCmgmClghO+pjcxvrcBKtiKt0uCF+hvbMO1fyv5BMImRK90SMb+dwUnfbGd+jw==", - "dev": true, "requires": { "is-svg": "^3.0.0", "postcss": "^7.0.0", "postcss-value-parser": "^3.0.0", "svgo": "^1.0.0" + }, + "dependencies": { + "postcss-value-parser": { + "version": "3.3.1", + "resolved": "https://registry.npmjs.org/postcss-value-parser/-/postcss-value-parser-3.3.1.tgz", + "integrity": "sha512-pISE66AbVkp4fDQ7VHBwRNXzAAKJjw4Vw7nWI/+Q3vuly7SNfgYXvm6i5IgFylHGK5sP/xHAbB7N49OS4gWNyQ==" + } } }, "postcss-unique-selectors": { "version": "4.0.1", "resolved": "https://registry.npmjs.org/postcss-unique-selectors/-/postcss-unique-selectors-4.0.1.tgz", "integrity": "sha512-+JanVaryLo9QwZjKrmJgkI4Fn8SBgRO6WXQBJi7KiAVPlmxikB5Jzc4EvXMT2H0/m0RjrVVm9rGNhZddm/8Spg==", - "dev": true, "requires": { "alphanum-sort": "^1.0.0", "postcss": "^7.0.0", @@ -7301,28 +6873,24 @@ } }, "postcss-value-parser": { - "version": "3.3.1", - "resolved": "https://registry.npmjs.org/postcss-value-parser/-/postcss-value-parser-3.3.1.tgz", - "integrity": "sha512-pISE66AbVkp4fDQ7VHBwRNXzAAKJjw4Vw7nWI/+Q3vuly7SNfgYXvm6i5IgFylHGK5sP/xHAbB7N49OS4gWNyQ==", - "dev": true + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/postcss-value-parser/-/postcss-value-parser-4.0.2.tgz", + "integrity": "sha512-LmeoohTpp/K4UiyQCwuGWlONxXamGzCMtFxLq4W1nZVGIQLYvMCJx3yAF9qyyuFpflABI9yVdtJAqbihOsCsJQ==" }, "prepend-http": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/prepend-http/-/prepend-http-2.0.0.tgz", - "integrity": "sha1-6SQ0v6XqjBn0HN/UAddBo8gZ2Jc=", - "dev": true + "integrity": "sha1-6SQ0v6XqjBn0HN/UAddBo8gZ2Jc=" }, "prettier": { "version": "1.16.3", "resolved": "https://registry.npmjs.org/prettier/-/prettier-1.16.3.tgz", - "integrity": "sha512-kn/GU6SMRYPxUakNXhpP0EedT/KmaPzr0H5lIsDogrykbaxOpOfAFfk5XA7DZrJyMAv1wlMV3CPcZruGXVVUZw==", - "dev": true + "integrity": "sha512-kn/GU6SMRYPxUakNXhpP0EedT/KmaPzr0H5lIsDogrykbaxOpOfAFfk5XA7DZrJyMAv1wlMV3CPcZruGXVVUZw==" }, "pretty-error": { "version": "2.1.1", "resolved": "https://registry.npmjs.org/pretty-error/-/pretty-error-2.1.1.tgz", "integrity": "sha1-X0+HyPkeWuPzuoerTPXgOxoX8aM=", - "dev": true, "requires": { "renderkid": "^2.0.1", "utila": "~0.4" @@ -7331,14 +6899,12 @@ "pretty-time": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/pretty-time/-/pretty-time-1.1.0.tgz", - "integrity": "sha512-28iF6xPQrP8Oa6uxE6a1biz+lWeTOAPKggvjB8HAs6nVMKZwf5bG++632Dx614hIWgUPkgivRfG+a8uAXGTIbA==", - "dev": true + "integrity": "sha512-28iF6xPQrP8Oa6uxE6a1biz+lWeTOAPKggvjB8HAs6nVMKZwf5bG++632Dx614hIWgUPkgivRfG+a8uAXGTIbA==" }, "prismjs": { - "version": "1.16.0", - "resolved": "https://registry.npmjs.org/prismjs/-/prismjs-1.16.0.tgz", - "integrity": "sha512-OA4MKxjFZHSvZcisLGe14THYsug/nF6O1f0pAJc0KN0wTyAcLqmsbE+lTGKSpyh+9pEW57+k6pg2AfYR+coyHA==", - "dev": true, + "version": "1.17.1", + "resolved": "https://registry.npmjs.org/prismjs/-/prismjs-1.17.1.tgz", + "integrity": "sha512-PrEDJAFdUGbOP6xK/UsfkC5ghJsPJviKgnQOoxaDbBjwc8op68Quupwt1DeAFoG8GImPhiKXAvvsH7wDSLsu1Q==", "requires": { "clipboard": "^2.0.0" } @@ -7346,32 +6912,35 @@ "private": { "version": "0.1.8", "resolved": "https://registry.npmjs.org/private/-/private-0.1.8.tgz", - "integrity": "sha512-VvivMrbvd2nKkiG38qjULzlc+4Vx4wm/whI9pQD35YrARNnhxeiRktSOhSukRLFNlzg6Br/cJPet5J/u19r/mg==", - "dev": true + "integrity": "sha512-VvivMrbvd2nKkiG38qjULzlc+4Vx4wm/whI9pQD35YrARNnhxeiRktSOhSukRLFNlzg6Br/cJPet5J/u19r/mg==" }, "process": { "version": "0.11.10", "resolved": "https://registry.npmjs.org/process/-/process-0.11.10.tgz", - "integrity": "sha1-czIwDoQBYb2j5podHZGn1LwW8YI=", - "dev": true + "integrity": "sha1-czIwDoQBYb2j5podHZGn1LwW8YI=" }, "process-nextick-args": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-2.0.1.tgz", - "integrity": "sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag==", - "dev": true + "integrity": "sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag==" + }, + "promise": { + "version": "7.3.1", + "resolved": "https://registry.npmjs.org/promise/-/promise-7.3.1.tgz", + "integrity": "sha512-nolQXZ/4L+bP/UGlkfaIujX9BKxGwmQ9OT4mOt5yvy8iK1h3wqTEJCijzGANTCCl9nWjY41juyAn2K3Q1hLLTg==", + "requires": { + "asap": "~2.0.3" + } }, "promise-inflight": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/promise-inflight/-/promise-inflight-1.0.1.tgz", - "integrity": "sha1-mEcocL8igTL8vdhoEputEsPAKeM=", - "dev": true + "integrity": "sha1-mEcocL8igTL8vdhoEputEsPAKeM=" }, "proxy-addr": { "version": "2.0.5", "resolved": "https://registry.npmjs.org/proxy-addr/-/proxy-addr-2.0.5.tgz", "integrity": "sha512-t/7RxHXPH6cJtP0pRG6smSr9QJidhB+3kXu0KgXnbGYMgzEnUxRQ4/LDdfOwZEMyIh3/xHb8PX3t+lfL9z+YVQ==", - "dev": true, "requires": { "forwarded": "~0.1.2", "ipaddr.js": "1.9.0" @@ -7380,26 +6949,22 @@ "prr": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/prr/-/prr-1.0.1.tgz", - "integrity": "sha1-0/wRS6BplaRexok/SEzrHXj19HY=", - "dev": true + "integrity": "sha1-0/wRS6BplaRexok/SEzrHXj19HY=" }, "pseudomap": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/pseudomap/-/pseudomap-1.0.2.tgz", - "integrity": "sha1-8FKijacOYYkX7wqKw0wa5aaChrM=", - "dev": true + "integrity": "sha1-8FKijacOYYkX7wqKw0wa5aaChrM=" }, "psl": { - "version": "1.1.33", - "resolved": "https://registry.npmjs.org/psl/-/psl-1.1.33.tgz", - "integrity": "sha512-LTDP2uSrsc7XCb5lO7A8BI1qYxRe/8EqlRvMeEl6rsnYAqDOl8xHR+8lSAIVfrNaSAlTPTNOCgNjWcoUL3AZsw==", - "dev": true + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/psl/-/psl-1.4.0.tgz", + "integrity": "sha512-HZzqCGPecFLyoRj5HLfuDSKYTJkAfB5thKBIkRHtGjWwY7p1dAyveIbXIq4tO0KYfDF2tHqPUgY9SDnGm00uFw==" }, "public-encrypt": { "version": "4.0.3", "resolved": "https://registry.npmjs.org/public-encrypt/-/public-encrypt-4.0.3.tgz", "integrity": "sha512-zVpa8oKZSz5bTMTFClc1fQOnyyEzpl5ozpi1B5YcvBrdohMjH2rfsBtyXcuNuwjsDIXmBYlF2N5FlJYhR29t8Q==", - "dev": true, "requires": { "bn.js": "^4.1.0", "browserify-rsa": "^4.0.0", @@ -7409,11 +6974,132 @@ "safe-buffer": "^5.1.2" } }, + "pug": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/pug/-/pug-2.0.4.tgz", + "integrity": "sha512-XhoaDlvi6NIzL49nu094R2NA6P37ijtgMDuWE+ofekDChvfKnzFal60bhSdiy8y2PBO6fmz3oMEIcfpBVRUdvw==", + "requires": { + "pug-code-gen": "^2.0.2", + "pug-filters": "^3.1.1", + "pug-lexer": "^4.1.0", + "pug-linker": "^3.0.6", + "pug-load": "^2.0.12", + "pug-parser": "^5.0.1", + "pug-runtime": "^2.0.5", + "pug-strip-comments": "^1.0.4" + } + }, + "pug-attrs": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/pug-attrs/-/pug-attrs-2.0.4.tgz", + "integrity": "sha512-TaZ4Z2TWUPDJcV3wjU3RtUXMrd3kM4Wzjbe3EWnSsZPsJ3LDI0F3yCnf2/W7PPFF+edUFQ0HgDL1IoxSz5K8EQ==", + "requires": { + "constantinople": "^3.0.1", + "js-stringify": "^1.0.1", + "pug-runtime": "^2.0.5" + } + }, + "pug-code-gen": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/pug-code-gen/-/pug-code-gen-2.0.2.tgz", + "integrity": "sha512-kROFWv/AHx/9CRgoGJeRSm+4mLWchbgpRzTEn8XCiwwOy6Vh0gAClS8Vh5TEJ9DBjaP8wCjS3J6HKsEsYdvaCw==", + "requires": { + "constantinople": "^3.1.2", + "doctypes": "^1.1.0", + "js-stringify": "^1.0.1", + "pug-attrs": "^2.0.4", + "pug-error": "^1.3.3", + "pug-runtime": "^2.0.5", + "void-elements": "^2.0.1", + "with": "^5.0.0" + } + }, + "pug-error": { + "version": "1.3.3", + "resolved": "https://registry.npmjs.org/pug-error/-/pug-error-1.3.3.tgz", + "integrity": "sha512-qE3YhESP2mRAWMFJgKdtT5D7ckThRScXRwkfo+Erqga7dyJdY3ZquspprMCj/9sJ2ijm5hXFWQE/A3l4poMWiQ==" + }, + "pug-filters": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/pug-filters/-/pug-filters-3.1.1.tgz", + "integrity": "sha512-lFfjNyGEyVWC4BwX0WyvkoWLapI5xHSM3xZJFUhx4JM4XyyRdO8Aucc6pCygnqV2uSgJFaJWW3Ft1wCWSoQkQg==", + "requires": { + "clean-css": "^4.1.11", + "constantinople": "^3.0.1", + "jstransformer": "1.0.0", + "pug-error": "^1.3.3", + "pug-walk": "^1.1.8", + "resolve": "^1.1.6", + "uglify-js": "^2.6.1" + } + }, + "pug-lexer": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/pug-lexer/-/pug-lexer-4.1.0.tgz", + "integrity": "sha512-i55yzEBtjm0mlplW4LoANq7k3S8gDdfC6+LThGEvsK4FuobcKfDAwt6V4jKPH9RtiE3a2Akfg5UpafZ1OksaPA==", + "requires": { + "character-parser": "^2.1.1", + "is-expression": "^3.0.0", + "pug-error": "^1.3.3" + } + }, + "pug-linker": { + "version": "3.0.6", + "resolved": "https://registry.npmjs.org/pug-linker/-/pug-linker-3.0.6.tgz", + "integrity": "sha512-bagfuHttfQOpANGy1Y6NJ+0mNb7dD2MswFG2ZKj22s8g0wVsojpRlqveEQHmgXXcfROB2RT6oqbPYr9EN2ZWzg==", + "requires": { + "pug-error": "^1.3.3", + "pug-walk": "^1.1.8" + } + }, + "pug-load": { + "version": "2.0.12", + "resolved": "https://registry.npmjs.org/pug-load/-/pug-load-2.0.12.tgz", + "integrity": "sha512-UqpgGpyyXRYgJs/X60sE6SIf8UBsmcHYKNaOccyVLEuT6OPBIMo6xMPhoJnqtB3Q3BbO4Z3Bjz5qDsUWh4rXsg==", + "requires": { + "object-assign": "^4.1.0", + "pug-walk": "^1.1.8" + } + }, + "pug-parser": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/pug-parser/-/pug-parser-5.0.1.tgz", + "integrity": "sha512-nGHqK+w07p5/PsPIyzkTQfzlYfuqoiGjaoqHv1LjOv2ZLXmGX1O+4Vcvps+P4LhxZ3drYSljjq4b+Naid126wA==", + "requires": { + "pug-error": "^1.3.3", + "token-stream": "0.0.1" + } + }, + "pug-plain-loader": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/pug-plain-loader/-/pug-plain-loader-1.0.0.tgz", + "integrity": "sha512-mDfq/qvJJ0xdug38mZ1ObW0BQTx9kAHnKqotXC+C00XQkKmsWaMe90JUg/kN4lS6MU7tpVsMZ+rmcnBSPfDtHA==", + "requires": { + "loader-utils": "^1.1.0" + } + }, + "pug-runtime": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/pug-runtime/-/pug-runtime-2.0.5.tgz", + "integrity": "sha512-P+rXKn9un4fQY77wtpcuFyvFaBww7/91f3jHa154qU26qFAnOe6SW1CbIDcxiG5lLK9HazYrMCCuDvNgDQNptw==" + }, + "pug-strip-comments": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/pug-strip-comments/-/pug-strip-comments-1.0.4.tgz", + "integrity": "sha512-i5j/9CS4yFhSxHp5iKPHwigaig/VV9g+FgReLJWWHEHbvKsbqL0oP/K5ubuLco6Wu3Kan5p7u7qk8A4oLLh6vw==", + "requires": { + "pug-error": "^1.3.3" + } + }, + "pug-walk": { + "version": "1.1.8", + "resolved": "https://registry.npmjs.org/pug-walk/-/pug-walk-1.1.8.tgz", + "integrity": "sha512-GMu3M5nUL3fju4/egXwZO0XLi6fW/K3T3VTgFQ14GxNi8btlxgT5qZL//JwZFm/2Fa64J/PNS8AZeys3wiMkVA==" + }, "pump": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/pump/-/pump-3.0.0.tgz", "integrity": "sha512-LwZy+p3SFs1Pytd/jYct4wpv49HiYCqd9Rlc5ZVdk0V+8Yzv6jR5Blk3TRmPL1ft69TxP0IMZGJ+WPFU2BFhww==", - "dev": true, "requires": { "end-of-stream": "^1.1.0", "once": "^1.3.1" @@ -7423,7 +7109,6 @@ "version": "1.5.1", "resolved": "https://registry.npmjs.org/pumpify/-/pumpify-1.5.1.tgz", "integrity": "sha512-oClZI37HvuUJJxSKKrC17bZ9Cu0ZYhEAGPsPUy9KlMUmv9dKX2o77RUmq7f3XjIxbwyGwYzbzQ1L2Ks8sIradQ==", - "dev": true, "requires": { "duplexify": "^3.6.0", "inherits": "^2.0.3", @@ -7434,7 +7119,6 @@ "version": "2.0.1", "resolved": "https://registry.npmjs.org/pump/-/pump-2.0.1.tgz", "integrity": "sha512-ruPMNRkN3MHP1cWJc9OWr+T/xDP0jhXYCLfJcBuX54hhfIBnaQmAUMfDcG4DM5UMWByBbJY69QSphm3jtDKIkA==", - "dev": true, "requires": { "end-of-stream": "^1.1.0", "once": "^1.3.1" @@ -7445,26 +7129,22 @@ "punycode": { "version": "2.1.1", "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.1.1.tgz", - "integrity": "sha512-XRsRjdf+j5ml+y/6GKHPZbrF/8p2Yga0JPtdqTIY2Xe5ohJPD9saDJJLPvp9+NSBprVvevdXZybnj2cv8OEd0A==", - "dev": true + "integrity": "sha512-XRsRjdf+j5ml+y/6GKHPZbrF/8p2Yga0JPtdqTIY2Xe5ohJPD9saDJJLPvp9+NSBprVvevdXZybnj2cv8OEd0A==" }, "q": { "version": "1.5.1", "resolved": "https://registry.npmjs.org/q/-/q-1.5.1.tgz", - "integrity": "sha1-fjL3W0E4EpHQRhHxvxQQmsAGUdc=", - "dev": true + "integrity": "sha1-fjL3W0E4EpHQRhHxvxQQmsAGUdc=" }, "qs": { "version": "6.7.0", "resolved": "https://registry.npmjs.org/qs/-/qs-6.7.0.tgz", - "integrity": "sha512-VCdBRNFTX1fyE7Nb6FYoURo/SPe62QCaAyzJvUjwRaIsc+NePBEniHlvxFmmX56+HZphIGtV0XeCirBtpDrTyQ==", - "dev": true + "integrity": "sha512-VCdBRNFTX1fyE7Nb6FYoURo/SPe62QCaAyzJvUjwRaIsc+NePBEniHlvxFmmX56+HZphIGtV0XeCirBtpDrTyQ==" }, "query-string": { "version": "5.1.1", "resolved": "https://registry.npmjs.org/query-string/-/query-string-5.1.1.tgz", "integrity": "sha512-gjWOsm2SoGlgLEdAGt7a6slVOk9mGiXmPFMqrEhLQ68rhQuBnpfs3+EmlvqKyxnCo9/PPlF+9MtY02S1aFg+Jw==", - "dev": true, "requires": { "decode-uri-component": "^0.2.0", "object-assign": "^4.1.0", @@ -7474,26 +7154,22 @@ "querystring": { "version": "0.2.0", "resolved": "https://registry.npmjs.org/querystring/-/querystring-0.2.0.tgz", - "integrity": "sha1-sgmEkgO7Jd+CDadW50cAWHhSFiA=", - "dev": true + "integrity": "sha1-sgmEkgO7Jd+CDadW50cAWHhSFiA=" }, "querystring-es3": { "version": "0.2.1", "resolved": "https://registry.npmjs.org/querystring-es3/-/querystring-es3-0.2.1.tgz", - "integrity": "sha1-nsYfeQSYdXB9aUFFlv2Qek1xHnM=", - "dev": true + "integrity": "sha1-nsYfeQSYdXB9aUFFlv2Qek1xHnM=" }, "querystringify": { "version": "2.1.1", "resolved": "https://registry.npmjs.org/querystringify/-/querystringify-2.1.1.tgz", - "integrity": "sha512-w7fLxIRCRT7U8Qu53jQnJyPkYZIaR4n5151KMfcJlO/A9397Wxb1amJvROTK6TOnp7PfoAmg/qXiNHI+08jRfA==", - "dev": true + "integrity": "sha512-w7fLxIRCRT7U8Qu53jQnJyPkYZIaR4n5151KMfcJlO/A9397Wxb1amJvROTK6TOnp7PfoAmg/qXiNHI+08jRfA==" }, "randombytes": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/randombytes/-/randombytes-2.1.0.tgz", "integrity": "sha512-vYl3iOX+4CKUWuxGi9Ukhie6fsqXqS9FE2Zaic4tNFD2N2QQaXOMFbuKK4QmDHC0JO6B1Zp41J0LpT0oR68amQ==", - "dev": true, "requires": { "safe-buffer": "^5.1.0" } @@ -7502,7 +7178,6 @@ "version": "1.0.4", "resolved": "https://registry.npmjs.org/randomfill/-/randomfill-1.0.4.tgz", "integrity": "sha512-87lcbR8+MhcWcUiQ+9e+Rwx8MyR2P7qnt15ynUlbm3TU/fjbgz4GsvfSUDTemtCCtVCqb4ZcEFlyPNTh9bBTLw==", - "dev": true, "requires": { "randombytes": "^2.0.5", "safe-buffer": "^5.1.0" @@ -7511,14 +7186,12 @@ "range-parser": { "version": "1.2.1", "resolved": "https://registry.npmjs.org/range-parser/-/range-parser-1.2.1.tgz", - "integrity": "sha512-Hrgsx+orqoygnmhFbKaHE6c296J+HTAQXoxEF6gNupROmmGJRoyzfG3ccAveqCBrwr/2yxQ5BVd/GTl5agOwSg==", - "dev": true + "integrity": "sha512-Hrgsx+orqoygnmhFbKaHE6c296J+HTAQXoxEF6gNupROmmGJRoyzfG3ccAveqCBrwr/2yxQ5BVd/GTl5agOwSg==" }, "raw-body": { "version": "2.4.0", "resolved": "https://registry.npmjs.org/raw-body/-/raw-body-2.4.0.tgz", "integrity": "sha512-4Oz8DUIwdvoa5qMJelxipzi/iJIi40O5cGV1wNYp5hvZP8ZN0T+jiNkL0QepXs+EsQ9XJ8ipEDoiH70ySUJP3Q==", - "dev": true, "requires": { "bytes": "3.1.0", "http-errors": "1.7.2", @@ -7529,8 +7202,7 @@ "bytes": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/bytes/-/bytes-3.1.0.tgz", - "integrity": "sha512-zauLjrfCG+xvoyaqLoV8bLVXXNGC4JqlxFCutSDWA6fJrTo2ZuvLYTqZ7aHBLZSMOopbzwv8f+wZcVzfVTI2Dg==", - "dev": true + "integrity": "sha512-zauLjrfCG+xvoyaqLoV8bLVXXNGC4JqlxFCutSDWA6fJrTo2ZuvLYTqZ7aHBLZSMOopbzwv8f+wZcVzfVTI2Dg==" } } }, @@ -7538,7 +7210,6 @@ "version": "2.3.6", "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.6.tgz", "integrity": "sha512-tQtKA9WIAhBF3+VLAseyMqZeBjW0AHJoxOtYqSUZNJxauErmLbVm2FW1y+J/YA9dUrAC39ITejlZWhVIwawkKw==", - "dev": true, "requires": { "core-util-is": "~1.0.0", "inherits": "~2.0.3", @@ -7553,7 +7224,6 @@ "version": "2.2.1", "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-2.2.1.tgz", "integrity": "sha512-1JU/8q+VgFZyxwrJ+SVIOsh+KywWGpds3NTqikiKpDMZWScmAYyKIgqkO+ARvNWJfXeXR1zxz7aHF4u4CyH6vQ==", - "dev": true, "requires": { "graceful-fs": "^4.1.11", "micromatch": "^3.1.10", @@ -7564,7 +7234,6 @@ "version": "1.0.2", "resolved": "https://registry.npmjs.org/reduce/-/reduce-1.0.2.tgz", "integrity": "sha512-xX7Fxke/oHO5IfZSk77lvPa/7bjMh9BuCk4OOoX5XTXrM7s0Z+MkPfSDfz0q7r91BhhGSs8gii/VEN/7zhCPpQ==", - "dev": true, "requires": { "object-keys": "^1.1.0" } @@ -7572,29 +7241,25 @@ "regenerate": { "version": "1.4.0", "resolved": "https://registry.npmjs.org/regenerate/-/regenerate-1.4.0.tgz", - "integrity": "sha512-1G6jJVDWrt0rK99kBjvEtziZNCICAuvIPkSiUFIQxVP06RCVpq3dmDo2oi6ABpYaDYaTRr67BEhL8r1wgEZZKg==", - "dev": true + "integrity": "sha512-1G6jJVDWrt0rK99kBjvEtziZNCICAuvIPkSiUFIQxVP06RCVpq3dmDo2oi6ABpYaDYaTRr67BEhL8r1wgEZZKg==" }, "regenerate-unicode-properties": { "version": "8.1.0", "resolved": "https://registry.npmjs.org/regenerate-unicode-properties/-/regenerate-unicode-properties-8.1.0.tgz", "integrity": "sha512-LGZzkgtLY79GeXLm8Dp0BVLdQlWICzBnJz/ipWUgo59qBaZ+BHtq51P2q1uVZlppMuUAT37SDk39qUbjTWB7bA==", - "dev": true, "requires": { "regenerate": "^1.4.0" } }, "regenerator-runtime": { - "version": "0.13.2", - "resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.13.2.tgz", - "integrity": "sha512-S/TQAZJO+D3m9xeN1WTI8dLKBBiRgXBlTJvbWjCThHWZj9EvHK70Ff50/tYj2J/fvBY6JtFVwRuazHN2E7M9BA==", - "dev": true + "version": "0.11.1", + "resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.11.1.tgz", + "integrity": "sha512-MguG95oij0fC3QV3URf4V2SDYGJhJnJGqvIIgdECeODCT98wSWDAJ94SSuVpYQUoTcGUIL6L4yNB7j1DFFHSBg==" }, "regenerator-transform": { - "version": "0.14.0", - "resolved": "https://registry.npmjs.org/regenerator-transform/-/regenerator-transform-0.14.0.tgz", - "integrity": "sha512-rtOelq4Cawlbmq9xuMR5gdFmv7ku/sFoB7sRiywx7aq53bc52b4j6zvH7Te1Vt/X2YveDKnCGUbioieU7FEL3w==", - "dev": true, + "version": "0.14.1", + "resolved": "https://registry.npmjs.org/regenerator-transform/-/regenerator-transform-0.14.1.tgz", + "integrity": "sha512-flVuee02C3FKRISbxhXl9mGzdbWUVHubl1SMaknjxkFB1/iqpJhArQUvRxOOPEc/9tAiX0BaQ28FJH10E4isSQ==", "requires": { "private": "^0.1.6" } @@ -7603,26 +7268,26 @@ "version": "1.0.2", "resolved": "https://registry.npmjs.org/regex-not/-/regex-not-1.0.2.tgz", "integrity": "sha512-J6SDjUgDxQj5NusnOtdFxDwN/+HWykR8GELwctJ7mdqhcyy1xEc4SRFHUXvxTp661YaVKAjfRLZ9cCqS6tn32A==", - "dev": true, "requires": { "extend-shallow": "^3.0.2", "safe-regex": "^1.1.0" } }, - "regexp-tree": { - "version": "0.1.10", - "resolved": "https://registry.npmjs.org/regexp-tree/-/regexp-tree-0.1.10.tgz", - "integrity": "sha512-K1qVSbcedffwuIslMwpe6vGlj+ZXRnGkvjAtFHfDZZZuEdA/h0dxljAPu9vhUo6Rrx2U2AwJ+nSQ6hK+lrP5MQ==", - "dev": true + "regexp.prototype.flags": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/regexp.prototype.flags/-/regexp.prototype.flags-1.2.0.tgz", + "integrity": "sha512-ztaw4M1VqgMwl9HlPpOuiYgItcHlunW0He2fE6eNfT6E/CF2FtYi9ofOYe4mKntstYk0Fyh/rDRBdS3AnxjlrA==", + "requires": { + "define-properties": "^1.1.2" + } }, "regexpu-core": { - "version": "4.5.4", - "resolved": "https://registry.npmjs.org/regexpu-core/-/regexpu-core-4.5.4.tgz", - "integrity": "sha512-BtizvGtFQKGPUcTy56o3nk1bGRp4SZOTYrDtGNlqCQufptV5IkkLN6Emw+yunAJjzf+C9FQFtvq7IoA3+oMYHQ==", - "dev": true, + "version": "4.6.0", + "resolved": "https://registry.npmjs.org/regexpu-core/-/regexpu-core-4.6.0.tgz", + "integrity": "sha512-YlVaefl8P5BnFYOITTNzDvan1ulLOiXJzCNZxduTIosN17b87h3bvG9yHMoHaRuo88H4mQ06Aodj5VtYGGGiTg==", "requires": { "regenerate": "^1.4.0", - "regenerate-unicode-properties": "^8.0.2", + "regenerate-unicode-properties": "^8.1.0", "regjsgen": "^0.5.0", "regjsparser": "^0.6.0", "unicode-match-property-ecmascript": "^1.0.4", @@ -7630,16 +7295,14 @@ } }, "regjsgen": { - "version": "0.5.0", - "resolved": "https://registry.npmjs.org/regjsgen/-/regjsgen-0.5.0.tgz", - "integrity": "sha512-RnIrLhrXCX5ow/E5/Mh2O4e/oa1/jW0eaBKTSy3LaCj+M3Bqvm97GWDp2yUtzIs4LEn65zR2yiYGFqb2ApnzDA==", - "dev": true + "version": "0.5.1", + "resolved": "https://registry.npmjs.org/regjsgen/-/regjsgen-0.5.1.tgz", + "integrity": "sha512-5qxzGZjDs9w4tzT3TPhCJqWdCc3RLYwy9J2NB0nm5Lz+S273lvWcpjaTGHsT1dc6Hhfq41uSEOw8wBmxrKOuyg==" }, "regjsparser": { "version": "0.6.0", "resolved": "https://registry.npmjs.org/regjsparser/-/regjsparser-0.6.0.tgz", "integrity": "sha512-RQ7YyokLiQBomUJuUG8iGVvkgOLxwyZM8k6d3q5SAXpg4r5TZJZigKFvC6PpD+qQ98bCDC5YelPeA3EucDoNeQ==", - "dev": true, "requires": { "jsesc": "~0.5.0" }, @@ -7647,28 +7310,24 @@ "jsesc": { "version": "0.5.0", "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-0.5.0.tgz", - "integrity": "sha1-597mbjXW/Bb3EP6R1c9p9w8IkR0=", - "dev": true + "integrity": "sha1-597mbjXW/Bb3EP6R1c9p9w8IkR0=" } } }, "relateurl": { "version": "0.2.7", "resolved": "https://registry.npmjs.org/relateurl/-/relateurl-0.2.7.tgz", - "integrity": "sha1-VNvzd+UUQKypCkzSdGANP/LYiKk=", - "dev": true + "integrity": "sha1-VNvzd+UUQKypCkzSdGANP/LYiKk=" }, "remove-trailing-separator": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/remove-trailing-separator/-/remove-trailing-separator-1.1.0.tgz", - "integrity": "sha1-wkvOKig62tW8P1jg1IJJuSN52O8=", - "dev": true + "integrity": "sha1-wkvOKig62tW8P1jg1IJJuSN52O8=" }, "renderkid": { "version": "2.0.3", "resolved": "https://registry.npmjs.org/renderkid/-/renderkid-2.0.3.tgz", "integrity": "sha512-z8CLQp7EZBPCwCnncgf9C4XAi3WR0dv+uWu/PjIyhhAb5d6IJ/QZqlHFprHeKT+59//V6BNUsLbvN8+2LarxGA==", - "dev": true, "requires": { "css-select": "^1.1.0", "dom-converter": "^0.2", @@ -7681,7 +7340,6 @@ "version": "1.2.0", "resolved": "https://registry.npmjs.org/css-select/-/css-select-1.2.0.tgz", "integrity": "sha1-KzoRBTnFNV8c2NMUYj6HCxIeyFg=", - "dev": true, "requires": { "boolbase": "~1.0.0", "css-what": "2.1", @@ -7693,7 +7351,6 @@ "version": "1.5.1", "resolved": "https://registry.npmjs.org/domutils/-/domutils-1.5.1.tgz", "integrity": "sha1-3NhIiib1Y9YQeeSMn3t+Mjc2gs8=", - "dev": true, "requires": { "dom-serializer": "0", "domelementtype": "1" @@ -7704,20 +7361,17 @@ "repeat-element": { "version": "1.1.3", "resolved": "https://registry.npmjs.org/repeat-element/-/repeat-element-1.1.3.tgz", - "integrity": "sha512-ahGq0ZnV5m5XtZLMb+vP76kcAM5nkLqk0lpqAuojSKGgQtn4eRi4ZZGm2olo2zKFH+sMsWaqOCW1dqAnOru72g==", - "dev": true + "integrity": "sha512-ahGq0ZnV5m5XtZLMb+vP76kcAM5nkLqk0lpqAuojSKGgQtn4eRi4ZZGm2olo2zKFH+sMsWaqOCW1dqAnOru72g==" }, "repeat-string": { "version": "1.6.1", "resolved": "https://registry.npmjs.org/repeat-string/-/repeat-string-1.6.1.tgz", - "integrity": "sha1-jcrkcOHIirwtYA//Sndihtp15jc=", - "dev": true + "integrity": "sha1-jcrkcOHIirwtYA//Sndihtp15jc=" }, "request": { "version": "2.88.0", "resolved": "https://registry.npmjs.org/request/-/request-2.88.0.tgz", "integrity": "sha512-NAqBSrijGLZdM0WZNsInLJpkJokL72XYjUpnB0iwsRgxh7dB6COrHnTBNwN0E+lHDAJzu7kLAkDeY08z2/A0hg==", - "dev": true, "requires": { "aws-sign2": "~0.7.0", "aws4": "^1.8.0", @@ -7744,40 +7398,34 @@ "qs": { "version": "6.5.2", "resolved": "https://registry.npmjs.org/qs/-/qs-6.5.2.tgz", - "integrity": "sha512-N5ZAX4/LxJmF+7wN74pUD6qAh9/wnvdQcjq9TZjevvXzSUo7bfmw91saqMjzGS2xq91/odN2dW/WOl7qQHNDGA==", - "dev": true + "integrity": "sha512-N5ZAX4/LxJmF+7wN74pUD6qAh9/wnvdQcjq9TZjevvXzSUo7bfmw91saqMjzGS2xq91/odN2dW/WOl7qQHNDGA==" } } }, "require-directory": { "version": "2.1.1", "resolved": "https://registry.npmjs.org/require-directory/-/require-directory-2.1.1.tgz", - "integrity": "sha1-jGStX9MNqxyXbiNE/+f3kqam30I=", - "dev": true + "integrity": "sha1-jGStX9MNqxyXbiNE/+f3kqam30I=" }, "require-main-filename": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/require-main-filename/-/require-main-filename-1.0.1.tgz", - "integrity": "sha1-l/cXtp1IeE9fUmpsWqj/3aBVpNE=", - "dev": true + "integrity": "sha1-l/cXtp1IeE9fUmpsWqj/3aBVpNE=" }, "requires-port": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/requires-port/-/requires-port-1.0.0.tgz", - "integrity": "sha1-kl0mAdOaxIXgkc8NpcbmlNw9yv8=", - "dev": true + "integrity": "sha1-kl0mAdOaxIXgkc8NpcbmlNw9yv8=" }, "reselect": { "version": "3.0.1", "resolved": "https://registry.npmjs.org/reselect/-/reselect-3.0.1.tgz", - "integrity": "sha1-79qpjqdFEyTQkrKyFjpqHXqaIUc=", - "dev": true + "integrity": "sha1-79qpjqdFEyTQkrKyFjpqHXqaIUc=" }, "resolve": { - "version": "1.11.1", - "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.11.1.tgz", - "integrity": "sha512-vIpgF6wfuJOZI7KKKSP+HmiKggadPQAdsp5HiC1mvqnfp0gF1vdwgBWZIdrVft9pgqoMFQN+R7BSWZiBxx+BBw==", - "dev": true, + "version": "1.12.0", + "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.12.0.tgz", + "integrity": "sha512-B/dOmuoAik5bKcD6s6nXDCjzUKnaDvdkRyAk6rsmsKLipWj4797iothd7jmmUhWTfinVMU+wc56rYKsit2Qy4w==", "requires": { "path-parse": "^1.0.6" } @@ -7786,7 +7434,6 @@ "version": "2.0.0", "resolved": "https://registry.npmjs.org/resolve-cwd/-/resolve-cwd-2.0.0.tgz", "integrity": "sha1-AKn3OHVW4nA46uIyyqNypqWbZlo=", - "dev": true, "requires": { "resolve-from": "^3.0.0" } @@ -7794,44 +7441,45 @@ "resolve-from": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-3.0.0.tgz", - "integrity": "sha1-six699nWiBvItuZTM17rywoYh0g=", - "dev": true + "integrity": "sha1-six699nWiBvItuZTM17rywoYh0g=" }, "resolve-url": { "version": "0.2.1", "resolved": "https://registry.npmjs.org/resolve-url/-/resolve-url-0.2.1.tgz", - "integrity": "sha1-LGN/53yJOv0qZj/iGqkIAGjiBSo=", - "dev": true + "integrity": "sha1-LGN/53yJOv0qZj/iGqkIAGjiBSo=" }, "ret": { "version": "0.1.15", "resolved": "https://registry.npmjs.org/ret/-/ret-0.1.15.tgz", - "integrity": "sha512-TTlYpa+OL+vMMNG24xSlQGEJ3B/RzEfUlLct7b5G/ytav+wPrplCpVMFuwzXbkecJrb6IYo1iFb0S9v37754mg==", - "dev": true + "integrity": "sha512-TTlYpa+OL+vMMNG24xSlQGEJ3B/RzEfUlLct7b5G/ytav+wPrplCpVMFuwzXbkecJrb6IYo1iFb0S9v37754mg==" }, "retry": { "version": "0.12.0", "resolved": "https://registry.npmjs.org/retry/-/retry-0.12.0.tgz", - "integrity": "sha1-G0KmJmoh8HQh0bC1S33BZ7AcATs=", - "dev": true + "integrity": "sha1-G0KmJmoh8HQh0bC1S33BZ7AcATs=" }, "rgb-regex": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/rgb-regex/-/rgb-regex-1.0.1.tgz", - "integrity": "sha1-wODWiC3w4jviVKR16O3UGRX+rrE=", - "dev": true + "integrity": "sha1-wODWiC3w4jviVKR16O3UGRX+rrE=" }, "rgba-regex": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/rgba-regex/-/rgba-regex-1.0.0.tgz", - "integrity": "sha1-QzdOLiyglosO8VI0YLfXMP8i7rM=", - "dev": true + "integrity": "sha1-QzdOLiyglosO8VI0YLfXMP8i7rM=" + }, + "right-align": { + "version": "0.1.3", + "resolved": "https://registry.npmjs.org/right-align/-/right-align-0.1.3.tgz", + "integrity": "sha1-YTObci/mo1FWiSENJOFMlhSGE+8=", + "requires": { + "align-text": "^0.1.1" + } }, "rimraf": { - "version": "2.6.3", - "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.6.3.tgz", - "integrity": "sha512-mwqeW5XsA2qAejG46gYdENaxXjx9onRNCfn7L0duuP4hCuTIi/QO7PDK07KJfp1d+izWPrzEJDcSqBa0OZQriA==", - "dev": true, + "version": "2.7.1", + "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.7.1.tgz", + "integrity": "sha512-uWjbaKIK3T1OSVptzX7Nl6PvQ3qAGtKEtVRjRuazjfL3Bx5eI409VZSqgND+4UNnmzLVdPj9FqFJNPqBZFve4w==", "requires": { "glob": "^7.1.3" } @@ -7840,7 +7488,6 @@ "version": "2.0.2", "resolved": "https://registry.npmjs.org/ripemd160/-/ripemd160-2.0.2.tgz", "integrity": "sha512-ii4iagi25WusVoiC4B4lq7pbXfAp3D9v5CwfkY33vffw2+pkDjY1D8GaN7spsxvCSx8dkPqOZCEZyfxcmJG2IA==", - "dev": true, "requires": { "hash-base": "^3.0.0", "inherits": "^2.0.1" @@ -7850,7 +7497,6 @@ "version": "1.0.3", "resolved": "https://registry.npmjs.org/run-queue/-/run-queue-1.0.3.tgz", "integrity": "sha1-6Eg5bwV9Ij8kOGkkYY4laUFh7Ec=", - "dev": true, "requires": { "aproba": "^1.1.1" } @@ -7858,14 +7504,12 @@ "safe-buffer": { "version": "5.1.2", "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", - "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==", - "dev": true + "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==" }, "safe-regex": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/safe-regex/-/safe-regex-1.1.0.tgz", "integrity": "sha1-QKNmnzsHfR6UPURinhV91IAjvy4=", - "dev": true, "requires": { "ret": "~0.1.10" } @@ -7873,20 +7517,17 @@ "safer-buffer": { "version": "2.1.2", "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz", - "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==", - "dev": true + "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==" }, "sax": { "version": "1.2.4", "resolved": "https://registry.npmjs.org/sax/-/sax-1.2.4.tgz", - "integrity": "sha512-NqVDv9TpANUjFm0N8uM5GxL36UgKi9/atZw+x7YFnQ8ckwFGKrl4xX4yWtrey3UJm5nP1kUbnYgLopqWNSRhWw==", - "dev": true + "integrity": "sha512-NqVDv9TpANUjFm0N8uM5GxL36UgKi9/atZw+x7YFnQ8ckwFGKrl4xX4yWtrey3UJm5nP1kUbnYgLopqWNSRhWw==" }, "schema-utils": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-1.0.0.tgz", "integrity": "sha512-i27Mic4KovM/lnGsy8whRCHhc7VicJajAjTrYg11K9zfZXnYIt4k5F+kZkwjnrhKzLic/HLU4j11mjsz2G/75g==", - "dev": true, "requires": { "ajv": "^6.1.0", "ajv-errors": "^1.0.0", @@ -7897,7 +7538,6 @@ "version": "1.0.0", "resolved": "https://registry.npmjs.org/section-matter/-/section-matter-1.0.0.tgz", "integrity": "sha512-vfD3pmTzGpufjScBh50YHKzEu2lxBWhVEHsNGoEXmCmn2hKGfeNLYMzCJpe8cD7gqX7TJluOVpBkAequ6dgMmA==", - "dev": true, "requires": { "extend-shallow": "^2.0.1", "kind-of": "^6.0.0" @@ -7907,10 +7547,14 @@ "version": "2.0.1", "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", - "dev": true, "requires": { "is-extendable": "^0.1.0" } + }, + "kind-of": { + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.2.tgz", + "integrity": "sha512-s5kLOcnH0XqDO+FvuaLX8DDjZ18CGFk7VygH40QoKPUQhW4e2rvM0rwUq0t8IQDOwYSeLK01U90OjzBTme2QqA==" } } }, @@ -7918,35 +7562,30 @@ "version": "1.1.2", "resolved": "https://registry.npmjs.org/select/-/select-1.1.2.tgz", "integrity": "sha1-DnNQrN7ICxEIUoeG7B1EGNEbOW0=", - "dev": true, "optional": true }, "select-hose": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/select-hose/-/select-hose-2.0.0.tgz", - "integrity": "sha1-Yl2GWPhlr0Psliv8N2o3NZpJlMo=", - "dev": true + "integrity": "sha1-Yl2GWPhlr0Psliv8N2o3NZpJlMo=" }, "selfsigned": { - "version": "1.10.4", - "resolved": "https://registry.npmjs.org/selfsigned/-/selfsigned-1.10.4.tgz", - "integrity": "sha512-9AukTiDmHXGXWtWjembZ5NDmVvP2695EtpgbCsxCa68w3c88B+alqbmZ4O3hZ4VWGXeGWzEVdvqgAJD8DQPCDw==", - "dev": true, + "version": "1.10.7", + "resolved": "https://registry.npmjs.org/selfsigned/-/selfsigned-1.10.7.tgz", + "integrity": "sha512-8M3wBCzeWIJnQfl43IKwOmC4H/RAp50S8DF60znzjW5GVqTcSe2vWclt7hmYVPkKPlHWOu5EaWOMZ2Y6W8ZXTA==", "requires": { - "node-forge": "0.7.5" + "node-forge": "0.9.0" } }, "semver": { - "version": "5.7.0", - "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.0.tgz", - "integrity": "sha512-Ya52jSX2u7QKghxeoFGpLwCtGlt7j0oY9DYb5apt9nPlJ42ID+ulTXESnt/qAQcoSERyZ5sl3LDIOw0nAn/5DA==", - "dev": true + "version": "5.7.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", + "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==" }, "send": { "version": "0.17.1", "resolved": "https://registry.npmjs.org/send/-/send-0.17.1.tgz", "integrity": "sha512-BsVKsiGcQMFwT8UxypobUKyv7irCNRHk1T0G680vk88yf6LBByGcZJOTJCrTP2xVN6yI+XjPJcNuE3V4fT9sAg==", - "dev": true, "requires": { "debug": "2.6.9", "depd": "~1.1.2", @@ -7967,7 +7606,6 @@ "version": "2.6.9", "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", - "dev": true, "requires": { "ms": "2.0.0" }, @@ -7975,36 +7613,31 @@ "ms": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", - "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=", - "dev": true + "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=" } } }, "mime": { "version": "1.6.0", "resolved": "https://registry.npmjs.org/mime/-/mime-1.6.0.tgz", - "integrity": "sha512-x0Vn8spI+wuJ1O6S7gnbaQg8Pxh4NNHb7KSINmEWKiPE4RKOplvijn+NkmYmmRgP68mc70j2EbeTFRsrswaQeg==", - "dev": true + "integrity": "sha512-x0Vn8spI+wuJ1O6S7gnbaQg8Pxh4NNHb7KSINmEWKiPE4RKOplvijn+NkmYmmRgP68mc70j2EbeTFRsrswaQeg==" }, "ms": { "version": "2.1.1", "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.1.tgz", - "integrity": "sha512-tgp+dl5cGk28utYktBsrFqA7HKgrhgPsg6Z/EfhWI4gl1Hwq8B/GmY/0oXZ6nF8hDVesS/FpnYaD/kOWhYQvyg==", - "dev": true + "integrity": "sha512-tgp+dl5cGk28utYktBsrFqA7HKgrhgPsg6Z/EfhWI4gl1Hwq8B/GmY/0oXZ6nF8hDVesS/FpnYaD/kOWhYQvyg==" } } }, "serialize-javascript": { - "version": "1.7.0", - "resolved": "https://registry.npmjs.org/serialize-javascript/-/serialize-javascript-1.7.0.tgz", - "integrity": "sha512-ke8UG8ulpFOxO8f8gRYabHQe/ZntKlcig2Mp+8+URDP1D8vJZ0KUt7LYo07q25Z/+JVSgpr/cui9PIp5H6/+nA==", - "dev": true + "version": "1.9.1", + "resolved": "https://registry.npmjs.org/serialize-javascript/-/serialize-javascript-1.9.1.tgz", + "integrity": "sha512-0Vb/54WJ6k5v8sSWN09S0ora+Hnr+cX40r9F170nT+mSkaxltoE/7R3OrIdBSUv1OoiobH1QoWQbCnAO+e8J1A==" }, "serve-index": { "version": "1.9.1", "resolved": "https://registry.npmjs.org/serve-index/-/serve-index-1.9.1.tgz", "integrity": "sha1-03aNabHn2C5c4FD/9bRTvqEqkjk=", - "dev": true, "requires": { "accepts": "~1.3.4", "batch": "0.6.1", @@ -8019,7 +7652,6 @@ "version": "2.6.9", "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", - "dev": true, "requires": { "ms": "2.0.0" } @@ -8028,7 +7660,6 @@ "version": "1.6.3", "resolved": "https://registry.npmjs.org/http-errors/-/http-errors-1.6.3.tgz", "integrity": "sha1-i1VoC7S+KDoLW/TqLjhYC+HZMg0=", - "dev": true, "requires": { "depd": "~1.1.2", "inherits": "2.0.3", @@ -8039,20 +7670,12 @@ "inherits": { "version": "2.0.3", "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.3.tgz", - "integrity": "sha1-Yzwsg+PaQqUC9SRmAiSA9CCCYd4=", - "dev": true - }, - "ms": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", - "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=", - "dev": true + "integrity": "sha1-Yzwsg+PaQqUC9SRmAiSA9CCCYd4=" }, "setprototypeof": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.1.0.tgz", - "integrity": "sha512-BvE/TwpZX4FXExxOxZyRGQQv651MSwmWKZGqvmPcRIjDqWub67kTKuIMx43cZZrS/cBBzwBcNDWoFxt2XEFIpQ==", - "dev": true + "integrity": "sha512-BvE/TwpZX4FXExxOxZyRGQQv651MSwmWKZGqvmPcRIjDqWub67kTKuIMx43cZZrS/cBBzwBcNDWoFxt2XEFIpQ==" } } }, @@ -8060,7 +7683,6 @@ "version": "1.14.1", "resolved": "https://registry.npmjs.org/serve-static/-/serve-static-1.14.1.tgz", "integrity": "sha512-JMrvUwE54emCYWlTI+hGrGv5I8dEwmco/00EvkzIIsR7MqrHonbD9pO2MOfFnpFntl7ecpZs+3mW+XbQZu9QCg==", - "dev": true, "requires": { "encodeurl": "~1.0.2", "escape-html": "~1.0.3", @@ -8071,14 +7693,12 @@ "set-blocking": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/set-blocking/-/set-blocking-2.0.0.tgz", - "integrity": "sha1-BF+XgtARrppoA93TgrJDkrPYkPc=", - "dev": true + "integrity": "sha1-BF+XgtARrppoA93TgrJDkrPYkPc=" }, "set-value": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/set-value/-/set-value-2.0.1.tgz", "integrity": "sha512-JxHc1weCN68wRY0fhCoXpyK55m/XPHafOmK4UWD7m2CI14GMcFypt4w/0+NV5f/ZMby2F6S2wwA7fgynh9gWSw==", - "dev": true, "requires": { "extend-shallow": "^2.0.1", "is-extendable": "^0.1.1", @@ -8090,7 +7710,6 @@ "version": "2.0.1", "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", - "dev": true, "requires": { "is-extendable": "^0.1.0" } @@ -8100,20 +7719,17 @@ "setimmediate": { "version": "1.0.5", "resolved": "https://registry.npmjs.org/setimmediate/-/setimmediate-1.0.5.tgz", - "integrity": "sha1-KQy7Iy4waULX1+qbg3Mqt4VvgoU=", - "dev": true + "integrity": "sha1-KQy7Iy4waULX1+qbg3Mqt4VvgoU=" }, "setprototypeof": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.1.1.tgz", - "integrity": "sha512-JvdAWfbXeIGaZ9cILp38HntZSFSo3mWg6xGcJJsd+d4aRMOqauag1C63dJfDw7OaMYwEbHMOxEZ1lqVRYP2OAw==", - "dev": true + "integrity": "sha512-JvdAWfbXeIGaZ9cILp38HntZSFSo3mWg6xGcJJsd+d4aRMOqauag1C63dJfDw7OaMYwEbHMOxEZ1lqVRYP2OAw==" }, "sha.js": { "version": "2.4.11", "resolved": "https://registry.npmjs.org/sha.js/-/sha.js-2.4.11.tgz", "integrity": "sha512-QMEp5B7cftE7APOjk5Y6xgrbWu+WkLVQwk8JNjZ8nKRciZaByEW6MubieAiToS7+dwvrjGhH8jRXz3MVd0AYqQ==", - "dev": true, "requires": { "inherits": "^2.0.1", "safe-buffer": "^5.0.1" @@ -8123,7 +7739,6 @@ "version": "1.2.0", "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-1.2.0.tgz", "integrity": "sha1-RKrGW2lbAzmJaMOfNj/uXer98eo=", - "dev": true, "requires": { "shebang-regex": "^1.0.0" } @@ -8131,20 +7746,17 @@ "shebang-regex": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-1.0.0.tgz", - "integrity": "sha1-2kL0l0DAtC2yypcoVxyxkMmO/qM=", - "dev": true + "integrity": "sha1-2kL0l0DAtC2yypcoVxyxkMmO/qM=" }, "signal-exit": { "version": "3.0.2", "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.2.tgz", - "integrity": "sha1-tf3AjxKH6hF4Yo5BXiUTK3NkbG0=", - "dev": true + "integrity": "sha1-tf3AjxKH6hF4Yo5BXiUTK3NkbG0=" }, "simple-swizzle": { "version": "0.2.2", "resolved": "https://registry.npmjs.org/simple-swizzle/-/simple-swizzle-0.2.2.tgz", "integrity": "sha1-pNprY1/8zMoz9w0Xy5JZLeleVXo=", - "dev": true, "requires": { "is-arrayish": "^0.3.1" }, @@ -8152,22 +7764,24 @@ "is-arrayish": { "version": "0.3.2", "resolved": "https://registry.npmjs.org/is-arrayish/-/is-arrayish-0.3.2.tgz", - "integrity": "sha512-eVRqCvVlZbuw3GrM63ovNSNAeA1K16kaR/LRY/92w0zxQ5/1YzwblUX652i4Xs9RwAGjW9d9y6X88t8OaAJfWQ==", - "dev": true + "integrity": "sha512-eVRqCvVlZbuw3GrM63ovNSNAeA1K16kaR/LRY/92w0zxQ5/1YzwblUX652i4Xs9RwAGjW9d9y6X88t8OaAJfWQ==" } } }, "slash": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/slash/-/slash-2.0.0.tgz", - "integrity": "sha512-ZYKh3Wh2z1PpEXWr0MpSBZ0V6mZHAQfYevttO11c51CaWjGTaadiKZ+wVt1PbMlDV5qhMFslpZCemhwOK7C89A==", - "dev": true + "integrity": "sha512-ZYKh3Wh2z1PpEXWr0MpSBZ0V6mZHAQfYevttO11c51CaWjGTaadiKZ+wVt1PbMlDV5qhMFslpZCemhwOK7C89A==" + }, + "smoothscroll-polyfill": { + "version": "0.4.4", + "resolved": "https://registry.npmjs.org/smoothscroll-polyfill/-/smoothscroll-polyfill-0.4.4.tgz", + "integrity": "sha512-TK5ZA9U5RqCwMpfoMq/l1mrH0JAR7y7KRvOBx0n2869aLxch+gT9GhN3yUfjiw+d/DiF1mKo14+hd62JyMmoBg==" }, "snapdragon": { "version": "0.8.2", "resolved": "https://registry.npmjs.org/snapdragon/-/snapdragon-0.8.2.tgz", "integrity": "sha512-FtyOnWN/wCHTVXOMwvSv26d+ko5vWlIDD6zoUJ7LW8vh+ZBC8QdljveRP+crNrtBwioEUWy/4dMtbBjA4ioNlg==", - "dev": true, "requires": { "base": "^0.11.1", "debug": "^2.2.0", @@ -8183,7 +7797,6 @@ "version": "2.6.9", "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", - "dev": true, "requires": { "ms": "2.0.0" } @@ -8192,7 +7805,6 @@ "version": "0.2.5", "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz", "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=", - "dev": true, "requires": { "is-descriptor": "^0.1.0" } @@ -8201,16 +7813,14 @@ "version": "2.0.1", "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", - "dev": true, "requires": { "is-extendable": "^0.1.0" } }, - "ms": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", - "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=", - "dev": true + "source-map": { + "version": "0.5.7", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz", + "integrity": "sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w=" } } }, @@ -8218,7 +7828,6 @@ "version": "2.1.1", "resolved": "https://registry.npmjs.org/snapdragon-node/-/snapdragon-node-2.1.1.tgz", "integrity": "sha512-O27l4xaMYt/RSQ5TR3vpWCAB5Kb/czIcqUFOM/C4fYcLnbZUc1PkjTAMjof2pBWaSTwOUd6qUHcFGVGj7aIwnw==", - "dev": true, "requires": { "define-property": "^1.0.0", "isobject": "^3.0.0", @@ -8229,7 +7838,6 @@ "version": "1.0.0", "resolved": "https://registry.npmjs.org/define-property/-/define-property-1.0.0.tgz", "integrity": "sha1-dp66rz9KY6rTr56NMEybvnm/sOY=", - "dev": true, "requires": { "is-descriptor": "^1.0.0" } @@ -8238,7 +7846,6 @@ "version": "1.0.0", "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-1.0.0.tgz", "integrity": "sha512-m5hnHTkcVsPfqx3AKlyttIPb7J+XykHvJP2B9bZDjlhLIoEq4XoK64Vg7boZlVWYK6LUY94dYPEE7Lh0ZkZKcQ==", - "dev": true, "requires": { "kind-of": "^6.0.0" } @@ -8247,7 +7854,6 @@ "version": "1.0.0", "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-1.0.0.tgz", "integrity": "sha512-jbRXy1FmtAoCjQkVmIVYwuuqDFUbaOeDjmed1tOGPrsMhtJA4rD9tkgA0F1qJ3gRFRXcHYVkdeaP50Q5rE/jLQ==", - "dev": true, "requires": { "kind-of": "^6.0.0" } @@ -8256,12 +7862,16 @@ "version": "1.0.2", "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-1.0.2.tgz", "integrity": "sha512-2eis5WqQGV7peooDyLmNEPUrps9+SXX5c9pL3xEB+4e9HnGuDa7mB7kHxHw4CbqS9k1T2hOH3miL8n8WtiYVtg==", - "dev": true, "requires": { "is-accessor-descriptor": "^1.0.0", "is-data-descriptor": "^1.0.0", "kind-of": "^6.0.2" } + }, + "kind-of": { + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.2.tgz", + "integrity": "sha512-s5kLOcnH0XqDO+FvuaLX8DDjZ18CGFk7VygH40QoKPUQhW4e2rvM0rwUq0t8IQDOwYSeLK01U90OjzBTme2QqA==" } } }, @@ -8269,37 +7879,23 @@ "version": "3.0.1", "resolved": "https://registry.npmjs.org/snapdragon-util/-/snapdragon-util-3.0.1.tgz", "integrity": "sha512-mbKkMdQKsjX4BAL4bRYTj21edOf8cN7XHdYUJEe+Zn99hVEYcMvKPct1IqNe7+AZPirn8BCDOQBHQZknqmKlZQ==", - "dev": true, "requires": { "kind-of": "^3.2.0" - }, - "dependencies": { - "kind-of": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", - "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", - "dev": true, - "requires": { - "is-buffer": "^1.1.5" - } - } } }, "sockjs": { "version": "0.3.19", "resolved": "https://registry.npmjs.org/sockjs/-/sockjs-0.3.19.tgz", "integrity": "sha512-V48klKZl8T6MzatbLlzzRNhMepEys9Y4oGFpypBFFn1gLI/QQ9HtLLyWJNbPlwGLelOVOEijUbTTJeLLI59jLw==", - "dev": true, "requires": { "faye-websocket": "^0.10.0", "uuid": "^3.0.1" } }, "sockjs-client": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/sockjs-client/-/sockjs-client-1.3.0.tgz", - "integrity": "sha512-R9jxEzhnnrdxLCNln0xg5uGHqMnkhPSTzUZH2eXcR03S/On9Yvoq2wyUZILRUhZCNVu2PmwWVoyuiPz8th8zbg==", - "dev": true, + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/sockjs-client/-/sockjs-client-1.4.0.tgz", + "integrity": "sha512-5zaLyO8/nri5cua0VtOrFXBPK1jbL4+1cebT/mmKA1E1ZXOvJrII75bPu0l0k843G/+iAbhEqzyKr0w/eCCj7g==", "requires": { "debug": "^3.2.5", "eventsource": "^1.0.7", @@ -8313,7 +7909,6 @@ "version": "3.2.6", "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.6.tgz", "integrity": "sha512-mel+jf7nrtEl5Pn1Qx46zARXKDpBbvzezse7p7LqINmdoIk8PYP5SySaxEmYv6TZ0JyEKA1hsCId6DIhgITtWQ==", - "dev": true, "requires": { "ms": "^2.1.1" } @@ -8322,10 +7917,14 @@ "version": "0.11.3", "resolved": "https://registry.npmjs.org/faye-websocket/-/faye-websocket-0.11.3.tgz", "integrity": "sha512-D2y4bovYpzziGgbHYtGCMjlJM36vAl/y+xUyn1C+FVx8szd1E+86KwVw6XvYSzOP8iMpm1X0I4xJD+QtUb36OA==", - "dev": true, "requires": { "websocket-driver": ">=0.5.1" } + }, + "ms": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", + "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==" } } }, @@ -8333,7 +7932,6 @@ "version": "2.0.0", "resolved": "https://registry.npmjs.org/sort-keys/-/sort-keys-2.0.0.tgz", "integrity": "sha1-ZYU1WEhh7JfXMNbPQYIuH1ZoQSg=", - "dev": true, "requires": { "is-plain-obj": "^1.0.0" } @@ -8341,20 +7939,17 @@ "source-list-map": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/source-list-map/-/source-list-map-2.0.1.tgz", - "integrity": "sha512-qnQ7gVMxGNxsiL4lEuJwe/To8UnK7fAnmbGEEH8RpLouuKbeEm0lhbQVFIrNSuB+G7tVrAlVsZgETT5nljf+Iw==", - "dev": true + "integrity": "sha512-qnQ7gVMxGNxsiL4lEuJwe/To8UnK7fAnmbGEEH8RpLouuKbeEm0lhbQVFIrNSuB+G7tVrAlVsZgETT5nljf+Iw==" }, "source-map": { - "version": "0.5.7", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz", - "integrity": "sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w=", - "dev": true + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", + "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==" }, "source-map-resolve": { "version": "0.5.2", "resolved": "https://registry.npmjs.org/source-map-resolve/-/source-map-resolve-0.5.2.tgz", "integrity": "sha512-MjqsvNwyz1s0k81Goz/9vRBe9SZdB09Bdw+/zYyO+3CuPk6fouTaxscHkgtE8jKvf01kVfl8riHzERQ/kefaSA==", - "dev": true, "requires": { "atob": "^2.1.1", "decode-uri-component": "^0.2.0", @@ -8364,47 +7959,50 @@ } }, "source-map-support": { - "version": "0.5.12", - "resolved": "https://registry.npmjs.org/source-map-support/-/source-map-support-0.5.12.tgz", - "integrity": "sha512-4h2Pbvyy15EE02G+JOZpUCmqWJuqrs+sEkzewTm++BPi7Hvn/HwcqLAcNxYAyI0x13CpPPn+kMjl+hplXMHITQ==", - "dev": true, + "version": "0.5.13", + "resolved": "https://registry.npmjs.org/source-map-support/-/source-map-support-0.5.13.tgz", + "integrity": "sha512-SHSKFHadjVA5oR4PPqhtAVdcBWwRYVd6g6cAXnIbRiIwc2EhPrTuKUBdSLvlEKyIP3GCf89fltvcZiP9MMFA1w==", "requires": { "buffer-from": "^1.0.0", "source-map": "^0.6.0" - }, - "dependencies": { - "source-map": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", - "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", - "dev": true - } } }, "source-map-url": { "version": "0.4.0", "resolved": "https://registry.npmjs.org/source-map-url/-/source-map-url-0.4.0.tgz", - "integrity": "sha1-PpNdfd1zYxuXZZlW1VEo6HtQhKM=", - "dev": true + "integrity": "sha1-PpNdfd1zYxuXZZlW1VEo6HtQhKM=" }, "spdy": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/spdy/-/spdy-4.0.0.tgz", - "integrity": "sha512-ot0oEGT/PGUpzf/6uk4AWLqkq+irlqHXkrdbk51oWONh3bxQmBuljxPNl66zlRRcIJStWq0QkLUCPOPjgjvU0Q==", - "dev": true, + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/spdy/-/spdy-4.0.1.tgz", + "integrity": "sha512-HeZS3PBdMA+sZSu0qwpCxl3DeALD5ASx8pAX0jZdKXSpPWbQ6SYGnlg3BBmYLx5LtiZrmkAZfErCm2oECBcioA==", "requires": { "debug": "^4.1.0", "handle-thing": "^2.0.0", "http-deceiver": "^1.2.7", "select-hose": "^2.0.0", "spdy-transport": "^3.0.0" + }, + "dependencies": { + "debug": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.1.1.tgz", + "integrity": "sha512-pYAIzeRo8J6KPEaJ0VWOh5Pzkbw/RetuzehGM7QRRX5he4fPHx2rdKMB256ehJCkX+XRQm16eZLqLNS8RSZXZw==", + "requires": { + "ms": "^2.1.1" + } + }, + "ms": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", + "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==" + } } }, "spdy-transport": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/spdy-transport/-/spdy-transport-3.0.0.tgz", "integrity": "sha512-hsLVFE5SjA6TCisWeJXFKniGGOpBgMLmerfO2aCyCU5s7nJ/rpAepqmFifv/GCbSbueEeAJJnmSQ2rKC/g8Fcw==", - "dev": true, "requires": { "debug": "^4.1.0", "detect-node": "^2.0.4", @@ -8414,11 +8012,23 @@ "wbuf": "^1.7.3" }, "dependencies": { + "debug": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.1.1.tgz", + "integrity": "sha512-pYAIzeRo8J6KPEaJ0VWOh5Pzkbw/RetuzehGM7QRRX5he4fPHx2rdKMB256ehJCkX+XRQm16eZLqLNS8RSZXZw==", + "requires": { + "ms": "^2.1.1" + } + }, + "ms": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", + "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==" + }, "readable-stream": { "version": "3.4.0", "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.4.0.tgz", "integrity": "sha512-jItXPLmrSR8jmTRmRWJXCnGJsfy85mB3Wd/uINMXA65yrnFo0cPClFIUWzo2najVNSl+mx7/4W8ttlLWJe99pQ==", - "dev": true, "requires": { "inherits": "^2.0.3", "string_decoder": "^1.1.1", @@ -8431,7 +8041,6 @@ "version": "3.1.0", "resolved": "https://registry.npmjs.org/split-string/-/split-string-3.1.0.tgz", "integrity": "sha512-NzNVhJDYpwceVVii8/Hu6DKfD2G+NrQHlS/V/qgv763EYudVwEcMQNxd2lh+0VrUByXN/oJkl5grOhYWvQUYiw==", - "dev": true, "requires": { "extend-shallow": "^3.0.0" } @@ -8439,14 +8048,12 @@ "sprintf-js": { "version": "1.0.3", "resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.0.3.tgz", - "integrity": "sha1-BOaSb2YolTVPPdAVIDYzuFcpfiw=", - "dev": true + "integrity": "sha1-BOaSb2YolTVPPdAVIDYzuFcpfiw=" }, "sshpk": { "version": "1.16.1", "resolved": "https://registry.npmjs.org/sshpk/-/sshpk-1.16.1.tgz", "integrity": "sha512-HXXqVUq7+pcKeLqqZj6mHFUMvXtOJt1uoUx09pFW6011inTMxqI8BA8PM95myrIyyKwdnzjdFjLiE6KBPVtJIg==", - "dev": true, "requires": { "asn1": "~0.2.3", "assert-plus": "^1.0.0", @@ -8463,7 +8070,6 @@ "version": "6.0.1", "resolved": "https://registry.npmjs.org/ssri/-/ssri-6.0.1.tgz", "integrity": "sha512-3Wge10hNcT1Kur4PDFwEieXSCMCJs/7WvSACcrMYrNp+b8kDL1/0wJch5Ni2WrtwEa2IO8OsVfeKIciKCDx/QA==", - "dev": true, "requires": { "figgy-pudding": "^3.5.1" } @@ -8471,20 +8077,17 @@ "stable": { "version": "0.1.8", "resolved": "https://registry.npmjs.org/stable/-/stable-0.1.8.tgz", - "integrity": "sha512-ji9qxRnOVfcuLDySj9qzhGSEFVobyt1kIOSkj1qZzYLzq7Tos/oUUWvotUPQLlrsidqsK6tBH89Bc9kL5zHA6w==", - "dev": true + "integrity": "sha512-ji9qxRnOVfcuLDySj9qzhGSEFVobyt1kIOSkj1qZzYLzq7Tos/oUUWvotUPQLlrsidqsK6tBH89Bc9kL5zHA6w==" }, "stack-utils": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/stack-utils/-/stack-utils-1.0.2.tgz", - "integrity": "sha512-MTX+MeG5U994cazkjd/9KNAapsHnibjMLnfXodlkXw76JEea0UiNzrqidzo1emMwk7w5Qhc9jd4Bn9TBb1MFwA==", - "dev": true + "integrity": "sha512-MTX+MeG5U994cazkjd/9KNAapsHnibjMLnfXodlkXw76JEea0UiNzrqidzo1emMwk7w5Qhc9jd4Bn9TBb1MFwA==" }, "static-extend": { "version": "0.1.2", "resolved": "https://registry.npmjs.org/static-extend/-/static-extend-0.1.2.tgz", "integrity": "sha1-YICcOcv/VTNyJv1eC1IPNB8ftcY=", - "dev": true, "requires": { "define-property": "^0.2.5", "object-copy": "^0.1.0" @@ -8494,7 +8097,6 @@ "version": "0.2.5", "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz", "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=", - "dev": true, "requires": { "is-descriptor": "^0.1.0" } @@ -8504,14 +8106,12 @@ "statuses": { "version": "1.5.0", "resolved": "https://registry.npmjs.org/statuses/-/statuses-1.5.0.tgz", - "integrity": "sha1-Fhx9rBd2Wf2YEfQ3cfqZOBR4Yow=", - "dev": true + "integrity": "sha1-Fhx9rBd2Wf2YEfQ3cfqZOBR4Yow=" }, "std-env": { "version": "2.2.1", "resolved": "https://registry.npmjs.org/std-env/-/std-env-2.2.1.tgz", "integrity": "sha512-IjYQUinA3lg5re/YMlwlfhqNRTzMZMqE+pezevdcTaHceqx8ngEi1alX9nNCk9Sc81fy1fLDeQoaCzeiW1yBOQ==", - "dev": true, "requires": { "ci-info": "^1.6.0" } @@ -8520,7 +8120,6 @@ "version": "2.0.2", "resolved": "https://registry.npmjs.org/stream-browserify/-/stream-browserify-2.0.2.tgz", "integrity": "sha512-nX6hmklHs/gr2FuxYDltq8fJA1GDlxKQCz8O/IM4atRqBH8OORmBNgfvW5gG10GT/qQ9u0CzIvr2X5Pkt6ntqg==", - "dev": true, "requires": { "inherits": "~2.0.1", "readable-stream": "^2.0.2" @@ -8530,7 +8129,6 @@ "version": "1.2.3", "resolved": "https://registry.npmjs.org/stream-each/-/stream-each-1.2.3.tgz", "integrity": "sha512-vlMC2f8I2u/bZGqkdfLQW/13Zihpej/7PmSiMQsbYddxuTsJp8vRe2x2FvVExZg7FaOds43ROAuFJwPR4MTZLw==", - "dev": true, "requires": { "end-of-stream": "^1.1.0", "stream-shift": "^1.0.0" @@ -8540,7 +8138,6 @@ "version": "2.8.3", "resolved": "https://registry.npmjs.org/stream-http/-/stream-http-2.8.3.tgz", "integrity": "sha512-+TSkfINHDo4J+ZobQLWiMouQYB+UVYFttRA94FpEzzJ7ZdqcL4uUUQ7WkdkI4DSozGmgBUE/a47L+38PenXhUw==", - "dev": true, "requires": { "builtin-status-codes": "^3.0.0", "inherits": "^2.0.1", @@ -8552,20 +8149,17 @@ "stream-shift": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/stream-shift/-/stream-shift-1.0.0.tgz", - "integrity": "sha1-1cdSgl5TZ+eG944Y5EXqIjoVWVI=", - "dev": true + "integrity": "sha1-1cdSgl5TZ+eG944Y5EXqIjoVWVI=" }, "strict-uri-encode": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/strict-uri-encode/-/strict-uri-encode-1.1.0.tgz", - "integrity": "sha1-J5siXfHVgrH1TmWt3UNS4Y+qBxM=", - "dev": true + "integrity": "sha1-J5siXfHVgrH1TmWt3UNS4Y+qBxM=" }, "string-width": { "version": "2.1.1", "resolved": "https://registry.npmjs.org/string-width/-/string-width-2.1.1.tgz", "integrity": "sha512-nOqH59deCq9SRHlxq1Aw85Jnt4w6KvLKqWVik6oA9ZklXLNIOlqg4F2yrT1MVaTjAqvVwdfeZ7w7aCvJD7ugkw==", - "dev": true, "requires": { "is-fullwidth-code-point": "^2.0.0", "strip-ansi": "^4.0.0" @@ -8574,25 +8168,40 @@ "ansi-regex": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-3.0.0.tgz", - "integrity": "sha1-7QMXwyIGT3lGbAKWa922Bas32Zg=", - "dev": true + "integrity": "sha1-7QMXwyIGT3lGbAKWa922Bas32Zg=" }, "strip-ansi": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-4.0.0.tgz", "integrity": "sha1-qEeQIusaw2iocTibY1JixQXuNo8=", - "dev": true, "requires": { "ansi-regex": "^3.0.0" } } } }, + "string.prototype.trimleft": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/string.prototype.trimleft/-/string.prototype.trimleft-2.1.0.tgz", + "integrity": "sha512-FJ6b7EgdKxxbDxc79cOlok6Afd++TTs5szo+zJTUyow3ycrRfJVE2pq3vcN53XexvKZu/DJMDfeI/qMiZTrjTw==", + "requires": { + "define-properties": "^1.1.3", + "function-bind": "^1.1.1" + } + }, + "string.prototype.trimright": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/string.prototype.trimright/-/string.prototype.trimright-2.1.0.tgz", + "integrity": "sha512-fXZTSV55dNBwv16uw+hh5jkghxSnc5oHq+5K/gXgizHwAvMetdAJlHqqoFC1FSDVPYWLkAKl2cxpUT41sV7nSg==", + "requires": { + "define-properties": "^1.1.3", + "function-bind": "^1.1.1" + } + }, "string_decoder": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", - "dev": true, "requires": { "safe-buffer": "~5.1.0" } @@ -8601,7 +8210,6 @@ "version": "3.0.1", "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz", "integrity": "sha1-ajhfuIU9lS1f8F0Oiq+UJ43GPc8=", - "dev": true, "requires": { "ansi-regex": "^2.0.0" } @@ -8609,20 +8217,17 @@ "strip-bom-string": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/strip-bom-string/-/strip-bom-string-1.0.0.tgz", - "integrity": "sha1-5SEekiQ2n7uB1jOi8ABE3IztrZI=", - "dev": true + "integrity": "sha1-5SEekiQ2n7uB1jOi8ABE3IztrZI=" }, "strip-eof": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/strip-eof/-/strip-eof-1.0.0.tgz", - "integrity": "sha1-u0P/VZim6wXYm1n80SnJgzE2Br8=", - "dev": true + "integrity": "sha1-u0P/VZim6wXYm1n80SnJgzE2Br8=" }, "stylehacks": { "version": "4.0.3", "resolved": "https://registry.npmjs.org/stylehacks/-/stylehacks-4.0.3.tgz", "integrity": "sha512-7GlLk9JwlElY4Y6a/rmbH2MhVlTyVmiJd1PfTCqFaIBEGMYNsrO/v3SeGTdhBThLg4Z+NbOk/qFMwCa+J+3p/g==", - "dev": true, "requires": { "browserslist": "^4.0.0", "postcss": "^7.0.0", @@ -8633,7 +8238,6 @@ "version": "3.1.1", "resolved": "https://registry.npmjs.org/postcss-selector-parser/-/postcss-selector-parser-3.1.1.tgz", "integrity": "sha1-T4dfSvsMllc9XPTXQBGu4lCn6GU=", - "dev": true, "requires": { "dot-prop": "^4.1.1", "indexes-of": "^1.0.1", @@ -8643,47 +8247,29 @@ } }, "stylus": { - "version": "0.54.5", - "resolved": "https://registry.npmjs.org/stylus/-/stylus-0.54.5.tgz", - "integrity": "sha1-QrlWCTHKcJDOhRWnmLqeaqPW3Hk=", - "dev": true, - "requires": { - "css-parse": "1.7.x", - "debug": "*", - "glob": "7.0.x", - "mkdirp": "0.5.x", - "sax": "0.5.x", - "source-map": "0.1.x" + "version": "0.54.7", + "resolved": "https://registry.npmjs.org/stylus/-/stylus-0.54.7.tgz", + "integrity": "sha512-Yw3WMTzVwevT6ZTrLCYNHAFmanMxdylelL3hkWNgPMeTCpMwpV3nXjpOHuBXtFv7aiO2xRuQS6OoAdgkNcSNug==", + "requires": { + "css-parse": "~2.0.0", + "debug": "~3.1.0", + "glob": "^7.1.3", + "mkdirp": "~0.5.x", + "safer-buffer": "^2.1.2", + "sax": "~1.2.4", + "semver": "^6.0.0", + "source-map": "^0.7.3" }, "dependencies": { - "glob": { - "version": "7.0.6", - "resolved": "https://registry.npmjs.org/glob/-/glob-7.0.6.tgz", - "integrity": "sha1-IRuvr0nlJbjNkyYNFKsTYVKz9Xo=", - "dev": true, - "requires": { - "fs.realpath": "^1.0.0", - "inflight": "^1.0.4", - "inherits": "2", - "minimatch": "^3.0.2", - "once": "^1.3.0", - "path-is-absolute": "^1.0.0" - } - }, - "sax": { - "version": "0.5.8", - "resolved": "https://registry.npmjs.org/sax/-/sax-0.5.8.tgz", - "integrity": "sha1-1HLbIo6zMcJQaw6MFVJK25OdEsE=", - "dev": true + "semver": { + "version": "6.3.0", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", + "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==" }, "source-map": { - "version": "0.1.43", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.1.43.tgz", - "integrity": "sha1-wkvBRspRfBRx9drL4lcbK3+eM0Y=", - "dev": true, - "requires": { - "amdefine": ">=0.0.4" - } + "version": "0.7.3", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.7.3.tgz", + "integrity": "sha512-CkCj6giN3S+n9qrYiBTX5gystlENnRW5jZeNLHpe6aue+SrHcG5VYwujhW9s4dY31mEGsxBDrHR6oI69fTXsaQ==" } } }, @@ -8691,7 +8277,6 @@ "version": "3.0.2", "resolved": "https://registry.npmjs.org/stylus-loader/-/stylus-loader-3.0.2.tgz", "integrity": "sha512-+VomPdZ6a0razP+zinir61yZgpw2NfljeSsdUF5kJuEzlo3khXhY19Fn6l8QQz1GRJGtMCo8nG5C04ePyV7SUA==", - "dev": true, "requires": { "loader-utils": "^1.0.2", "lodash.clonedeep": "^4.5.0", @@ -8702,7 +8287,6 @@ "version": "5.5.0", "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", - "dev": true, "requires": { "has-flag": "^3.0.0" } @@ -8710,21 +8294,18 @@ "svg-tags": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/svg-tags/-/svg-tags-1.0.0.tgz", - "integrity": "sha1-WPcc7jvVGbWdSyqEO2x95krAR2Q=", - "dev": true + "integrity": "sha1-WPcc7jvVGbWdSyqEO2x95krAR2Q=" }, "svgo": { - "version": "1.2.2", - "resolved": "https://registry.npmjs.org/svgo/-/svgo-1.2.2.tgz", - "integrity": "sha512-rAfulcwp2D9jjdGu+0CuqlrAUin6bBWrpoqXWwKDZZZJfXcUXQSxLJOFJCQCSA0x0pP2U0TxSlJu2ROq5Bq6qA==", - "dev": true, + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/svgo/-/svgo-1.3.0.tgz", + "integrity": "sha512-MLfUA6O+qauLDbym+mMZgtXCGRfIxyQoeH6IKVcFslyODEe/ElJNwr0FohQ3xG4C6HK6bk3KYPPXwHVJk3V5NQ==", "requires": { "chalk": "^2.4.1", "coa": "^2.0.2", "css-select": "^2.0.0", "css-select-base-adapter": "^0.1.1", - "css-tree": "1.0.0-alpha.28", - "css-url-regex": "^1.1.0", + "css-tree": "1.0.0-alpha.33", "csso": "^3.5.1", "js-yaml": "^3.13.1", "mkdirp": "~0.5.1", @@ -8738,93 +8319,93 @@ "tapable": { "version": "1.1.3", "resolved": "https://registry.npmjs.org/tapable/-/tapable-1.1.3.tgz", - "integrity": "sha512-4WK/bYZmj8xLr+HUCODHGF1ZFzsYffasLUgEiMBY4fgtltdO6B4WJtlSbPaDTLpYTcGVwM2qLnFTICEcNxs3kA==", - "dev": true + "integrity": "sha512-4WK/bYZmj8xLr+HUCODHGF1ZFzsYffasLUgEiMBY4fgtltdO6B4WJtlSbPaDTLpYTcGVwM2qLnFTICEcNxs3kA==" }, "terser": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/terser/-/terser-4.0.0.tgz", - "integrity": "sha512-dOapGTU0hETFl1tCo4t56FN+2jffoKyER9qBGoUFyZ6y7WLoKT0bF+lAYi6B6YsILcGF3q1C2FBh8QcKSCgkgA==", - "dev": true, + "version": "4.3.9", + "resolved": "https://registry.npmjs.org/terser/-/terser-4.3.9.tgz", + "integrity": "sha512-NFGMpHjlzmyOtPL+fDw3G7+6Ueh/sz4mkaUYa4lJCxOPTNzd0Uj0aZJOmsDYoSQyfuVoWDMSWTPU3huyOm2zdA==", "requires": { - "commander": "^2.19.0", + "commander": "^2.20.0", "source-map": "~0.6.1", - "source-map-support": "~0.5.10" + "source-map-support": "~0.5.12" }, "dependencies": { "commander": { - "version": "2.20.0", - "resolved": "https://registry.npmjs.org/commander/-/commander-2.20.0.tgz", - "integrity": "sha512-7j2y+40w61zy6YC2iRNpUe/NwhNyoXrYpHMrSunaMG64nRnaf96zO/KMQR4OyN/UnE5KLyEBnKHd4aG3rskjpQ==", - "dev": true - }, - "source-map": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", - "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", - "dev": true + "version": "2.20.3", + "resolved": "https://registry.npmjs.org/commander/-/commander-2.20.3.tgz", + "integrity": "sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ==" } } }, "terser-webpack-plugin": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/terser-webpack-plugin/-/terser-webpack-plugin-1.3.0.tgz", - "integrity": "sha512-W2YWmxPjjkUcOWa4pBEv4OP4er1aeQJlSo2UhtCFQCuRXEHjOFscO8VyWHj9JLlA0RzQb8Y2/Ta78XZvT54uGg==", - "dev": true, + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/terser-webpack-plugin/-/terser-webpack-plugin-1.4.1.tgz", + "integrity": "sha512-ZXmmfiwtCLfz8WKZyYUuuHf3dMYEjg8NrjHMb0JqHVHVOSkzp3cW2/XG1fP3tRhqEqSzMwzzRQGtAPbs4Cncxg==", "requires": { - "cacache": "^11.3.2", - "find-cache-dir": "^2.0.0", + "cacache": "^12.0.2", + "find-cache-dir": "^2.1.0", "is-wsl": "^1.1.0", - "loader-utils": "^1.2.3", "schema-utils": "^1.0.0", "serialize-javascript": "^1.7.0", "source-map": "^0.6.1", - "terser": "^4.0.0", - "webpack-sources": "^1.3.0", + "terser": "^4.1.2", + "webpack-sources": "^1.4.0", "worker-farm": "^1.7.0" }, "dependencies": { - "source-map": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", - "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", - "dev": true + "cacache": { + "version": "12.0.3", + "resolved": "https://registry.npmjs.org/cacache/-/cacache-12.0.3.tgz", + "integrity": "sha512-kqdmfXEGFepesTuROHMs3MpFLWrPkSSpRqOw80RCflZXy/khxaArvFrQ7uJxSUduzAufc6G0g1VUCOZXxWavPw==", + "requires": { + "bluebird": "^3.5.5", + "chownr": "^1.1.1", + "figgy-pudding": "^3.5.1", + "glob": "^7.1.4", + "graceful-fs": "^4.1.15", + "infer-owner": "^1.0.3", + "lru-cache": "^5.1.1", + "mississippi": "^3.0.0", + "mkdirp": "^0.5.1", + "move-concurrently": "^1.0.1", + "promise-inflight": "^1.0.1", + "rimraf": "^2.6.3", + "ssri": "^6.0.1", + "unique-filename": "^1.1.1", + "y18n": "^4.0.0" + } } } }, "text-table": { "version": "0.2.0", "resolved": "https://registry.npmjs.org/text-table/-/text-table-0.2.0.tgz", - "integrity": "sha1-f17oI66AUgfACvLfSoTsP8+lcLQ=", - "dev": true + "integrity": "sha1-f17oI66AUgfACvLfSoTsP8+lcLQ=" }, "through": { "version": "2.3.8", "resolved": "https://registry.npmjs.org/through/-/through-2.3.8.tgz", - "integrity": "sha1-DdTJ/6q8NXlgsbckEV1+Doai4fU=", - "dev": true + "integrity": "sha1-DdTJ/6q8NXlgsbckEV1+Doai4fU=" }, "through2": { "version": "2.0.5", "resolved": "https://registry.npmjs.org/through2/-/through2-2.0.5.tgz", "integrity": "sha512-/mrRod8xqpA+IHSLyGCQ2s8SPHiCDEeQJSep1jqLYeEUClOFG2Qsh+4FU6G9VeqpZnGW/Su8LQGc4YKni5rYSQ==", - "dev": true, "requires": { "readable-stream": "~2.3.6", "xtend": "~4.0.1" } }, "thunky": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/thunky/-/thunky-1.0.3.tgz", - "integrity": "sha512-YwT8pjmNcAXBZqrubu22P4FYsh2D4dxRmnWBOL8Jk8bUcRUtc5326kx32tuTmFDAZtLOGEVNl8POAR8j896Iow==", - "dev": true + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/thunky/-/thunky-1.1.0.tgz", + "integrity": "sha512-eHY7nBftgThBqOyHGVN+l8gF0BucP09fMo0oO/Lb0w1OF80dJv+lDVpXG60WMQvkcxAkNybKsrEIE3ZtKGmPrA==" }, "timers-browserify": { - "version": "2.0.10", - "resolved": "https://registry.npmjs.org/timers-browserify/-/timers-browserify-2.0.10.tgz", - "integrity": "sha512-YvC1SV1XdOUaL6gx5CoGroT3Gu49pK9+TZ38ErPldOWW4j49GI1HKs9DV+KGq/w6y+LZ72W1c8cKz2vzY+qpzg==", - "dev": true, + "version": "2.0.11", + "resolved": "https://registry.npmjs.org/timers-browserify/-/timers-browserify-2.0.11.tgz", + "integrity": "sha512-60aV6sgJ5YEbzUdn9c8kYGIqOubPoUdqQCul3SBAsRCZ40s6Y5cMcrW4dt3/k/EsbLVJNl9n6Vz3fTc+k2GeKQ==", "requires": { "setimmediate": "^1.0.4" } @@ -8832,59 +8413,49 @@ "timsort": { "version": "0.3.0", "resolved": "https://registry.npmjs.org/timsort/-/timsort-0.3.0.tgz", - "integrity": "sha1-QFQRqOfmM5/mTbmiNN4R3DHgK9Q=", - "dev": true + "integrity": "sha1-QFQRqOfmM5/mTbmiNN4R3DHgK9Q=" }, "tiny-emitter": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/tiny-emitter/-/tiny-emitter-2.1.0.tgz", "integrity": "sha512-NB6Dk1A9xgQPMoGqC5CVXn123gWyte215ONT5Pp5a0yt4nlEoO1ZWeCwpncaekPHXO60i47ihFnZPiRPjRMq4Q==", - "dev": true, "optional": true }, + "tm-tooltip": { + "version": "0.0.10", + "resolved": "https://registry.npmjs.org/tm-tooltip/-/tm-tooltip-0.0.10.tgz", + "integrity": "sha512-ud+LicFlyhwLwO/nfGvtASg3TyUCjaEQC5GCZaE/JzXQmwK0ndb+4F0/ek8xr07rOENFUIT9N+1tmUDqCAtv1g==", + "requires": { + "markdown-it": "^9.1.0" + } + }, "to-arraybuffer": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/to-arraybuffer/-/to-arraybuffer-1.0.1.tgz", - "integrity": "sha1-fSKbH8xjfkZsoIEYCDanqr/4P0M=", - "dev": true + "integrity": "sha1-fSKbH8xjfkZsoIEYCDanqr/4P0M=" }, "to-factory": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/to-factory/-/to-factory-1.0.0.tgz", - "integrity": "sha1-hzivi9lxIK0dQEeXKtpVY7+UebE=", - "dev": true + "integrity": "sha1-hzivi9lxIK0dQEeXKtpVY7+UebE=" }, "to-fast-properties": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/to-fast-properties/-/to-fast-properties-2.0.0.tgz", - "integrity": "sha1-3F5pjL0HkmW8c+A3doGk5Og/YW4=", - "dev": true + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/to-fast-properties/-/to-fast-properties-1.0.3.tgz", + "integrity": "sha1-uDVx+k2MJbguIxsG46MFXeTKGkc=" }, "to-object-path": { "version": "0.3.0", "resolved": "https://registry.npmjs.org/to-object-path/-/to-object-path-0.3.0.tgz", "integrity": "sha1-KXWIt7Dn4KwI4E5nL4XB9JmeF68=", - "dev": true, "requires": { "kind-of": "^3.0.2" - }, - "dependencies": { - "kind-of": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", - "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", - "dev": true, - "requires": { - "is-buffer": "^1.1.5" - } - } } }, "to-regex": { "version": "3.0.2", "resolved": "https://registry.npmjs.org/to-regex/-/to-regex-3.0.2.tgz", "integrity": "sha512-FWtleNAtZ/Ki2qtqej2CXTOayOH9bHDQF+Q48VpWyDXjbYxA4Yz8iDB31zXOBUlOHHKidDbqGVrTUvQMPmBGBw==", - "dev": true, "requires": { "define-property": "^2.0.2", "extend-shallow": "^3.0.2", @@ -8896,7 +8467,6 @@ "version": "2.1.1", "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-2.1.1.tgz", "integrity": "sha1-fIDBe53+vlmeJzZ+DU3VWQFB2zg=", - "dev": true, "requires": { "is-number": "^3.0.0", "repeat-string": "^1.6.1" @@ -8905,26 +8475,27 @@ "toidentifier": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/toidentifier/-/toidentifier-1.0.0.tgz", - "integrity": "sha512-yaOH/Pk/VEhBWWTlhI+qXxDFXlejDGcQipMlyxda9nthulaxLZUNcUqFxokp0vcYnvteJln5FNQDRrxj3YcbVw==", - "dev": true + "integrity": "sha512-yaOH/Pk/VEhBWWTlhI+qXxDFXlejDGcQipMlyxda9nthulaxLZUNcUqFxokp0vcYnvteJln5FNQDRrxj3YcbVw==" + }, + "token-stream": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/token-stream/-/token-stream-0.0.1.tgz", + "integrity": "sha1-zu78cXp2xDFvEm0LnbqlXX598Bo=" }, "toml": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/toml/-/toml-3.0.0.tgz", - "integrity": "sha512-y/mWCZinnvxjTKYhJ+pYxwD0mRLVvOtdS2Awbgxln6iEnt4rk0yBxeSBHkGJcPucRiG0e55mwWp+g/05rsrd6w==", - "dev": true + "integrity": "sha512-y/mWCZinnvxjTKYhJ+pYxwD0mRLVvOtdS2Awbgxln6iEnt4rk0yBxeSBHkGJcPucRiG0e55mwWp+g/05rsrd6w==" }, "toposort": { "version": "1.0.7", "resolved": "https://registry.npmjs.org/toposort/-/toposort-1.0.7.tgz", - "integrity": "sha1-LmhELZ9k7HILjMieZEOsbKqVACk=", - "dev": true + "integrity": "sha1-LmhELZ9k7HILjMieZEOsbKqVACk=" }, "tough-cookie": { "version": "2.4.3", "resolved": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-2.4.3.tgz", "integrity": "sha512-Q5srk/4vDM54WJsJio3XNn6K2sCG+CQ8G5Wz6bZhRZoAe/+TxjWB/GlFAnYEbkYVlON9FMk/fE3h2RLpPXo4lQ==", - "dev": true, "requires": { "psl": "^1.1.24", "punycode": "^1.4.1" @@ -8933,34 +8504,24 @@ "punycode": { "version": "1.4.1", "resolved": "https://registry.npmjs.org/punycode/-/punycode-1.4.1.tgz", - "integrity": "sha1-wNWmOycYgArY4esPpSachN1BhF4=", - "dev": true + "integrity": "sha1-wNWmOycYgArY4esPpSachN1BhF4=" } } }, - "trim-right": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/trim-right/-/trim-right-1.0.1.tgz", - "integrity": "sha1-yy4SAwZ+DI3h9hQJS5/kVwTqYAM=", - "dev": true - }, "tslib": { "version": "1.10.0", "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.10.0.tgz", - "integrity": "sha512-qOebF53frne81cf0S9B41ByenJ3/IuH8yJKngAX35CmiZySA0khhkovshKK+jGCaMnVomla7gVlIcc3EvKPbTQ==", - "dev": true + "integrity": "sha512-qOebF53frne81cf0S9B41ByenJ3/IuH8yJKngAX35CmiZySA0khhkovshKK+jGCaMnVomla7gVlIcc3EvKPbTQ==" }, "tty-browserify": { "version": "0.0.0", "resolved": "https://registry.npmjs.org/tty-browserify/-/tty-browserify-0.0.0.tgz", - "integrity": "sha1-oVe6QC2iTpv5V/mqadUk7tQpAaY=", - "dev": true + "integrity": "sha1-oVe6QC2iTpv5V/mqadUk7tQpAaY=" }, "tunnel-agent": { "version": "0.6.0", "resolved": "https://registry.npmjs.org/tunnel-agent/-/tunnel-agent-0.6.0.tgz", "integrity": "sha1-J6XeoGs2sEoKmWZ3SykIaPD8QP0=", - "dev": true, "requires": { "safe-buffer": "^5.0.1" } @@ -8968,20 +8529,17 @@ "tweetnacl": { "version": "0.14.5", "resolved": "https://registry.npmjs.org/tweetnacl/-/tweetnacl-0.14.5.tgz", - "integrity": "sha1-WuaBd/GS1EViadEIr6k/+HQ/T2Q=", - "dev": true + "integrity": "sha1-WuaBd/GS1EViadEIr6k/+HQ/T2Q=" }, "type-fest": { "version": "0.5.2", "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.5.2.tgz", - "integrity": "sha512-DWkS49EQKVX//Tbupb9TFa19c7+MK1XmzkrZUR8TAktmE/DizXoaoJV6TZ/tSIPXipqNiRI6CyAe7x69Jb6RSw==", - "dev": true + "integrity": "sha512-DWkS49EQKVX//Tbupb9TFa19c7+MK1XmzkrZUR8TAktmE/DizXoaoJV6TZ/tSIPXipqNiRI6CyAe7x69Jb6RSw==" }, "type-is": { "version": "1.6.18", "resolved": "https://registry.npmjs.org/type-is/-/type-is-1.6.18.tgz", "integrity": "sha512-TkRKr9sUTxEH8MdfuCSP7VizJyzRNMjj2J2do2Jr3Kym598JVdEksuzPQCnlFPW4ky9Q+iA+ma9BGm06XQBy8g==", - "dev": true, "requires": { "media-typer": "0.3.0", "mime-types": "~2.1.24" @@ -8990,50 +8548,45 @@ "typedarray": { "version": "0.0.6", "resolved": "https://registry.npmjs.org/typedarray/-/typedarray-0.0.6.tgz", - "integrity": "sha1-hnrHTjhkGHsdPUfZlqeOxciDB3c=", - "dev": true + "integrity": "sha1-hnrHTjhkGHsdPUfZlqeOxciDB3c=" }, "uc.micro": { "version": "1.0.6", "resolved": "https://registry.npmjs.org/uc.micro/-/uc.micro-1.0.6.tgz", - "integrity": "sha512-8Y75pvTYkLJW2hWQHXxoqRgV7qb9B+9vFEtidML+7koHUFapnVJAZ6cKs+Qjz5Aw3aZWHMC6u0wJE3At+nSGwA==", - "dev": true + "integrity": "sha512-8Y75pvTYkLJW2hWQHXxoqRgV7qb9B+9vFEtidML+7koHUFapnVJAZ6cKs+Qjz5Aw3aZWHMC6u0wJE3At+nSGwA==" }, "uglify-js": { - "version": "3.4.10", - "resolved": "https://registry.npmjs.org/uglify-js/-/uglify-js-3.4.10.tgz", - "integrity": "sha512-Y2VsbPVs0FIshJztycsO2SfPk7/KAF/T72qzv9u5EpQ4kB2hQoHlhNQTsNyy6ul7lQtqJN/AoWeS23OzEiEFxw==", - "dev": true, + "version": "2.8.29", + "resolved": "https://registry.npmjs.org/uglify-js/-/uglify-js-2.8.29.tgz", + "integrity": "sha1-KcVzMUgFe7Th913zW3qcty5qWd0=", "requires": { - "commander": "~2.19.0", - "source-map": "~0.6.1" + "source-map": "~0.5.1", + "uglify-to-browserify": "~1.0.0", + "yargs": "~3.10.0" }, "dependencies": { - "commander": { - "version": "2.19.0", - "resolved": "https://registry.npmjs.org/commander/-/commander-2.19.0.tgz", - "integrity": "sha512-6tvAOO+D6OENvRAh524Dh9jcfKTYDQAqvqezbCW82xj5X0pSrcpxtvRKHLG0yBY6SD7PSDrJaj+0AiOcKVd1Xg==", - "dev": true - }, "source-map": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", - "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", - "dev": true + "version": "0.5.7", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz", + "integrity": "sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w=" } } }, + "uglify-to-browserify": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/uglify-to-browserify/-/uglify-to-browserify-1.0.2.tgz", + "integrity": "sha1-bgkk1r2mta/jSeOabWMoUKD4grc=", + "optional": true + }, "unicode-canonical-property-names-ecmascript": { "version": "1.0.4", "resolved": "https://registry.npmjs.org/unicode-canonical-property-names-ecmascript/-/unicode-canonical-property-names-ecmascript-1.0.4.tgz", - "integrity": "sha512-jDrNnXWHd4oHiTZnx/ZG7gtUTVp+gCcTTKr8L0HjlwphROEW3+Him+IpvC+xcJEFegapiMZyZe02CyuOnRmbnQ==", - "dev": true + "integrity": "sha512-jDrNnXWHd4oHiTZnx/ZG7gtUTVp+gCcTTKr8L0HjlwphROEW3+Him+IpvC+xcJEFegapiMZyZe02CyuOnRmbnQ==" }, "unicode-match-property-ecmascript": { "version": "1.0.4", "resolved": "https://registry.npmjs.org/unicode-match-property-ecmascript/-/unicode-match-property-ecmascript-1.0.4.tgz", "integrity": "sha512-L4Qoh15vTfntsn4P1zqnHulG0LdXgjSO035fEpdtp6YxXhMT51Q6vgM5lYdG/5X3MjS+k/Y9Xw4SFCY9IkR0rg==", - "dev": true, "requires": { "unicode-canonical-property-names-ecmascript": "^1.0.4", "unicode-property-aliases-ecmascript": "^1.0.4" @@ -9042,20 +8595,17 @@ "unicode-match-property-value-ecmascript": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/unicode-match-property-value-ecmascript/-/unicode-match-property-value-ecmascript-1.1.0.tgz", - "integrity": "sha512-hDTHvaBk3RmFzvSl0UVrUmC3PuW9wKVnpoUDYH0JDkSIovzw+J5viQmeYHxVSBptubnr7PbH2e0fnpDRQnQl5g==", - "dev": true + "integrity": "sha512-hDTHvaBk3RmFzvSl0UVrUmC3PuW9wKVnpoUDYH0JDkSIovzw+J5viQmeYHxVSBptubnr7PbH2e0fnpDRQnQl5g==" }, "unicode-property-aliases-ecmascript": { "version": "1.0.5", "resolved": "https://registry.npmjs.org/unicode-property-aliases-ecmascript/-/unicode-property-aliases-ecmascript-1.0.5.tgz", - "integrity": "sha512-L5RAqCfXqAwR3RriF8pM0lU0w4Ryf/GgzONwi6KnL1taJQa7x1TCxdJnILX59WIGOwR57IVxn7Nej0fz1Ny6fw==", - "dev": true + "integrity": "sha512-L5RAqCfXqAwR3RriF8pM0lU0w4Ryf/GgzONwi6KnL1taJQa7x1TCxdJnILX59WIGOwR57IVxn7Nej0fz1Ny6fw==" }, "union-value": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/union-value/-/union-value-1.0.1.tgz", "integrity": "sha512-tJfXmxMeWYnczCVs7XAEvIV7ieppALdyepWMkHkwciRpZraG/xwT+s2JN8+pr1+8jCRf80FFzvr+MpQeeoF4Xg==", - "dev": true, "requires": { "arr-union": "^3.1.0", "get-value": "^2.0.6", @@ -9066,20 +8616,17 @@ "uniq": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/uniq/-/uniq-1.0.1.tgz", - "integrity": "sha1-sxxa6CVIRKOoKBVBzisEuGWnNP8=", - "dev": true + "integrity": "sha1-sxxa6CVIRKOoKBVBzisEuGWnNP8=" }, "uniqs": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/uniqs/-/uniqs-2.0.0.tgz", - "integrity": "sha1-/+3ks2slKQaW5uFl1KWe25mOawI=", - "dev": true + "integrity": "sha1-/+3ks2slKQaW5uFl1KWe25mOawI=" }, "unique-filename": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/unique-filename/-/unique-filename-1.1.1.tgz", "integrity": "sha512-Vmp0jIp2ln35UTXuryvjzkjGdRyf9b2lTXuSYUiPmzRcl3FDtYqAwOnTJkAngD9SWhnoJzDbTKwaOrZ+STtxNQ==", - "dev": true, "requires": { "unique-slug": "^2.0.0" } @@ -9088,7 +8635,6 @@ "version": "2.0.2", "resolved": "https://registry.npmjs.org/unique-slug/-/unique-slug-2.0.2.tgz", "integrity": "sha512-zoWr9ObaxALD3DOPfjPSqxt4fnZiWblxHIgeWqW8x7UqDzEtHEQLzji2cuJYQFCU6KmoJikOYAZlrTHHebjx2w==", - "dev": true, "requires": { "imurmurhash": "^0.1.4" } @@ -9096,26 +8642,22 @@ "universalify": { "version": "0.1.2", "resolved": "https://registry.npmjs.org/universalify/-/universalify-0.1.2.tgz", - "integrity": "sha512-rBJeI5CXAlmy1pV+617WB9J63U6XcazHHF2f2dbJix4XzpUF0RS3Zbj0FGIOCAva5P/d/GBOYaACQ1w+0azUkg==", - "dev": true + "integrity": "sha512-rBJeI5CXAlmy1pV+617WB9J63U6XcazHHF2f2dbJix4XzpUF0RS3Zbj0FGIOCAva5P/d/GBOYaACQ1w+0azUkg==" }, "unpipe": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/unpipe/-/unpipe-1.0.0.tgz", - "integrity": "sha1-sr9O6FFKrmFltIF4KdIbLvSZBOw=", - "dev": true + "integrity": "sha1-sr9O6FFKrmFltIF4KdIbLvSZBOw=" }, "unquote": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/unquote/-/unquote-1.1.1.tgz", - "integrity": "sha1-j97XMk7G6IoP+LkF58CYzcCG1UQ=", - "dev": true + "integrity": "sha1-j97XMk7G6IoP+LkF58CYzcCG1UQ=" }, "unset-value": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/unset-value/-/unset-value-1.0.0.tgz", "integrity": "sha1-g3aHP30jNRef+x5vw6jtDfyKtVk=", - "dev": true, "requires": { "has-value": "^0.3.1", "isobject": "^3.0.0" @@ -9125,7 +8667,6 @@ "version": "0.3.1", "resolved": "https://registry.npmjs.org/has-value/-/has-value-0.3.1.tgz", "integrity": "sha1-ex9YutpiyoJ+wKIHgCVlSEWZXh8=", - "dev": true, "requires": { "get-value": "^2.0.3", "has-values": "^0.1.4", @@ -9136,7 +8677,6 @@ "version": "2.1.0", "resolved": "https://registry.npmjs.org/isobject/-/isobject-2.1.0.tgz", "integrity": "sha1-8GVWEJaj8dou9GJy+BXIQNh+DIk=", - "dev": true, "requires": { "isarray": "1.0.0" } @@ -9146,28 +8686,24 @@ "has-values": { "version": "0.1.4", "resolved": "https://registry.npmjs.org/has-values/-/has-values-0.1.4.tgz", - "integrity": "sha1-bWHeldkd/Km5oCCJrThL/49it3E=", - "dev": true + "integrity": "sha1-bWHeldkd/Km5oCCJrThL/49it3E=" } } }, "upath": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/upath/-/upath-1.1.2.tgz", - "integrity": "sha512-kXpym8nmDmlCBr7nKdIx8P2jNBa+pBpIUFRnKJ4dr8htyYGJFokkr2ZvERRtUN+9SY+JqXouNgUPtv6JQva/2Q==", - "dev": true + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/upath/-/upath-1.2.0.tgz", + "integrity": "sha512-aZwGpamFO61g3OlfT7OQCHqhGnW43ieH9WZeP7QxN/G/jS4jfqUkZxoryvJgVPEcrl5NL/ggHsSmLMHuH64Lhg==" }, "upper-case": { "version": "1.1.3", "resolved": "https://registry.npmjs.org/upper-case/-/upper-case-1.1.3.tgz", - "integrity": "sha1-9rRQHC7EzdJrp4vnIilh3ndiFZg=", - "dev": true + "integrity": "sha1-9rRQHC7EzdJrp4vnIilh3ndiFZg=" }, "uri-js": { "version": "4.2.2", "resolved": "https://registry.npmjs.org/uri-js/-/uri-js-4.2.2.tgz", "integrity": "sha512-KY9Frmirql91X2Qgjry0Wd4Y+YTdrdZheS8TFwvkbLWf/G5KNJDCh6pKL5OZctEW4+0Baa5idK2ZQuELRwPznQ==", - "dev": true, "requires": { "punycode": "^2.1.0" } @@ -9175,14 +8711,12 @@ "urix": { "version": "0.1.0", "resolved": "https://registry.npmjs.org/urix/-/urix-0.1.0.tgz", - "integrity": "sha1-2pN/emLiH+wf0Y1Js1wpNQZ6bHI=", - "dev": true + "integrity": "sha1-2pN/emLiH+wf0Y1Js1wpNQZ6bHI=" }, "url": { "version": "0.11.0", "resolved": "https://registry.npmjs.org/url/-/url-0.11.0.tgz", "integrity": "sha1-ODjpfPxgUh63PFJajlW/3Z4uKPE=", - "dev": true, "requires": { "punycode": "1.3.2", "querystring": "0.2.0" @@ -9191,8 +8725,7 @@ "punycode": { "version": "1.3.2", "resolved": "https://registry.npmjs.org/punycode/-/punycode-1.3.2.tgz", - "integrity": "sha1-llOgNvt8HuQjQvIyXM7v6jkmxI0=", - "dev": true + "integrity": "sha1-llOgNvt8HuQjQvIyXM7v6jkmxI0=" } } }, @@ -9200,7 +8733,6 @@ "version": "1.1.2", "resolved": "https://registry.npmjs.org/url-loader/-/url-loader-1.1.2.tgz", "integrity": "sha512-dXHkKmw8FhPqu8asTc1puBfe3TehOCo2+RmOOev5suNCIYBcT626kxiWg1NBVkwc4rO8BGa7gP70W7VXuqHrjg==", - "dev": true, "requires": { "loader-utils": "^1.1.0", "mime": "^2.0.3", @@ -9211,7 +8743,6 @@ "version": "1.4.7", "resolved": "https://registry.npmjs.org/url-parse/-/url-parse-1.4.7.tgz", "integrity": "sha512-d3uaVyzDB9tQoSXFvuSUNFibTd9zxd2bkVrDRvF5TmvWWQwqE4lgYJ5m+x1DbecWkw+LK4RNl2CU1hHuOKPVlg==", - "dev": true, "requires": { "querystringify": "^2.1.1", "requires-port": "^1.0.0" @@ -9220,14 +8751,12 @@ "use": { "version": "3.1.1", "resolved": "https://registry.npmjs.org/use/-/use-3.1.1.tgz", - "integrity": "sha512-cwESVXlO3url9YWlFW/TA9cshCEhtu7IKJ/p5soJ/gGpj7vbvFrAY/eIioQ6Dw23KjZhYgiIo8HOs1nQ2vr/oQ==", - "dev": true + "integrity": "sha512-cwESVXlO3url9YWlFW/TA9cshCEhtu7IKJ/p5soJ/gGpj7vbvFrAY/eIioQ6Dw23KjZhYgiIo8HOs1nQ2vr/oQ==" }, "util": { "version": "0.11.1", "resolved": "https://registry.npmjs.org/util/-/util-0.11.1.tgz", "integrity": "sha512-HShAsny+zS2TZfaXxD9tYj4HQGlBezXZMZuM/S5PKLLoZkShZiGk9o5CzukI1LVHZvjdvZ2Sj1aW/Ndn2NB/HQ==", - "dev": true, "requires": { "inherits": "2.0.3" }, @@ -9235,22 +8764,19 @@ "inherits": { "version": "2.0.3", "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.3.tgz", - "integrity": "sha1-Yzwsg+PaQqUC9SRmAiSA9CCCYd4=", - "dev": true + "integrity": "sha1-Yzwsg+PaQqUC9SRmAiSA9CCCYd4=" } } }, "util-deprecate": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz", - "integrity": "sha1-RQ1Nyfpw3nMnYvvS1KKJgUGaDM8=", - "dev": true + "integrity": "sha1-RQ1Nyfpw3nMnYvvS1KKJgUGaDM8=" }, "util.promisify": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/util.promisify/-/util.promisify-1.0.0.tgz", "integrity": "sha512-i+6qA2MPhvoKLuxnJNpXAGhg7HphQOSUq2LKMZD0m15EiskXUkMvKdF4Uui0WYeCUGea+o2cw/ZuwehtfsrNkA==", - "dev": true, "requires": { "define-properties": "^1.1.2", "object.getownpropertydescriptors": "^2.0.3" @@ -9259,38 +8785,32 @@ "utila": { "version": "0.4.0", "resolved": "https://registry.npmjs.org/utila/-/utila-0.4.0.tgz", - "integrity": "sha1-ihagXURWV6Oupe7MWxKk+lN5dyw=", - "dev": true + "integrity": "sha1-ihagXURWV6Oupe7MWxKk+lN5dyw=" }, "utils-merge": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/utils-merge/-/utils-merge-1.0.1.tgz", - "integrity": "sha1-n5VxD1CiZ5R7LMwSR0HBAoQn5xM=", - "dev": true + "integrity": "sha1-n5VxD1CiZ5R7LMwSR0HBAoQn5xM=" }, "uuid": { - "version": "3.3.2", - "resolved": "https://registry.npmjs.org/uuid/-/uuid-3.3.2.tgz", - "integrity": "sha512-yXJmeNaw3DnnKAOKJE51sL/ZaYfWJRl1pK9dr19YFCu0ObS231AB1/LbqTKRAQ5kw8A90rA6fr4riOUpTZvQZA==", - "dev": true + "version": "3.3.3", + "resolved": "https://registry.npmjs.org/uuid/-/uuid-3.3.3.tgz", + "integrity": "sha512-pW0No1RGHgzlpHJO1nsVrHKpOEIxkGg1xB+v0ZmdNH5OAeAwzAVrCnI2/6Mtx+Uys6iaylxa+D3g4j63IKKjSQ==" }, "vary": { "version": "1.1.2", "resolved": "https://registry.npmjs.org/vary/-/vary-1.1.2.tgz", - "integrity": "sha1-IpnwLG3tMNSllhsLn3RSShj2NPw=", - "dev": true + "integrity": "sha1-IpnwLG3tMNSllhsLn3RSShj2NPw=" }, "vendors": { "version": "1.0.3", "resolved": "https://registry.npmjs.org/vendors/-/vendors-1.0.3.tgz", - "integrity": "sha512-fOi47nsJP5Wqefa43kyWSg80qF+Q3XA6MUkgi7Hp1HQaKDQW4cQrK2D0P7mmbFtsV1N89am55Yru/nyEwRubcw==", - "dev": true + "integrity": "sha512-fOi47nsJP5Wqefa43kyWSg80qF+Q3XA6MUkgi7Hp1HQaKDQW4cQrK2D0P7mmbFtsV1N89am55Yru/nyEwRubcw==" }, "verror": { "version": "1.10.0", "resolved": "https://registry.npmjs.org/verror/-/verror-1.10.0.tgz", "integrity": "sha1-OhBcoXBTr1XW4nDB+CiGguGNpAA=", - "dev": true, "requires": { "assert-plus": "^1.0.0", "core-util-is": "1.0.2", @@ -9300,28 +8820,29 @@ "vm-browserify": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/vm-browserify/-/vm-browserify-1.1.0.tgz", - "integrity": "sha512-iq+S7vZJE60yejDYM0ek6zg308+UZsdtPExWP9VZoCFCz1zkJoXFnAX7aZfd/ZwrkidzdUZL0C/ryW+JwAiIGw==", - "dev": true + "integrity": "sha512-iq+S7vZJE60yejDYM0ek6zg308+UZsdtPExWP9VZoCFCz1zkJoXFnAX7aZfd/ZwrkidzdUZL0C/ryW+JwAiIGw==" + }, + "void-elements": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/void-elements/-/void-elements-2.0.1.tgz", + "integrity": "sha1-wGavtYK7HLQSjWDqkjkulNXp2+w=" }, "vue": { "version": "2.6.10", "resolved": "https://registry.npmjs.org/vue/-/vue-2.6.10.tgz", - "integrity": "sha512-ImThpeNU9HbdZL3utgMCq0oiMzAkt1mcgy3/E6zWC/G6AaQoeuFdsl9nDhTDU3X1R6FK7nsIUuRACVcjI+A2GQ==", - "dev": true + "integrity": "sha512-ImThpeNU9HbdZL3utgMCq0oiMzAkt1mcgy3/E6zWC/G6AaQoeuFdsl9nDhTDU3X1R6FK7nsIUuRACVcjI+A2GQ==" }, "vue-hot-reload-api": { - "version": "2.3.3", - "resolved": "https://registry.npmjs.org/vue-hot-reload-api/-/vue-hot-reload-api-2.3.3.tgz", - "integrity": "sha512-KmvZVtmM26BQOMK1rwUZsrqxEGeKiYSZGA7SNWE6uExx8UX/cj9hq2MRV/wWC3Cq6AoeDGk57rL9YMFRel/q+g==", - "dev": true + "version": "2.3.4", + "resolved": "https://registry.npmjs.org/vue-hot-reload-api/-/vue-hot-reload-api-2.3.4.tgz", + "integrity": "sha512-BXq3jwIagosjgNVae6tkHzzIk6a8MHFtzAdwhnV5VlvPTFxDCvIttgSiHWjdGoTJvXtmRu5HacExfdarRcFhog==" }, "vue-loader": { - "version": "15.7.0", - "resolved": "https://registry.npmjs.org/vue-loader/-/vue-loader-15.7.0.tgz", - "integrity": "sha512-x+NZ4RIthQOxcFclEcs8sXGEWqnZHodL2J9Vq+hUz+TDZzBaDIh1j3d9M2IUlTjtrHTZy4uMuRdTi8BGws7jLA==", - "dev": true, + "version": "15.7.1", + "resolved": "https://registry.npmjs.org/vue-loader/-/vue-loader-15.7.1.tgz", + "integrity": "sha512-fwIKtA23Pl/rqfYP5TSGK7gkEuLhoTvRYW+TU7ER3q9GpNLt/PjG5NLv3XHRDiTg7OPM1JcckBgds+VnAc+HbA==", "requires": { - "@vue/component-compiler-utils": "^2.5.1", + "@vue/component-compiler-utils": "^3.0.0", "hash-sum": "^1.0.2", "loader-utils": "^1.1.0", "vue-hot-reload-api": "^2.3.0", @@ -9329,16 +8850,14 @@ } }, "vue-router": { - "version": "3.0.6", - "resolved": "https://registry.npmjs.org/vue-router/-/vue-router-3.0.6.tgz", - "integrity": "sha512-Ox0ciFLswtSGRTHYhGvx2L44sVbTPNS+uD2kRISuo8B39Y79rOo0Kw0hzupTmiVtftQYCZl87mwldhh2L9Aquw==", - "dev": true + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/vue-router/-/vue-router-3.1.3.tgz", + "integrity": "sha512-8iSa4mGNXBjyuSZFCCO4fiKfvzqk+mhL0lnKuGcQtO1eoj8nq3CmbEG8FwK5QqoqwDgsjsf1GDuisDX4cdb/aQ==" }, "vue-server-renderer": { "version": "2.6.10", "resolved": "https://registry.npmjs.org/vue-server-renderer/-/vue-server-renderer-2.6.10.tgz", "integrity": "sha512-UYoCEutBpKzL2fKCwx8zlRtRtwxbPZXKTqbl2iIF4yRZUNO/ovrHyDAJDljft0kd+K0tZhN53XRHkgvCZoIhug==", - "dev": true, "requires": { "chalk": "^1.1.3", "hash-sum": "^1.0.2", @@ -9353,14 +8872,12 @@ "ansi-styles": { "version": "2.2.1", "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-2.2.1.tgz", - "integrity": "sha1-tDLdM1i2NM914eRmQ2gkBTPB3b4=", - "dev": true + "integrity": "sha1-tDLdM1i2NM914eRmQ2gkBTPB3b4=" }, "chalk": { "version": "1.1.3", "resolved": "https://registry.npmjs.org/chalk/-/chalk-1.1.3.tgz", "integrity": "sha1-qBFcVeSnAv5NFQq9OHKCKn4J/Jg=", - "dev": true, "requires": { "ansi-styles": "^2.2.1", "escape-string-regexp": "^1.0.2", @@ -9372,14 +8889,12 @@ "source-map": { "version": "0.5.6", "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.6.tgz", - "integrity": "sha1-dc449SvwczxafwwRjYEzSiu19BI=", - "dev": true + "integrity": "sha1-dc449SvwczxafwwRjYEzSiu19BI=" }, "supports-color": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-2.0.0.tgz", - "integrity": "sha1-U10EXOa2Nj+kARcIRimZXp3zJMc=", - "dev": true + "integrity": "sha1-U10EXOa2Nj+kARcIRimZXp3zJMc=" } } }, @@ -9387,7 +8902,6 @@ "version": "4.1.2", "resolved": "https://registry.npmjs.org/vue-style-loader/-/vue-style-loader-4.1.2.tgz", "integrity": "sha512-0ip8ge6Gzz/Bk0iHovU9XAUQaFt/G2B61bnWa2tCcqqdgfHs1lF9xXorFbE55Gmy92okFT+8bfmySuUOu13vxQ==", - "dev": true, "requires": { "hash-sum": "^1.0.2", "loader-utils": "^1.0.2" @@ -9397,7 +8911,6 @@ "version": "2.6.10", "resolved": "https://registry.npmjs.org/vue-template-compiler/-/vue-template-compiler-2.6.10.tgz", "integrity": "sha512-jVZkw4/I/HT5ZMvRnhv78okGusqe0+qH2A0Em0Cp8aq78+NK9TII263CDVz2QXZsIT+yyV/gZc/j/vlwa+Epyg==", - "dev": true, "requires": { "de-indent": "^1.0.2", "he": "^1.1.0" @@ -9406,26 +8919,24 @@ "vue-template-es2015-compiler": { "version": "1.9.1", "resolved": "https://registry.npmjs.org/vue-template-es2015-compiler/-/vue-template-es2015-compiler-1.9.1.tgz", - "integrity": "sha512-4gDntzrifFnCEvyoO8PqyJDmguXgVPxKiIxrBKjIowvL9l+N66196+72XVYR8BBf1Uv1Fgt3bGevJ+sEmxfZzw==", - "dev": true + "integrity": "sha512-4gDntzrifFnCEvyoO8PqyJDmguXgVPxKiIxrBKjIowvL9l+N66196+72XVYR8BBf1Uv1Fgt3bGevJ+sEmxfZzw==" }, "vuepress": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/vuepress/-/vuepress-1.0.2.tgz", - "integrity": "sha512-HPRWxrq6D+S9uCR3oJ8/OTCy8GcYm9l1HxHb44rvaN2gyySVXIiqSkCwzd9r2PY8+pwvrfYE4rcY1RsTTpJ25g==", - "dev": true, + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/vuepress/-/vuepress-1.2.0.tgz", + "integrity": "sha512-EfHo8Cc73qo+1Pm18hM0qOGynmDr8q5fu2664obynsdCJ1zpvoShVnA0Msraw4SI2xDc0iAoIb3dTwxUIM8DAw==", "requires": { - "@vuepress/core": "^1.0.2", - "@vuepress/theme-default": "^1.0.2", + "@vuepress/core": "^1.2.0", + "@vuepress/theme-default": "^1.2.0", "cac": "^6.3.9", - "envinfo": "^7.2.0" + "envinfo": "^7.2.0", + "opencollective-postinstall": "^2.0.2" } }, "vuepress-html-webpack-plugin": { "version": "3.2.0", "resolved": "https://registry.npmjs.org/vuepress-html-webpack-plugin/-/vuepress-html-webpack-plugin-3.2.0.tgz", "integrity": "sha512-BebAEl1BmWlro3+VyDhIOCY6Gef2MCBllEVAP3NUAtMguiyOwo/dClbwJ167WYmcxHJKLl7b0Chr9H7fpn1d0A==", - "dev": true, "requires": { "html-minifier": "^3.2.3", "loader-utils": "^0.2.16", @@ -9439,20 +8950,17 @@ "big.js": { "version": "3.2.0", "resolved": "https://registry.npmjs.org/big.js/-/big.js-3.2.0.tgz", - "integrity": "sha512-+hN/Zh2D08Mx65pZ/4g5bsmNiZUuChDiQfTUQ7qJr4/kuopCr88xZsAXv6mBoZEsUI4OuGHlX59qE94K2mMW8Q==", - "dev": true + "integrity": "sha512-+hN/Zh2D08Mx65pZ/4g5bsmNiZUuChDiQfTUQ7qJr4/kuopCr88xZsAXv6mBoZEsUI4OuGHlX59qE94K2mMW8Q==" }, "json5": { "version": "0.5.1", "resolved": "https://registry.npmjs.org/json5/-/json5-0.5.1.tgz", - "integrity": "sha1-Hq3nrMASA0rYTiOWdn6tn6VJWCE=", - "dev": true + "integrity": "sha1-Hq3nrMASA0rYTiOWdn6tn6VJWCE=" }, "loader-utils": { "version": "0.2.17", "resolved": "https://registry.npmjs.org/loader-utils/-/loader-utils-0.2.17.tgz", "integrity": "sha1-+G5jdNQyBabmxg6RlvF8Apm/s0g=", - "dev": true, "requires": { "big.js": "^3.1.3", "emojis-list": "^2.0.0", @@ -9463,19 +8971,41 @@ } }, "vuepress-plugin-container": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/vuepress-plugin-container/-/vuepress-plugin-container-2.0.1.tgz", - "integrity": "sha512-SMlWJl0uZYkqAxD2RUZmIrANZWKgiZdM64K7WmdyHyQPYI+NUj3ugi5D+zDn62BoO9NfQTiskEIa2u619SRweA==", - "dev": true, + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/vuepress-plugin-container/-/vuepress-plugin-container-2.1.0.tgz", + "integrity": "sha512-i4p7S1cqYUrg/3pt+xSghZtKSHVI3VXMQNept8ILxA+lMK1XJkdRkjNovZzwpXlrErQssvrUOTWBV0hdBv7eXQ==", "requires": { "markdown-it-container": "^2.0.0" } }, + "vuepress-plugin-smooth-scroll": { + "version": "0.0.3", + "resolved": "https://registry.npmjs.org/vuepress-plugin-smooth-scroll/-/vuepress-plugin-smooth-scroll-0.0.3.tgz", + "integrity": "sha512-qsQkDftLVFLe8BiviIHaLV0Ea38YLZKKonDGsNQy1IE0wllFpFIEldWD8frWZtDFdx6b/O3KDMgVQ0qp5NjJCg==", + "requires": { + "smoothscroll-polyfill": "^0.4.3" + } + }, + "vuepress-theme-cosmos": { + "version": "1.0.35", + "resolved": "https://registry.npmjs.org/vuepress-theme-cosmos/-/vuepress-theme-cosmos-1.0.35.tgz", + "integrity": "sha512-JB8674x4izaCMpRgG+GKYslA9KiiyhpfCjG8LpWg2//ynnZGUlPW9R+fzciM9+KIfU5eC4G7bquQwf19Nqi3Xg==", + "requires": { + "@cosmos-ui/vue": "^0.5.11", + "@vuepress/plugin-last-updated": "^1.2.0", + "@vuepress/plugin-search": "^1.1.0", + "pug": "^2.0.4", + "pug-plain-loader": "^1.0.0", + "stylus": "^0.54.7", + "stylus-loader": "^3.0.2", + "tm-tooltip": "0.0.10", + "vuepress": "^1.1.0" + } + }, "watchpack": { "version": "1.6.0", "resolved": "https://registry.npmjs.org/watchpack/-/watchpack-1.6.0.tgz", "integrity": "sha512-i6dHe3EyLjMmDlU1/bGQpEw25XSjkJULPuAVKCbNRefQVq48yXKUpwg538F7AZTf9kyr57zj++pQFltUa5H7yA==", - "dev": true, "requires": { "chokidar": "^2.0.2", "graceful-fs": "^4.1.2", @@ -9486,118 +9016,220 @@ "version": "1.7.3", "resolved": "https://registry.npmjs.org/wbuf/-/wbuf-1.7.3.tgz", "integrity": "sha512-O84QOnr0icsbFGLS0O3bI5FswxzRr8/gHwWkDlQFskhSPryQXvrTMxjxGP4+iWYoauLoBvfDpkrOauZ+0iZpDA==", - "dev": true, "requires": { "minimalistic-assert": "^1.0.0" } }, "webpack": { - "version": "4.35.0", - "resolved": "https://registry.npmjs.org/webpack/-/webpack-4.35.0.tgz", - "integrity": "sha512-M5hL3qpVvtr8d4YaJANbAQBc4uT01G33eDpl/psRTBCfjxFTihdhin1NtAKB1ruDwzeVdcsHHV3NX+QsAgOosw==", - "dev": true, + "version": "4.41.2", + "resolved": "https://registry.npmjs.org/webpack/-/webpack-4.41.2.tgz", + "integrity": "sha512-Zhw69edTGfbz9/8JJoyRQ/pq8FYUoY0diOXqW0T6yhgdhCv6wr0hra5DwwWexNRns2Z2+gsnrNcbe9hbGBgk/A==", "requires": { "@webassemblyjs/ast": "1.8.5", "@webassemblyjs/helper-module-context": "1.8.5", "@webassemblyjs/wasm-edit": "1.8.5", "@webassemblyjs/wasm-parser": "1.8.5", - "acorn": "^6.0.5", - "acorn-dynamic-import": "^4.0.0", - "ajv": "^6.1.0", - "ajv-keywords": "^3.1.0", - "chrome-trace-event": "^1.0.0", + "acorn": "^6.2.1", + "ajv": "^6.10.2", + "ajv-keywords": "^3.4.1", + "chrome-trace-event": "^1.0.2", "enhanced-resolve": "^4.1.0", - "eslint-scope": "^4.0.0", + "eslint-scope": "^4.0.3", "json-parse-better-errors": "^1.0.2", - "loader-runner": "^2.3.0", - "loader-utils": "^1.1.0", - "memory-fs": "~0.4.1", - "micromatch": "^3.1.8", - "mkdirp": "~0.5.0", - "neo-async": "^2.5.0", - "node-libs-browser": "^2.0.0", + "loader-runner": "^2.4.0", + "loader-utils": "^1.2.3", + "memory-fs": "^0.4.1", + "micromatch": "^3.1.10", + "mkdirp": "^0.5.1", + "neo-async": "^2.6.1", + "node-libs-browser": "^2.2.1", "schema-utils": "^1.0.0", - "tapable": "^1.1.0", - "terser-webpack-plugin": "^1.1.0", - "watchpack": "^1.5.0", - "webpack-sources": "^1.3.0" + "tapable": "^1.1.3", + "terser-webpack-plugin": "^1.4.1", + "watchpack": "^1.6.0", + "webpack-sources": "^1.4.1" + }, + "dependencies": { + "acorn": { + "version": "6.3.0", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-6.3.0.tgz", + "integrity": "sha512-/czfa8BwS88b9gWQVhc8eknunSA2DoJpJyTQkhheIf5E48u1N0R4q/YxxsAeqRrmK9TQ/uYfgLDfZo91UlANIA==" + } } }, "webpack-chain": { "version": "4.12.1", "resolved": "https://registry.npmjs.org/webpack-chain/-/webpack-chain-4.12.1.tgz", "integrity": "sha512-BCfKo2YkDe2ByqkEWe1Rw+zko4LsyS75LVr29C6xIrxAg9JHJ4pl8kaIZ396SUSNp6b4815dRZPSTAS8LlURRQ==", - "dev": true, "requires": { "deepmerge": "^1.5.2", "javascript-stringify": "^1.6.0" } }, "webpack-dev-middleware": { - "version": "3.7.0", - "resolved": "https://registry.npmjs.org/webpack-dev-middleware/-/webpack-dev-middleware-3.7.0.tgz", - "integrity": "sha512-qvDesR1QZRIAZHOE3iQ4CXLZZSQ1lAUsSpnQmlB1PBfoN/xdRjmge3Dok0W4IdaVLJOGJy3sGI4sZHwjRU0PCA==", - "dev": true, + "version": "3.7.2", + "resolved": "https://registry.npmjs.org/webpack-dev-middleware/-/webpack-dev-middleware-3.7.2.tgz", + "integrity": "sha512-1xC42LxbYoqLNAhV6YzTYacicgMZQTqRd27Sim9wn5hJrX3I5nxYy1SxSd4+gjUFsz1dQFj+yEe6zEVmSkeJjw==", "requires": { "memory-fs": "^0.4.1", - "mime": "^2.4.2", + "mime": "^2.4.4", + "mkdirp": "^0.5.1", "range-parser": "^1.2.1", "webpack-log": "^2.0.0" } }, "webpack-dev-server": { - "version": "3.7.2", - "resolved": "https://registry.npmjs.org/webpack-dev-server/-/webpack-dev-server-3.7.2.tgz", - "integrity": "sha512-mjWtrKJW2T9SsjJ4/dxDC2fkFVUw8jlpemDERqV0ZJIkjjjamR2AbQlr3oz+j4JLhYCHImHnXZK5H06P2wvUew==", - "dev": true, + "version": "3.9.0", + "resolved": "https://registry.npmjs.org/webpack-dev-server/-/webpack-dev-server-3.9.0.tgz", + "integrity": "sha512-E6uQ4kRrTX9URN9s/lIbqTAztwEPdvzVrcmHE8EQ9YnuT9J8Es5Wrd8n9BKg1a0oZ5EgEke/EQFgUsp18dSTBw==", "requires": { "ansi-html": "0.0.7", "bonjour": "^3.5.0", - "chokidar": "^2.1.6", + "chokidar": "^2.1.8", "compression": "^1.7.4", "connect-history-api-fallback": "^1.6.0", "debug": "^4.1.1", "del": "^4.1.1", "express": "^4.17.1", "html-entities": "^1.2.1", - "http-proxy-middleware": "^0.19.1", + "http-proxy-middleware": "0.19.1", "import-local": "^2.0.0", "internal-ip": "^4.3.0", "ip": "^1.1.5", + "is-absolute-url": "^3.0.3", "killable": "^1.0.1", - "loglevel": "^1.6.3", + "loglevel": "^1.6.4", "opn": "^5.5.0", "p-retry": "^3.0.1", - "portfinder": "^1.0.20", + "portfinder": "^1.0.25", "schema-utils": "^1.0.0", - "selfsigned": "^1.10.4", - "semver": "^6.1.1", + "selfsigned": "^1.10.7", + "semver": "^6.3.0", "serve-index": "^1.9.1", "sockjs": "0.3.19", - "sockjs-client": "1.3.0", - "spdy": "^4.0.0", + "sockjs-client": "1.4.0", + "spdy": "^4.0.1", "strip-ansi": "^3.0.1", "supports-color": "^6.1.0", "url": "^0.11.0", - "webpack-dev-middleware": "^3.7.0", + "webpack-dev-middleware": "^3.7.2", "webpack-log": "^2.0.0", + "ws": "^6.2.1", "yargs": "12.0.5" }, "dependencies": { + "ansi-regex": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-3.0.0.tgz", + "integrity": "sha1-7QMXwyIGT3lGbAKWa922Bas32Zg=" + }, + "cliui": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/cliui/-/cliui-4.1.0.tgz", + "integrity": "sha512-4FG+RSG9DL7uEwRUZXZn3SS34DiDPfzP0VOiEwtUWlE+AR2EIg+hSyvrIgUUfhdgR/UkAeW2QHgeP+hWrXs7jQ==", + "requires": { + "string-width": "^2.1.1", + "strip-ansi": "^4.0.0", + "wrap-ansi": "^2.0.0" + }, + "dependencies": { + "strip-ansi": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-4.0.0.tgz", + "integrity": "sha1-qEeQIusaw2iocTibY1JixQXuNo8=", + "requires": { + "ansi-regex": "^3.0.0" + } + } + } + }, + "debug": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.1.1.tgz", + "integrity": "sha512-pYAIzeRo8J6KPEaJ0VWOh5Pzkbw/RetuzehGM7QRRX5he4fPHx2rdKMB256ehJCkX+XRQm16eZLqLNS8RSZXZw==", + "requires": { + "ms": "^2.1.1" + } + }, + "find-up": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-3.0.0.tgz", + "integrity": "sha512-1yD6RmLI1XBfxugvORwlck6f75tYL+iR0jqwsOrOxMZyGYqUuDhJ0l4AXdO1iX/FTs9cBAMEk1gWSEx1kSbylg==", + "requires": { + "locate-path": "^3.0.0" + } + }, + "is-absolute-url": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/is-absolute-url/-/is-absolute-url-3.0.3.tgz", + "integrity": "sha512-opmNIX7uFnS96NtPmhWQgQx6/NYFgsUXYMllcfzwWKUMwfo8kku1TvE6hkNcH+Q1ts5cMVrsY7j0bxXQDciu9Q==" + }, + "locate-path": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-3.0.0.tgz", + "integrity": "sha512-7AO748wWnIhNqAuaty2ZWHkQHRSNfPVIsPIfwEOWO22AmaoVrWavlOcMR5nzTLNYvp36X220/maaRsrec1G65A==", + "requires": { + "p-locate": "^3.0.0", + "path-exists": "^3.0.0" + } + }, + "ms": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", + "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==" + }, + "p-limit": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.2.1.tgz", + "integrity": "sha512-85Tk+90UCVWvbDavCLKPOLC9vvY8OwEX/RtKF+/1OADJMVlFfEHOiMTPVyxg7mk/dKa+ipdHm0OUkTvCpMTuwg==", + "requires": { + "p-try": "^2.0.0" + } + }, + "p-locate": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-3.0.0.tgz", + "integrity": "sha512-x+12w/To+4GFfgJhBEpiDcLozRJGegY+Ei7/z0tSLkMmxGZNybVMSfWj9aJn8Z5Fc7dBUNJOOVgPv2H7IwulSQ==", + "requires": { + "p-limit": "^2.0.0" + } + }, + "p-try": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/p-try/-/p-try-2.2.0.tgz", + "integrity": "sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ==" + }, "semver": { - "version": "6.1.2", - "resolved": "https://registry.npmjs.org/semver/-/semver-6.1.2.tgz", - "integrity": "sha512-z4PqiCpomGtWj8633oeAdXm1Kn1W++3T8epkZYnwiVgIYIJ0QHszhInYSJTYxebByQH7KVCEAn8R9duzZW2PhQ==", - "dev": true + "version": "6.3.0", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", + "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==" }, "supports-color": { "version": "6.1.0", "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-6.1.0.tgz", "integrity": "sha512-qe1jfm1Mg7Nq/NSh6XE24gPXROEVsWHxC1LIx//XNlD9iw7YZQGjZNjYN7xGaEG6iKdA8EtNFW6R0gjnVXp+wQ==", - "dev": true, "requires": { "has-flag": "^3.0.0" } + }, + "yargs": { + "version": "12.0.5", + "resolved": "https://registry.npmjs.org/yargs/-/yargs-12.0.5.tgz", + "integrity": "sha512-Lhz8TLaYnxq/2ObqHDql8dX8CJi97oHxrjUcYtzKbbykPtVW9WB+poxI+NM2UIzsMgNCZTIf0AQwsjK5yMAqZw==", + "requires": { + "cliui": "^4.0.0", + "decamelize": "^1.2.0", + "find-up": "^3.0.0", + "get-caller-file": "^1.0.1", + "os-locale": "^3.0.0", + "require-directory": "^2.1.1", + "require-main-filename": "^1.0.1", + "set-blocking": "^2.0.0", + "string-width": "^2.0.0", + "which-module": "^2.0.0", + "y18n": "^3.2.1 || ^4.0.0", + "yargs-parser": "^11.1.1" + } } } }, @@ -9605,44 +9237,32 @@ "version": "2.0.0", "resolved": "https://registry.npmjs.org/webpack-log/-/webpack-log-2.0.0.tgz", "integrity": "sha512-cX8G2vR/85UYG59FgkoMamwHUIkSSlV3bBMRsbxVXVUk2j6NleCKjQ/WE9eYg9WY4w25O9w8wKP4rzNZFmUcUg==", - "dev": true, "requires": { "ansi-colors": "^3.0.0", "uuid": "^3.3.2" } }, "webpack-merge": { - "version": "4.2.1", - "resolved": "https://registry.npmjs.org/webpack-merge/-/webpack-merge-4.2.1.tgz", - "integrity": "sha512-4p8WQyS98bUJcCvFMbdGZyZmsKuWjWVnVHnAS3FFg0HDaRVrPbkivx2RYCre8UiemD67RsiFFLfn4JhLAin8Vw==", - "dev": true, + "version": "4.2.2", + "resolved": "https://registry.npmjs.org/webpack-merge/-/webpack-merge-4.2.2.tgz", + "integrity": "sha512-TUE1UGoTX2Cd42j3krGYqObZbOD+xF7u28WB7tfUordytSjbWTIjK/8V0amkBfTYN4/pB/GIDlJZZ657BGG19g==", "requires": { - "lodash": "^4.17.5" + "lodash": "^4.17.15" } }, "webpack-sources": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/webpack-sources/-/webpack-sources-1.3.0.tgz", - "integrity": "sha512-OiVgSrbGu7NEnEvQJJgdSFPl2qWKkWq5lHMhgiToIiN9w34EBnjYzSYs+VbL5KoYiLNtFFa7BZIKxRED3I32pA==", - "dev": true, + "version": "1.4.3", + "resolved": "https://registry.npmjs.org/webpack-sources/-/webpack-sources-1.4.3.tgz", + "integrity": "sha512-lgTS3Xhv1lCOKo7SA5TjKXMjpSM4sBjNV5+q2bqesbSPs5FjGmU6jjtBSkX9b4qW87vDIsCIlUPOEhbZrMdjeQ==", "requires": { "source-list-map": "^2.0.0", "source-map": "~0.6.1" - }, - "dependencies": { - "source-map": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", - "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", - "dev": true - } } }, "webpackbar": { "version": "3.2.0", "resolved": "https://registry.npmjs.org/webpackbar/-/webpackbar-3.2.0.tgz", "integrity": "sha512-PC4o+1c8gWWileUfwabe0gqptlXUDJd5E0zbpr2xHP1VSOVlZVPBZ8j6NCR8zM5zbKdxPhctHXahgpNK1qFDPw==", - "dev": true, "requires": { "ansi-escapes": "^4.1.0", "chalk": "^2.4.1", @@ -9657,14 +9277,12 @@ "ansi-regex": { "version": "4.1.0", "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-4.1.0.tgz", - "integrity": "sha512-1apePfXM1UOSqw0o9IiFAovVz9M5S1Dg+4TrDwfMewQ6p/rmMueb7tWZjQ1rx4Loy1ArBggoqGpfqqdI4rondg==", - "dev": true + "integrity": "sha512-1apePfXM1UOSqw0o9IiFAovVz9M5S1Dg+4TrDwfMewQ6p/rmMueb7tWZjQ1rx4Loy1ArBggoqGpfqqdI4rondg==" }, "string-width": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/string-width/-/string-width-3.1.0.tgz", "integrity": "sha512-vafcv6KjVZKSgz06oM/H6GDBrAtz8vdhQakGjFIvNrHA6y3HCF1CInLy+QLq8dTJPQ1b+KDUqDFctkdRW44e1w==", - "dev": true, "requires": { "emoji-regex": "^7.0.1", "is-fullwidth-code-point": "^2.0.0", @@ -9675,7 +9293,6 @@ "version": "5.2.0", "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-5.2.0.tgz", "integrity": "sha512-DuRs1gKbBqsMKIZlrffwlug8MHkcnpjs5VPmL1PAh+mA30U0DTotfDZ0d2UUsXpPmPmMMJ6W773MaA3J+lbiWA==", - "dev": true, "requires": { "ansi-regex": "^4.1.0" } @@ -9684,7 +9301,6 @@ "version": "5.1.0", "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-5.1.0.tgz", "integrity": "sha512-QC1/iN/2/RPVJ5jYK8BGttj5z83LmSKmvbvrXPNCLZSEb32KKVDJDl/MOt2N01qU2H/FkzEa9PKto1BqDjtd7Q==", - "dev": true, "requires": { "ansi-styles": "^3.2.0", "string-width": "^3.0.0", @@ -9697,7 +9313,6 @@ "version": "0.7.3", "resolved": "https://registry.npmjs.org/websocket-driver/-/websocket-driver-0.7.3.tgz", "integrity": "sha512-bpxWlvbbB459Mlipc5GBzzZwhoZgGEZLuqPaR0INBGnPAY1vdBX6hPnoFXiw+3yWxDuHyQjO2oXTMyS8A5haFg==", - "dev": true, "requires": { "http-parser-js": ">=0.4.0 <0.4.11", "safe-buffer": ">=5.1.0", @@ -9707,20 +9322,17 @@ "websocket-extensions": { "version": "0.1.3", "resolved": "https://registry.npmjs.org/websocket-extensions/-/websocket-extensions-0.1.3.tgz", - "integrity": "sha512-nqHUnMXmBzT0w570r2JpJxfiSD1IzoI+HGVdd3aZ0yNi3ngvQ4jv1dtHt5VGxfI2yj5yqImPhOK4vmIh2xMbGg==", - "dev": true + "integrity": "sha512-nqHUnMXmBzT0w570r2JpJxfiSD1IzoI+HGVdd3aZ0yNi3ngvQ4jv1dtHt5VGxfI2yj5yqImPhOK4vmIh2xMbGg==" }, "when": { "version": "3.6.4", "resolved": "https://registry.npmjs.org/when/-/when-3.6.4.tgz", - "integrity": "sha1-RztRfsFZ4rhQBUl6E5g/CVQS404=", - "dev": true + "integrity": "sha1-RztRfsFZ4rhQBUl6E5g/CVQS404=" }, "which": { "version": "1.3.1", "resolved": "https://registry.npmjs.org/which/-/which-1.3.1.tgz", "integrity": "sha512-HxJdYWq1MTIQbJ3nw0cqssHoTNU267KlrDuGZ1WYlxDStUtKUhOaJmh112/TZmHxxUfuJqPXSOm7tDyas0OSIQ==", - "dev": true, "requires": { "isexe": "^2.0.0" } @@ -9728,14 +9340,31 @@ "which-module": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/which-module/-/which-module-2.0.0.tgz", - "integrity": "sha1-2e8H3Od7mQK4o6j6SzHD4/fm6Ho=", - "dev": true + "integrity": "sha1-2e8H3Od7mQK4o6j6SzHD4/fm6Ho=" + }, + "window-size": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/window-size/-/window-size-0.1.0.tgz", + "integrity": "sha1-VDjNLqk7IC76Ohn+iIeu58lPnJ0=" + }, + "with": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/with/-/with-5.1.1.tgz", + "integrity": "sha1-+k2qktrzLE6pTtRTyB8EaGtXXf4=", + "requires": { + "acorn": "^3.1.0", + "acorn-globals": "^3.0.0" + } + }, + "wordwrap": { + "version": "0.0.2", + "resolved": "https://registry.npmjs.org/wordwrap/-/wordwrap-0.0.2.tgz", + "integrity": "sha1-t5Zpu0LstAn4PVg8rVLKF+qhZD8=" }, "worker-farm": { "version": "1.7.0", "resolved": "https://registry.npmjs.org/worker-farm/-/worker-farm-1.7.0.tgz", "integrity": "sha512-rvw3QTZc8lAxyVrqcSGVm5yP/IJ2UcB3U0graE3LCFoZ0Yn2x4EoVSqJKdB/T5M+FLcRPjz4TDacRf3OCfNUzw==", - "dev": true, "requires": { "errno": "~0.1.7" } @@ -9744,7 +9373,6 @@ "version": "2.1.0", "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-2.1.0.tgz", "integrity": "sha1-2Pw9KE3QV5T+hJc8rs3Rz4JP3YU=", - "dev": true, "requires": { "string-width": "^1.0.1", "strip-ansi": "^3.0.1" @@ -9754,7 +9382,6 @@ "version": "1.0.0", "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-1.0.0.tgz", "integrity": "sha1-754xOG8DGn8NZDr4L95QxFfvAMs=", - "dev": true, "requires": { "number-is-nan": "^1.0.0" } @@ -9763,7 +9390,6 @@ "version": "1.0.2", "resolved": "https://registry.npmjs.org/string-width/-/string-width-1.0.2.tgz", "integrity": "sha1-EYvfW4zcUaKn5w0hHgfisLmxB9M=", - "dev": true, "requires": { "code-point-at": "^1.0.0", "is-fullwidth-code-point": "^1.0.0", @@ -9775,107 +9401,62 @@ "wrappy": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", - "integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8=", - "dev": true + "integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8=" + }, + "ws": { + "version": "6.2.1", + "resolved": "https://registry.npmjs.org/ws/-/ws-6.2.1.tgz", + "integrity": "sha512-GIyAXC2cB7LjvpgMt9EKS2ldqr0MTrORaleiOno6TweZ6r3TKtoFQWay/2PceJ3RuBasOHzXNn5Lrw1X0bEjqA==", + "requires": { + "async-limiter": "~1.0.0" + } }, "xtend": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/xtend/-/xtend-4.0.1.tgz", - "integrity": "sha1-pcbVMr5lbiPbgg77lDofBJmNY68=", - "dev": true + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/xtend/-/xtend-4.0.2.tgz", + "integrity": "sha512-LKYU1iAXJXUgAXn9URjiu+MWhyUXHsvfp7mcuYm9dSUKK0/CjtrUwFAxD82/mCWbtLsGjFIad0wIsod4zrTAEQ==" }, "y18n": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/y18n/-/y18n-4.0.0.tgz", - "integrity": "sha512-r9S/ZyXu/Xu9q1tYlpsLIsa3EeLXXk0VwlxqTcFRfg9EhMW+17kbt9G0NrgCmhGb5vT2hyhJZLfDGx+7+5Uj/w==", - "dev": true + "integrity": "sha512-r9S/ZyXu/Xu9q1tYlpsLIsa3EeLXXk0VwlxqTcFRfg9EhMW+17kbt9G0NrgCmhGb5vT2hyhJZLfDGx+7+5Uj/w==" }, "yallist": { - "version": "3.0.3", - "resolved": "https://registry.npmjs.org/yallist/-/yallist-3.0.3.tgz", - "integrity": "sha512-S+Zk8DEWE6oKpV+vI3qWkaK+jSbIK86pCwe2IF/xwIpQ8jEuxpw9NyaGjmp9+BoJv5FV2piqCDcoCtStppiq2A==", - "dev": true + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-3.1.1.tgz", + "integrity": "sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g==" }, "yargs": { - "version": "12.0.5", - "resolved": "https://registry.npmjs.org/yargs/-/yargs-12.0.5.tgz", - "integrity": "sha512-Lhz8TLaYnxq/2ObqHDql8dX8CJi97oHxrjUcYtzKbbykPtVW9WB+poxI+NM2UIzsMgNCZTIf0AQwsjK5yMAqZw==", - "dev": true, - "requires": { - "cliui": "^4.0.0", - "decamelize": "^1.2.0", - "find-up": "^3.0.0", - "get-caller-file": "^1.0.1", - "os-locale": "^3.0.0", - "require-directory": "^2.1.1", - "require-main-filename": "^1.0.1", - "set-blocking": "^2.0.0", - "string-width": "^2.0.0", - "which-module": "^2.0.0", - "y18n": "^3.2.1 || ^4.0.0", - "yargs-parser": "^11.1.1" - }, - "dependencies": { - "find-up": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/find-up/-/find-up-3.0.0.tgz", - "integrity": "sha512-1yD6RmLI1XBfxugvORwlck6f75tYL+iR0jqwsOrOxMZyGYqUuDhJ0l4AXdO1iX/FTs9cBAMEk1gWSEx1kSbylg==", - "dev": true, - "requires": { - "locate-path": "^3.0.0" - } - }, - "locate-path": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-3.0.0.tgz", - "integrity": "sha512-7AO748wWnIhNqAuaty2ZWHkQHRSNfPVIsPIfwEOWO22AmaoVrWavlOcMR5nzTLNYvp36X220/maaRsrec1G65A==", - "dev": true, - "requires": { - "p-locate": "^3.0.0", - "path-exists": "^3.0.0" - } - }, - "p-limit": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.2.0.tgz", - "integrity": "sha512-pZbTJpoUsCzV48Mc9Nh51VbwO0X9cuPFE8gYwx9BTCt9SF8/b7Zljd2fVgOxhIF/HDTKgpVzs+GPhyKfjLLFRQ==", - "dev": true, - "requires": { - "p-try": "^2.0.0" - } - }, - "p-locate": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-3.0.0.tgz", - "integrity": "sha512-x+12w/To+4GFfgJhBEpiDcLozRJGegY+Ei7/z0tSLkMmxGZNybVMSfWj9aJn8Z5Fc7dBUNJOOVgPv2H7IwulSQ==", - "dev": true, - "requires": { - "p-limit": "^2.0.0" - } - }, - "p-try": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/p-try/-/p-try-2.2.0.tgz", - "integrity": "sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ==", - "dev": true - } + "version": "3.10.0", + "resolved": "https://registry.npmjs.org/yargs/-/yargs-3.10.0.tgz", + "integrity": "sha1-9+572FfdfB0tOMDnTvvWgdFDH9E=", + "requires": { + "camelcase": "^1.0.2", + "cliui": "^2.1.0", + "decamelize": "^1.0.0", + "window-size": "0.1.0" } }, "yargs-parser": { "version": "11.1.1", "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-11.1.1.tgz", "integrity": "sha512-C6kB/WJDiaxONLJQnF8ccx9SEeoTTLek8RVbaOIsrAUS8VrBEXfmeSnCZxygc+XC2sNMBIwOOnfcxiynjHsVSQ==", - "dev": true, "requires": { "camelcase": "^5.0.0", "decamelize": "^1.2.0" + }, + "dependencies": { + "camelcase": { + "version": "5.3.1", + "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-5.3.1.tgz", + "integrity": "sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg==" + } } }, "zepto": { "version": "1.2.0", "resolved": "https://registry.npmjs.org/zepto/-/zepto-1.2.0.tgz", - "integrity": "sha1-4Se9nmb9hGvl6rSME5SIL3wOT5g=", - "dev": true + "integrity": "sha1-4Se9nmb9hGvl6rSME5SIL3wOT5g=" } } } diff --git a/docs/package.json b/docs/package.json index 91d5c9af52eb..f8f9d5b335af 100644 --- a/docs/package.json +++ b/docs/package.json @@ -4,18 +4,16 @@ "description": "## Get Started", "main": "index.js", "scripts": { - "serve": "vuepress dev", - "build": "vuepress build" + "preserve": "./pre.sh", + "serve": "trap 'exit 0' SIGINT; vuepress dev", + "postserve": "./post.sh", + "prebuild": "./pre.sh", + "build": "trap 'exit 0' SIGINT; vuepress build", + "postbuild": "./post.sh" }, "author": "", "license": "ISC", - "devDependencies": { - "lodash": "^4.17.11", - "markdown-it": "^8.4.2", - "markdown-it-meta": "0.0.1", - "vuepress": "^1.0.2" - }, "dependencies": { - "axios": "^0.19.0" + "vuepress-theme-cosmos": "^1.0.35" } } diff --git a/docs/post.sh b/docs/post.sh new file mode 100755 index 000000000000..fa6afe440f43 --- /dev/null +++ b/docs/post.sh @@ -0,0 +1,7 @@ +#!/usr/bin/env bash + +for D in ../x/*; do + if [ -d "${D}" ]; then + rm -rf "modules/$(echo $D | awk -F/ '{print $NF}')" + fi +done \ No newline at end of file diff --git a/docs/pre.sh b/docs/pre.sh new file mode 100755 index 000000000000..cb027a843aa4 --- /dev/null +++ b/docs/pre.sh @@ -0,0 +1,10 @@ +#!/usr/bin/env bash + +mkdir -p modules + +for D in ../x/*; do + if [ -d "${D}" ]; then + rm -rf "modules/$(echo $D | awk -F/ '{print $NF}')" + mkdir -p "modules/$(echo $D | awk -F/ '{print $NF}')" && cp -r $D/spec/ "$_" + fi +done \ No newline at end of file diff --git a/docs/ru/readme.md b/docs/ru/readme.md index 6f9cc8f33199..c8872c30fa41 100644 --- a/docs/ru/readme.md +++ b/docs/ru/readme.md @@ -1 +1,6 @@ -# RU \ No newline at end of file +--- +parent: + order: false +--- + +# RU diff --git a/docs/spec/README.md b/docs/spec/README.md index 5c2a3f6063ed..0c98aa485bea 100644 --- a/docs/spec/README.md +++ b/docs/spec/README.md @@ -1,3 +1,8 @@ +--- +parent: + order: false +--- + # Specifications This directory contains specifications for the modules of the Cosmos SDK as well as Interchain Standards (ICS) and other specifications. diff --git a/docs/yarn.lock b/docs/yarn.lock deleted file mode 100644 index 9181fb4646f2..000000000000 --- a/docs/yarn.lock +++ /dev/null @@ -1,7285 +0,0 @@ -# THIS IS AN AUTOGENERATED FILE. DO NOT EDIT THIS FILE DIRECTLY. -# yarn lockfile v1 - - -"@babel/code-frame@^7.0.0", "@babel/code-frame@^7.5.5": - version "7.5.5" - resolved "https://registry.yarnpkg.com/@babel/code-frame/-/code-frame-7.5.5.tgz#bc0782f6d69f7b7d49531219699b988f669a8f9d" - integrity sha512-27d4lZoomVyo51VegxI20xZPuSHusqbQag/ztrBC7wegWoQ1nLREPVSKSW8byhTlzTKyNE4ifaTA6lCp7JjpFw== - dependencies: - "@babel/highlight" "^7.0.0" - -"@babel/core@^7.0.0": - version "7.5.5" - resolved "https://registry.yarnpkg.com/@babel/core/-/core-7.5.5.tgz#17b2686ef0d6bc58f963dddd68ab669755582c30" - integrity sha512-i4qoSr2KTtce0DmkuuQBV4AuQgGPUcPXMr9L5MyYAtk06z068lQ10a4O009fe5OB/DfNV+h+qqT7ddNV8UnRjg== - dependencies: - "@babel/code-frame" "^7.5.5" - "@babel/generator" "^7.5.5" - "@babel/helpers" "^7.5.5" - "@babel/parser" "^7.5.5" - "@babel/template" "^7.4.4" - "@babel/traverse" "^7.5.5" - "@babel/types" "^7.5.5" - convert-source-map "^1.1.0" - debug "^4.1.0" - json5 "^2.1.0" - lodash "^4.17.13" - resolve "^1.3.2" - semver "^5.4.1" - source-map "^0.5.0" - -"@babel/generator@^7.5.5": - version "7.5.5" - resolved "https://registry.yarnpkg.com/@babel/generator/-/generator-7.5.5.tgz#873a7f936a3c89491b43536d12245b626664e3cf" - integrity sha512-ETI/4vyTSxTzGnU2c49XHv2zhExkv9JHLTwDAFz85kmcwuShvYG2H08FwgIguQf4JC75CBnXAUM5PqeF4fj0nQ== - dependencies: - "@babel/types" "^7.5.5" - jsesc "^2.5.1" - lodash "^4.17.13" - source-map "^0.5.0" - trim-right "^1.0.1" - -"@babel/helper-annotate-as-pure@^7.0.0": - version "7.0.0" - resolved "https://registry.yarnpkg.com/@babel/helper-annotate-as-pure/-/helper-annotate-as-pure-7.0.0.tgz#323d39dd0b50e10c7c06ca7d7638e6864d8c5c32" - integrity sha512-3UYcJUj9kvSLbLbUIfQTqzcy5VX7GRZ/CCDrnOaZorFFM01aXp1+GJwuFGV4NDDoAS+mOUyHcO6UD/RfqOks3Q== - dependencies: - "@babel/types" "^7.0.0" - -"@babel/helper-builder-binary-assignment-operator-visitor@^7.1.0": - version "7.1.0" - resolved "https://registry.yarnpkg.com/@babel/helper-builder-binary-assignment-operator-visitor/-/helper-builder-binary-assignment-operator-visitor-7.1.0.tgz#6b69628dfe4087798e0c4ed98e3d4a6b2fbd2f5f" - integrity sha512-qNSR4jrmJ8M1VMM9tibvyRAHXQs2PmaksQF7c1CGJNipfe3D8p+wgNwgso/P2A2r2mdgBWAXljNWR0QRZAMW8w== - dependencies: - "@babel/helper-explode-assignable-expression" "^7.1.0" - "@babel/types" "^7.0.0" - -"@babel/helper-call-delegate@^7.4.4": - version "7.4.4" - resolved "https://registry.yarnpkg.com/@babel/helper-call-delegate/-/helper-call-delegate-7.4.4.tgz#87c1f8ca19ad552a736a7a27b1c1fcf8b1ff1f43" - integrity sha512-l79boDFJ8S1c5hvQvG+rc+wHw6IuH7YldmRKsYtpbawsxURu/paVy57FZMomGK22/JckepaikOkY0MoAmdyOlQ== - dependencies: - "@babel/helper-hoist-variables" "^7.4.4" - "@babel/traverse" "^7.4.4" - "@babel/types" "^7.4.4" - -"@babel/helper-create-class-features-plugin@^7.4.4", "@babel/helper-create-class-features-plugin@^7.5.5": - version "7.5.5" - resolved "https://registry.yarnpkg.com/@babel/helper-create-class-features-plugin/-/helper-create-class-features-plugin-7.5.5.tgz#401f302c8ddbc0edd36f7c6b2887d8fa1122e5a4" - integrity sha512-ZsxkyYiRA7Bg+ZTRpPvB6AbOFKTFFK4LrvTet8lInm0V468MWCaSYJE+I7v2z2r8KNLtYiV+K5kTCnR7dvyZjg== - dependencies: - "@babel/helper-function-name" "^7.1.0" - "@babel/helper-member-expression-to-functions" "^7.5.5" - "@babel/helper-optimise-call-expression" "^7.0.0" - "@babel/helper-plugin-utils" "^7.0.0" - "@babel/helper-replace-supers" "^7.5.5" - "@babel/helper-split-export-declaration" "^7.4.4" - -"@babel/helper-define-map@^7.5.5": - version "7.5.5" - resolved "https://registry.yarnpkg.com/@babel/helper-define-map/-/helper-define-map-7.5.5.tgz#3dec32c2046f37e09b28c93eb0b103fd2a25d369" - integrity sha512-fTfxx7i0B5NJqvUOBBGREnrqbTxRh7zinBANpZXAVDlsZxYdclDp467G1sQ8VZYMnAURY3RpBUAgOYT9GfzHBg== - dependencies: - "@babel/helper-function-name" "^7.1.0" - "@babel/types" "^7.5.5" - lodash "^4.17.13" - -"@babel/helper-explode-assignable-expression@^7.1.0": - version "7.1.0" - resolved "https://registry.yarnpkg.com/@babel/helper-explode-assignable-expression/-/helper-explode-assignable-expression-7.1.0.tgz#537fa13f6f1674df745b0c00ec8fe4e99681c8f6" - integrity sha512-NRQpfHrJ1msCHtKjbzs9YcMmJZOg6mQMmGRB+hbamEdG5PNpaSm95275VD92DvJKuyl0s2sFiDmMZ+EnnvufqA== - dependencies: - "@babel/traverse" "^7.1.0" - "@babel/types" "^7.0.0" - -"@babel/helper-function-name@^7.1.0": - version "7.1.0" - resolved "https://registry.yarnpkg.com/@babel/helper-function-name/-/helper-function-name-7.1.0.tgz#a0ceb01685f73355d4360c1247f582bfafc8ff53" - integrity sha512-A95XEoCpb3TO+KZzJ4S/5uW5fNe26DjBGqf1o9ucyLyCmi1dXq/B3c8iaWTfBk3VvetUxl16e8tIrd5teOCfGw== - dependencies: - "@babel/helper-get-function-arity" "^7.0.0" - "@babel/template" "^7.1.0" - "@babel/types" "^7.0.0" - -"@babel/helper-get-function-arity@^7.0.0": - version "7.0.0" - resolved "https://registry.yarnpkg.com/@babel/helper-get-function-arity/-/helper-get-function-arity-7.0.0.tgz#83572d4320e2a4657263734113c42868b64e49c3" - integrity sha512-r2DbJeg4svYvt3HOS74U4eWKsUAMRH01Z1ds1zx8KNTPtpTL5JAsdFv8BNyOpVqdFhHkkRDIg5B4AsxmkjAlmQ== - dependencies: - "@babel/types" "^7.0.0" - -"@babel/helper-hoist-variables@^7.4.4": - version "7.4.4" - resolved "https://registry.yarnpkg.com/@babel/helper-hoist-variables/-/helper-hoist-variables-7.4.4.tgz#0298b5f25c8c09c53102d52ac4a98f773eb2850a" - integrity sha512-VYk2/H/BnYbZDDg39hr3t2kKyifAm1W6zHRfhx8jGjIHpQEBv9dry7oQ2f3+J703TLu69nYdxsovl0XYfcnK4w== - dependencies: - "@babel/types" "^7.4.4" - -"@babel/helper-member-expression-to-functions@^7.5.5": - version "7.5.5" - resolved "https://registry.yarnpkg.com/@babel/helper-member-expression-to-functions/-/helper-member-expression-to-functions-7.5.5.tgz#1fb5b8ec4453a93c439ee9fe3aeea4a84b76b590" - integrity sha512-5qZ3D1uMclSNqYcXqiHoA0meVdv+xUEex9em2fqMnrk/scphGlGgg66zjMrPJESPwrFJ6sbfFQYUSa0Mz7FabA== - dependencies: - "@babel/types" "^7.5.5" - -"@babel/helper-module-imports@^7.0.0": - version "7.0.0" - resolved "https://registry.yarnpkg.com/@babel/helper-module-imports/-/helper-module-imports-7.0.0.tgz#96081b7111e486da4d2cd971ad1a4fe216cc2e3d" - integrity sha512-aP/hlLq01DWNEiDg4Jn23i+CXxW/owM4WpDLFUbpjxe4NS3BhLVZQ5i7E0ZrxuQ/vwekIeciyamgB1UIYxxM6A== - dependencies: - "@babel/types" "^7.0.0" - -"@babel/helper-module-transforms@^7.1.0", "@babel/helper-module-transforms@^7.4.4": - version "7.5.5" - resolved "https://registry.yarnpkg.com/@babel/helper-module-transforms/-/helper-module-transforms-7.5.5.tgz#f84ff8a09038dcbca1fd4355661a500937165b4a" - integrity sha512-jBeCvETKuJqeiaCdyaheF40aXnnU1+wkSiUs/IQg3tB85up1LyL8x77ClY8qJpuRJUcXQo+ZtdNESmZl4j56Pw== - dependencies: - "@babel/helper-module-imports" "^7.0.0" - "@babel/helper-simple-access" "^7.1.0" - "@babel/helper-split-export-declaration" "^7.4.4" - "@babel/template" "^7.4.4" - "@babel/types" "^7.5.5" - lodash "^4.17.13" - -"@babel/helper-optimise-call-expression@^7.0.0": - version "7.0.0" - resolved "https://registry.yarnpkg.com/@babel/helper-optimise-call-expression/-/helper-optimise-call-expression-7.0.0.tgz#a2920c5702b073c15de51106200aa8cad20497d5" - integrity sha512-u8nd9NQePYNQV8iPWu/pLLYBqZBa4ZaY1YWRFMuxrid94wKI1QNt67NEZ7GAe5Kc/0LLScbim05xZFWkAdrj9g== - dependencies: - "@babel/types" "^7.0.0" - -"@babel/helper-plugin-utils@^7.0.0": - version "7.0.0" - resolved "https://registry.yarnpkg.com/@babel/helper-plugin-utils/-/helper-plugin-utils-7.0.0.tgz#bbb3fbee98661c569034237cc03967ba99b4f250" - integrity sha512-CYAOUCARwExnEixLdB6sDm2dIJ/YgEAKDM1MOeMeZu9Ld/bDgVo8aiWrXwcY7OBh+1Ea2uUcVRcxKk0GJvW7QA== - -"@babel/helper-regex@^7.0.0", "@babel/helper-regex@^7.4.4": - version "7.5.5" - resolved "https://registry.yarnpkg.com/@babel/helper-regex/-/helper-regex-7.5.5.tgz#0aa6824f7100a2e0e89c1527c23936c152cab351" - integrity sha512-CkCYQLkfkiugbRDO8eZn6lRuR8kzZoGXCg3149iTk5se7g6qykSpy3+hELSwquhu+TgHn8nkLiBwHvNX8Hofcw== - dependencies: - lodash "^4.17.13" - -"@babel/helper-remap-async-to-generator@^7.1.0": - version "7.1.0" - resolved "https://registry.yarnpkg.com/@babel/helper-remap-async-to-generator/-/helper-remap-async-to-generator-7.1.0.tgz#361d80821b6f38da75bd3f0785ece20a88c5fe7f" - integrity sha512-3fOK0L+Fdlg8S5al8u/hWE6vhufGSn0bN09xm2LXMy//REAF8kDCrYoOBKYmA8m5Nom+sV9LyLCwrFynA8/slg== - dependencies: - "@babel/helper-annotate-as-pure" "^7.0.0" - "@babel/helper-wrap-function" "^7.1.0" - "@babel/template" "^7.1.0" - "@babel/traverse" "^7.1.0" - "@babel/types" "^7.0.0" - -"@babel/helper-replace-supers@^7.5.5": - version "7.5.5" - resolved "https://registry.yarnpkg.com/@babel/helper-replace-supers/-/helper-replace-supers-7.5.5.tgz#f84ce43df031222d2bad068d2626cb5799c34bc2" - integrity sha512-XvRFWrNnlsow2u7jXDuH4jDDctkxbS7gXssrP4q2nUD606ukXHRvydj346wmNg+zAgpFx4MWf4+usfC93bElJg== - dependencies: - "@babel/helper-member-expression-to-functions" "^7.5.5" - "@babel/helper-optimise-call-expression" "^7.0.0" - "@babel/traverse" "^7.5.5" - "@babel/types" "^7.5.5" - -"@babel/helper-simple-access@^7.1.0": - version "7.1.0" - resolved "https://registry.yarnpkg.com/@babel/helper-simple-access/-/helper-simple-access-7.1.0.tgz#65eeb954c8c245beaa4e859da6188f39d71e585c" - integrity sha512-Vk+78hNjRbsiu49zAPALxTb+JUQCz1aolpd8osOF16BGnLtseD21nbHgLPGUwrXEurZgiCOUmvs3ExTu4F5x6w== - dependencies: - "@babel/template" "^7.1.0" - "@babel/types" "^7.0.0" - -"@babel/helper-split-export-declaration@^7.4.4": - version "7.4.4" - resolved "https://registry.yarnpkg.com/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.4.4.tgz#ff94894a340be78f53f06af038b205c49d993677" - integrity sha512-Ro/XkzLf3JFITkW6b+hNxzZ1n5OQ80NvIUdmHspih1XAhtN3vPTuUFT4eQnela+2MaZ5ulH+iyP513KJrxbN7Q== - dependencies: - "@babel/types" "^7.4.4" - -"@babel/helper-wrap-function@^7.1.0": - version "7.2.0" - resolved "https://registry.yarnpkg.com/@babel/helper-wrap-function/-/helper-wrap-function-7.2.0.tgz#c4e0012445769e2815b55296ead43a958549f6fa" - integrity sha512-o9fP1BZLLSrYlxYEYyl2aS+Flun5gtjTIG8iln+XuEzQTs0PLagAGSXUcqruJwD5fM48jzIEggCKpIfWTcR7pQ== - dependencies: - "@babel/helper-function-name" "^7.1.0" - "@babel/template" "^7.1.0" - "@babel/traverse" "^7.1.0" - "@babel/types" "^7.2.0" - -"@babel/helpers@^7.5.5": - version "7.5.5" - resolved "https://registry.yarnpkg.com/@babel/helpers/-/helpers-7.5.5.tgz#63908d2a73942229d1e6685bc2a0e730dde3b75e" - integrity sha512-nRq2BUhxZFnfEn/ciJuhklHvFOqjJUD5wpx+1bxUF2axL9C+v4DE/dmp5sT2dKnpOs4orZWzpAZqlCy8QqE/7g== - dependencies: - "@babel/template" "^7.4.4" - "@babel/traverse" "^7.5.5" - "@babel/types" "^7.5.5" - -"@babel/highlight@^7.0.0": - version "7.5.0" - resolved "https://registry.yarnpkg.com/@babel/highlight/-/highlight-7.5.0.tgz#56d11312bd9248fa619591d02472be6e8cb32540" - integrity sha512-7dV4eu9gBxoM0dAnj/BCFDW9LFU0zvTrkq0ugM7pnHEgguOEeOz1so2ZghEdzviYzQEED0r4EAgpsBChKy1TRQ== - dependencies: - chalk "^2.0.0" - esutils "^2.0.2" - js-tokens "^4.0.0" - -"@babel/parser@^7.4.4", "@babel/parser@^7.5.5": - version "7.5.5" - resolved "https://registry.yarnpkg.com/@babel/parser/-/parser-7.5.5.tgz#02f077ac8817d3df4a832ef59de67565e71cca4b" - integrity sha512-E5BN68cqR7dhKan1SfqgPGhQ178bkVKpXTPEXnFJBrEt8/DKRZlybmy+IgYLTeN7tp1R5Ccmbm2rBk17sHYU3g== - -"@babel/plugin-proposal-async-generator-functions@^7.2.0": - version "7.2.0" - resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-async-generator-functions/-/plugin-proposal-async-generator-functions-7.2.0.tgz#b289b306669dce4ad20b0252889a15768c9d417e" - integrity sha512-+Dfo/SCQqrwx48ptLVGLdE39YtWRuKc/Y9I5Fy0P1DDBB9lsAHpjcEJQt+4IifuSOSTLBKJObJqMvaO1pIE8LQ== - dependencies: - "@babel/helper-plugin-utils" "^7.0.0" - "@babel/helper-remap-async-to-generator" "^7.1.0" - "@babel/plugin-syntax-async-generators" "^7.2.0" - -"@babel/plugin-proposal-class-properties@^7.0.0": - version "7.5.5" - resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-class-properties/-/plugin-proposal-class-properties-7.5.5.tgz#a974cfae1e37c3110e71f3c6a2e48b8e71958cd4" - integrity sha512-AF79FsnWFxjlaosgdi421vmYG6/jg79bVD0dpD44QdgobzHKuLZ6S3vl8la9qIeSwGi8i1fS0O1mfuDAAdo1/A== - dependencies: - "@babel/helper-create-class-features-plugin" "^7.5.5" - "@babel/helper-plugin-utils" "^7.0.0" - -"@babel/plugin-proposal-decorators@^7.1.0": - version "7.4.4" - resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-decorators/-/plugin-proposal-decorators-7.4.4.tgz#de9b2a1a8ab0196f378e2a82f10b6e2a36f21cc0" - integrity sha512-z7MpQz3XC/iQJWXH9y+MaWcLPNSMY9RQSthrLzak8R8hCj0fuyNk+Dzi9kfNe/JxxlWQ2g7wkABbgWjW36MTcw== - dependencies: - "@babel/helper-create-class-features-plugin" "^7.4.4" - "@babel/helper-plugin-utils" "^7.0.0" - "@babel/plugin-syntax-decorators" "^7.2.0" - -"@babel/plugin-proposal-json-strings@^7.2.0": - version "7.2.0" - resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-json-strings/-/plugin-proposal-json-strings-7.2.0.tgz#568ecc446c6148ae6b267f02551130891e29f317" - integrity sha512-MAFV1CA/YVmYwZG0fBQyXhmj0BHCB5egZHCKWIFVv/XCxAeVGIHfos3SwDck4LvCllENIAg7xMKOG5kH0dzyUg== - dependencies: - "@babel/helper-plugin-utils" "^7.0.0" - "@babel/plugin-syntax-json-strings" "^7.2.0" - -"@babel/plugin-proposal-object-rest-spread@^7.3.4": - version "7.5.5" - resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-object-rest-spread/-/plugin-proposal-object-rest-spread-7.5.5.tgz#61939744f71ba76a3ae46b5eea18a54c16d22e58" - integrity sha512-F2DxJJSQ7f64FyTVl5cw/9MWn6naXGdk3Q3UhDbFEEHv+EilCPoeRD3Zh/Utx1CJz4uyKlQ4uH+bJPbEhMV7Zw== - dependencies: - "@babel/helper-plugin-utils" "^7.0.0" - "@babel/plugin-syntax-object-rest-spread" "^7.2.0" - -"@babel/plugin-proposal-optional-catch-binding@^7.2.0": - version "7.2.0" - resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-optional-catch-binding/-/plugin-proposal-optional-catch-binding-7.2.0.tgz#135d81edb68a081e55e56ec48541ece8065c38f5" - integrity sha512-mgYj3jCcxug6KUcX4OBoOJz3CMrwRfQELPQ5560F70YQUBZB7uac9fqaWamKR1iWUzGiK2t0ygzjTScZnVz75g== - dependencies: - "@babel/helper-plugin-utils" "^7.0.0" - "@babel/plugin-syntax-optional-catch-binding" "^7.2.0" - -"@babel/plugin-proposal-unicode-property-regex@^7.2.0": - version "7.4.4" - resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-unicode-property-regex/-/plugin-proposal-unicode-property-regex-7.4.4.tgz#501ffd9826c0b91da22690720722ac7cb1ca9c78" - integrity sha512-j1NwnOqMG9mFUOH58JTFsA/+ZYzQLUZ/drqWUqxCYLGeu2JFZL8YrNC9hBxKmWtAuOCHPcRpgv7fhap09Fb4kA== - dependencies: - "@babel/helper-plugin-utils" "^7.0.0" - "@babel/helper-regex" "^7.4.4" - regexpu-core "^4.5.4" - -"@babel/plugin-syntax-async-generators@^7.2.0": - version "7.2.0" - resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-async-generators/-/plugin-syntax-async-generators-7.2.0.tgz#69e1f0db34c6f5a0cf7e2b3323bf159a76c8cb7f" - integrity sha512-1ZrIRBv2t0GSlcwVoQ6VgSLpLgiN/FVQUzt9znxo7v2Ov4jJrs8RY8tv0wvDmFN3qIdMKWrmMMW6yZ0G19MfGg== - dependencies: - "@babel/helper-plugin-utils" "^7.0.0" - -"@babel/plugin-syntax-decorators@^7.2.0": - version "7.2.0" - resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-decorators/-/plugin-syntax-decorators-7.2.0.tgz#c50b1b957dcc69e4b1127b65e1c33eef61570c1b" - integrity sha512-38QdqVoXdHUQfTpZo3rQwqQdWtCn5tMv4uV6r2RMfTqNBuv4ZBhz79SfaQWKTVmxHjeFv/DnXVC/+agHCklYWA== - dependencies: - "@babel/helper-plugin-utils" "^7.0.0" - -"@babel/plugin-syntax-dynamic-import@^7.0.0": - version "7.2.0" - resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-dynamic-import/-/plugin-syntax-dynamic-import-7.2.0.tgz#69c159ffaf4998122161ad8ebc5e6d1f55df8612" - integrity sha512-mVxuJ0YroI/h/tbFTPGZR8cv6ai+STMKNBq0f8hFxsxWjl94qqhsb+wXbpNMDPU3cfR1TIsVFzU3nXyZMqyK4w== - dependencies: - "@babel/helper-plugin-utils" "^7.0.0" - -"@babel/plugin-syntax-json-strings@^7.2.0": - version "7.2.0" - resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-json-strings/-/plugin-syntax-json-strings-7.2.0.tgz#72bd13f6ffe1d25938129d2a186b11fd62951470" - integrity sha512-5UGYnMSLRE1dqqZwug+1LISpA403HzlSfsg6P9VXU6TBjcSHeNlw4DxDx7LgpF+iKZoOG/+uzqoRHTdcUpiZNg== - dependencies: - "@babel/helper-plugin-utils" "^7.0.0" - -"@babel/plugin-syntax-jsx@^7.0.0", "@babel/plugin-syntax-jsx@^7.2.0": - version "7.2.0" - resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-jsx/-/plugin-syntax-jsx-7.2.0.tgz#0b85a3b4bc7cdf4cc4b8bf236335b907ca22e7c7" - integrity sha512-VyN4QANJkRW6lDBmENzRszvZf3/4AXaj9YR7GwrWeeN9tEBPuXbmDYVU9bYBN0D70zCWVwUy0HWq2553VCb6Hw== - dependencies: - "@babel/helper-plugin-utils" "^7.0.0" - -"@babel/plugin-syntax-object-rest-spread@^7.2.0": - version "7.2.0" - resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-object-rest-spread/-/plugin-syntax-object-rest-spread-7.2.0.tgz#3b7a3e733510c57e820b9142a6579ac8b0dfad2e" - integrity sha512-t0JKGgqk2We+9may3t0xDdmneaXmyxq0xieYcKHxIsrJO64n1OiMWNUtc5gQK1PA0NpdCRrtZp4z+IUaKugrSA== - dependencies: - "@babel/helper-plugin-utils" "^7.0.0" - -"@babel/plugin-syntax-optional-catch-binding@^7.2.0": - version "7.2.0" - resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-optional-catch-binding/-/plugin-syntax-optional-catch-binding-7.2.0.tgz#a94013d6eda8908dfe6a477e7f9eda85656ecf5c" - integrity sha512-bDe4xKNhb0LI7IvZHiA13kff0KEfaGX/Hv4lMA9+7TEc63hMNvfKo6ZFpXhKuEp+II/q35Gc4NoMeDZyaUbj9w== - dependencies: - "@babel/helper-plugin-utils" "^7.0.0" - -"@babel/plugin-transform-arrow-functions@^7.2.0": - version "7.2.0" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-arrow-functions/-/plugin-transform-arrow-functions-7.2.0.tgz#9aeafbe4d6ffc6563bf8f8372091628f00779550" - integrity sha512-ER77Cax1+8/8jCB9fo4Ud161OZzWN5qawi4GusDuRLcDbDG+bIGYY20zb2dfAFdTRGzrfq2xZPvF0R64EHnimg== - dependencies: - "@babel/helper-plugin-utils" "^7.0.0" - -"@babel/plugin-transform-async-to-generator@^7.3.4": - version "7.5.0" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-async-to-generator/-/plugin-transform-async-to-generator-7.5.0.tgz#89a3848a0166623b5bc481164b5936ab947e887e" - integrity sha512-mqvkzwIGkq0bEF1zLRRiTdjfomZJDV33AH3oQzHVGkI2VzEmXLpKKOBvEVaFZBJdN0XTyH38s9j/Kiqr68dggg== - dependencies: - "@babel/helper-module-imports" "^7.0.0" - "@babel/helper-plugin-utils" "^7.0.0" - "@babel/helper-remap-async-to-generator" "^7.1.0" - -"@babel/plugin-transform-block-scoped-functions@^7.2.0": - version "7.2.0" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-block-scoped-functions/-/plugin-transform-block-scoped-functions-7.2.0.tgz#5d3cc11e8d5ddd752aa64c9148d0db6cb79fd190" - integrity sha512-ntQPR6q1/NKuphly49+QiQiTN0O63uOwjdD6dhIjSWBI5xlrbUFh720TIpzBhpnrLfv2tNH/BXvLIab1+BAI0w== - dependencies: - "@babel/helper-plugin-utils" "^7.0.0" - -"@babel/plugin-transform-block-scoping@^7.3.4": - version "7.5.5" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-block-scoping/-/plugin-transform-block-scoping-7.5.5.tgz#a35f395e5402822f10d2119f6f8e045e3639a2ce" - integrity sha512-82A3CLRRdYubkG85lKwhZB0WZoHxLGsJdux/cOVaJCJpvYFl1LVzAIFyRsa7CvXqW8rBM4Zf3Bfn8PHt5DP0Sg== - dependencies: - "@babel/helper-plugin-utils" "^7.0.0" - lodash "^4.17.13" - -"@babel/plugin-transform-classes@^7.3.4": - version "7.5.5" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-classes/-/plugin-transform-classes-7.5.5.tgz#d094299d9bd680a14a2a0edae38305ad60fb4de9" - integrity sha512-U2htCNK/6e9K7jGyJ++1p5XRU+LJjrwtoiVn9SzRlDT2KubcZ11OOwy3s24TjHxPgxNwonCYP7U2K51uVYCMDg== - dependencies: - "@babel/helper-annotate-as-pure" "^7.0.0" - "@babel/helper-define-map" "^7.5.5" - "@babel/helper-function-name" "^7.1.0" - "@babel/helper-optimise-call-expression" "^7.0.0" - "@babel/helper-plugin-utils" "^7.0.0" - "@babel/helper-replace-supers" "^7.5.5" - "@babel/helper-split-export-declaration" "^7.4.4" - globals "^11.1.0" - -"@babel/plugin-transform-computed-properties@^7.2.0": - version "7.2.0" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-computed-properties/-/plugin-transform-computed-properties-7.2.0.tgz#83a7df6a658865b1c8f641d510c6f3af220216da" - integrity sha512-kP/drqTxY6Xt3NNpKiMomfgkNn4o7+vKxK2DDKcBG9sHj51vHqMBGy8wbDS/J4lMxnqs153/T3+DmCEAkC5cpA== - dependencies: - "@babel/helper-plugin-utils" "^7.0.0" - -"@babel/plugin-transform-destructuring@^7.2.0": - version "7.5.0" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-destructuring/-/plugin-transform-destructuring-7.5.0.tgz#f6c09fdfe3f94516ff074fe877db7bc9ef05855a" - integrity sha512-YbYgbd3TryYYLGyC7ZR+Tq8H/+bCmwoaxHfJHupom5ECstzbRLTch6gOQbhEY9Z4hiCNHEURgq06ykFv9JZ/QQ== - dependencies: - "@babel/helper-plugin-utils" "^7.0.0" - -"@babel/plugin-transform-dotall-regex@^7.2.0": - version "7.4.4" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-dotall-regex/-/plugin-transform-dotall-regex-7.4.4.tgz#361a148bc951444312c69446d76ed1ea8e4450c3" - integrity sha512-P05YEhRc2h53lZDjRPk/OektxCVevFzZs2Gfjd545Wde3k+yFDbXORgl2e0xpbq8mLcKJ7Idss4fAg0zORN/zg== - dependencies: - "@babel/helper-plugin-utils" "^7.0.0" - "@babel/helper-regex" "^7.4.4" - regexpu-core "^4.5.4" - -"@babel/plugin-transform-duplicate-keys@^7.2.0": - version "7.5.0" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-duplicate-keys/-/plugin-transform-duplicate-keys-7.5.0.tgz#c5dbf5106bf84cdf691222c0974c12b1df931853" - integrity sha512-igcziksHizyQPlX9gfSjHkE2wmoCH3evvD2qR5w29/Dk0SMKE/eOI7f1HhBdNhR/zxJDqrgpoDTq5YSLH/XMsQ== - dependencies: - "@babel/helper-plugin-utils" "^7.0.0" - -"@babel/plugin-transform-exponentiation-operator@^7.2.0": - version "7.2.0" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-exponentiation-operator/-/plugin-transform-exponentiation-operator-7.2.0.tgz#a63868289e5b4007f7054d46491af51435766008" - integrity sha512-umh4hR6N7mu4Elq9GG8TOu9M0bakvlsREEC+ialrQN6ABS4oDQ69qJv1VtR3uxlKMCQMCvzk7vr17RHKcjx68A== - dependencies: - "@babel/helper-builder-binary-assignment-operator-visitor" "^7.1.0" - "@babel/helper-plugin-utils" "^7.0.0" - -"@babel/plugin-transform-for-of@^7.2.0": - version "7.4.4" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-for-of/-/plugin-transform-for-of-7.4.4.tgz#0267fc735e24c808ba173866c6c4d1440fc3c556" - integrity sha512-9T/5Dlr14Z9TIEXLXkt8T1DU7F24cbhwhMNUziN3hB1AXoZcdzPcTiKGRn/6iOymDqtTKWnr/BtRKN9JwbKtdQ== - dependencies: - "@babel/helper-plugin-utils" "^7.0.0" - -"@babel/plugin-transform-function-name@^7.2.0": - version "7.4.4" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-function-name/-/plugin-transform-function-name-7.4.4.tgz#e1436116abb0610c2259094848754ac5230922ad" - integrity sha512-iU9pv7U+2jC9ANQkKeNF6DrPy4GBa4NWQtl6dHB4Pb3izX2JOEvDTFarlNsBj/63ZEzNNIAMs3Qw4fNCcSOXJA== - dependencies: - "@babel/helper-function-name" "^7.1.0" - "@babel/helper-plugin-utils" "^7.0.0" - -"@babel/plugin-transform-literals@^7.2.0": - version "7.2.0" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-literals/-/plugin-transform-literals-7.2.0.tgz#690353e81f9267dad4fd8cfd77eafa86aba53ea1" - integrity sha512-2ThDhm4lI4oV7fVQ6pNNK+sx+c/GM5/SaML0w/r4ZB7sAneD/piDJtwdKlNckXeyGK7wlwg2E2w33C/Hh+VFCg== - dependencies: - "@babel/helper-plugin-utils" "^7.0.0" - -"@babel/plugin-transform-modules-amd@^7.2.0": - version "7.5.0" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-modules-amd/-/plugin-transform-modules-amd-7.5.0.tgz#ef00435d46da0a5961aa728a1d2ecff063e4fb91" - integrity sha512-n20UsQMKnWrltocZZm24cRURxQnWIvsABPJlw/fvoy9c6AgHZzoelAIzajDHAQrDpuKFFPPcFGd7ChsYuIUMpg== - dependencies: - "@babel/helper-module-transforms" "^7.1.0" - "@babel/helper-plugin-utils" "^7.0.0" - babel-plugin-dynamic-import-node "^2.3.0" - -"@babel/plugin-transform-modules-commonjs@^7.2.0": - version "7.5.0" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-modules-commonjs/-/plugin-transform-modules-commonjs-7.5.0.tgz#425127e6045231360858eeaa47a71d75eded7a74" - integrity sha512-xmHq0B+ytyrWJvQTc5OWAC4ii6Dhr0s22STOoydokG51JjWhyYo5mRPXoi+ZmtHQhZZwuXNN+GG5jy5UZZJxIQ== - dependencies: - "@babel/helper-module-transforms" "^7.4.4" - "@babel/helper-plugin-utils" "^7.0.0" - "@babel/helper-simple-access" "^7.1.0" - babel-plugin-dynamic-import-node "^2.3.0" - -"@babel/plugin-transform-modules-systemjs@^7.3.4": - version "7.5.0" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-modules-systemjs/-/plugin-transform-modules-systemjs-7.5.0.tgz#e75266a13ef94202db2a0620977756f51d52d249" - integrity sha512-Q2m56tyoQWmuNGxEtUyeEkm6qJYFqs4c+XyXH5RAuYxObRNz9Zgj/1g2GMnjYp2EUyEy7YTrxliGCXzecl/vJg== - dependencies: - "@babel/helper-hoist-variables" "^7.4.4" - "@babel/helper-plugin-utils" "^7.0.0" - babel-plugin-dynamic-import-node "^2.3.0" - -"@babel/plugin-transform-modules-umd@^7.2.0": - version "7.2.0" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-modules-umd/-/plugin-transform-modules-umd-7.2.0.tgz#7678ce75169f0877b8eb2235538c074268dd01ae" - integrity sha512-BV3bw6MyUH1iIsGhXlOK6sXhmSarZjtJ/vMiD9dNmpY8QXFFQTj+6v92pcfy1iqa8DeAfJFwoxcrS/TUZda6sw== - dependencies: - "@babel/helper-module-transforms" "^7.1.0" - "@babel/helper-plugin-utils" "^7.0.0" - -"@babel/plugin-transform-named-capturing-groups-regex@^7.3.0": - version "7.4.5" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-named-capturing-groups-regex/-/plugin-transform-named-capturing-groups-regex-7.4.5.tgz#9d269fd28a370258199b4294736813a60bbdd106" - integrity sha512-z7+2IsWafTBbjNsOxU/Iv5CvTJlr5w4+HGu1HovKYTtgJ362f7kBcQglkfmlspKKZ3bgrbSGvLfNx++ZJgCWsg== - dependencies: - regexp-tree "^0.1.6" - -"@babel/plugin-transform-new-target@^7.0.0": - version "7.4.4" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-new-target/-/plugin-transform-new-target-7.4.4.tgz#18d120438b0cc9ee95a47f2c72bc9768fbed60a5" - integrity sha512-r1z3T2DNGQwwe2vPGZMBNjioT2scgWzK9BCnDEh+46z8EEwXBq24uRzd65I7pjtugzPSj921aM15RpESgzsSuA== - dependencies: - "@babel/helper-plugin-utils" "^7.0.0" - -"@babel/plugin-transform-object-super@^7.2.0": - version "7.5.5" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-object-super/-/plugin-transform-object-super-7.5.5.tgz#c70021df834073c65eb613b8679cc4a381d1a9f9" - integrity sha512-un1zJQAhSosGFBduPgN/YFNvWVpRuHKU7IHBglLoLZsGmruJPOo6pbInneflUdmq7YvSVqhpPs5zdBvLnteltQ== - dependencies: - "@babel/helper-plugin-utils" "^7.0.0" - "@babel/helper-replace-supers" "^7.5.5" - -"@babel/plugin-transform-parameters@^7.2.0": - version "7.4.4" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-parameters/-/plugin-transform-parameters-7.4.4.tgz#7556cf03f318bd2719fe4c922d2d808be5571e16" - integrity sha512-oMh5DUO1V63nZcu/ZVLQFqiihBGo4OpxJxR1otF50GMeCLiRx5nUdtokd+u9SuVJrvvuIh9OosRFPP4pIPnwmw== - dependencies: - "@babel/helper-call-delegate" "^7.4.4" - "@babel/helper-get-function-arity" "^7.0.0" - "@babel/helper-plugin-utils" "^7.0.0" - -"@babel/plugin-transform-regenerator@^7.3.4": - version "7.4.5" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-regenerator/-/plugin-transform-regenerator-7.4.5.tgz#629dc82512c55cee01341fb27bdfcb210354680f" - integrity sha512-gBKRh5qAaCWntnd09S8QC7r3auLCqq5DI6O0DlfoyDjslSBVqBibrMdsqO+Uhmx3+BlOmE/Kw1HFxmGbv0N9dA== - dependencies: - regenerator-transform "^0.14.0" - -"@babel/plugin-transform-runtime@^7.4.0": - version "7.5.5" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-runtime/-/plugin-transform-runtime-7.5.5.tgz#a6331afbfc59189d2135b2e09474457a8e3d28bc" - integrity sha512-6Xmeidsun5rkwnGfMOp6/z9nSzWpHFNVr2Jx7kwoq4mVatQfQx5S56drBgEHF+XQbKOdIaOiMIINvp/kAwMN+w== - dependencies: - "@babel/helper-module-imports" "^7.0.0" - "@babel/helper-plugin-utils" "^7.0.0" - resolve "^1.8.1" - semver "^5.5.1" - -"@babel/plugin-transform-shorthand-properties@^7.2.0": - version "7.2.0" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-shorthand-properties/-/plugin-transform-shorthand-properties-7.2.0.tgz#6333aee2f8d6ee7e28615457298934a3b46198f0" - integrity sha512-QP4eUM83ha9zmYtpbnyjTLAGKQritA5XW/iG9cjtuOI8s1RuL/3V6a3DeSHfKutJQ+ayUfeZJPcnCYEQzaPQqg== - dependencies: - "@babel/helper-plugin-utils" "^7.0.0" - -"@babel/plugin-transform-spread@^7.2.0": - version "7.2.2" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-spread/-/plugin-transform-spread-7.2.2.tgz#3103a9abe22f742b6d406ecd3cd49b774919b406" - integrity sha512-KWfky/58vubwtS0hLqEnrWJjsMGaOeSBn90Ezn5Jeg9Z8KKHmELbP1yGylMlm5N6TPKeY9A2+UaSYLdxahg01w== - dependencies: - "@babel/helper-plugin-utils" "^7.0.0" - -"@babel/plugin-transform-sticky-regex@^7.2.0": - version "7.2.0" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-sticky-regex/-/plugin-transform-sticky-regex-7.2.0.tgz#a1e454b5995560a9c1e0d537dfc15061fd2687e1" - integrity sha512-KKYCoGaRAf+ckH8gEL3JHUaFVyNHKe3ASNsZ+AlktgHevvxGigoIttrEJb8iKN03Q7Eazlv1s6cx2B2cQ3Jabw== - dependencies: - "@babel/helper-plugin-utils" "^7.0.0" - "@babel/helper-regex" "^7.0.0" - -"@babel/plugin-transform-template-literals@^7.2.0": - version "7.4.4" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-template-literals/-/plugin-transform-template-literals-7.4.4.tgz#9d28fea7bbce637fb7612a0750989d8321d4bcb0" - integrity sha512-mQrEC4TWkhLN0z8ygIvEL9ZEToPhG5K7KDW3pzGqOfIGZ28Jb0POUkeWcoz8HnHvhFy6dwAT1j8OzqN8s804+g== - dependencies: - "@babel/helper-annotate-as-pure" "^7.0.0" - "@babel/helper-plugin-utils" "^7.0.0" - -"@babel/plugin-transform-typeof-symbol@^7.2.0": - version "7.2.0" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-typeof-symbol/-/plugin-transform-typeof-symbol-7.2.0.tgz#117d2bcec2fbf64b4b59d1f9819894682d29f2b2" - integrity sha512-2LNhETWYxiYysBtrBTqL8+La0jIoQQnIScUJc74OYvUGRmkskNY4EzLCnjHBzdmb38wqtTaixpo1NctEcvMDZw== - dependencies: - "@babel/helper-plugin-utils" "^7.0.0" - -"@babel/plugin-transform-unicode-regex@^7.2.0": - version "7.4.4" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-unicode-regex/-/plugin-transform-unicode-regex-7.4.4.tgz#ab4634bb4f14d36728bf5978322b35587787970f" - integrity sha512-il+/XdNw01i93+M9J9u4T7/e/Ue/vWfNZE4IRUQjplu2Mqb/AFTDimkw2tdEdSH50wuQXZAbXSql0UphQke+vA== - dependencies: - "@babel/helper-plugin-utils" "^7.0.0" - "@babel/helper-regex" "^7.4.4" - regexpu-core "^4.5.4" - -"@babel/preset-env@^7.0.0 < 7.4.0": - version "7.3.4" - resolved "https://registry.yarnpkg.com/@babel/preset-env/-/preset-env-7.3.4.tgz#887cf38b6d23c82f19b5135298bdb160062e33e1" - integrity sha512-2mwqfYMK8weA0g0uBKOt4FE3iEodiHy9/CW0b+nWXcbL+pGzLx8ESYc+j9IIxr6LTDHWKgPm71i9smo02bw+gA== - dependencies: - "@babel/helper-module-imports" "^7.0.0" - "@babel/helper-plugin-utils" "^7.0.0" - "@babel/plugin-proposal-async-generator-functions" "^7.2.0" - "@babel/plugin-proposal-json-strings" "^7.2.0" - "@babel/plugin-proposal-object-rest-spread" "^7.3.4" - "@babel/plugin-proposal-optional-catch-binding" "^7.2.0" - "@babel/plugin-proposal-unicode-property-regex" "^7.2.0" - "@babel/plugin-syntax-async-generators" "^7.2.0" - "@babel/plugin-syntax-json-strings" "^7.2.0" - "@babel/plugin-syntax-object-rest-spread" "^7.2.0" - "@babel/plugin-syntax-optional-catch-binding" "^7.2.0" - "@babel/plugin-transform-arrow-functions" "^7.2.0" - "@babel/plugin-transform-async-to-generator" "^7.3.4" - "@babel/plugin-transform-block-scoped-functions" "^7.2.0" - "@babel/plugin-transform-block-scoping" "^7.3.4" - "@babel/plugin-transform-classes" "^7.3.4" - "@babel/plugin-transform-computed-properties" "^7.2.0" - "@babel/plugin-transform-destructuring" "^7.2.0" - "@babel/plugin-transform-dotall-regex" "^7.2.0" - "@babel/plugin-transform-duplicate-keys" "^7.2.0" - "@babel/plugin-transform-exponentiation-operator" "^7.2.0" - "@babel/plugin-transform-for-of" "^7.2.0" - "@babel/plugin-transform-function-name" "^7.2.0" - "@babel/plugin-transform-literals" "^7.2.0" - "@babel/plugin-transform-modules-amd" "^7.2.0" - "@babel/plugin-transform-modules-commonjs" "^7.2.0" - "@babel/plugin-transform-modules-systemjs" "^7.3.4" - "@babel/plugin-transform-modules-umd" "^7.2.0" - "@babel/plugin-transform-named-capturing-groups-regex" "^7.3.0" - "@babel/plugin-transform-new-target" "^7.0.0" - "@babel/plugin-transform-object-super" "^7.2.0" - "@babel/plugin-transform-parameters" "^7.2.0" - "@babel/plugin-transform-regenerator" "^7.3.4" - "@babel/plugin-transform-shorthand-properties" "^7.2.0" - "@babel/plugin-transform-spread" "^7.2.0" - "@babel/plugin-transform-sticky-regex" "^7.2.0" - "@babel/plugin-transform-template-literals" "^7.2.0" - "@babel/plugin-transform-typeof-symbol" "^7.2.0" - "@babel/plugin-transform-unicode-regex" "^7.2.0" - browserslist "^4.3.4" - invariant "^2.2.2" - js-levenshtein "^1.1.3" - semver "^5.3.0" - -"@babel/runtime-corejs2@^7.2.0": - version "7.5.5" - resolved "https://registry.yarnpkg.com/@babel/runtime-corejs2/-/runtime-corejs2-7.5.5.tgz#c3214c08ef20341af4187f1c9fbdc357fbec96b2" - integrity sha512-FYATQVR00NSNi7mUfpPDp7E8RYMXDuO8gaix7u/w3GekfUinKgX1AcTxs7SoiEmoEW9mbpjrwqWSW6zCmw5h8A== - dependencies: - core-js "^2.6.5" - regenerator-runtime "^0.13.2" - -"@babel/runtime@^7.0.0": - version "7.5.5" - resolved "https://registry.yarnpkg.com/@babel/runtime/-/runtime-7.5.5.tgz#74fba56d35efbeca444091c7850ccd494fd2f132" - integrity sha512-28QvEGyQyNkB0/m2B4FU7IEZGK2NUrcMtT6BZEFALTguLk+AUT6ofsHtPk5QyjAdUkpMJ+/Em+quwz4HOt30AQ== - dependencies: - regenerator-runtime "^0.13.2" - -"@babel/template@^7.1.0", "@babel/template@^7.4.4": - version "7.4.4" - resolved "https://registry.yarnpkg.com/@babel/template/-/template-7.4.4.tgz#f4b88d1225689a08f5bc3a17483545be9e4ed237" - integrity sha512-CiGzLN9KgAvgZsnivND7rkA+AeJ9JB0ciPOD4U59GKbQP2iQl+olF1l76kJOupqidozfZ32ghwBEJDhnk9MEcw== - dependencies: - "@babel/code-frame" "^7.0.0" - "@babel/parser" "^7.4.4" - "@babel/types" "^7.4.4" - -"@babel/traverse@^7.1.0", "@babel/traverse@^7.4.4", "@babel/traverse@^7.5.5": - version "7.5.5" - resolved "https://registry.yarnpkg.com/@babel/traverse/-/traverse-7.5.5.tgz#f664f8f368ed32988cd648da9f72d5ca70f165bb" - integrity sha512-MqB0782whsfffYfSjH4TM+LMjrJnhCNEDMDIjeTpl+ASaUvxcjoiVCo/sM1GhS1pHOXYfWVCYneLjMckuUxDaQ== - dependencies: - "@babel/code-frame" "^7.5.5" - "@babel/generator" "^7.5.5" - "@babel/helper-function-name" "^7.1.0" - "@babel/helper-split-export-declaration" "^7.4.4" - "@babel/parser" "^7.5.5" - "@babel/types" "^7.5.5" - debug "^4.1.0" - globals "^11.1.0" - lodash "^4.17.13" - -"@babel/types@^7.0.0", "@babel/types@^7.2.0", "@babel/types@^7.4.4", "@babel/types@^7.5.5": - version "7.5.5" - resolved "https://registry.yarnpkg.com/@babel/types/-/types-7.5.5.tgz#97b9f728e182785909aa4ab56264f090a028d18a" - integrity sha512-s63F9nJioLqOlW3UkyMd+BYhXt44YuaFm/VV0VwuteqjYwRrObkU7ra9pY4wAJR3oXi8hJrMcrcJdO/HH33vtw== - dependencies: - esutils "^2.0.2" - lodash "^4.17.13" - to-fast-properties "^2.0.0" - -"@mrmlnc/readdir-enhanced@^2.2.1": - version "2.2.1" - resolved "https://registry.yarnpkg.com/@mrmlnc/readdir-enhanced/-/readdir-enhanced-2.2.1.tgz#524af240d1a360527b730475ecfa1344aa540dde" - integrity sha512-bPHp6Ji8b41szTOcaP63VlnbbO5Ny6dwAATtY6JTjh5N2OLrb5Qk/Th5cRkRQhkWCt+EJsYrNB0MiL+Gpn6e3g== - dependencies: - call-me-maybe "^1.0.1" - glob-to-regexp "^0.3.0" - -"@nodelib/fs.stat@^1.1.2": - version "1.1.3" - resolved "https://registry.yarnpkg.com/@nodelib/fs.stat/-/fs.stat-1.1.3.tgz#2b5a3ab3f918cca48a8c754c08168e3f03eba61b" - integrity sha512-shAmDyaQC4H92APFoIaVDHCx5bStIocgvbwQyxPRrbUY20V1EYTbSDchWbuwlMG3V17cprZhA6+78JfB+3DTPw== - -"@types/events@*": - version "3.0.0" - resolved "https://registry.yarnpkg.com/@types/events/-/events-3.0.0.tgz#2862f3f58a9a7f7c3e78d79f130dd4d71c25c2a7" - integrity sha512-EaObqwIvayI5a8dCzhFrjKzVwKLxjoG9T6Ppd5CEo07LRKfQ8Yokw54r5+Wq7FaBQ+yXRvQAYPrHwya1/UFt9g== - -"@types/glob@^7.1.1": - version "7.1.1" - resolved "https://registry.yarnpkg.com/@types/glob/-/glob-7.1.1.tgz#aa59a1c6e3fbc421e07ccd31a944c30eba521575" - integrity sha512-1Bh06cbWJUHMC97acuD6UMG29nMt0Aqz1vF3guLfG+kHHJhy3AyohZFFxYk2f7Q1SQIrNwvncxAE0N/9s70F2w== - dependencies: - "@types/events" "*" - "@types/minimatch" "*" - "@types/node" "*" - -"@types/minimatch@*": - version "3.0.3" - resolved "https://registry.yarnpkg.com/@types/minimatch/-/minimatch-3.0.3.tgz#3dca0e3f33b200fc7d1139c0cd96c1268cadfd9d" - integrity sha512-tHq6qdbT9U1IRSGf14CL0pUlULksvY9OZ+5eEgl1N7t+OA3tGvNpxJCzuKQlsNgCVwbAs670L1vcVQi8j9HjnA== - -"@types/node@*": - version "12.6.8" - resolved "https://registry.yarnpkg.com/@types/node/-/node-12.6.8.tgz#e469b4bf9d1c9832aee4907ba8a051494357c12c" - integrity sha512-aX+gFgA5GHcDi89KG5keey2zf0WfZk/HAQotEamsK2kbey+8yGKcson0hbK8E+v0NArlCJQCqMP161YhV6ZXLg== - -"@types/q@^1.5.1": - version "1.5.2" - resolved "https://registry.yarnpkg.com/@types/q/-/q-1.5.2.tgz#690a1475b84f2a884fd07cd797c00f5f31356ea8" - integrity sha512-ce5d3q03Ex0sy4R14722Rmt6MT07Ua+k4FwDfdcToYJcMKNtRVQvJ6JCAPdAmAnbRb6CsX6aYb9m96NGod9uTw== - -"@vue/babel-helper-vue-jsx-merge-props@^1.0.0": - version "1.0.0" - resolved "https://registry.yarnpkg.com/@vue/babel-helper-vue-jsx-merge-props/-/babel-helper-vue-jsx-merge-props-1.0.0.tgz#048fe579958da408fb7a8b2a3ec050b50a661040" - integrity sha512-6tyf5Cqm4m6v7buITuwS+jHzPlIPxbFzEhXR5JGZpbrvOcp1hiQKckd305/3C7C36wFekNTQSxAtgeM0j0yoUw== - -"@vue/babel-plugin-transform-vue-jsx@^1.0.0": - version "1.0.0" - resolved "https://registry.yarnpkg.com/@vue/babel-plugin-transform-vue-jsx/-/babel-plugin-transform-vue-jsx-1.0.0.tgz#ebcbf39c312c94114c8c4f407ee4f6c97aa45432" - integrity sha512-U+JNwVQSmaLKjO3lzCUC3cNXxprgezV1N+jOdqbP4xWNaqtWUCJnkjTVcgECM18A/AinDKPcUUeoyhU7yxUxXQ== - dependencies: - "@babel/helper-module-imports" "^7.0.0" - "@babel/plugin-syntax-jsx" "^7.2.0" - "@vue/babel-helper-vue-jsx-merge-props" "^1.0.0" - html-tags "^2.0.0" - lodash.kebabcase "^4.1.1" - svg-tags "^1.0.0" - -"@vue/babel-preset-app@^3.1.1": - version "3.9.2" - resolved "https://registry.yarnpkg.com/@vue/babel-preset-app/-/babel-preset-app-3.9.2.tgz#b72a9b06abbe3f8f272783be13951271277be338" - integrity sha512-0suuCbu4jkVcVYBjPmuKxeDbrhwThYZHu3DUmtsVuOzFEGeXmco60VmXveniL/bnDUdZyknSuYP4FxgS34gw9w== - dependencies: - "@babel/helper-module-imports" "^7.0.0" - "@babel/plugin-proposal-class-properties" "^7.0.0" - "@babel/plugin-proposal-decorators" "^7.1.0" - "@babel/plugin-syntax-dynamic-import" "^7.0.0" - "@babel/plugin-syntax-jsx" "^7.0.0" - "@babel/plugin-transform-runtime" "^7.4.0" - "@babel/preset-env" "^7.0.0 < 7.4.0" - "@babel/runtime" "^7.0.0" - "@babel/runtime-corejs2" "^7.2.0" - "@vue/babel-preset-jsx" "^1.0.0" - babel-plugin-dynamic-import-node "^2.2.0" - babel-plugin-module-resolver "3.2.0" - core-js "^2.6.5" - -"@vue/babel-preset-jsx@^1.0.0": - version "1.0.0" - resolved "https://registry.yarnpkg.com/@vue/babel-preset-jsx/-/babel-preset-jsx-1.0.0.tgz#e515cd453a5a8ea6b0f30b2bb92f266d8ab4e9f5" - integrity sha512-5CbDu/QHS+TtQNw5aYAffiMxBBB2Eo9+RJpS8X+6FJbdG5Rvc4TVipEqkrg0pJviWadNg7TEy0Uz4o7VNXeIZw== - dependencies: - "@vue/babel-helper-vue-jsx-merge-props" "^1.0.0" - "@vue/babel-plugin-transform-vue-jsx" "^1.0.0" - "@vue/babel-sugar-functional-vue" "^1.0.0" - "@vue/babel-sugar-inject-h" "^1.0.0" - "@vue/babel-sugar-v-model" "^1.0.0" - "@vue/babel-sugar-v-on" "^1.0.0" - -"@vue/babel-sugar-functional-vue@^1.0.0": - version "1.0.0" - resolved "https://registry.yarnpkg.com/@vue/babel-sugar-functional-vue/-/babel-sugar-functional-vue-1.0.0.tgz#17e2c4ca27b74b244da3b923240ec91d10048cb3" - integrity sha512-XE/jNaaorTuhWayCz+QClk5AB9OV5HzrwbzEC6sIUY0J60A28ONQKeTwxfidW42egOkqNH/UU6eE3KLfmiDj0Q== - dependencies: - "@babel/plugin-syntax-jsx" "^7.2.0" - -"@vue/babel-sugar-inject-h@^1.0.0": - version "1.0.0" - resolved "https://registry.yarnpkg.com/@vue/babel-sugar-inject-h/-/babel-sugar-inject-h-1.0.0.tgz#e5efb6c5b5b7988dc03831af6d133bf7bcde6347" - integrity sha512-NxWU+DqtbZgfGvd25GPoFMj+rvyQ8ZA1pHj8vIeqRij+vx3sXoKkObjA9ulZunvWw5F6uG9xYy4ytpxab/X+Hg== - dependencies: - "@babel/plugin-syntax-jsx" "^7.2.0" - -"@vue/babel-sugar-v-model@^1.0.0": - version "1.0.0" - resolved "https://registry.yarnpkg.com/@vue/babel-sugar-v-model/-/babel-sugar-v-model-1.0.0.tgz#f4da56aa67f65a349bd2c269a95e72e601af4613" - integrity sha512-Pfg2Al0io66P1eO6zUbRIgpyKCU2qTnumiE0lao/wA/uNdb7Dx5Tfd1W6tO5SsByETPnEs8i8+gawRIXX40rFw== - dependencies: - "@babel/plugin-syntax-jsx" "^7.2.0" - "@vue/babel-helper-vue-jsx-merge-props" "^1.0.0" - "@vue/babel-plugin-transform-vue-jsx" "^1.0.0" - camelcase "^5.0.0" - html-tags "^2.0.0" - svg-tags "^1.0.0" - -"@vue/babel-sugar-v-on@^1.0.0": - version "1.0.0" - resolved "https://registry.yarnpkg.com/@vue/babel-sugar-v-on/-/babel-sugar-v-on-1.0.0.tgz#a633ee8fe205763e865b011246981b7f89668033" - integrity sha512-2aqJaDLKdSSGlxZU+GjFERaSNUaa6DQreV+V/K4W/6Lxj8520/r1lChWEa/zuAoPD2Vhy0D2QrqqO+I0D6CkKw== - dependencies: - "@babel/plugin-syntax-jsx" "^7.2.0" - "@vue/babel-plugin-transform-vue-jsx" "^1.0.0" - camelcase "^5.0.0" - -"@vue/component-compiler-utils@^3.0.0": - version "3.0.0" - resolved "https://registry.yarnpkg.com/@vue/component-compiler-utils/-/component-compiler-utils-3.0.0.tgz#d16fa26b836c06df5baaeb45f3d80afc47e35634" - integrity sha512-am+04/0UX7ektcmvhYmrf84BDVAD8afFOf4asZjN84q8xzxFclbk5x0MtxuKGfp+zjN5WWPJn3fjFAWtDdIGSw== - dependencies: - consolidate "^0.15.1" - hash-sum "^1.0.2" - lru-cache "^4.1.2" - merge-source-map "^1.1.0" - postcss "^7.0.14" - postcss-selector-parser "^5.0.0" - prettier "1.16.3" - source-map "~0.6.1" - vue-template-es2015-compiler "^1.9.0" - -"@vuepress/core@^1.0.2": - version "1.0.2" - resolved "https://registry.yarnpkg.com/@vuepress/core/-/core-1.0.2.tgz#75d0c6ccb4be92c6674c3bbfbe25639c8239921b" - integrity sha512-PUMaxq44wEuqXHutcmxj6q9cCRS4kZ1nyBvvHr9AIuxJflgYDw/k8wxhYuZjsxVWhpJjsPywLGNRyLN88vJcqQ== - dependencies: - "@babel/core" "^7.0.0" - "@vue/babel-preset-app" "^3.1.1" - "@vuepress/markdown" "^1.0.2" - "@vuepress/markdown-loader" "^1.0.2" - "@vuepress/plugin-last-updated" "^1.0.2" - "@vuepress/plugin-register-components" "^1.0.2" - "@vuepress/shared-utils" "^1.0.2" - autoprefixer "^9.5.1" - babel-loader "^8.0.4" - cache-loader "^3.0.0" - chokidar "^2.0.3" - connect-history-api-fallback "^1.5.0" - copy-webpack-plugin "^5.0.2" - cross-spawn "^6.0.5" - css-loader "^2.1.1" - file-loader "^3.0.1" - js-yaml "^3.11.0" - lru-cache "^5.1.1" - mini-css-extract-plugin "0.6.0" - optimize-css-assets-webpack-plugin "^5.0.1" - portfinder "^1.0.13" - postcss-loader "^3.0.0" - postcss-safe-parser "^4.0.1" - toml "^3.0.0" - url-loader "^1.0.1" - vue "^2.5.16" - vue-loader "^15.2.4" - vue-router "^3.0.2" - vue-server-renderer "^2.5.16" - vue-template-compiler "^2.5.16" - vuepress-html-webpack-plugin "^3.2.0" - vuepress-plugin-container "^2.0.0" - webpack "^4.8.1" - webpack-chain "^4.6.0" - webpack-dev-server "^3.5.1" - webpack-merge "^4.1.2" - webpackbar "3.2.0" - -"@vuepress/markdown-loader@^1.0.2": - version "1.0.2" - resolved "https://registry.yarnpkg.com/@vuepress/markdown-loader/-/markdown-loader-1.0.2.tgz#b068df3049f6b63cfee329f85aed3bb0aa9e7ab0" - integrity sha512-ljD2mVDpeq0VvCHMHfemGW+0fhLmOMldtWIAYQ/I8LjLuV2qknAwjzZ4tEAqveaVIFMUBRP3V6d8YGIK9dr6kg== - dependencies: - "@vuepress/markdown" "^1.0.2" - loader-utils "^1.1.0" - lru-cache "^5.1.1" - -"@vuepress/markdown@^1.0.2": - version "1.0.2" - resolved "https://registry.yarnpkg.com/@vuepress/markdown/-/markdown-1.0.2.tgz#436c5aa74e22cf7f6705b99c8892b6ba2d84cd0a" - integrity sha512-ddl0FG11aeidjcFYYNU53xZ1WLEYb3g5/hijfSCEQKyMv+gDXy7Z3/uc4I4oH2UNtB2Wpo3pQoeKGY56edcBuA== - dependencies: - "@vuepress/shared-utils" "^1.0.2" - markdown-it "^8.4.1" - markdown-it-anchor "^5.0.2" - markdown-it-chain "^1.3.0" - markdown-it-emoji "^1.4.0" - markdown-it-table-of-contents "^0.4.0" - prismjs "^1.13.0" - -"@vuepress/plugin-active-header-links@^1.0.2": - version "1.0.2" - resolved "https://registry.yarnpkg.com/@vuepress/plugin-active-header-links/-/plugin-active-header-links-1.0.2.tgz#df04f7fc21640d3e0a0b704037e360e75974d1a2" - integrity sha512-Wo9NP55OOJ/vGFnYwStZcDBJMnf1gNDL159K7oiiEltuz8kjZBqmtsIjQXOzXFjA8voYh/RVL48Sr4eGCDd7LQ== - dependencies: - lodash.throttle "^4.1.1" - -"@vuepress/plugin-last-updated@^1.0.2": - version "1.0.2" - resolved "https://registry.yarnpkg.com/@vuepress/plugin-last-updated/-/plugin-last-updated-1.0.2.tgz#c839c5fb585c469a8c2ff70c16204dd72478545a" - integrity sha512-SwugVHcllUwy9WPqtWWM+hUEvH6SDPFJAHnpIs0kXJmaxIIipqF/9+CokT5QzxzGVHeYPU4YKtLadEIXdRcXsw== - dependencies: - cross-spawn "^6.0.5" - -"@vuepress/plugin-nprogress@^1.0.2": - version "1.0.2" - resolved "https://registry.yarnpkg.com/@vuepress/plugin-nprogress/-/plugin-nprogress-1.0.2.tgz#3fae13c8af23292cf324d159c77e4d0ffc3133ab" - integrity sha512-degCJe2Z0eHbYblUGQXuDMIZSwH7twQcbWtkuH8goxXNilvtVxtWvBkUJouJ9RN3RuSk7EfPT171mrwq9yqbUg== - dependencies: - nprogress "^0.2.0" - -"@vuepress/plugin-register-components@^1.0.2": - version "1.0.2" - resolved "https://registry.yarnpkg.com/@vuepress/plugin-register-components/-/plugin-register-components-1.0.2.tgz#504c190b1c1836e3428d90749a2dbd59f6e596b9" - integrity sha512-iqUq4kgNdVHba0cZJLv81DfB9ZsTdJY7gynN0NYHFwDEjsdOh1cRMgteuWa/mmK9XfopMO5oysD9WDhzCiIjfQ== - dependencies: - "@vuepress/shared-utils" "^1.0.2" - -"@vuepress/plugin-search@^1.0.2": - version "1.0.2" - resolved "https://registry.yarnpkg.com/@vuepress/plugin-search/-/plugin-search-1.0.2.tgz#6d43fb46b207d48b797a5bc5b01824662db4684d" - integrity sha512-LCFZLp+adppdHETIEARwQhczj+mdpa+D25qL9RNmYxzU9mF6qItYNLl57P6omGU2Vr8frAc+rWgjbi4cjkbCvQ== - -"@vuepress/shared-utils@^1.0.2": - version "1.0.2" - resolved "https://registry.yarnpkg.com/@vuepress/shared-utils/-/shared-utils-1.0.2.tgz#4e1342748b7594fe4fde9dce3bf201538fa5ca67" - integrity sha512-QyNV76Dn0u2ooXbC3AXJZrQLuTNS4i8xSmJqZWsel2ooJKknXP3UIMIENcK1QFHnlIACznyV53u9hRAYBaZEWQ== - dependencies: - chalk "^2.3.2" - diacritics "^1.3.0" - escape-html "^1.0.3" - fs-extra "^7.0.1" - globby "^9.2.0" - gray-matter "^4.0.1" - hash-sum "^1.0.2" - semver "^6.0.0" - upath "^1.1.0" - -"@vuepress/theme-default@^1.0.2": - version "1.0.2" - resolved "https://registry.yarnpkg.com/@vuepress/theme-default/-/theme-default-1.0.2.tgz#7678c4755db9d891effee838991287d31ae9c5ed" - integrity sha512-fawiYshvQWXyaEgMXcyqj7j0atHLysIA2AzFt4K6y29WaMfiIAPE9lsxymTzT4zkc/T6nRP/TqwiuUaOK12wkw== - dependencies: - "@vuepress/plugin-active-header-links" "^1.0.2" - "@vuepress/plugin-nprogress" "^1.0.2" - "@vuepress/plugin-search" "^1.0.2" - docsearch.js "^2.5.2" - stylus "^0.54.5" - stylus-loader "^3.0.2" - vuepress-plugin-container "^2.0.0" - -"@webassemblyjs/ast@1.8.5": - version "1.8.5" - resolved "https://registry.yarnpkg.com/@webassemblyjs/ast/-/ast-1.8.5.tgz#51b1c5fe6576a34953bf4b253df9f0d490d9e359" - integrity sha512-aJMfngIZ65+t71C3y2nBBg5FFG0Okt9m0XEgWZ7Ywgn1oMAT8cNwx00Uv1cQyHtidq0Xn94R4TAywO+LCQ+ZAQ== - dependencies: - "@webassemblyjs/helper-module-context" "1.8.5" - "@webassemblyjs/helper-wasm-bytecode" "1.8.5" - "@webassemblyjs/wast-parser" "1.8.5" - -"@webassemblyjs/floating-point-hex-parser@1.8.5": - version "1.8.5" - resolved "https://registry.yarnpkg.com/@webassemblyjs/floating-point-hex-parser/-/floating-point-hex-parser-1.8.5.tgz#1ba926a2923613edce496fd5b02e8ce8a5f49721" - integrity sha512-9p+79WHru1oqBh9ewP9zW95E3XAo+90oth7S5Re3eQnECGq59ly1Ri5tsIipKGpiStHsUYmY3zMLqtk3gTcOtQ== - -"@webassemblyjs/helper-api-error@1.8.5": - version "1.8.5" - resolved "https://registry.yarnpkg.com/@webassemblyjs/helper-api-error/-/helper-api-error-1.8.5.tgz#c49dad22f645227c5edb610bdb9697f1aab721f7" - integrity sha512-Za/tnzsvnqdaSPOUXHyKJ2XI7PDX64kWtURyGiJJZKVEdFOsdKUCPTNEVFZq3zJ2R0G5wc2PZ5gvdTRFgm81zA== - -"@webassemblyjs/helper-buffer@1.8.5": - version "1.8.5" - resolved "https://registry.yarnpkg.com/@webassemblyjs/helper-buffer/-/helper-buffer-1.8.5.tgz#fea93e429863dd5e4338555f42292385a653f204" - integrity sha512-Ri2R8nOS0U6G49Q86goFIPNgjyl6+oE1abW1pS84BuhP1Qcr5JqMwRFT3Ah3ADDDYGEgGs1iyb1DGX+kAi/c/Q== - -"@webassemblyjs/helper-code-frame@1.8.5": - version "1.8.5" - resolved "https://registry.yarnpkg.com/@webassemblyjs/helper-code-frame/-/helper-code-frame-1.8.5.tgz#9a740ff48e3faa3022b1dff54423df9aa293c25e" - integrity sha512-VQAadSubZIhNpH46IR3yWO4kZZjMxN1opDrzePLdVKAZ+DFjkGD/rf4v1jap744uPVU6yjL/smZbRIIJTOUnKQ== - dependencies: - "@webassemblyjs/wast-printer" "1.8.5" - -"@webassemblyjs/helper-fsm@1.8.5": - version "1.8.5" - resolved "https://registry.yarnpkg.com/@webassemblyjs/helper-fsm/-/helper-fsm-1.8.5.tgz#ba0b7d3b3f7e4733da6059c9332275d860702452" - integrity sha512-kRuX/saORcg8se/ft6Q2UbRpZwP4y7YrWsLXPbbmtepKr22i8Z4O3V5QE9DbZK908dh5Xya4Un57SDIKwB9eow== - -"@webassemblyjs/helper-module-context@1.8.5": - version "1.8.5" - resolved "https://registry.yarnpkg.com/@webassemblyjs/helper-module-context/-/helper-module-context-1.8.5.tgz#def4b9927b0101dc8cbbd8d1edb5b7b9c82eb245" - integrity sha512-/O1B236mN7UNEU4t9X7Pj38i4VoU8CcMHyy3l2cV/kIF4U5KoHXDVqcDuOs1ltkac90IM4vZdHc52t1x8Yfs3g== - dependencies: - "@webassemblyjs/ast" "1.8.5" - mamacro "^0.0.3" - -"@webassemblyjs/helper-wasm-bytecode@1.8.5": - version "1.8.5" - resolved "https://registry.yarnpkg.com/@webassemblyjs/helper-wasm-bytecode/-/helper-wasm-bytecode-1.8.5.tgz#537a750eddf5c1e932f3744206551c91c1b93e61" - integrity sha512-Cu4YMYG3Ddl72CbmpjU/wbP6SACcOPVbHN1dI4VJNJVgFwaKf1ppeFJrwydOG3NDHxVGuCfPlLZNyEdIYlQ6QQ== - -"@webassemblyjs/helper-wasm-section@1.8.5": - version "1.8.5" - resolved "https://registry.yarnpkg.com/@webassemblyjs/helper-wasm-section/-/helper-wasm-section-1.8.5.tgz#74ca6a6bcbe19e50a3b6b462847e69503e6bfcbf" - integrity sha512-VV083zwR+VTrIWWtgIUpqfvVdK4ff38loRmrdDBgBT8ADXYsEZ5mPQ4Nde90N3UYatHdYoDIFb7oHzMncI02tA== - dependencies: - "@webassemblyjs/ast" "1.8.5" - "@webassemblyjs/helper-buffer" "1.8.5" - "@webassemblyjs/helper-wasm-bytecode" "1.8.5" - "@webassemblyjs/wasm-gen" "1.8.5" - -"@webassemblyjs/ieee754@1.8.5": - version "1.8.5" - resolved "https://registry.yarnpkg.com/@webassemblyjs/ieee754/-/ieee754-1.8.5.tgz#712329dbef240f36bf57bd2f7b8fb9bf4154421e" - integrity sha512-aaCvQYrvKbY/n6wKHb/ylAJr27GglahUO89CcGXMItrOBqRarUMxWLJgxm9PJNuKULwN5n1csT9bYoMeZOGF3g== - dependencies: - "@xtuc/ieee754" "^1.2.0" - -"@webassemblyjs/leb128@1.8.5": - version "1.8.5" - resolved "https://registry.yarnpkg.com/@webassemblyjs/leb128/-/leb128-1.8.5.tgz#044edeb34ea679f3e04cd4fd9824d5e35767ae10" - integrity sha512-plYUuUwleLIziknvlP8VpTgO4kqNaH57Y3JnNa6DLpu/sGcP6hbVdfdX5aHAV716pQBKrfuU26BJK29qY37J7A== - dependencies: - "@xtuc/long" "4.2.2" - -"@webassemblyjs/utf8@1.8.5": - version "1.8.5" - resolved "https://registry.yarnpkg.com/@webassemblyjs/utf8/-/utf8-1.8.5.tgz#a8bf3b5d8ffe986c7c1e373ccbdc2a0915f0cedc" - integrity sha512-U7zgftmQriw37tfD934UNInokz6yTmn29inT2cAetAsaU9YeVCveWEwhKL1Mg4yS7q//NGdzy79nlXh3bT8Kjw== - -"@webassemblyjs/wasm-edit@1.8.5": - version "1.8.5" - resolved "https://registry.yarnpkg.com/@webassemblyjs/wasm-edit/-/wasm-edit-1.8.5.tgz#962da12aa5acc1c131c81c4232991c82ce56e01a" - integrity sha512-A41EMy8MWw5yvqj7MQzkDjU29K7UJq1VrX2vWLzfpRHt3ISftOXqrtojn7nlPsZ9Ijhp5NwuODuycSvfAO/26Q== - dependencies: - "@webassemblyjs/ast" "1.8.5" - "@webassemblyjs/helper-buffer" "1.8.5" - "@webassemblyjs/helper-wasm-bytecode" "1.8.5" - "@webassemblyjs/helper-wasm-section" "1.8.5" - "@webassemblyjs/wasm-gen" "1.8.5" - "@webassemblyjs/wasm-opt" "1.8.5" - "@webassemblyjs/wasm-parser" "1.8.5" - "@webassemblyjs/wast-printer" "1.8.5" - -"@webassemblyjs/wasm-gen@1.8.5": - version "1.8.5" - resolved "https://registry.yarnpkg.com/@webassemblyjs/wasm-gen/-/wasm-gen-1.8.5.tgz#54840766c2c1002eb64ed1abe720aded714f98bc" - integrity sha512-BCZBT0LURC0CXDzj5FXSc2FPTsxwp3nWcqXQdOZE4U7h7i8FqtFK5Egia6f9raQLpEKT1VL7zr4r3+QX6zArWg== - dependencies: - "@webassemblyjs/ast" "1.8.5" - "@webassemblyjs/helper-wasm-bytecode" "1.8.5" - "@webassemblyjs/ieee754" "1.8.5" - "@webassemblyjs/leb128" "1.8.5" - "@webassemblyjs/utf8" "1.8.5" - -"@webassemblyjs/wasm-opt@1.8.5": - version "1.8.5" - resolved "https://registry.yarnpkg.com/@webassemblyjs/wasm-opt/-/wasm-opt-1.8.5.tgz#b24d9f6ba50394af1349f510afa8ffcb8a63d264" - integrity sha512-HKo2mO/Uh9A6ojzu7cjslGaHaUU14LdLbGEKqTR7PBKwT6LdPtLLh9fPY33rmr5wcOMrsWDbbdCHq4hQUdd37Q== - dependencies: - "@webassemblyjs/ast" "1.8.5" - "@webassemblyjs/helper-buffer" "1.8.5" - "@webassemblyjs/wasm-gen" "1.8.5" - "@webassemblyjs/wasm-parser" "1.8.5" - -"@webassemblyjs/wasm-parser@1.8.5": - version "1.8.5" - resolved "https://registry.yarnpkg.com/@webassemblyjs/wasm-parser/-/wasm-parser-1.8.5.tgz#21576f0ec88b91427357b8536383668ef7c66b8d" - integrity sha512-pi0SYE9T6tfcMkthwcgCpL0cM9nRYr6/6fjgDtL6q/ZqKHdMWvxitRi5JcZ7RI4SNJJYnYNaWy5UUrHQy998lw== - dependencies: - "@webassemblyjs/ast" "1.8.5" - "@webassemblyjs/helper-api-error" "1.8.5" - "@webassemblyjs/helper-wasm-bytecode" "1.8.5" - "@webassemblyjs/ieee754" "1.8.5" - "@webassemblyjs/leb128" "1.8.5" - "@webassemblyjs/utf8" "1.8.5" - -"@webassemblyjs/wast-parser@1.8.5": - version "1.8.5" - resolved "https://registry.yarnpkg.com/@webassemblyjs/wast-parser/-/wast-parser-1.8.5.tgz#e10eecd542d0e7bd394f6827c49f3df6d4eefb8c" - integrity sha512-daXC1FyKWHF1i11obK086QRlsMsY4+tIOKgBqI1lxAnkp9xe9YMcgOxm9kLe+ttjs5aWV2KKE1TWJCN57/Btsg== - dependencies: - "@webassemblyjs/ast" "1.8.5" - "@webassemblyjs/floating-point-hex-parser" "1.8.5" - "@webassemblyjs/helper-api-error" "1.8.5" - "@webassemblyjs/helper-code-frame" "1.8.5" - "@webassemblyjs/helper-fsm" "1.8.5" - "@xtuc/long" "4.2.2" - -"@webassemblyjs/wast-printer@1.8.5": - version "1.8.5" - resolved "https://registry.yarnpkg.com/@webassemblyjs/wast-printer/-/wast-printer-1.8.5.tgz#114bbc481fd10ca0e23b3560fa812748b0bae5bc" - integrity sha512-w0U0pD4EhlnvRyeJzBqaVSJAo9w/ce7/WPogeXLzGkO6hzhr4GnQIZ4W4uUt5b9ooAaXPtnXlj0gzsXEOUNYMg== - dependencies: - "@webassemblyjs/ast" "1.8.5" - "@webassemblyjs/wast-parser" "1.8.5" - "@xtuc/long" "4.2.2" - -"@xtuc/ieee754@^1.2.0": - version "1.2.0" - resolved "https://registry.yarnpkg.com/@xtuc/ieee754/-/ieee754-1.2.0.tgz#eef014a3145ae477a1cbc00cd1e552336dceb790" - integrity sha512-DX8nKgqcGwsc0eJSqYt5lwP4DH5FlHnmuWWBRy7X0NcaGR0ZtuyeESgMwTYVEtxmsNGY+qit4QYT/MIYTOTPeA== - -"@xtuc/long@4.2.2": - version "4.2.2" - resolved "https://registry.yarnpkg.com/@xtuc/long/-/long-4.2.2.tgz#d291c6a4e97989b5c61d9acf396ae4fe133a718d" - integrity sha512-NuHqBY1PB/D8xU6s/thBgOAiAP7HOYDQ32+BFZILJ8ivkUkAHQnWfn6WhL79Owj1qmUnoN/YPhktdIoucipkAQ== - -abbrev@1: - version "1.1.1" - resolved "https://registry.yarnpkg.com/abbrev/-/abbrev-1.1.1.tgz#f8f2c887ad10bf67f634f005b6987fed3179aac8" - integrity sha512-nne9/IiQ/hzIhY6pdDnbBtz7DjPTKrY00P/zvPSm5pOFkl6xuGrGnXn/VtTNNfNtAfZ9/1RtehkszU9qcTii0Q== - -accepts@~1.3.4, accepts@~1.3.5, accepts@~1.3.7: - version "1.3.7" - resolved "https://registry.yarnpkg.com/accepts/-/accepts-1.3.7.tgz#531bc726517a3b2b41f850021c6cc15eaab507cd" - integrity sha512-Il80Qs2WjYlJIBNzNkK6KYqlVMTbZLXgHx2oT0pU/fjRHyEp+PEfEPY0R3WCwAGVOtauxh1hOxNgIf5bv7dQpA== - dependencies: - mime-types "~2.1.24" - negotiator "0.6.2" - -acorn@^6.2.0: - version "6.2.0" - resolved "https://registry.yarnpkg.com/acorn/-/acorn-6.2.0.tgz#67f0da2fc339d6cfb5d6fb244fd449f33cd8bbe3" - integrity sha512-8oe72N3WPMjA+2zVG71Ia0nXZ8DpQH+QyyHO+p06jT8eg8FGG3FbcUIi8KziHlAfheJQZeoqbvq1mQSQHXKYLw== - -agentkeepalive@^2.2.0: - version "2.2.0" - resolved "https://registry.yarnpkg.com/agentkeepalive/-/agentkeepalive-2.2.0.tgz#c5d1bd4b129008f1163f236f86e5faea2026e2ef" - integrity sha1-xdG9SxKQCPEWPyNvhuX66iAm4u8= - -ajv-errors@^1.0.0: - version "1.0.1" - resolved "https://registry.yarnpkg.com/ajv-errors/-/ajv-errors-1.0.1.tgz#f35986aceb91afadec4102fbd85014950cefa64d" - integrity sha512-DCRfO/4nQ+89p/RK43i8Ezd41EqdGIU4ld7nGF8OQ14oc/we5rEntLCUa7+jrn3nn83BosfwZA0wb4pon2o8iQ== - -ajv-keywords@^3.1.0: - version "3.4.1" - resolved "https://registry.yarnpkg.com/ajv-keywords/-/ajv-keywords-3.4.1.tgz#ef916e271c64ac12171fd8384eaae6b2345854da" - integrity sha512-RO1ibKvd27e6FEShVFfPALuHI3WjSVNeK5FIsmme/LYRNxjKuNj+Dt7bucLa6NdSv3JcVTyMlm9kGR84z1XpaQ== - -ajv@^6.1.0, ajv@^6.5.5: - version "6.10.2" - resolved "https://registry.yarnpkg.com/ajv/-/ajv-6.10.2.tgz#d3cea04d6b017b2894ad69040fec8b623eb4bd52" - integrity sha512-TXtUUEYHuaTEbLZWIKUr5pmBuhDLy+8KYtPYdcV8qC+pOZL+NKqYwvWSRrVXHn+ZmRRAu8vJTAznH7Oag6RVRw== - dependencies: - fast-deep-equal "^2.0.1" - fast-json-stable-stringify "^2.0.0" - json-schema-traverse "^0.4.1" - uri-js "^4.2.2" - -algoliasearch@^3.24.5: - version "3.33.0" - resolved "https://registry.yarnpkg.com/algoliasearch/-/algoliasearch-3.33.0.tgz#83b541124ebb0db54643009d4e660866b3177cdf" - integrity sha512-9DaVmOd7cvcZeYyV0BWAeJHVWJmgOL2DNUEBY/DTR4MzD1wCWs4Djl7LAlfvkGwGBdRHZCG+l0HA1572w3T8zg== - dependencies: - agentkeepalive "^2.2.0" - debug "^2.6.9" - envify "^4.0.0" - es6-promise "^4.1.0" - events "^1.1.0" - foreach "^2.0.5" - global "^4.3.2" - inherits "^2.0.1" - isarray "^2.0.1" - load-script "^1.0.0" - object-keys "^1.0.11" - querystring-es3 "^0.2.1" - reduce "^1.0.1" - semver "^5.1.0" - tunnel-agent "^0.6.0" - -alphanum-sort@^1.0.0: - version "1.0.2" - resolved "https://registry.yarnpkg.com/alphanum-sort/-/alphanum-sort-1.0.2.tgz#97a1119649b211ad33691d9f9f486a8ec9fbe0a3" - integrity sha1-l6ERlkmyEa0zaR2fn0hqjsn74KM= - -amdefine@>=0.0.4: - version "1.0.1" - resolved "https://registry.yarnpkg.com/amdefine/-/amdefine-1.0.1.tgz#4a5282ac164729e93619bcfd3ad151f817ce91f5" - integrity sha1-SlKCrBZHKek2Gbz9OtFR+BfOkfU= - -ansi-colors@^3.0.0: - version "3.2.4" - resolved "https://registry.yarnpkg.com/ansi-colors/-/ansi-colors-3.2.4.tgz#e3a3da4bfbae6c86a9c285625de124a234026fbf" - integrity sha512-hHUXGagefjN2iRrID63xckIvotOXOojhQKWIPUZ4mNUZ9nLZW+7FMNoE1lOkEhNWYsx/7ysGIuJYCiMAA9FnrA== - -ansi-escapes@^4.1.0: - version "4.2.0" - resolved "https://registry.yarnpkg.com/ansi-escapes/-/ansi-escapes-4.2.0.tgz#c38600259cefba178ee3f7166c5ea3a5dd2e88fc" - integrity sha512-0+VX4uhi8m3aNbzoqKmkAVOEj6uQzcUHXoFPkKjhZPTpGRUBqVh930KbB6PS4zIyDZccphlLIYlu8nsjFzkXwg== - dependencies: - type-fest "^0.5.2" - -ansi-html@0.0.7: - version "0.0.7" - resolved "https://registry.yarnpkg.com/ansi-html/-/ansi-html-0.0.7.tgz#813584021962a9e9e6fd039f940d12f56ca7859e" - integrity sha1-gTWEAhliqenm/QOflA0S9WynhZ4= - -ansi-regex@^2.0.0: - version "2.1.1" - resolved "https://registry.yarnpkg.com/ansi-regex/-/ansi-regex-2.1.1.tgz#c3b33ab5ee360d86e0e628f0468ae7ef27d654df" - integrity sha1-w7M6te42DYbg5ijwRorn7yfWVN8= - -ansi-regex@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/ansi-regex/-/ansi-regex-3.0.0.tgz#ed0317c322064f79466c02966bddb605ab37d998" - integrity sha1-7QMXwyIGT3lGbAKWa922Bas32Zg= - -ansi-regex@^4.1.0: - version "4.1.0" - resolved "https://registry.yarnpkg.com/ansi-regex/-/ansi-regex-4.1.0.tgz#8b9f8f08cf1acb843756a839ca8c7e3168c51997" - integrity sha512-1apePfXM1UOSqw0o9IiFAovVz9M5S1Dg+4TrDwfMewQ6p/rmMueb7tWZjQ1rx4Loy1ArBggoqGpfqqdI4rondg== - -ansi-styles@^2.2.1: - version "2.2.1" - resolved "https://registry.yarnpkg.com/ansi-styles/-/ansi-styles-2.2.1.tgz#b432dd3358b634cf75e1e4664368240533c1ddbe" - integrity sha1-tDLdM1i2NM914eRmQ2gkBTPB3b4= - -ansi-styles@^3.2.0, ansi-styles@^3.2.1: - version "3.2.1" - resolved "https://registry.yarnpkg.com/ansi-styles/-/ansi-styles-3.2.1.tgz#41fbb20243e50b12be0f04b8dedbf07520ce841d" - integrity sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA== - dependencies: - color-convert "^1.9.0" - -anymatch@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/anymatch/-/anymatch-2.0.0.tgz#bcb24b4f37934d9aa7ac17b4adaf89e7c76ef2eb" - integrity sha512-5teOsQWABXHHBFP9y3skS5P3d/WfWXpv3FUpy+LorMrNYaT9pI4oLMQX7jzQ2KklNpGpWHzdCXTDT2Y3XGlZBw== - dependencies: - micromatch "^3.1.4" - normalize-path "^2.1.1" - -aproba@^1.0.3, aproba@^1.1.1: - version "1.2.0" - resolved "https://registry.yarnpkg.com/aproba/-/aproba-1.2.0.tgz#6802e6264efd18c790a1b0d517f0f2627bf2c94a" - integrity sha512-Y9J6ZjXtoYh8RnXVCMOU/ttDmk1aBjunq9vO0ta5x85WDQiQfUF9sIPBITdbiiIVcBo03Hi3jMxigBtsddlXRw== - -are-we-there-yet@~1.1.2: - version "1.1.5" - resolved "https://registry.yarnpkg.com/are-we-there-yet/-/are-we-there-yet-1.1.5.tgz#4b35c2944f062a8bfcda66410760350fe9ddfc21" - integrity sha512-5hYdAkZlcG8tOLujVDTgCT+uPX0VnpAH28gWsLfzpXYm7wP6mp5Q/gYyR7YQ0cKVJcXJnl3j2kpBan13PtQf6w== - dependencies: - delegates "^1.0.0" - readable-stream "^2.0.6" - -argparse@^1.0.7: - version "1.0.10" - resolved "https://registry.yarnpkg.com/argparse/-/argparse-1.0.10.tgz#bcd6791ea5ae09725e17e5ad988134cd40b3d911" - integrity sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg== - dependencies: - sprintf-js "~1.0.2" - -arr-diff@^4.0.0: - version "4.0.0" - resolved "https://registry.yarnpkg.com/arr-diff/-/arr-diff-4.0.0.tgz#d6461074febfec71e7e15235761a329a5dc7c520" - integrity sha1-1kYQdP6/7HHn4VI1dhoyml3HxSA= - -arr-flatten@^1.1.0: - version "1.1.0" - resolved "https://registry.yarnpkg.com/arr-flatten/-/arr-flatten-1.1.0.tgz#36048bbff4e7b47e136644316c99669ea5ae91f1" - integrity sha512-L3hKV5R/p5o81R7O02IGnwpDmkp6E982XhtbuwSe3O4qOtMMMtodicASA1Cny2U+aCXcNpml+m4dPsvsJ3jatg== - -arr-union@^3.1.0: - version "3.1.0" - resolved "https://registry.yarnpkg.com/arr-union/-/arr-union-3.1.0.tgz#e39b09aea9def866a8f206e288af63919bae39c4" - integrity sha1-45sJrqne+Gao8gbiiK9jkZuuOcQ= - -array-flatten@1.1.1: - version "1.1.1" - resolved "https://registry.yarnpkg.com/array-flatten/-/array-flatten-1.1.1.tgz#9a5f699051b1e7073328f2a008968b64ea2955d2" - integrity sha1-ml9pkFGx5wczKPKgCJaLZOopVdI= - -array-flatten@^2.1.0: - version "2.1.2" - resolved "https://registry.yarnpkg.com/array-flatten/-/array-flatten-2.1.2.tgz#24ef80a28c1a893617e2149b0c6d0d788293b099" - integrity sha512-hNfzcOV8W4NdualtqBFPyVO+54DSJuZGY9qT4pRroB6S9e3iiido2ISIC5h9R2sPJ8H3FHCIiEnsv1lPXO3KtQ== - -array-union@^1.0.1, array-union@^1.0.2: - version "1.0.2" - resolved "https://registry.yarnpkg.com/array-union/-/array-union-1.0.2.tgz#9a34410e4f4e3da23dea375be5be70f24778ec39" - integrity sha1-mjRBDk9OPaI96jdb5b5w8kd47Dk= - dependencies: - array-uniq "^1.0.1" - -array-uniq@^1.0.1: - version "1.0.3" - resolved "https://registry.yarnpkg.com/array-uniq/-/array-uniq-1.0.3.tgz#af6ac877a25cc7f74e058894753858dfdb24fdb6" - integrity sha1-r2rId6Jcx/dOBYiUdThY39sk/bY= - -array-unique@^0.3.2: - version "0.3.2" - resolved "https://registry.yarnpkg.com/array-unique/-/array-unique-0.3.2.tgz#a894b75d4bc4f6cd679ef3244a9fd8f46ae2d428" - integrity sha1-qJS3XUvE9s1nnvMkSp/Y9Gri1Cg= - -asn1.js@^4.0.0: - version "4.10.1" - resolved "https://registry.yarnpkg.com/asn1.js/-/asn1.js-4.10.1.tgz#b9c2bf5805f1e64aadeed6df3a2bfafb5a73f5a0" - integrity sha512-p32cOF5q0Zqs9uBiONKYLm6BClCoBCM5O9JfeUSlnQLBTxYdTK+pW+nXflm8UkKd2UYlEbYz5qEi0JuZR9ckSw== - dependencies: - bn.js "^4.0.0" - inherits "^2.0.1" - minimalistic-assert "^1.0.0" - -asn1@~0.2.3: - version "0.2.4" - resolved "https://registry.yarnpkg.com/asn1/-/asn1-0.2.4.tgz#8d2475dfab553bb33e77b54e59e880bb8ce23136" - integrity sha512-jxwzQpLQjSmWXgwaCZE9Nz+glAG01yF1QnWgbhGwHI5A6FRIEY6IVqtHhIepHqI7/kyEyQEagBC5mBEFlIYvdg== - dependencies: - safer-buffer "~2.1.0" - -assert-plus@1.0.0, assert-plus@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/assert-plus/-/assert-plus-1.0.0.tgz#f12e0f3c5d77b0b1cdd9146942e4e96c1e4dd525" - integrity sha1-8S4PPF13sLHN2RRpQuTpbB5N1SU= - -assert@^1.1.1: - version "1.5.0" - resolved "https://registry.yarnpkg.com/assert/-/assert-1.5.0.tgz#55c109aaf6e0aefdb3dc4b71240c70bf574b18eb" - integrity sha512-EDsgawzwoun2CZkCgtxJbv392v4nbk9XDD06zI+kQYoBM/3RBWLlEyJARDOmhAAosBjWACEkKL6S+lIZtcAubA== - dependencies: - object-assign "^4.1.1" - util "0.10.3" - -assign-symbols@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/assign-symbols/-/assign-symbols-1.0.0.tgz#59667f41fadd4f20ccbc2bb96b8d4f7f78ec0367" - integrity sha1-WWZ/QfrdTyDMvCu5a41Pf3jsA2c= - -async-each@^1.0.1: - version "1.0.3" - resolved "https://registry.yarnpkg.com/async-each/-/async-each-1.0.3.tgz#b727dbf87d7651602f06f4d4ac387f47d91b0cbf" - integrity sha512-z/WhQ5FPySLdvREByI2vZiTWwCnF0moMJ1hK9YQwDTHKh6I7/uSckMetoRGb5UBZPC1z0jlw+n/XCgjeH7y1AQ== - -async@^1.5.2: - version "1.5.2" - resolved "https://registry.yarnpkg.com/async/-/async-1.5.2.tgz#ec6a61ae56480c0c3cb241c95618e20892f9672a" - integrity sha1-7GphrlZIDAw8skHJVhjiCJL5Zyo= - -asynckit@^0.4.0: - version "0.4.0" - resolved "https://registry.yarnpkg.com/asynckit/-/asynckit-0.4.0.tgz#c79ed97f7f34cb8f2ba1bc9790bcc366474b4b79" - integrity sha1-x57Zf380y48robyXkLzDZkdLS3k= - -atob@^2.1.1: - version "2.1.2" - resolved "https://registry.yarnpkg.com/atob/-/atob-2.1.2.tgz#6d9517eb9e030d2436666651e86bd9f6f13533c9" - integrity sha512-Wm6ukoaOGJi/73p/cl2GvLjTI5JM1k/O14isD73YML8StrH/7/lRFgmg8nICZgD3bZZvjwCGxtMOD3wWNAu8cg== - -autocomplete.js@0.36.0: - version "0.36.0" - resolved "https://registry.yarnpkg.com/autocomplete.js/-/autocomplete.js-0.36.0.tgz#94fe775fe64b6cd42e622d076dc7fd26bedd837b" - integrity sha512-jEwUXnVMeCHHutUt10i/8ZiRaCb0Wo+ZyKxeGsYwBDtw6EJHqEeDrq4UwZRD8YBSvp3g6klP678il2eeiVXN2Q== - dependencies: - immediate "^3.2.3" - -autoprefixer@^9.5.1: - version "9.6.1" - resolved "https://registry.yarnpkg.com/autoprefixer/-/autoprefixer-9.6.1.tgz#51967a02d2d2300bb01866c1611ec8348d355a47" - integrity sha512-aVo5WxR3VyvyJxcJC3h4FKfwCQvQWb1tSI5VHNibddCVWrcD1NvlxEweg3TSgiPztMnWfjpy2FURKA2kvDE+Tw== - dependencies: - browserslist "^4.6.3" - caniuse-lite "^1.0.30000980" - chalk "^2.4.2" - normalize-range "^0.1.2" - num2fraction "^1.2.2" - postcss "^7.0.17" - postcss-value-parser "^4.0.0" - -aws-sign2@~0.7.0: - version "0.7.0" - resolved "https://registry.yarnpkg.com/aws-sign2/-/aws-sign2-0.7.0.tgz#b46e890934a9591f2d2f6f86d7e6a9f1b3fe76a8" - integrity sha1-tG6JCTSpWR8tL2+G1+ap8bP+dqg= - -aws4@^1.8.0: - version "1.8.0" - resolved "https://registry.yarnpkg.com/aws4/-/aws4-1.8.0.tgz#f0e003d9ca9e7f59c7a508945d7b2ef9a04a542f" - integrity sha512-ReZxvNHIOv88FlT7rxcXIIC0fPt4KZqZbOlivyWtXLt8ESx84zd3kMC6iK5jVeS2qt+g7ftS7ye4fi06X5rtRQ== - -axios@^0.19.0: - version "0.19.0" - resolved "https://registry.yarnpkg.com/axios/-/axios-0.19.0.tgz#8e09bff3d9122e133f7b8101c8fbdd00ed3d2ab8" - integrity sha512-1uvKqKQta3KBxIz14F2v06AEHZ/dIoeKfbTRkK1E5oqjDnuEerLmYTgJB5AiQZHJcljpg1TuRzdjDR06qNk0DQ== - dependencies: - follow-redirects "1.5.10" - is-buffer "^2.0.2" - -babel-loader@^8.0.4: - version "8.0.6" - resolved "https://registry.yarnpkg.com/babel-loader/-/babel-loader-8.0.6.tgz#e33bdb6f362b03f4bb141a0c21ab87c501b70dfb" - integrity sha512-4BmWKtBOBm13uoUwd08UwjZlaw3O9GWf456R9j+5YykFZ6LUIjIKLc0zEZf+hauxPOJs96C8k6FvYD09vWzhYw== - dependencies: - find-cache-dir "^2.0.0" - loader-utils "^1.0.2" - mkdirp "^0.5.1" - pify "^4.0.1" - -babel-plugin-dynamic-import-node@^2.2.0, babel-plugin-dynamic-import-node@^2.3.0: - version "2.3.0" - resolved "https://registry.yarnpkg.com/babel-plugin-dynamic-import-node/-/babel-plugin-dynamic-import-node-2.3.0.tgz#f00f507bdaa3c3e3ff6e7e5e98d90a7acab96f7f" - integrity sha512-o6qFkpeQEBxcqt0XYlWzAVxNCSCZdUgcR8IRlhD/8DylxjjO4foPcvTW0GGKa/cVt3rvxZ7o5ippJ+/0nvLhlQ== - dependencies: - object.assign "^4.1.0" - -babel-plugin-module-resolver@3.2.0: - version "3.2.0" - resolved "https://registry.yarnpkg.com/babel-plugin-module-resolver/-/babel-plugin-module-resolver-3.2.0.tgz#ddfa5e301e3b9aa12d852a9979f18b37881ff5a7" - integrity sha512-tjR0GvSndzPew/Iayf4uICWZqjBwnlMWjSx6brryfQ81F9rxBVqwDJtFCV8oOs0+vJeefK9TmdZtkIFdFe1UnA== - dependencies: - find-babel-config "^1.1.0" - glob "^7.1.2" - pkg-up "^2.0.0" - reselect "^3.0.1" - resolve "^1.4.0" - -balanced-match@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/balanced-match/-/balanced-match-1.0.0.tgz#89b4d199ab2bee49de164ea02b89ce462d71b767" - integrity sha1-ibTRmasr7kneFk6gK4nORi1xt2c= - -base64-js@^1.0.2: - version "1.3.0" - resolved "https://registry.yarnpkg.com/base64-js/-/base64-js-1.3.0.tgz#cab1e6118f051095e58b5281aea8c1cd22bfc0e3" - integrity sha512-ccav/yGvoa80BQDljCxsmmQ3Xvx60/UpBIij5QN21W3wBi/hhIC9OoO+KLpu9IJTS9j4DRVJ3aDDF9cMSoa2lw== - -base@^0.11.1: - version "0.11.2" - resolved "https://registry.yarnpkg.com/base/-/base-0.11.2.tgz#7bde5ced145b6d551a90db87f83c558b4eb48a8f" - integrity sha512-5T6P4xPgpp0YDFvSWwEZ4NoE3aM4QBQXDzmVbraCkFj8zHM+mba8SyqB5DbZWyR7mYHo6Y7BdQo3MoA4m0TeQg== - dependencies: - cache-base "^1.0.1" - class-utils "^0.3.5" - component-emitter "^1.2.1" - define-property "^1.0.0" - isobject "^3.0.1" - mixin-deep "^1.2.0" - pascalcase "^0.1.1" - -batch@0.6.1: - version "0.6.1" - resolved "https://registry.yarnpkg.com/batch/-/batch-0.6.1.tgz#dc34314f4e679318093fc760272525f94bf25c16" - integrity sha1-3DQxT05nkxgJP8dgJyUl+UvyXBY= - -bcrypt-pbkdf@^1.0.0: - version "1.0.2" - resolved "https://registry.yarnpkg.com/bcrypt-pbkdf/-/bcrypt-pbkdf-1.0.2.tgz#a4301d389b6a43f9b67ff3ca11a3f6637e360e9e" - integrity sha1-pDAdOJtqQ/m2f/PKEaP2Y342Dp4= - dependencies: - tweetnacl "^0.14.3" - -big.js@^3.1.3: - version "3.2.0" - resolved "https://registry.yarnpkg.com/big.js/-/big.js-3.2.0.tgz#a5fc298b81b9e0dca2e458824784b65c52ba588e" - integrity sha512-+hN/Zh2D08Mx65pZ/4g5bsmNiZUuChDiQfTUQ7qJr4/kuopCr88xZsAXv6mBoZEsUI4OuGHlX59qE94K2mMW8Q== - -big.js@^5.2.2: - version "5.2.2" - resolved "https://registry.yarnpkg.com/big.js/-/big.js-5.2.2.tgz#65f0af382f578bcdc742bd9c281e9cb2d7768328" - integrity sha512-vyL2OymJxmarO8gxMr0mhChsO9QGwhynfuu4+MHTAW6czfq9humCB7rKpUjDd9YUiDPU4mzpyupFSvOClAwbmQ== - -binary-extensions@^1.0.0: - version "1.13.1" - resolved "https://registry.yarnpkg.com/binary-extensions/-/binary-extensions-1.13.1.tgz#598afe54755b2868a5330d2aff9d4ebb53209b65" - integrity sha512-Un7MIEDdUC5gNpcGDV97op1Ywk748MpHcFTHoYs6qnj1Z3j7I53VG3nwZhKzoBZmbdRNnb6WRdFlwl7tSDuZGw== - -bluebird@^3.1.1, bluebird@^3.5.5: - version "3.5.5" - resolved "https://registry.yarnpkg.com/bluebird/-/bluebird-3.5.5.tgz#a8d0afd73251effbbd5fe384a77d73003c17a71f" - integrity sha512-5am6HnnfN+urzt4yfg7IgTbotDjIT/u8AJpEt0sIU9FtXfVeezXAPKswrG+xKUCOYAINpSdgZVDU6QFh+cuH3w== - -bn.js@^4.0.0, bn.js@^4.1.0, bn.js@^4.1.1, bn.js@^4.4.0: - version "4.11.8" - resolved "https://registry.yarnpkg.com/bn.js/-/bn.js-4.11.8.tgz#2cde09eb5ee341f484746bb0309b3253b1b1442f" - integrity sha512-ItfYfPLkWHUjckQCk8xC+LwxgK8NYcXywGigJgSwOP8Y2iyWT4f2vsZnoOXTTbo+o5yXmIUJ4gn5538SO5S3gA== - -body-parser@1.19.0: - version "1.19.0" - resolved "https://registry.yarnpkg.com/body-parser/-/body-parser-1.19.0.tgz#96b2709e57c9c4e09a6fd66a8fd979844f69f08a" - integrity sha512-dhEPs72UPbDnAQJ9ZKMNTP6ptJaionhP5cBb541nXPlW60Jepo9RV/a4fX4XWW9CuFNK22krhrj1+rgzifNCsw== - dependencies: - bytes "3.1.0" - content-type "~1.0.4" - debug "2.6.9" - depd "~1.1.2" - http-errors "1.7.2" - iconv-lite "0.4.24" - on-finished "~2.3.0" - qs "6.7.0" - raw-body "2.4.0" - type-is "~1.6.17" - -bonjour@^3.5.0: - version "3.5.0" - resolved "https://registry.yarnpkg.com/bonjour/-/bonjour-3.5.0.tgz#8e890a183d8ee9a2393b3844c691a42bcf7bc9f5" - integrity sha1-jokKGD2O6aI5OzhExpGkK897yfU= - dependencies: - array-flatten "^2.1.0" - deep-equal "^1.0.1" - dns-equal "^1.0.0" - dns-txt "^2.0.2" - multicast-dns "^6.0.1" - multicast-dns-service-types "^1.1.0" - -boolbase@^1.0.0, boolbase@~1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/boolbase/-/boolbase-1.0.0.tgz#68dff5fbe60c51eb37725ea9e3ed310dcc1e776e" - integrity sha1-aN/1++YMUes3cl6p4+0xDcwed24= - -brace-expansion@^1.1.7: - version "1.1.11" - resolved "https://registry.yarnpkg.com/brace-expansion/-/brace-expansion-1.1.11.tgz#3c7fcbf529d87226f3d2f52b966ff5271eb441dd" - integrity sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA== - dependencies: - balanced-match "^1.0.0" - concat-map "0.0.1" - -braces@^2.3.1, braces@^2.3.2: - version "2.3.2" - resolved "https://registry.yarnpkg.com/braces/-/braces-2.3.2.tgz#5979fd3f14cd531565e5fa2df1abfff1dfaee729" - integrity sha512-aNdbnj9P8PjdXU4ybaWLK2IF3jc/EoDYbC7AazW6to3TRsfXxscC9UXOB5iDiEQrkyIbWp2SLQda4+QAa7nc3w== - dependencies: - arr-flatten "^1.1.0" - array-unique "^0.3.2" - extend-shallow "^2.0.1" - fill-range "^4.0.0" - isobject "^3.0.1" - repeat-element "^1.1.2" - snapdragon "^0.8.1" - snapdragon-node "^2.0.1" - split-string "^3.0.2" - to-regex "^3.0.1" - -brorand@^1.0.1: - version "1.1.0" - resolved "https://registry.yarnpkg.com/brorand/-/brorand-1.1.0.tgz#12c25efe40a45e3c323eb8675a0a0ce57b22371f" - integrity sha1-EsJe/kCkXjwyPrhnWgoM5XsiNx8= - -browserify-aes@^1.0.0, browserify-aes@^1.0.4: - version "1.2.0" - resolved "https://registry.yarnpkg.com/browserify-aes/-/browserify-aes-1.2.0.tgz#326734642f403dabc3003209853bb70ad428ef48" - integrity sha512-+7CHXqGuspUn/Sl5aO7Ea0xWGAtETPXNSAjHo48JfLdPWcMng33Xe4znFvQweqc/uzk5zSOI3H52CYnjCfb5hA== - dependencies: - buffer-xor "^1.0.3" - cipher-base "^1.0.0" - create-hash "^1.1.0" - evp_bytestokey "^1.0.3" - inherits "^2.0.1" - safe-buffer "^5.0.1" - -browserify-cipher@^1.0.0: - version "1.0.1" - resolved "https://registry.yarnpkg.com/browserify-cipher/-/browserify-cipher-1.0.1.tgz#8d6474c1b870bfdabcd3bcfcc1934a10e94f15f0" - integrity sha512-sPhkz0ARKbf4rRQt2hTpAHqn47X3llLkUGn+xEJzLjwY8LRs2p0v7ljvI5EyoRO/mexrNunNECisZs+gw2zz1w== - dependencies: - browserify-aes "^1.0.4" - browserify-des "^1.0.0" - evp_bytestokey "^1.0.0" - -browserify-des@^1.0.0: - version "1.0.2" - resolved "https://registry.yarnpkg.com/browserify-des/-/browserify-des-1.0.2.tgz#3af4f1f59839403572f1c66204375f7a7f703e9c" - integrity sha512-BioO1xf3hFwz4kc6iBhI3ieDFompMhrMlnDFC4/0/vd5MokpuAc3R+LYbwTA9A5Yc9pq9UYPqffKpW2ObuwX5A== - dependencies: - cipher-base "^1.0.1" - des.js "^1.0.0" - inherits "^2.0.1" - safe-buffer "^5.1.2" - -browserify-rsa@^4.0.0: - version "4.0.1" - resolved "https://registry.yarnpkg.com/browserify-rsa/-/browserify-rsa-4.0.1.tgz#21e0abfaf6f2029cf2fafb133567a701d4135524" - integrity sha1-IeCr+vbyApzy+vsTNWenAdQTVSQ= - dependencies: - bn.js "^4.1.0" - randombytes "^2.0.1" - -browserify-sign@^4.0.0: - version "4.0.4" - resolved "https://registry.yarnpkg.com/browserify-sign/-/browserify-sign-4.0.4.tgz#aa4eb68e5d7b658baa6bf6a57e630cbd7a93d298" - integrity sha1-qk62jl17ZYuqa/alfmMMvXqT0pg= - dependencies: - bn.js "^4.1.1" - browserify-rsa "^4.0.0" - create-hash "^1.1.0" - create-hmac "^1.1.2" - elliptic "^6.0.0" - inherits "^2.0.1" - parse-asn1 "^5.0.0" - -browserify-zlib@^0.2.0: - version "0.2.0" - resolved "https://registry.yarnpkg.com/browserify-zlib/-/browserify-zlib-0.2.0.tgz#2869459d9aa3be245fe8fe2ca1f46e2e7f54d73f" - integrity sha512-Z942RysHXmJrhqk88FmKBVq/v5tqmSkDz7p54G/MGyjMnCFFnC79XWNbg+Vta8W6Wb2qtSZTSxIGkJrRpCFEiA== - dependencies: - pako "~1.0.5" - -browserslist@^4.0.0, browserslist@^4.3.4, browserslist@^4.6.3: - version "4.6.6" - resolved "https://registry.yarnpkg.com/browserslist/-/browserslist-4.6.6.tgz#6e4bf467cde520bc9dbdf3747dafa03531cec453" - integrity sha512-D2Nk3W9JL9Fp/gIcWei8LrERCS+eXu9AM5cfXA8WEZ84lFks+ARnZ0q/R69m2SV3Wjma83QDDPxsNKXUwdIsyA== - dependencies: - caniuse-lite "^1.0.30000984" - electron-to-chromium "^1.3.191" - node-releases "^1.1.25" - -buffer-from@^1.0.0: - version "1.1.1" - resolved "https://registry.yarnpkg.com/buffer-from/-/buffer-from-1.1.1.tgz#32713bc028f75c02fdb710d7c7bcec1f2c6070ef" - integrity sha512-MQcXEUbCKtEo7bhqEs6560Hyd4XaovZlO/k9V3hjVUF/zwW7KBVdSK4gIt/bzwS9MbR5qob+F5jusZsb0YQK2A== - -buffer-indexof@^1.0.0: - version "1.1.1" - resolved "https://registry.yarnpkg.com/buffer-indexof/-/buffer-indexof-1.1.1.tgz#52fabcc6a606d1a00302802648ef68f639da268c" - integrity sha512-4/rOEg86jivtPTeOUUT61jJO1Ya1TrR/OkqCSZDyq84WJh3LuuiphBYJN+fm5xufIk4XAFcEwte/8WzC8If/1g== - -buffer-json@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/buffer-json/-/buffer-json-2.0.0.tgz#f73e13b1e42f196fe2fd67d001c7d7107edd7c23" - integrity sha512-+jjPFVqyfF1esi9fvfUs3NqM0pH1ziZ36VP4hmA/y/Ssfo/5w5xHKfTw9BwQjoJ1w/oVtpLomqwUHKdefGyuHw== - -buffer-xor@^1.0.3: - version "1.0.3" - resolved "https://registry.yarnpkg.com/buffer-xor/-/buffer-xor-1.0.3.tgz#26e61ed1422fb70dd42e6e36729ed51d855fe8d9" - integrity sha1-JuYe0UIvtw3ULm42cp7VHYVf6Nk= - -buffer@^4.3.0: - version "4.9.1" - resolved "https://registry.yarnpkg.com/buffer/-/buffer-4.9.1.tgz#6d1bb601b07a4efced97094132093027c95bc298" - integrity sha1-bRu2AbB6TvztlwlBMgkwJ8lbwpg= - dependencies: - base64-js "^1.0.2" - ieee754 "^1.1.4" - isarray "^1.0.0" - -builtin-status-codes@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/builtin-status-codes/-/builtin-status-codes-3.0.0.tgz#85982878e21b98e1c66425e03d0174788f569ee8" - integrity sha1-hZgoeOIbmOHGZCXgPQF0eI9Wnug= - -bytes@3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/bytes/-/bytes-3.0.0.tgz#d32815404d689699f85a4ea4fa8755dd13a96048" - integrity sha1-0ygVQE1olpn4Wk6k+odV3ROpYEg= - -bytes@3.1.0: - version "3.1.0" - resolved "https://registry.yarnpkg.com/bytes/-/bytes-3.1.0.tgz#f6cf7933a360e0588fa9fde85651cdc7f805d1f6" - integrity sha512-zauLjrfCG+xvoyaqLoV8bLVXXNGC4JqlxFCutSDWA6fJrTo2ZuvLYTqZ7aHBLZSMOopbzwv8f+wZcVzfVTI2Dg== - -cac@^6.3.9: - version "6.5.2" - resolved "https://registry.yarnpkg.com/cac/-/cac-6.5.2.tgz#92ef1490b9ffde5f0be7eeadec5ea926f0e78ef6" - integrity sha512-8JdiD9/ZLsG418j/chyZQ3VWuhFELSGlH4EUxzNKgIH8wK8dO0j5Pqu6Pk7B/RP3kX9aasyQhPrrUjYO5e0w7w== - -cacache@^11.3.2: - version "11.3.3" - resolved "https://registry.yarnpkg.com/cacache/-/cacache-11.3.3.tgz#8bd29df8c6a718a6ebd2d010da4d7972ae3bbadc" - integrity sha512-p8WcneCytvzPxhDvYp31PD039vi77I12W+/KfR9S8AZbaiARFBCpsPJS+9uhWfeBfeAtW7o/4vt3MUqLkbY6nA== - dependencies: - bluebird "^3.5.5" - chownr "^1.1.1" - figgy-pudding "^3.5.1" - glob "^7.1.4" - graceful-fs "^4.1.15" - lru-cache "^5.1.1" - mississippi "^3.0.0" - mkdirp "^0.5.1" - move-concurrently "^1.0.1" - promise-inflight "^1.0.1" - rimraf "^2.6.3" - ssri "^6.0.1" - unique-filename "^1.1.1" - y18n "^4.0.0" - -cache-base@^1.0.1: - version "1.0.1" - resolved "https://registry.yarnpkg.com/cache-base/-/cache-base-1.0.1.tgz#0a7f46416831c8b662ee36fe4e7c59d76f666ab2" - integrity sha512-AKcdTnFSWATd5/GCPRxr2ChwIJ85CeyrEyjRHlKxQ56d4XJMGym0uAiKn0xbLOGOl3+yRpOTi484dVCEc5AUzQ== - dependencies: - collection-visit "^1.0.0" - component-emitter "^1.2.1" - get-value "^2.0.6" - has-value "^1.0.0" - isobject "^3.0.1" - set-value "^2.0.0" - to-object-path "^0.3.0" - union-value "^1.0.0" - unset-value "^1.0.0" - -cache-loader@^3.0.0: - version "3.0.1" - resolved "https://registry.yarnpkg.com/cache-loader/-/cache-loader-3.0.1.tgz#cee6cf4b3cdc7c610905b26bad6c2fc439c821af" - integrity sha512-HzJIvGiGqYsFUrMjAJNDbVZoG7qQA+vy9AIoKs7s9DscNfki0I589mf2w6/tW+kkFH3zyiknoWV5Jdynu6b/zw== - dependencies: - buffer-json "^2.0.0" - find-cache-dir "^2.1.0" - loader-utils "^1.2.3" - mkdirp "^0.5.1" - neo-async "^2.6.1" - schema-utils "^1.0.0" - -call-me-maybe@^1.0.1: - version "1.0.1" - resolved "https://registry.yarnpkg.com/call-me-maybe/-/call-me-maybe-1.0.1.tgz#26d208ea89e37b5cbde60250a15f031c16a4d66b" - integrity sha1-JtII6onje1y95gJQoV8DHBak1ms= - -caller-callsite@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/caller-callsite/-/caller-callsite-2.0.0.tgz#847e0fce0a223750a9a027c54b33731ad3154134" - integrity sha1-hH4PzgoiN1CpoCfFSzNzGtMVQTQ= - dependencies: - callsites "^2.0.0" - -caller-path@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/caller-path/-/caller-path-2.0.0.tgz#468f83044e369ab2010fac5f06ceee15bb2cb1f4" - integrity sha1-Ro+DBE42mrIBD6xfBs7uFbsssfQ= - dependencies: - caller-callsite "^2.0.0" - -callsites@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/callsites/-/callsites-2.0.0.tgz#06eb84f00eea413da86affefacbffb36093b3c50" - integrity sha1-BuuE8A7qQT2oav/vrL/7Ngk7PFA= - -camel-case@3.0.x: - version "3.0.0" - resolved "https://registry.yarnpkg.com/camel-case/-/camel-case-3.0.0.tgz#ca3c3688a4e9cf3a4cda777dc4dcbc713249cf73" - integrity sha1-yjw2iKTpzzpM2nd9xNy8cTJJz3M= - dependencies: - no-case "^2.2.0" - upper-case "^1.1.1" - -camelcase@^5.0.0, camelcase@^5.2.0: - version "5.3.1" - resolved "https://registry.yarnpkg.com/camelcase/-/camelcase-5.3.1.tgz#e3c9b31569e106811df242f715725a1f4c494320" - integrity sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg== - -caniuse-api@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/caniuse-api/-/caniuse-api-3.0.0.tgz#5e4d90e2274961d46291997df599e3ed008ee4c0" - integrity sha512-bsTwuIg/BZZK/vreVTYYbSWoe2F+71P7K5QGEX+pT250DZbfU1MQ5prOKpPR+LL6uWKK3KMwMCAS74QB3Um1uw== - dependencies: - browserslist "^4.0.0" - caniuse-lite "^1.0.0" - lodash.memoize "^4.1.2" - lodash.uniq "^4.5.0" - -caniuse-lite@^1.0.0, caniuse-lite@^1.0.30000980, caniuse-lite@^1.0.30000984: - version "1.0.30000984" - resolved "https://registry.yarnpkg.com/caniuse-lite/-/caniuse-lite-1.0.30000984.tgz#dc96c3c469e9bcfc6ad5bdd24c77ec918ea76fe0" - integrity sha512-n5tKOjMaZ1fksIpQbjERuqCyfgec/m9pferkFQbLmWtqLUdmt12hNhjSwsmPdqeiG2NkITOQhr1VYIwWSAceiA== - -caseless@~0.12.0: - version "0.12.0" - resolved "https://registry.yarnpkg.com/caseless/-/caseless-0.12.0.tgz#1b681c21ff84033c826543090689420d187151dc" - integrity sha1-G2gcIf+EAzyCZUMJBolCDRhxUdw= - -chalk@^1.1.3: - version "1.1.3" - resolved "https://registry.yarnpkg.com/chalk/-/chalk-1.1.3.tgz#a8115c55e4a702fe4d150abd3872822a7e09fc98" - integrity sha1-qBFcVeSnAv5NFQq9OHKCKn4J/Jg= - dependencies: - ansi-styles "^2.2.1" - escape-string-regexp "^1.0.2" - has-ansi "^2.0.0" - strip-ansi "^3.0.0" - supports-color "^2.0.0" - -chalk@^2.0.0, chalk@^2.3.2, chalk@^2.4.1, chalk@^2.4.2: - version "2.4.2" - resolved "https://registry.yarnpkg.com/chalk/-/chalk-2.4.2.tgz#cd42541677a54333cf541a49108c1432b44c9424" - integrity sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ== - dependencies: - ansi-styles "^3.2.1" - escape-string-regexp "^1.0.5" - supports-color "^5.3.0" - -chokidar@^2.0.2, chokidar@^2.0.3, chokidar@^2.1.6: - version "2.1.6" - resolved "https://registry.yarnpkg.com/chokidar/-/chokidar-2.1.6.tgz#b6cad653a929e244ce8a834244164d241fa954c5" - integrity sha512-V2jUo67OKkc6ySiRpJrjlpJKl9kDuG+Xb8VgsGzb+aEouhgS1D0weyPU4lEzdAcsCAvrih2J2BqyXqHWvVLw5g== - dependencies: - anymatch "^2.0.0" - async-each "^1.0.1" - braces "^2.3.2" - glob-parent "^3.1.0" - inherits "^2.0.3" - is-binary-path "^1.0.0" - is-glob "^4.0.0" - normalize-path "^3.0.0" - path-is-absolute "^1.0.0" - readdirp "^2.2.1" - upath "^1.1.1" - optionalDependencies: - fsevents "^1.2.7" - -chownr@^1.1.1: - version "1.1.2" - resolved "https://registry.yarnpkg.com/chownr/-/chownr-1.1.2.tgz#a18f1e0b269c8a6a5d3c86eb298beb14c3dd7bf6" - integrity sha512-GkfeAQh+QNy3wquu9oIZr6SS5x7wGdSgNQvD10X3r+AZr1Oys22HW8kAmDMvNg2+Dm0TeGaEuO8gFwdBXxwO8A== - -chrome-trace-event@^1.0.0: - version "1.0.2" - resolved "https://registry.yarnpkg.com/chrome-trace-event/-/chrome-trace-event-1.0.2.tgz#234090ee97c7d4ad1a2c4beae27505deffc608a4" - integrity sha512-9e/zx1jw7B4CO+c/RXoCsfg/x1AfUBioy4owYH0bJprEYAx5hRFLRhWBqHAG57D0ZM4H7vxbP7bPe0VwhQRYDQ== - dependencies: - tslib "^1.9.0" - -ci-info@^1.6.0: - version "1.6.0" - resolved "https://registry.yarnpkg.com/ci-info/-/ci-info-1.6.0.tgz#2ca20dbb9ceb32d4524a683303313f0304b1e497" - integrity sha512-vsGdkwSCDpWmP80ncATX7iea5DWQemg1UgCW5J8tqjU3lYw4FBYuj89J0CTVomA7BEfvSZd84GmHko+MxFQU2A== - -cipher-base@^1.0.0, cipher-base@^1.0.1, cipher-base@^1.0.3: - version "1.0.4" - resolved "https://registry.yarnpkg.com/cipher-base/-/cipher-base-1.0.4.tgz#8760e4ecc272f4c363532f926d874aae2c1397de" - integrity sha512-Kkht5ye6ZGmwv40uUDZztayT2ThLQGfnj/T71N/XzeZeo3nf8foyW7zGTsPYkEya3m5f3cAypH+qe7YOrM1U2Q== - dependencies: - inherits "^2.0.1" - safe-buffer "^5.0.1" - -class-utils@^0.3.5: - version "0.3.6" - resolved "https://registry.yarnpkg.com/class-utils/-/class-utils-0.3.6.tgz#f93369ae8b9a7ce02fd41faad0ca83033190c463" - integrity sha512-qOhPa/Fj7s6TY8H8esGu5QNpMMQxz79h+urzrNYN6mn+9BnxlDGf5QZ+XeCDsxSjPqsSR56XOZOJmpeurnLMeg== - dependencies: - arr-union "^3.1.0" - define-property "^0.2.5" - isobject "^3.0.0" - static-extend "^0.1.1" - -clean-css@4.2.x: - version "4.2.1" - resolved "https://registry.yarnpkg.com/clean-css/-/clean-css-4.2.1.tgz#2d411ef76b8569b6d0c84068dabe85b0aa5e5c17" - integrity sha512-4ZxI6dy4lrY6FHzfiy1aEOXgu4LIsW2MhwG0VBKdcoGoH/XLFgaHSdLTGr4O8Be6A8r3MOphEiI8Gc1n0ecf3g== - dependencies: - source-map "~0.6.0" - -clipboard@^2.0.0: - version "2.0.4" - resolved "https://registry.yarnpkg.com/clipboard/-/clipboard-2.0.4.tgz#836dafd66cf0fea5d71ce5d5b0bf6e958009112d" - integrity sha512-Vw26VSLRpJfBofiVaFb/I8PVfdI1OxKcYShe6fm0sP/DtmiWQNCjhM/okTvdCo0G+lMMm1rMYbk4IK4x1X+kgQ== - dependencies: - good-listener "^1.2.2" - select "^1.1.2" - tiny-emitter "^2.0.0" - -cliui@^4.0.0: - version "4.1.0" - resolved "https://registry.yarnpkg.com/cliui/-/cliui-4.1.0.tgz#348422dbe82d800b3022eef4f6ac10bf2e4d1b49" - integrity sha512-4FG+RSG9DL7uEwRUZXZn3SS34DiDPfzP0VOiEwtUWlE+AR2EIg+hSyvrIgUUfhdgR/UkAeW2QHgeP+hWrXs7jQ== - dependencies: - string-width "^2.1.1" - strip-ansi "^4.0.0" - wrap-ansi "^2.0.0" - -coa@^2.0.2: - version "2.0.2" - resolved "https://registry.yarnpkg.com/coa/-/coa-2.0.2.tgz#43f6c21151b4ef2bf57187db0d73de229e3e7ec3" - integrity sha512-q5/jG+YQnSy4nRTV4F7lPepBJZ8qBNJJDBuJdoejDyLXgmL7IEo+Le2JDZudFTFt7mrCqIRaSjws4ygRCTCAXA== - dependencies: - "@types/q" "^1.5.1" - chalk "^2.4.1" - q "^1.1.2" - -code-point-at@^1.0.0: - version "1.1.0" - resolved "https://registry.yarnpkg.com/code-point-at/-/code-point-at-1.1.0.tgz#0d070b4d043a5bea33a2f1a40e2edb3d9a4ccf77" - integrity sha1-DQcLTQQ6W+ozovGkDi7bPZpMz3c= - -collection-visit@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/collection-visit/-/collection-visit-1.0.0.tgz#4bc0373c164bc3291b4d368c829cf1a80a59dca0" - integrity sha1-S8A3PBZLwykbTTaMgpzxqApZ3KA= - dependencies: - map-visit "^1.0.0" - object-visit "^1.0.0" - -color-convert@^1.9.0, color-convert@^1.9.1: - version "1.9.3" - resolved "https://registry.yarnpkg.com/color-convert/-/color-convert-1.9.3.tgz#bb71850690e1f136567de629d2d5471deda4c1e8" - integrity sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg== - dependencies: - color-name "1.1.3" - -color-name@1.1.3: - version "1.1.3" - resolved "https://registry.yarnpkg.com/color-name/-/color-name-1.1.3.tgz#a7d0558bd89c42f795dd42328f740831ca53bc25" - integrity sha1-p9BVi9icQveV3UIyj3QIMcpTvCU= - -color-name@^1.0.0: - version "1.1.4" - resolved "https://registry.yarnpkg.com/color-name/-/color-name-1.1.4.tgz#c2a09a87acbde69543de6f63fa3995c826c536a2" - integrity sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA== - -color-string@^1.5.2: - version "1.5.3" - resolved "https://registry.yarnpkg.com/color-string/-/color-string-1.5.3.tgz#c9bbc5f01b58b5492f3d6857459cb6590ce204cc" - integrity sha512-dC2C5qeWoYkxki5UAXapdjqO672AM4vZuPGRQfO8b5HKuKGBbKWpITyDYN7TOFKvRW7kOgAn3746clDBMDJyQw== - dependencies: - color-name "^1.0.0" - simple-swizzle "^0.2.2" - -color@^3.0.0: - version "3.1.2" - resolved "https://registry.yarnpkg.com/color/-/color-3.1.2.tgz#68148e7f85d41ad7649c5fa8c8106f098d229e10" - integrity sha512-vXTJhHebByxZn3lDvDJYw4lR5+uB3vuoHsuYA5AKuxRVn5wzzIfQKGLBmgdVRHKTJYeK5rvJcHnrd0Li49CFpg== - dependencies: - color-convert "^1.9.1" - color-string "^1.5.2" - -combined-stream@^1.0.6, combined-stream@~1.0.6: - version "1.0.8" - resolved "https://registry.yarnpkg.com/combined-stream/-/combined-stream-1.0.8.tgz#c3d45a8b34fd730631a110a8a2520682b31d5a7f" - integrity sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg== - dependencies: - delayed-stream "~1.0.0" - -commander@2.17.x: - version "2.17.1" - resolved "https://registry.yarnpkg.com/commander/-/commander-2.17.1.tgz#bd77ab7de6de94205ceacc72f1716d29f20a77bf" - integrity sha512-wPMUt6FnH2yzG95SA6mzjQOEKUU3aLaDEmzs1ti+1E9h+CsrZghRlqEM/EJ4KscsQVG8uNN4uVreUeT8+drlgg== - -commander@^2.20.0: - version "2.20.0" - resolved "https://registry.yarnpkg.com/commander/-/commander-2.20.0.tgz#d58bb2b5c1ee8f87b0d340027e9e94e222c5a422" - integrity sha512-7j2y+40w61zy6YC2iRNpUe/NwhNyoXrYpHMrSunaMG64nRnaf96zO/KMQR4OyN/UnE5KLyEBnKHd4aG3rskjpQ== - -commander@~2.19.0: - version "2.19.0" - resolved "https://registry.yarnpkg.com/commander/-/commander-2.19.0.tgz#f6198aa84e5b83c46054b94ddedbfed5ee9ff12a" - integrity sha512-6tvAOO+D6OENvRAh524Dh9jcfKTYDQAqvqezbCW82xj5X0pSrcpxtvRKHLG0yBY6SD7PSDrJaj+0AiOcKVd1Xg== - -commondir@^1.0.1: - version "1.0.1" - resolved "https://registry.yarnpkg.com/commondir/-/commondir-1.0.1.tgz#ddd800da0c66127393cca5950ea968a3aaf1253b" - integrity sha1-3dgA2gxmEnOTzKWVDqloo6rxJTs= - -component-emitter@^1.2.1: - version "1.3.0" - resolved "https://registry.yarnpkg.com/component-emitter/-/component-emitter-1.3.0.tgz#16e4070fba8ae29b679f2215853ee181ab2eabc0" - integrity sha512-Rd3se6QB+sO1TwqZjscQrurpEPIfO0/yYnSin6Q/rD3mOutHvUrCAhJub3r90uNb+SESBuE0QYoB90YdfatsRg== - -compressible@~2.0.16: - version "2.0.17" - resolved "https://registry.yarnpkg.com/compressible/-/compressible-2.0.17.tgz#6e8c108a16ad58384a977f3a482ca20bff2f38c1" - integrity sha512-BGHeLCK1GV7j1bSmQQAi26X+GgWcTjLr/0tzSvMCl3LH1w1IJ4PFSPoV5316b30cneTziC+B1a+3OjoSUcQYmw== - dependencies: - mime-db ">= 1.40.0 < 2" - -compression@^1.7.4: - version "1.7.4" - resolved "https://registry.yarnpkg.com/compression/-/compression-1.7.4.tgz#95523eff170ca57c29a0ca41e6fe131f41e5bb8f" - integrity sha512-jaSIDzP9pZVS4ZfQ+TzvtiWhdpFhE2RDHz8QJkpX9SIpLq88VueF5jJw6t+6CUQcAoA6t+x89MLrWAqpfDE8iQ== - dependencies: - accepts "~1.3.5" - bytes "3.0.0" - compressible "~2.0.16" - debug "2.6.9" - on-headers "~1.0.2" - safe-buffer "5.1.2" - vary "~1.1.2" - -concat-map@0.0.1: - version "0.0.1" - resolved "https://registry.yarnpkg.com/concat-map/-/concat-map-0.0.1.tgz#d8a96bd77fd68df7793a73036a3ba0d5405d477b" - integrity sha1-2Klr13/Wjfd5OnMDajug1UBdR3s= - -concat-stream@^1.5.0: - version "1.6.2" - resolved "https://registry.yarnpkg.com/concat-stream/-/concat-stream-1.6.2.tgz#904bdf194cd3122fc675c77fc4ac3d4ff0fd1a34" - integrity sha512-27HBghJxjiZtIk3Ycvn/4kbJk/1uZuJFfuPEns6LaEvpvG1f0hTea8lilrouyo9mVc2GWdcEZ8OLoGmSADlrCw== - dependencies: - buffer-from "^1.0.0" - inherits "^2.0.3" - readable-stream "^2.2.2" - typedarray "^0.0.6" - -connect-history-api-fallback@^1.5.0, connect-history-api-fallback@^1.6.0: - version "1.6.0" - resolved "https://registry.yarnpkg.com/connect-history-api-fallback/-/connect-history-api-fallback-1.6.0.tgz#8b32089359308d111115d81cad3fceab888f97bc" - integrity sha512-e54B99q/OUoH64zYYRf3HBP5z24G38h5D3qXu23JGRoigpX5Ss4r9ZnDk3g0Z8uQC2x2lPaJ+UlWBc1ZWBWdLg== - -consola@^2.6.0: - version "2.9.0" - resolved "https://registry.yarnpkg.com/consola/-/consola-2.9.0.tgz#57760e3a65a53ec27337f4add31505802d902278" - integrity sha512-34Iue+LRcWbndFIfZc5boNizWlsrRjqIBJZTe591vImgbnq7nx2EzlrLtANj9TH2Fxm7puFJBJAOk5BhvZOddQ== - -console-browserify@^1.1.0: - version "1.1.0" - resolved "https://registry.yarnpkg.com/console-browserify/-/console-browserify-1.1.0.tgz#f0241c45730a9fc6323b206dbf38edc741d0bb10" - integrity sha1-8CQcRXMKn8YyOyBtvzjtx0HQuxA= - dependencies: - date-now "^0.1.4" - -console-control-strings@^1.0.0, console-control-strings@~1.1.0: - version "1.1.0" - resolved "https://registry.yarnpkg.com/console-control-strings/-/console-control-strings-1.1.0.tgz#3d7cf4464db6446ea644bf4b39507f9851008e8e" - integrity sha1-PXz0Rk22RG6mRL9LOVB/mFEAjo4= - -consolidate@^0.15.1: - version "0.15.1" - resolved "https://registry.yarnpkg.com/consolidate/-/consolidate-0.15.1.tgz#21ab043235c71a07d45d9aad98593b0dba56bab7" - integrity sha512-DW46nrsMJgy9kqAbPt5rKaCr7uFtpo4mSUvLHIUbJEjm0vo+aY5QLwBUq3FK4tRnJr/X0Psc0C4jf/h+HtXSMw== - dependencies: - bluebird "^3.1.1" - -constants-browserify@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/constants-browserify/-/constants-browserify-1.0.0.tgz#c20b96d8c617748aaf1c16021760cd27fcb8cb75" - integrity sha1-wguW2MYXdIqvHBYCF2DNJ/y4y3U= - -content-disposition@0.5.3: - version "0.5.3" - resolved "https://registry.yarnpkg.com/content-disposition/-/content-disposition-0.5.3.tgz#e130caf7e7279087c5616c2007d0485698984fbd" - integrity sha512-ExO0774ikEObIAEV9kDo50o+79VCUdEB6n6lzKgGwupcVeRlhrj3qGAfwq8G6uBJjkqLrhT0qEYFcWng8z1z0g== - dependencies: - safe-buffer "5.1.2" - -content-type@~1.0.4: - version "1.0.4" - resolved "https://registry.yarnpkg.com/content-type/-/content-type-1.0.4.tgz#e138cc75e040c727b1966fe5e5f8c9aee256fe3b" - integrity sha512-hIP3EEPs8tB9AT1L+NUqtwOAps4mk2Zob89MWXMHjHWg9milF/j4osnnQLXBCBFBk/tvIG/tUc9mOUJiPBhPXA== - -convert-source-map@^1.1.0: - version "1.6.0" - resolved "https://registry.yarnpkg.com/convert-source-map/-/convert-source-map-1.6.0.tgz#51b537a8c43e0f04dec1993bffcdd504e758ac20" - integrity sha512-eFu7XigvxdZ1ETfbgPBohgyQ/Z++C0eEhTor0qRwBw9unw+L0/6V8wkSuGgzdThkiS5lSpdptOQPD8Ak40a+7A== - dependencies: - safe-buffer "~5.1.1" - -cookie-signature@1.0.6: - version "1.0.6" - resolved "https://registry.yarnpkg.com/cookie-signature/-/cookie-signature-1.0.6.tgz#e303a882b342cc3ee8ca513a79999734dab3ae2c" - integrity sha1-4wOogrNCzD7oylE6eZmXNNqzriw= - -cookie@0.4.0: - version "0.4.0" - resolved "https://registry.yarnpkg.com/cookie/-/cookie-0.4.0.tgz#beb437e7022b3b6d49019d088665303ebe9c14ba" - integrity sha512-+Hp8fLp57wnUSt0tY0tHEXh4voZRDnoIrZPqlo3DPiI4y9lwg/jqx+1Om94/W6ZaPDOUbnjOt/99w66zk+l1Xg== - -copy-concurrently@^1.0.0: - version "1.0.5" - resolved "https://registry.yarnpkg.com/copy-concurrently/-/copy-concurrently-1.0.5.tgz#92297398cae34937fcafd6ec8139c18051f0b5e0" - integrity sha512-f2domd9fsVDFtaFcbaRZuYXwtdmnzqbADSwhSWYxYB/Q8zsdUUFMXVRwXGDMWmbEzAn1kdRrtI1T/KTFOL4X2A== - dependencies: - aproba "^1.1.1" - fs-write-stream-atomic "^1.0.8" - iferr "^0.1.5" - mkdirp "^0.5.1" - rimraf "^2.5.4" - run-queue "^1.0.0" - -copy-descriptor@^0.1.0: - version "0.1.1" - resolved "https://registry.yarnpkg.com/copy-descriptor/-/copy-descriptor-0.1.1.tgz#676f6eb3c39997c2ee1ac3a924fd6124748f578d" - integrity sha1-Z29us8OZl8LuGsOpJP1hJHSPV40= - -copy-webpack-plugin@^5.0.2: - version "5.0.3" - resolved "https://registry.yarnpkg.com/copy-webpack-plugin/-/copy-webpack-plugin-5.0.3.tgz#2179e3c8fd69f13afe74da338896f1f01a875b5c" - integrity sha512-PlZRs9CUMnAVylZq+vg2Juew662jWtwOXOqH4lbQD9ZFhRG9R7tVStOgHt21CBGVq7k5yIJaz8TXDLSjV+Lj8Q== - dependencies: - cacache "^11.3.2" - find-cache-dir "^2.1.0" - glob-parent "^3.1.0" - globby "^7.1.1" - is-glob "^4.0.1" - loader-utils "^1.2.3" - minimatch "^3.0.4" - normalize-path "^3.0.0" - p-limit "^2.2.0" - schema-utils "^1.0.0" - serialize-javascript "^1.7.0" - webpack-log "^2.0.0" - -core-js@^2.6.5: - version "2.6.9" - resolved "https://registry.yarnpkg.com/core-js/-/core-js-2.6.9.tgz#6b4b214620c834152e179323727fc19741b084f2" - integrity sha512-HOpZf6eXmnl7la+cUdMnLvUxKNqLUzJvgIziQ0DiF3JwSImNphIqdGqzj6hIKyX04MmV0poclQ7+wjWvxQyR2A== - -core-util-is@1.0.2, core-util-is@~1.0.0: - version "1.0.2" - resolved "https://registry.yarnpkg.com/core-util-is/-/core-util-is-1.0.2.tgz#b5fd54220aa2bc5ab57aab7140c940754503c1a7" - integrity sha1-tf1UIgqivFq1eqtxQMlAdUUDwac= - -cosmiconfig@^5.0.0: - version "5.2.1" - resolved "https://registry.yarnpkg.com/cosmiconfig/-/cosmiconfig-5.2.1.tgz#040f726809c591e77a17c0a3626ca45b4f168b1a" - integrity sha512-H65gsXo1SKjf8zmrJ67eJk8aIRKV5ff2D4uKZIBZShbhGSpEmsQOPW/SKMKYhSTrqR7ufy6RP69rPogdaPh/kA== - dependencies: - import-fresh "^2.0.0" - is-directory "^0.3.1" - js-yaml "^3.13.1" - parse-json "^4.0.0" - -create-ecdh@^4.0.0: - version "4.0.3" - resolved "https://registry.yarnpkg.com/create-ecdh/-/create-ecdh-4.0.3.tgz#c9111b6f33045c4697f144787f9254cdc77c45ff" - integrity sha512-GbEHQPMOswGpKXM9kCWVrremUcBmjteUaQ01T9rkKCPDXfUHX0IoP9LpHYo2NPFampa4e+/pFDc3jQdxrxQLaw== - dependencies: - bn.js "^4.1.0" - elliptic "^6.0.0" - -create-hash@^1.1.0, create-hash@^1.1.2: - version "1.2.0" - resolved "https://registry.yarnpkg.com/create-hash/-/create-hash-1.2.0.tgz#889078af11a63756bcfb59bd221996be3a9ef196" - integrity sha512-z00bCGNHDG8mHAkP7CtT1qVu+bFQUPjYq/4Iv3C3kWjTFV10zIjfSoeqXo9Asws8gwSHDGj/hl2u4OGIjapeCg== - dependencies: - cipher-base "^1.0.1" - inherits "^2.0.1" - md5.js "^1.3.4" - ripemd160 "^2.0.1" - sha.js "^2.4.0" - -create-hmac@^1.1.0, create-hmac@^1.1.2, create-hmac@^1.1.4: - version "1.1.7" - resolved "https://registry.yarnpkg.com/create-hmac/-/create-hmac-1.1.7.tgz#69170c78b3ab957147b2b8b04572e47ead2243ff" - integrity sha512-MJG9liiZ+ogc4TzUwuvbER1JRdgvUFSB5+VR/g5h82fGaIRWMWddtKBHi7/sVhfjQZ6SehlyhvQYrcYkaUIpLg== - dependencies: - cipher-base "^1.0.3" - create-hash "^1.1.0" - inherits "^2.0.1" - ripemd160 "^2.0.0" - safe-buffer "^5.0.1" - sha.js "^2.4.8" - -cross-spawn@^6.0.0, cross-spawn@^6.0.5: - version "6.0.5" - resolved "https://registry.yarnpkg.com/cross-spawn/-/cross-spawn-6.0.5.tgz#4a5ec7c64dfae22c3a14124dbacdee846d80cbc4" - integrity sha512-eTVLrBSt7fjbDygz805pMnstIs2VTBNkRm0qxZd+M7A5XDdxVRWO5MxGBXZhjY4cqLYLdtrGqRf8mBPmzwSpWQ== - dependencies: - nice-try "^1.0.4" - path-key "^2.0.1" - semver "^5.5.0" - shebang-command "^1.2.0" - which "^1.2.9" - -crypto-browserify@^3.11.0: - version "3.12.0" - resolved "https://registry.yarnpkg.com/crypto-browserify/-/crypto-browserify-3.12.0.tgz#396cf9f3137f03e4b8e532c58f698254e00f80ec" - integrity sha512-fz4spIh+znjO2VjL+IdhEpRJ3YN6sMzITSBijk6FK2UvTqruSQW+/cCZTSNsMiZNvUeq0CqurF+dAbyiGOY6Wg== - dependencies: - browserify-cipher "^1.0.0" - browserify-sign "^4.0.0" - create-ecdh "^4.0.0" - create-hash "^1.1.0" - create-hmac "^1.1.0" - diffie-hellman "^5.0.0" - inherits "^2.0.1" - pbkdf2 "^3.0.3" - public-encrypt "^4.0.0" - randombytes "^2.0.0" - randomfill "^1.0.3" - -css-color-names@0.0.4, css-color-names@^0.0.4: - version "0.0.4" - resolved "https://registry.yarnpkg.com/css-color-names/-/css-color-names-0.0.4.tgz#808adc2e79cf84738069b646cb20ec27beb629e0" - integrity sha1-gIrcLnnPhHOAabZGyyDsJ762KeA= - -css-declaration-sorter@^4.0.1: - version "4.0.1" - resolved "https://registry.yarnpkg.com/css-declaration-sorter/-/css-declaration-sorter-4.0.1.tgz#c198940f63a76d7e36c1e71018b001721054cb22" - integrity sha512-BcxQSKTSEEQUftYpBVnsH4SF05NTuBokb19/sBt6asXGKZ/6VP7PLG1CBCkFDYOnhXhPh0jMhO6xZ71oYHXHBA== - dependencies: - postcss "^7.0.1" - timsort "^0.3.0" - -css-loader@^2.1.1: - version "2.1.1" - resolved "https://registry.yarnpkg.com/css-loader/-/css-loader-2.1.1.tgz#d8254f72e412bb2238bb44dd674ffbef497333ea" - integrity sha512-OcKJU/lt232vl1P9EEDamhoO9iKY3tIjY5GU+XDLblAykTdgs6Ux9P1hTHve8nFKy5KPpOXOsVI/hIwi3841+w== - dependencies: - camelcase "^5.2.0" - icss-utils "^4.1.0" - loader-utils "^1.2.3" - normalize-path "^3.0.0" - postcss "^7.0.14" - postcss-modules-extract-imports "^2.0.0" - postcss-modules-local-by-default "^2.0.6" - postcss-modules-scope "^2.1.0" - postcss-modules-values "^2.0.0" - postcss-value-parser "^3.3.0" - schema-utils "^1.0.0" - -css-parse@1.7.x: - version "1.7.0" - resolved "https://registry.yarnpkg.com/css-parse/-/css-parse-1.7.0.tgz#321f6cf73782a6ff751111390fc05e2c657d8c9b" - integrity sha1-Mh9s9zeCpv91ERE5D8BeLGV9jJs= - -css-select-base-adapter@^0.1.1: - version "0.1.1" - resolved "https://registry.yarnpkg.com/css-select-base-adapter/-/css-select-base-adapter-0.1.1.tgz#3b2ff4972cc362ab88561507a95408a1432135d7" - integrity sha512-jQVeeRG70QI08vSTwf1jHxp74JoZsr2XSgETae8/xC8ovSnL2WF87GTLO86Sbwdt2lK4Umg4HnnwMO4YF3Ce7w== - -css-select@^1.1.0: - version "1.2.0" - resolved "https://registry.yarnpkg.com/css-select/-/css-select-1.2.0.tgz#2b3a110539c5355f1cd8d314623e870b121ec858" - integrity sha1-KzoRBTnFNV8c2NMUYj6HCxIeyFg= - dependencies: - boolbase "~1.0.0" - css-what "2.1" - domutils "1.5.1" - nth-check "~1.0.1" - -css-select@^2.0.0: - version "2.0.2" - resolved "https://registry.yarnpkg.com/css-select/-/css-select-2.0.2.tgz#ab4386cec9e1f668855564b17c3733b43b2a5ede" - integrity sha512-dSpYaDVoWaELjvZ3mS6IKZM/y2PMPa/XYoEfYNZePL4U/XgyxZNroHEHReDx/d+VgXh9VbCTtFqLkFbmeqeaRQ== - dependencies: - boolbase "^1.0.0" - css-what "^2.1.2" - domutils "^1.7.0" - nth-check "^1.0.2" - -css-tree@1.0.0-alpha.29: - version "1.0.0-alpha.29" - resolved "https://registry.yarnpkg.com/css-tree/-/css-tree-1.0.0-alpha.29.tgz#3fa9d4ef3142cbd1c301e7664c1f352bd82f5a39" - integrity sha512-sRNb1XydwkW9IOci6iB2xmy8IGCj6r/fr+JWitvJ2JxQRPzN3T4AGGVWCMlVmVwM1gtgALJRmGIlWv5ppnGGkg== - dependencies: - mdn-data "~1.1.0" - source-map "^0.5.3" - -css-tree@1.0.0-alpha.33: - version "1.0.0-alpha.33" - resolved "https://registry.yarnpkg.com/css-tree/-/css-tree-1.0.0-alpha.33.tgz#970e20e5a91f7a378ddd0fc58d0b6c8d4f3be93e" - integrity sha512-SPt57bh5nQnpsTBsx/IXbO14sRc9xXu5MtMAVuo0BaQQmyf0NupNPPSoMaqiAF5tDFafYsTkfeH4Q/HCKXkg4w== - dependencies: - mdn-data "2.0.4" - source-map "^0.5.3" - -css-unit-converter@^1.1.1: - version "1.1.1" - resolved "https://registry.yarnpkg.com/css-unit-converter/-/css-unit-converter-1.1.1.tgz#d9b9281adcfd8ced935bdbaba83786897f64e996" - integrity sha1-2bkoGtz9jO2TW9urqDeGiX9k6ZY= - -css-what@2.1, css-what@^2.1.2: - version "2.1.3" - resolved "https://registry.yarnpkg.com/css-what/-/css-what-2.1.3.tgz#a6d7604573365fe74686c3f311c56513d88285f2" - integrity sha512-a+EPoD+uZiNfh+5fxw2nO9QwFa6nJe2Or35fGY6Ipw1R3R4AGz1d1TEZrCegvw2YTmZ0jXirGYlzxxpYSHwpEg== - -cssesc@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/cssesc/-/cssesc-2.0.0.tgz#3b13bd1bb1cb36e1bcb5a4dcd27f54c5dcb35703" - integrity sha512-MsCAG1z9lPdoO/IUMLSBWBSVxVtJ1395VGIQ+Fc2gNdkQ1hNDnQdw3YhA71WJCBW1vdwA0cAnk/DnW6bqoEUYg== - -cssesc@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/cssesc/-/cssesc-3.0.0.tgz#37741919903b868565e1c09ea747445cd18983ee" - integrity sha512-/Tb/JcjK111nNScGob5MNtsntNM1aCNUDipB/TkwZFhyDrrE47SOx/18wF2bbjgc3ZzCSKW1T5nt5EbFoAz/Vg== - -cssnano-preset-default@^4.0.7: - version "4.0.7" - resolved "https://registry.yarnpkg.com/cssnano-preset-default/-/cssnano-preset-default-4.0.7.tgz#51ec662ccfca0f88b396dcd9679cdb931be17f76" - integrity sha512-x0YHHx2h6p0fCl1zY9L9roD7rnlltugGu7zXSKQx6k2rYw0Hi3IqxcoAGF7u9Q5w1nt7vK0ulxV8Lo+EvllGsA== - dependencies: - css-declaration-sorter "^4.0.1" - cssnano-util-raw-cache "^4.0.1" - postcss "^7.0.0" - postcss-calc "^7.0.1" - postcss-colormin "^4.0.3" - postcss-convert-values "^4.0.1" - postcss-discard-comments "^4.0.2" - postcss-discard-duplicates "^4.0.2" - postcss-discard-empty "^4.0.1" - postcss-discard-overridden "^4.0.1" - postcss-merge-longhand "^4.0.11" - postcss-merge-rules "^4.0.3" - postcss-minify-font-values "^4.0.2" - postcss-minify-gradients "^4.0.2" - postcss-minify-params "^4.0.2" - postcss-minify-selectors "^4.0.2" - postcss-normalize-charset "^4.0.1" - postcss-normalize-display-values "^4.0.2" - postcss-normalize-positions "^4.0.2" - postcss-normalize-repeat-style "^4.0.2" - postcss-normalize-string "^4.0.2" - postcss-normalize-timing-functions "^4.0.2" - postcss-normalize-unicode "^4.0.1" - postcss-normalize-url "^4.0.1" - postcss-normalize-whitespace "^4.0.2" - postcss-ordered-values "^4.1.2" - postcss-reduce-initial "^4.0.3" - postcss-reduce-transforms "^4.0.2" - postcss-svgo "^4.0.2" - postcss-unique-selectors "^4.0.1" - -cssnano-util-get-arguments@^4.0.0: - version "4.0.0" - resolved "https://registry.yarnpkg.com/cssnano-util-get-arguments/-/cssnano-util-get-arguments-4.0.0.tgz#ed3a08299f21d75741b20f3b81f194ed49cc150f" - integrity sha1-7ToIKZ8h11dBsg87gfGU7UnMFQ8= - -cssnano-util-get-match@^4.0.0: - version "4.0.0" - resolved "https://registry.yarnpkg.com/cssnano-util-get-match/-/cssnano-util-get-match-4.0.0.tgz#c0e4ca07f5386bb17ec5e52250b4f5961365156d" - integrity sha1-wOTKB/U4a7F+xeUiULT1lhNlFW0= - -cssnano-util-raw-cache@^4.0.1: - version "4.0.1" - resolved "https://registry.yarnpkg.com/cssnano-util-raw-cache/-/cssnano-util-raw-cache-4.0.1.tgz#b26d5fd5f72a11dfe7a7846fb4c67260f96bf282" - integrity sha512-qLuYtWK2b2Dy55I8ZX3ky1Z16WYsx544Q0UWViebptpwn/xDBmog2TLg4f+DBMg1rJ6JDWtn96WHbOKDWt1WQA== - dependencies: - postcss "^7.0.0" - -cssnano-util-same-parent@^4.0.0: - version "4.0.1" - resolved "https://registry.yarnpkg.com/cssnano-util-same-parent/-/cssnano-util-same-parent-4.0.1.tgz#574082fb2859d2db433855835d9a8456ea18bbf3" - integrity sha512-WcKx5OY+KoSIAxBW6UBBRay1U6vkYheCdjyVNDm85zt5K9mHoGOfsOsqIszfAqrQQFIIKgjh2+FDgIj/zsl21Q== - -cssnano@^4.1.10: - version "4.1.10" - resolved "https://registry.yarnpkg.com/cssnano/-/cssnano-4.1.10.tgz#0ac41f0b13d13d465487e111b778d42da631b8b2" - integrity sha512-5wny+F6H4/8RgNlaqab4ktc3e0/blKutmq8yNlBFXA//nSFFAqAngjNVRzUvCgYROULmZZUoosL/KSoZo5aUaQ== - dependencies: - cosmiconfig "^5.0.0" - cssnano-preset-default "^4.0.7" - is-resolvable "^1.0.0" - postcss "^7.0.0" - -csso@^3.5.1: - version "3.5.1" - resolved "https://registry.yarnpkg.com/csso/-/csso-3.5.1.tgz#7b9eb8be61628973c1b261e169d2f024008e758b" - integrity sha512-vrqULLffYU1Q2tLdJvaCYbONStnfkfimRxXNaGjxMldI0C7JPBC4rB1RyjhfdZ4m1frm8pM9uRPKH3d2knZ8gg== - dependencies: - css-tree "1.0.0-alpha.29" - -cyclist@~0.2.2: - version "0.2.2" - resolved "https://registry.yarnpkg.com/cyclist/-/cyclist-0.2.2.tgz#1b33792e11e914a2fd6d6ed6447464444e5fa640" - integrity sha1-GzN5LhHpFKL9bW7WRHRkRE5fpkA= - -dashdash@^1.12.0: - version "1.14.1" - resolved "https://registry.yarnpkg.com/dashdash/-/dashdash-1.14.1.tgz#853cfa0f7cbe2fed5de20326b8dd581035f6e2f0" - integrity sha1-hTz6D3y+L+1d4gMmuN1YEDX24vA= - dependencies: - assert-plus "^1.0.0" - -date-now@^0.1.4: - version "0.1.4" - resolved "https://registry.yarnpkg.com/date-now/-/date-now-0.1.4.tgz#eaf439fd4d4848ad74e5cc7dbef200672b9e345b" - integrity sha1-6vQ5/U1ISK105cx9vvIAZyueNFs= - -de-indent@^1.0.2: - version "1.0.2" - resolved "https://registry.yarnpkg.com/de-indent/-/de-indent-1.0.2.tgz#b2038e846dc33baa5796128d0804b455b8c1e21d" - integrity sha1-sgOOhG3DO6pXlhKNCAS0VbjB4h0= - -debug@*, debug@^4.1.0, debug@^4.1.1: - version "4.1.1" - resolved "https://registry.yarnpkg.com/debug/-/debug-4.1.1.tgz#3b72260255109c6b589cee050f1d516139664791" - integrity sha512-pYAIzeRo8J6KPEaJ0VWOh5Pzkbw/RetuzehGM7QRRX5he4fPHx2rdKMB256ehJCkX+XRQm16eZLqLNS8RSZXZw== - dependencies: - ms "^2.1.1" - -debug@2.6.9, debug@^2.2.0, debug@^2.3.3, debug@^2.6.9: - version "2.6.9" - resolved "https://registry.yarnpkg.com/debug/-/debug-2.6.9.tgz#5d128515df134ff327e90a4c93f4e077a536341f" - integrity sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA== - dependencies: - ms "2.0.0" - -debug@=3.1.0: - version "3.1.0" - resolved "https://registry.yarnpkg.com/debug/-/debug-3.1.0.tgz#5bb5a0672628b64149566ba16819e61518c67261" - integrity sha512-OX8XqP7/1a9cqkxYw2yXss15f26NKWBpDXQd0/uK/KPqdQhxbPa994hnzjcE2VqQpDslf55723cKPUOGSmMY3g== - dependencies: - ms "2.0.0" - -debug@^3.2.5, debug@^3.2.6: - version "3.2.6" - resolved "https://registry.yarnpkg.com/debug/-/debug-3.2.6.tgz#e83d17de16d8a7efb7717edbe5fb10135eee629b" - integrity sha512-mel+jf7nrtEl5Pn1Qx46zARXKDpBbvzezse7p7LqINmdoIk8PYP5SySaxEmYv6TZ0JyEKA1hsCId6DIhgITtWQ== - dependencies: - ms "^2.1.1" - -decamelize@^1.2.0: - version "1.2.0" - resolved "https://registry.yarnpkg.com/decamelize/-/decamelize-1.2.0.tgz#f6534d15148269b20352e7bee26f501f9a191290" - integrity sha1-9lNNFRSCabIDUue+4m9QH5oZEpA= - -decode-uri-component@^0.2.0: - version "0.2.0" - resolved "https://registry.yarnpkg.com/decode-uri-component/-/decode-uri-component-0.2.0.tgz#eb3913333458775cb84cd1a1fae062106bb87545" - integrity sha1-6zkTMzRYd1y4TNGh+uBiEGu4dUU= - -deep-equal@^1.0.1: - version "1.0.1" - resolved "https://registry.yarnpkg.com/deep-equal/-/deep-equal-1.0.1.tgz#f5d260292b660e084eff4cdbc9f08ad3247448b5" - integrity sha1-9dJgKStmDghO/0zbyfCK0yR0SLU= - -deep-extend@^0.6.0: - version "0.6.0" - resolved "https://registry.yarnpkg.com/deep-extend/-/deep-extend-0.6.0.tgz#c4fa7c95404a17a9c3e8ca7e1537312b736330ac" - integrity sha512-LOHxIOaPYdHlJRtCQfDIVZtfw/ufM8+rVj649RIHzcm/vGwQRXFt6OPqIFWsm2XEMrNIEtWR64sY1LEKD2vAOA== - -deepmerge@^1.5.2: - version "1.5.2" - resolved "https://registry.yarnpkg.com/deepmerge/-/deepmerge-1.5.2.tgz#10499d868844cdad4fee0842df8c7f6f0c95a753" - integrity sha512-95k0GDqvBjZavkuvzx/YqVLv/6YYa17fz6ILMSf7neqQITCPbnfEnQvEgMPNjH4kgobe7+WIL0yJEHku+H3qtQ== - -default-gateway@^4.2.0: - version "4.2.0" - resolved "https://registry.yarnpkg.com/default-gateway/-/default-gateway-4.2.0.tgz#167104c7500c2115f6dd69b0a536bb8ed720552b" - integrity sha512-h6sMrVB1VMWVrW13mSc6ia/DwYYw5MN6+exNu1OaJeFac5aSAvwM7lZ0NVfTABuSkQelr4h5oebg3KB1XPdjgA== - dependencies: - execa "^1.0.0" - ip-regex "^2.1.0" - -define-properties@^1.1.2, define-properties@^1.1.3: - version "1.1.3" - resolved "https://registry.yarnpkg.com/define-properties/-/define-properties-1.1.3.tgz#cf88da6cbee26fe6db7094f61d870cbd84cee9f1" - integrity sha512-3MqfYKj2lLzdMSf8ZIZE/V+Zuy+BgD6f164e8K2w7dgnpKArBDerGYpM46IYYcjnkdPNMjPk9A6VFB8+3SKlXQ== - dependencies: - object-keys "^1.0.12" - -define-property@^0.2.5: - version "0.2.5" - resolved "https://registry.yarnpkg.com/define-property/-/define-property-0.2.5.tgz#c35b1ef918ec3c990f9a5bc57be04aacec5c8116" - integrity sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY= - dependencies: - is-descriptor "^0.1.0" - -define-property@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/define-property/-/define-property-1.0.0.tgz#769ebaaf3f4a63aad3af9e8d304c9bbe79bfb0e6" - integrity sha1-dp66rz9KY6rTr56NMEybvnm/sOY= - dependencies: - is-descriptor "^1.0.0" - -define-property@^2.0.2: - version "2.0.2" - resolved "https://registry.yarnpkg.com/define-property/-/define-property-2.0.2.tgz#d459689e8d654ba77e02a817f8710d702cb16e9d" - integrity sha512-jwK2UV4cnPpbcG7+VRARKTZPUWowwXA8bzH5NP6ud0oeAxyYPuGZUAC7hMugpCdz4BeSZl2Dl9k66CHJ/46ZYQ== - dependencies: - is-descriptor "^1.0.2" - isobject "^3.0.1" - -del@^4.1.1: - version "4.1.1" - resolved "https://registry.yarnpkg.com/del/-/del-4.1.1.tgz#9e8f117222ea44a31ff3a156c049b99052a9f0b4" - integrity sha512-QwGuEUouP2kVwQenAsOof5Fv8K9t3D8Ca8NxcXKrIpEHjTXK5J2nXLdP+ALI1cgv8wj7KuwBhTwBkOZSJKM5XQ== - dependencies: - "@types/glob" "^7.1.1" - globby "^6.1.0" - is-path-cwd "^2.0.0" - is-path-in-cwd "^2.0.0" - p-map "^2.0.0" - pify "^4.0.1" - rimraf "^2.6.3" - -delayed-stream@~1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/delayed-stream/-/delayed-stream-1.0.0.tgz#df3ae199acadfb7d440aaae0b29e2272b24ec619" - integrity sha1-3zrhmayt+31ECqrgsp4icrJOxhk= - -delegate@^3.1.2: - version "3.2.0" - resolved "https://registry.yarnpkg.com/delegate/-/delegate-3.2.0.tgz#b66b71c3158522e8ab5744f720d8ca0c2af59166" - integrity sha512-IofjkYBZaZivn0V8nnsMJGBr4jVLxHDheKSW88PyxS5QC4Vo9ZbZVvhzlSxY87fVq3STR6r+4cGepyHkcWOQSw== - -delegates@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/delegates/-/delegates-1.0.0.tgz#84c6e159b81904fdca59a0ef44cd870d31250f9a" - integrity sha1-hMbhWbgZBP3KWaDvRM2HDTElD5o= - -depd@~1.1.2: - version "1.1.2" - resolved "https://registry.yarnpkg.com/depd/-/depd-1.1.2.tgz#9bcd52e14c097763e749b274c4346ed2e560b5a9" - integrity sha1-m81S4UwJd2PnSbJ0xDRu0uVgtak= - -des.js@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/des.js/-/des.js-1.0.0.tgz#c074d2e2aa6a8a9a07dbd61f9a15c2cd83ec8ecc" - integrity sha1-wHTS4qpqipoH29YfmhXCzYPsjsw= - dependencies: - inherits "^2.0.1" - minimalistic-assert "^1.0.0" - -destroy@~1.0.4: - version "1.0.4" - resolved "https://registry.yarnpkg.com/destroy/-/destroy-1.0.4.tgz#978857442c44749e4206613e37946205826abd80" - integrity sha1-l4hXRCxEdJ5CBmE+N5RiBYJqvYA= - -detect-libc@^1.0.2: - version "1.0.3" - resolved "https://registry.yarnpkg.com/detect-libc/-/detect-libc-1.0.3.tgz#fa137c4bd698edf55cd5cd02ac559f91a4c4ba9b" - integrity sha1-+hN8S9aY7fVc1c0CrFWfkaTEups= - -detect-node@^2.0.4: - version "2.0.4" - resolved "https://registry.yarnpkg.com/detect-node/-/detect-node-2.0.4.tgz#014ee8f8f669c5c58023da64b8179c083a28c46c" - integrity sha512-ZIzRpLJrOj7jjP2miAtgqIfmzbxa4ZOr5jJc601zklsfEx9oTzmmj2nVpIPRpNlRTIh8lc1kyViIY7BWSGNmKw== - -diacritics@^1.3.0: - version "1.3.0" - resolved "https://registry.yarnpkg.com/diacritics/-/diacritics-1.3.0.tgz#3efa87323ebb863e6696cebb0082d48ff3d6f7a1" - integrity sha1-PvqHMj67hj5mls67AILUj/PW96E= - -diffie-hellman@^5.0.0: - version "5.0.3" - resolved "https://registry.yarnpkg.com/diffie-hellman/-/diffie-hellman-5.0.3.tgz#40e8ee98f55a2149607146921c63e1ae5f3d2875" - integrity sha512-kqag/Nl+f3GwyK25fhUMYj81BUOrZ9IuJsjIcDE5icNM9FJHAVm3VcUDxdLPoQtTuUylWm6ZIknYJwwaPxsUzg== - dependencies: - bn.js "^4.1.0" - miller-rabin "^4.0.0" - randombytes "^2.0.0" - -dir-glob@^2.0.0, dir-glob@^2.2.2: - version "2.2.2" - resolved "https://registry.yarnpkg.com/dir-glob/-/dir-glob-2.2.2.tgz#fa09f0694153c8918b18ba0deafae94769fc50c4" - integrity sha512-f9LBi5QWzIW3I6e//uxZoLBlUt9kcp66qo0sSCxL6YZKc75R1c4MFCoe/LaZiBGmgujvQdxc5Bn3QhfyvK5Hsw== - dependencies: - path-type "^3.0.0" - -dns-equal@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/dns-equal/-/dns-equal-1.0.0.tgz#b39e7f1da6eb0a75ba9c17324b34753c47e0654d" - integrity sha1-s55/HabrCnW6nBcySzR1PEfgZU0= - -dns-packet@^1.3.1: - version "1.3.1" - resolved "https://registry.yarnpkg.com/dns-packet/-/dns-packet-1.3.1.tgz#12aa426981075be500b910eedcd0b47dd7deda5a" - integrity sha512-0UxfQkMhYAUaZI+xrNZOz/as5KgDU0M/fQ9b6SpkyLbk3GEswDi6PADJVaYJradtRVsRIlF1zLyOodbcTCDzUg== - dependencies: - ip "^1.1.0" - safe-buffer "^5.0.1" - -dns-txt@^2.0.2: - version "2.0.2" - resolved "https://registry.yarnpkg.com/dns-txt/-/dns-txt-2.0.2.tgz#b91d806f5d27188e4ab3e7d107d881a1cc4642b6" - integrity sha1-uR2Ab10nGI5Ks+fRB9iBocxGQrY= - dependencies: - buffer-indexof "^1.0.0" - -docsearch.js@^2.5.2: - version "2.6.3" - resolved "https://registry.yarnpkg.com/docsearch.js/-/docsearch.js-2.6.3.tgz#57cb4600d3b6553c677e7cbbe6a734593e38625d" - integrity sha512-GN+MBozuyz664ycpZY0ecdQE0ND/LSgJKhTLA0/v3arIS3S1Rpf2OJz6A35ReMsm91V5apcmzr5/kM84cvUg+A== - dependencies: - algoliasearch "^3.24.5" - autocomplete.js "0.36.0" - hogan.js "^3.0.2" - request "^2.87.0" - stack-utils "^1.0.1" - to-factory "^1.0.0" - zepto "^1.2.0" - -dom-converter@^0.2: - version "0.2.0" - resolved "https://registry.yarnpkg.com/dom-converter/-/dom-converter-0.2.0.tgz#6721a9daee2e293682955b6afe416771627bb768" - integrity sha512-gd3ypIPfOMr9h5jIKq8E3sHOTCjeirnl0WK5ZdS1AW0Odt0b1PaWaHdJ4Qk4klv+YB9aJBS7mESXjFoDQPu6DA== - dependencies: - utila "~0.4" - -dom-serializer@0: - version "0.1.1" - resolved "https://registry.yarnpkg.com/dom-serializer/-/dom-serializer-0.1.1.tgz#1ec4059e284babed36eec2941d4a970a189ce7c0" - integrity sha512-l0IU0pPzLWSHBcieZbpOKgkIn3ts3vAh7ZuFyXNwJxJXk/c4Gwj9xaTJwIDVQCXawWD0qb3IzMGH5rglQaO0XA== - dependencies: - domelementtype "^1.3.0" - entities "^1.1.1" - -dom-walk@^0.1.0: - version "0.1.1" - resolved "https://registry.yarnpkg.com/dom-walk/-/dom-walk-0.1.1.tgz#672226dc74c8f799ad35307df936aba11acd6018" - integrity sha1-ZyIm3HTI95mtNTB9+TaroRrNYBg= - -domain-browser@^1.1.1: - version "1.2.0" - resolved "https://registry.yarnpkg.com/domain-browser/-/domain-browser-1.2.0.tgz#3d31f50191a6749dd1375a7f522e823d42e54eda" - integrity sha512-jnjyiM6eRyZl2H+W8Q/zLMA481hzi0eszAaBUzIVnmYVDBbnLxVNnfu1HgEBvCbL+71FrxMl3E6lpKH7Ge3OXA== - -domelementtype@1, domelementtype@^1.3.0, domelementtype@^1.3.1: - version "1.3.1" - resolved "https://registry.yarnpkg.com/domelementtype/-/domelementtype-1.3.1.tgz#d048c44b37b0d10a7f2a3d5fee3f4333d790481f" - integrity sha512-BSKB+TSpMpFI/HOxCNr1O8aMOTZ8hT3pM3GQ0w/mWRmkhEDSFJkkyzz4XQsBV44BChwGkrDfMyjVD0eA2aFV3w== - -domhandler@^2.3.0: - version "2.4.2" - resolved "https://registry.yarnpkg.com/domhandler/-/domhandler-2.4.2.tgz#8805097e933d65e85546f726d60f5eb88b44f803" - integrity sha512-JiK04h0Ht5u/80fdLMCEmV4zkNh2BcoMFBmZ/91WtYZ8qVXSKjiw7fXMgFPnHcSZgOo3XdinHvmnDUeMf5R4wA== - dependencies: - domelementtype "1" - -domutils@1.5.1: - version "1.5.1" - resolved "https://registry.yarnpkg.com/domutils/-/domutils-1.5.1.tgz#dcd8488a26f563d61079e48c9f7b7e32373682cf" - integrity sha1-3NhIiib1Y9YQeeSMn3t+Mjc2gs8= - dependencies: - dom-serializer "0" - domelementtype "1" - -domutils@^1.5.1, domutils@^1.7.0: - version "1.7.0" - resolved "https://registry.yarnpkg.com/domutils/-/domutils-1.7.0.tgz#56ea341e834e06e6748af7a1cb25da67ea9f8c2a" - integrity sha512-Lgd2XcJ/NjEw+7tFvfKxOzCYKZsdct5lczQ2ZaQY8Djz7pfAD3Gbp8ySJWtreII/vDlMVmxwa6pHmdxIYgttDg== - dependencies: - dom-serializer "0" - domelementtype "1" - -dot-prop@^4.1.1: - version "4.2.0" - resolved "https://registry.yarnpkg.com/dot-prop/-/dot-prop-4.2.0.tgz#1f19e0c2e1aa0e32797c49799f2837ac6af69c57" - integrity sha512-tUMXrxlExSW6U2EXiiKGSBVdYgtV8qlHL+C10TsW4PURY/ic+eaysnSkwB4kA/mBlCyy/IKDJ+Lc3wbWeaXtuQ== - dependencies: - is-obj "^1.0.0" - -duplexify@^3.4.2, duplexify@^3.6.0: - version "3.7.1" - resolved "https://registry.yarnpkg.com/duplexify/-/duplexify-3.7.1.tgz#2a4df5317f6ccfd91f86d6fd25d8d8a103b88309" - integrity sha512-07z8uv2wMyS51kKhD1KsdXJg5WQ6t93RneqRxUHnskXVtlYYkLqM0gqStQZ3pj073g687jPCHrqNfCzawLYh5g== - dependencies: - end-of-stream "^1.0.0" - inherits "^2.0.1" - readable-stream "^2.0.0" - stream-shift "^1.0.0" - -ecc-jsbn@~0.1.1: - version "0.1.2" - resolved "https://registry.yarnpkg.com/ecc-jsbn/-/ecc-jsbn-0.1.2.tgz#3a83a904e54353287874c564b7549386849a98c9" - integrity sha1-OoOpBOVDUyh4dMVkt1SThoSamMk= - dependencies: - jsbn "~0.1.0" - safer-buffer "^2.1.0" - -ee-first@1.1.1: - version "1.1.1" - resolved "https://registry.yarnpkg.com/ee-first/-/ee-first-1.1.1.tgz#590c61156b0ae2f4f0255732a158b266bc56b21d" - integrity sha1-WQxhFWsK4vTwJVcyoViyZrxWsh0= - -electron-to-chromium@^1.3.191: - version "1.3.194" - resolved "https://registry.yarnpkg.com/electron-to-chromium/-/electron-to-chromium-1.3.194.tgz#a96452a96d4539131957aade9f634a45721f2819" - integrity sha512-w0LHR2YD9Ex1o+Sz4IN2hYzCB8vaFtMNW+yJcBf6SZlVqgFahkne/4rGVJdk4fPF98Gch9snY7PiabOh+vqHNg== - -elliptic@^6.0.0: - version "6.5.0" - resolved "https://registry.yarnpkg.com/elliptic/-/elliptic-6.5.0.tgz#2b8ed4c891b7de3200e14412a5b8248c7af505ca" - integrity sha512-eFOJTMyCYb7xtE/caJ6JJu+bhi67WCYNbkGSknu20pmM8Ke/bqOfdnZWxyoGN26JgfxTbXrsCkEw4KheCT/KGg== - dependencies: - bn.js "^4.4.0" - brorand "^1.0.1" - hash.js "^1.0.0" - hmac-drbg "^1.0.0" - inherits "^2.0.1" - minimalistic-assert "^1.0.0" - minimalistic-crypto-utils "^1.0.0" - -emoji-regex@^7.0.1: - version "7.0.3" - resolved "https://registry.yarnpkg.com/emoji-regex/-/emoji-regex-7.0.3.tgz#933a04052860c85e83c122479c4748a8e4c72156" - integrity sha512-CwBLREIQ7LvYFB0WyRvwhq5N5qPhc6PMjD6bYggFlI5YyDgl+0vxq5VHbMOFqLg7hfWzmu8T5Z1QofhmTIhItA== - -emojis-list@^2.0.0: - version "2.1.0" - resolved "https://registry.yarnpkg.com/emojis-list/-/emojis-list-2.1.0.tgz#4daa4d9db00f9819880c79fa457ae5b09a1fd389" - integrity sha1-TapNnbAPmBmIDHn6RXrlsJof04k= - -encodeurl@~1.0.2: - version "1.0.2" - resolved "https://registry.yarnpkg.com/encodeurl/-/encodeurl-1.0.2.tgz#ad3ff4c86ec2d029322f5a02c3a9a606c95b3f59" - integrity sha1-rT/0yG7C0CkyL1oCw6mmBslbP1k= - -end-of-stream@^1.0.0, end-of-stream@^1.1.0: - version "1.4.1" - resolved "https://registry.yarnpkg.com/end-of-stream/-/end-of-stream-1.4.1.tgz#ed29634d19baba463b6ce6b80a37213eab71ec43" - integrity sha512-1MkrZNvWTKCaigbn+W15elq2BB/L22nqrSY5DKlo3X6+vclJm8Bb5djXJBmEX6fS3+zCh/F4VBK5Z2KxJt4s2Q== - dependencies: - once "^1.4.0" - -enhanced-resolve@^4.1.0: - version "4.1.0" - resolved "https://registry.yarnpkg.com/enhanced-resolve/-/enhanced-resolve-4.1.0.tgz#41c7e0bfdfe74ac1ffe1e57ad6a5c6c9f3742a7f" - integrity sha512-F/7vkyTtyc/llOIn8oWclcB25KdRaiPBpZYDgJHgh/UHtpgT2p2eldQgtQnLtUvfMKPKxbRaQM/hHkvLHt1Vng== - dependencies: - graceful-fs "^4.1.2" - memory-fs "^0.4.0" - tapable "^1.0.0" - -entities@^1.1.1, entities@~1.1.1: - version "1.1.2" - resolved "https://registry.yarnpkg.com/entities/-/entities-1.1.2.tgz#bdfa735299664dfafd34529ed4f8522a275fea56" - integrity sha512-f2LZMYl1Fzu7YSBKg+RoROelpOaNrcGmE9AZubeDfrCEia483oW4MI4VyFd5VNHIgQ/7qm1I0wUHK1eJnn2y2w== - -envify@^4.0.0: - version "4.1.0" - resolved "https://registry.yarnpkg.com/envify/-/envify-4.1.0.tgz#f39ad3db9d6801b4e6b478b61028d3f0b6819f7e" - integrity sha512-IKRVVoAYr4pIx4yIWNsz9mOsboxlNXiu7TNBnem/K/uTHdkyzXWDzHCK7UTolqBbgaBz0tQHsD3YNls0uIIjiw== - dependencies: - esprima "^4.0.0" - through "~2.3.4" - -envinfo@^7.2.0: - version "7.3.1" - resolved "https://registry.yarnpkg.com/envinfo/-/envinfo-7.3.1.tgz#892e42f7bf858b3446d9414ad240dbaf8da52f09" - integrity sha512-GvXiDTqLYrORVSCuJCsWHPXF5BFvoWMQA9xX4YVjPT1jyS3aZEHUBwjzxU/6LTPF9ReHgVEbX7IEN5UvSXHw/A== - -errno@^0.1.3, errno@~0.1.7: - version "0.1.7" - resolved "https://registry.yarnpkg.com/errno/-/errno-0.1.7.tgz#4684d71779ad39af177e3f007996f7c67c852618" - integrity sha512-MfrRBDWzIWifgq6tJj60gkAwtLNb6sQPlcFrSOflcP1aFmmruKQ2wRnze/8V6kgyz7H3FF8Npzv78mZ7XLLflg== - dependencies: - prr "~1.0.1" - -error-ex@^1.3.1: - version "1.3.2" - resolved "https://registry.yarnpkg.com/error-ex/-/error-ex-1.3.2.tgz#b4ac40648107fdcdcfae242f428bea8a14d4f1bf" - integrity sha512-7dFHNmqeFSEt2ZBsCriorKnn3Z2pj+fd9kmI6QoWw4//DL+icEBfc0U7qJCisqrTsKTjw4fNFy2pW9OqStD84g== - dependencies: - is-arrayish "^0.2.1" - -es-abstract@^1.12.0, es-abstract@^1.5.1: - version "1.13.0" - resolved "https://registry.yarnpkg.com/es-abstract/-/es-abstract-1.13.0.tgz#ac86145fdd5099d8dd49558ccba2eaf9b88e24e9" - integrity sha512-vDZfg/ykNxQVwup/8E1BZhVzFfBxs9NqMzGcvIJrqg5k2/5Za2bWo40dK2J1pgLngZ7c+Shh8lwYtLGyrwPutg== - dependencies: - es-to-primitive "^1.2.0" - function-bind "^1.1.1" - has "^1.0.3" - is-callable "^1.1.4" - is-regex "^1.0.4" - object-keys "^1.0.12" - -es-to-primitive@^1.2.0: - version "1.2.0" - resolved "https://registry.yarnpkg.com/es-to-primitive/-/es-to-primitive-1.2.0.tgz#edf72478033456e8dda8ef09e00ad9650707f377" - integrity sha512-qZryBOJjV//LaxLTV6UC//WewneB3LcXOL9NP++ozKVXsIIIpm/2c13UDiD9Jp2eThsecw9m3jPqDwTyobcdbg== - dependencies: - is-callable "^1.1.4" - is-date-object "^1.0.1" - is-symbol "^1.0.2" - -es6-promise@^4.1.0: - version "4.2.8" - resolved "https://registry.yarnpkg.com/es6-promise/-/es6-promise-4.2.8.tgz#4eb21594c972bc40553d276e510539143db53e0a" - integrity sha512-HJDGx5daxeIvxdBxvG2cb9g4tEvwIk3i8+nhX0yGrYmZUzbkdg8QbDevheDB8gd0//uPj4c1EQua8Q+MViT0/w== - -escape-html@^1.0.3, escape-html@~1.0.3: - version "1.0.3" - resolved "https://registry.yarnpkg.com/escape-html/-/escape-html-1.0.3.tgz#0258eae4d3d0c0974de1c169188ef0051d1d1988" - integrity sha1-Aljq5NPQwJdN4cFpGI7wBR0dGYg= - -escape-string-regexp@^1.0.2, escape-string-regexp@^1.0.5: - version "1.0.5" - resolved "https://registry.yarnpkg.com/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz#1b61c0562190a8dff6ae3bb2cf0200ca130b86d4" - integrity sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ= - -eslint-scope@^4.0.0: - version "4.0.3" - resolved "https://registry.yarnpkg.com/eslint-scope/-/eslint-scope-4.0.3.tgz#ca03833310f6889a3264781aa82e63eb9cfe7848" - integrity sha512-p7VutNr1O/QrxysMo3E45FjYDTeXBy0iTltPFNSqKAIfjDSXC+4dj+qfyuD8bfAXrW/y6lW3O76VaYNPKfpKrg== - dependencies: - esrecurse "^4.1.0" - estraverse "^4.1.1" - -esprima@^4.0.0: - version "4.0.1" - resolved "https://registry.yarnpkg.com/esprima/-/esprima-4.0.1.tgz#13b04cdb3e6c5d19df91ab6987a8695619b0aa71" - integrity sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A== - -esrecurse@^4.1.0: - version "4.2.1" - resolved "https://registry.yarnpkg.com/esrecurse/-/esrecurse-4.2.1.tgz#007a3b9fdbc2b3bb87e4879ea19c92fdbd3942cf" - integrity sha512-64RBB++fIOAXPw3P9cy89qfMlvZEXZkqqJkjqqXIvzP5ezRZjW+lPWjw35UX/3EhUPFYbg5ER4JYgDw4007/DQ== - dependencies: - estraverse "^4.1.0" - -estraverse@^4.1.0, estraverse@^4.1.1: - version "4.2.0" - resolved "https://registry.yarnpkg.com/estraverse/-/estraverse-4.2.0.tgz#0dee3fed31fcd469618ce7342099fc1afa0bdb13" - integrity sha1-De4/7TH81GlhjOc0IJn8GvoL2xM= - -esutils@^2.0.2: - version "2.0.2" - resolved "https://registry.yarnpkg.com/esutils/-/esutils-2.0.2.tgz#0abf4f1caa5bcb1f7a9d8acc6dea4faaa04bac9b" - integrity sha1-Cr9PHKpbyx96nYrMbepPqqBLrJs= - -etag@~1.8.1: - version "1.8.1" - resolved "https://registry.yarnpkg.com/etag/-/etag-1.8.1.tgz#41ae2eeb65efa62268aebfea83ac7d79299b0887" - integrity sha1-Qa4u62XvpiJorr/qg6x9eSmbCIc= - -eventemitter3@^3.0.0: - version "3.1.2" - resolved "https://registry.yarnpkg.com/eventemitter3/-/eventemitter3-3.1.2.tgz#2d3d48f9c346698fce83a85d7d664e98535df6e7" - integrity sha512-tvtQIeLVHjDkJYnzf2dgVMxfuSGJeM/7UCG17TT4EumTfNtF+0nebF/4zWOIkCreAbtNqhGEboB6BWrwqNaw4Q== - -events@^1.1.0: - version "1.1.1" - resolved "https://registry.yarnpkg.com/events/-/events-1.1.1.tgz#9ebdb7635ad099c70dcc4c2a1f5004288e8bd924" - integrity sha1-nr23Y1rQmccNzEwqH1AEKI6L2SQ= - -events@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/events/-/events-3.0.0.tgz#9a0a0dfaf62893d92b875b8f2698ca4114973e88" - integrity sha512-Dc381HFWJzEOhQ+d8pkNon++bk9h6cdAoAj4iE6Q4y6xgTzySWXlKn05/TVNpjnfRqi/X0EpJEJohPjNI3zpVA== - -eventsource@^1.0.7: - version "1.0.7" - resolved "https://registry.yarnpkg.com/eventsource/-/eventsource-1.0.7.tgz#8fbc72c93fcd34088090bc0a4e64f4b5cee6d8d0" - integrity sha512-4Ln17+vVT0k8aWq+t/bF5arcS3EpT9gYtW66EPacdj/mAFevznsnyoHLPy2BA8gbIQeIHoPsvwmfBftfcG//BQ== - dependencies: - original "^1.0.0" - -evp_bytestokey@^1.0.0, evp_bytestokey@^1.0.3: - version "1.0.3" - resolved "https://registry.yarnpkg.com/evp_bytestokey/-/evp_bytestokey-1.0.3.tgz#7fcbdb198dc71959432efe13842684e0525acb02" - integrity sha512-/f2Go4TognH/KvCISP7OUsHn85hT9nUkxxA9BEWxFn+Oj9o8ZNLm/40hdlgSLyuOimsrTKLUMEorQexp/aPQeA== - dependencies: - md5.js "^1.3.4" - safe-buffer "^5.1.1" - -execa@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/execa/-/execa-1.0.0.tgz#c6236a5bb4df6d6f15e88e7f017798216749ddd8" - integrity sha512-adbxcyWV46qiHyvSp50TKt05tB4tK3HcmF7/nxfAdhnox83seTDbwnaqKO4sXRy7roHAIFqJP/Rw/AuEbX61LA== - dependencies: - cross-spawn "^6.0.0" - get-stream "^4.0.0" - is-stream "^1.1.0" - npm-run-path "^2.0.0" - p-finally "^1.0.0" - signal-exit "^3.0.0" - strip-eof "^1.0.0" - -expand-brackets@^2.1.4: - version "2.1.4" - resolved "https://registry.yarnpkg.com/expand-brackets/-/expand-brackets-2.1.4.tgz#b77735e315ce30f6b6eff0f83b04151a22449622" - integrity sha1-t3c14xXOMPa27/D4OwQVGiJEliI= - dependencies: - debug "^2.3.3" - define-property "^0.2.5" - extend-shallow "^2.0.1" - posix-character-classes "^0.1.0" - regex-not "^1.0.0" - snapdragon "^0.8.1" - to-regex "^3.0.1" - -express@^4.17.1: - version "4.17.1" - resolved "https://registry.yarnpkg.com/express/-/express-4.17.1.tgz#4491fc38605cf51f8629d39c2b5d026f98a4c134" - integrity sha512-mHJ9O79RqluphRrcw2X/GTh3k9tVv8YcoyY4Kkh4WDMUYKRZUq0h1o0w2rrrxBqM7VoeUVqgb27xlEMXTnYt4g== - dependencies: - accepts "~1.3.7" - array-flatten "1.1.1" - body-parser "1.19.0" - content-disposition "0.5.3" - content-type "~1.0.4" - cookie "0.4.0" - cookie-signature "1.0.6" - debug "2.6.9" - depd "~1.1.2" - encodeurl "~1.0.2" - escape-html "~1.0.3" - etag "~1.8.1" - finalhandler "~1.1.2" - fresh "0.5.2" - merge-descriptors "1.0.1" - methods "~1.1.2" - on-finished "~2.3.0" - parseurl "~1.3.3" - path-to-regexp "0.1.7" - proxy-addr "~2.0.5" - qs "6.7.0" - range-parser "~1.2.1" - safe-buffer "5.1.2" - send "0.17.1" - serve-static "1.14.1" - setprototypeof "1.1.1" - statuses "~1.5.0" - type-is "~1.6.18" - utils-merge "1.0.1" - vary "~1.1.2" - -extend-shallow@^2.0.1: - version "2.0.1" - resolved "https://registry.yarnpkg.com/extend-shallow/-/extend-shallow-2.0.1.tgz#51af7d614ad9a9f610ea1bafbb989d6b1c56890f" - integrity sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8= - dependencies: - is-extendable "^0.1.0" - -extend-shallow@^3.0.0, extend-shallow@^3.0.2: - version "3.0.2" - resolved "https://registry.yarnpkg.com/extend-shallow/-/extend-shallow-3.0.2.tgz#26a71aaf073b39fb2127172746131c2704028db8" - integrity sha1-Jqcarwc7OfshJxcnRhMcJwQCjbg= - dependencies: - assign-symbols "^1.0.0" - is-extendable "^1.0.1" - -extend@~3.0.2: - version "3.0.2" - resolved "https://registry.yarnpkg.com/extend/-/extend-3.0.2.tgz#f8b1136b4071fbd8eb140aff858b1019ec2915fa" - integrity sha512-fjquC59cD7CyW6urNXK0FBufkZcoiGG80wTuPujX590cB5Ttln20E2UB4S/WARVqhXffZl2LNgS+gQdPIIim/g== - -extglob@^2.0.4: - version "2.0.4" - resolved "https://registry.yarnpkg.com/extglob/-/extglob-2.0.4.tgz#ad00fe4dc612a9232e8718711dc5cb5ab0285543" - integrity sha512-Nmb6QXkELsuBr24CJSkilo6UHHgbekK5UiZgfE6UHD3Eb27YC6oD+bhcT+tJ6cl8dmsgdQxnWlcry8ksBIBLpw== - dependencies: - array-unique "^0.3.2" - define-property "^1.0.0" - expand-brackets "^2.1.4" - extend-shallow "^2.0.1" - fragment-cache "^0.2.1" - regex-not "^1.0.0" - snapdragon "^0.8.1" - to-regex "^3.0.1" - -extsprintf@1.3.0: - version "1.3.0" - resolved "https://registry.yarnpkg.com/extsprintf/-/extsprintf-1.3.0.tgz#96918440e3041a7a414f8c52e3c574eb3c3e1e05" - integrity sha1-lpGEQOMEGnpBT4xS48V06zw+HgU= - -extsprintf@^1.2.0: - version "1.4.0" - resolved "https://registry.yarnpkg.com/extsprintf/-/extsprintf-1.4.0.tgz#e2689f8f356fad62cca65a3a91c5df5f9551692f" - integrity sha1-4mifjzVvrWLMplo6kcXfX5VRaS8= - -fast-deep-equal@^2.0.1: - version "2.0.1" - resolved "https://registry.yarnpkg.com/fast-deep-equal/-/fast-deep-equal-2.0.1.tgz#7b05218ddf9667bf7f370bf7fdb2cb15fdd0aa49" - integrity sha1-ewUhjd+WZ79/Nwv3/bLLFf3Qqkk= - -fast-glob@^2.2.6: - version "2.2.7" - resolved "https://registry.yarnpkg.com/fast-glob/-/fast-glob-2.2.7.tgz#6953857c3afa475fff92ee6015d52da70a4cd39d" - integrity sha512-g1KuQwHOZAmOZMuBtHdxDtju+T2RT8jgCC9aANsbpdiDDTSnjgfuVsIBNKbUeJI3oKMRExcfNDtJl4OhbffMsw== - dependencies: - "@mrmlnc/readdir-enhanced" "^2.2.1" - "@nodelib/fs.stat" "^1.1.2" - glob-parent "^3.1.0" - is-glob "^4.0.0" - merge2 "^1.2.3" - micromatch "^3.1.10" - -fast-json-stable-stringify@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/fast-json-stable-stringify/-/fast-json-stable-stringify-2.0.0.tgz#d5142c0caee6b1189f87d3a76111064f86c8bbf2" - integrity sha1-1RQsDK7msRifh9OnYREGT4bIu/I= - -faye-websocket@^0.10.0: - version "0.10.0" - resolved "https://registry.yarnpkg.com/faye-websocket/-/faye-websocket-0.10.0.tgz#4e492f8d04dfb6f89003507f6edbf2d501e7c6f4" - integrity sha1-TkkvjQTftviQA1B/btvy1QHnxvQ= - dependencies: - websocket-driver ">=0.5.1" - -faye-websocket@~0.11.1: - version "0.11.3" - resolved "https://registry.yarnpkg.com/faye-websocket/-/faye-websocket-0.11.3.tgz#5c0e9a8968e8912c286639fde977a8b209f2508e" - integrity sha512-D2y4bovYpzziGgbHYtGCMjlJM36vAl/y+xUyn1C+FVx8szd1E+86KwVw6XvYSzOP8iMpm1X0I4xJD+QtUb36OA== - dependencies: - websocket-driver ">=0.5.1" - -figgy-pudding@^3.5.1: - version "3.5.1" - resolved "https://registry.yarnpkg.com/figgy-pudding/-/figgy-pudding-3.5.1.tgz#862470112901c727a0e495a80744bd5baa1d6790" - integrity sha512-vNKxJHTEKNThjfrdJwHc7brvM6eVevuO5nTj6ez8ZQ1qbXTvGthucRF7S4vf2cr71QVnT70V34v0S1DyQsti0w== - -figures@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/figures/-/figures-3.0.0.tgz#756275c964646163cc6f9197c7a0295dbfd04de9" - integrity sha512-HKri+WoWoUgr83pehn/SIgLOMZ9nAWC6dcGj26RY2R4F50u4+RTUz0RCrUlOV3nKRAICW1UGzyb+kcX2qK1S/g== - dependencies: - escape-string-regexp "^1.0.5" - -file-loader@^3.0.1: - version "3.0.1" - resolved "https://registry.yarnpkg.com/file-loader/-/file-loader-3.0.1.tgz#f8e0ba0b599918b51adfe45d66d1e771ad560faa" - integrity sha512-4sNIOXgtH/9WZq4NvlfU3Opn5ynUsqBwSLyM+I7UOwdGigTBYfVVQEwe/msZNX/j4pCJTIM14Fsw66Svo1oVrw== - dependencies: - loader-utils "^1.0.2" - schema-utils "^1.0.0" - -fill-range@^4.0.0: - version "4.0.0" - resolved "https://registry.yarnpkg.com/fill-range/-/fill-range-4.0.0.tgz#d544811d428f98eb06a63dc402d2403c328c38f7" - integrity sha1-1USBHUKPmOsGpj3EAtJAPDKMOPc= - dependencies: - extend-shallow "^2.0.1" - is-number "^3.0.0" - repeat-string "^1.6.1" - to-regex-range "^2.1.0" - -finalhandler@~1.1.2: - version "1.1.2" - resolved "https://registry.yarnpkg.com/finalhandler/-/finalhandler-1.1.2.tgz#b7e7d000ffd11938d0fdb053506f6ebabe9f587d" - integrity sha512-aAWcW57uxVNrQZqFXjITpW3sIUQmHGG3qSb9mUah9MgMC4NeWhNOlNjXEYq3HjRAvL6arUviZGGJsBg6z0zsWA== - dependencies: - debug "2.6.9" - encodeurl "~1.0.2" - escape-html "~1.0.3" - on-finished "~2.3.0" - parseurl "~1.3.3" - statuses "~1.5.0" - unpipe "~1.0.0" - -find-babel-config@^1.1.0: - version "1.2.0" - resolved "https://registry.yarnpkg.com/find-babel-config/-/find-babel-config-1.2.0.tgz#a9b7b317eb5b9860cda9d54740a8c8337a2283a2" - integrity sha512-jB2CHJeqy6a820ssiqwrKMeyC6nNdmrcgkKWJWmpoxpE8RKciYJXCcXRq1h2AzCo5I5BJeN2tkGEO3hLTuePRA== - dependencies: - json5 "^0.5.1" - path-exists "^3.0.0" - -find-cache-dir@^2.0.0, find-cache-dir@^2.1.0: - version "2.1.0" - resolved "https://registry.yarnpkg.com/find-cache-dir/-/find-cache-dir-2.1.0.tgz#8d0f94cd13fe43c6c7c261a0d86115ca918c05f7" - integrity sha512-Tq6PixE0w/VMFfCgbONnkiQIVol/JJL7nRMi20fqzA4NRs9AfeqMGeRdPi3wIhYkxjeBaWh2rxwapn5Tu3IqOQ== - dependencies: - commondir "^1.0.1" - make-dir "^2.0.0" - pkg-dir "^3.0.0" - -find-up@^2.1.0: - version "2.1.0" - resolved "https://registry.yarnpkg.com/find-up/-/find-up-2.1.0.tgz#45d1b7e506c717ddd482775a2b77920a3c0c57a7" - integrity sha1-RdG35QbHF93UgndaK3eSCjwMV6c= - dependencies: - locate-path "^2.0.0" - -find-up@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/find-up/-/find-up-3.0.0.tgz#49169f1d7993430646da61ecc5ae355c21c97b73" - integrity sha512-1yD6RmLI1XBfxugvORwlck6f75tYL+iR0jqwsOrOxMZyGYqUuDhJ0l4AXdO1iX/FTs9cBAMEk1gWSEx1kSbylg== - dependencies: - locate-path "^3.0.0" - -flush-write-stream@^1.0.0: - version "1.1.1" - resolved "https://registry.yarnpkg.com/flush-write-stream/-/flush-write-stream-1.1.1.tgz#8dd7d873a1babc207d94ead0c2e0e44276ebf2e8" - integrity sha512-3Z4XhFZ3992uIq0XOqb9AreonueSYphE6oYbpt5+3u06JWklbsPkNv3ZKkP9Bz/r+1MWCaMoSQ28P85+1Yc77w== - dependencies: - inherits "^2.0.3" - readable-stream "^2.3.6" - -follow-redirects@1.5.10: - version "1.5.10" - resolved "https://registry.yarnpkg.com/follow-redirects/-/follow-redirects-1.5.10.tgz#7b7a9f9aea2fdff36786a94ff643ed07f4ff5e2a" - integrity sha512-0V5l4Cizzvqt5D44aTXbFZz+FtyXV1vrDN6qrelxtfYQKW0KO0W2T/hkE8xvGa/540LkZlkaUjO4ailYTFtHVQ== - dependencies: - debug "=3.1.0" - -follow-redirects@^1.0.0: - version "1.7.0" - resolved "https://registry.yarnpkg.com/follow-redirects/-/follow-redirects-1.7.0.tgz#489ebc198dc0e7f64167bd23b03c4c19b5784c76" - integrity sha512-m/pZQy4Gj287eNy94nivy5wchN3Kp+Q5WgUPNy5lJSZ3sgkVKSYV/ZChMAQVIgx1SqfZ2zBZtPA2YlXIWxxJOQ== - dependencies: - debug "^3.2.6" - -for-in@^1.0.2: - version "1.0.2" - resolved "https://registry.yarnpkg.com/for-in/-/for-in-1.0.2.tgz#81068d295a8142ec0ac726c6e2200c30fb6d5e80" - integrity sha1-gQaNKVqBQuwKxybG4iAMMPttXoA= - -foreach@^2.0.5: - version "2.0.5" - resolved "https://registry.yarnpkg.com/foreach/-/foreach-2.0.5.tgz#0bee005018aeb260d0a3af3ae658dd0136ec1b99" - integrity sha1-C+4AUBiusmDQo6865ljdATbsG5k= - -forever-agent@~0.6.1: - version "0.6.1" - resolved "https://registry.yarnpkg.com/forever-agent/-/forever-agent-0.6.1.tgz#fbc71f0c41adeb37f96c577ad1ed42d8fdacca91" - integrity sha1-+8cfDEGt6zf5bFd60e1C2P2sypE= - -form-data@~2.3.2: - version "2.3.3" - resolved "https://registry.yarnpkg.com/form-data/-/form-data-2.3.3.tgz#dcce52c05f644f298c6a7ab936bd724ceffbf3a6" - integrity sha512-1lLKB2Mu3aGP1Q/2eCOx0fNbRMe7XdwktwOruhfqqd0rIJWwN4Dh+E3hrPSlDCXnSR7UtZ1N38rVXm+6+MEhJQ== - dependencies: - asynckit "^0.4.0" - combined-stream "^1.0.6" - mime-types "^2.1.12" - -forwarded@~0.1.2: - version "0.1.2" - resolved "https://registry.yarnpkg.com/forwarded/-/forwarded-0.1.2.tgz#98c23dab1175657b8c0573e8ceccd91b0ff18c84" - integrity sha1-mMI9qxF1ZXuMBXPozszZGw/xjIQ= - -fragment-cache@^0.2.1: - version "0.2.1" - resolved "https://registry.yarnpkg.com/fragment-cache/-/fragment-cache-0.2.1.tgz#4290fad27f13e89be7f33799c6bc5a0abfff0d19" - integrity sha1-QpD60n8T6Jvn8zeZxrxaCr//DRk= - dependencies: - map-cache "^0.2.2" - -fresh@0.5.2: - version "0.5.2" - resolved "https://registry.yarnpkg.com/fresh/-/fresh-0.5.2.tgz#3d8cadd90d976569fa835ab1f8e4b23a105605a7" - integrity sha1-PYyt2Q2XZWn6g1qx+OSyOhBWBac= - -from2@^2.1.0: - version "2.3.0" - resolved "https://registry.yarnpkg.com/from2/-/from2-2.3.0.tgz#8bfb5502bde4a4d36cfdeea007fcca21d7e382af" - integrity sha1-i/tVAr3kpNNs/e6gB/zKIdfjgq8= - dependencies: - inherits "^2.0.1" - readable-stream "^2.0.0" - -fs-extra@^7.0.1: - version "7.0.1" - resolved "https://registry.yarnpkg.com/fs-extra/-/fs-extra-7.0.1.tgz#4f189c44aa123b895f722804f55ea23eadc348e9" - integrity sha512-YJDaCJZEnBmcbw13fvdAM9AwNOJwOzrE4pqMqBq5nFiEqXUqHwlK4B+3pUw6JNvfSPtX05xFHtYy/1ni01eGCw== - dependencies: - graceful-fs "^4.1.2" - jsonfile "^4.0.0" - universalify "^0.1.0" - -fs-minipass@^1.2.5: - version "1.2.6" - resolved "https://registry.yarnpkg.com/fs-minipass/-/fs-minipass-1.2.6.tgz#2c5cc30ded81282bfe8a0d7c7c1853ddeb102c07" - integrity sha512-crhvyXcMejjv3Z5d2Fa9sf5xLYVCF5O1c71QxbVnbLsmYMBEvDAftewesN/HhY03YRoA7zOMxjNGrF5svGaaeQ== - dependencies: - minipass "^2.2.1" - -fs-write-stream-atomic@^1.0.8: - version "1.0.10" - resolved "https://registry.yarnpkg.com/fs-write-stream-atomic/-/fs-write-stream-atomic-1.0.10.tgz#b47df53493ef911df75731e70a9ded0189db40c9" - integrity sha1-tH31NJPvkR33VzHnCp3tAYnbQMk= - dependencies: - graceful-fs "^4.1.2" - iferr "^0.1.5" - imurmurhash "^0.1.4" - readable-stream "1 || 2" - -fs.realpath@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/fs.realpath/-/fs.realpath-1.0.0.tgz#1504ad2523158caa40db4a2787cb01411994ea4f" - integrity sha1-FQStJSMVjKpA20onh8sBQRmU6k8= - -fsevents@^1.2.7: - version "1.2.9" - resolved "https://registry.yarnpkg.com/fsevents/-/fsevents-1.2.9.tgz#3f5ed66583ccd6f400b5a00db6f7e861363e388f" - integrity sha512-oeyj2H3EjjonWcFjD5NvZNE9Rqe4UW+nQBU2HNeKw0koVLEFIhtyETyAakeAM3de7Z/SW5kcA+fZUait9EApnw== - dependencies: - nan "^2.12.1" - node-pre-gyp "^0.12.0" - -function-bind@^1.1.1: - version "1.1.1" - resolved "https://registry.yarnpkg.com/function-bind/-/function-bind-1.1.1.tgz#a56899d3ea3c9bab874bb9773b7c5ede92f4895d" - integrity sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A== - -gauge@~2.7.3: - version "2.7.4" - resolved "https://registry.yarnpkg.com/gauge/-/gauge-2.7.4.tgz#2c03405c7538c39d7eb37b317022e325fb018bf7" - integrity sha1-LANAXHU4w51+s3sxcCLjJfsBi/c= - dependencies: - aproba "^1.0.3" - console-control-strings "^1.0.0" - has-unicode "^2.0.0" - object-assign "^4.1.0" - signal-exit "^3.0.0" - string-width "^1.0.1" - strip-ansi "^3.0.1" - wide-align "^1.1.0" - -get-caller-file@^1.0.1: - version "1.0.3" - resolved "https://registry.yarnpkg.com/get-caller-file/-/get-caller-file-1.0.3.tgz#f978fa4c90d1dfe7ff2d6beda2a515e713bdcf4a" - integrity sha512-3t6rVToeoZfYSGd8YoLFR2DJkiQrIiUrGcjvFX2mDw3bn6k2OtwHN0TNCLbBO+w8qTvimhDkv+LSscbJY1vE6w== - -get-stream@^4.0.0: - version "4.1.0" - resolved "https://registry.yarnpkg.com/get-stream/-/get-stream-4.1.0.tgz#c1b255575f3dc21d59bfc79cd3d2b46b1c3a54b5" - integrity sha512-GMat4EJ5161kIy2HevLlr4luNjBgvmj413KaQA7jt4V8B4RDsfpHk7WQ9GVqfYyyx8OS/L66Kox+rJRNklLK7w== - dependencies: - pump "^3.0.0" - -get-value@^2.0.3, get-value@^2.0.6: - version "2.0.6" - resolved "https://registry.yarnpkg.com/get-value/-/get-value-2.0.6.tgz#dc15ca1c672387ca76bd37ac0a395ba2042a2c28" - integrity sha1-3BXKHGcjh8p2vTesCjlbogQqLCg= - -getpass@^0.1.1: - version "0.1.7" - resolved "https://registry.yarnpkg.com/getpass/-/getpass-0.1.7.tgz#5eff8e3e684d569ae4cb2b1282604e8ba62149fa" - integrity sha1-Xv+OPmhNVprkyysSgmBOi6YhSfo= - dependencies: - assert-plus "^1.0.0" - -glob-parent@^3.1.0: - version "3.1.0" - resolved "https://registry.yarnpkg.com/glob-parent/-/glob-parent-3.1.0.tgz#9e6af6299d8d3bd2bd40430832bd113df906c5ae" - integrity sha1-nmr2KZ2NO9K9QEMIMr0RPfkGxa4= - dependencies: - is-glob "^3.1.0" - path-dirname "^1.0.0" - -glob-to-regexp@^0.3.0: - version "0.3.0" - resolved "https://registry.yarnpkg.com/glob-to-regexp/-/glob-to-regexp-0.3.0.tgz#8c5a1494d2066c570cc3bfe4496175acc4d502ab" - integrity sha1-jFoUlNIGbFcMw7/kSWF1rMTVAqs= - -glob@7.0.x: - version "7.0.6" - resolved "https://registry.yarnpkg.com/glob/-/glob-7.0.6.tgz#211bafaf49e525b8cd93260d14ab136152b3f57a" - integrity sha1-IRuvr0nlJbjNkyYNFKsTYVKz9Xo= - dependencies: - fs.realpath "^1.0.0" - inflight "^1.0.4" - inherits "2" - minimatch "^3.0.2" - once "^1.3.0" - path-is-absolute "^1.0.0" - -glob@^7.0.3, glob@^7.1.2, glob@^7.1.3, glob@^7.1.4: - version "7.1.4" - resolved "https://registry.yarnpkg.com/glob/-/glob-7.1.4.tgz#aa608a2f6c577ad357e1ae5a5c26d9a8d1969255" - integrity sha512-hkLPepehmnKk41pUGm3sYxoFs/umurYfYJCerbXEyFIWcAzvpipAgVkBqqT9RBKMGjnq6kMuyYwha6csxbiM1A== - dependencies: - fs.realpath "^1.0.0" - inflight "^1.0.4" - inherits "2" - minimatch "^3.0.4" - once "^1.3.0" - path-is-absolute "^1.0.0" - -global@^4.3.2: - version "4.4.0" - resolved "https://registry.yarnpkg.com/global/-/global-4.4.0.tgz#3e7b105179006a323ed71aafca3e9c57a5cc6406" - integrity sha512-wv/LAoHdRE3BeTGz53FAamhGlPLhlssK45usmGFThIi4XqnBmjKQ16u+RNbP7WvigRZDxUsM0J3gcQ5yicaL0w== - dependencies: - min-document "^2.19.0" - process "^0.11.10" - -globals@^11.1.0: - version "11.12.0" - resolved "https://registry.yarnpkg.com/globals/-/globals-11.12.0.tgz#ab8795338868a0babd8525758018c2a7eb95c42e" - integrity sha512-WOBp/EEGUiIsJSp7wcv/y6MO+lV9UoncWqxuFfm8eBwzWNgyfBd6Gz+IeKQ9jCmyhoH99g15M3T+QaVHFjizVA== - -globby@^6.1.0: - version "6.1.0" - resolved "https://registry.yarnpkg.com/globby/-/globby-6.1.0.tgz#f5a6d70e8395e21c858fb0489d64df02424d506c" - integrity sha1-9abXDoOV4hyFj7BInWTfAkJNUGw= - dependencies: - array-union "^1.0.1" - glob "^7.0.3" - object-assign "^4.0.1" - pify "^2.0.0" - pinkie-promise "^2.0.0" - -globby@^7.1.1: - version "7.1.1" - resolved "https://registry.yarnpkg.com/globby/-/globby-7.1.1.tgz#fb2ccff9401f8600945dfada97440cca972b8680" - integrity sha1-+yzP+UAfhgCUXfral0QMypcrhoA= - dependencies: - array-union "^1.0.1" - dir-glob "^2.0.0" - glob "^7.1.2" - ignore "^3.3.5" - pify "^3.0.0" - slash "^1.0.0" - -globby@^9.2.0: - version "9.2.0" - resolved "https://registry.yarnpkg.com/globby/-/globby-9.2.0.tgz#fd029a706c703d29bdd170f4b6db3a3f7a7cb63d" - integrity sha512-ollPHROa5mcxDEkwg6bPt3QbEf4pDQSNtd6JPL1YvOvAo/7/0VAm9TccUeoTmarjPw4pfUthSCqcyfNB1I3ZSg== - dependencies: - "@types/glob" "^7.1.1" - array-union "^1.0.2" - dir-glob "^2.2.2" - fast-glob "^2.2.6" - glob "^7.1.3" - ignore "^4.0.3" - pify "^4.0.1" - slash "^2.0.0" - -good-listener@^1.2.2: - version "1.2.2" - resolved "https://registry.yarnpkg.com/good-listener/-/good-listener-1.2.2.tgz#d53b30cdf9313dffb7dc9a0d477096aa6d145c50" - integrity sha1-1TswzfkxPf+33JoNR3CWqm0UXFA= - dependencies: - delegate "^3.1.2" - -graceful-fs@^4.1.11, graceful-fs@^4.1.15, graceful-fs@^4.1.2, graceful-fs@^4.1.6: - version "4.2.0" - resolved "https://registry.yarnpkg.com/graceful-fs/-/graceful-fs-4.2.0.tgz#8d8fdc73977cb04104721cb53666c1ca64cd328b" - integrity sha512-jpSvDPV4Cq/bgtpndIWbI5hmYxhQGHPC4d4cqBPb4DLniCfhJokdXhwhaDuLBGLQdvvRum/UiX6ECVIPvDXqdg== - -gray-matter@^4.0.1: - version "4.0.2" - resolved "https://registry.yarnpkg.com/gray-matter/-/gray-matter-4.0.2.tgz#9aa379e3acaf421193fce7d2a28cebd4518ac454" - integrity sha512-7hB/+LxrOjq/dd8APlK0r24uL/67w7SkYnfwhNFwg/VDIGWGmduTDYf3WNstLW2fbbmRwrDGCVSJ2isuf2+4Hw== - dependencies: - js-yaml "^3.11.0" - kind-of "^6.0.2" - section-matter "^1.0.0" - strip-bom-string "^1.0.0" - -handle-thing@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/handle-thing/-/handle-thing-2.0.0.tgz#0e039695ff50c93fc288557d696f3c1dc6776754" - integrity sha512-d4sze1JNC454Wdo2fkuyzCr6aHcbL6PGGuFAz0Li/NcOm1tCHGnWDRmJP85dh9IhQErTc2svWFEX5xHIOo//kQ== - -har-schema@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/har-schema/-/har-schema-2.0.0.tgz#a94c2224ebcac04782a0d9035521f24735b7ec92" - integrity sha1-qUwiJOvKwEeCoNkDVSHyRzW37JI= - -har-validator@~5.1.0: - version "5.1.3" - resolved "https://registry.yarnpkg.com/har-validator/-/har-validator-5.1.3.tgz#1ef89ebd3e4996557675eed9893110dc350fa080" - integrity sha512-sNvOCzEQNr/qrvJgc3UG/kD4QtlHycrzwS+6mfTrrSq97BvaYcPZZI1ZSqGSPR73Cxn4LKTD4PttRwfU7jWq5g== - dependencies: - ajv "^6.5.5" - har-schema "^2.0.0" - -has-ansi@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/has-ansi/-/has-ansi-2.0.0.tgz#34f5049ce1ecdf2b0649af3ef24e45ed35416d91" - integrity sha1-NPUEnOHs3ysGSa8+8k5F7TVBbZE= - dependencies: - ansi-regex "^2.0.0" - -has-flag@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/has-flag/-/has-flag-3.0.0.tgz#b5d454dc2199ae225699f3467e5a07f3b955bafd" - integrity sha1-tdRU3CGZriJWmfNGfloH87lVuv0= - -has-symbols@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/has-symbols/-/has-symbols-1.0.0.tgz#ba1a8f1af2a0fc39650f5c850367704122063b44" - integrity sha1-uhqPGvKg/DllD1yFA2dwQSIGO0Q= - -has-unicode@^2.0.0: - version "2.0.1" - resolved "https://registry.yarnpkg.com/has-unicode/-/has-unicode-2.0.1.tgz#e0e6fe6a28cf51138855e086d1691e771de2a8b9" - integrity sha1-4Ob+aijPUROIVeCG0Wkedx3iqLk= - -has-value@^0.3.1: - version "0.3.1" - resolved "https://registry.yarnpkg.com/has-value/-/has-value-0.3.1.tgz#7b1f58bada62ca827ec0a2078025654845995e1f" - integrity sha1-ex9YutpiyoJ+wKIHgCVlSEWZXh8= - dependencies: - get-value "^2.0.3" - has-values "^0.1.4" - isobject "^2.0.0" - -has-value@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/has-value/-/has-value-1.0.0.tgz#18b281da585b1c5c51def24c930ed29a0be6b177" - integrity sha1-GLKB2lhbHFxR3vJMkw7SmgvmsXc= - dependencies: - get-value "^2.0.6" - has-values "^1.0.0" - isobject "^3.0.0" - -has-values@^0.1.4: - version "0.1.4" - resolved "https://registry.yarnpkg.com/has-values/-/has-values-0.1.4.tgz#6d61de95d91dfca9b9a02089ad384bff8f62b771" - integrity sha1-bWHeldkd/Km5oCCJrThL/49it3E= - -has-values@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/has-values/-/has-values-1.0.0.tgz#95b0b63fec2146619a6fe57fe75628d5a39efe4f" - integrity sha1-lbC2P+whRmGab+V/51Yo1aOe/k8= - dependencies: - is-number "^3.0.0" - kind-of "^4.0.0" - -has@^1.0.0, has@^1.0.1, has@^1.0.3: - version "1.0.3" - resolved "https://registry.yarnpkg.com/has/-/has-1.0.3.tgz#722d7cbfc1f6aa8241f16dd814e011e1f41e8796" - integrity sha512-f2dvO0VU6Oej7RkWJGrehjbzMAjFp5/VKPp5tTpWIV4JHHZK1/BxbFRtf/siA2SWTe09caDmVtYYzWEIbBS4zw== - dependencies: - function-bind "^1.1.1" - -hash-base@^3.0.0: - version "3.0.4" - resolved "https://registry.yarnpkg.com/hash-base/-/hash-base-3.0.4.tgz#5fc8686847ecd73499403319a6b0a3f3f6ae4918" - integrity sha1-X8hoaEfs1zSZQDMZprCj8/auSRg= - dependencies: - inherits "^2.0.1" - safe-buffer "^5.0.1" - -hash-sum@^1.0.2: - version "1.0.2" - resolved "https://registry.yarnpkg.com/hash-sum/-/hash-sum-1.0.2.tgz#33b40777754c6432573c120cc3808bbd10d47f04" - integrity sha1-M7QHd3VMZDJXPBIMw4CLvRDUfwQ= - -hash.js@^1.0.0, hash.js@^1.0.3: - version "1.1.7" - resolved "https://registry.yarnpkg.com/hash.js/-/hash.js-1.1.7.tgz#0babca538e8d4ee4a0f8988d68866537a003cf42" - integrity sha512-taOaskGt4z4SOANNseOviYDvjEJinIkRgmp7LbKP2YTTmVxWBl87s/uzK9r+44BclBSp2X7K1hqeNfz9JbBeXA== - dependencies: - inherits "^2.0.3" - minimalistic-assert "^1.0.1" - -he@1.2.x, he@^1.1.0: - version "1.2.0" - resolved "https://registry.yarnpkg.com/he/-/he-1.2.0.tgz#84ae65fa7eafb165fddb61566ae14baf05664f0f" - integrity sha512-F/1DnUGPopORZi0ni+CvrCgHQ5FyEAHRLSApuYWMmrbSwoN2Mn/7k+Gl38gJnR7yyDZk6WLXwiGod1JOWNDKGw== - -hex-color-regex@^1.1.0: - version "1.1.0" - resolved "https://registry.yarnpkg.com/hex-color-regex/-/hex-color-regex-1.1.0.tgz#4c06fccb4602fe2602b3c93df82d7e7dbf1a8a8e" - integrity sha512-l9sfDFsuqtOqKDsQdqrMRk0U85RZc0RtOR9yPI7mRVOa4FsR/BVnZ0shmQRM96Ji99kYZP/7hn1cedc1+ApsTQ== - -hmac-drbg@^1.0.0: - version "1.0.1" - resolved "https://registry.yarnpkg.com/hmac-drbg/-/hmac-drbg-1.0.1.tgz#d2745701025a6c775a6c545793ed502fc0c649a1" - integrity sha1-0nRXAQJabHdabFRXk+1QL8DGSaE= - dependencies: - hash.js "^1.0.3" - minimalistic-assert "^1.0.0" - minimalistic-crypto-utils "^1.0.1" - -hogan.js@^3.0.2: - version "3.0.2" - resolved "https://registry.yarnpkg.com/hogan.js/-/hogan.js-3.0.2.tgz#4cd9e1abd4294146e7679e41d7898732b02c7bfd" - integrity sha1-TNnhq9QpQUbnZ55B14mHMrAse/0= - dependencies: - mkdirp "0.3.0" - nopt "1.0.10" - -hpack.js@^2.1.6: - version "2.1.6" - resolved "https://registry.yarnpkg.com/hpack.js/-/hpack.js-2.1.6.tgz#87774c0949e513f42e84575b3c45681fade2a0b2" - integrity sha1-h3dMCUnlE/QuhFdbPEVoH63ioLI= - dependencies: - inherits "^2.0.1" - obuf "^1.0.0" - readable-stream "^2.0.1" - wbuf "^1.1.0" - -hsl-regex@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/hsl-regex/-/hsl-regex-1.0.0.tgz#d49330c789ed819e276a4c0d272dffa30b18fe6e" - integrity sha1-1JMwx4ntgZ4nakwNJy3/owsY/m4= - -hsla-regex@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/hsla-regex/-/hsla-regex-1.0.0.tgz#c1ce7a3168c8c6614033a4b5f7877f3b225f9c38" - integrity sha1-wc56MWjIxmFAM6S194d/OyJfnDg= - -html-comment-regex@^1.1.0: - version "1.1.2" - resolved "https://registry.yarnpkg.com/html-comment-regex/-/html-comment-regex-1.1.2.tgz#97d4688aeb5c81886a364faa0cad1dda14d433a7" - integrity sha512-P+M65QY2JQ5Y0G9KKdlDpo0zK+/OHptU5AaBwUfAIDJZk1MYf32Frm84EcOytfJE0t5JvkAnKlmjsXDnWzCJmQ== - -html-entities@^1.2.1: - version "1.2.1" - resolved "https://registry.yarnpkg.com/html-entities/-/html-entities-1.2.1.tgz#0df29351f0721163515dfb9e5543e5f6eed5162f" - integrity sha1-DfKTUfByEWNRXfueVUPl9u7VFi8= - -html-minifier@^3.2.3: - version "3.5.21" - resolved "https://registry.yarnpkg.com/html-minifier/-/html-minifier-3.5.21.tgz#d0040e054730e354db008463593194015212d20c" - integrity sha512-LKUKwuJDhxNa3uf/LPR/KVjm/l3rBqtYeCOAekvG8F1vItxMUpueGd94i/asDDr8/1u7InxzFA5EeGjhhG5mMA== - dependencies: - camel-case "3.0.x" - clean-css "4.2.x" - commander "2.17.x" - he "1.2.x" - param-case "2.1.x" - relateurl "0.2.x" - uglify-js "3.4.x" - -html-tags@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/html-tags/-/html-tags-2.0.0.tgz#10b30a386085f43cede353cc8fa7cb0deeea668b" - integrity sha1-ELMKOGCF9Dzt41PMj6fLDe7qZos= - -htmlparser2@^3.3.0: - version "3.10.1" - resolved "https://registry.yarnpkg.com/htmlparser2/-/htmlparser2-3.10.1.tgz#bd679dc3f59897b6a34bb10749c855bb53a9392f" - integrity sha512-IgieNijUMbkDovyoKObU1DUhm1iwNYE/fuifEoEHfd1oZKZDaONBSkal7Y01shxsM49R4XaMdGez3WnF9UfiCQ== - dependencies: - domelementtype "^1.3.1" - domhandler "^2.3.0" - domutils "^1.5.1" - entities "^1.1.1" - inherits "^2.0.1" - readable-stream "^3.1.1" - -http-deceiver@^1.2.7: - version "1.2.7" - resolved "https://registry.yarnpkg.com/http-deceiver/-/http-deceiver-1.2.7.tgz#fa7168944ab9a519d337cb0bec7284dc3e723d87" - integrity sha1-+nFolEq5pRnTN8sL7HKE3D5yPYc= - -http-errors@1.7.2: - version "1.7.2" - resolved "https://registry.yarnpkg.com/http-errors/-/http-errors-1.7.2.tgz#4f5029cf13239f31036e5b2e55292bcfbcc85c8f" - integrity sha512-uUQBt3H/cSIVfch6i1EuPNy/YsRSOUBXTVfZ+yR7Zjez3qjBz6i9+i4zjNaoqcoFVI4lQJ5plg63TvGfRSDCRg== - dependencies: - depd "~1.1.2" - inherits "2.0.3" - setprototypeof "1.1.1" - statuses ">= 1.5.0 < 2" - toidentifier "1.0.0" - -http-errors@~1.6.2: - version "1.6.3" - resolved "https://registry.yarnpkg.com/http-errors/-/http-errors-1.6.3.tgz#8b55680bb4be283a0b5bf4ea2e38580be1d9320d" - integrity sha1-i1VoC7S+KDoLW/TqLjhYC+HZMg0= - dependencies: - depd "~1.1.2" - inherits "2.0.3" - setprototypeof "1.1.0" - statuses ">= 1.4.0 < 2" - -http-errors@~1.7.2: - version "1.7.3" - resolved "https://registry.yarnpkg.com/http-errors/-/http-errors-1.7.3.tgz#6c619e4f9c60308c38519498c14fbb10aacebb06" - integrity sha512-ZTTX0MWrsQ2ZAhA1cejAwDLycFsd7I7nVtnkT3Ol0aqodaKW+0CTZDQ1uBv5whptCnc8e8HeRRJxRs0kmm/Qfw== - dependencies: - depd "~1.1.2" - inherits "2.0.4" - setprototypeof "1.1.1" - statuses ">= 1.5.0 < 2" - toidentifier "1.0.0" - -"http-parser-js@>=0.4.0 <0.4.11": - version "0.4.10" - resolved "https://registry.yarnpkg.com/http-parser-js/-/http-parser-js-0.4.10.tgz#92c9c1374c35085f75db359ec56cc257cbb93fa4" - integrity sha1-ksnBN0w1CF912zWexWzCV8u5P6Q= - -http-proxy-middleware@^0.19.1: - version "0.19.1" - resolved "https://registry.yarnpkg.com/http-proxy-middleware/-/http-proxy-middleware-0.19.1.tgz#183c7dc4aa1479150306498c210cdaf96080a43a" - integrity sha512-yHYTgWMQO8VvwNS22eLLloAkvungsKdKTLO8AJlftYIKNfJr3GK3zK0ZCfzDDGUBttdGc8xFy1mCitvNKQtC3Q== - dependencies: - http-proxy "^1.17.0" - is-glob "^4.0.0" - lodash "^4.17.11" - micromatch "^3.1.10" - -http-proxy@^1.17.0: - version "1.17.0" - resolved "https://registry.yarnpkg.com/http-proxy/-/http-proxy-1.17.0.tgz#7ad38494658f84605e2f6db4436df410f4e5be9a" - integrity sha512-Taqn+3nNvYRfJ3bGvKfBSRwy1v6eePlm3oc/aWVxZp57DQr5Eq3xhKJi7Z4hZpS8PC3H4qI+Yly5EmFacGuA/g== - dependencies: - eventemitter3 "^3.0.0" - follow-redirects "^1.0.0" - requires-port "^1.0.0" - -http-signature@~1.2.0: - version "1.2.0" - resolved "https://registry.yarnpkg.com/http-signature/-/http-signature-1.2.0.tgz#9aecd925114772f3d95b65a60abb8f7c18fbace1" - integrity sha1-muzZJRFHcvPZW2WmCruPfBj7rOE= - dependencies: - assert-plus "^1.0.0" - jsprim "^1.2.2" - sshpk "^1.7.0" - -https-browserify@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/https-browserify/-/https-browserify-1.0.0.tgz#ec06c10e0a34c0f2faf199f7fd7fc78fffd03c73" - integrity sha1-7AbBDgo0wPL68Zn3/X/Hj//QPHM= - -iconv-lite@0.4.24, iconv-lite@^0.4.4: - version "0.4.24" - resolved "https://registry.yarnpkg.com/iconv-lite/-/iconv-lite-0.4.24.tgz#2022b4b25fbddc21d2f524974a474aafe733908b" - integrity sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA== - dependencies: - safer-buffer ">= 2.1.2 < 3" - -icss-replace-symbols@^1.1.0: - version "1.1.0" - resolved "https://registry.yarnpkg.com/icss-replace-symbols/-/icss-replace-symbols-1.1.0.tgz#06ea6f83679a7749e386cfe1fe812ae5db223ded" - integrity sha1-Bupvg2ead0njhs/h/oEq5dsiPe0= - -icss-utils@^4.1.0: - version "4.1.1" - resolved "https://registry.yarnpkg.com/icss-utils/-/icss-utils-4.1.1.tgz#21170b53789ee27447c2f47dd683081403f9a467" - integrity sha512-4aFq7wvWyMHKgxsH8QQtGpvbASCf+eM3wPRLI6R+MgAnTCZ6STYsRvttLvRWK0Nfif5piF394St3HeJDaljGPA== - dependencies: - postcss "^7.0.14" - -ieee754@^1.1.4: - version "1.1.13" - resolved "https://registry.yarnpkg.com/ieee754/-/ieee754-1.1.13.tgz#ec168558e95aa181fd87d37f55c32bbcb6708b84" - integrity sha512-4vf7I2LYV/HaWerSo3XmlMkp5eZ83i+/CDluXi/IGTs/O1sejBNhTtnxzmRZfvOUqj7lZjqHkeTvpgSFDlWZTg== - -iferr@^0.1.5: - version "0.1.5" - resolved "https://registry.yarnpkg.com/iferr/-/iferr-0.1.5.tgz#c60eed69e6d8fdb6b3104a1fcbca1c192dc5b501" - integrity sha1-xg7taebY/bazEEofy8ocGS3FtQE= - -ignore-walk@^3.0.1: - version "3.0.1" - resolved "https://registry.yarnpkg.com/ignore-walk/-/ignore-walk-3.0.1.tgz#a83e62e7d272ac0e3b551aaa82831a19b69f82f8" - integrity sha512-DTVlMx3IYPe0/JJcYP7Gxg7ttZZu3IInhuEhbchuqneY9wWe5Ojy2mXLBaQFUQmo0AW2r3qG7m1mg86js+gnlQ== - dependencies: - minimatch "^3.0.4" - -ignore@^3.3.5: - version "3.3.10" - resolved "https://registry.yarnpkg.com/ignore/-/ignore-3.3.10.tgz#0a97fb876986e8081c631160f8f9f389157f0043" - integrity sha512-Pgs951kaMm5GXP7MOvxERINe3gsaVjUWFm+UZPSq9xYriQAksyhg0csnS0KXSNRD5NmNdapXEpjxG49+AKh/ug== - -ignore@^4.0.3: - version "4.0.6" - resolved "https://registry.yarnpkg.com/ignore/-/ignore-4.0.6.tgz#750e3db5862087b4737ebac8207ffd1ef27b25fc" - integrity sha512-cyFDKrqc/YdcWFniJhzI42+AzS+gNwmUzOSFcRCQYwySuBBBy/KjuxWLZ/FHEH6Moq1NizMOBWyTcv8O4OZIMg== - -immediate@^3.2.3: - version "3.2.3" - resolved "https://registry.yarnpkg.com/immediate/-/immediate-3.2.3.tgz#d140fa8f614659bd6541233097ddaac25cdd991c" - integrity sha1-0UD6j2FGWb1lQSMwl92qwlzdmRw= - -import-cwd@^2.0.0: - version "2.1.0" - resolved "https://registry.yarnpkg.com/import-cwd/-/import-cwd-2.1.0.tgz#aa6cf36e722761285cb371ec6519f53e2435b0a9" - integrity sha1-qmzzbnInYShcs3HsZRn1PiQ1sKk= - dependencies: - import-from "^2.1.0" - -import-fresh@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/import-fresh/-/import-fresh-2.0.0.tgz#d81355c15612d386c61f9ddd3922d4304822a546" - integrity sha1-2BNVwVYS04bGH53dOSLUMEgipUY= - dependencies: - caller-path "^2.0.0" - resolve-from "^3.0.0" - -import-from@^2.1.0: - version "2.1.0" - resolved "https://registry.yarnpkg.com/import-from/-/import-from-2.1.0.tgz#335db7f2a7affd53aaa471d4b8021dee36b7f3b1" - integrity sha1-M1238qev/VOqpHHUuAId7ja387E= - dependencies: - resolve-from "^3.0.0" - -import-local@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/import-local/-/import-local-2.0.0.tgz#55070be38a5993cf18ef6db7e961f5bee5c5a09d" - integrity sha512-b6s04m3O+s3CGSbqDIyP4R6aAwAeYlVq9+WUWep6iHa8ETRf9yei1U48C5MmfJmV9AiLYYBKPMq/W+/WRpQmCQ== - dependencies: - pkg-dir "^3.0.0" - resolve-cwd "^2.0.0" - -imurmurhash@^0.1.4: - version "0.1.4" - resolved "https://registry.yarnpkg.com/imurmurhash/-/imurmurhash-0.1.4.tgz#9218b9b2b928a238b13dc4fb6b6d576f231453ea" - integrity sha1-khi5srkoojixPcT7a21XbyMUU+o= - -indexes-of@^1.0.1: - version "1.0.1" - resolved "https://registry.yarnpkg.com/indexes-of/-/indexes-of-1.0.1.tgz#f30f716c8e2bd346c7b67d3df3915566a7c05607" - integrity sha1-8w9xbI4r00bHtn0985FVZqfAVgc= - -inflight@^1.0.4: - version "1.0.6" - resolved "https://registry.yarnpkg.com/inflight/-/inflight-1.0.6.tgz#49bd6331d7d02d0c09bc910a1075ba8165b56df9" - integrity sha1-Sb1jMdfQLQwJvJEKEHW6gWW1bfk= - dependencies: - once "^1.3.0" - wrappy "1" - -inherits@2, inherits@2.0.4, inherits@^2.0.1, inherits@^2.0.3, inherits@~2.0.1, inherits@~2.0.3: - version "2.0.4" - resolved "https://registry.yarnpkg.com/inherits/-/inherits-2.0.4.tgz#0fa2c64f932917c3433a0ded55363aae37416b7c" - integrity sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ== - -inherits@2.0.1: - version "2.0.1" - resolved "https://registry.yarnpkg.com/inherits/-/inherits-2.0.1.tgz#b17d08d326b4423e568eff719f91b0b1cbdf69f1" - integrity sha1-sX0I0ya0Qj5Wjv9xn5GwscvfafE= - -inherits@2.0.3: - version "2.0.3" - resolved "https://registry.yarnpkg.com/inherits/-/inherits-2.0.3.tgz#633c2c83e3da42a502f52466022480f4208261de" - integrity sha1-Yzwsg+PaQqUC9SRmAiSA9CCCYd4= - -ini@~1.3.0: - version "1.3.5" - resolved "https://registry.yarnpkg.com/ini/-/ini-1.3.5.tgz#eee25f56db1c9ec6085e0c22778083f596abf927" - integrity sha512-RZY5huIKCMRWDUqZlEi72f/lmXKMvuszcMBduliQ3nnWbx9X/ZBQO7DijMEYS9EhHBb2qacRUMtC7svLwe0lcw== - -internal-ip@^4.3.0: - version "4.3.0" - resolved "https://registry.yarnpkg.com/internal-ip/-/internal-ip-4.3.0.tgz#845452baad9d2ca3b69c635a137acb9a0dad0907" - integrity sha512-S1zBo1D6zcsyuC6PMmY5+55YMILQ9av8lotMx447Bq6SAgo/sDK6y6uUKmuYhW7eacnIhFfsPmCNYdDzsnnDCg== - dependencies: - default-gateway "^4.2.0" - ipaddr.js "^1.9.0" - -invariant@^2.2.2: - version "2.2.4" - resolved "https://registry.yarnpkg.com/invariant/-/invariant-2.2.4.tgz#610f3c92c9359ce1db616e538008d23ff35158e6" - integrity sha512-phJfQVBuaJM5raOpJjSfkiD6BpbCE4Ns//LaXl6wGYtUBY83nWS6Rf9tXm2e8VaK60JEjYldbPif/A2B1C2gNA== - dependencies: - loose-envify "^1.0.0" - -invert-kv@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/invert-kv/-/invert-kv-2.0.0.tgz#7393f5afa59ec9ff5f67a27620d11c226e3eec02" - integrity sha512-wPVv/y/QQ/Uiirj/vh3oP+1Ww+AWehmi1g5fFWGPF6IpCBCDVrhgHRMvrLfdYcwDh3QJbGXDW4JAuzxElLSqKA== - -ip-regex@^2.1.0: - version "2.1.0" - resolved "https://registry.yarnpkg.com/ip-regex/-/ip-regex-2.1.0.tgz#fa78bf5d2e6913c911ce9f819ee5146bb6d844e9" - integrity sha1-+ni/XS5pE8kRzp+BnuUUa7bYROk= - -ip@^1.1.0, ip@^1.1.5: - version "1.1.5" - resolved "https://registry.yarnpkg.com/ip/-/ip-1.1.5.tgz#bdded70114290828c0a039e72ef25f5aaec4354a" - integrity sha1-vd7XARQpCCjAoDnnLvJfWq7ENUo= - -ipaddr.js@1.9.0: - version "1.9.0" - resolved "https://registry.yarnpkg.com/ipaddr.js/-/ipaddr.js-1.9.0.tgz#37df74e430a0e47550fe54a2defe30d8acd95f65" - integrity sha512-M4Sjn6N/+O6/IXSJseKqHoFc+5FdGJ22sXqnjTpdZweHK64MzEPAyQZyEU3R/KRv2GLoa7nNtg/C2Ev6m7z+eA== - -ipaddr.js@^1.9.0: - version "1.9.1" - resolved "https://registry.yarnpkg.com/ipaddr.js/-/ipaddr.js-1.9.1.tgz#bff38543eeb8984825079ff3a2a8e6cbd46781b3" - integrity sha512-0KI/607xoxSToH7GjN1FfSbLoU0+btTicjsQSWQlh/hZykN8KpmMf7uYwPW3R+akZ6R/w18ZlXSHBYXiYUPO3g== - -is-absolute-url@^2.0.0: - version "2.1.0" - resolved "https://registry.yarnpkg.com/is-absolute-url/-/is-absolute-url-2.1.0.tgz#50530dfb84fcc9aa7dbe7852e83a37b93b9f2aa6" - integrity sha1-UFMN+4T8yap9vnhS6Do3uTufKqY= - -is-accessor-descriptor@^0.1.6: - version "0.1.6" - resolved "https://registry.yarnpkg.com/is-accessor-descriptor/-/is-accessor-descriptor-0.1.6.tgz#a9e12cb3ae8d876727eeef3843f8a0897b5c98d6" - integrity sha1-qeEss66Nh2cn7u84Q/igiXtcmNY= - dependencies: - kind-of "^3.0.2" - -is-accessor-descriptor@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/is-accessor-descriptor/-/is-accessor-descriptor-1.0.0.tgz#169c2f6d3df1f992618072365c9b0ea1f6878656" - integrity sha512-m5hnHTkcVsPfqx3AKlyttIPb7J+XykHvJP2B9bZDjlhLIoEq4XoK64Vg7boZlVWYK6LUY94dYPEE7Lh0ZkZKcQ== - dependencies: - kind-of "^6.0.0" - -is-arrayish@^0.2.1: - version "0.2.1" - resolved "https://registry.yarnpkg.com/is-arrayish/-/is-arrayish-0.2.1.tgz#77c99840527aa8ecb1a8ba697b80645a7a926a9d" - integrity sha1-d8mYQFJ6qOyxqLppe4BkWnqSap0= - -is-arrayish@^0.3.1: - version "0.3.2" - resolved "https://registry.yarnpkg.com/is-arrayish/-/is-arrayish-0.3.2.tgz#4574a2ae56f7ab206896fb431eaeed066fdf8f03" - integrity sha512-eVRqCvVlZbuw3GrM63ovNSNAeA1K16kaR/LRY/92w0zxQ5/1YzwblUX652i4Xs9RwAGjW9d9y6X88t8OaAJfWQ== - -is-binary-path@^1.0.0: - version "1.0.1" - resolved "https://registry.yarnpkg.com/is-binary-path/-/is-binary-path-1.0.1.tgz#75f16642b480f187a711c814161fd3a4a7655898" - integrity sha1-dfFmQrSA8YenEcgUFh/TpKdlWJg= - dependencies: - binary-extensions "^1.0.0" - -is-buffer@^1.1.5: - version "1.1.6" - resolved "https://registry.yarnpkg.com/is-buffer/-/is-buffer-1.1.6.tgz#efaa2ea9daa0d7ab2ea13a97b2b8ad51fefbe8be" - integrity sha512-NcdALwpXkTm5Zvvbk7owOUSvVvBKDgKP5/ewfXEznmQFfs4ZRmanOeKBTjRVjka3QFoN6XJ+9F3USqfHqTaU5w== - -is-buffer@^2.0.2: - version "2.0.3" - resolved "https://registry.yarnpkg.com/is-buffer/-/is-buffer-2.0.3.tgz#4ecf3fcf749cbd1e472689e109ac66261a25e725" - integrity sha512-U15Q7MXTuZlrbymiz95PJpZxu8IlipAp4dtS3wOdgPXx3mqBnslrWU14kxfHB+Py/+2PVKSr37dMAgM2A4uArw== - -is-callable@^1.1.4: - version "1.1.4" - resolved "https://registry.yarnpkg.com/is-callable/-/is-callable-1.1.4.tgz#1e1adf219e1eeb684d691f9d6a05ff0d30a24d75" - integrity sha512-r5p9sxJjYnArLjObpjA4xu5EKI3CuKHkJXMhT7kwbpUyIFD1n5PMAsoPvWnvtZiNz7LjkYDRZhd7FlI0eMijEA== - -is-color-stop@^1.0.0: - version "1.1.0" - resolved "https://registry.yarnpkg.com/is-color-stop/-/is-color-stop-1.1.0.tgz#cfff471aee4dd5c9e158598fbe12967b5cdad345" - integrity sha1-z/9HGu5N1cnhWFmPvhKWe1za00U= - dependencies: - css-color-names "^0.0.4" - hex-color-regex "^1.1.0" - hsl-regex "^1.0.0" - hsla-regex "^1.0.0" - rgb-regex "^1.0.1" - rgba-regex "^1.0.0" - -is-data-descriptor@^0.1.4: - version "0.1.4" - resolved "https://registry.yarnpkg.com/is-data-descriptor/-/is-data-descriptor-0.1.4.tgz#0b5ee648388e2c860282e793f1856fec3f301b56" - integrity sha1-C17mSDiOLIYCgueT8YVv7D8wG1Y= - dependencies: - kind-of "^3.0.2" - -is-data-descriptor@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/is-data-descriptor/-/is-data-descriptor-1.0.0.tgz#d84876321d0e7add03990406abbbbd36ba9268c7" - integrity sha512-jbRXy1FmtAoCjQkVmIVYwuuqDFUbaOeDjmed1tOGPrsMhtJA4rD9tkgA0F1qJ3gRFRXcHYVkdeaP50Q5rE/jLQ== - dependencies: - kind-of "^6.0.0" - -is-date-object@^1.0.1: - version "1.0.1" - resolved "https://registry.yarnpkg.com/is-date-object/-/is-date-object-1.0.1.tgz#9aa20eb6aeebbff77fbd33e74ca01b33581d3a16" - integrity sha1-mqIOtq7rv/d/vTPnTKAbM1gdOhY= - -is-descriptor@^0.1.0: - version "0.1.6" - resolved "https://registry.yarnpkg.com/is-descriptor/-/is-descriptor-0.1.6.tgz#366d8240dde487ca51823b1ab9f07a10a78251ca" - integrity sha512-avDYr0SB3DwO9zsMov0gKCESFYqCnE4hq/4z3TdUlukEy5t9C0YRq7HLrsN52NAcqXKaepeCD0n+B0arnVG3Hg== - dependencies: - is-accessor-descriptor "^0.1.6" - is-data-descriptor "^0.1.4" - kind-of "^5.0.0" - -is-descriptor@^1.0.0, is-descriptor@^1.0.2: - version "1.0.2" - resolved "https://registry.yarnpkg.com/is-descriptor/-/is-descriptor-1.0.2.tgz#3b159746a66604b04f8c81524ba365c5f14d86ec" - integrity sha512-2eis5WqQGV7peooDyLmNEPUrps9+SXX5c9pL3xEB+4e9HnGuDa7mB7kHxHw4CbqS9k1T2hOH3miL8n8WtiYVtg== - dependencies: - is-accessor-descriptor "^1.0.0" - is-data-descriptor "^1.0.0" - kind-of "^6.0.2" - -is-directory@^0.3.1: - version "0.3.1" - resolved "https://registry.yarnpkg.com/is-directory/-/is-directory-0.3.1.tgz#61339b6f2475fc772fd9c9d83f5c8575dc154ae1" - integrity sha1-YTObbyR1/Hcv2cnYP1yFddwVSuE= - -is-extendable@^0.1.0, is-extendable@^0.1.1: - version "0.1.1" - resolved "https://registry.yarnpkg.com/is-extendable/-/is-extendable-0.1.1.tgz#62b110e289a471418e3ec36a617d472e301dfc89" - integrity sha1-YrEQ4omkcUGOPsNqYX1HLjAd/Ik= - -is-extendable@^1.0.1: - version "1.0.1" - resolved "https://registry.yarnpkg.com/is-extendable/-/is-extendable-1.0.1.tgz#a7470f9e426733d81bd81e1155264e3a3507cab4" - integrity sha512-arnXMxT1hhoKo9k1LZdmlNyJdDDfy2v0fXjFlmok4+i8ul/6WlbVge9bhM74OpNPQPMGUToDtz+KXa1PneJxOA== - dependencies: - is-plain-object "^2.0.4" - -is-extglob@^2.1.0, is-extglob@^2.1.1: - version "2.1.1" - resolved "https://registry.yarnpkg.com/is-extglob/-/is-extglob-2.1.1.tgz#a88c02535791f02ed37c76a1b9ea9773c833f8c2" - integrity sha1-qIwCU1eR8C7TfHahueqXc8gz+MI= - -is-fullwidth-code-point@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/is-fullwidth-code-point/-/is-fullwidth-code-point-1.0.0.tgz#ef9e31386f031a7f0d643af82fde50c457ef00cb" - integrity sha1-754xOG8DGn8NZDr4L95QxFfvAMs= - dependencies: - number-is-nan "^1.0.0" - -is-fullwidth-code-point@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz#a3b30a5c4f199183167aaab93beefae3ddfb654f" - integrity sha1-o7MKXE8ZkYMWeqq5O+764937ZU8= - -is-glob@^3.1.0: - version "3.1.0" - resolved "https://registry.yarnpkg.com/is-glob/-/is-glob-3.1.0.tgz#7ba5ae24217804ac70707b96922567486cc3e84a" - integrity sha1-e6WuJCF4BKxwcHuWkiVnSGzD6Eo= - dependencies: - is-extglob "^2.1.0" - -is-glob@^4.0.0, is-glob@^4.0.1: - version "4.0.1" - resolved "https://registry.yarnpkg.com/is-glob/-/is-glob-4.0.1.tgz#7567dbe9f2f5e2467bc77ab83c4a29482407a5dc" - integrity sha512-5G0tKtBTFImOqDnLB2hG6Bp2qcKEFduo4tZu9MT/H6NQv/ghhy30o55ufafxJ/LdH79LLs2Kfrn85TLKyA7BUg== - dependencies: - is-extglob "^2.1.1" - -is-number@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/is-number/-/is-number-3.0.0.tgz#24fd6201a4782cf50561c810276afc7d12d71195" - integrity sha1-JP1iAaR4LPUFYcgQJ2r8fRLXEZU= - dependencies: - kind-of "^3.0.2" - -is-obj@^1.0.0: - version "1.0.1" - resolved "https://registry.yarnpkg.com/is-obj/-/is-obj-1.0.1.tgz#3e4729ac1f5fde025cd7d83a896dab9f4f67db0f" - integrity sha1-PkcprB9f3gJc19g6iW2rn09n2w8= - -is-path-cwd@^2.0.0: - version "2.2.0" - resolved "https://registry.yarnpkg.com/is-path-cwd/-/is-path-cwd-2.2.0.tgz#67d43b82664a7b5191fd9119127eb300048a9fdb" - integrity sha512-w942bTcih8fdJPJmQHFzkS76NEP8Kzzvmw92cXsazb8intwLqPibPPdXf4ANdKV3rYMuuQYGIWtvz9JilB3NFQ== - -is-path-in-cwd@^2.0.0: - version "2.1.0" - resolved "https://registry.yarnpkg.com/is-path-in-cwd/-/is-path-in-cwd-2.1.0.tgz#bfe2dca26c69f397265a4009963602935a053acb" - integrity sha512-rNocXHgipO+rvnP6dk3zI20RpOtrAM/kzbB258Uw5BWr3TpXi861yzjo16Dn4hUox07iw5AyeMLHWsujkjzvRQ== - dependencies: - is-path-inside "^2.1.0" - -is-path-inside@^2.1.0: - version "2.1.0" - resolved "https://registry.yarnpkg.com/is-path-inside/-/is-path-inside-2.1.0.tgz#7c9810587d659a40d27bcdb4d5616eab059494b2" - integrity sha512-wiyhTzfDWsvwAW53OBWF5zuvaOGlZ6PwYxAbPVDhpm+gM09xKQGjBq/8uYN12aDvMxnAnq3dxTyoSoRNmg5YFg== - dependencies: - path-is-inside "^1.0.2" - -is-plain-obj@^1.0.0: - version "1.1.0" - resolved "https://registry.yarnpkg.com/is-plain-obj/-/is-plain-obj-1.1.0.tgz#71a50c8429dfca773c92a390a4a03b39fcd51d3e" - integrity sha1-caUMhCnfync8kqOQpKA7OfzVHT4= - -is-plain-object@^2.0.3, is-plain-object@^2.0.4: - version "2.0.4" - resolved "https://registry.yarnpkg.com/is-plain-object/-/is-plain-object-2.0.4.tgz#2c163b3fafb1b606d9d17928f05c2a1c38e07677" - integrity sha512-h5PpgXkWitc38BBMYawTYMWJHFZJVnBquFE57xFpjB8pJFiF6gZ+bU+WyI/yqXiFR5mdLsgYNaPe8uao6Uv9Og== - dependencies: - isobject "^3.0.1" - -is-regex@^1.0.4: - version "1.0.4" - resolved "https://registry.yarnpkg.com/is-regex/-/is-regex-1.0.4.tgz#5517489b547091b0930e095654ced25ee97e9491" - integrity sha1-VRdIm1RwkbCTDglWVM7SXul+lJE= - dependencies: - has "^1.0.1" - -is-resolvable@^1.0.0: - version "1.1.0" - resolved "https://registry.yarnpkg.com/is-resolvable/-/is-resolvable-1.1.0.tgz#fb18f87ce1feb925169c9a407c19318a3206ed88" - integrity sha512-qgDYXFSR5WvEfuS5dMj6oTMEbrrSaM0CrFk2Yiq/gXnBvD9pMa2jGXxyhGLfvhZpuMZe18CJpFxAt3CRs42NMg== - -is-stream@^1.1.0: - version "1.1.0" - resolved "https://registry.yarnpkg.com/is-stream/-/is-stream-1.1.0.tgz#12d4a3dd4e68e0b79ceb8dbc84173ae80d91ca44" - integrity sha1-EtSj3U5o4Lec6428hBc66A2RykQ= - -is-svg@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/is-svg/-/is-svg-3.0.0.tgz#9321dbd29c212e5ca99c4fa9794c714bcafa2f75" - integrity sha512-gi4iHK53LR2ujhLVVj+37Ykh9GLqYHX6JOVXbLAucaG/Cqw9xwdFOjDM2qeifLs1sF1npXXFvDu0r5HNgCMrzQ== - dependencies: - html-comment-regex "^1.1.0" - -is-symbol@^1.0.2: - version "1.0.2" - resolved "https://registry.yarnpkg.com/is-symbol/-/is-symbol-1.0.2.tgz#a055f6ae57192caee329e7a860118b497a950f38" - integrity sha512-HS8bZ9ox60yCJLH9snBpIwv9pYUAkcuLhSA1oero1UB5y9aiQpRA8y2ex945AOtCZL1lJDeIk3G5LthswI46Lw== - dependencies: - has-symbols "^1.0.0" - -is-typedarray@~1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/is-typedarray/-/is-typedarray-1.0.0.tgz#e479c80858df0c1b11ddda6940f96011fcda4a9a" - integrity sha1-5HnICFjfDBsR3dppQPlgEfzaSpo= - -is-windows@^1.0.2: - version "1.0.2" - resolved "https://registry.yarnpkg.com/is-windows/-/is-windows-1.0.2.tgz#d1850eb9791ecd18e6182ce12a30f396634bb19d" - integrity sha512-eXK1UInq2bPmjyX6e3VHIzMLobc4J94i4AWn+Hpq3OU5KkrRC96OAcR3PRJ/pGu6m8TRnBHP9dkXQVsT/COVIA== - -is-wsl@^1.1.0: - version "1.1.0" - resolved "https://registry.yarnpkg.com/is-wsl/-/is-wsl-1.1.0.tgz#1f16e4aa22b04d1336b66188a66af3c600c3a66d" - integrity sha1-HxbkqiKwTRM2tmGIpmrzxgDDpm0= - -isarray@1.0.0, isarray@^1.0.0, isarray@~1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/isarray/-/isarray-1.0.0.tgz#bb935d48582cba168c06834957a54a3e07124f11" - integrity sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE= - -isarray@^2.0.1: - version "2.0.5" - resolved "https://registry.yarnpkg.com/isarray/-/isarray-2.0.5.tgz#8af1e4c1221244cc62459faf38940d4e644a5723" - integrity sha512-xHjhDr3cNBK0BzdUJSPXZntQUx/mwMS5Rw4A7lPJ90XGAO6ISP/ePDNuo0vhqOZU+UD5JoodwCAAoZQd3FeAKw== - -isexe@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/isexe/-/isexe-2.0.0.tgz#e8fbf374dc556ff8947a10dcb0572d633f2cfa10" - integrity sha1-6PvzdNxVb/iUehDcsFctYz8s+hA= - -isobject@^2.0.0: - version "2.1.0" - resolved "https://registry.yarnpkg.com/isobject/-/isobject-2.1.0.tgz#f065561096a3f1da2ef46272f815c840d87e0c89" - integrity sha1-8GVWEJaj8dou9GJy+BXIQNh+DIk= - dependencies: - isarray "1.0.0" - -isobject@^3.0.0, isobject@^3.0.1: - version "3.0.1" - resolved "https://registry.yarnpkg.com/isobject/-/isobject-3.0.1.tgz#4e431e92b11a9731636aa1f9c8d1ccbcfdab78df" - integrity sha1-TkMekrEalzFjaqH5yNHMvP2reN8= - -isstream@~0.1.2: - version "0.1.2" - resolved "https://registry.yarnpkg.com/isstream/-/isstream-0.1.2.tgz#47e63f7af55afa6f92e1500e690eb8b8529c099a" - integrity sha1-R+Y/evVa+m+S4VAOaQ64uFKcCZo= - -javascript-stringify@^1.6.0: - version "1.6.0" - resolved "https://registry.yarnpkg.com/javascript-stringify/-/javascript-stringify-1.6.0.tgz#142d111f3a6e3dae8f4a9afd77d45855b5a9cce3" - integrity sha1-FC0RHzpuPa6PSpr9d9RYVbWpzOM= - -js-levenshtein@^1.1.3: - version "1.1.6" - resolved "https://registry.yarnpkg.com/js-levenshtein/-/js-levenshtein-1.1.6.tgz#c6cee58eb3550372df8deb85fad5ce66ce01d59d" - integrity sha512-X2BB11YZtrRqY4EnQcLX5Rh373zbK4alC1FW7D7MBhL2gtcC17cTnr6DmfHZeS0s2rTHjUTMMHfG7gO8SSdw+g== - -"js-tokens@^3.0.0 || ^4.0.0", js-tokens@^4.0.0: - version "4.0.0" - resolved "https://registry.yarnpkg.com/js-tokens/-/js-tokens-4.0.0.tgz#19203fb59991df98e3a287050d4647cdeaf32499" - integrity sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ== - -js-yaml@^3.11.0, js-yaml@^3.13.1, js-yaml@^3.8.1: - version "3.13.1" - resolved "https://registry.yarnpkg.com/js-yaml/-/js-yaml-3.13.1.tgz#aff151b30bfdfa8e49e05da22e7415e9dfa37847" - integrity sha512-YfbcO7jXDdyj0DGxYVSlSeQNHbD7XPWvrVWeVUujrQEoZzWJIRrCPoyk6kL6IAjAG2IolMK4T0hNUe0HOUs5Jw== - dependencies: - argparse "^1.0.7" - esprima "^4.0.0" - -jsbn@~0.1.0: - version "0.1.1" - resolved "https://registry.yarnpkg.com/jsbn/-/jsbn-0.1.1.tgz#a5e654c2e5a2deb5f201d96cefbca80c0ef2f513" - integrity sha1-peZUwuWi3rXyAdls77yoDA7y9RM= - -jsesc@^2.5.1: - version "2.5.2" - resolved "https://registry.yarnpkg.com/jsesc/-/jsesc-2.5.2.tgz#80564d2e483dacf6e8ef209650a67df3f0c283a4" - integrity sha512-OYu7XEzjkCQ3C5Ps3QIZsQfNpqoJyZZA99wd9aWd05NCtC5pWOkShK2mkL6HXQR6/Cy2lbNdPlZBpuQHXE63gA== - -jsesc@~0.5.0: - version "0.5.0" - resolved "https://registry.yarnpkg.com/jsesc/-/jsesc-0.5.0.tgz#e7dee66e35d6fc16f710fe91d5cf69f70f08911d" - integrity sha1-597mbjXW/Bb3EP6R1c9p9w8IkR0= - -json-parse-better-errors@^1.0.1, json-parse-better-errors@^1.0.2: - version "1.0.2" - resolved "https://registry.yarnpkg.com/json-parse-better-errors/-/json-parse-better-errors-1.0.2.tgz#bb867cfb3450e69107c131d1c514bab3dc8bcaa9" - integrity sha512-mrqyZKfX5EhL7hvqcV6WG1yYjnjeuYDzDhhcAAUrq8Po85NBQBJP+ZDUT75qZQ98IkUoBqdkExkukOU7Ts2wrw== - -json-schema-traverse@^0.4.1: - version "0.4.1" - resolved "https://registry.yarnpkg.com/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz#69f6a87d9513ab8bb8fe63bdb0979c448e684660" - integrity sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg== - -json-schema@0.2.3: - version "0.2.3" - resolved "https://registry.yarnpkg.com/json-schema/-/json-schema-0.2.3.tgz#b480c892e59a2f05954ce727bd3f2a4e882f9e13" - integrity sha1-tIDIkuWaLwWVTOcnvT8qTogvnhM= - -json-stringify-safe@~5.0.1: - version "5.0.1" - resolved "https://registry.yarnpkg.com/json-stringify-safe/-/json-stringify-safe-5.0.1.tgz#1296a2d58fd45f19a0f6ce01d65701e2c735b6eb" - integrity sha1-Epai1Y/UXxmg9s4B1lcB4sc1tus= - -json3@^3.3.2: - version "3.3.3" - resolved "https://registry.yarnpkg.com/json3/-/json3-3.3.3.tgz#7fc10e375fc5ae42c4705a5cc0aa6f62be305b81" - integrity sha512-c7/8mbUsKigAbLkD5B010BK4D9LZm7A1pNItkEwiUZRpIN66exu/e7YQWysGun+TRKaJp8MhemM+VkfWv42aCA== - -json5@^0.5.0, json5@^0.5.1: - version "0.5.1" - resolved "https://registry.yarnpkg.com/json5/-/json5-0.5.1.tgz#1eade7acc012034ad84e2396767ead9fa5495821" - integrity sha1-Hq3nrMASA0rYTiOWdn6tn6VJWCE= - -json5@^1.0.1: - version "1.0.1" - resolved "https://registry.yarnpkg.com/json5/-/json5-1.0.1.tgz#779fb0018604fa854eacbf6252180d83543e3dbe" - integrity sha512-aKS4WQjPenRxiQsC93MNfjx+nbF4PAdYzmd/1JIj8HYzqfbu86beTuNgXDzPknWk0n0uARlyewZo4s++ES36Ow== - dependencies: - minimist "^1.2.0" - -json5@^2.1.0: - version "2.1.0" - resolved "https://registry.yarnpkg.com/json5/-/json5-2.1.0.tgz#e7a0c62c48285c628d20a10b85c89bb807c32850" - integrity sha512-8Mh9h6xViijj36g7Dxi+Y4S6hNGV96vcJZr/SrlHh1LR/pEn/8j/+qIBbs44YKl69Lrfctp4QD+AdWLTMqEZAQ== - dependencies: - minimist "^1.2.0" - -jsonfile@^4.0.0: - version "4.0.0" - resolved "https://registry.yarnpkg.com/jsonfile/-/jsonfile-4.0.0.tgz#8771aae0799b64076b76640fca058f9c10e33ecb" - integrity sha1-h3Gq4HmbZAdrdmQPygWPnBDjPss= - optionalDependencies: - graceful-fs "^4.1.6" - -jsprim@^1.2.2: - version "1.4.1" - resolved "https://registry.yarnpkg.com/jsprim/-/jsprim-1.4.1.tgz#313e66bc1e5cc06e438bc1b7499c2e5c56acb6a2" - integrity sha1-MT5mvB5cwG5Di8G3SZwuXFastqI= - dependencies: - assert-plus "1.0.0" - extsprintf "1.3.0" - json-schema "0.2.3" - verror "1.10.0" - -killable@^1.0.1: - version "1.0.1" - resolved "https://registry.yarnpkg.com/killable/-/killable-1.0.1.tgz#4c8ce441187a061c7474fb87ca08e2a638194892" - integrity sha512-LzqtLKlUwirEUyl/nicirVmNiPvYs7l5n8wOPP7fyJVpUPkvCnW/vuiXGpylGUlnPDnB7311rARzAt3Mhswpjg== - -kind-of@^3.0.2, kind-of@^3.0.3, kind-of@^3.2.0: - version "3.2.2" - resolved "https://registry.yarnpkg.com/kind-of/-/kind-of-3.2.2.tgz#31ea21a734bab9bbb0f32466d893aea51e4a3c64" - integrity sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ= - dependencies: - is-buffer "^1.1.5" - -kind-of@^4.0.0: - version "4.0.0" - resolved "https://registry.yarnpkg.com/kind-of/-/kind-of-4.0.0.tgz#20813df3d712928b207378691a45066fae72dd57" - integrity sha1-IIE989cSkosgc3hpGkUGb65y3Vc= - dependencies: - is-buffer "^1.1.5" - -kind-of@^5.0.0: - version "5.1.0" - resolved "https://registry.yarnpkg.com/kind-of/-/kind-of-5.1.0.tgz#729c91e2d857b7a419a1f9aa65685c4c33f5845d" - integrity sha512-NGEErnH6F2vUuXDh+OlbcKW7/wOcfdRHaZ7VWtqCztfHri/++YKmP51OdWeGPuqCOba6kk2OTe5d02VmTB80Pw== - -kind-of@^6.0.0, kind-of@^6.0.2: - version "6.0.2" - resolved "https://registry.yarnpkg.com/kind-of/-/kind-of-6.0.2.tgz#01146b36a6218e64e58f3a8d66de5d7fc6f6d051" - integrity sha512-s5kLOcnH0XqDO+FvuaLX8DDjZ18CGFk7VygH40QoKPUQhW4e2rvM0rwUq0t8IQDOwYSeLK01U90OjzBTme2QqA== - -last-call-webpack-plugin@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/last-call-webpack-plugin/-/last-call-webpack-plugin-3.0.0.tgz#9742df0e10e3cf46e5c0381c2de90d3a7a2d7555" - integrity sha512-7KI2l2GIZa9p2spzPIVZBYyNKkN+e/SQPpnjlTiPhdbDW3F86tdKKELxKpzJ5sgU19wQWsACULZmpTPYHeWO5w== - dependencies: - lodash "^4.17.5" - webpack-sources "^1.1.0" - -lcid@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/lcid/-/lcid-2.0.0.tgz#6ef5d2df60e52f82eb228a4c373e8d1f397253cf" - integrity sha512-avPEb8P8EGnwXKClwsNUgryVjllcRqtMYa49NTsbQagYuT1DcXnl1915oxWjoyGrXR6zH/Y0Zc96xWsPcoDKeA== - dependencies: - invert-kv "^2.0.0" - -linkify-it@^2.0.0: - version "2.2.0" - resolved "https://registry.yarnpkg.com/linkify-it/-/linkify-it-2.2.0.tgz#e3b54697e78bf915c70a38acd78fd09e0058b1cf" - integrity sha512-GnAl/knGn+i1U/wjBz3akz2stz+HrHLsxMwHQGofCDfPvlf+gDKN58UtfmUquTY4/MXeE2x7k19KQmeoZi94Iw== - dependencies: - uc.micro "^1.0.1" - -load-script@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/load-script/-/load-script-1.0.0.tgz#0491939e0bee5643ee494a7e3da3d2bac70c6ca4" - integrity sha1-BJGTngvuVkPuSUp+PaPSuscMbKQ= - -loader-runner@^2.3.0: - version "2.4.0" - resolved "https://registry.yarnpkg.com/loader-runner/-/loader-runner-2.4.0.tgz#ed47066bfe534d7e84c4c7b9998c2a75607d9357" - integrity sha512-Jsmr89RcXGIwivFY21FcRrisYZfvLMTWx5kOLc+JTxtpBOG6xML0vzbc6SEQG2FO9/4Fc3wW4LVcB5DmGflaRw== - -loader-utils@^0.2.16: - version "0.2.17" - resolved "https://registry.yarnpkg.com/loader-utils/-/loader-utils-0.2.17.tgz#f86e6374d43205a6e6c60e9196f17c0299bfb348" - integrity sha1-+G5jdNQyBabmxg6RlvF8Apm/s0g= - dependencies: - big.js "^3.1.3" - emojis-list "^2.0.0" - json5 "^0.5.0" - object-assign "^4.0.1" - -loader-utils@^1.0.2, loader-utils@^1.1.0, loader-utils@^1.2.3: - version "1.2.3" - resolved "https://registry.yarnpkg.com/loader-utils/-/loader-utils-1.2.3.tgz#1ff5dc6911c9f0a062531a4c04b609406108c2c7" - integrity sha512-fkpz8ejdnEMG3s37wGL07iSBDg99O9D5yflE9RGNH3hRdx9SOwYfnGYdZOUIZitN8E+E2vkq3MUMYMvPYl5ZZA== - dependencies: - big.js "^5.2.2" - emojis-list "^2.0.0" - json5 "^1.0.1" - -locate-path@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/locate-path/-/locate-path-2.0.0.tgz#2b568b265eec944c6d9c0de9c3dbbbca0354cd8e" - integrity sha1-K1aLJl7slExtnA3pw9u7ygNUzY4= - dependencies: - p-locate "^2.0.0" - path-exists "^3.0.0" - -locate-path@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/locate-path/-/locate-path-3.0.0.tgz#dbec3b3ab759758071b58fe59fc41871af21400e" - integrity sha512-7AO748wWnIhNqAuaty2ZWHkQHRSNfPVIsPIfwEOWO22AmaoVrWavlOcMR5nzTLNYvp36X220/maaRsrec1G65A== - dependencies: - p-locate "^3.0.0" - path-exists "^3.0.0" - -lodash._reinterpolate@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/lodash._reinterpolate/-/lodash._reinterpolate-3.0.0.tgz#0ccf2d89166af03b3663c796538b75ac6e114d9d" - integrity sha1-DM8tiRZq8Ds2Y8eWU4t1rG4RTZ0= - -lodash.clonedeep@^4.5.0: - version "4.5.0" - resolved "https://registry.yarnpkg.com/lodash.clonedeep/-/lodash.clonedeep-4.5.0.tgz#e23f3f9c4f8fbdde872529c1071857a086e5ccef" - integrity sha1-4j8/nE+Pvd6HJSnBBxhXoIblzO8= - -lodash.kebabcase@^4.1.1: - version "4.1.1" - resolved "https://registry.yarnpkg.com/lodash.kebabcase/-/lodash.kebabcase-4.1.1.tgz#8489b1cb0d29ff88195cceca448ff6d6cc295c36" - integrity sha1-hImxyw0p/4gZXM7KRI/21swpXDY= - -lodash.memoize@^4.1.2: - version "4.1.2" - resolved "https://registry.yarnpkg.com/lodash.memoize/-/lodash.memoize-4.1.2.tgz#bcc6c49a42a2840ed997f323eada5ecd182e0bfe" - integrity sha1-vMbEmkKihA7Zl/Mj6tpezRguC/4= - -lodash.template@^4.4.0: - version "4.5.0" - resolved "https://registry.yarnpkg.com/lodash.template/-/lodash.template-4.5.0.tgz#f976195cf3f347d0d5f52483569fe8031ccce8ab" - integrity sha512-84vYFxIkmidUiFxidA/KjjH9pAycqW+h980j7Fuz5qxRtO9pgB7MDFTdys1N7A5mcucRiDyEq4fusljItR1T/A== - dependencies: - lodash._reinterpolate "^3.0.0" - lodash.templatesettings "^4.0.0" - -lodash.templatesettings@^4.0.0: - version "4.2.0" - resolved "https://registry.yarnpkg.com/lodash.templatesettings/-/lodash.templatesettings-4.2.0.tgz#e481310f049d3cf6d47e912ad09313b154f0fb33" - integrity sha512-stgLz+i3Aa9mZgnjr/O+v9ruKZsPsndy7qPZOchbqk2cnTU1ZaldKK+v7m54WoKIyxiuMZTKT2H81F8BeAc3ZQ== - dependencies: - lodash._reinterpolate "^3.0.0" - -lodash.throttle@^4.1.1: - version "4.1.1" - resolved "https://registry.yarnpkg.com/lodash.throttle/-/lodash.throttle-4.1.1.tgz#c23e91b710242ac70c37f1e1cda9274cc39bf2f4" - integrity sha1-wj6RtxAkKscMN/HhzaknTMOb8vQ= - -lodash.uniq@^4.5.0: - version "4.5.0" - resolved "https://registry.yarnpkg.com/lodash.uniq/-/lodash.uniq-4.5.0.tgz#d0225373aeb652adc1bc82e4945339a842754773" - integrity sha1-0CJTc662Uq3BvILklFM5qEJ1R3M= - -lodash@^4.17.11, lodash@^4.17.13, lodash@^4.17.3, lodash@^4.17.5: - version "4.17.15" - resolved "https://registry.yarnpkg.com/lodash/-/lodash-4.17.15.tgz#b447f6670a0455bbfeedd11392eff330ea097548" - integrity sha512-8xOcRHvCjnocdS5cpwXQXVzmmh5e5+saE2QGoeQmbKmRS6J3VQppPOIt0MnmE+4xlZoumy0GPG0D0MVIQbNA1A== - -loglevel@^1.6.3: - version "1.6.3" - resolved "https://registry.yarnpkg.com/loglevel/-/loglevel-1.6.3.tgz#77f2eb64be55a404c9fd04ad16d57c1d6d6b1280" - integrity sha512-LoEDv5pgpvWgPF4kNYuIp0qqSJVWak/dML0RY74xlzMZiT9w77teNAwKYKWBTYjlokMirg+o3jBwp+vlLrcfAA== - -loose-envify@^1.0.0: - version "1.4.0" - resolved "https://registry.yarnpkg.com/loose-envify/-/loose-envify-1.4.0.tgz#71ee51fa7be4caec1a63839f7e682d8132d30caf" - integrity sha512-lyuxPGr/Wfhrlem2CL/UcnUc1zcqKAImBDzukY7Y5F/yQiNdko6+fRLevlw1HgMySw7f611UIY408EtxRSoK3Q== - dependencies: - js-tokens "^3.0.0 || ^4.0.0" - -lower-case@^1.1.1: - version "1.1.4" - resolved "https://registry.yarnpkg.com/lower-case/-/lower-case-1.1.4.tgz#9a2cabd1b9e8e0ae993a4bf7d5875c39c42e8eac" - integrity sha1-miyr0bno4K6ZOkv31YdcOcQujqw= - -lru-cache@^4.1.2: - version "4.1.5" - resolved "https://registry.yarnpkg.com/lru-cache/-/lru-cache-4.1.5.tgz#8bbe50ea85bed59bc9e33dcab8235ee9bcf443cd" - integrity sha512-sWZlbEP2OsHNkXrMl5GYk/jKk70MBng6UU4YI/qGDYbgf6YbP4EvmqISbXCoJiRKs+1bSpFHVgQxvJ17F2li5g== - dependencies: - pseudomap "^1.0.2" - yallist "^2.1.2" - -lru-cache@^5.1.1: - version "5.1.1" - resolved "https://registry.yarnpkg.com/lru-cache/-/lru-cache-5.1.1.tgz#1da27e6710271947695daf6848e847f01d84b920" - integrity sha512-KpNARQA3Iwv+jTA0utUVVbrh+Jlrr1Fv0e56GGzAFOXN7dk/FviaDW8LHmK52DlcH4WP2n6gI8vN1aesBFgo9w== - dependencies: - yallist "^3.0.2" - -make-dir@^2.0.0: - version "2.1.0" - resolved "https://registry.yarnpkg.com/make-dir/-/make-dir-2.1.0.tgz#5f0310e18b8be898cc07009295a30ae41e91e6f5" - integrity sha512-LS9X+dc8KLxXCb8dni79fLIIUA5VyZoyjSMCwTluaXA0o27cCK0bhXkpgw+sTXVpPy/lSO57ilRixqk0vDmtRA== - dependencies: - pify "^4.0.1" - semver "^5.6.0" - -mamacro@^0.0.3: - version "0.0.3" - resolved "https://registry.yarnpkg.com/mamacro/-/mamacro-0.0.3.tgz#ad2c9576197c9f1abf308d0787865bd975a3f3e4" - integrity sha512-qMEwh+UujcQ+kbz3T6V+wAmO2U8veoq2w+3wY8MquqwVA3jChfwY+Tk52GZKDfACEPjuZ7r2oJLejwpt8jtwTA== - -map-age-cleaner@^0.1.1: - version "0.1.3" - resolved "https://registry.yarnpkg.com/map-age-cleaner/-/map-age-cleaner-0.1.3.tgz#7d583a7306434c055fe474b0f45078e6e1b4b92a" - integrity sha512-bJzx6nMoP6PDLPBFmg7+xRKeFZvFboMrGlxmNj9ClvX53KrmvM5bXFXEWjbz4cz1AFn+jWJ9z/DJSz7hrs0w3w== - dependencies: - p-defer "^1.0.0" - -map-cache@^0.2.2: - version "0.2.2" - resolved "https://registry.yarnpkg.com/map-cache/-/map-cache-0.2.2.tgz#c32abd0bd6525d9b051645bb4f26ac5dc98a0dbf" - integrity sha1-wyq9C9ZSXZsFFkW7TyasXcmKDb8= - -map-visit@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/map-visit/-/map-visit-1.0.0.tgz#ecdca8f13144e660f1b5bd41f12f3479d98dfb8f" - integrity sha1-7Nyo8TFE5mDxtb1B8S80edmN+48= - dependencies: - object-visit "^1.0.0" - -markdown-it-anchor@^5.0.2: - version "5.2.4" - resolved "https://registry.yarnpkg.com/markdown-it-anchor/-/markdown-it-anchor-5.2.4.tgz#d39306fe4c199705b4479d3036842cf34dcba24f" - integrity sha512-n8zCGjxA3T+Mx1pG8HEgbJbkB8JFUuRkeTZQuIM8iPY6oQ8sWOPRZJDFC9a/pNg2QkHEjjGkhBEl/RSyzaDZ3A== - -markdown-it-chain@^1.3.0: - version "1.3.0" - resolved "https://registry.yarnpkg.com/markdown-it-chain/-/markdown-it-chain-1.3.0.tgz#ccf6fe86c10266bafb4e547380dfd7f277cc17bc" - integrity sha512-XClV8I1TKy8L2qsT9iX3qiV+50ZtcInGXI80CA+DP62sMs7hXlyV/RM3hfwy5O3Ad0sJm9xIwQELgANfESo8mQ== - dependencies: - webpack-chain "^4.9.0" - -markdown-it-container@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/markdown-it-container/-/markdown-it-container-2.0.0.tgz#0019b43fd02eefece2f1960a2895fba81a404695" - integrity sha1-ABm0P9Au7+zi8ZYKKJX7qBpARpU= - -markdown-it-emoji@^1.4.0: - version "1.4.0" - resolved "https://registry.yarnpkg.com/markdown-it-emoji/-/markdown-it-emoji-1.4.0.tgz#9bee0e9a990a963ba96df6980c4fddb05dfb4dcc" - integrity sha1-m+4OmpkKljupbfaYDE/dsF37Tcw= - -markdown-it-meta@0.0.1: - version "0.0.1" - resolved "https://registry.yarnpkg.com/markdown-it-meta/-/markdown-it-meta-0.0.1.tgz#d75b68f115659caf568e4ad43cb460a471248c39" - integrity sha1-11to8RVlnK9WjkrUPLRgpHEkjDk= - dependencies: - js-yaml "^3.8.1" - -markdown-it-table-of-contents@^0.4.0: - version "0.4.4" - resolved "https://registry.yarnpkg.com/markdown-it-table-of-contents/-/markdown-it-table-of-contents-0.4.4.tgz#3dc7ce8b8fc17e5981c77cc398d1782319f37fbc" - integrity sha512-TAIHTHPwa9+ltKvKPWulm/beozQU41Ab+FIefRaQV1NRnpzwcV9QOe6wXQS5WLivm5Q/nlo0rl6laGkMDZE7Gw== - -markdown-it@^8.4.1, markdown-it@^8.4.2: - version "8.4.2" - resolved "https://registry.yarnpkg.com/markdown-it/-/markdown-it-8.4.2.tgz#386f98998dc15a37722aa7722084f4020bdd9b54" - integrity sha512-GcRz3AWTqSUphY3vsUqQSFMbgR38a4Lh3GWlHRh/7MRwz8mcu9n2IO7HOh+bXHrR9kOPDl5RNCaEsrneb+xhHQ== - dependencies: - argparse "^1.0.7" - entities "~1.1.1" - linkify-it "^2.0.0" - mdurl "^1.0.1" - uc.micro "^1.0.5" - -md5.js@^1.3.4: - version "1.3.5" - resolved "https://registry.yarnpkg.com/md5.js/-/md5.js-1.3.5.tgz#b5d07b8e3216e3e27cd728d72f70d1e6a342005f" - integrity sha512-xitP+WxNPcTTOgnTJcrhM0xvdPepipPSf3I8EIpGKeFLjt3PlJLIDG3u8EX53ZIubkb+5U2+3rELYpEhHhzdkg== - dependencies: - hash-base "^3.0.0" - inherits "^2.0.1" - safe-buffer "^5.1.2" - -mdn-data@2.0.4: - version "2.0.4" - resolved "https://registry.yarnpkg.com/mdn-data/-/mdn-data-2.0.4.tgz#699b3c38ac6f1d728091a64650b65d388502fd5b" - integrity sha512-iV3XNKw06j5Q7mi6h+9vbx23Tv7JkjEVgKHW4pimwyDGWm0OIQntJJ+u1C6mg6mK1EaTv42XQ7w76yuzH7M2cA== - -mdn-data@~1.1.0: - version "1.1.4" - resolved "https://registry.yarnpkg.com/mdn-data/-/mdn-data-1.1.4.tgz#50b5d4ffc4575276573c4eedb8780812a8419f01" - integrity sha512-FSYbp3lyKjyj3E7fMl6rYvUdX0FBXaluGqlFoYESWQlyUTq8R+wp0rkFxoYFqZlHCvsUXGjyJmLQSnXToYhOSA== - -mdurl@^1.0.1: - version "1.0.1" - resolved "https://registry.yarnpkg.com/mdurl/-/mdurl-1.0.1.tgz#fe85b2ec75a59037f2adfec100fd6c601761152e" - integrity sha1-/oWy7HWlkDfyrf7BAP1sYBdhFS4= - -media-typer@0.3.0: - version "0.3.0" - resolved "https://registry.yarnpkg.com/media-typer/-/media-typer-0.3.0.tgz#8710d7af0aa626f8fffa1ce00168545263255748" - integrity sha1-hxDXrwqmJvj/+hzgAWhUUmMlV0g= - -mem@^4.0.0: - version "4.3.0" - resolved "https://registry.yarnpkg.com/mem/-/mem-4.3.0.tgz#461af497bc4ae09608cdb2e60eefb69bff744178" - integrity sha512-qX2bG48pTqYRVmDB37rn/6PT7LcR8T7oAX3bf99u1Tt1nzxYfxkgqDwUwolPlXweM0XzBOBFzSx4kfp7KP1s/w== - dependencies: - map-age-cleaner "^0.1.1" - mimic-fn "^2.0.0" - p-is-promise "^2.0.0" - -memory-fs@^0.4.0, memory-fs@^0.4.1, memory-fs@~0.4.1: - version "0.4.1" - resolved "https://registry.yarnpkg.com/memory-fs/-/memory-fs-0.4.1.tgz#3a9a20b8462523e447cfbc7e8bb80ed667bfc552" - integrity sha1-OpoguEYlI+RHz7x+i7gO1me/xVI= - dependencies: - errno "^0.1.3" - readable-stream "^2.0.1" - -merge-descriptors@1.0.1: - version "1.0.1" - resolved "https://registry.yarnpkg.com/merge-descriptors/-/merge-descriptors-1.0.1.tgz#b00aaa556dd8b44568150ec9d1b953f3f90cbb61" - integrity sha1-sAqqVW3YtEVoFQ7J0blT8/kMu2E= - -merge-source-map@^1.1.0: - version "1.1.0" - resolved "https://registry.yarnpkg.com/merge-source-map/-/merge-source-map-1.1.0.tgz#2fdde7e6020939f70906a68f2d7ae685e4c8c646" - integrity sha512-Qkcp7P2ygktpMPh2mCQZaf3jhN6D3Z/qVZHSdWvQ+2Ef5HgRAPBO57A77+ENm0CPx2+1Ce/MYKi3ymqdfuqibw== - dependencies: - source-map "^0.6.1" - -merge2@^1.2.3: - version "1.2.3" - resolved "https://registry.yarnpkg.com/merge2/-/merge2-1.2.3.tgz#7ee99dbd69bb6481689253f018488a1b902b0ed5" - integrity sha512-gdUU1Fwj5ep4kplwcmftruWofEFt6lfpkkr3h860CXbAB9c3hGb55EOL2ali0Td5oebvW0E1+3Sr+Ur7XfKpRA== - -methods@~1.1.2: - version "1.1.2" - resolved "https://registry.yarnpkg.com/methods/-/methods-1.1.2.tgz#5529a4d67654134edcc5266656835b0f851afcee" - integrity sha1-VSmk1nZUE07cxSZmVoNbD4Ua/O4= - -micromatch@^3.1.10, micromatch@^3.1.4, micromatch@^3.1.8: - version "3.1.10" - resolved "https://registry.yarnpkg.com/micromatch/-/micromatch-3.1.10.tgz#70859bc95c9840952f359a068a3fc49f9ecfac23" - integrity sha512-MWikgl9n9M3w+bpsY3He8L+w9eF9338xRl8IAO5viDizwSzziFEyUzo2xrrloB64ADbTf8uA8vRqqttDTOmccg== - dependencies: - arr-diff "^4.0.0" - array-unique "^0.3.2" - braces "^2.3.1" - define-property "^2.0.2" - extend-shallow "^3.0.2" - extglob "^2.0.4" - fragment-cache "^0.2.1" - kind-of "^6.0.2" - nanomatch "^1.2.9" - object.pick "^1.3.0" - regex-not "^1.0.0" - snapdragon "^0.8.1" - to-regex "^3.0.2" - -miller-rabin@^4.0.0: - version "4.0.1" - resolved "https://registry.yarnpkg.com/miller-rabin/-/miller-rabin-4.0.1.tgz#f080351c865b0dc562a8462966daa53543c78a4d" - integrity sha512-115fLhvZVqWwHPbClyntxEVfVDfl9DLLTuJvq3g2O/Oxi8AiNouAHvDSzHS0viUJc+V5vm3eq91Xwqn9dp4jRA== - dependencies: - bn.js "^4.0.0" - brorand "^1.0.1" - -mime-db@1.40.0, "mime-db@>= 1.40.0 < 2": - version "1.40.0" - resolved "https://registry.yarnpkg.com/mime-db/-/mime-db-1.40.0.tgz#a65057e998db090f732a68f6c276d387d4126c32" - integrity sha512-jYdeOMPy9vnxEqFRRo6ZvTZ8d9oPb+k18PKoYNYUe2stVEBPPwsln/qWzdbmaIvnhZ9v2P+CuecK+fpUfsV2mA== - -mime-types@^2.1.12, mime-types@~2.1.17, mime-types@~2.1.19, mime-types@~2.1.24: - version "2.1.24" - resolved "https://registry.yarnpkg.com/mime-types/-/mime-types-2.1.24.tgz#b6f8d0b3e951efb77dedeca194cff6d16f676f81" - integrity sha512-WaFHS3MCl5fapm3oLxU4eYDw77IQM2ACcxQ9RIxfaC3ooc6PFuBMGZZsYpvoXS5D5QTWPieo1jjLdAm3TBP3cQ== - dependencies: - mime-db "1.40.0" - -mime@1.6.0: - version "1.6.0" - resolved "https://registry.yarnpkg.com/mime/-/mime-1.6.0.tgz#32cd9e5c64553bd58d19a568af452acff04981b1" - integrity sha512-x0Vn8spI+wuJ1O6S7gnbaQg8Pxh4NNHb7KSINmEWKiPE4RKOplvijn+NkmYmmRgP68mc70j2EbeTFRsrswaQeg== - -mime@^2.0.3, mime@^2.4.2: - version "2.4.4" - resolved "https://registry.yarnpkg.com/mime/-/mime-2.4.4.tgz#bd7b91135fc6b01cde3e9bae33d659b63d8857e5" - integrity sha512-LRxmNwziLPT828z+4YkNzloCFC2YM4wrB99k+AV5ZbEyfGNWfG8SO1FUXLmLDBSo89NrJZ4DIWeLjy1CHGhMGA== - -mimic-fn@^2.0.0: - version "2.1.0" - resolved "https://registry.yarnpkg.com/mimic-fn/-/mimic-fn-2.1.0.tgz#7ed2c2ccccaf84d3ffcb7a69b57711fc2083401b" - integrity sha512-OqbOk5oEQeAZ8WXWydlu9HJjz9WVdEIvamMCcXmuqUYjTknH/sqsWvhQ3vgwKFRR1HpjvNBKQ37nbJgYzGqGcg== - -min-document@^2.19.0: - version "2.19.0" - resolved "https://registry.yarnpkg.com/min-document/-/min-document-2.19.0.tgz#7bd282e3f5842ed295bb748cdd9f1ffa2c824685" - integrity sha1-e9KC4/WELtKVu3SM3Z8f+iyCRoU= - dependencies: - dom-walk "^0.1.0" - -mini-css-extract-plugin@0.6.0: - version "0.6.0" - resolved "https://registry.yarnpkg.com/mini-css-extract-plugin/-/mini-css-extract-plugin-0.6.0.tgz#a3f13372d6fcde912f3ee4cd039665704801e3b9" - integrity sha512-79q5P7YGI6rdnVyIAV4NXpBQJFWdkzJxCim3Kog4078fM0piAaFlwocqbejdWtLW1cEzCexPrh6EdyFsPgVdAw== - dependencies: - loader-utils "^1.1.0" - normalize-url "^2.0.1" - schema-utils "^1.0.0" - webpack-sources "^1.1.0" - -minimalistic-assert@^1.0.0, minimalistic-assert@^1.0.1: - version "1.0.1" - resolved "https://registry.yarnpkg.com/minimalistic-assert/-/minimalistic-assert-1.0.1.tgz#2e194de044626d4a10e7f7fbc00ce73e83e4d5c7" - integrity sha512-UtJcAD4yEaGtjPezWuO9wC4nwUnVH/8/Im3yEHQP4b67cXlD/Qr9hdITCU1xDbSEXg2XKNaP8jsReV7vQd00/A== - -minimalistic-crypto-utils@^1.0.0, minimalistic-crypto-utils@^1.0.1: - version "1.0.1" - resolved "https://registry.yarnpkg.com/minimalistic-crypto-utils/-/minimalistic-crypto-utils-1.0.1.tgz#f6c00c1c0b082246e5c4d99dfb8c7c083b2b582a" - integrity sha1-9sAMHAsIIkblxNmd+4x8CDsrWCo= - -minimatch@^3.0.2, minimatch@^3.0.4: - version "3.0.4" - resolved "https://registry.yarnpkg.com/minimatch/-/minimatch-3.0.4.tgz#5166e286457f03306064be5497e8dbb0c3d32083" - integrity sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA== - dependencies: - brace-expansion "^1.1.7" - -minimist@0.0.8: - version "0.0.8" - resolved "https://registry.yarnpkg.com/minimist/-/minimist-0.0.8.tgz#857fcabfc3397d2625b8228262e86aa7a011b05d" - integrity sha1-hX/Kv8M5fSYluCKCYuhqp6ARsF0= - -minimist@^1.2.0: - version "1.2.0" - resolved "https://registry.yarnpkg.com/minimist/-/minimist-1.2.0.tgz#a35008b20f41383eec1fb914f4cd5df79a264284" - integrity sha1-o1AIsg9BOD7sH7kU9M1d95omQoQ= - -minipass@^2.2.1, minipass@^2.3.5: - version "2.3.5" - resolved "https://registry.yarnpkg.com/minipass/-/minipass-2.3.5.tgz#cacebe492022497f656b0f0f51e2682a9ed2d848" - integrity sha512-Gi1W4k059gyRbyVUZQ4mEqLm0YIUiGYfvxhF6SIlk3ui1WVxMTGfGdQ2SInh3PDrRTVvPKgULkpJtT4RH10+VA== - dependencies: - safe-buffer "^5.1.2" - yallist "^3.0.0" - -minizlib@^1.2.1: - version "1.2.1" - resolved "https://registry.yarnpkg.com/minizlib/-/minizlib-1.2.1.tgz#dd27ea6136243c7c880684e8672bb3a45fd9b614" - integrity sha512-7+4oTUOWKg7AuL3vloEWekXY2/D20cevzsrNT2kGWm+39J9hGTCBv8VI5Pm5lXZ/o3/mdR4f8rflAPhnQb8mPA== - dependencies: - minipass "^2.2.1" - -mississippi@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/mississippi/-/mississippi-3.0.0.tgz#ea0a3291f97e0b5e8776b363d5f0a12d94c67022" - integrity sha512-x471SsVjUtBRtcvd4BzKE9kFC+/2TeWgKCgw0bZcw1b9l2X3QX5vCWgF+KaZaYm87Ss//rHnWryupDrgLvmSkA== - dependencies: - concat-stream "^1.5.0" - duplexify "^3.4.2" - end-of-stream "^1.1.0" - flush-write-stream "^1.0.0" - from2 "^2.1.0" - parallel-transform "^1.1.0" - pump "^3.0.0" - pumpify "^1.3.3" - stream-each "^1.1.0" - through2 "^2.0.0" - -mixin-deep@^1.2.0: - version "1.3.2" - resolved "https://registry.yarnpkg.com/mixin-deep/-/mixin-deep-1.3.2.tgz#1120b43dc359a785dce65b55b82e257ccf479566" - integrity sha512-WRoDn//mXBiJ1H40rqa3vH0toePwSsGb45iInWlTySa+Uu4k3tYUSxa2v1KqAiLtvlrSzaExqS1gtk96A9zvEA== - dependencies: - for-in "^1.0.2" - is-extendable "^1.0.1" - -mkdirp@0.3.0: - version "0.3.0" - resolved "https://registry.yarnpkg.com/mkdirp/-/mkdirp-0.3.0.tgz#1bbf5ab1ba827af23575143490426455f481fe1e" - integrity sha1-G79asbqCevI1dRQ0kEJkVfSB/h4= - -mkdirp@0.5.x, mkdirp@^0.5.0, mkdirp@^0.5.1, mkdirp@~0.5.0, mkdirp@~0.5.1: - version "0.5.1" - resolved "https://registry.yarnpkg.com/mkdirp/-/mkdirp-0.5.1.tgz#30057438eac6cf7f8c4767f38648d6697d75c903" - integrity sha1-MAV0OOrGz3+MR2fzhkjWaX11yQM= - dependencies: - minimist "0.0.8" - -move-concurrently@^1.0.1: - version "1.0.1" - resolved "https://registry.yarnpkg.com/move-concurrently/-/move-concurrently-1.0.1.tgz#be2c005fda32e0b29af1f05d7c4b33214c701f92" - integrity sha1-viwAX9oy4LKa8fBdfEszIUxwH5I= - dependencies: - aproba "^1.1.1" - copy-concurrently "^1.0.0" - fs-write-stream-atomic "^1.0.8" - mkdirp "^0.5.1" - rimraf "^2.5.4" - run-queue "^1.0.3" - -ms@2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/ms/-/ms-2.0.0.tgz#5608aeadfc00be6c2901df5f9861788de0d597c8" - integrity sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g= - -ms@2.1.1: - version "2.1.1" - resolved "https://registry.yarnpkg.com/ms/-/ms-2.1.1.tgz#30a5864eb3ebb0a66f2ebe6d727af06a09d86e0a" - integrity sha512-tgp+dl5cGk28utYktBsrFqA7HKgrhgPsg6Z/EfhWI4gl1Hwq8B/GmY/0oXZ6nF8hDVesS/FpnYaD/kOWhYQvyg== - -ms@^2.1.1: - version "2.1.2" - resolved "https://registry.yarnpkg.com/ms/-/ms-2.1.2.tgz#d09d1f357b443f493382a8eb3ccd183872ae6009" - integrity sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w== - -multicast-dns-service-types@^1.1.0: - version "1.1.0" - resolved "https://registry.yarnpkg.com/multicast-dns-service-types/-/multicast-dns-service-types-1.1.0.tgz#899f11d9686e5e05cb91b35d5f0e63b773cfc901" - integrity sha1-iZ8R2WhuXgXLkbNdXw5jt3PPyQE= - -multicast-dns@^6.0.1: - version "6.2.3" - resolved "https://registry.yarnpkg.com/multicast-dns/-/multicast-dns-6.2.3.tgz#a0ec7bd9055c4282f790c3c82f4e28db3b31b229" - integrity sha512-ji6J5enbMyGRHIAkAOu3WdV8nggqviKCEKtXcOqfphZZtQrmHKycfynJ2V7eVPUA4NhJ6V7Wf4TmGbTwKE9B6g== - dependencies: - dns-packet "^1.3.1" - thunky "^1.0.2" - -nan@^2.12.1: - version "2.14.0" - resolved "https://registry.yarnpkg.com/nan/-/nan-2.14.0.tgz#7818f722027b2459a86f0295d434d1fc2336c52c" - integrity sha512-INOFj37C7k3AfaNTtX8RhsTw7qRy7eLET14cROi9+5HAVbbHuIWUHEauBv5qT4Av2tWasiTY1Jw6puUNqRJXQg== - -nanomatch@^1.2.9: - version "1.2.13" - resolved "https://registry.yarnpkg.com/nanomatch/-/nanomatch-1.2.13.tgz#b87a8aa4fc0de8fe6be88895b38983ff265bd119" - integrity sha512-fpoe2T0RbHwBTBUOftAfBPaDEi06ufaUai0mE6Yn1kacc3SnTErfb/h+X94VXzI64rKFHYImXSvdwGGCmwOqCA== - dependencies: - arr-diff "^4.0.0" - array-unique "^0.3.2" - define-property "^2.0.2" - extend-shallow "^3.0.2" - fragment-cache "^0.2.1" - is-windows "^1.0.2" - kind-of "^6.0.2" - object.pick "^1.3.0" - regex-not "^1.0.0" - snapdragon "^0.8.1" - to-regex "^3.0.1" - -needle@^2.2.1: - version "2.4.0" - resolved "https://registry.yarnpkg.com/needle/-/needle-2.4.0.tgz#6833e74975c444642590e15a750288c5f939b57c" - integrity sha512-4Hnwzr3mi5L97hMYeNl8wRW/Onhy4nUKR/lVemJ8gJedxxUyBLm9kkrDColJvoSfwi0jCNhD+xCdOtiGDQiRZg== - dependencies: - debug "^3.2.6" - iconv-lite "^0.4.4" - sax "^1.2.4" - -negotiator@0.6.2: - version "0.6.2" - resolved "https://registry.yarnpkg.com/negotiator/-/negotiator-0.6.2.tgz#feacf7ccf525a77ae9634436a64883ffeca346fb" - integrity sha512-hZXc7K2e+PgeI1eDBe/10Ard4ekbfrrqG8Ep+8Jmf4JID2bNg7NvCPOZN+kfF574pFQI7mum2AUqDidoKqcTOw== - -neo-async@^2.5.0, neo-async@^2.6.1: - version "2.6.1" - resolved "https://registry.yarnpkg.com/neo-async/-/neo-async-2.6.1.tgz#ac27ada66167fa8849a6addd837f6b189ad2081c" - integrity sha512-iyam8fBuCUpWeKPGpaNMetEocMt364qkCsfL9JuhjXX6dRnguRVOfk2GZaDpPjcOKiiXCPINZC1GczQ7iTq3Zw== - -nice-try@^1.0.4: - version "1.0.5" - resolved "https://registry.yarnpkg.com/nice-try/-/nice-try-1.0.5.tgz#a3378a7696ce7d223e88fc9b764bd7ef1089e366" - integrity sha512-1nh45deeb5olNY7eX82BkPO7SSxR5SSYJiPTrTdFUVYwAl8CKMA5N9PjTYkHiRjisVcxcQ1HXdLhx2qxxJzLNQ== - -no-case@^2.2.0: - version "2.3.2" - resolved "https://registry.yarnpkg.com/no-case/-/no-case-2.3.2.tgz#60b813396be39b3f1288a4c1ed5d1e7d28b464ac" - integrity sha512-rmTZ9kz+f3rCvK2TD1Ue/oZlns7OGoIWP4fc3llxxRXlOkHKoWPPWJOfFYpITabSow43QJbRIoHQXtt10VldyQ== - dependencies: - lower-case "^1.1.1" - -node-forge@0.7.5: - version "0.7.5" - resolved "https://registry.yarnpkg.com/node-forge/-/node-forge-0.7.5.tgz#6c152c345ce11c52f465c2abd957e8639cd674df" - integrity sha512-MmbQJ2MTESTjt3Gi/3yG1wGpIMhUfcIypUCGtTizFR9IiccFwxSpfp0vtIZlkFclEqERemxfnSdZEMR9VqqEFQ== - -node-libs-browser@^2.0.0: - version "2.2.1" - resolved "https://registry.yarnpkg.com/node-libs-browser/-/node-libs-browser-2.2.1.tgz#b64f513d18338625f90346d27b0d235e631f6425" - integrity sha512-h/zcD8H9kaDZ9ALUWwlBUDo6TKF8a7qBSCSEGfjTVIYeqsioSKaAX+BN7NgiMGp6iSIXZ3PxgCu8KS3b71YK5Q== - dependencies: - assert "^1.1.1" - browserify-zlib "^0.2.0" - buffer "^4.3.0" - console-browserify "^1.1.0" - constants-browserify "^1.0.0" - crypto-browserify "^3.11.0" - domain-browser "^1.1.1" - events "^3.0.0" - https-browserify "^1.0.0" - os-browserify "^0.3.0" - path-browserify "0.0.1" - process "^0.11.10" - punycode "^1.2.4" - querystring-es3 "^0.2.0" - readable-stream "^2.3.3" - stream-browserify "^2.0.1" - stream-http "^2.7.2" - string_decoder "^1.0.0" - timers-browserify "^2.0.4" - tty-browserify "0.0.0" - url "^0.11.0" - util "^0.11.0" - vm-browserify "^1.0.1" - -node-pre-gyp@^0.12.0: - version "0.12.0" - resolved "https://registry.yarnpkg.com/node-pre-gyp/-/node-pre-gyp-0.12.0.tgz#39ba4bb1439da030295f899e3b520b7785766149" - integrity sha512-4KghwV8vH5k+g2ylT+sLTjy5wmUOb9vPhnM8NHvRf9dHmnW/CndrFXy2aRPaPST6dugXSdHXfeaHQm77PIz/1A== - dependencies: - detect-libc "^1.0.2" - mkdirp "^0.5.1" - needle "^2.2.1" - nopt "^4.0.1" - npm-packlist "^1.1.6" - npmlog "^4.0.2" - rc "^1.2.7" - rimraf "^2.6.1" - semver "^5.3.0" - tar "^4" - -node-releases@^1.1.25: - version "1.1.25" - resolved "https://registry.yarnpkg.com/node-releases/-/node-releases-1.1.25.tgz#0c2d7dbc7fed30fbe02a9ee3007b8c90bf0133d3" - integrity sha512-fI5BXuk83lKEoZDdH3gRhtsNgh05/wZacuXkgbiYkceE7+QIMXOg98n9ZV7mz27B+kFHnqHcUpscZZlGRSmTpQ== - dependencies: - semver "^5.3.0" - -nopt@1.0.10: - version "1.0.10" - resolved "https://registry.yarnpkg.com/nopt/-/nopt-1.0.10.tgz#6ddd21bd2a31417b92727dd585f8a6f37608ebee" - integrity sha1-bd0hvSoxQXuScn3Vhfim83YI6+4= - dependencies: - abbrev "1" - -nopt@^4.0.1: - version "4.0.1" - resolved "https://registry.yarnpkg.com/nopt/-/nopt-4.0.1.tgz#d0d4685afd5415193c8c7505602d0d17cd64474d" - integrity sha1-0NRoWv1UFRk8jHUFYC0NF81kR00= - dependencies: - abbrev "1" - osenv "^0.1.4" - -normalize-path@^2.1.1: - version "2.1.1" - resolved "https://registry.yarnpkg.com/normalize-path/-/normalize-path-2.1.1.tgz#1ab28b556e198363a8c1a6f7e6fa20137fe6aed9" - integrity sha1-GrKLVW4Zg2Oowab35vogE3/mrtk= - dependencies: - remove-trailing-separator "^1.0.1" - -normalize-path@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/normalize-path/-/normalize-path-3.0.0.tgz#0dcd69ff23a1c9b11fd0978316644a0388216a65" - integrity sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA== - -normalize-range@^0.1.2: - version "0.1.2" - resolved "https://registry.yarnpkg.com/normalize-range/-/normalize-range-0.1.2.tgz#2d10c06bdfd312ea9777695a4d28439456b75942" - integrity sha1-LRDAa9/TEuqXd2laTShDlFa3WUI= - -normalize-url@^2.0.1: - version "2.0.1" - resolved "https://registry.yarnpkg.com/normalize-url/-/normalize-url-2.0.1.tgz#835a9da1551fa26f70e92329069a23aa6574d7e6" - integrity sha512-D6MUW4K/VzoJ4rJ01JFKxDrtY1v9wrgzCX5f2qj/lzH1m/lW6MhUZFKerVsnyjOhOsYzI9Kqqak+10l4LvLpMw== - dependencies: - prepend-http "^2.0.0" - query-string "^5.0.1" - sort-keys "^2.0.0" - -normalize-url@^3.0.0: - version "3.3.0" - resolved "https://registry.yarnpkg.com/normalize-url/-/normalize-url-3.3.0.tgz#b2e1c4dc4f7c6d57743df733a4f5978d18650559" - integrity sha512-U+JJi7duF1o+u2pynbp2zXDW2/PADgC30f0GsHZtRh+HOcXHnw137TrNlyxxRvWW5fjKd3bcLHPxofWuCjaeZg== - -npm-bundled@^1.0.1: - version "1.0.6" - resolved "https://registry.yarnpkg.com/npm-bundled/-/npm-bundled-1.0.6.tgz#e7ba9aadcef962bb61248f91721cd932b3fe6bdd" - integrity sha512-8/JCaftHwbd//k6y2rEWp6k1wxVfpFzB6t1p825+cUb7Ym2XQfhwIC5KwhrvzZRJu+LtDE585zVaS32+CGtf0g== - -npm-packlist@^1.1.6: - version "1.4.4" - resolved "https://registry.yarnpkg.com/npm-packlist/-/npm-packlist-1.4.4.tgz#866224233850ac534b63d1a6e76050092b5d2f44" - integrity sha512-zTLo8UcVYtDU3gdeaFu2Xu0n0EvelfHDGuqtNIn5RO7yQj4H1TqNdBc/yZjxnWA0PVB8D3Woyp0i5B43JwQ6Vw== - dependencies: - ignore-walk "^3.0.1" - npm-bundled "^1.0.1" - -npm-run-path@^2.0.0: - version "2.0.2" - resolved "https://registry.yarnpkg.com/npm-run-path/-/npm-run-path-2.0.2.tgz#35a9232dfa35d7067b4cb2ddf2357b1871536c5f" - integrity sha1-NakjLfo11wZ7TLLd8jV7GHFTbF8= - dependencies: - path-key "^2.0.0" - -npmlog@^4.0.2: - version "4.1.2" - resolved "https://registry.yarnpkg.com/npmlog/-/npmlog-4.1.2.tgz#08a7f2a8bf734604779a9efa4ad5cc717abb954b" - integrity sha512-2uUqazuKlTaSI/dC8AzicUck7+IrEaOnN/e0jd3Xtt1KcGpwx30v50mL7oPyr/h9bL3E4aZccVwpwP+5W9Vjkg== - dependencies: - are-we-there-yet "~1.1.2" - console-control-strings "~1.1.0" - gauge "~2.7.3" - set-blocking "~2.0.0" - -nprogress@^0.2.0: - version "0.2.0" - resolved "https://registry.yarnpkg.com/nprogress/-/nprogress-0.2.0.tgz#cb8f34c53213d895723fcbab907e9422adbcafb1" - integrity sha1-y480xTIT2JVyP8urkH6UIq28r7E= - -nth-check@^1.0.2, nth-check@~1.0.1: - version "1.0.2" - resolved "https://registry.yarnpkg.com/nth-check/-/nth-check-1.0.2.tgz#b2bd295c37e3dd58a3bf0700376663ba4d9cf05c" - integrity sha512-WeBOdju8SnzPN5vTUJYxYUxLeXpCaVP5i5e0LF8fg7WORF2Wd7wFX/pk0tYZk7s8T+J7VLy0Da6J1+wCT0AtHg== - dependencies: - boolbase "~1.0.0" - -num2fraction@^1.2.2: - version "1.2.2" - resolved "https://registry.yarnpkg.com/num2fraction/-/num2fraction-1.2.2.tgz#6f682b6a027a4e9ddfa4564cd2589d1d4e669ede" - integrity sha1-b2gragJ6Tp3fpFZM0lidHU5mnt4= - -number-is-nan@^1.0.0: - version "1.0.1" - resolved "https://registry.yarnpkg.com/number-is-nan/-/number-is-nan-1.0.1.tgz#097b602b53422a522c1afb8790318336941a011d" - integrity sha1-CXtgK1NCKlIsGvuHkDGDNpQaAR0= - -oauth-sign@~0.9.0: - version "0.9.0" - resolved "https://registry.yarnpkg.com/oauth-sign/-/oauth-sign-0.9.0.tgz#47a7b016baa68b5fa0ecf3dee08a85c679ac6455" - integrity sha512-fexhUFFPTGV8ybAtSIGbV6gOkSv8UtRbDBnAyLQw4QPKkgNlsH2ByPGtMUqdWkos6YCRmAqViwgZrJc/mRDzZQ== - -object-assign@^4.0.1, object-assign@^4.1.0, object-assign@^4.1.1: - version "4.1.1" - resolved "https://registry.yarnpkg.com/object-assign/-/object-assign-4.1.1.tgz#2109adc7965887cfc05cbbd442cac8bfbb360863" - integrity sha1-IQmtx5ZYh8/AXLvUQsrIv7s2CGM= - -object-copy@^0.1.0: - version "0.1.0" - resolved "https://registry.yarnpkg.com/object-copy/-/object-copy-0.1.0.tgz#7e7d858b781bd7c991a41ba975ed3812754e998c" - integrity sha1-fn2Fi3gb18mRpBupde04EnVOmYw= - dependencies: - copy-descriptor "^0.1.0" - define-property "^0.2.5" - kind-of "^3.0.3" - -object-keys@^1.0.11, object-keys@^1.0.12, object-keys@^1.1.0: - version "1.1.1" - resolved "https://registry.yarnpkg.com/object-keys/-/object-keys-1.1.1.tgz#1c47f272df277f3b1daf061677d9c82e2322c60e" - integrity sha512-NuAESUOUMrlIXOfHKzD6bpPu3tYt3xvjNdRIQ+FeT0lNb4K8WR70CaDxhuNguS2XG+GjkyMwOzsN5ZktImfhLA== - -object-visit@^1.0.0: - version "1.0.1" - resolved "https://registry.yarnpkg.com/object-visit/-/object-visit-1.0.1.tgz#f79c4493af0c5377b59fe39d395e41042dd045bb" - integrity sha1-95xEk68MU3e1n+OdOV5BBC3QRbs= - dependencies: - isobject "^3.0.0" - -object.assign@^4.1.0: - version "4.1.0" - resolved "https://registry.yarnpkg.com/object.assign/-/object.assign-4.1.0.tgz#968bf1100d7956bb3ca086f006f846b3bc4008da" - integrity sha512-exHJeq6kBKj58mqGyTQ9DFvrZC/eR6OwxzoM9YRoGBqrXYonaFyGiFMuc9VZrXf7DarreEwMpurG3dd+CNyW5w== - dependencies: - define-properties "^1.1.2" - function-bind "^1.1.1" - has-symbols "^1.0.0" - object-keys "^1.0.11" - -object.getownpropertydescriptors@^2.0.3: - version "2.0.3" - resolved "https://registry.yarnpkg.com/object.getownpropertydescriptors/-/object.getownpropertydescriptors-2.0.3.tgz#8758c846f5b407adab0f236e0986f14b051caa16" - integrity sha1-h1jIRvW0B62rDyNuCYbxSwUcqhY= - dependencies: - define-properties "^1.1.2" - es-abstract "^1.5.1" - -object.pick@^1.3.0: - version "1.3.0" - resolved "https://registry.yarnpkg.com/object.pick/-/object.pick-1.3.0.tgz#87a10ac4c1694bd2e1cbf53591a66141fb5dd747" - integrity sha1-h6EKxMFpS9Lhy/U1kaZhQftd10c= - dependencies: - isobject "^3.0.1" - -object.values@^1.1.0: - version "1.1.0" - resolved "https://registry.yarnpkg.com/object.values/-/object.values-1.1.0.tgz#bf6810ef5da3e5325790eaaa2be213ea84624da9" - integrity sha512-8mf0nKLAoFX6VlNVdhGj31SVYpaNFtUnuoOXWyFEstsWRgU837AK+JYM0iAxwkSzGRbwn8cbFmgbyxj1j4VbXg== - dependencies: - define-properties "^1.1.3" - es-abstract "^1.12.0" - function-bind "^1.1.1" - has "^1.0.3" - -obuf@^1.0.0, obuf@^1.1.2: - version "1.1.2" - resolved "https://registry.yarnpkg.com/obuf/-/obuf-1.1.2.tgz#09bea3343d41859ebd446292d11c9d4db619084e" - integrity sha512-PX1wu0AmAdPqOL1mWhqmlOd8kOIZQwGZw6rh7uby9fTc5lhaOWFLX3I6R1hrF9k3zUY40e6igsLGkDXK92LJNg== - -on-finished@~2.3.0: - version "2.3.0" - resolved "https://registry.yarnpkg.com/on-finished/-/on-finished-2.3.0.tgz#20f1336481b083cd75337992a16971aa2d906947" - integrity sha1-IPEzZIGwg811M3mSoWlxqi2QaUc= - dependencies: - ee-first "1.1.1" - -on-headers@~1.0.2: - version "1.0.2" - resolved "https://registry.yarnpkg.com/on-headers/-/on-headers-1.0.2.tgz#772b0ae6aaa525c399e489adfad90c403eb3c28f" - integrity sha512-pZAE+FJLoyITytdqK0U5s+FIpjN0JP3OzFi/u8Rx+EV5/W+JTWGXG8xFzevE7AjBfDqHv/8vL8qQsIhHnqRkrA== - -once@^1.3.0, once@^1.3.1, once@^1.4.0: - version "1.4.0" - resolved "https://registry.yarnpkg.com/once/-/once-1.4.0.tgz#583b1aa775961d4b113ac17d9c50baef9dd76bd1" - integrity sha1-WDsap3WWHUsROsF9nFC6753Xa9E= - dependencies: - wrappy "1" - -opn@^5.5.0: - version "5.5.0" - resolved "https://registry.yarnpkg.com/opn/-/opn-5.5.0.tgz#fc7164fab56d235904c51c3b27da6758ca3b9bfc" - integrity sha512-PqHpggC9bLV0VeWcdKhkpxY+3JTzetLSqTCWL/z/tFIbI6G8JCjondXklT1JinczLz2Xib62sSp0T/gKT4KksA== - dependencies: - is-wsl "^1.1.0" - -optimize-css-assets-webpack-plugin@^5.0.1: - version "5.0.3" - resolved "https://registry.yarnpkg.com/optimize-css-assets-webpack-plugin/-/optimize-css-assets-webpack-plugin-5.0.3.tgz#e2f1d4d94ad8c0af8967ebd7cf138dcb1ef14572" - integrity sha512-q9fbvCRS6EYtUKKSwI87qm2IxlyJK5b4dygW1rKUBT6mMDhdG5e5bZT63v6tnJR9F9FB/H5a0HTmtw+laUBxKA== - dependencies: - cssnano "^4.1.10" - last-call-webpack-plugin "^3.0.0" - -original@^1.0.0: - version "1.0.2" - resolved "https://registry.yarnpkg.com/original/-/original-1.0.2.tgz#e442a61cffe1c5fd20a65f3261c26663b303f25f" - integrity sha512-hyBVl6iqqUOJ8FqRe+l/gS8H+kKYjrEndd5Pm1MfBtsEKA038HkkdbAl/72EAXGyonD/PFsvmVG+EvcIpliMBg== - dependencies: - url-parse "^1.4.3" - -os-browserify@^0.3.0: - version "0.3.0" - resolved "https://registry.yarnpkg.com/os-browserify/-/os-browserify-0.3.0.tgz#854373c7f5c2315914fc9bfc6bd8238fdda1ec27" - integrity sha1-hUNzx/XCMVkU/Jv8a9gjj92h7Cc= - -os-homedir@^1.0.0: - version "1.0.2" - resolved "https://registry.yarnpkg.com/os-homedir/-/os-homedir-1.0.2.tgz#ffbc4988336e0e833de0c168c7ef152121aa7fb3" - integrity sha1-/7xJiDNuDoM94MFox+8VISGqf7M= - -os-locale@^3.0.0: - version "3.1.0" - resolved "https://registry.yarnpkg.com/os-locale/-/os-locale-3.1.0.tgz#a802a6ee17f24c10483ab9935719cef4ed16bf1a" - integrity sha512-Z8l3R4wYWM40/52Z+S265okfFj8Kt2cC2MKY+xNi3kFs+XGI7WXu/I309QQQYbRW4ijiZ+yxs9pqEhJh0DqW3Q== - dependencies: - execa "^1.0.0" - lcid "^2.0.0" - mem "^4.0.0" - -os-tmpdir@^1.0.0: - version "1.0.2" - resolved "https://registry.yarnpkg.com/os-tmpdir/-/os-tmpdir-1.0.2.tgz#bbe67406c79aa85c5cfec766fe5734555dfa1274" - integrity sha1-u+Z0BseaqFxc/sdm/lc0VV36EnQ= - -osenv@^0.1.4: - version "0.1.5" - resolved "https://registry.yarnpkg.com/osenv/-/osenv-0.1.5.tgz#85cdfafaeb28e8677f416e287592b5f3f49ea410" - integrity sha512-0CWcCECdMVc2Rw3U5w9ZjqX6ga6ubk1xDVKxtBQPK7wis/0F2r9T6k4ydGYhecl7YUBxBVxhL5oisPsNxAPe2g== - dependencies: - os-homedir "^1.0.0" - os-tmpdir "^1.0.0" - -p-defer@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/p-defer/-/p-defer-1.0.0.tgz#9f6eb182f6c9aa8cd743004a7d4f96b196b0fb0c" - integrity sha1-n26xgvbJqozXQwBKfU+WsZaw+ww= - -p-finally@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/p-finally/-/p-finally-1.0.0.tgz#3fbcfb15b899a44123b34b6dcc18b724336a2cae" - integrity sha1-P7z7FbiZpEEjs0ttzBi3JDNqLK4= - -p-is-promise@^2.0.0: - version "2.1.0" - resolved "https://registry.yarnpkg.com/p-is-promise/-/p-is-promise-2.1.0.tgz#918cebaea248a62cf7ffab8e3bca8c5f882fc42e" - integrity sha512-Y3W0wlRPK8ZMRbNq97l4M5otioeA5lm1z7bkNkxCka8HSPjR0xRWmpCmc9utiaLP9Jb1eD8BgeIxTW4AIF45Pg== - -p-limit@^1.1.0: - version "1.3.0" - resolved "https://registry.yarnpkg.com/p-limit/-/p-limit-1.3.0.tgz#b86bd5f0c25690911c7590fcbfc2010d54b3ccb8" - integrity sha512-vvcXsLAJ9Dr5rQOPk7toZQZJApBl2K4J6dANSsEuh6QI41JYcsS/qhTGa9ErIUUgK3WNQoJYvylxvjqmiqEA9Q== - dependencies: - p-try "^1.0.0" - -p-limit@^2.0.0, p-limit@^2.2.0: - version "2.2.0" - resolved "https://registry.yarnpkg.com/p-limit/-/p-limit-2.2.0.tgz#417c9941e6027a9abcba5092dd2904e255b5fbc2" - integrity sha512-pZbTJpoUsCzV48Mc9Nh51VbwO0X9cuPFE8gYwx9BTCt9SF8/b7Zljd2fVgOxhIF/HDTKgpVzs+GPhyKfjLLFRQ== - dependencies: - p-try "^2.0.0" - -p-locate@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/p-locate/-/p-locate-2.0.0.tgz#20a0103b222a70c8fd39cc2e580680f3dde5ec43" - integrity sha1-IKAQOyIqcMj9OcwuWAaA893l7EM= - dependencies: - p-limit "^1.1.0" - -p-locate@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/p-locate/-/p-locate-3.0.0.tgz#322d69a05c0264b25997d9f40cd8a891ab0064a4" - integrity sha512-x+12w/To+4GFfgJhBEpiDcLozRJGegY+Ei7/z0tSLkMmxGZNybVMSfWj9aJn8Z5Fc7dBUNJOOVgPv2H7IwulSQ== - dependencies: - p-limit "^2.0.0" - -p-map@^2.0.0: - version "2.1.0" - resolved "https://registry.yarnpkg.com/p-map/-/p-map-2.1.0.tgz#310928feef9c9ecc65b68b17693018a665cea175" - integrity sha512-y3b8Kpd8OAN444hxfBbFfj1FY/RjtTd8tzYwhUqNYXx0fXx2iX4maP4Qr6qhIKbQXI02wTLAda4fYUbDagTUFw== - -p-retry@^3.0.1: - version "3.0.1" - resolved "https://registry.yarnpkg.com/p-retry/-/p-retry-3.0.1.tgz#316b4c8893e2c8dc1cfa891f406c4b422bebf328" - integrity sha512-XE6G4+YTTkT2a0UWb2kjZe8xNwf8bIbnqpc/IS/idOBVhyves0mK5OJgeocjx7q5pvX/6m23xuzVPYT1uGM73w== - dependencies: - retry "^0.12.0" - -p-try@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/p-try/-/p-try-1.0.0.tgz#cbc79cdbaf8fd4228e13f621f2b1a237c1b207b3" - integrity sha1-y8ec26+P1CKOE/Yh8rGiN8GyB7M= - -p-try@^2.0.0: - version "2.2.0" - resolved "https://registry.yarnpkg.com/p-try/-/p-try-2.2.0.tgz#cb2868540e313d61de58fafbe35ce9004d5540e6" - integrity sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ== - -pako@~1.0.5: - version "1.0.10" - resolved "https://registry.yarnpkg.com/pako/-/pako-1.0.10.tgz#4328badb5086a426aa90f541977d4955da5c9732" - integrity sha512-0DTvPVU3ed8+HNXOu5Bs+o//Mbdj9VNQMUOe9oKCwh8l0GNwpTDMKCWbRjgtD291AWnkAgkqA/LOnQS8AmS1tw== - -parallel-transform@^1.1.0: - version "1.1.0" - resolved "https://registry.yarnpkg.com/parallel-transform/-/parallel-transform-1.1.0.tgz#d410f065b05da23081fcd10f28854c29bda33b06" - integrity sha1-1BDwZbBdojCB/NEPKIVMKb2jOwY= - dependencies: - cyclist "~0.2.2" - inherits "^2.0.3" - readable-stream "^2.1.5" - -param-case@2.1.x: - version "2.1.1" - resolved "https://registry.yarnpkg.com/param-case/-/param-case-2.1.1.tgz#df94fd8cf6531ecf75e6bef9a0858fbc72be2247" - integrity sha1-35T9jPZTHs915r75oIWPvHK+Ikc= - dependencies: - no-case "^2.2.0" - -parse-asn1@^5.0.0: - version "5.1.4" - resolved "https://registry.yarnpkg.com/parse-asn1/-/parse-asn1-5.1.4.tgz#37f6628f823fbdeb2273b4d540434a22f3ef1fcc" - integrity sha512-Qs5duJcuvNExRfFZ99HDD3z4mAi3r9Wl/FOjEOijlxwCZs7E7mW2vjTpgQ4J8LpTF8x5v+1Vn5UQFejmWT11aw== - dependencies: - asn1.js "^4.0.0" - browserify-aes "^1.0.0" - create-hash "^1.1.0" - evp_bytestokey "^1.0.0" - pbkdf2 "^3.0.3" - safe-buffer "^5.1.1" - -parse-json@^4.0.0: - version "4.0.0" - resolved "https://registry.yarnpkg.com/parse-json/-/parse-json-4.0.0.tgz#be35f5425be1f7f6c747184f98a788cb99477ee0" - integrity sha1-vjX1Qlvh9/bHRxhPmKeIy5lHfuA= - dependencies: - error-ex "^1.3.1" - json-parse-better-errors "^1.0.1" - -parseurl@~1.3.2, parseurl@~1.3.3: - version "1.3.3" - resolved "https://registry.yarnpkg.com/parseurl/-/parseurl-1.3.3.tgz#9da19e7bee8d12dff0513ed5b76957793bc2e8d4" - integrity sha512-CiyeOxFT/JZyN5m0z9PfXw4SCBJ6Sygz1Dpl0wqjlhDEGGBP1GnsUVEL0p63hoG1fcj3fHynXi9NYO4nWOL+qQ== - -pascalcase@^0.1.1: - version "0.1.1" - resolved "https://registry.yarnpkg.com/pascalcase/-/pascalcase-0.1.1.tgz#b363e55e8006ca6fe21784d2db22bd15d7917f14" - integrity sha1-s2PlXoAGym/iF4TS2yK9FdeRfxQ= - -path-browserify@0.0.1: - version "0.0.1" - resolved "https://registry.yarnpkg.com/path-browserify/-/path-browserify-0.0.1.tgz#e6c4ddd7ed3aa27c68a20cc4e50e1a4ee83bbc4a" - integrity sha512-BapA40NHICOS+USX9SN4tyhq+A2RrN/Ws5F0Z5aMHDp98Fl86lX8Oti8B7uN93L4Ifv4fHOEA+pQw87gmMO/lQ== - -path-dirname@^1.0.0: - version "1.0.2" - resolved "https://registry.yarnpkg.com/path-dirname/-/path-dirname-1.0.2.tgz#cc33d24d525e099a5388c0336c6e32b9160609e0" - integrity sha1-zDPSTVJeCZpTiMAzbG4yuRYGCeA= - -path-exists@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/path-exists/-/path-exists-3.0.0.tgz#ce0ebeaa5f78cb18925ea7d810d7b59b010fd515" - integrity sha1-zg6+ql94yxiSXqfYENe1mwEP1RU= - -path-is-absolute@^1.0.0: - version "1.0.1" - resolved "https://registry.yarnpkg.com/path-is-absolute/-/path-is-absolute-1.0.1.tgz#174b9268735534ffbc7ace6bf53a5a9e1b5c5f5f" - integrity sha1-F0uSaHNVNP+8es5r9TpanhtcX18= - -path-is-inside@^1.0.2: - version "1.0.2" - resolved "https://registry.yarnpkg.com/path-is-inside/-/path-is-inside-1.0.2.tgz#365417dede44430d1c11af61027facf074bdfc53" - integrity sha1-NlQX3t5EQw0cEa9hAn+s8HS9/FM= - -path-key@^2.0.0, path-key@^2.0.1: - version "2.0.1" - resolved "https://registry.yarnpkg.com/path-key/-/path-key-2.0.1.tgz#411cadb574c5a140d3a4b1910d40d80cc9f40b40" - integrity sha1-QRyttXTFoUDTpLGRDUDYDMn0C0A= - -path-parse@^1.0.6: - version "1.0.6" - resolved "https://registry.yarnpkg.com/path-parse/-/path-parse-1.0.6.tgz#d62dbb5679405d72c4737ec58600e9ddcf06d24c" - integrity sha512-GSmOT2EbHrINBf9SR7CDELwlJ8AENk3Qn7OikK4nFYAu3Ote2+JYNVvkpAEQm3/TLNEJFD/xZJjzyxg3KBWOzw== - -path-to-regexp@0.1.7: - version "0.1.7" - resolved "https://registry.yarnpkg.com/path-to-regexp/-/path-to-regexp-0.1.7.tgz#df604178005f522f15eb4490e7247a1bfaa67f8c" - integrity sha1-32BBeABfUi8V60SQ5yR6G/qmf4w= - -path-type@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/path-type/-/path-type-3.0.0.tgz#cef31dc8e0a1a3bb0d105c0cd97cf3bf47f4e36f" - integrity sha512-T2ZUsdZFHgA3u4e5PfPbjd7HDDpxPnQb5jN0SrDsjNSuVXHJqtwTnWqG0B1jZrgmJ/7lj1EmVIByWt1gxGkWvg== - dependencies: - pify "^3.0.0" - -pbkdf2@^3.0.3: - version "3.0.17" - resolved "https://registry.yarnpkg.com/pbkdf2/-/pbkdf2-3.0.17.tgz#976c206530617b14ebb32114239f7b09336e93a6" - integrity sha512-U/il5MsrZp7mGg3mSQfn742na2T+1/vHDCG5/iTI3X9MKUuYUZVLQhyRsg06mCgDBTd57TxzgZt7P+fYfjRLtA== - dependencies: - create-hash "^1.1.2" - create-hmac "^1.1.4" - ripemd160 "^2.0.1" - safe-buffer "^5.0.1" - sha.js "^2.4.8" - -performance-now@^2.1.0: - version "2.1.0" - resolved "https://registry.yarnpkg.com/performance-now/-/performance-now-2.1.0.tgz#6309f4e0e5fa913ec1c69307ae364b4b377c9e7b" - integrity sha1-Ywn04OX6kT7BxpMHrjZLSzd8nns= - -pify@^2.0.0: - version "2.3.0" - resolved "https://registry.yarnpkg.com/pify/-/pify-2.3.0.tgz#ed141a6ac043a849ea588498e7dca8b15330e90c" - integrity sha1-7RQaasBDqEnqWISY59yosVMw6Qw= - -pify@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/pify/-/pify-3.0.0.tgz#e5a4acd2c101fdf3d9a4d07f0dbc4db49dd28176" - integrity sha1-5aSs0sEB/fPZpNB/DbxNtJ3SgXY= - -pify@^4.0.1: - version "4.0.1" - resolved "https://registry.yarnpkg.com/pify/-/pify-4.0.1.tgz#4b2cd25c50d598735c50292224fd8c6df41e3231" - integrity sha512-uB80kBFb/tfd68bVleG9T5GGsGPjJrLAUpR5PZIrhBnIaRTQRjqdJSsIKkOP6OAIFbj7GOrcudc5pNjZ+geV2g== - -pinkie-promise@^2.0.0: - version "2.0.1" - resolved "https://registry.yarnpkg.com/pinkie-promise/-/pinkie-promise-2.0.1.tgz#2135d6dfa7a358c069ac9b178776288228450ffa" - integrity sha1-ITXW36ejWMBprJsXh3YogihFD/o= - dependencies: - pinkie "^2.0.0" - -pinkie@^2.0.0: - version "2.0.4" - resolved "https://registry.yarnpkg.com/pinkie/-/pinkie-2.0.4.tgz#72556b80cfa0d48a974e80e77248e80ed4f7f870" - integrity sha1-clVrgM+g1IqXToDnckjoDtT3+HA= - -pkg-dir@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/pkg-dir/-/pkg-dir-3.0.0.tgz#2749020f239ed990881b1f71210d51eb6523bea3" - integrity sha512-/E57AYkoeQ25qkxMj5PBOVgF8Kiu/h7cYS30Z5+R7WaiCCBfLq58ZI/dSeaEKb9WVJV5n/03QwrN3IeWIFllvw== - dependencies: - find-up "^3.0.0" - -pkg-up@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/pkg-up/-/pkg-up-2.0.0.tgz#c819ac728059a461cab1c3889a2be3c49a004d7f" - integrity sha1-yBmscoBZpGHKscOImivjxJoATX8= - dependencies: - find-up "^2.1.0" - -portfinder@^1.0.13, portfinder@^1.0.20: - version "1.0.21" - resolved "https://registry.yarnpkg.com/portfinder/-/portfinder-1.0.21.tgz#60e1397b95ac170749db70034ece306b9a27e324" - integrity sha512-ESabpDCzmBS3ekHbmpAIiESq3udRsCBGiBZLsC+HgBKv2ezb0R4oG+7RnYEVZ/ZCfhel5Tx3UzdNWA0Lox2QCA== - dependencies: - async "^1.5.2" - debug "^2.2.0" - mkdirp "0.5.x" - -posix-character-classes@^0.1.0: - version "0.1.1" - resolved "https://registry.yarnpkg.com/posix-character-classes/-/posix-character-classes-0.1.1.tgz#01eac0fe3b5af71a2a6c02feabb8c1fef7e00eab" - integrity sha1-AerA/jta9xoqbAL+q7jB/vfgDqs= - -postcss-calc@^7.0.1: - version "7.0.1" - resolved "https://registry.yarnpkg.com/postcss-calc/-/postcss-calc-7.0.1.tgz#36d77bab023b0ecbb9789d84dcb23c4941145436" - integrity sha512-oXqx0m6tb4N3JGdmeMSc/i91KppbYsFZKdH0xMOqK8V1rJlzrKlTdokz8ozUXLVejydRN6u2IddxpcijRj2FqQ== - dependencies: - css-unit-converter "^1.1.1" - postcss "^7.0.5" - postcss-selector-parser "^5.0.0-rc.4" - postcss-value-parser "^3.3.1" - -postcss-colormin@^4.0.3: - version "4.0.3" - resolved "https://registry.yarnpkg.com/postcss-colormin/-/postcss-colormin-4.0.3.tgz#ae060bce93ed794ac71264f08132d550956bd381" - integrity sha512-WyQFAdDZpExQh32j0U0feWisZ0dmOtPl44qYmJKkq9xFWY3p+4qnRzCHeNrkeRhwPHz9bQ3mo0/yVkaply0MNw== - dependencies: - browserslist "^4.0.0" - color "^3.0.0" - has "^1.0.0" - postcss "^7.0.0" - postcss-value-parser "^3.0.0" - -postcss-convert-values@^4.0.1: - version "4.0.1" - resolved "https://registry.yarnpkg.com/postcss-convert-values/-/postcss-convert-values-4.0.1.tgz#ca3813ed4da0f812f9d43703584e449ebe189a7f" - integrity sha512-Kisdo1y77KUC0Jmn0OXU/COOJbzM8cImvw1ZFsBgBgMgb1iL23Zs/LXRe3r+EZqM3vGYKdQ2YJVQ5VkJI+zEJQ== - dependencies: - postcss "^7.0.0" - postcss-value-parser "^3.0.0" - -postcss-discard-comments@^4.0.2: - version "4.0.2" - resolved "https://registry.yarnpkg.com/postcss-discard-comments/-/postcss-discard-comments-4.0.2.tgz#1fbabd2c246bff6aaad7997b2b0918f4d7af4033" - integrity sha512-RJutN259iuRf3IW7GZyLM5Sw4GLTOH8FmsXBnv8Ab/Tc2k4SR4qbV4DNbyyY4+Sjo362SyDmW2DQ7lBSChrpkg== - dependencies: - postcss "^7.0.0" - -postcss-discard-duplicates@^4.0.2: - version "4.0.2" - resolved "https://registry.yarnpkg.com/postcss-discard-duplicates/-/postcss-discard-duplicates-4.0.2.tgz#3fe133cd3c82282e550fc9b239176a9207b784eb" - integrity sha512-ZNQfR1gPNAiXZhgENFfEglF93pciw0WxMkJeVmw8eF+JZBbMD7jp6C67GqJAXVZP2BWbOztKfbsdmMp/k8c6oQ== - dependencies: - postcss "^7.0.0" - -postcss-discard-empty@^4.0.1: - version "4.0.1" - resolved "https://registry.yarnpkg.com/postcss-discard-empty/-/postcss-discard-empty-4.0.1.tgz#c8c951e9f73ed9428019458444a02ad90bb9f765" - integrity sha512-B9miTzbznhDjTfjvipfHoqbWKwd0Mj+/fL5s1QOz06wufguil+Xheo4XpOnc4NqKYBCNqqEzgPv2aPBIJLox0w== - dependencies: - postcss "^7.0.0" - -postcss-discard-overridden@^4.0.1: - version "4.0.1" - resolved "https://registry.yarnpkg.com/postcss-discard-overridden/-/postcss-discard-overridden-4.0.1.tgz#652aef8a96726f029f5e3e00146ee7a4e755ff57" - integrity sha512-IYY2bEDD7g1XM1IDEsUT4//iEYCxAmP5oDSFMVU/JVvT7gh+l4fmjciLqGgwjdWpQIdb0Che2VX00QObS5+cTg== - dependencies: - postcss "^7.0.0" - -postcss-load-config@^2.0.0: - version "2.1.0" - resolved "https://registry.yarnpkg.com/postcss-load-config/-/postcss-load-config-2.1.0.tgz#c84d692b7bb7b41ddced94ee62e8ab31b417b003" - integrity sha512-4pV3JJVPLd5+RueiVVB+gFOAa7GWc25XQcMp86Zexzke69mKf6Nx9LRcQywdz7yZI9n1udOxmLuAwTBypypF8Q== - dependencies: - cosmiconfig "^5.0.0" - import-cwd "^2.0.0" - -postcss-loader@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/postcss-loader/-/postcss-loader-3.0.0.tgz#6b97943e47c72d845fa9e03f273773d4e8dd6c2d" - integrity sha512-cLWoDEY5OwHcAjDnkyRQzAXfs2jrKjXpO/HQFcc5b5u/r7aa471wdmChmwfnv7x2u840iat/wi0lQ5nbRgSkUA== - dependencies: - loader-utils "^1.1.0" - postcss "^7.0.0" - postcss-load-config "^2.0.0" - schema-utils "^1.0.0" - -postcss-merge-longhand@^4.0.11: - version "4.0.11" - resolved "https://registry.yarnpkg.com/postcss-merge-longhand/-/postcss-merge-longhand-4.0.11.tgz#62f49a13e4a0ee04e7b98f42bb16062ca2549e24" - integrity sha512-alx/zmoeXvJjp7L4mxEMjh8lxVlDFX1gqWHzaaQewwMZiVhLo42TEClKaeHbRf6J7j82ZOdTJ808RtN0ZOZwvw== - dependencies: - css-color-names "0.0.4" - postcss "^7.0.0" - postcss-value-parser "^3.0.0" - stylehacks "^4.0.0" - -postcss-merge-rules@^4.0.3: - version "4.0.3" - resolved "https://registry.yarnpkg.com/postcss-merge-rules/-/postcss-merge-rules-4.0.3.tgz#362bea4ff5a1f98e4075a713c6cb25aefef9a650" - integrity sha512-U7e3r1SbvYzO0Jr3UT/zKBVgYYyhAz0aitvGIYOYK5CPmkNih+WDSsS5tvPrJ8YMQYlEMvsZIiqmn7HdFUaeEQ== - dependencies: - browserslist "^4.0.0" - caniuse-api "^3.0.0" - cssnano-util-same-parent "^4.0.0" - postcss "^7.0.0" - postcss-selector-parser "^3.0.0" - vendors "^1.0.0" - -postcss-minify-font-values@^4.0.2: - version "4.0.2" - resolved "https://registry.yarnpkg.com/postcss-minify-font-values/-/postcss-minify-font-values-4.0.2.tgz#cd4c344cce474343fac5d82206ab2cbcb8afd5a6" - integrity sha512-j85oO6OnRU9zPf04+PZv1LYIYOprWm6IA6zkXkrJXyRveDEuQggG6tvoy8ir8ZwjLxLuGfNkCZEQG7zan+Hbtg== - dependencies: - postcss "^7.0.0" - postcss-value-parser "^3.0.0" - -postcss-minify-gradients@^4.0.2: - version "4.0.2" - resolved "https://registry.yarnpkg.com/postcss-minify-gradients/-/postcss-minify-gradients-4.0.2.tgz#93b29c2ff5099c535eecda56c4aa6e665a663471" - integrity sha512-qKPfwlONdcf/AndP1U8SJ/uzIJtowHlMaSioKzebAXSG4iJthlWC9iSWznQcX4f66gIWX44RSA841HTHj3wK+Q== - dependencies: - cssnano-util-get-arguments "^4.0.0" - is-color-stop "^1.0.0" - postcss "^7.0.0" - postcss-value-parser "^3.0.0" - -postcss-minify-params@^4.0.2: - version "4.0.2" - resolved "https://registry.yarnpkg.com/postcss-minify-params/-/postcss-minify-params-4.0.2.tgz#6b9cef030c11e35261f95f618c90036d680db874" - integrity sha512-G7eWyzEx0xL4/wiBBJxJOz48zAKV2WG3iZOqVhPet/9geefm/Px5uo1fzlHu+DOjT+m0Mmiz3jkQzVHe6wxAWg== - dependencies: - alphanum-sort "^1.0.0" - browserslist "^4.0.0" - cssnano-util-get-arguments "^4.0.0" - postcss "^7.0.0" - postcss-value-parser "^3.0.0" - uniqs "^2.0.0" - -postcss-minify-selectors@^4.0.2: - version "4.0.2" - resolved "https://registry.yarnpkg.com/postcss-minify-selectors/-/postcss-minify-selectors-4.0.2.tgz#e2e5eb40bfee500d0cd9243500f5f8ea4262fbd8" - integrity sha512-D5S1iViljXBj9kflQo4YutWnJmwm8VvIsU1GeXJGiG9j8CIg9zs4voPMdQDUmIxetUOh60VilsNzCiAFTOqu3g== - dependencies: - alphanum-sort "^1.0.0" - has "^1.0.0" - postcss "^7.0.0" - postcss-selector-parser "^3.0.0" - -postcss-modules-extract-imports@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/postcss-modules-extract-imports/-/postcss-modules-extract-imports-2.0.0.tgz#818719a1ae1da325f9832446b01136eeb493cd7e" - integrity sha512-LaYLDNS4SG8Q5WAWqIJgdHPJrDDr/Lv775rMBFUbgjTz6j34lUznACHcdRWroPvXANP2Vj7yNK57vp9eFqzLWQ== - dependencies: - postcss "^7.0.5" - -postcss-modules-local-by-default@^2.0.6: - version "2.0.6" - resolved "https://registry.yarnpkg.com/postcss-modules-local-by-default/-/postcss-modules-local-by-default-2.0.6.tgz#dd9953f6dd476b5fd1ef2d8830c8929760b56e63" - integrity sha512-oLUV5YNkeIBa0yQl7EYnxMgy4N6noxmiwZStaEJUSe2xPMcdNc8WmBQuQCx18H5psYbVxz8zoHk0RAAYZXP9gA== - dependencies: - postcss "^7.0.6" - postcss-selector-parser "^6.0.0" - postcss-value-parser "^3.3.1" - -postcss-modules-scope@^2.1.0: - version "2.1.0" - resolved "https://registry.yarnpkg.com/postcss-modules-scope/-/postcss-modules-scope-2.1.0.tgz#ad3f5bf7856114f6fcab901b0502e2a2bc39d4eb" - integrity sha512-91Rjps0JnmtUB0cujlc8KIKCsJXWjzuxGeT/+Q2i2HXKZ7nBUeF9YQTZZTNvHVoNYj1AthsjnGLtqDUE0Op79A== - dependencies: - postcss "^7.0.6" - postcss-selector-parser "^6.0.0" - -postcss-modules-values@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/postcss-modules-values/-/postcss-modules-values-2.0.0.tgz#479b46dc0c5ca3dc7fa5270851836b9ec7152f64" - integrity sha512-Ki7JZa7ff1N3EIMlPnGTZfUMe69FFwiQPnVSXC9mnn3jozCRBYIxiZd44yJOV2AmabOo4qFf8s0dC/+lweG7+w== - dependencies: - icss-replace-symbols "^1.1.0" - postcss "^7.0.6" - -postcss-normalize-charset@^4.0.1: - version "4.0.1" - resolved "https://registry.yarnpkg.com/postcss-normalize-charset/-/postcss-normalize-charset-4.0.1.tgz#8b35add3aee83a136b0471e0d59be58a50285dd4" - integrity sha512-gMXCrrlWh6G27U0hF3vNvR3w8I1s2wOBILvA87iNXaPvSNo5uZAMYsZG7XjCUf1eVxuPfyL4TJ7++SGZLc9A3g== - dependencies: - postcss "^7.0.0" - -postcss-normalize-display-values@^4.0.2: - version "4.0.2" - resolved "https://registry.yarnpkg.com/postcss-normalize-display-values/-/postcss-normalize-display-values-4.0.2.tgz#0dbe04a4ce9063d4667ed2be476bb830c825935a" - integrity sha512-3F2jcsaMW7+VtRMAqf/3m4cPFhPD3EFRgNs18u+k3lTJJlVe7d0YPO+bnwqo2xg8YiRpDXJI2u8A0wqJxMsQuQ== - dependencies: - cssnano-util-get-match "^4.0.0" - postcss "^7.0.0" - postcss-value-parser "^3.0.0" - -postcss-normalize-positions@^4.0.2: - version "4.0.2" - resolved "https://registry.yarnpkg.com/postcss-normalize-positions/-/postcss-normalize-positions-4.0.2.tgz#05f757f84f260437378368a91f8932d4b102917f" - integrity sha512-Dlf3/9AxpxE+NF1fJxYDeggi5WwV35MXGFnnoccP/9qDtFrTArZ0D0R+iKcg5WsUd8nUYMIl8yXDCtcrT8JrdA== - dependencies: - cssnano-util-get-arguments "^4.0.0" - has "^1.0.0" - postcss "^7.0.0" - postcss-value-parser "^3.0.0" - -postcss-normalize-repeat-style@^4.0.2: - version "4.0.2" - resolved "https://registry.yarnpkg.com/postcss-normalize-repeat-style/-/postcss-normalize-repeat-style-4.0.2.tgz#c4ebbc289f3991a028d44751cbdd11918b17910c" - integrity sha512-qvigdYYMpSuoFs3Is/f5nHdRLJN/ITA7huIoCyqqENJe9PvPmLhNLMu7QTjPdtnVf6OcYYO5SHonx4+fbJE1+Q== - dependencies: - cssnano-util-get-arguments "^4.0.0" - cssnano-util-get-match "^4.0.0" - postcss "^7.0.0" - postcss-value-parser "^3.0.0" - -postcss-normalize-string@^4.0.2: - version "4.0.2" - resolved "https://registry.yarnpkg.com/postcss-normalize-string/-/postcss-normalize-string-4.0.2.tgz#cd44c40ab07a0c7a36dc5e99aace1eca4ec2690c" - integrity sha512-RrERod97Dnwqq49WNz8qo66ps0swYZDSb6rM57kN2J+aoyEAJfZ6bMx0sx/F9TIEX0xthPGCmeyiam/jXif0eA== - dependencies: - has "^1.0.0" - postcss "^7.0.0" - postcss-value-parser "^3.0.0" - -postcss-normalize-timing-functions@^4.0.2: - version "4.0.2" - resolved "https://registry.yarnpkg.com/postcss-normalize-timing-functions/-/postcss-normalize-timing-functions-4.0.2.tgz#8e009ca2a3949cdaf8ad23e6b6ab99cb5e7d28d9" - integrity sha512-acwJY95edP762e++00Ehq9L4sZCEcOPyaHwoaFOhIwWCDfik6YvqsYNxckee65JHLKzuNSSmAdxwD2Cud1Z54A== - dependencies: - cssnano-util-get-match "^4.0.0" - postcss "^7.0.0" - postcss-value-parser "^3.0.0" - -postcss-normalize-unicode@^4.0.1: - version "4.0.1" - resolved "https://registry.yarnpkg.com/postcss-normalize-unicode/-/postcss-normalize-unicode-4.0.1.tgz#841bd48fdcf3019ad4baa7493a3d363b52ae1cfb" - integrity sha512-od18Uq2wCYn+vZ/qCOeutvHjB5jm57ToxRaMeNuf0nWVHaP9Hua56QyMF6fs/4FSUnVIw0CBPsU0K4LnBPwYwg== - dependencies: - browserslist "^4.0.0" - postcss "^7.0.0" - postcss-value-parser "^3.0.0" - -postcss-normalize-url@^4.0.1: - version "4.0.1" - resolved "https://registry.yarnpkg.com/postcss-normalize-url/-/postcss-normalize-url-4.0.1.tgz#10e437f86bc7c7e58f7b9652ed878daaa95faae1" - integrity sha512-p5oVaF4+IHwu7VpMan/SSpmpYxcJMtkGppYf0VbdH5B6hN8YNmVyJLuY9FmLQTzY3fag5ESUUHDqM+heid0UVA== - dependencies: - is-absolute-url "^2.0.0" - normalize-url "^3.0.0" - postcss "^7.0.0" - postcss-value-parser "^3.0.0" - -postcss-normalize-whitespace@^4.0.2: - version "4.0.2" - resolved "https://registry.yarnpkg.com/postcss-normalize-whitespace/-/postcss-normalize-whitespace-4.0.2.tgz#bf1d4070fe4fcea87d1348e825d8cc0c5faa7d82" - integrity sha512-tO8QIgrsI3p95r8fyqKV+ufKlSHh9hMJqACqbv2XknufqEDhDvbguXGBBqxw9nsQoXWf0qOqppziKJKHMD4GtA== - dependencies: - postcss "^7.0.0" - postcss-value-parser "^3.0.0" - -postcss-ordered-values@^4.1.2: - version "4.1.2" - resolved "https://registry.yarnpkg.com/postcss-ordered-values/-/postcss-ordered-values-4.1.2.tgz#0cf75c820ec7d5c4d280189559e0b571ebac0eee" - integrity sha512-2fCObh5UanxvSxeXrtLtlwVThBvHn6MQcu4ksNT2tsaV2Fg76R2CV98W7wNSlX+5/pFwEyaDwKLLoEV7uRybAw== - dependencies: - cssnano-util-get-arguments "^4.0.0" - postcss "^7.0.0" - postcss-value-parser "^3.0.0" - -postcss-reduce-initial@^4.0.3: - version "4.0.3" - resolved "https://registry.yarnpkg.com/postcss-reduce-initial/-/postcss-reduce-initial-4.0.3.tgz#7fd42ebea5e9c814609639e2c2e84ae270ba48df" - integrity sha512-gKWmR5aUulSjbzOfD9AlJiHCGH6AEVLaM0AV+aSioxUDd16qXP1PCh8d1/BGVvpdWn8k/HiK7n6TjeoXN1F7DA== - dependencies: - browserslist "^4.0.0" - caniuse-api "^3.0.0" - has "^1.0.0" - postcss "^7.0.0" - -postcss-reduce-transforms@^4.0.2: - version "4.0.2" - resolved "https://registry.yarnpkg.com/postcss-reduce-transforms/-/postcss-reduce-transforms-4.0.2.tgz#17efa405eacc6e07be3414a5ca2d1074681d4e29" - integrity sha512-EEVig1Q2QJ4ELpJXMZR8Vt5DQx8/mo+dGWSR7vWXqcob2gQLyQGsionYcGKATXvQzMPn6DSN1vTN7yFximdIAg== - dependencies: - cssnano-util-get-match "^4.0.0" - has "^1.0.0" - postcss "^7.0.0" - postcss-value-parser "^3.0.0" - -postcss-safe-parser@^4.0.1: - version "4.0.1" - resolved "https://registry.yarnpkg.com/postcss-safe-parser/-/postcss-safe-parser-4.0.1.tgz#8756d9e4c36fdce2c72b091bbc8ca176ab1fcdea" - integrity sha512-xZsFA3uX8MO3yAda03QrG3/Eg1LN3EPfjjf07vke/46HERLZyHrTsQ9E1r1w1W//fWEhtYNndo2hQplN2cVpCQ== - dependencies: - postcss "^7.0.0" - -postcss-selector-parser@^3.0.0: - version "3.1.1" - resolved "https://registry.yarnpkg.com/postcss-selector-parser/-/postcss-selector-parser-3.1.1.tgz#4f875f4afb0c96573d5cf4d74011aee250a7e865" - integrity sha1-T4dfSvsMllc9XPTXQBGu4lCn6GU= - dependencies: - dot-prop "^4.1.1" - indexes-of "^1.0.1" - uniq "^1.0.1" - -postcss-selector-parser@^5.0.0, postcss-selector-parser@^5.0.0-rc.4: - version "5.0.0" - resolved "https://registry.yarnpkg.com/postcss-selector-parser/-/postcss-selector-parser-5.0.0.tgz#249044356697b33b64f1a8f7c80922dddee7195c" - integrity sha512-w+zLE5Jhg6Liz8+rQOWEAwtwkyqpfnmsinXjXg6cY7YIONZZtgvE0v2O0uhQBs0peNomOJwWRKt6JBfTdTd3OQ== - dependencies: - cssesc "^2.0.0" - indexes-of "^1.0.1" - uniq "^1.0.1" - -postcss-selector-parser@^6.0.0: - version "6.0.2" - resolved "https://registry.yarnpkg.com/postcss-selector-parser/-/postcss-selector-parser-6.0.2.tgz#934cf799d016c83411859e09dcecade01286ec5c" - integrity sha512-36P2QR59jDTOAiIkqEprfJDsoNrvwFei3eCqKd1Y0tUsBimsq39BLp7RD+JWny3WgB1zGhJX8XVePwm9k4wdBg== - dependencies: - cssesc "^3.0.0" - indexes-of "^1.0.1" - uniq "^1.0.1" - -postcss-svgo@^4.0.2: - version "4.0.2" - resolved "https://registry.yarnpkg.com/postcss-svgo/-/postcss-svgo-4.0.2.tgz#17b997bc711b333bab143aaed3b8d3d6e3d38258" - integrity sha512-C6wyjo3VwFm0QgBy+Fu7gCYOkCmgmClghO+pjcxvrcBKtiKt0uCF+hvbMO1fyv5BMImRK90SMb+dwUnfbGd+jw== - dependencies: - is-svg "^3.0.0" - postcss "^7.0.0" - postcss-value-parser "^3.0.0" - svgo "^1.0.0" - -postcss-unique-selectors@^4.0.1: - version "4.0.1" - resolved "https://registry.yarnpkg.com/postcss-unique-selectors/-/postcss-unique-selectors-4.0.1.tgz#9446911f3289bfd64c6d680f073c03b1f9ee4bac" - integrity sha512-+JanVaryLo9QwZjKrmJgkI4Fn8SBgRO6WXQBJi7KiAVPlmxikB5Jzc4EvXMT2H0/m0RjrVVm9rGNhZddm/8Spg== - dependencies: - alphanum-sort "^1.0.0" - postcss "^7.0.0" - uniqs "^2.0.0" - -postcss-value-parser@^3.0.0, postcss-value-parser@^3.3.0, postcss-value-parser@^3.3.1: - version "3.3.1" - resolved "https://registry.yarnpkg.com/postcss-value-parser/-/postcss-value-parser-3.3.1.tgz#9ff822547e2893213cf1c30efa51ac5fd1ba8281" - integrity sha512-pISE66AbVkp4fDQ7VHBwRNXzAAKJjw4Vw7nWI/+Q3vuly7SNfgYXvm6i5IgFylHGK5sP/xHAbB7N49OS4gWNyQ== - -postcss-value-parser@^4.0.0: - version "4.0.0" - resolved "https://registry.yarnpkg.com/postcss-value-parser/-/postcss-value-parser-4.0.0.tgz#99a983d365f7b2ad8d0f9b8c3094926eab4b936d" - integrity sha512-ESPktioptiSUchCKgggAkzdmkgzKfmp0EU8jXH+5kbIUB+unr0Y4CY9SRMvibuvYUBjNh1ACLbxqYNpdTQOteQ== - -postcss@^7.0.0, postcss@^7.0.1, postcss@^7.0.14, postcss@^7.0.17, postcss@^7.0.5, postcss@^7.0.6: - version "7.0.17" - resolved "https://registry.yarnpkg.com/postcss/-/postcss-7.0.17.tgz#4da1bdff5322d4a0acaab4d87f3e782436bad31f" - integrity sha512-546ZowA+KZ3OasvQZHsbuEpysvwTZNGJv9EfyCQdsIDltPSWHAeTQ5fQy/Npi2ZDtLI3zs7Ps/p6wThErhm9fQ== - dependencies: - chalk "^2.4.2" - source-map "^0.6.1" - supports-color "^6.1.0" - -prepend-http@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/prepend-http/-/prepend-http-2.0.0.tgz#e92434bfa5ea8c19f41cdfd401d741a3c819d897" - integrity sha1-6SQ0v6XqjBn0HN/UAddBo8gZ2Jc= - -prettier@1.16.3: - version "1.16.3" - resolved "https://registry.yarnpkg.com/prettier/-/prettier-1.16.3.tgz#8c62168453badef702f34b45b6ee899574a6a65d" - integrity sha512-kn/GU6SMRYPxUakNXhpP0EedT/KmaPzr0H5lIsDogrykbaxOpOfAFfk5XA7DZrJyMAv1wlMV3CPcZruGXVVUZw== - -pretty-error@^2.0.2: - version "2.1.1" - resolved "https://registry.yarnpkg.com/pretty-error/-/pretty-error-2.1.1.tgz#5f4f87c8f91e5ae3f3ba87ab4cf5e03b1a17f1a3" - integrity sha1-X0+HyPkeWuPzuoerTPXgOxoX8aM= - dependencies: - renderkid "^2.0.1" - utila "~0.4" - -pretty-time@^1.1.0: - version "1.1.0" - resolved "https://registry.yarnpkg.com/pretty-time/-/pretty-time-1.1.0.tgz#ffb7429afabb8535c346a34e41873adf3d74dd0e" - integrity sha512-28iF6xPQrP8Oa6uxE6a1biz+lWeTOAPKggvjB8HAs6nVMKZwf5bG++632Dx614hIWgUPkgivRfG+a8uAXGTIbA== - -prismjs@^1.13.0: - version "1.16.0" - resolved "https://registry.yarnpkg.com/prismjs/-/prismjs-1.16.0.tgz#406eb2c8aacb0f5f0f1167930cb83835d10a4308" - integrity sha512-OA4MKxjFZHSvZcisLGe14THYsug/nF6O1f0pAJc0KN0wTyAcLqmsbE+lTGKSpyh+9pEW57+k6pg2AfYR+coyHA== - optionalDependencies: - clipboard "^2.0.0" - -private@^0.1.6: - version "0.1.8" - resolved "https://registry.yarnpkg.com/private/-/private-0.1.8.tgz#2381edb3689f7a53d653190060fcf822d2f368ff" - integrity sha512-VvivMrbvd2nKkiG38qjULzlc+4Vx4wm/whI9pQD35YrARNnhxeiRktSOhSukRLFNlzg6Br/cJPet5J/u19r/mg== - -process-nextick-args@~2.0.0: - version "2.0.1" - resolved "https://registry.yarnpkg.com/process-nextick-args/-/process-nextick-args-2.0.1.tgz#7820d9b16120cc55ca9ae7792680ae7dba6d7fe2" - integrity sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag== - -process@^0.11.10: - version "0.11.10" - resolved "https://registry.yarnpkg.com/process/-/process-0.11.10.tgz#7332300e840161bda3e69a1d1d91a7d4bc16f182" - integrity sha1-czIwDoQBYb2j5podHZGn1LwW8YI= - -promise-inflight@^1.0.1: - version "1.0.1" - resolved "https://registry.yarnpkg.com/promise-inflight/-/promise-inflight-1.0.1.tgz#98472870bf228132fcbdd868129bad12c3c029e3" - integrity sha1-mEcocL8igTL8vdhoEputEsPAKeM= - -proxy-addr@~2.0.5: - version "2.0.5" - resolved "https://registry.yarnpkg.com/proxy-addr/-/proxy-addr-2.0.5.tgz#34cbd64a2d81f4b1fd21e76f9f06c8a45299ee34" - integrity sha512-t/7RxHXPH6cJtP0pRG6smSr9QJidhB+3kXu0KgXnbGYMgzEnUxRQ4/LDdfOwZEMyIh3/xHb8PX3t+lfL9z+YVQ== - dependencies: - forwarded "~0.1.2" - ipaddr.js "1.9.0" - -prr@~1.0.1: - version "1.0.1" - resolved "https://registry.yarnpkg.com/prr/-/prr-1.0.1.tgz#d3fc114ba06995a45ec6893f484ceb1d78f5f476" - integrity sha1-0/wRS6BplaRexok/SEzrHXj19HY= - -pseudomap@^1.0.2: - version "1.0.2" - resolved "https://registry.yarnpkg.com/pseudomap/-/pseudomap-1.0.2.tgz#f052a28da70e618917ef0a8ac34c1ae5a68286b3" - integrity sha1-8FKijacOYYkX7wqKw0wa5aaChrM= - -psl@^1.1.24: - version "1.2.0" - resolved "https://registry.yarnpkg.com/psl/-/psl-1.2.0.tgz#df12b5b1b3a30f51c329eacbdef98f3a6e136dc6" - integrity sha512-GEn74ZffufCmkDDLNcl3uuyF/aSD6exEyh1v/ZSdAomB82t6G9hzJVRx0jBmLDW+VfZqks3aScmMw9DszwUalA== - -public-encrypt@^4.0.0: - version "4.0.3" - resolved "https://registry.yarnpkg.com/public-encrypt/-/public-encrypt-4.0.3.tgz#4fcc9d77a07e48ba7527e7cbe0de33d0701331e0" - integrity sha512-zVpa8oKZSz5bTMTFClc1fQOnyyEzpl5ozpi1B5YcvBrdohMjH2rfsBtyXcuNuwjsDIXmBYlF2N5FlJYhR29t8Q== - dependencies: - bn.js "^4.1.0" - browserify-rsa "^4.0.0" - create-hash "^1.1.0" - parse-asn1 "^5.0.0" - randombytes "^2.0.1" - safe-buffer "^5.1.2" - -pump@^2.0.0: - version "2.0.1" - resolved "https://registry.yarnpkg.com/pump/-/pump-2.0.1.tgz#12399add6e4cf7526d973cbc8b5ce2e2908b3909" - integrity sha512-ruPMNRkN3MHP1cWJc9OWr+T/xDP0jhXYCLfJcBuX54hhfIBnaQmAUMfDcG4DM5UMWByBbJY69QSphm3jtDKIkA== - dependencies: - end-of-stream "^1.1.0" - once "^1.3.1" - -pump@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/pump/-/pump-3.0.0.tgz#b4a2116815bde2f4e1ea602354e8c75565107a64" - integrity sha512-LwZy+p3SFs1Pytd/jYct4wpv49HiYCqd9Rlc5ZVdk0V+8Yzv6jR5Blk3TRmPL1ft69TxP0IMZGJ+WPFU2BFhww== - dependencies: - end-of-stream "^1.1.0" - once "^1.3.1" - -pumpify@^1.3.3: - version "1.5.1" - resolved "https://registry.yarnpkg.com/pumpify/-/pumpify-1.5.1.tgz#36513be246ab27570b1a374a5ce278bfd74370ce" - integrity sha512-oClZI37HvuUJJxSKKrC17bZ9Cu0ZYhEAGPsPUy9KlMUmv9dKX2o77RUmq7f3XjIxbwyGwYzbzQ1L2Ks8sIradQ== - dependencies: - duplexify "^3.6.0" - inherits "^2.0.3" - pump "^2.0.0" - -punycode@1.3.2: - version "1.3.2" - resolved "https://registry.yarnpkg.com/punycode/-/punycode-1.3.2.tgz#9653a036fb7c1ee42342f2325cceefea3926c48d" - integrity sha1-llOgNvt8HuQjQvIyXM7v6jkmxI0= - -punycode@^1.2.4, punycode@^1.4.1: - version "1.4.1" - resolved "https://registry.yarnpkg.com/punycode/-/punycode-1.4.1.tgz#c0d5a63b2718800ad8e1eb0fa5269c84dd41845e" - integrity sha1-wNWmOycYgArY4esPpSachN1BhF4= - -punycode@^2.1.0: - version "2.1.1" - resolved "https://registry.yarnpkg.com/punycode/-/punycode-2.1.1.tgz#b58b010ac40c22c5657616c8d2c2c02c7bf479ec" - integrity sha512-XRsRjdf+j5ml+y/6GKHPZbrF/8p2Yga0JPtdqTIY2Xe5ohJPD9saDJJLPvp9+NSBprVvevdXZybnj2cv8OEd0A== - -q@^1.1.2: - version "1.5.1" - resolved "https://registry.yarnpkg.com/q/-/q-1.5.1.tgz#7e32f75b41381291d04611f1bf14109ac00651d7" - integrity sha1-fjL3W0E4EpHQRhHxvxQQmsAGUdc= - -qs@6.7.0: - version "6.7.0" - resolved "https://registry.yarnpkg.com/qs/-/qs-6.7.0.tgz#41dc1a015e3d581f1621776be31afb2876a9b1bc" - integrity sha512-VCdBRNFTX1fyE7Nb6FYoURo/SPe62QCaAyzJvUjwRaIsc+NePBEniHlvxFmmX56+HZphIGtV0XeCirBtpDrTyQ== - -qs@~6.5.2: - version "6.5.2" - resolved "https://registry.yarnpkg.com/qs/-/qs-6.5.2.tgz#cb3ae806e8740444584ef154ce8ee98d403f3e36" - integrity sha512-N5ZAX4/LxJmF+7wN74pUD6qAh9/wnvdQcjq9TZjevvXzSUo7bfmw91saqMjzGS2xq91/odN2dW/WOl7qQHNDGA== - -query-string@^5.0.1: - version "5.1.1" - resolved "https://registry.yarnpkg.com/query-string/-/query-string-5.1.1.tgz#a78c012b71c17e05f2e3fa2319dd330682efb3cb" - integrity sha512-gjWOsm2SoGlgLEdAGt7a6slVOk9mGiXmPFMqrEhLQ68rhQuBnpfs3+EmlvqKyxnCo9/PPlF+9MtY02S1aFg+Jw== - dependencies: - decode-uri-component "^0.2.0" - object-assign "^4.1.0" - strict-uri-encode "^1.0.0" - -querystring-es3@^0.2.0, querystring-es3@^0.2.1: - version "0.2.1" - resolved "https://registry.yarnpkg.com/querystring-es3/-/querystring-es3-0.2.1.tgz#9ec61f79049875707d69414596fd907a4d711e73" - integrity sha1-nsYfeQSYdXB9aUFFlv2Qek1xHnM= - -querystring@0.2.0: - version "0.2.0" - resolved "https://registry.yarnpkg.com/querystring/-/querystring-0.2.0.tgz#b209849203bb25df820da756e747005878521620" - integrity sha1-sgmEkgO7Jd+CDadW50cAWHhSFiA= - -querystringify@^2.1.1: - version "2.1.1" - resolved "https://registry.yarnpkg.com/querystringify/-/querystringify-2.1.1.tgz#60e5a5fd64a7f8bfa4d2ab2ed6fdf4c85bad154e" - integrity sha512-w7fLxIRCRT7U8Qu53jQnJyPkYZIaR4n5151KMfcJlO/A9397Wxb1amJvROTK6TOnp7PfoAmg/qXiNHI+08jRfA== - -randombytes@^2.0.0, randombytes@^2.0.1, randombytes@^2.0.5: - version "2.1.0" - resolved "https://registry.yarnpkg.com/randombytes/-/randombytes-2.1.0.tgz#df6f84372f0270dc65cdf6291349ab7a473d4f2a" - integrity sha512-vYl3iOX+4CKUWuxGi9Ukhie6fsqXqS9FE2Zaic4tNFD2N2QQaXOMFbuKK4QmDHC0JO6B1Zp41J0LpT0oR68amQ== - dependencies: - safe-buffer "^5.1.0" - -randomfill@^1.0.3: - version "1.0.4" - resolved "https://registry.yarnpkg.com/randomfill/-/randomfill-1.0.4.tgz#c92196fc86ab42be983f1bf31778224931d61458" - integrity sha512-87lcbR8+MhcWcUiQ+9e+Rwx8MyR2P7qnt15ynUlbm3TU/fjbgz4GsvfSUDTemtCCtVCqb4ZcEFlyPNTh9bBTLw== - dependencies: - randombytes "^2.0.5" - safe-buffer "^5.1.0" - -range-parser@^1.2.1, range-parser@~1.2.1: - version "1.2.1" - resolved "https://registry.yarnpkg.com/range-parser/-/range-parser-1.2.1.tgz#3cf37023d199e1c24d1a55b84800c2f3e6468031" - integrity sha512-Hrgsx+orqoygnmhFbKaHE6c296J+HTAQXoxEF6gNupROmmGJRoyzfG3ccAveqCBrwr/2yxQ5BVd/GTl5agOwSg== - -raw-body@2.4.0: - version "2.4.0" - resolved "https://registry.yarnpkg.com/raw-body/-/raw-body-2.4.0.tgz#a1ce6fb9c9bc356ca52e89256ab59059e13d0332" - integrity sha512-4Oz8DUIwdvoa5qMJelxipzi/iJIi40O5cGV1wNYp5hvZP8ZN0T+jiNkL0QepXs+EsQ9XJ8ipEDoiH70ySUJP3Q== - dependencies: - bytes "3.1.0" - http-errors "1.7.2" - iconv-lite "0.4.24" - unpipe "1.0.0" - -rc@^1.2.7: - version "1.2.8" - resolved "https://registry.yarnpkg.com/rc/-/rc-1.2.8.tgz#cd924bf5200a075b83c188cd6b9e211b7fc0d3ed" - integrity sha512-y3bGgqKj3QBdxLbLkomlohkvsA8gdAiUQlSBJnBhfn+BPxg4bc62d8TcBW15wavDfgexCgccckhcZvywyQYPOw== - dependencies: - deep-extend "^0.6.0" - ini "~1.3.0" - minimist "^1.2.0" - strip-json-comments "~2.0.1" - -"readable-stream@1 || 2", readable-stream@^2.0.0, readable-stream@^2.0.1, readable-stream@^2.0.2, readable-stream@^2.0.6, readable-stream@^2.1.5, readable-stream@^2.2.2, readable-stream@^2.3.3, readable-stream@^2.3.6, readable-stream@~2.3.6: - version "2.3.6" - resolved "https://registry.yarnpkg.com/readable-stream/-/readable-stream-2.3.6.tgz#b11c27d88b8ff1fbe070643cf94b0c79ae1b0aaf" - integrity sha512-tQtKA9WIAhBF3+VLAseyMqZeBjW0AHJoxOtYqSUZNJxauErmLbVm2FW1y+J/YA9dUrAC39ITejlZWhVIwawkKw== - dependencies: - core-util-is "~1.0.0" - inherits "~2.0.3" - isarray "~1.0.0" - process-nextick-args "~2.0.0" - safe-buffer "~5.1.1" - string_decoder "~1.1.1" - util-deprecate "~1.0.1" - -readable-stream@^3.0.6, readable-stream@^3.1.1: - version "3.4.0" - resolved "https://registry.yarnpkg.com/readable-stream/-/readable-stream-3.4.0.tgz#a51c26754658e0a3c21dbf59163bd45ba6f447fc" - integrity sha512-jItXPLmrSR8jmTRmRWJXCnGJsfy85mB3Wd/uINMXA65yrnFo0cPClFIUWzo2najVNSl+mx7/4W8ttlLWJe99pQ== - dependencies: - inherits "^2.0.3" - string_decoder "^1.1.1" - util-deprecate "^1.0.1" - -readdirp@^2.2.1: - version "2.2.1" - resolved "https://registry.yarnpkg.com/readdirp/-/readdirp-2.2.1.tgz#0e87622a3325aa33e892285caf8b4e846529a525" - integrity sha512-1JU/8q+VgFZyxwrJ+SVIOsh+KywWGpds3NTqikiKpDMZWScmAYyKIgqkO+ARvNWJfXeXR1zxz7aHF4u4CyH6vQ== - dependencies: - graceful-fs "^4.1.11" - micromatch "^3.1.10" - readable-stream "^2.0.2" - -reduce@^1.0.1: - version "1.0.2" - resolved "https://registry.yarnpkg.com/reduce/-/reduce-1.0.2.tgz#0cd680ad3ffe0b060e57a5c68bdfce37168d361b" - integrity sha512-xX7Fxke/oHO5IfZSk77lvPa/7bjMh9BuCk4OOoX5XTXrM7s0Z+MkPfSDfz0q7r91BhhGSs8gii/VEN/7zhCPpQ== - dependencies: - object-keys "^1.1.0" - -regenerate-unicode-properties@^8.0.2: - version "8.1.0" - resolved "https://registry.yarnpkg.com/regenerate-unicode-properties/-/regenerate-unicode-properties-8.1.0.tgz#ef51e0f0ea4ad424b77bf7cb41f3e015c70a3f0e" - integrity sha512-LGZzkgtLY79GeXLm8Dp0BVLdQlWICzBnJz/ipWUgo59qBaZ+BHtq51P2q1uVZlppMuUAT37SDk39qUbjTWB7bA== - dependencies: - regenerate "^1.4.0" - -regenerate@^1.4.0: - version "1.4.0" - resolved "https://registry.yarnpkg.com/regenerate/-/regenerate-1.4.0.tgz#4a856ec4b56e4077c557589cae85e7a4c8869a11" - integrity sha512-1G6jJVDWrt0rK99kBjvEtziZNCICAuvIPkSiUFIQxVP06RCVpq3dmDo2oi6ABpYaDYaTRr67BEhL8r1wgEZZKg== - -regenerator-runtime@^0.13.2: - version "0.13.2" - resolved "https://registry.yarnpkg.com/regenerator-runtime/-/regenerator-runtime-0.13.2.tgz#32e59c9a6fb9b1a4aff09b4930ca2d4477343447" - integrity sha512-S/TQAZJO+D3m9xeN1WTI8dLKBBiRgXBlTJvbWjCThHWZj9EvHK70Ff50/tYj2J/fvBY6JtFVwRuazHN2E7M9BA== - -regenerator-transform@^0.14.0: - version "0.14.0" - resolved "https://registry.yarnpkg.com/regenerator-transform/-/regenerator-transform-0.14.0.tgz#2ca9aaf7a2c239dd32e4761218425b8c7a86ecaf" - integrity sha512-rtOelq4Cawlbmq9xuMR5gdFmv7ku/sFoB7sRiywx7aq53bc52b4j6zvH7Te1Vt/X2YveDKnCGUbioieU7FEL3w== - dependencies: - private "^0.1.6" - -regex-not@^1.0.0, regex-not@^1.0.2: - version "1.0.2" - resolved "https://registry.yarnpkg.com/regex-not/-/regex-not-1.0.2.tgz#1f4ece27e00b0b65e0247a6810e6a85d83a5752c" - integrity sha512-J6SDjUgDxQj5NusnOtdFxDwN/+HWykR8GELwctJ7mdqhcyy1xEc4SRFHUXvxTp661YaVKAjfRLZ9cCqS6tn32A== - dependencies: - extend-shallow "^3.0.2" - safe-regex "^1.1.0" - -regexp-tree@^0.1.6: - version "0.1.11" - resolved "https://registry.yarnpkg.com/regexp-tree/-/regexp-tree-0.1.11.tgz#c9c7f00fcf722e0a56c7390983a7a63dd6c272f3" - integrity sha512-7/l/DgapVVDzZobwMCCgMlqiqyLFJ0cduo/j+3BcDJIB+yJdsYCfKuI3l/04NV+H/rfNRdPIDbXNZHM9XvQatg== - -regexpu-core@^4.5.4: - version "4.5.4" - resolved "https://registry.yarnpkg.com/regexpu-core/-/regexpu-core-4.5.4.tgz#080d9d02289aa87fe1667a4f5136bc98a6aebaae" - integrity sha512-BtizvGtFQKGPUcTy56o3nk1bGRp4SZOTYrDtGNlqCQufptV5IkkLN6Emw+yunAJjzf+C9FQFtvq7IoA3+oMYHQ== - dependencies: - regenerate "^1.4.0" - regenerate-unicode-properties "^8.0.2" - regjsgen "^0.5.0" - regjsparser "^0.6.0" - unicode-match-property-ecmascript "^1.0.4" - unicode-match-property-value-ecmascript "^1.1.0" - -regjsgen@^0.5.0: - version "0.5.0" - resolved "https://registry.yarnpkg.com/regjsgen/-/regjsgen-0.5.0.tgz#a7634dc08f89209c2049adda3525711fb97265dd" - integrity sha512-RnIrLhrXCX5ow/E5/Mh2O4e/oa1/jW0eaBKTSy3LaCj+M3Bqvm97GWDp2yUtzIs4LEn65zR2yiYGFqb2ApnzDA== - -regjsparser@^0.6.0: - version "0.6.0" - resolved "https://registry.yarnpkg.com/regjsparser/-/regjsparser-0.6.0.tgz#f1e6ae8b7da2bae96c99399b868cd6c933a2ba9c" - integrity sha512-RQ7YyokLiQBomUJuUG8iGVvkgOLxwyZM8k6d3q5SAXpg4r5TZJZigKFvC6PpD+qQ98bCDC5YelPeA3EucDoNeQ== - dependencies: - jsesc "~0.5.0" - -relateurl@0.2.x: - version "0.2.7" - resolved "https://registry.yarnpkg.com/relateurl/-/relateurl-0.2.7.tgz#54dbf377e51440aca90a4cd274600d3ff2d888a9" - integrity sha1-VNvzd+UUQKypCkzSdGANP/LYiKk= - -remove-trailing-separator@^1.0.1: - version "1.1.0" - resolved "https://registry.yarnpkg.com/remove-trailing-separator/-/remove-trailing-separator-1.1.0.tgz#c24bce2a283adad5bc3f58e0d48249b92379d8ef" - integrity sha1-wkvOKig62tW8P1jg1IJJuSN52O8= - -renderkid@^2.0.1: - version "2.0.3" - resolved "https://registry.yarnpkg.com/renderkid/-/renderkid-2.0.3.tgz#380179c2ff5ae1365c522bf2fcfcff01c5b74149" - integrity sha512-z8CLQp7EZBPCwCnncgf9C4XAi3WR0dv+uWu/PjIyhhAb5d6IJ/QZqlHFprHeKT+59//V6BNUsLbvN8+2LarxGA== - dependencies: - css-select "^1.1.0" - dom-converter "^0.2" - htmlparser2 "^3.3.0" - strip-ansi "^3.0.0" - utila "^0.4.0" - -repeat-element@^1.1.2: - version "1.1.3" - resolved "https://registry.yarnpkg.com/repeat-element/-/repeat-element-1.1.3.tgz#782e0d825c0c5a3bb39731f84efee6b742e6b1ce" - integrity sha512-ahGq0ZnV5m5XtZLMb+vP76kcAM5nkLqk0lpqAuojSKGgQtn4eRi4ZZGm2olo2zKFH+sMsWaqOCW1dqAnOru72g== - -repeat-string@^1.6.1: - version "1.6.1" - resolved "https://registry.yarnpkg.com/repeat-string/-/repeat-string-1.6.1.tgz#8dcae470e1c88abc2d600fff4a776286da75e637" - integrity sha1-jcrkcOHIirwtYA//Sndihtp15jc= - -request@^2.87.0: - version "2.88.0" - resolved "https://registry.yarnpkg.com/request/-/request-2.88.0.tgz#9c2fca4f7d35b592efe57c7f0a55e81052124fef" - integrity sha512-NAqBSrijGLZdM0WZNsInLJpkJokL72XYjUpnB0iwsRgxh7dB6COrHnTBNwN0E+lHDAJzu7kLAkDeY08z2/A0hg== - dependencies: - aws-sign2 "~0.7.0" - aws4 "^1.8.0" - caseless "~0.12.0" - combined-stream "~1.0.6" - extend "~3.0.2" - forever-agent "~0.6.1" - form-data "~2.3.2" - har-validator "~5.1.0" - http-signature "~1.2.0" - is-typedarray "~1.0.0" - isstream "~0.1.2" - json-stringify-safe "~5.0.1" - mime-types "~2.1.19" - oauth-sign "~0.9.0" - performance-now "^2.1.0" - qs "~6.5.2" - safe-buffer "^5.1.2" - tough-cookie "~2.4.3" - tunnel-agent "^0.6.0" - uuid "^3.3.2" - -require-directory@^2.1.1: - version "2.1.1" - resolved "https://registry.yarnpkg.com/require-directory/-/require-directory-2.1.1.tgz#8c64ad5fd30dab1c976e2344ffe7f792a6a6df42" - integrity sha1-jGStX9MNqxyXbiNE/+f3kqam30I= - -require-main-filename@^1.0.1: - version "1.0.1" - resolved "https://registry.yarnpkg.com/require-main-filename/-/require-main-filename-1.0.1.tgz#97f717b69d48784f5f526a6c5aa8ffdda055a4d1" - integrity sha1-l/cXtp1IeE9fUmpsWqj/3aBVpNE= - -requires-port@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/requires-port/-/requires-port-1.0.0.tgz#925d2601d39ac485e091cf0da5c6e694dc3dcaff" - integrity sha1-kl0mAdOaxIXgkc8NpcbmlNw9yv8= - -reselect@^3.0.1: - version "3.0.1" - resolved "https://registry.yarnpkg.com/reselect/-/reselect-3.0.1.tgz#efdaa98ea7451324d092b2b2163a6a1d7a9a2147" - integrity sha1-79qpjqdFEyTQkrKyFjpqHXqaIUc= - -resolve-cwd@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/resolve-cwd/-/resolve-cwd-2.0.0.tgz#00a9f7387556e27038eae232caa372a6a59b665a" - integrity sha1-AKn3OHVW4nA46uIyyqNypqWbZlo= - dependencies: - resolve-from "^3.0.0" - -resolve-from@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/resolve-from/-/resolve-from-3.0.0.tgz#b22c7af7d9d6881bc8b6e653335eebcb0a188748" - integrity sha1-six699nWiBvItuZTM17rywoYh0g= - -resolve-url@^0.2.1: - version "0.2.1" - resolved "https://registry.yarnpkg.com/resolve-url/-/resolve-url-0.2.1.tgz#2c637fe77c893afd2a663fe21aa9080068e2052a" - integrity sha1-LGN/53yJOv0qZj/iGqkIAGjiBSo= - -resolve@^1.2.0, resolve@^1.3.2, resolve@^1.4.0, resolve@^1.8.1: - version "1.11.1" - resolved "https://registry.yarnpkg.com/resolve/-/resolve-1.11.1.tgz#ea10d8110376982fef578df8fc30b9ac30a07a3e" - integrity sha512-vIpgF6wfuJOZI7KKKSP+HmiKggadPQAdsp5HiC1mvqnfp0gF1vdwgBWZIdrVft9pgqoMFQN+R7BSWZiBxx+BBw== - dependencies: - path-parse "^1.0.6" - -ret@~0.1.10: - version "0.1.15" - resolved "https://registry.yarnpkg.com/ret/-/ret-0.1.15.tgz#b8a4825d5bdb1fc3f6f53c2bc33f81388681c7bc" - integrity sha512-TTlYpa+OL+vMMNG24xSlQGEJ3B/RzEfUlLct7b5G/ytav+wPrplCpVMFuwzXbkecJrb6IYo1iFb0S9v37754mg== - -retry@^0.12.0: - version "0.12.0" - resolved "https://registry.yarnpkg.com/retry/-/retry-0.12.0.tgz#1b42a6266a21f07421d1b0b54b7dc167b01c013b" - integrity sha1-G0KmJmoh8HQh0bC1S33BZ7AcATs= - -rgb-regex@^1.0.1: - version "1.0.1" - resolved "https://registry.yarnpkg.com/rgb-regex/-/rgb-regex-1.0.1.tgz#c0e0d6882df0e23be254a475e8edd41915feaeb1" - integrity sha1-wODWiC3w4jviVKR16O3UGRX+rrE= - -rgba-regex@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/rgba-regex/-/rgba-regex-1.0.0.tgz#43374e2e2ca0968b0ef1523460b7d730ff22eeb3" - integrity sha1-QzdOLiyglosO8VI0YLfXMP8i7rM= - -rimraf@^2.5.4, rimraf@^2.6.1, rimraf@^2.6.3: - version "2.6.3" - resolved "https://registry.yarnpkg.com/rimraf/-/rimraf-2.6.3.tgz#b2d104fe0d8fb27cf9e0a1cda8262dd3833c6cab" - integrity sha512-mwqeW5XsA2qAejG46gYdENaxXjx9onRNCfn7L0duuP4hCuTIi/QO7PDK07KJfp1d+izWPrzEJDcSqBa0OZQriA== - dependencies: - glob "^7.1.3" - -ripemd160@^2.0.0, ripemd160@^2.0.1: - version "2.0.2" - resolved "https://registry.yarnpkg.com/ripemd160/-/ripemd160-2.0.2.tgz#a1c1a6f624751577ba5d07914cbc92850585890c" - integrity sha512-ii4iagi25WusVoiC4B4lq7pbXfAp3D9v5CwfkY33vffw2+pkDjY1D8GaN7spsxvCSx8dkPqOZCEZyfxcmJG2IA== - dependencies: - hash-base "^3.0.0" - inherits "^2.0.1" - -run-queue@^1.0.0, run-queue@^1.0.3: - version "1.0.3" - resolved "https://registry.yarnpkg.com/run-queue/-/run-queue-1.0.3.tgz#e848396f057d223f24386924618e25694161ec47" - integrity sha1-6Eg5bwV9Ij8kOGkkYY4laUFh7Ec= - dependencies: - aproba "^1.1.1" - -safe-buffer@5.1.2, safe-buffer@~5.1.0, safe-buffer@~5.1.1: - version "5.1.2" - resolved "https://registry.yarnpkg.com/safe-buffer/-/safe-buffer-5.1.2.tgz#991ec69d296e0313747d59bdfd2b745c35f8828d" - integrity sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g== - -safe-buffer@>=5.1.0, safe-buffer@^5.0.1, safe-buffer@^5.1.0, safe-buffer@^5.1.1, safe-buffer@^5.1.2: - version "5.2.0" - resolved "https://registry.yarnpkg.com/safe-buffer/-/safe-buffer-5.2.0.tgz#b74daec49b1148f88c64b68d49b1e815c1f2f519" - integrity sha512-fZEwUGbVl7kouZs1jCdMLdt95hdIv0ZeHg6L7qPeciMZhZ+/gdesW4wgTARkrFWEpspjEATAzUGPG8N2jJiwbg== - -safe-regex@^1.1.0: - version "1.1.0" - resolved "https://registry.yarnpkg.com/safe-regex/-/safe-regex-1.1.0.tgz#40a3669f3b077d1e943d44629e157dd48023bf2e" - integrity sha1-QKNmnzsHfR6UPURinhV91IAjvy4= - dependencies: - ret "~0.1.10" - -"safer-buffer@>= 2.1.2 < 3", safer-buffer@^2.0.2, safer-buffer@^2.1.0, safer-buffer@~2.1.0: - version "2.1.2" - resolved "https://registry.yarnpkg.com/safer-buffer/-/safer-buffer-2.1.2.tgz#44fa161b0187b9549dd84bb91802f9bd8385cd6a" - integrity sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg== - -sax@0.5.x: - version "0.5.8" - resolved "https://registry.yarnpkg.com/sax/-/sax-0.5.8.tgz#d472db228eb331c2506b0e8c15524adb939d12c1" - integrity sha1-1HLbIo6zMcJQaw6MFVJK25OdEsE= - -sax@^1.2.4, sax@~1.2.4: - version "1.2.4" - resolved "https://registry.yarnpkg.com/sax/-/sax-1.2.4.tgz#2816234e2378bddc4e5354fab5caa895df7100d9" - integrity sha512-NqVDv9TpANUjFm0N8uM5GxL36UgKi9/atZw+x7YFnQ8ckwFGKrl4xX4yWtrey3UJm5nP1kUbnYgLopqWNSRhWw== - -schema-utils@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/schema-utils/-/schema-utils-1.0.0.tgz#0b79a93204d7b600d4b2850d1f66c2a34951c770" - integrity sha512-i27Mic4KovM/lnGsy8whRCHhc7VicJajAjTrYg11K9zfZXnYIt4k5F+kZkwjnrhKzLic/HLU4j11mjsz2G/75g== - dependencies: - ajv "^6.1.0" - ajv-errors "^1.0.0" - ajv-keywords "^3.1.0" - -section-matter@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/section-matter/-/section-matter-1.0.0.tgz#e9041953506780ec01d59f292a19c7b850b84167" - integrity sha512-vfD3pmTzGpufjScBh50YHKzEu2lxBWhVEHsNGoEXmCmn2hKGfeNLYMzCJpe8cD7gqX7TJluOVpBkAequ6dgMmA== - dependencies: - extend-shallow "^2.0.1" - kind-of "^6.0.0" - -select-hose@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/select-hose/-/select-hose-2.0.0.tgz#625d8658f865af43ec962bfc376a37359a4994ca" - integrity sha1-Yl2GWPhlr0Psliv8N2o3NZpJlMo= - -select@^1.1.2: - version "1.1.2" - resolved "https://registry.yarnpkg.com/select/-/select-1.1.2.tgz#0e7350acdec80b1108528786ec1d4418d11b396d" - integrity sha1-DnNQrN7ICxEIUoeG7B1EGNEbOW0= - -selfsigned@^1.10.4: - version "1.10.4" - resolved "https://registry.yarnpkg.com/selfsigned/-/selfsigned-1.10.4.tgz#cdd7eccfca4ed7635d47a08bf2d5d3074092e2cd" - integrity sha512-9AukTiDmHXGXWtWjembZ5NDmVvP2695EtpgbCsxCa68w3c88B+alqbmZ4O3hZ4VWGXeGWzEVdvqgAJD8DQPCDw== - dependencies: - node-forge "0.7.5" - -semver@^5.1.0, semver@^5.3.0, semver@^5.4.1, semver@^5.5.0, semver@^5.5.1, semver@^5.6.0: - version "5.7.0" - resolved "https://registry.yarnpkg.com/semver/-/semver-5.7.0.tgz#790a7cf6fea5459bac96110b29b60412dc8ff96b" - integrity sha512-Ya52jSX2u7QKghxeoFGpLwCtGlt7j0oY9DYb5apt9nPlJ42ID+ulTXESnt/qAQcoSERyZ5sl3LDIOw0nAn/5DA== - -semver@^6.0.0, semver@^6.1.1: - version "6.2.0" - resolved "https://registry.yarnpkg.com/semver/-/semver-6.2.0.tgz#4d813d9590aaf8a9192693d6c85b9344de5901db" - integrity sha512-jdFC1VdUGT/2Scgbimf7FSx9iJLXoqfglSF+gJeuNWVpiE37OIbc1jywR/GJyFdz3mnkz2/id0L0J/cr0izR5A== - -send@0.17.1: - version "0.17.1" - resolved "https://registry.yarnpkg.com/send/-/send-0.17.1.tgz#c1d8b059f7900f7466dd4938bdc44e11ddb376c8" - integrity sha512-BsVKsiGcQMFwT8UxypobUKyv7irCNRHk1T0G680vk88yf6LBByGcZJOTJCrTP2xVN6yI+XjPJcNuE3V4fT9sAg== - dependencies: - debug "2.6.9" - depd "~1.1.2" - destroy "~1.0.4" - encodeurl "~1.0.2" - escape-html "~1.0.3" - etag "~1.8.1" - fresh "0.5.2" - http-errors "~1.7.2" - mime "1.6.0" - ms "2.1.1" - on-finished "~2.3.0" - range-parser "~1.2.1" - statuses "~1.5.0" - -serialize-javascript@^1.3.0, serialize-javascript@^1.7.0: - version "1.7.0" - resolved "https://registry.yarnpkg.com/serialize-javascript/-/serialize-javascript-1.7.0.tgz#d6e0dfb2a3832a8c94468e6eb1db97e55a192a65" - integrity sha512-ke8UG8ulpFOxO8f8gRYabHQe/ZntKlcig2Mp+8+URDP1D8vJZ0KUt7LYo07q25Z/+JVSgpr/cui9PIp5H6/+nA== - -serve-index@^1.9.1: - version "1.9.1" - resolved "https://registry.yarnpkg.com/serve-index/-/serve-index-1.9.1.tgz#d3768d69b1e7d82e5ce050fff5b453bea12a9239" - integrity sha1-03aNabHn2C5c4FD/9bRTvqEqkjk= - dependencies: - accepts "~1.3.4" - batch "0.6.1" - debug "2.6.9" - escape-html "~1.0.3" - http-errors "~1.6.2" - mime-types "~2.1.17" - parseurl "~1.3.2" - -serve-static@1.14.1: - version "1.14.1" - resolved "https://registry.yarnpkg.com/serve-static/-/serve-static-1.14.1.tgz#666e636dc4f010f7ef29970a88a674320898b2f9" - integrity sha512-JMrvUwE54emCYWlTI+hGrGv5I8dEwmco/00EvkzIIsR7MqrHonbD9pO2MOfFnpFntl7ecpZs+3mW+XbQZu9QCg== - dependencies: - encodeurl "~1.0.2" - escape-html "~1.0.3" - parseurl "~1.3.3" - send "0.17.1" - -set-blocking@^2.0.0, set-blocking@~2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/set-blocking/-/set-blocking-2.0.0.tgz#045f9782d011ae9a6803ddd382b24392b3d890f7" - integrity sha1-BF+XgtARrppoA93TgrJDkrPYkPc= - -set-value@^2.0.0, set-value@^2.0.1: - version "2.0.1" - resolved "https://registry.yarnpkg.com/set-value/-/set-value-2.0.1.tgz#a18d40530e6f07de4228c7defe4227af8cad005b" - integrity sha512-JxHc1weCN68wRY0fhCoXpyK55m/XPHafOmK4UWD7m2CI14GMcFypt4w/0+NV5f/ZMby2F6S2wwA7fgynh9gWSw== - dependencies: - extend-shallow "^2.0.1" - is-extendable "^0.1.1" - is-plain-object "^2.0.3" - split-string "^3.0.1" - -setimmediate@^1.0.4: - version "1.0.5" - resolved "https://registry.yarnpkg.com/setimmediate/-/setimmediate-1.0.5.tgz#290cbb232e306942d7d7ea9b83732ab7856f8285" - integrity sha1-KQy7Iy4waULX1+qbg3Mqt4VvgoU= - -setprototypeof@1.1.0: - version "1.1.0" - resolved "https://registry.yarnpkg.com/setprototypeof/-/setprototypeof-1.1.0.tgz#d0bd85536887b6fe7c0d818cb962d9d91c54e656" - integrity sha512-BvE/TwpZX4FXExxOxZyRGQQv651MSwmWKZGqvmPcRIjDqWub67kTKuIMx43cZZrS/cBBzwBcNDWoFxt2XEFIpQ== - -setprototypeof@1.1.1: - version "1.1.1" - resolved "https://registry.yarnpkg.com/setprototypeof/-/setprototypeof-1.1.1.tgz#7e95acb24aa92f5885e0abef5ba131330d4ae683" - integrity sha512-JvdAWfbXeIGaZ9cILp38HntZSFSo3mWg6xGcJJsd+d4aRMOqauag1C63dJfDw7OaMYwEbHMOxEZ1lqVRYP2OAw== - -sha.js@^2.4.0, sha.js@^2.4.8: - version "2.4.11" - resolved "https://registry.yarnpkg.com/sha.js/-/sha.js-2.4.11.tgz#37a5cf0b81ecbc6943de109ba2960d1b26584ae7" - integrity sha512-QMEp5B7cftE7APOjk5Y6xgrbWu+WkLVQwk8JNjZ8nKRciZaByEW6MubieAiToS7+dwvrjGhH8jRXz3MVd0AYqQ== - dependencies: - inherits "^2.0.1" - safe-buffer "^5.0.1" - -shebang-command@^1.2.0: - version "1.2.0" - resolved "https://registry.yarnpkg.com/shebang-command/-/shebang-command-1.2.0.tgz#44aac65b695b03398968c39f363fee5deafdf1ea" - integrity sha1-RKrGW2lbAzmJaMOfNj/uXer98eo= - dependencies: - shebang-regex "^1.0.0" - -shebang-regex@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/shebang-regex/-/shebang-regex-1.0.0.tgz#da42f49740c0b42db2ca9728571cb190c98efea3" - integrity sha1-2kL0l0DAtC2yypcoVxyxkMmO/qM= - -signal-exit@^3.0.0: - version "3.0.2" - resolved "https://registry.yarnpkg.com/signal-exit/-/signal-exit-3.0.2.tgz#b5fdc08f1287ea1178628e415e25132b73646c6d" - integrity sha1-tf3AjxKH6hF4Yo5BXiUTK3NkbG0= - -simple-swizzle@^0.2.2: - version "0.2.2" - resolved "https://registry.yarnpkg.com/simple-swizzle/-/simple-swizzle-0.2.2.tgz#a4da6b635ffcccca33f70d17cb92592de95e557a" - integrity sha1-pNprY1/8zMoz9w0Xy5JZLeleVXo= - dependencies: - is-arrayish "^0.3.1" - -slash@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/slash/-/slash-1.0.0.tgz#c41f2f6c39fc16d1cd17ad4b5d896114ae470d55" - integrity sha1-xB8vbDn8FtHNF61LXYlhFK5HDVU= - -slash@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/slash/-/slash-2.0.0.tgz#de552851a1759df3a8f206535442f5ec4ddeab44" - integrity sha512-ZYKh3Wh2z1PpEXWr0MpSBZ0V6mZHAQfYevttO11c51CaWjGTaadiKZ+wVt1PbMlDV5qhMFslpZCemhwOK7C89A== - -snapdragon-node@^2.0.1: - version "2.1.1" - resolved "https://registry.yarnpkg.com/snapdragon-node/-/snapdragon-node-2.1.1.tgz#6c175f86ff14bdb0724563e8f3c1b021a286853b" - integrity sha512-O27l4xaMYt/RSQ5TR3vpWCAB5Kb/czIcqUFOM/C4fYcLnbZUc1PkjTAMjof2pBWaSTwOUd6qUHcFGVGj7aIwnw== - dependencies: - define-property "^1.0.0" - isobject "^3.0.0" - snapdragon-util "^3.0.1" - -snapdragon-util@^3.0.1: - version "3.0.1" - resolved "https://registry.yarnpkg.com/snapdragon-util/-/snapdragon-util-3.0.1.tgz#f956479486f2acd79700693f6f7b805e45ab56e2" - integrity sha512-mbKkMdQKsjX4BAL4bRYTj21edOf8cN7XHdYUJEe+Zn99hVEYcMvKPct1IqNe7+AZPirn8BCDOQBHQZknqmKlZQ== - dependencies: - kind-of "^3.2.0" - -snapdragon@^0.8.1: - version "0.8.2" - resolved "https://registry.yarnpkg.com/snapdragon/-/snapdragon-0.8.2.tgz#64922e7c565b0e14204ba1aa7d6964278d25182d" - integrity sha512-FtyOnWN/wCHTVXOMwvSv26d+ko5vWlIDD6zoUJ7LW8vh+ZBC8QdljveRP+crNrtBwioEUWy/4dMtbBjA4ioNlg== - dependencies: - base "^0.11.1" - debug "^2.2.0" - define-property "^0.2.5" - extend-shallow "^2.0.1" - map-cache "^0.2.2" - source-map "^0.5.6" - source-map-resolve "^0.5.0" - use "^3.1.0" - -sockjs-client@1.3.0: - version "1.3.0" - resolved "https://registry.yarnpkg.com/sockjs-client/-/sockjs-client-1.3.0.tgz#12fc9d6cb663da5739d3dc5fb6e8687da95cb177" - integrity sha512-R9jxEzhnnrdxLCNln0xg5uGHqMnkhPSTzUZH2eXcR03S/On9Yvoq2wyUZILRUhZCNVu2PmwWVoyuiPz8th8zbg== - dependencies: - debug "^3.2.5" - eventsource "^1.0.7" - faye-websocket "~0.11.1" - inherits "^2.0.3" - json3 "^3.3.2" - url-parse "^1.4.3" - -sockjs@0.3.19: - version "0.3.19" - resolved "https://registry.yarnpkg.com/sockjs/-/sockjs-0.3.19.tgz#d976bbe800af7bd20ae08598d582393508993c0d" - integrity sha512-V48klKZl8T6MzatbLlzzRNhMepEys9Y4oGFpypBFFn1gLI/QQ9HtLLyWJNbPlwGLelOVOEijUbTTJeLLI59jLw== - dependencies: - faye-websocket "^0.10.0" - uuid "^3.0.1" - -sort-keys@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/sort-keys/-/sort-keys-2.0.0.tgz#658535584861ec97d730d6cf41822e1f56684128" - integrity sha1-ZYU1WEhh7JfXMNbPQYIuH1ZoQSg= - dependencies: - is-plain-obj "^1.0.0" - -source-list-map@^2.0.0: - version "2.0.1" - resolved "https://registry.yarnpkg.com/source-list-map/-/source-list-map-2.0.1.tgz#3993bd873bfc48479cca9ea3a547835c7c154b34" - integrity sha512-qnQ7gVMxGNxsiL4lEuJwe/To8UnK7fAnmbGEEH8RpLouuKbeEm0lhbQVFIrNSuB+G7tVrAlVsZgETT5nljf+Iw== - -source-map-resolve@^0.5.0: - version "0.5.2" - resolved "https://registry.yarnpkg.com/source-map-resolve/-/source-map-resolve-0.5.2.tgz#72e2cc34095543e43b2c62b2c4c10d4a9054f259" - integrity sha512-MjqsvNwyz1s0k81Goz/9vRBe9SZdB09Bdw+/zYyO+3CuPk6fouTaxscHkgtE8jKvf01kVfl8riHzERQ/kefaSA== - dependencies: - atob "^2.1.1" - decode-uri-component "^0.2.0" - resolve-url "^0.2.1" - source-map-url "^0.4.0" - urix "^0.1.0" - -source-map-support@~0.5.12: - version "0.5.12" - resolved "https://registry.yarnpkg.com/source-map-support/-/source-map-support-0.5.12.tgz#b4f3b10d51857a5af0138d3ce8003b201613d599" - integrity sha512-4h2Pbvyy15EE02G+JOZpUCmqWJuqrs+sEkzewTm++BPi7Hvn/HwcqLAcNxYAyI0x13CpPPn+kMjl+hplXMHITQ== - dependencies: - buffer-from "^1.0.0" - source-map "^0.6.0" - -source-map-url@^0.4.0: - version "0.4.0" - resolved "https://registry.yarnpkg.com/source-map-url/-/source-map-url-0.4.0.tgz#3e935d7ddd73631b97659956d55128e87b5084a3" - integrity sha1-PpNdfd1zYxuXZZlW1VEo6HtQhKM= - -source-map@0.1.x: - version "0.1.43" - resolved "https://registry.yarnpkg.com/source-map/-/source-map-0.1.43.tgz#c24bc146ca517c1471f5dacbe2571b2b7f9e3346" - integrity sha1-wkvBRspRfBRx9drL4lcbK3+eM0Y= - dependencies: - amdefine ">=0.0.4" - -source-map@0.5.6: - version "0.5.6" - resolved "https://registry.yarnpkg.com/source-map/-/source-map-0.5.6.tgz#75ce38f52bf0733c5a7f0c118d81334a2bb5f412" - integrity sha1-dc449SvwczxafwwRjYEzSiu19BI= - -source-map@^0.5.0, source-map@^0.5.3, source-map@^0.5.6: - version "0.5.7" - resolved "https://registry.yarnpkg.com/source-map/-/source-map-0.5.7.tgz#8a039d2d1021d22d1ea14c80d8ea468ba2ef3fcc" - integrity sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w= - -source-map@^0.6.0, source-map@^0.6.1, source-map@~0.6.0, source-map@~0.6.1: - version "0.6.1" - resolved "https://registry.yarnpkg.com/source-map/-/source-map-0.6.1.tgz#74722af32e9614e9c287a8d0bbde48b5e2f1a263" - integrity sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g== - -spdy-transport@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/spdy-transport/-/spdy-transport-3.0.0.tgz#00d4863a6400ad75df93361a1608605e5dcdcf31" - integrity sha512-hsLVFE5SjA6TCisWeJXFKniGGOpBgMLmerfO2aCyCU5s7nJ/rpAepqmFifv/GCbSbueEeAJJnmSQ2rKC/g8Fcw== - dependencies: - debug "^4.1.0" - detect-node "^2.0.4" - hpack.js "^2.1.6" - obuf "^1.1.2" - readable-stream "^3.0.6" - wbuf "^1.7.3" - -spdy@^4.0.0: - version "4.0.0" - resolved "https://registry.yarnpkg.com/spdy/-/spdy-4.0.0.tgz#81f222b5a743a329aa12cea6a390e60e9b613c52" - integrity sha512-ot0oEGT/PGUpzf/6uk4AWLqkq+irlqHXkrdbk51oWONh3bxQmBuljxPNl66zlRRcIJStWq0QkLUCPOPjgjvU0Q== - dependencies: - debug "^4.1.0" - handle-thing "^2.0.0" - http-deceiver "^1.2.7" - select-hose "^2.0.0" - spdy-transport "^3.0.0" - -split-string@^3.0.1, split-string@^3.0.2: - version "3.1.0" - resolved "https://registry.yarnpkg.com/split-string/-/split-string-3.1.0.tgz#7cb09dda3a86585705c64b39a6466038682e8fe2" - integrity sha512-NzNVhJDYpwceVVii8/Hu6DKfD2G+NrQHlS/V/qgv763EYudVwEcMQNxd2lh+0VrUByXN/oJkl5grOhYWvQUYiw== - dependencies: - extend-shallow "^3.0.0" - -sprintf-js@~1.0.2: - version "1.0.3" - resolved "https://registry.yarnpkg.com/sprintf-js/-/sprintf-js-1.0.3.tgz#04e6926f662895354f3dd015203633b857297e2c" - integrity sha1-BOaSb2YolTVPPdAVIDYzuFcpfiw= - -sshpk@^1.7.0: - version "1.16.1" - resolved "https://registry.yarnpkg.com/sshpk/-/sshpk-1.16.1.tgz#fb661c0bef29b39db40769ee39fa70093d6f6877" - integrity sha512-HXXqVUq7+pcKeLqqZj6mHFUMvXtOJt1uoUx09pFW6011inTMxqI8BA8PM95myrIyyKwdnzjdFjLiE6KBPVtJIg== - dependencies: - asn1 "~0.2.3" - assert-plus "^1.0.0" - bcrypt-pbkdf "^1.0.0" - dashdash "^1.12.0" - ecc-jsbn "~0.1.1" - getpass "^0.1.1" - jsbn "~0.1.0" - safer-buffer "^2.0.2" - tweetnacl "~0.14.0" - -ssri@^6.0.1: - version "6.0.1" - resolved "https://registry.yarnpkg.com/ssri/-/ssri-6.0.1.tgz#2a3c41b28dd45b62b63676ecb74001265ae9edd8" - integrity sha512-3Wge10hNcT1Kur4PDFwEieXSCMCJs/7WvSACcrMYrNp+b8kDL1/0wJch5Ni2WrtwEa2IO8OsVfeKIciKCDx/QA== - dependencies: - figgy-pudding "^3.5.1" - -stable@^0.1.8: - version "0.1.8" - resolved "https://registry.yarnpkg.com/stable/-/stable-0.1.8.tgz#836eb3c8382fe2936feaf544631017ce7d47a3cf" - integrity sha512-ji9qxRnOVfcuLDySj9qzhGSEFVobyt1kIOSkj1qZzYLzq7Tos/oUUWvotUPQLlrsidqsK6tBH89Bc9kL5zHA6w== - -stack-utils@^1.0.1: - version "1.0.2" - resolved "https://registry.yarnpkg.com/stack-utils/-/stack-utils-1.0.2.tgz#33eba3897788558bebfc2db059dc158ec36cebb8" - integrity sha512-MTX+MeG5U994cazkjd/9KNAapsHnibjMLnfXodlkXw76JEea0UiNzrqidzo1emMwk7w5Qhc9jd4Bn9TBb1MFwA== - -static-extend@^0.1.1: - version "0.1.2" - resolved "https://registry.yarnpkg.com/static-extend/-/static-extend-0.1.2.tgz#60809c39cbff55337226fd5e0b520f341f1fb5c6" - integrity sha1-YICcOcv/VTNyJv1eC1IPNB8ftcY= - dependencies: - define-property "^0.2.5" - object-copy "^0.1.0" - -"statuses@>= 1.4.0 < 2", "statuses@>= 1.5.0 < 2", statuses@~1.5.0: - version "1.5.0" - resolved "https://registry.yarnpkg.com/statuses/-/statuses-1.5.0.tgz#161c7dac177659fd9811f43771fa99381478628c" - integrity sha1-Fhx9rBd2Wf2YEfQ3cfqZOBR4Yow= - -std-env@^2.2.1: - version "2.2.1" - resolved "https://registry.yarnpkg.com/std-env/-/std-env-2.2.1.tgz#2ffa0fdc9e2263e0004c1211966e960948a40f6b" - integrity sha512-IjYQUinA3lg5re/YMlwlfhqNRTzMZMqE+pezevdcTaHceqx8ngEi1alX9nNCk9Sc81fy1fLDeQoaCzeiW1yBOQ== - dependencies: - ci-info "^1.6.0" - -stream-browserify@^2.0.1: - version "2.0.2" - resolved "https://registry.yarnpkg.com/stream-browserify/-/stream-browserify-2.0.2.tgz#87521d38a44aa7ee91ce1cd2a47df0cb49dd660b" - integrity sha512-nX6hmklHs/gr2FuxYDltq8fJA1GDlxKQCz8O/IM4atRqBH8OORmBNgfvW5gG10GT/qQ9u0CzIvr2X5Pkt6ntqg== - dependencies: - inherits "~2.0.1" - readable-stream "^2.0.2" - -stream-each@^1.1.0: - version "1.2.3" - resolved "https://registry.yarnpkg.com/stream-each/-/stream-each-1.2.3.tgz#ebe27a0c389b04fbcc233642952e10731afa9bae" - integrity sha512-vlMC2f8I2u/bZGqkdfLQW/13Zihpej/7PmSiMQsbYddxuTsJp8vRe2x2FvVExZg7FaOds43ROAuFJwPR4MTZLw== - dependencies: - end-of-stream "^1.1.0" - stream-shift "^1.0.0" - -stream-http@^2.7.2: - version "2.8.3" - resolved "https://registry.yarnpkg.com/stream-http/-/stream-http-2.8.3.tgz#b2d242469288a5a27ec4fe8933acf623de6514fc" - integrity sha512-+TSkfINHDo4J+ZobQLWiMouQYB+UVYFttRA94FpEzzJ7ZdqcL4uUUQ7WkdkI4DSozGmgBUE/a47L+38PenXhUw== - dependencies: - builtin-status-codes "^3.0.0" - inherits "^2.0.1" - readable-stream "^2.3.6" - to-arraybuffer "^1.0.0" - xtend "^4.0.0" - -stream-shift@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/stream-shift/-/stream-shift-1.0.0.tgz#d5c752825e5367e786f78e18e445ea223a155952" - integrity sha1-1cdSgl5TZ+eG944Y5EXqIjoVWVI= - -strict-uri-encode@^1.0.0: - version "1.1.0" - resolved "https://registry.yarnpkg.com/strict-uri-encode/-/strict-uri-encode-1.1.0.tgz#279b225df1d582b1f54e65addd4352e18faa0713" - integrity sha1-J5siXfHVgrH1TmWt3UNS4Y+qBxM= - -string-width@^1.0.1: - version "1.0.2" - resolved "https://registry.yarnpkg.com/string-width/-/string-width-1.0.2.tgz#118bdf5b8cdc51a2a7e70d211e07e2b0b9b107d3" - integrity sha1-EYvfW4zcUaKn5w0hHgfisLmxB9M= - dependencies: - code-point-at "^1.0.0" - is-fullwidth-code-point "^1.0.0" - strip-ansi "^3.0.0" - -"string-width@^1.0.2 || 2", string-width@^2.0.0, string-width@^2.1.1: - version "2.1.1" - resolved "https://registry.yarnpkg.com/string-width/-/string-width-2.1.1.tgz#ab93f27a8dc13d28cac815c462143a6d9012ae9e" - integrity sha512-nOqH59deCq9SRHlxq1Aw85Jnt4w6KvLKqWVik6oA9ZklXLNIOlqg4F2yrT1MVaTjAqvVwdfeZ7w7aCvJD7ugkw== - dependencies: - is-fullwidth-code-point "^2.0.0" - strip-ansi "^4.0.0" - -string-width@^3.0.0: - version "3.1.0" - resolved "https://registry.yarnpkg.com/string-width/-/string-width-3.1.0.tgz#22767be21b62af1081574306f69ac51b62203961" - integrity sha512-vafcv6KjVZKSgz06oM/H6GDBrAtz8vdhQakGjFIvNrHA6y3HCF1CInLy+QLq8dTJPQ1b+KDUqDFctkdRW44e1w== - dependencies: - emoji-regex "^7.0.1" - is-fullwidth-code-point "^2.0.0" - strip-ansi "^5.1.0" - -string_decoder@^1.0.0, string_decoder@^1.1.1: - version "1.2.0" - resolved "https://registry.yarnpkg.com/string_decoder/-/string_decoder-1.2.0.tgz#fe86e738b19544afe70469243b2a1ee9240eae8d" - integrity sha512-6YqyX6ZWEYguAxgZzHGL7SsCeGx3V2TtOTqZz1xSTSWnqsbWwbptafNyvf/ACquZUXV3DANr5BDIwNYe1mN42w== - dependencies: - safe-buffer "~5.1.0" - -string_decoder@~1.1.1: - version "1.1.1" - resolved "https://registry.yarnpkg.com/string_decoder/-/string_decoder-1.1.1.tgz#9cf1611ba62685d7030ae9e4ba34149c3af03fc8" - integrity sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg== - dependencies: - safe-buffer "~5.1.0" - -strip-ansi@^3.0.0, strip-ansi@^3.0.1: - version "3.0.1" - resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-3.0.1.tgz#6a385fb8853d952d5ff05d0e8aaf94278dc63dcf" - integrity sha1-ajhfuIU9lS1f8F0Oiq+UJ43GPc8= - dependencies: - ansi-regex "^2.0.0" - -strip-ansi@^4.0.0: - version "4.0.0" - resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-4.0.0.tgz#a8479022eb1ac368a871389b635262c505ee368f" - integrity sha1-qEeQIusaw2iocTibY1JixQXuNo8= - dependencies: - ansi-regex "^3.0.0" - -strip-ansi@^5.0.0, strip-ansi@^5.1.0: - version "5.2.0" - resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-5.2.0.tgz#8c9a536feb6afc962bdfa5b104a5091c1ad9c0ae" - integrity sha512-DuRs1gKbBqsMKIZlrffwlug8MHkcnpjs5VPmL1PAh+mA30U0DTotfDZ0d2UUsXpPmPmMMJ6W773MaA3J+lbiWA== - dependencies: - ansi-regex "^4.1.0" - -strip-bom-string@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/strip-bom-string/-/strip-bom-string-1.0.0.tgz#e5211e9224369fbb81d633a2f00044dc8cedad92" - integrity sha1-5SEekiQ2n7uB1jOi8ABE3IztrZI= - -strip-eof@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/strip-eof/-/strip-eof-1.0.0.tgz#bb43ff5598a6eb05d89b59fcd129c983313606bf" - integrity sha1-u0P/VZim6wXYm1n80SnJgzE2Br8= - -strip-json-comments@~2.0.1: - version "2.0.1" - resolved "https://registry.yarnpkg.com/strip-json-comments/-/strip-json-comments-2.0.1.tgz#3c531942e908c2697c0ec344858c286c7ca0a60a" - integrity sha1-PFMZQukIwml8DsNEhYwobHygpgo= - -stylehacks@^4.0.0: - version "4.0.3" - resolved "https://registry.yarnpkg.com/stylehacks/-/stylehacks-4.0.3.tgz#6718fcaf4d1e07d8a1318690881e8d96726a71d5" - integrity sha512-7GlLk9JwlElY4Y6a/rmbH2MhVlTyVmiJd1PfTCqFaIBEGMYNsrO/v3SeGTdhBThLg4Z+NbOk/qFMwCa+J+3p/g== - dependencies: - browserslist "^4.0.0" - postcss "^7.0.0" - postcss-selector-parser "^3.0.0" - -stylus-loader@^3.0.2: - version "3.0.2" - resolved "https://registry.yarnpkg.com/stylus-loader/-/stylus-loader-3.0.2.tgz#27a706420b05a38e038e7cacb153578d450513c6" - integrity sha512-+VomPdZ6a0razP+zinir61yZgpw2NfljeSsdUF5kJuEzlo3khXhY19Fn6l8QQz1GRJGtMCo8nG5C04ePyV7SUA== - dependencies: - loader-utils "^1.0.2" - lodash.clonedeep "^4.5.0" - when "~3.6.x" - -stylus@^0.54.5: - version "0.54.5" - resolved "https://registry.yarnpkg.com/stylus/-/stylus-0.54.5.tgz#42b9560931ca7090ce8515a798ba9e6aa3d6dc79" - integrity sha1-QrlWCTHKcJDOhRWnmLqeaqPW3Hk= - dependencies: - css-parse "1.7.x" - debug "*" - glob "7.0.x" - mkdirp "0.5.x" - sax "0.5.x" - source-map "0.1.x" - -supports-color@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-2.0.0.tgz#535d045ce6b6363fa40117084629995e9df324c7" - integrity sha1-U10EXOa2Nj+kARcIRimZXp3zJMc= - -supports-color@^5.3.0: - version "5.5.0" - resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-5.5.0.tgz#e2e69a44ac8772f78a1ec0b35b689df6530efc8f" - integrity sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow== - dependencies: - has-flag "^3.0.0" - -supports-color@^6.1.0: - version "6.1.0" - resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-6.1.0.tgz#0764abc69c63d5ac842dd4867e8d025e880df8f3" - integrity sha512-qe1jfm1Mg7Nq/NSh6XE24gPXROEVsWHxC1LIx//XNlD9iw7YZQGjZNjYN7xGaEG6iKdA8EtNFW6R0gjnVXp+wQ== - dependencies: - has-flag "^3.0.0" - -svg-tags@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/svg-tags/-/svg-tags-1.0.0.tgz#58f71cee3bd519b59d4b2a843b6c7de64ac04764" - integrity sha1-WPcc7jvVGbWdSyqEO2x95krAR2Q= - -svgo@^1.0.0: - version "1.3.0" - resolved "https://registry.yarnpkg.com/svgo/-/svgo-1.3.0.tgz#bae51ba95ded9a33a36b7c46ce9c359ae9154313" - integrity sha512-MLfUA6O+qauLDbym+mMZgtXCGRfIxyQoeH6IKVcFslyODEe/ElJNwr0FohQ3xG4C6HK6bk3KYPPXwHVJk3V5NQ== - dependencies: - chalk "^2.4.1" - coa "^2.0.2" - css-select "^2.0.0" - css-select-base-adapter "^0.1.1" - css-tree "1.0.0-alpha.33" - csso "^3.5.1" - js-yaml "^3.13.1" - mkdirp "~0.5.1" - object.values "^1.1.0" - sax "~1.2.4" - stable "^0.1.8" - unquote "~1.1.1" - util.promisify "~1.0.0" - -tapable@^1.0.0, tapable@^1.1.0: - version "1.1.3" - resolved "https://registry.yarnpkg.com/tapable/-/tapable-1.1.3.tgz#a1fccc06b58db61fd7a45da2da44f5f3a3e67ba2" - integrity sha512-4WK/bYZmj8xLr+HUCODHGF1ZFzsYffasLUgEiMBY4fgtltdO6B4WJtlSbPaDTLpYTcGVwM2qLnFTICEcNxs3kA== - -tar@^4: - version "4.4.10" - resolved "https://registry.yarnpkg.com/tar/-/tar-4.4.10.tgz#946b2810b9a5e0b26140cf78bea6b0b0d689eba1" - integrity sha512-g2SVs5QIxvo6OLp0GudTqEf05maawKUxXru104iaayWA09551tFCTI8f1Asb4lPfkBr91k07iL4c11XO3/b0tA== - dependencies: - chownr "^1.1.1" - fs-minipass "^1.2.5" - minipass "^2.3.5" - minizlib "^1.2.1" - mkdirp "^0.5.0" - safe-buffer "^5.1.2" - yallist "^3.0.3" - -terser-webpack-plugin@^1.1.0: - version "1.3.0" - resolved "https://registry.yarnpkg.com/terser-webpack-plugin/-/terser-webpack-plugin-1.3.0.tgz#69aa22426299f4b5b3775cbed8cb2c5d419aa1d4" - integrity sha512-W2YWmxPjjkUcOWa4pBEv4OP4er1aeQJlSo2UhtCFQCuRXEHjOFscO8VyWHj9JLlA0RzQb8Y2/Ta78XZvT54uGg== - dependencies: - cacache "^11.3.2" - find-cache-dir "^2.0.0" - is-wsl "^1.1.0" - loader-utils "^1.2.3" - schema-utils "^1.0.0" - serialize-javascript "^1.7.0" - source-map "^0.6.1" - terser "^4.0.0" - webpack-sources "^1.3.0" - worker-farm "^1.7.0" - -terser@^4.0.0: - version "4.1.2" - resolved "https://registry.yarnpkg.com/terser/-/terser-4.1.2.tgz#b2656c8a506f7ce805a3f300a2ff48db022fa391" - integrity sha512-jvNoEQSPXJdssFwqPSgWjsOrb+ELoE+ILpHPKXC83tIxOlh2U75F1KuB2luLD/3a6/7K3Vw5pDn+hvu0C4AzSw== - dependencies: - commander "^2.20.0" - source-map "~0.6.1" - source-map-support "~0.5.12" - -text-table@^0.2.0: - version "0.2.0" - resolved "https://registry.yarnpkg.com/text-table/-/text-table-0.2.0.tgz#7f5ee823ae805207c00af2df4a84ec3fcfa570b4" - integrity sha1-f17oI66AUgfACvLfSoTsP8+lcLQ= - -through2@^2.0.0: - version "2.0.5" - resolved "https://registry.yarnpkg.com/through2/-/through2-2.0.5.tgz#01c1e39eb31d07cb7d03a96a70823260b23132cd" - integrity sha512-/mrRod8xqpA+IHSLyGCQ2s8SPHiCDEeQJSep1jqLYeEUClOFG2Qsh+4FU6G9VeqpZnGW/Su8LQGc4YKni5rYSQ== - dependencies: - readable-stream "~2.3.6" - xtend "~4.0.1" - -through@~2.3.4: - version "2.3.8" - resolved "https://registry.yarnpkg.com/through/-/through-2.3.8.tgz#0dd4c9ffaabc357960b1b724115d7e0e86a2e1f5" - integrity sha1-DdTJ/6q8NXlgsbckEV1+Doai4fU= - -thunky@^1.0.2: - version "1.0.3" - resolved "https://registry.yarnpkg.com/thunky/-/thunky-1.0.3.tgz#f5df732453407b09191dae73e2a8cc73f381a826" - integrity sha512-YwT8pjmNcAXBZqrubu22P4FYsh2D4dxRmnWBOL8Jk8bUcRUtc5326kx32tuTmFDAZtLOGEVNl8POAR8j896Iow== - -timers-browserify@^2.0.4: - version "2.0.10" - resolved "https://registry.yarnpkg.com/timers-browserify/-/timers-browserify-2.0.10.tgz#1d28e3d2aadf1d5a5996c4e9f95601cd053480ae" - integrity sha512-YvC1SV1XdOUaL6gx5CoGroT3Gu49pK9+TZ38ErPldOWW4j49GI1HKs9DV+KGq/w6y+LZ72W1c8cKz2vzY+qpzg== - dependencies: - setimmediate "^1.0.4" - -timsort@^0.3.0: - version "0.3.0" - resolved "https://registry.yarnpkg.com/timsort/-/timsort-0.3.0.tgz#405411a8e7e6339fe64db9a234de11dc31e02bd4" - integrity sha1-QFQRqOfmM5/mTbmiNN4R3DHgK9Q= - -tiny-emitter@^2.0.0: - version "2.1.0" - resolved "https://registry.yarnpkg.com/tiny-emitter/-/tiny-emitter-2.1.0.tgz#1d1a56edfc51c43e863cbb5382a72330e3555423" - integrity sha512-NB6Dk1A9xgQPMoGqC5CVXn123gWyte215ONT5Pp5a0yt4nlEoO1ZWeCwpncaekPHXO60i47ihFnZPiRPjRMq4Q== - -to-arraybuffer@^1.0.0: - version "1.0.1" - resolved "https://registry.yarnpkg.com/to-arraybuffer/-/to-arraybuffer-1.0.1.tgz#7d229b1fcc637e466ca081180836a7aabff83f43" - integrity sha1-fSKbH8xjfkZsoIEYCDanqr/4P0M= - -to-factory@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/to-factory/-/to-factory-1.0.0.tgz#8738af8bd97120ad1d4047972ada5563bf9479b1" - integrity sha1-hzivi9lxIK0dQEeXKtpVY7+UebE= - -to-fast-properties@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/to-fast-properties/-/to-fast-properties-2.0.0.tgz#dc5e698cbd079265bc73e0377681a4e4e83f616e" - integrity sha1-3F5pjL0HkmW8c+A3doGk5Og/YW4= - -to-object-path@^0.3.0: - version "0.3.0" - resolved "https://registry.yarnpkg.com/to-object-path/-/to-object-path-0.3.0.tgz#297588b7b0e7e0ac08e04e672f85c1f4999e17af" - integrity sha1-KXWIt7Dn4KwI4E5nL4XB9JmeF68= - dependencies: - kind-of "^3.0.2" - -to-regex-range@^2.1.0: - version "2.1.1" - resolved "https://registry.yarnpkg.com/to-regex-range/-/to-regex-range-2.1.1.tgz#7c80c17b9dfebe599e27367e0d4dd5590141db38" - integrity sha1-fIDBe53+vlmeJzZ+DU3VWQFB2zg= - dependencies: - is-number "^3.0.0" - repeat-string "^1.6.1" - -to-regex@^3.0.1, to-regex@^3.0.2: - version "3.0.2" - resolved "https://registry.yarnpkg.com/to-regex/-/to-regex-3.0.2.tgz#13cfdd9b336552f30b51f33a8ae1b42a7a7599ce" - integrity sha512-FWtleNAtZ/Ki2qtqej2CXTOayOH9bHDQF+Q48VpWyDXjbYxA4Yz8iDB31zXOBUlOHHKidDbqGVrTUvQMPmBGBw== - dependencies: - define-property "^2.0.2" - extend-shallow "^3.0.2" - regex-not "^1.0.2" - safe-regex "^1.1.0" - -toidentifier@1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/toidentifier/-/toidentifier-1.0.0.tgz#7e1be3470f1e77948bc43d94a3c8f4d7752ba553" - integrity sha512-yaOH/Pk/VEhBWWTlhI+qXxDFXlejDGcQipMlyxda9nthulaxLZUNcUqFxokp0vcYnvteJln5FNQDRrxj3YcbVw== - -toml@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/toml/-/toml-3.0.0.tgz#342160f1af1904ec9d204d03a5d61222d762c5ee" - integrity sha512-y/mWCZinnvxjTKYhJ+pYxwD0mRLVvOtdS2Awbgxln6iEnt4rk0yBxeSBHkGJcPucRiG0e55mwWp+g/05rsrd6w== - -toposort@^1.0.0: - version "1.0.7" - resolved "https://registry.yarnpkg.com/toposort/-/toposort-1.0.7.tgz#2e68442d9f64ec720b8cc89e6443ac6caa950029" - integrity sha1-LmhELZ9k7HILjMieZEOsbKqVACk= - -tough-cookie@~2.4.3: - version "2.4.3" - resolved "https://registry.yarnpkg.com/tough-cookie/-/tough-cookie-2.4.3.tgz#53f36da3f47783b0925afa06ff9f3b165280f781" - integrity sha512-Q5srk/4vDM54WJsJio3XNn6K2sCG+CQ8G5Wz6bZhRZoAe/+TxjWB/GlFAnYEbkYVlON9FMk/fE3h2RLpPXo4lQ== - dependencies: - psl "^1.1.24" - punycode "^1.4.1" - -trim-right@^1.0.1: - version "1.0.1" - resolved "https://registry.yarnpkg.com/trim-right/-/trim-right-1.0.1.tgz#cb2e1203067e0c8de1f614094b9fe45704ea6003" - integrity sha1-yy4SAwZ+DI3h9hQJS5/kVwTqYAM= - -tslib@^1.9.0: - version "1.10.0" - resolved "https://registry.yarnpkg.com/tslib/-/tslib-1.10.0.tgz#c3c19f95973fb0a62973fb09d90d961ee43e5c8a" - integrity sha512-qOebF53frne81cf0S9B41ByenJ3/IuH8yJKngAX35CmiZySA0khhkovshKK+jGCaMnVomla7gVlIcc3EvKPbTQ== - -tty-browserify@0.0.0: - version "0.0.0" - resolved "https://registry.yarnpkg.com/tty-browserify/-/tty-browserify-0.0.0.tgz#a157ba402da24e9bf957f9aa69d524eed42901a6" - integrity sha1-oVe6QC2iTpv5V/mqadUk7tQpAaY= - -tunnel-agent@^0.6.0: - version "0.6.0" - resolved "https://registry.yarnpkg.com/tunnel-agent/-/tunnel-agent-0.6.0.tgz#27a5dea06b36b04a0a9966774b290868f0fc40fd" - integrity sha1-J6XeoGs2sEoKmWZ3SykIaPD8QP0= - dependencies: - safe-buffer "^5.0.1" - -tweetnacl@^0.14.3, tweetnacl@~0.14.0: - version "0.14.5" - resolved "https://registry.yarnpkg.com/tweetnacl/-/tweetnacl-0.14.5.tgz#5ae68177f192d4456269d108afa93ff8743f4f64" - integrity sha1-WuaBd/GS1EViadEIr6k/+HQ/T2Q= - -type-fest@^0.5.2: - version "0.5.2" - resolved "https://registry.yarnpkg.com/type-fest/-/type-fest-0.5.2.tgz#d6ef42a0356c6cd45f49485c3b6281fc148e48a2" - integrity sha512-DWkS49EQKVX//Tbupb9TFa19c7+MK1XmzkrZUR8TAktmE/DizXoaoJV6TZ/tSIPXipqNiRI6CyAe7x69Jb6RSw== - -type-is@~1.6.17, type-is@~1.6.18: - version "1.6.18" - resolved "https://registry.yarnpkg.com/type-is/-/type-is-1.6.18.tgz#4e552cd05df09467dcbc4ef739de89f2cf37c131" - integrity sha512-TkRKr9sUTxEH8MdfuCSP7VizJyzRNMjj2J2do2Jr3Kym598JVdEksuzPQCnlFPW4ky9Q+iA+ma9BGm06XQBy8g== - dependencies: - media-typer "0.3.0" - mime-types "~2.1.24" - -typedarray@^0.0.6: - version "0.0.6" - resolved "https://registry.yarnpkg.com/typedarray/-/typedarray-0.0.6.tgz#867ac74e3864187b1d3d47d996a78ec5c8830777" - integrity sha1-hnrHTjhkGHsdPUfZlqeOxciDB3c= - -uc.micro@^1.0.1, uc.micro@^1.0.5: - version "1.0.6" - resolved "https://registry.yarnpkg.com/uc.micro/-/uc.micro-1.0.6.tgz#9c411a802a409a91fc6cf74081baba34b24499ac" - integrity sha512-8Y75pvTYkLJW2hWQHXxoqRgV7qb9B+9vFEtidML+7koHUFapnVJAZ6cKs+Qjz5Aw3aZWHMC6u0wJE3At+nSGwA== - -uglify-js@3.4.x: - version "3.4.10" - resolved "https://registry.yarnpkg.com/uglify-js/-/uglify-js-3.4.10.tgz#9ad9563d8eb3acdfb8d38597d2af1d815f6a755f" - integrity sha512-Y2VsbPVs0FIshJztycsO2SfPk7/KAF/T72qzv9u5EpQ4kB2hQoHlhNQTsNyy6ul7lQtqJN/AoWeS23OzEiEFxw== - dependencies: - commander "~2.19.0" - source-map "~0.6.1" - -unicode-canonical-property-names-ecmascript@^1.0.4: - version "1.0.4" - resolved "https://registry.yarnpkg.com/unicode-canonical-property-names-ecmascript/-/unicode-canonical-property-names-ecmascript-1.0.4.tgz#2619800c4c825800efdd8343af7dd9933cbe2818" - integrity sha512-jDrNnXWHd4oHiTZnx/ZG7gtUTVp+gCcTTKr8L0HjlwphROEW3+Him+IpvC+xcJEFegapiMZyZe02CyuOnRmbnQ== - -unicode-match-property-ecmascript@^1.0.4: - version "1.0.4" - resolved "https://registry.yarnpkg.com/unicode-match-property-ecmascript/-/unicode-match-property-ecmascript-1.0.4.tgz#8ed2a32569961bce9227d09cd3ffbb8fed5f020c" - integrity sha512-L4Qoh15vTfntsn4P1zqnHulG0LdXgjSO035fEpdtp6YxXhMT51Q6vgM5lYdG/5X3MjS+k/Y9Xw4SFCY9IkR0rg== - dependencies: - unicode-canonical-property-names-ecmascript "^1.0.4" - unicode-property-aliases-ecmascript "^1.0.4" - -unicode-match-property-value-ecmascript@^1.1.0: - version "1.1.0" - resolved "https://registry.yarnpkg.com/unicode-match-property-value-ecmascript/-/unicode-match-property-value-ecmascript-1.1.0.tgz#5b4b426e08d13a80365e0d657ac7a6c1ec46a277" - integrity sha512-hDTHvaBk3RmFzvSl0UVrUmC3PuW9wKVnpoUDYH0JDkSIovzw+J5viQmeYHxVSBptubnr7PbH2e0fnpDRQnQl5g== - -unicode-property-aliases-ecmascript@^1.0.4: - version "1.0.5" - resolved "https://registry.yarnpkg.com/unicode-property-aliases-ecmascript/-/unicode-property-aliases-ecmascript-1.0.5.tgz#a9cc6cc7ce63a0a3023fc99e341b94431d405a57" - integrity sha512-L5RAqCfXqAwR3RriF8pM0lU0w4Ryf/GgzONwi6KnL1taJQa7x1TCxdJnILX59WIGOwR57IVxn7Nej0fz1Ny6fw== - -union-value@^1.0.0: - version "1.0.1" - resolved "https://registry.yarnpkg.com/union-value/-/union-value-1.0.1.tgz#0b6fe7b835aecda61c6ea4d4f02c14221e109847" - integrity sha512-tJfXmxMeWYnczCVs7XAEvIV7ieppALdyepWMkHkwciRpZraG/xwT+s2JN8+pr1+8jCRf80FFzvr+MpQeeoF4Xg== - dependencies: - arr-union "^3.1.0" - get-value "^2.0.6" - is-extendable "^0.1.1" - set-value "^2.0.1" - -uniq@^1.0.1: - version "1.0.1" - resolved "https://registry.yarnpkg.com/uniq/-/uniq-1.0.1.tgz#b31c5ae8254844a3a8281541ce2b04b865a734ff" - integrity sha1-sxxa6CVIRKOoKBVBzisEuGWnNP8= - -uniqs@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/uniqs/-/uniqs-2.0.0.tgz#ffede4b36b25290696e6e165d4a59edb998e6b02" - integrity sha1-/+3ks2slKQaW5uFl1KWe25mOawI= - -unique-filename@^1.1.1: - version "1.1.1" - resolved "https://registry.yarnpkg.com/unique-filename/-/unique-filename-1.1.1.tgz#1d69769369ada0583103a1e6ae87681b56573230" - integrity sha512-Vmp0jIp2ln35UTXuryvjzkjGdRyf9b2lTXuSYUiPmzRcl3FDtYqAwOnTJkAngD9SWhnoJzDbTKwaOrZ+STtxNQ== - dependencies: - unique-slug "^2.0.0" - -unique-slug@^2.0.0: - version "2.0.2" - resolved "https://registry.yarnpkg.com/unique-slug/-/unique-slug-2.0.2.tgz#baabce91083fc64e945b0f3ad613e264f7cd4e6c" - integrity sha512-zoWr9ObaxALD3DOPfjPSqxt4fnZiWblxHIgeWqW8x7UqDzEtHEQLzji2cuJYQFCU6KmoJikOYAZlrTHHebjx2w== - dependencies: - imurmurhash "^0.1.4" - -universalify@^0.1.0: - version "0.1.2" - resolved "https://registry.yarnpkg.com/universalify/-/universalify-0.1.2.tgz#b646f69be3942dabcecc9d6639c80dc105efaa66" - integrity sha512-rBJeI5CXAlmy1pV+617WB9J63U6XcazHHF2f2dbJix4XzpUF0RS3Zbj0FGIOCAva5P/d/GBOYaACQ1w+0azUkg== - -unpipe@1.0.0, unpipe@~1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/unpipe/-/unpipe-1.0.0.tgz#b2bf4ee8514aae6165b4817829d21b2ef49904ec" - integrity sha1-sr9O6FFKrmFltIF4KdIbLvSZBOw= - -unquote@~1.1.1: - version "1.1.1" - resolved "https://registry.yarnpkg.com/unquote/-/unquote-1.1.1.tgz#8fded7324ec6e88a0ff8b905e7c098cdc086d544" - integrity sha1-j97XMk7G6IoP+LkF58CYzcCG1UQ= - -unset-value@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/unset-value/-/unset-value-1.0.0.tgz#8376873f7d2335179ffb1e6fc3a8ed0dfc8ab559" - integrity sha1-g3aHP30jNRef+x5vw6jtDfyKtVk= - dependencies: - has-value "^0.3.1" - isobject "^3.0.0" - -upath@^1.1.0, upath@^1.1.1: - version "1.1.2" - resolved "https://registry.yarnpkg.com/upath/-/upath-1.1.2.tgz#3db658600edaeeccbe6db5e684d67ee8c2acd068" - integrity sha512-kXpym8nmDmlCBr7nKdIx8P2jNBa+pBpIUFRnKJ4dr8htyYGJFokkr2ZvERRtUN+9SY+JqXouNgUPtv6JQva/2Q== - -upper-case@^1.1.1: - version "1.1.3" - resolved "https://registry.yarnpkg.com/upper-case/-/upper-case-1.1.3.tgz#f6b4501c2ec4cdd26ba78be7222961de77621598" - integrity sha1-9rRQHC7EzdJrp4vnIilh3ndiFZg= - -uri-js@^4.2.2: - version "4.2.2" - resolved "https://registry.yarnpkg.com/uri-js/-/uri-js-4.2.2.tgz#94c540e1ff772956e2299507c010aea6c8838eb0" - integrity sha512-KY9Frmirql91X2Qgjry0Wd4Y+YTdrdZheS8TFwvkbLWf/G5KNJDCh6pKL5OZctEW4+0Baa5idK2ZQuELRwPznQ== - dependencies: - punycode "^2.1.0" - -urix@^0.1.0: - version "0.1.0" - resolved "https://registry.yarnpkg.com/urix/-/urix-0.1.0.tgz#da937f7a62e21fec1fd18d49b35c2935067a6c72" - integrity sha1-2pN/emLiH+wf0Y1Js1wpNQZ6bHI= - -url-loader@^1.0.1: - version "1.1.2" - resolved "https://registry.yarnpkg.com/url-loader/-/url-loader-1.1.2.tgz#b971d191b83af693c5e3fea4064be9e1f2d7f8d8" - integrity sha512-dXHkKmw8FhPqu8asTc1puBfe3TehOCo2+RmOOev5suNCIYBcT626kxiWg1NBVkwc4rO8BGa7gP70W7VXuqHrjg== - dependencies: - loader-utils "^1.1.0" - mime "^2.0.3" - schema-utils "^1.0.0" - -url-parse@^1.4.3: - version "1.4.7" - resolved "https://registry.yarnpkg.com/url-parse/-/url-parse-1.4.7.tgz#a8a83535e8c00a316e403a5db4ac1b9b853ae278" - integrity sha512-d3uaVyzDB9tQoSXFvuSUNFibTd9zxd2bkVrDRvF5TmvWWQwqE4lgYJ5m+x1DbecWkw+LK4RNl2CU1hHuOKPVlg== - dependencies: - querystringify "^2.1.1" - requires-port "^1.0.0" - -url@^0.11.0: - version "0.11.0" - resolved "https://registry.yarnpkg.com/url/-/url-0.11.0.tgz#3838e97cfc60521eb73c525a8e55bfdd9e2e28f1" - integrity sha1-ODjpfPxgUh63PFJajlW/3Z4uKPE= - dependencies: - punycode "1.3.2" - querystring "0.2.0" - -use@^3.1.0: - version "3.1.1" - resolved "https://registry.yarnpkg.com/use/-/use-3.1.1.tgz#d50c8cac79a19fbc20f2911f56eb973f4e10070f" - integrity sha512-cwESVXlO3url9YWlFW/TA9cshCEhtu7IKJ/p5soJ/gGpj7vbvFrAY/eIioQ6Dw23KjZhYgiIo8HOs1nQ2vr/oQ== - -util-deprecate@^1.0.1, util-deprecate@~1.0.1: - version "1.0.2" - resolved "https://registry.yarnpkg.com/util-deprecate/-/util-deprecate-1.0.2.tgz#450d4dc9fa70de732762fbd2d4a28981419a0ccf" - integrity sha1-RQ1Nyfpw3nMnYvvS1KKJgUGaDM8= - -util.promisify@1.0.0, util.promisify@~1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/util.promisify/-/util.promisify-1.0.0.tgz#440f7165a459c9a16dc145eb8e72f35687097030" - integrity sha512-i+6qA2MPhvoKLuxnJNpXAGhg7HphQOSUq2LKMZD0m15EiskXUkMvKdF4Uui0WYeCUGea+o2cw/ZuwehtfsrNkA== - dependencies: - define-properties "^1.1.2" - object.getownpropertydescriptors "^2.0.3" - -util@0.10.3: - version "0.10.3" - resolved "https://registry.yarnpkg.com/util/-/util-0.10.3.tgz#7afb1afe50805246489e3db7fe0ed379336ac0f9" - integrity sha1-evsa/lCAUkZInj23/g7TeTNqwPk= - dependencies: - inherits "2.0.1" - -util@^0.11.0: - version "0.11.1" - resolved "https://registry.yarnpkg.com/util/-/util-0.11.1.tgz#3236733720ec64bb27f6e26f421aaa2e1b588d61" - integrity sha512-HShAsny+zS2TZfaXxD9tYj4HQGlBezXZMZuM/S5PKLLoZkShZiGk9o5CzukI1LVHZvjdvZ2Sj1aW/Ndn2NB/HQ== - dependencies: - inherits "2.0.3" - -utila@^0.4.0, utila@~0.4: - version "0.4.0" - resolved "https://registry.yarnpkg.com/utila/-/utila-0.4.0.tgz#8a16a05d445657a3aea5eecc5b12a4fa5379772c" - integrity sha1-ihagXURWV6Oupe7MWxKk+lN5dyw= - -utils-merge@1.0.1: - version "1.0.1" - resolved "https://registry.yarnpkg.com/utils-merge/-/utils-merge-1.0.1.tgz#9f95710f50a267947b2ccc124741c1028427e713" - integrity sha1-n5VxD1CiZ5R7LMwSR0HBAoQn5xM= - -uuid@^3.0.1, uuid@^3.3.2: - version "3.3.2" - resolved "https://registry.yarnpkg.com/uuid/-/uuid-3.3.2.tgz#1b4af4955eb3077c501c23872fc6513811587131" - integrity sha512-yXJmeNaw3DnnKAOKJE51sL/ZaYfWJRl1pK9dr19YFCu0ObS231AB1/LbqTKRAQ5kw8A90rA6fr4riOUpTZvQZA== - -vary@~1.1.2: - version "1.1.2" - resolved "https://registry.yarnpkg.com/vary/-/vary-1.1.2.tgz#2299f02c6ded30d4a5961b0b9f74524a18f634fc" - integrity sha1-IpnwLG3tMNSllhsLn3RSShj2NPw= - -vendors@^1.0.0: - version "1.0.3" - resolved "https://registry.yarnpkg.com/vendors/-/vendors-1.0.3.tgz#a6467781abd366217c050f8202e7e50cc9eef8c0" - integrity sha512-fOi47nsJP5Wqefa43kyWSg80qF+Q3XA6MUkgi7Hp1HQaKDQW4cQrK2D0P7mmbFtsV1N89am55Yru/nyEwRubcw== - -verror@1.10.0: - version "1.10.0" - resolved "https://registry.yarnpkg.com/verror/-/verror-1.10.0.tgz#3a105ca17053af55d6e270c1f8288682e18da400" - integrity sha1-OhBcoXBTr1XW4nDB+CiGguGNpAA= - dependencies: - assert-plus "^1.0.0" - core-util-is "1.0.2" - extsprintf "^1.2.0" - -vm-browserify@^1.0.1: - version "1.1.0" - resolved "https://registry.yarnpkg.com/vm-browserify/-/vm-browserify-1.1.0.tgz#bd76d6a23323e2ca8ffa12028dc04559c75f9019" - integrity sha512-iq+S7vZJE60yejDYM0ek6zg308+UZsdtPExWP9VZoCFCz1zkJoXFnAX7aZfd/ZwrkidzdUZL0C/ryW+JwAiIGw== - -vue-hot-reload-api@^2.3.0: - version "2.3.3" - resolved "https://registry.yarnpkg.com/vue-hot-reload-api/-/vue-hot-reload-api-2.3.3.tgz#2756f46cb3258054c5f4723de8ae7e87302a1ccf" - integrity sha512-KmvZVtmM26BQOMK1rwUZsrqxEGeKiYSZGA7SNWE6uExx8UX/cj9hq2MRV/wWC3Cq6AoeDGk57rL9YMFRel/q+g== - -vue-loader@^15.2.4: - version "15.7.1" - resolved "https://registry.yarnpkg.com/vue-loader/-/vue-loader-15.7.1.tgz#6ccacd4122aa80f69baaac08ff295a62e3aefcfd" - integrity sha512-fwIKtA23Pl/rqfYP5TSGK7gkEuLhoTvRYW+TU7ER3q9GpNLt/PjG5NLv3XHRDiTg7OPM1JcckBgds+VnAc+HbA== - dependencies: - "@vue/component-compiler-utils" "^3.0.0" - hash-sum "^1.0.2" - loader-utils "^1.1.0" - vue-hot-reload-api "^2.3.0" - vue-style-loader "^4.1.0" - -vue-router@^3.0.2: - version "3.0.7" - resolved "https://registry.yarnpkg.com/vue-router/-/vue-router-3.0.7.tgz#b36ca107b4acb8ff5bc4ff824584059c23fcb87b" - integrity sha512-utJ+QR3YlIC/6x6xq17UMXeAfxEvXA0VKD3PiSio7hBOZNusA1jXcbxZxVEfJunLp48oonjTepY8ORoIlRx/EQ== - -vue-server-renderer@^2.5.16: - version "2.6.10" - resolved "https://registry.yarnpkg.com/vue-server-renderer/-/vue-server-renderer-2.6.10.tgz#cb2558842ead360ae2ec1f3719b75564a805b375" - integrity sha512-UYoCEutBpKzL2fKCwx8zlRtRtwxbPZXKTqbl2iIF4yRZUNO/ovrHyDAJDljft0kd+K0tZhN53XRHkgvCZoIhug== - dependencies: - chalk "^1.1.3" - hash-sum "^1.0.2" - he "^1.1.0" - lodash.template "^4.4.0" - lodash.uniq "^4.5.0" - resolve "^1.2.0" - serialize-javascript "^1.3.0" - source-map "0.5.6" - -vue-style-loader@^4.1.0: - version "4.1.2" - resolved "https://registry.yarnpkg.com/vue-style-loader/-/vue-style-loader-4.1.2.tgz#dedf349806f25ceb4e64f3ad7c0a44fba735fcf8" - integrity sha512-0ip8ge6Gzz/Bk0iHovU9XAUQaFt/G2B61bnWa2tCcqqdgfHs1lF9xXorFbE55Gmy92okFT+8bfmySuUOu13vxQ== - dependencies: - hash-sum "^1.0.2" - loader-utils "^1.0.2" - -vue-template-compiler@^2.5.16: - version "2.6.10" - resolved "https://registry.yarnpkg.com/vue-template-compiler/-/vue-template-compiler-2.6.10.tgz#323b4f3495f04faa3503337a82f5d6507799c9cc" - integrity sha512-jVZkw4/I/HT5ZMvRnhv78okGusqe0+qH2A0Em0Cp8aq78+NK9TII263CDVz2QXZsIT+yyV/gZc/j/vlwa+Epyg== - dependencies: - de-indent "^1.0.2" - he "^1.1.0" - -vue-template-es2015-compiler@^1.9.0: - version "1.9.1" - resolved "https://registry.yarnpkg.com/vue-template-es2015-compiler/-/vue-template-es2015-compiler-1.9.1.tgz#1ee3bc9a16ecbf5118be334bb15f9c46f82f5825" - integrity sha512-4gDntzrifFnCEvyoO8PqyJDmguXgVPxKiIxrBKjIowvL9l+N66196+72XVYR8BBf1Uv1Fgt3bGevJ+sEmxfZzw== - -vue@^2.5.16: - version "2.6.10" - resolved "https://registry.yarnpkg.com/vue/-/vue-2.6.10.tgz#a72b1a42a4d82a721ea438d1b6bf55e66195c637" - integrity sha512-ImThpeNU9HbdZL3utgMCq0oiMzAkt1mcgy3/E6zWC/G6AaQoeuFdsl9nDhTDU3X1R6FK7nsIUuRACVcjI+A2GQ== - -vuepress-html-webpack-plugin@^3.2.0: - version "3.2.0" - resolved "https://registry.yarnpkg.com/vuepress-html-webpack-plugin/-/vuepress-html-webpack-plugin-3.2.0.tgz#219be272ad510faa8750d2d4e70fd028bfd1c16e" - integrity sha512-BebAEl1BmWlro3+VyDhIOCY6Gef2MCBllEVAP3NUAtMguiyOwo/dClbwJ167WYmcxHJKLl7b0Chr9H7fpn1d0A== - dependencies: - html-minifier "^3.2.3" - loader-utils "^0.2.16" - lodash "^4.17.3" - pretty-error "^2.0.2" - tapable "^1.0.0" - toposort "^1.0.0" - util.promisify "1.0.0" - -vuepress-plugin-container@^2.0.0: - version "2.0.2" - resolved "https://registry.yarnpkg.com/vuepress-plugin-container/-/vuepress-plugin-container-2.0.2.tgz#3489cc732c7a210b31f202556e1346125dffeb73" - integrity sha512-SrGYYT7lkie7xlIlAVhn+9sDW42MytNCoxWL/2uDr+q9wZA4h1uYlQvfc2DVjy+FsM9PPPSslkeo/zCpYVY82g== - dependencies: - markdown-it-container "^2.0.0" - -vuepress@^1.0.2: - version "1.0.2" - resolved "https://registry.yarnpkg.com/vuepress/-/vuepress-1.0.2.tgz#da62d6e43faca0b8af0bcffff6975fa27dbfdea3" - integrity sha512-HPRWxrq6D+S9uCR3oJ8/OTCy8GcYm9l1HxHb44rvaN2gyySVXIiqSkCwzd9r2PY8+pwvrfYE4rcY1RsTTpJ25g== - dependencies: - "@vuepress/core" "^1.0.2" - "@vuepress/theme-default" "^1.0.2" - cac "^6.3.9" - envinfo "^7.2.0" - -watchpack@^1.5.0: - version "1.6.0" - resolved "https://registry.yarnpkg.com/watchpack/-/watchpack-1.6.0.tgz#4bc12c2ebe8aa277a71f1d3f14d685c7b446cd00" - integrity sha512-i6dHe3EyLjMmDlU1/bGQpEw25XSjkJULPuAVKCbNRefQVq48yXKUpwg538F7AZTf9kyr57zj++pQFltUa5H7yA== - dependencies: - chokidar "^2.0.2" - graceful-fs "^4.1.2" - neo-async "^2.5.0" - -wbuf@^1.1.0, wbuf@^1.7.3: - version "1.7.3" - resolved "https://registry.yarnpkg.com/wbuf/-/wbuf-1.7.3.tgz#c1d8d149316d3ea852848895cb6a0bfe887b87df" - integrity sha512-O84QOnr0icsbFGLS0O3bI5FswxzRr8/gHwWkDlQFskhSPryQXvrTMxjxGP4+iWYoauLoBvfDpkrOauZ+0iZpDA== - dependencies: - minimalistic-assert "^1.0.0" - -webpack-chain@^4.6.0, webpack-chain@^4.9.0: - version "4.12.1" - resolved "https://registry.yarnpkg.com/webpack-chain/-/webpack-chain-4.12.1.tgz#6c8439bbb2ab550952d60e1ea9319141906c02a6" - integrity sha512-BCfKo2YkDe2ByqkEWe1Rw+zko4LsyS75LVr29C6xIrxAg9JHJ4pl8kaIZ396SUSNp6b4815dRZPSTAS8LlURRQ== - dependencies: - deepmerge "^1.5.2" - javascript-stringify "^1.6.0" - -webpack-dev-middleware@^3.7.0: - version "3.7.0" - resolved "https://registry.yarnpkg.com/webpack-dev-middleware/-/webpack-dev-middleware-3.7.0.tgz#ef751d25f4e9a5c8a35da600c5fda3582b5c6cff" - integrity sha512-qvDesR1QZRIAZHOE3iQ4CXLZZSQ1lAUsSpnQmlB1PBfoN/xdRjmge3Dok0W4IdaVLJOGJy3sGI4sZHwjRU0PCA== - dependencies: - memory-fs "^0.4.1" - mime "^2.4.2" - range-parser "^1.2.1" - webpack-log "^2.0.0" - -webpack-dev-server@^3.5.1: - version "3.7.2" - resolved "https://registry.yarnpkg.com/webpack-dev-server/-/webpack-dev-server-3.7.2.tgz#f79caa5974b7f8b63268ef5421222a8486d792f5" - integrity sha512-mjWtrKJW2T9SsjJ4/dxDC2fkFVUw8jlpemDERqV0ZJIkjjjamR2AbQlr3oz+j4JLhYCHImHnXZK5H06P2wvUew== - dependencies: - ansi-html "0.0.7" - bonjour "^3.5.0" - chokidar "^2.1.6" - compression "^1.7.4" - connect-history-api-fallback "^1.6.0" - debug "^4.1.1" - del "^4.1.1" - express "^4.17.1" - html-entities "^1.2.1" - http-proxy-middleware "^0.19.1" - import-local "^2.0.0" - internal-ip "^4.3.0" - ip "^1.1.5" - killable "^1.0.1" - loglevel "^1.6.3" - opn "^5.5.0" - p-retry "^3.0.1" - portfinder "^1.0.20" - schema-utils "^1.0.0" - selfsigned "^1.10.4" - semver "^6.1.1" - serve-index "^1.9.1" - sockjs "0.3.19" - sockjs-client "1.3.0" - spdy "^4.0.0" - strip-ansi "^3.0.1" - supports-color "^6.1.0" - url "^0.11.0" - webpack-dev-middleware "^3.7.0" - webpack-log "^2.0.0" - yargs "12.0.5" - -webpack-log@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/webpack-log/-/webpack-log-2.0.0.tgz#5b7928e0637593f119d32f6227c1e0ac31e1b47f" - integrity sha512-cX8G2vR/85UYG59FgkoMamwHUIkSSlV3bBMRsbxVXVUk2j6NleCKjQ/WE9eYg9WY4w25O9w8wKP4rzNZFmUcUg== - dependencies: - ansi-colors "^3.0.0" - uuid "^3.3.2" - -webpack-merge@^4.1.2: - version "4.2.1" - resolved "https://registry.yarnpkg.com/webpack-merge/-/webpack-merge-4.2.1.tgz#5e923cf802ea2ace4fd5af1d3247368a633489b4" - integrity sha512-4p8WQyS98bUJcCvFMbdGZyZmsKuWjWVnVHnAS3FFg0HDaRVrPbkivx2RYCre8UiemD67RsiFFLfn4JhLAin8Vw== - dependencies: - lodash "^4.17.5" - -webpack-sources@^1.1.0, webpack-sources@^1.3.0: - version "1.3.0" - resolved "https://registry.yarnpkg.com/webpack-sources/-/webpack-sources-1.3.0.tgz#2a28dcb9f1f45fe960d8f1493252b5ee6530fa85" - integrity sha512-OiVgSrbGu7NEnEvQJJgdSFPl2qWKkWq5lHMhgiToIiN9w34EBnjYzSYs+VbL5KoYiLNtFFa7BZIKxRED3I32pA== - dependencies: - source-list-map "^2.0.0" - source-map "~0.6.1" - -webpack@^4.8.1: - version "4.36.1" - resolved "https://registry.yarnpkg.com/webpack/-/webpack-4.36.1.tgz#f546fda7a403a76faeaaa7196c50d12370ed18a9" - integrity sha512-Ej01/N9W8DVyhEpeQnbUdGvOECw0L46FxS12cCOs8gSK7bhUlrbHRnWkjiXckGlHjUrmL89kDpTRIkUk6Y+fKg== - dependencies: - "@webassemblyjs/ast" "1.8.5" - "@webassemblyjs/helper-module-context" "1.8.5" - "@webassemblyjs/wasm-edit" "1.8.5" - "@webassemblyjs/wasm-parser" "1.8.5" - acorn "^6.2.0" - ajv "^6.1.0" - ajv-keywords "^3.1.0" - chrome-trace-event "^1.0.0" - enhanced-resolve "^4.1.0" - eslint-scope "^4.0.0" - json-parse-better-errors "^1.0.2" - loader-runner "^2.3.0" - loader-utils "^1.1.0" - memory-fs "~0.4.1" - micromatch "^3.1.8" - mkdirp "~0.5.0" - neo-async "^2.5.0" - node-libs-browser "^2.0.0" - schema-utils "^1.0.0" - tapable "^1.1.0" - terser-webpack-plugin "^1.1.0" - watchpack "^1.5.0" - webpack-sources "^1.3.0" - -webpackbar@3.2.0: - version "3.2.0" - resolved "https://registry.yarnpkg.com/webpackbar/-/webpackbar-3.2.0.tgz#bdaad103fad11a4e612500e72aaae98b08ba493f" - integrity sha512-PC4o+1c8gWWileUfwabe0gqptlXUDJd5E0zbpr2xHP1VSOVlZVPBZ8j6NCR8zM5zbKdxPhctHXahgpNK1qFDPw== - dependencies: - ansi-escapes "^4.1.0" - chalk "^2.4.1" - consola "^2.6.0" - figures "^3.0.0" - pretty-time "^1.1.0" - std-env "^2.2.1" - text-table "^0.2.0" - wrap-ansi "^5.1.0" - -websocket-driver@>=0.5.1: - version "0.7.3" - resolved "https://registry.yarnpkg.com/websocket-driver/-/websocket-driver-0.7.3.tgz#a2d4e0d4f4f116f1e6297eba58b05d430100e9f9" - integrity sha512-bpxWlvbbB459Mlipc5GBzzZwhoZgGEZLuqPaR0INBGnPAY1vdBX6hPnoFXiw+3yWxDuHyQjO2oXTMyS8A5haFg== - dependencies: - http-parser-js ">=0.4.0 <0.4.11" - safe-buffer ">=5.1.0" - websocket-extensions ">=0.1.1" - -websocket-extensions@>=0.1.1: - version "0.1.3" - resolved "https://registry.yarnpkg.com/websocket-extensions/-/websocket-extensions-0.1.3.tgz#5d2ff22977003ec687a4b87073dfbbac146ccf29" - integrity sha512-nqHUnMXmBzT0w570r2JpJxfiSD1IzoI+HGVdd3aZ0yNi3ngvQ4jv1dtHt5VGxfI2yj5yqImPhOK4vmIh2xMbGg== - -when@~3.6.x: - version "3.6.4" - resolved "https://registry.yarnpkg.com/when/-/when-3.6.4.tgz#473b517ec159e2b85005497a13983f095412e34e" - integrity sha1-RztRfsFZ4rhQBUl6E5g/CVQS404= - -which-module@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/which-module/-/which-module-2.0.0.tgz#d9ef07dce77b9902b8a3a8fa4b31c3e3f7e6e87a" - integrity sha1-2e8H3Od7mQK4o6j6SzHD4/fm6Ho= - -which@^1.2.9: - version "1.3.1" - resolved "https://registry.yarnpkg.com/which/-/which-1.3.1.tgz#a45043d54f5805316da8d62f9f50918d3da70b0a" - integrity sha512-HxJdYWq1MTIQbJ3nw0cqssHoTNU267KlrDuGZ1WYlxDStUtKUhOaJmh112/TZmHxxUfuJqPXSOm7tDyas0OSIQ== - dependencies: - isexe "^2.0.0" - -wide-align@^1.1.0: - version "1.1.3" - resolved "https://registry.yarnpkg.com/wide-align/-/wide-align-1.1.3.tgz#ae074e6bdc0c14a431e804e624549c633b000457" - integrity sha512-QGkOQc8XL6Bt5PwnsExKBPuMKBxnGxWWW3fU55Xt4feHozMUhdUMaBCk290qpm/wG5u/RSKzwdAC4i51YigihA== - dependencies: - string-width "^1.0.2 || 2" - -worker-farm@^1.7.0: - version "1.7.0" - resolved "https://registry.yarnpkg.com/worker-farm/-/worker-farm-1.7.0.tgz#26a94c5391bbca926152002f69b84a4bf772e5a8" - integrity sha512-rvw3QTZc8lAxyVrqcSGVm5yP/IJ2UcB3U0graE3LCFoZ0Yn2x4EoVSqJKdB/T5M+FLcRPjz4TDacRf3OCfNUzw== - dependencies: - errno "~0.1.7" - -wrap-ansi@^2.0.0: - version "2.1.0" - resolved "https://registry.yarnpkg.com/wrap-ansi/-/wrap-ansi-2.1.0.tgz#d8fc3d284dd05794fe84973caecdd1cf824fdd85" - integrity sha1-2Pw9KE3QV5T+hJc8rs3Rz4JP3YU= - dependencies: - string-width "^1.0.1" - strip-ansi "^3.0.1" - -wrap-ansi@^5.1.0: - version "5.1.0" - resolved "https://registry.yarnpkg.com/wrap-ansi/-/wrap-ansi-5.1.0.tgz#1fd1f67235d5b6d0fee781056001bfb694c03b09" - integrity sha512-QC1/iN/2/RPVJ5jYK8BGttj5z83LmSKmvbvrXPNCLZSEb32KKVDJDl/MOt2N01qU2H/FkzEa9PKto1BqDjtd7Q== - dependencies: - ansi-styles "^3.2.0" - string-width "^3.0.0" - strip-ansi "^5.0.0" - -wrappy@1: - version "1.0.2" - resolved "https://registry.yarnpkg.com/wrappy/-/wrappy-1.0.2.tgz#b5243d8f3ec1aa35f1364605bc0d1036e30ab69f" - integrity sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8= - -xtend@^4.0.0, xtend@~4.0.1: - version "4.0.2" - resolved "https://registry.yarnpkg.com/xtend/-/xtend-4.0.2.tgz#bb72779f5fa465186b1f438f674fa347fdb5db54" - integrity sha512-LKYU1iAXJXUgAXn9URjiu+MWhyUXHsvfp7mcuYm9dSUKK0/CjtrUwFAxD82/mCWbtLsGjFIad0wIsod4zrTAEQ== - -"y18n@^3.2.1 || ^4.0.0", y18n@^4.0.0: - version "4.0.0" - resolved "https://registry.yarnpkg.com/y18n/-/y18n-4.0.0.tgz#95ef94f85ecc81d007c264e190a120f0a3c8566b" - integrity sha512-r9S/ZyXu/Xu9q1tYlpsLIsa3EeLXXk0VwlxqTcFRfg9EhMW+17kbt9G0NrgCmhGb5vT2hyhJZLfDGx+7+5Uj/w== - -yallist@^2.1.2: - version "2.1.2" - resolved "https://registry.yarnpkg.com/yallist/-/yallist-2.1.2.tgz#1c11f9218f076089a47dd512f93c6699a6a81d52" - integrity sha1-HBH5IY8HYImkfdUS+TxmmaaoHVI= - -yallist@^3.0.0, yallist@^3.0.2, yallist@^3.0.3: - version "3.0.3" - resolved "https://registry.yarnpkg.com/yallist/-/yallist-3.0.3.tgz#b4b049e314be545e3ce802236d6cd22cd91c3de9" - integrity sha512-S+Zk8DEWE6oKpV+vI3qWkaK+jSbIK86pCwe2IF/xwIpQ8jEuxpw9NyaGjmp9+BoJv5FV2piqCDcoCtStppiq2A== - -yargs-parser@^11.1.1: - version "11.1.1" - resolved "https://registry.yarnpkg.com/yargs-parser/-/yargs-parser-11.1.1.tgz#879a0865973bca9f6bab5cbdf3b1c67ec7d3bcf4" - integrity sha512-C6kB/WJDiaxONLJQnF8ccx9SEeoTTLek8RVbaOIsrAUS8VrBEXfmeSnCZxygc+XC2sNMBIwOOnfcxiynjHsVSQ== - dependencies: - camelcase "^5.0.0" - decamelize "^1.2.0" - -yargs@12.0.5: - version "12.0.5" - resolved "https://registry.yarnpkg.com/yargs/-/yargs-12.0.5.tgz#05f5997b609647b64f66b81e3b4b10a368e7ad13" - integrity sha512-Lhz8TLaYnxq/2ObqHDql8dX8CJi97oHxrjUcYtzKbbykPtVW9WB+poxI+NM2UIzsMgNCZTIf0AQwsjK5yMAqZw== - dependencies: - cliui "^4.0.0" - decamelize "^1.2.0" - find-up "^3.0.0" - get-caller-file "^1.0.1" - os-locale "^3.0.0" - require-directory "^2.1.1" - require-main-filename "^1.0.1" - set-blocking "^2.0.0" - string-width "^2.0.0" - which-module "^2.0.0" - y18n "^3.2.1 || ^4.0.0" - yargs-parser "^11.1.1" - -zepto@^1.2.0: - version "1.2.0" - resolved "https://registry.yarnpkg.com/zepto/-/zepto-1.2.0.tgz#e127bd9e66fd846be5eab48c1394882f7c0e4f98" - integrity sha1-4Se9nmb9hGvl6rSME5SIL3wOT5g= From fb63c07c7f4e2faa9bd01757541d0303f803e35d Mon Sep 17 00:00:00 2001 From: gamarin2 Date: Mon, 28 Oct 2019 10:59:12 +0100 Subject: [PATCH 129/196] R4R: Docs Cleanup (#5246) * start * work * work * work * remove table of content * links intro * fix links * remove junk * cleanup * cleanup * work * finish cleanup * addback readmes * remove nft --- README.md | 6 +- docs/README.md | 23 +-- docs/architecture/{README.MD => README.md} | 2 +- .../adr-002-docs-structure.md | 0 .../readme.md~origin_master-docs} | 0 docs/basics/README.md | 16 ++ docs/basics/app-anatomy.md | 78 +++---- docs/basics/gas-fees.md | 18 +- docs/basics/readme.md | 12 +- docs/basics/tx-lifecycle.md | 77 +++---- docs/building-modules/README.md | 91 ++------ docs/building-modules/beginblock-endblock.md | 12 +- docs/building-modules/genesis.md | 19 +- docs/building-modules/handler.md | 11 +- docs/building-modules/intro.md | 22 +- docs/building-modules/invariants.md | 19 +- docs/building-modules/keeper.md | 20 +- docs/building-modules/messages-and-queries.md | 20 +- docs/building-modules/module-interfaces.md | 33 ++- docs/building-modules/module-manager.md | 22 +- docs/building-modules/querier.md | 9 +- docs/building-modules/structure.md | 6 +- docs/concepts/readme.md | 5 - docs/core/README.md | 20 ++ docs/core/baseapp.md | 59 ++---- docs/core/context.md | 48 ++--- docs/core/encoding.md | 4 + docs/core/events.md | 9 +- docs/core/node.md | 13 +- docs/core/ocap.md | 11 +- docs/core/readme.md | 17 +- docs/core/store.md | 28 +-- docs/core/transactions.md | 52 ++--- docs/interfaces/README.md | 15 ++ docs/interfaces/cli.md | 44 ++-- docs/interfaces/clients.md | 26 --- docs/interfaces/interfaces-intro.md | 30 ++- docs/interfaces/lite/readme.md | 5 + docs/interfaces/lite/specification.md | 2 +- docs/interfaces/query-lifecycle.md | 28 ++- docs/interfaces/readme.md | 12 +- docs/interfaces/rest.md | 19 +- docs/interfaces/service-providers.md | 195 ------------------ docs/intro/README.md | 15 ++ docs/intro/intro.md | 10 +- docs/intro/readme.md | 13 +- docs/intro/sdk-app-architecture.md | 23 +-- docs/intro/sdk-design.md | 18 +- docs/intro/why-app-specific.md | 21 +- docs/modules/readme.md | 5 - docs/readme.md | 37 ++++ docs/spec/README.md | 14 +- docs/using-the-sdk/README.md | 10 + .../using-the-sdk/simulation.md | 0 x/README.md | 17 ++ x/auth/spec/README.md | 2 +- x/bank/spec/README.md | 2 +- x/crisis/spec/README.md | 2 +- x/distribution/spec/README.md | 2 +- x/gov/spec/README.md | 2 +- x/mint/spec/README.md | 2 +- x/params/spec/README.md | 2 +- x/slashing/spec/README.md | 2 +- x/staking/spec/README.md | 2 +- x/supply/spec/README.md | 2 +- 65 files changed, 584 insertions(+), 777 deletions(-) rename docs/architecture/{README.MD => README.md} (96%) rename docs/{_architecture => architecture}/adr-002-docs-structure.md (100%) rename docs/{_architecture/readme.md => architecture/readme.md~origin_master-docs} (100%) create mode 100644 docs/basics/README.md delete mode 100644 docs/concepts/readme.md create mode 100644 docs/core/README.md create mode 100644 docs/interfaces/README.md delete mode 100644 docs/interfaces/clients.md delete mode 100644 docs/interfaces/service-providers.md create mode 100644 docs/intro/README.md delete mode 100644 docs/modules/readme.md create mode 100644 docs/readme.md create mode 100644 docs/using-the-sdk/README.md rename docs/{concepts => }/using-the-sdk/simulation.md (100%) create mode 100644 x/README.md diff --git a/README.md b/README.md index 3d3e8ffd9d54..b239968141dc 100644 --- a/README.md +++ b/README.md @@ -12,7 +12,7 @@ [![riot.im](https://img.shields.io/badge/riot.im-JOIN%20CHAT-green.svg)](https://riot.im/app/#/room/#cosmos-sdk:matrix.org) The Cosmos-SDK is a framework for building blockchain applications in Golang. -It is being used to build `Gaia`, the first implementation of the Cosmos Hub. +It is being used to build [`Gaia`](https://github.com/cosmos/gaia), the first implementation of the Cosmos Hub. **WARNING**: The SDK has mostly stabilized, but we are still making some breaking changes. @@ -23,9 +23,9 @@ breaking changes. To learn how the SDK works from a high-level perspective, go to the [SDK Intro](./docs/intro/intro.md). -If you want to get started quickly and learn how to build on top of the SDK, please follow the [SDK Application Tutorial](https://github.com/cosmos/sdk-application-tutorial). You can also fork the tutorial's repo to get started building your own Cosmos SDK application. +If you want to get started quickly and learn how to build on top of the SDK, please follow the [SDK Application Tutorial](https://github.com/cosmos/sdk-application-tutorial). You can also fork the tutorial's repository to get started building your own Cosmos SDK application. -For more, please go to the [Cosmos SDK Docs](./docs/README.md) +For more, please go to the [Cosmos SDK Docs](./docs/README.md). ## Cosmos Hub Mainnet diff --git a/docs/README.md b/docs/README.md index aa68d54a99f9..0a277930bf31 100644 --- a/docs/README.md +++ b/docs/README.md @@ -3,20 +3,21 @@ ## Get Started - **[SDK Intro](./intro/intro.md)**: High-level overview of the Cosmos SDK. -- **[SDK application tutorial](https://github.com/cosmos/sdk-application-tutorial)**: A tutorial to learn the SDK. It showcases how to build an SDK-based blockchain from scratch, and explains the basic principles of the SDK in the process. +- **[SDK Application Tutorial](https://github.com/cosmos/sdk-application-tutorial)**: A tutorial that showcases how to build an SDK-based blockchain from scratch and explains the basic principles of the SDK in the process. -## Resources +## Reference -- [Specifications](./spec/README.md): Specifications of modules and other parts of the Cosmos SDK. -- [SDK API Reference](https://godoc.org/github.com/cosmos/cosmos-sdk): Godocs of the Cosmos SDK. -- [REST API spec](https://cosmos.network/rpc/): List of endpoints to interact with a `gaia` full-node through REST. +- **[Basics](./basics/README.md)**: Documentation on the basic concepts of the Cosmos SDK, like the standard anatomy of an application, the transaction lifecycle and accounts management. +- **[Core](./core/README.md)**: Documentation on the core concepts of the Cosmos SDK, like `baseapp`, the `store` or the `server`. +- **[Building Modules](./building-modules/README.md)**: Important concepts for module developers like `message`s, `keeper`s, `handler`s and `querier`s. +- **[Interfaces](./interfaces/README.md)**: Documentation on building interfaces for Cosmos SDK applications. -## Creating a new SDK project +## Other Resources -To create a new project, you can either: - -- Fork [this repo](https://github.com/cosmos/sdk-application-tutorial/). Do not forget to remove the `nameservice` module from the various files if you don't need it. -- Use community tools like [chainkit](https://github.com/blocklayerhq/chainkit). +- **[Module Directory](../x/README.md)**: Module implementations and their respective documentation. +- **[Specifications](./spec/README.md)**: Specifications of modules and other parts of the Cosmos SDK. +- **[SDK API Reference](https://godoc.org/github.com/cosmos/cosmos-sdk)**: Godocs of the Cosmos SDK. +- **[REST API spec](https://cosmos.network/rpc/)**: List of endpoints to interact with a `gaia` full-node through REST. ## Cosmos Hub @@ -33,6 +34,4 @@ Contact us for information about funding an implementation in another language. See [this file](https://github.com/cosmos/cosmos-sdk/blob/master/docs/DOCS_README.md) for details of the build process and considerations when making changes. -## Version -This documentation is built from the following commit: diff --git a/docs/architecture/README.MD b/docs/architecture/README.md similarity index 96% rename from docs/architecture/README.MD rename to docs/architecture/README.md index be5406063ec0..1d8701d95d4e 100644 --- a/docs/architecture/README.MD +++ b/docs/architecture/README.md @@ -36,4 +36,4 @@ Please add a entry below in your Pull Request for an ADR. - [ADR 009: Evidence Module](./adr-009-evidence-module.md) - [ADR 010: Modular AnteHandler](./adr-010-modular-antehandler.md) - [ADR 011: Generalize Genesis Accounts](./adr-011-generalize-genesis-accounts.md) -- [ADR 012: State Accessors](./adr-012-state-accessors.md) +- [ADR 012: State Accessors](./adr-012-state-accessors.md) \ No newline at end of file diff --git a/docs/_architecture/adr-002-docs-structure.md b/docs/architecture/adr-002-docs-structure.md similarity index 100% rename from docs/_architecture/adr-002-docs-structure.md rename to docs/architecture/adr-002-docs-structure.md diff --git a/docs/_architecture/readme.md b/docs/architecture/readme.md~origin_master-docs similarity index 100% rename from docs/_architecture/readme.md rename to docs/architecture/readme.md~origin_master-docs diff --git a/docs/basics/README.md b/docs/basics/README.md new file mode 100644 index 000000000000..c2e3e519fe76 --- /dev/null +++ b/docs/basics/README.md @@ -0,0 +1,16 @@ +--- +order: false +parent: + order: 2 +--- + +# Basics + +This repository contains reference documentation on the basic concepts of the Cosmos SDK. + +1. [Anatomy of an SDK Application](./app-anatomy.md) +2. [Lifecycle of a transaction](./tx-lifecycle.md) +3. [Accounts](./accounts.md) +4. [Gas and Fees](./gas-fees.md) + +After reading the basics, head on to the [Core Reference](../core/README.md) for more advanced material. \ No newline at end of file diff --git a/docs/basics/app-anatomy.md b/docs/basics/app-anatomy.md index acd01e5b6112..670a6a4042e7 100644 --- a/docs/basics/app-anatomy.md +++ b/docs/basics/app-anatomy.md @@ -1,3 +1,7 @@ +--- +order: 1 +--- + # Anatomy of an SDK Application ## Pre-requisite reading @@ -7,33 +11,11 @@ ## Synopsis -This document describes the core parts of a Cosmos SDK application. The placeholder name for this application will be `app`. - -- [Node Client](#node-client) -- [Core Application File](#core-application-file) -- [Modules](#modules) -- [Interfaces](#interfaces) -- [Dependencies and Makefile](#dependencies-and-makefile) - -The core parts listed above will generally translate to the following directory tree: - -``` -./app -├── cmd/ -│ ├── appd -│ └── appcli -├── app.go -├── x/ -│ ├── auth -│ ├── ... -│ └── bank -├── go.mod -└── Makefile -``` +This document describes the core parts of a Cosmos SDK application. Throughout the document, a placeholder application named `app` will be used. ## Node Client -The Daemon, or Full-Node Client, is the core process of an SDK-based blockchain. Participants in the network run this process to initialize their state-machine, connect with other full-nodes and update their state-machine as new blocks come in. +The Daemon, or [Full-Node Client](../core/node.md), is the core process of an SDK-based blockchain. Participants in the network run this process to initialize their state-machine, connect with other full-nodes and update their state-machine as new blocks come in. ``` ^ +-------------------------------+ ^ @@ -53,9 +35,7 @@ Blockchain Node | | Consensus | | v +-------------------------------+ v ``` -The blockchain full-node presents itself as a binary, generally suffixed by `-d` for "daemon" (e.g. `appd` for `app` or `gaiad` for `gaia`). This binary is built by running a simple `main.go` function placed in `cmd/appd/`. This operation usually happens through the [Makefile](#dependencies-and-makefile). - -To learn more about the `main.go` function, [click here](../core/node.md#main-function). +The blockchain full-node presents itself as a binary, generally suffixed by `-d` for "daemon" (e.g. `appd` for `app` or `gaiad` for `gaia`). This binary is built by running a simple [`main.go`]((../core/node.md#main-function)) function placed in `./cmd/appd/`. This operation usually happens through the [Makefile](#dependencies-and-makefile). Once the main binary is built, the node can be started by running the `start` command. The core logic behind the `start` command is implemented in the SDK itself in the [`/server/start.go`](https://github.com/cosmos/cosmos-sdk/blob/master/server/start.go) file. The main [`start` command function](https://github.com/cosmos/cosmos-sdk/blob/master/server/start.go#L31) takes a [`context`](https://godoc.org/github.com/cosmos/cosmos-sdk/client/context) and [`appCreator`](<#constructor-function-(`appCreator`)>) as arguments. The `appCreator` is a constructor function for the SDK application, and is used in the starting process of the full-node. @@ -73,11 +53,11 @@ In general, the core of the state-machine is defined in a file called `app.go`. The first thing defined in `app.go` is the `type` of the application. It is generally comprised of the following parts: -- **A reference to [`baseapp`](../core/baseapp.md).** The custom application defined in `app.go` is an extension of the `baseapp` type. When a transaction is relayed by Tendermint to the application, the latter uses `baseapp`'s methods to route them to the appropriate module. `baseapp` implements most of the core logic for the application, including all the [ABCI methods](https://tendermint.com/docs/spec/abci/abci.html#overview) and the routing logic. Since `baseapp` implements these ABCI methods and `app` extends `baseapp`, it means that `app` satisfies the [`abci.Application` interface](https://github.com/tendermint/tendermint/blob/bc572217c07b90ad9cee851f193aaa8e9557cbc7/abci/types/application.go#L11-L26), which is a must for the [full-node](../core/node.md) to work. -- **A list of store keys**. The [store](../core/store.md), which contains the entire state, is implemented as a multistore (i.e. a store of stores) in the Cosmos SDK. Each module uses one or multiple stores in the multistore to persist their part of the state. These stores can be accessed with specific keys that are declared in the `app` type. These keys, along with the `keepers`, are at the heart of the [object-capabilities model](../intro/ocap.md) of the Cosmos SDK. -- **A list of module's `keepers`.** Each module defines an abstraction called [`keeper`](../building-modules/keeper.md), which handles reads and writes for this module's store(s). The `keeper`'s methods of one module can be called from other modules (if authorized), which is why they are declared in the application's type and exported as interfaces to other modules so that they are only allowed to access the authorized functions. -- **A reference to a [`codec`](../core/encoding.md).** The Cosmos SDK gives developers the freedom to choose the encoding framework for their application. The application's `codec` is used to serialize and deserialize data structures in order to store them, as stores can only persist `[]bytes`. The `codec` must be deterministic. The default codec is [amino](./amino.md). -- **A reference to a [module manager](../building-modules/module-manager.md#manager)** and a [basic module manager](../building-modules/module-manager.md#basicmanager). The module manager is an object that contains a list of the application's module. It facilitates operations related to these modules, like registering [`routes`](./baseapp.md#routing), [query routes](#./baseapp.md#query-routing) or setting the order of execution between modules for various functions like [`InitChainer`](#initchainer), [`BeginBlocker` and `EndBlocker`](#beginblocker-and-endblocker). +- **A reference to [`baseapp`](../core/baseapp.md).** The custom application defined in `app.go` is an extension of `baseapp`. When a transaction is relayed by Tendermint to the application, `app` uses `baseapp`'s methods to route them to the appropriate module. `baseapp` implements most of the core logic for the application, including all the [ABCI methods](https://tendermint.com/docs/spec/abci/abci.html#overview) and the [routing logic](../core/baseapp.md#routing). Since `baseapp` implements ABCI methods and `app` extends `baseapp`, it means that `app` satisfies the [`abci.Application` interface](https://github.com/tendermint/tendermint/blob/bc572217c07b90ad9cee851f193aaa8e9557cbc7/abci/types/application.go#L11-L26), which is a must for the [full-node](../core/node.md) to work. +- **A list of store keys**. The [store](../core/store.md), which contains the entire state, is implemented as a [`multistore`](../core/store.md#multistore) (i.e. a store of stores) in the Cosmos SDK. Each module uses one or multiple stores in the multistore to persist their part of the state. These stores can be accessed with specific keys that are declared in the `app` type. These keys, along with the `keepers`, are at the heart of the [object-capabilities model](../core/ocap.md) of the Cosmos SDK. +- **A list of module's `keeper`s.** Each module defines an abstraction called [`keeper`](../building-modules/keeper.md), which handles reads and writes for this module's store(s). The `keeper`'s methods of one module can be called from other modules (if authorized), which is why they are declared in the application's type and exported as interfaces to other modules so that the latter can only access the authorized functions. +- **A reference to a [`codec`](../core/encoding.md).** The application's `codec` is used to serialize and deserialize data structures in order to store them, as stores can only persist `[]bytes`. The `codec` must be deterministic. The default codec is [amino](../core/encoding.md). +- **A reference to a [module manager](../building-modules/module-manager.md#manager)** and a [basic module manager](../building-modules/module-manager.md#basicmanager). The module manager is an object that contains a list of the application's module. It facilitates operations related to these modules, like registering [`routes`](../core/baseapp.md#routing), [query routes](../core/baseapp.md#query-routing) or setting the order of execution between modules for various functions like [`InitChainer`](#initchainer), [`BeginBlocker` and `EndBlocker`](#beginblocker-and-endblocker). You can see an example of application type definition [here](https://github.com/cosmos/gaia/blob/master/app/app.go#L73-L107). @@ -105,9 +85,9 @@ You can see an example of application constructor [here](https://github.com/cosm ### InitChainer -The `InitChainer` is a function that initializes the state of the application from a [genesis file](../core/genesis.md) (i.e. token balances of genesis accounts). It is called when the application receives the `InitChain` message from the Tendermint engine, which happens when the node is started at `appBlockHeight == 0` (i.e. on genesis). The application must set the `InitChainer` in its constructor via the [`SetInitChainer`](https://godoc.org/github.com/cosmos/cosmos-sdk/baseapp#BaseApp.SetInitChainer) method. +The `InitChainer` is a function that initializes the state of the application from a genesis file (i.e. token balances of genesis accounts). It is called when the application receives the `InitChain` message from the Tendermint engine, which happens when the node is started at `appBlockHeight == 0` (i.e. on genesis). The application must set the `InitChainer` in its constructor via the [`SetInitChainer`](https://godoc.org/github.com/cosmos/cosmos-sdk/baseapp#BaseApp.SetInitChainer) method. -In general, the `InitChainer` is mostly composed of the `InitGenesis` function of each of the application's modules. This is done by calling the `InitGenesis` function of the module manager, which in turn will call the `InitGenesis` function of each of the modules it contains. Note that the order in which the modules' `InitGenesis` functions must be called has to be set in the module manager using the `SetOrderInitGenesis` method. This is done in the [application's constructor](#application-constructor), and the `SetOrderInitGenesis` has to be called before the `SetInitChainer`. +In general, the `InitChainer` is mostly composed of the [`InitGenesis`](../building-modules/genesis.md#initgenesis) function of each of the application's modules. This is done by calling the `InitGenesis` function of the module manager, which in turn will call the `InitGenesis` function of each of the modules it contains. Note that the order in which the modules' `InitGenesis` functions must be called has to be set in the module manager using the [module manager's](../building-modules/module-manager.md) `SetOrderInitGenesis` method. This is done in the [application's constructor](#application-constructor), and the `SetOrderInitGenesis` has to be called before the `SetInitChainer`. You can see an example of an `InitChainer` [here](https://github.com/cosmos/gaia/blob/f41a660cdd5bea173139965ade55bd25d1ee3429/app/app.go#L235-L239). @@ -115,7 +95,7 @@ You can see an example of an `InitChainer` [here](https://github.com/cosmos/gaia The SDK offers developers the possibility to implement automatic execution of code as part of their application. This is implemented through two function called `BeginBlocker` and `EndBlocker`. They are called when the application receives respectively the `BeginBlock` and `EndBlock` messages from the Tendermint engine, which happens at the beginning and at the end of each block. The application must set the `BeginBlocker` and `EndBlocker` in its constructor via the [`SetBeginBlocker`](https://godoc.org/github.com/cosmos/cosmos-sdk/baseapp#BaseApp.SetBeginBlocker) and [`SetEndBlocker`](https://godoc.org/github.com/cosmos/cosmos-sdk/baseapp#BaseApp.SetEndBlocker) methods. -In general, the `BeginBlocker` and `EndBlocker` functions are mostly composed of the `BeginBlock` and `EndBlock` functions of each of the application's modules. This is done by calling the `BeginBlock` and `EndBlock` functions of the module manager, which in turn will call the `BeginBLock` and `EndBlock` functions of each of the modules it contains. Note that the order in which the modules' `BegingBlock` and `EndBlock` functions must be called has to be set in the module manager using the `SetOrderBeginBlock` and `SetOrderEndBlock` methods respectively. This is done in the [application's constructor](#application-constructor), and the `SetOrderBeginBlock` and `SetOrderEndBlock` methods have to be called before the `SetBeginBlocker` and `SetEndBlocker` functions. +In general, the `BeginBlocker` and `EndBlocker` functions are mostly composed of the [`BeginBlock` and `EndBlock`](../building-modules/beginblock-endblock.md) functions of each of the application's modules. This is done by calling the `BeginBlock` and `EndBlock` functions of the module manager, which in turn will call the `BeginBLock` and `EndBlock` functions of each of the modules it contains. Note that the order in which the modules' `BegingBlock` and `EndBlock` functions must be called has to be set in the module manager using the `SetOrderBeginBlock` and `SetOrderEndBlock` methods respectively. This is done via the [module manager](../building-modules/module-manager.md) in the [application's constructor](#application-constructor), and the `SetOrderBeginBlock` and `SetOrderEndBlock` methods have to be called before the `SetBeginBlocker` and `SetEndBlocker` functions. As a sidenote, it is important to remember that application-specific blockchains are deterministic. Developers must be careful not to introduce non-determinism in `BeginBlocker` or `EndBlocker`, and must also be careful not to make them too computationally expensive, as [gas](./gas-fees.md) does not constrain the cost of `BeginBlocker` and `EndBlocker` execution. @@ -123,7 +103,7 @@ You can see an example of `BeginBlocker` and `EndBlocker` functions [here](https ### Register Codec -The `MakeCodec` function is the last important function of the `app.go` file. The goal of this function is to instantiate a codec `cdc` (e.g. amino) initialize the codec of the SDK and each of the application's modules using the `RegisterCodec` function. +The `MakeCodec` function is the last important function of the `app.go` file. The goal of this function is to instantiate a [codec `cdc`](../core/encoding.md) (e.g. amino) initialize the codec of the SDK and each of the application's modules using the `RegisterCodec` function. To register the application's modules, the `MakeCodec` function calls `RegisterCodec` on `ModuleBasics`. `ModuleBasics` is a [basic manager](../building-modules/module-manager.md#basicmanager) which lists all of the application's modules. It is instanciated in the `init()` function, and only serves to easily register non-dependant elements of application's modules (such as codec). To learn more about the basic module manager, click [here](../building-modules/module-manager.md#basicmanager). @@ -131,13 +111,13 @@ You can see an example of a `MakeCodec` [here](https://github.com/cosmos/gaia/bl ## Modules -Modules are the heart and soul of an SDK application. They can be considered as state-machines within the state-machine. When a transaction is relayed from the underlying Tendermint engine via the ABCI to the application, it is routed by [`baseapp`](../core/baseapp.md) to the appropriate module in order to be processed. This paradigm enables developers to easily build complex state-machines, as most of the modules they need often already exist. For developers, most of the work involved in building an SDK application revolves around building custom modules required by their application that do not exist, and integrating them with modules that do already exist into one coherent application. In the application directory, the standard practice is to store modules in the `x/` folder (not to be confused with the SDK's `x/` folder, which contains already-built modules). +Modules are the heart and soul of SDK applications. They can be considered as state-machines within the state-machine. When a transaction is relayed from the underlying Tendermint engine via the ABCI to the application, it is routed by [`baseapp`](../core/baseapp.md) to the appropriate module in order to be processed. This paradigm enables developers to easily build complex state-machines, as most of the modules they need often already exist. For developers, most of the work involved in building an SDK application revolves around building custom modules required by their application that do not exist yet, and integrating them with modules that do already exist into one coherent application. In the application directory, the standard practice is to store modules in the `x/` folder (not to be confused with the SDK's `x/` folder, which contains already-built modules). -To learn more about modules, [click here](./modules.md) +To learn more about modules, [click here](../building-modules/intro.md) ### Application Module Interface -Modules implement two interfaces defined in the Cosmos SDK, [`AppModuleBasic`](../building-modules/module-manager.md#appmodulebasic) and [`AppModule`](../building-modules/module-manager.md#appmodule). The former implements basic non-dependant elements of the module, such as the `codec`, while the latter handles the bulk of the module methods (including methods that require references to other modules' `keeper`s). Both the `AppModule` and `AppModuleBasic` types are defined in a file called `./module.go`. +Modules must implement two interfaces defined in the Cosmos SDK, [`AppModuleBasic`](../building-modules/module-manager.md#appmodulebasic) and [`AppModule`](../building-modules/module-manager.md#appmodule). The former implements basic non-dependant elements of the module, such as the `codec`, while the latter handles the bulk of the module methods (including methods that require references to other modules' `keeper`s). Both the `AppModule` and `AppModuleBasic` types are defined in a file called `./module.go`. `AppModule` exposes a collection of useful methods on the module that facilitates the composition of modules into a coherent application. These methods are are called from the `module manager`(../building-modules/module-manager.md#manager), which manages the application's collection of modules. @@ -145,26 +125,28 @@ To learn more about the application module interface, [click here](../building-m ### Message Types -A message is a custom type defined by each module that implements the [`message`](../building-modules/messages-and-queries.md#messages) interface. Each [`transaction`](../core/transaction.md) contains one or multiple `messages`. When a valid block of transactions is received by the full-node, Tendermint relays each one to the application via [`DeliverTx`](https://tendermint.com/docs/app-dev/abci-spec.html#delivertx). Then, the application handles the transaction: +`Message`s are objects defined by each module that implement the [`message`](../building-modules/messages-and-queries.md#messages) interface. Each [`transaction`](../core/transactions.md) contains one or multiple `messages`. + +When a valid block of transactions is received by the full-node, Tendermint relays each one to the application via [`DeliverTx`](https://tendermint.com/docs/app-dev/abci-spec.html#delivertx). Then, the application handles the transaction: 1. Upon receiving the transaction, the application first unmarshalls it from `[]bytes`. 2. Then, it verifies a few things about the transaction like [fee payment and signatures](#gas-fees.md#antehandler) before extracting the message(s) contained in the transaction. -3. With the [`Type()`](https://github.com/cosmos/cosmos-sdk/blob/master/types/tx_msg.go#L16) method, `baseapp` is able to know which modules defines the message. It is then able to route it to the appropriate module's [handler](#handler) in order for the message to be processed. +3. With the [`Type()`](https://github.com/cosmos/cosmos-sdk/blob/master/types/tx_msg.go#L16) method, `baseapp` is able to know which modules defines the message. It is then able to route it to the appropriate module's [`handler`](#handler) in order for the message to be processed. 4. If the message is successfully processed, the state is updated. For a more detailed look at a transaction lifecycle, click [here](./tx-lifecycle.md). -Module developers create custom message types when they build their own module. The general practice is to prefix the type declaration of the message with `Msg`. For example, the message type [`MsgSend`](https://github.com/cosmos/cosmos-sdk/blob/master/x/bank/types/msgs.go#L10-L15) allows users to transfer tokens. It is processed by the handler of the `bank` module, which ultimately calls the `keeper` of the `auth` module in order to update the state. +Module developers create custom message types when they build their own module. The general practice is to prefix the type declaration of the message with `Msg`. For example, the message type [`MsgSend`](https://github.com/cosmos/cosmos-sdk/blob/master/x/bank/internal/types/msgs.go#L11-L15) allows users to transfer tokens. It is processed by the `handler` of the `bank` module, which ultimately calls the `keeper` of the `auth` module in order to update the state. To learn more about messages, [click here](../building-modules/messages-and-queries.md#messages). ### Handler -The [`handler`](../building-modules/handler.md) refers to the part of the module responsible for processing the message after it is routed by `baseapp`. `handler` functions of modules (except those of the `auth` module) are only executed if the transaction is relayed from Tendermint by the `DeliverTx` ABCI message. If the transaction is relayed by `CheckTx`, only stateless checks and fee-related (i.e. `auth` module-related) stateful checks are performed. To better understand the difference between `DeliverTx`and `CheckTx`, as well as the difference between stateful and stateless checks, click [here](./tx-lifecycle.md). +The [`handler`](../building-modules/handler.md) refers to the part of the module responsible for processing the `message` after it is routed by `baseapp`. `handler` functions of modules are only executed if the transaction is relayed from Tendermint by the `DeliverTx` ABCI message. If the transaction is relayed by `CheckTx`, only stateless checks and fee-related stateful checks are performed. To better understand the difference between `DeliverTx`and `CheckTx`, as well as the difference between stateful and stateless checks, click [here](./tx-lifecycle.md). -The handler of a module is generally defined in a file called `handler.go` and consists of: +The `handler` of a module is generally defined in a file called `handler.go` and consists of: -- A **switch function** `NewHandler` to route the message to the appropriate handler function. This function returns a `handler` function, and is registered in the [`AppModule`](#application-module-interface) to be used in the application's module manager to initialize the [application's router](../core/baseapp.md#routing). See an example of such a switch [here](https://github.com/cosmos/sdk-application-tutorial/blob/c6754a1e313eb1ed973c5c91dcc606f2fd288811/x/nameservice/handler.go#L10-L22). +- A **switch function** `NewHandler` to route the message to the appropriate `handler` function. This function returns a `handler` function, and is registered in the [`AppModule`](#application-module-interface) to be used in the application's module manager to initialize the [application's router](../core/baseapp.md#routing). See an example of such a switch [here](https://github.com/cosmos/sdk-application-tutorial/blob/c6754a1e313eb1ed973c5c91dcc606f2fd288811/x/nameservice/handler.go#L10-L22). - **One handler function for each message type defined by the module**. Developers write the message processing logic in these functions. This generally involves doing stateful checks to ensure the message is valid and calling [`keeper`](#keeper)'s methods to update the state. Handler functions return a result of type [`sdk.Result`](https://github.com/cosmos/cosmos-sdk/blob/master/types/result.go#L14-L37), which informs the application on whether the message was successfully processed. @@ -173,7 +155,7 @@ To learn more about handlers, [click here](../building-modules/handler.md). ### Keeper -[`Keepers`](../building-module/keeper.md) are the gatekeepers of their module's store(s). To read or write in a module's store, it is mandatory to go through one of its `keeper`'s methods. This is ensured by the [object-capabilities](../core/ocap.md) model of the Cosmos SDK. Only objects that hold the key to a store can access it, and only the module's `keeper` should hold the key(s) to the module's store(s). +[`Keepers`](../building-modules/keeper.md) are the gatekeepers of their module's store(s). To read or write in a module's store, it is mandatory to go through one of its `keeper`'s methods. This is ensured by the [object-capabilities](../core/ocap.md) model of the Cosmos SDK. Only objects that hold the key to a store can access it, and only the module's `keeper` should hold the key(s) to the module's store(s). `Keepers` are generally defined in a file called `keeper.go`. It contains the `keeper`'s type definition and methods. @@ -207,7 +189,7 @@ Each module defines command-line commands and REST routes to be exposed to end-u Generally, the commands related to a module are defined in a folder called `client/cli` in the module's folder. The CLI divides commands in two category, transactions and queries, defined in `client/cli/tx.go` and `client/cli/query.go` respectively. Both commands are built on top of the [Cobra Library](https://github.com/spf13/cobra): - Transactions commands let users generate new transactions so that they can be included in a block and eventually update the state. One command should be created for each [message type](#message-types) defined in the module. The command calls the constructor of the message with the parameters provided by the end-user, and wraps it into a transaction. The SDK handles signing and the addition of other transaction metadata. -- Queries let users query the subset of the state defined by the module. Query commands forward queries to the [application's query router](./baseapp.md#query-routing), which routes them to the appropriate [querier](#querier) the `queryRoute` parameter supplied. +- Queries let users query the subset of the state defined by the module. Query commands forward queries to the [application's query router](../core/baseapp.md#query-routing), which routes them to the appropriate [querier](#querier) the `queryRoute` parameter supplied. To learn more about modules CLI, [click here](../building-modules/module-interfaces.md#cli). @@ -234,7 +216,7 @@ The main interface is the [Command-Line Interface](../interfaces/cli.md). The CL See an example of an application's main command-line file [here](https://github.com/cosmos/sdk-application-tutorial/blob/c6754a1e313eb1ed973c5c91dcc606f2fd288811/cmd/nscli/main.go). -To learn more about interfaces, [click here](../interfaces/intro.md). +To learn more about interfaces, [click here](../interfaces/interfaces-intro.md). ## Dependencies and Makefile diff --git a/docs/basics/gas-fees.md b/docs/basics/gas-fees.md index 908197f2d951..49e19521479e 100644 --- a/docs/basics/gas-fees.md +++ b/docs/basics/gas-fees.md @@ -13,7 +13,7 @@ This document describes the default strategies to handle gas and fees within a C In the Cosmos SDK, `gas` is a special unit that is used to track the consumption of resources during execution. `gas` is typically consumed whenever read and writes are made to the store, but it can also be consumed if expensive computation needs to be done. It serves two main purposes: - Make sure blocks are not consuming too many resources and will be finalized. This is implemented by default in the SDK via the [block gas meter](#block-gas-meter). -- Prevent spam and abuse from end-user. To this end, `gas` consumed during [`message`](../building-modules/messages-and-queries.md#messages) execution is typically priced, resulting in a `fee` (`fees = gas * gas-prices`). This fee generally has to be paid by the sender of the `message`. Note that the SDK does not enforce `gas` pricing by default, as there may be other ways to prevent spam (e.g. bandwidth schemes). Still, most applications will implement `fee` mechanisms to prevent spam. This is done via the [`AnteHandler`](#antehandler). +- Prevent spam and abuse from end-user. To this end, `gas` consumed during [`message`](../building-modules/messages-and-queries.md#messages) execution is typically priced, resulting in a `fee` (`fees = gas * gas-prices`). `fees` generally have to be paid by the sender of the `message`. Note that the SDK does not enforce `gas` pricing by default, as there may be other ways to prevent spam (e.g. bandwidth schemes). Still, most applications will implement `fee` mechanisms to prevent spam. This is done via the [`AnteHandler`](#antehandler). ## Gas Meter @@ -55,20 +55,20 @@ Gas comsumption can be done manually, generally by the module developer in the [ ### Block Gas Meter -`ctx.BlockGasMeter()` is the gas meter used to track gas consumption per block and make sure it does not go above a certain limit. A new instance of the `BlockGasMeter` is created each time [`BeginBlock`](../core/baseapp.go#beginblock) is called. The `BlockGasMeter` is finite, and the limit of gas per block is defined in the application's consensus parameters. +`ctx.BlockGasMeter()` is the gas meter used to track gas consumption per block and make sure it does not go above a certain limit. A new instance of the `BlockGasMeter` is created each time [`BeginBlock`](../core/baseapp.md#beginblock) is called. The `BlockGasMeter` is finite, and the limit of gas per block is defined in the application's consensus parameters (by default Cosmos SDK applications use the [default consensus parameters provided by Tendermint](https://github.com/tendermint/tendermint/blob/f323c80cb3b78e123ea6238c8e136a30ff749ccc/types/params.go#L65-L72)). -When a new [transaction](../core/transaction.md) is being processed via `DeliverTx`, the current value of `BlockGasMeter` is checked to see if it is above the limit. If it is, `DeliverTx` returns immediately. This can happen even with the first transaction in a block, as `BeginBlock` itself can consume gas. If not, the transaction is processed normally. At the end of `DeliverTx`, the gas tracked by `ctx.BlockGasMeter()` is increased by the amount consumed to process the transaction: +When a new [transaction](../core/transactions.md) is being processed via `DeliverTx`, the current value of `BlockGasMeter` is checked to see if it is above the limit. If it is, `DeliverTx` returns immediately. This can happen even with the first transaction in a block, as `BeginBlock` itself can consume gas. If not, the transaction is processed normally. At the end of `DeliverTx`, the gas tracked by `ctx.BlockGasMeter()` is increased by the amount consumed to process the transaction: ```go ctx.BlockGasMeter().ConsumeGas( - ctx.GasMeter().GasConsumedToLimit(), - "block gas meter", - ) + ctx.GasMeter().GasConsumedToLimit(), + "block gas meter", +) ``` ## AnteHandler -The `AnteHandler` is a special `handler` that is run for every transaction during `CheckTx` and `DeliverTx`, before the `handler` of each `message` in the transaction. `AnteHandler` have a different signature than `handler`s: +The `AnteHandler` is a special `handler` that is run for every transaction during `CheckTx` and `DeliverTx`, before the `handler` of each `message` in the transaction. `AnteHandler`s have a different signature than `handler`s: ```go // AnteHandler authenticates transactions, before their internal messages are handled. @@ -76,13 +76,13 @@ The `AnteHandler` is a special `handler` that is run for every transaction durin type AnteHandler func(ctx Context, tx Tx, simulate bool) (newCtx Context, result Result, abort bool) ``` -Being a `handler`, the `anteHandler` is not implemented in the core SDK but in a module. This gives the possibility to developers to choose the version of `AnteHandler` that fits their application's needs. That said, most applications today use the default implementation defined in the [`auth` module](https://github.com/cosmos/cosmos-sdk/tree/master/x/auth). Here is what the `anteHandler` is intended to do in a normal Cosmos SDK application: +The `anteHandler` is not implemented in the core SDK but in a module. This gives the possibility to developers to choose which version of `AnteHandler` fits their application's needs. That said, most applications today use the default implementation defined in the [`auth` module](https://github.com/cosmos/cosmos-sdk/tree/master/x/auth). Here is what the `anteHandler` is intended to do in a normal Cosmos SDK application: - Verify that the transaction are of the correct type. Transaction types are defined in the module that implements the `anteHandler`, and they follow the [transaction interface](https://github.com/cosmos/cosmos-sdk/blob/master/types/tx_msg.go#L34-L41). This enables developers to play with various types for the transaction of their application. In the default `auth` module, the standard transaction type is [`StdTx`](https://github.com/cosmos/cosmos-sdk/blob/master/x/auth/types/stdtx.go#L23-L28). - Verify signatures for each [`message`](../building-modules/messages-and-queries.md#messages) contained in the transaction. Each `message` should be signed by one or multiple sender(s), and these signatures must be verified in the `anteHandler`. - During `CheckTx`, verify that the gas prices provided with the transaction is greater than the local `min-gas-prices` (as a reminder, gas-prices can be deducted from the following equation: `fees = gas * gas-prices`). `min-gas-prices` is a parameter local to each full-node and used during `CheckTx` to discard transactions that do not provide a minimum amount of fees. This ensure that the mempool cannot be spammed with garbage transactions. - Verify that the sender of the transaction has enough funds to cover for the `fees`. When the end-user generates a transaction, they must indicate 2 of the 3 following parameters (the third one being implicit): `fees`, `gas` and `gas-prices`. This signals how much they are willing to pay for nodes to execute their transaction. The provided `gas` value is stored in a parameter called `GasWanted` for later use. -- Set `newCtx.GasMeter` to 0, with a limit of `GasWanted`. **This step is extremely important**, as it not only makes sure the transaction cannot consume infinite gas, but also that `ctx.GasMeter` is reset in-between each `DeliverTx` (`ctx` is set to `newCtx` after `anteHandler` is run). +- Set `newCtx.GasMeter` to 0, with a limit of `GasWanted`. **This step is extremely important**, as it not only makes sure the transaction cannot consume infinite gas, but also that `ctx.GasMeter` is reset in-between each `DeliverTx` (`ctx` is set to `newCtx` after `anteHandler` is run, and the `anteHandler` is run each time `DeliverTx` is called). As explained above, the `anteHandler` returns a maximum limit of `gas` the transaction can consume during execution called `GasWanted`. The actual amount consumed in the end is denominated `GasUsed`, and we must therefore have `GasUsed =< GasWanted`. Both `GasWanted` and `GasUsed` are relayed to the underlying consensus engine when [`DeliverTx`](../core/baseapp.md#delivertx) returns. diff --git a/docs/basics/readme.md b/docs/basics/readme.md index 1d13db5d1f5b..c2e3e519fe76 100644 --- a/docs/basics/readme.md +++ b/docs/basics/readme.md @@ -2,5 +2,15 @@ order: false parent: order: 2 - title: Basics --- + +# Basics + +This repository contains reference documentation on the basic concepts of the Cosmos SDK. + +1. [Anatomy of an SDK Application](./app-anatomy.md) +2. [Lifecycle of a transaction](./tx-lifecycle.md) +3. [Accounts](./accounts.md) +4. [Gas and Fees](./gas-fees.md) + +After reading the basics, head on to the [Core Reference](../core/README.md) for more advanced material. \ No newline at end of file diff --git a/docs/basics/tx-lifecycle.md b/docs/basics/tx-lifecycle.md index 86b5f2753da6..c964ad2addaf 100644 --- a/docs/basics/tx-lifecycle.md +++ b/docs/basics/tx-lifecycle.md @@ -1,3 +1,7 @@ +--- +order: 2 +--- + # Transaction Lifecycle ## Prerequisite Reading @@ -6,13 +10,7 @@ ## Synopsis -This document describes the lifecycle of a transaction from creation to committed state changes. Transaction definition is described in a [different doc](../core/tx-msgs.md#transactions). The transaction will be referred to as `Tx`. - -- [Creation](#creation) -- [Addition to Mempool](#addition-to-mempool) -- [Inclusion in a Block](#inclusion-in-a-block) -- [State Changes](#state-changes) -- [Consensus and Commit](#consensus-and-commit) +This document describes the lifecycle of a transaction from creation to committed state changes. Transaction definition is described in a [different doc](../core/transactions.md). The transaction will be referred to as `Tx`. ## Creation @@ -56,12 +54,8 @@ The command-line is an easy way to interact with an application, but `Tx` can al ## Addition to Mempool Each full-node (running Tendermint) that receives a `Tx` sends an [ABCI message](https://tendermint.com/docs/spec/abci/abci.html#messages), -`CheckTx`, to the application layer to check for validity, and receives an -`abci.ResponseCheckTx`. If the `Tx` passes the checks, it is held in the nodes' -[**Mempool**](https://tendermint.com/docs/tendermint-core/mempool.html#mempool) -(an in-memory pool of transactions unique to each node) pending inclusion in a -block - honest nodes will discard `Tx` if it is found to be invalid. Prior to -consensus, nodes continuously check incoming transactions and gossip them to their peers. +`CheckTx`, to the application layer to check for validity, and receives an `abci.ResponseCheckTx`. If the `Tx` passes the checks, it is held in the nodes' +[**Mempool**](https://tendermint.com/docs/tendermint-core/mempool.html#mempool), an in-memory pool of transactions unique to each node) pending inclusion in a block - honest nodes will discard `Tx` if it is found to be invalid. Prior to consensus, nodes continuously check incoming transactions and gossip them to their peers. ### Types of Checks @@ -86,21 +80,21 @@ through several steps, beginning with decoding `Tx`. ### Decoding -When `Tx` is received by the application from the underlying consensus engine (e.g. Tendermint), it is still in its encoded (i.e. using [Amino](https://tendermint.com/docs/spec/blockchain/encoding.html#amino)) `[]byte` form and needs to be unmarshaled in order to be processed. Then, the [`runTx`](../core/baseapp.md#runtx-and-runmsgs) function is called to run in `runTxModeCheck` mode, meaning the function will run all checks but exit before executing messages and writing state changes. +When `Tx` is received by the application from the underlying consensus engine (e.g. Tendermint), it is still in its [encoded](../core/encoding.md) `[]byte` form and needs to be unmarshaled in order to be processed. Then, the [`runTx`](../core/baseapp.md#runtx-and-runmsgs) function is called to run in `runTxModeCheck` mode, meaning the function will run all checks but exit before executing messages and writing state changes. ### ValidateBasic -[Messages](../core/tx-msgs.md#messages) are extracted from `Tx` and `ValidateBasic`, a function defined by the module developer for every message, is run for each one. It should include basic stateless sanity checks. For example, if the message is to send coins from one address to another, `ValidateBasic` likely checks for nonempty addresses and a nonnegative coin amount, but does not require knowledge of state such as account balance of an address. +[`Message`s](../core/transactions.md#messages) are extracted from `Tx` and `ValidateBasic`, a method of the `Msg` interface implemented by the module developer, is run for each one. It should include basic **stateless** sanity checks. For example, if the message is to send coins from one address to another, `ValidateBasic` likely checks for nonempty addresses and a nonnegative coin amount, but does not require knowledge of state such as account balance of an address. ### AnteHandler -The [`AnteHandler`](../core/baseapp.md#antehandler), which is technically optional but should be defined for each application, is run. A deep copy of the internal state, `checkState`, is made and the defined `AnteHandler` performs limited checks specified for the transaction type. Using a copy allows the handler to do stateful checks for `Tx` without modifying the last committed state, and revert back to the original if the execution fails. +The [`AnteHandler`](../basics/gas-fees.md#antehandler), which is technically optional but should be defined for each application, is run. A deep copy of the internal state, `checkState`, is made and the defined `AnteHandler` performs limited checks specified for the transaction type. Using a copy allows the handler to do stateful checks for `Tx` without modifying the last committed state, and revert back to the original if the execution fails. -For example, the [`auth`](https://github.com/cosmos/cosmos-sdk/tree/master/docs/spec/auth) module `AnteHandler` checks and increments sequence numbers, checks signatures and account numbers, and deducts fees from the first signer of the transaction - all state changes are made using the `checkState`. +For example, the [`auth`](https://github.com/cosmos/cosmos-sdk/tree/master/x/auth/spec) module `AnteHandler` checks and increments sequence numbers, checks signatures and account numbers, and deducts fees from the first signer of the transaction - all state changes are made using the `checkState`. ### Gas -The [`Context`](../core/context.md) used to keep track of important data while `AnteHandler` is executing `Tx` keeps a `GasMeter` which tracks how much gas has been used. The user-provided amount for gas is known as the value `GasWanted`. If `GasConsumed`, the amount of gas consumed so far, ever exceeds `GasWanted`, execution stops. Otherwise, `CheckTx` sets `GasUsed` equal to `GasConsumed` and returns it in the result. After calculating the gas and fee values, validator-nodes check that the user-specified `gas-prices` is less than their locally defined `min-gas-prices`. +The [`Context`](../core/context.md), which keeps a `GasMeter` that will track how much gas has been used during the execution of `Tx`, is initialized. The user-provided amount of gas for `Tx` is known as `GasWanted`. If `GasConsumed`, the amount of gas consumed so during execution, ever exceeds `GasWanted`, the execution will stop and the changes made to the cacehd copy of the state won't be committed. Otherwise, `CheckTx` sets `GasUsed` equal to `GasConsumed` and returns it in the result. After calculating the gas and fee values, validator-nodes check that the user-specified `gas-prices` is less than their locally defined `min-gas-prices`. ### Discard or Addition to Mempool @@ -109,8 +103,7 @@ there. Otherwise, if it passes `CheckTx` successfully, the default protocol is t nodes and add it to the Mempool so that the `Tx` becomes a candidate to be included in the next block. The **mempool** serves the purpose of keeping track of transactions seen by all full-nodes. -Full-nodes that are not validators (and thus do not participate in creating blocks) keep a -**mempool cache** of the last `mempool.cache_size` transactions they have seen, as a first line of +Full-nodes keep a **mempool cache** of the last `mempool.cache_size` transactions they have seen, as a first line of defense to prevent replay attacks. Ideally, `mempool.cache_size` is large enough to encompass all of the transactions in the full mempool. If the the mempool cache is too small to keep track of all the transactions, `CheckTx` is responsible for identifying and rejecting replayed transactions. @@ -142,11 +135,11 @@ must be in this proposer's mempool. ## State Changes The next step of consensus is to execute the transactions to fully validate them. All full-nodes -that receive a block proposal execute the transactions by calling the ABCI functions +that receive a block proposal from the correct proposer execute the transactions by calling the ABCI functions [`BeginBlock`](./app-anatomy.md#beginblocker-and-endblocker), `DeliverTx` for each transaction, -and [`EndBlock`](./app-anatomy.md#beginblocker-and-endblocker). While full-nodes each run everything -individually, since the messages' state transitions are deterministic and transactions are -explicitly ordered in the block proposal, this process yields a single, unambiguous result. +and [`EndBlock`](./app-anatomy.md#beginblocker-and-endblocker). While each full-node runs everything +locally, this process yields a single, unambiguous result, since the messages' state transitions are deterministic and transactions are +explicitly ordered in the block proposal. ``` ----------------------- @@ -190,7 +183,7 @@ explicitly ordered in the block proposal, this process yields a single, unambigu The `DeliverTx` ABCI function defined in [`baseapp`](../core/baseapp.md) does the bulk of the state transitions: it is run for each transaction in the block in sequential order as committed to during consensus. Under the hood, `DeliverTx` is almost identical to `CheckTx` but calls the -[`runTx`](../core/baseapp.md#runtx-and-runmsgs) function in deliver mode instead of check mode. +[`runTx`](../core/baseapp.md#runtx) function in deliver mode instead of check mode. Instead of using their `checkState`, full-nodes use `deliverState`: * **Decoding:** Since `DeliverTx` is an ABCI call, `Tx` is received in the encoded `[]byte` form. @@ -206,16 +199,16 @@ to each node - differing values across nodes would yield nondeterministic result * **Route and Handler:** While `CheckTx` would have exited, `DeliverTx` continues to run [`runMsgs`](../core/baseapp.md#runtx-and-runmsgs) to fully execute each `Msg` within the transaction. Since the transaction may have messages from different modules, `baseapp` needs to know which module -to find the appropriate Handler. Thus, the [`Route`](../core/tx-msgs.md#route) function is called to -retrieve the route name and find the `Handler` within the module. +to find the appropriate Handler. Thus, the `route` function is called via the [module manager](../building-modules/module-manager.md) to +retrieve the route name and find the [`Handler`](../building-modules/handler.md) within the module. -* **Handler:** The `Handler`, a step up from `AnteHandler`, is responsible for executing each +* **Handler:** The `handler`, a step up from `AnteHandler`, is responsible for executing each message in the `Tx` and causes state transitions to persist in `deliverTxState`. It is defined within a `Msg`'s module and writes to the appropriate stores within the module. -* **Gas:** While a `Tx` is being delivered, a block `GasMeter` is used to keep track of how much -gas is left for each transaction; if execution completes, `GasUsed` is set and returned in the -`abci.ResponseDeliverTx`. If execution halts because `GasMeter` has run out or something else goes +* **Gas:** While a `Tx` is being delivered, a `GasMeter` is used to keep track of how much +gas is being used; if execution completes, `GasUsed` is set and returned in the +`abci.ResponseDeliverTx`. If execution halts because `BlockGasMeter` or `GasMeter` has run out or something else goes wrong, a deferred function at the end appropriately errors or panics. If there are any failed state changes resulting from a `Tx` being invalid or `GasMeter` running out, @@ -224,25 +217,15 @@ block proposal cause validator nodes to reject the block and vote for a `nil` bl `Tx` is delivered successfully, any leftover gas is returned to the user and the transaction is validated. -### Consensus and Commit +### Commit -The final step is for validator nodes to commit the block and state changes. Validator nodes +The final step is for nodes to commit the block and state changes. Validator nodes perform the previous step of executing state transitions in order to validate the transactions, -then sign the block to confirm and vote for them. Full nodes that are not validators do not +then sign the block to confirm it. Full nodes that are not validators do not participate in consensus - i.e. they cannot vote - but listen for votes to understand whether or -not they should commit the state changes. - -#### Consensus - -The consensus layer may technically run any consensus algorithm to come to agreement on which block -to accept. In [Tendermint BFT](https://tendermint.com/docs/spec/consensus/consensus.html), validator -nodes go through a Prevote stage and a Precommit stage, and the block requires +2/3 Precommits from -the validator-nodes to move into the commit stage. Note that this phase is purely in the consensus -layer; a `Tx` is represented as a `[]byte`. - -#### Commit +not they should commit the state changes. -In the **Commit** stage, full nodes commit to a new block to be added to the blockchain and +When they receive enough validator votes (2/3+ *precommits* weighted by voting power), full nodes commit to a new block to be added to the blockchain and finalize the state transitions in the application layer. A new state root is generated to serve as a merkle proof for the state transitions. Applications use the [`Commit`](../core/baseapp.md#commit) ABCI method inherited from [Baseapp](../core/baseapp.md); it syncs all the state transitions by @@ -262,4 +245,4 @@ in `[]byte` form, is stored in a block and appended to the blockchain. ## Next -Learn about [accounts](../accounts.md). +Learn about [accounts](./accounts.md). diff --git a/docs/building-modules/README.md b/docs/building-modules/README.md index 908825572708..732485c74477 100644 --- a/docs/building-modules/README.md +++ b/docs/building-modules/README.md @@ -1,83 +1,22 @@ --- +order: false parent: - title: Building modules + order: 4 --- -# Auth +# Building Modules -The `x/auth` modules is used for accounts +This repository contains documentation on concepts developers need to know in order to build modules for Cosmos SDK applications. -See the [API docs](https://godoc.org/github.com/cosmos/cosmos-sdk/x/auth) +1. [Introduction to Cosmos SDK Modules](./intro.md) +2. [`AppModule` Interface and Module Manager](./module-manager.md) +3. [Messages and Queries](./messages-and-queries.md) +4. [`Handler`s - Processing Messages](./handler.md) +5. [`Querier`s - Processing Queries](./querier.md) +6. [BeginBlocker and EndBlocker](./beginblock-endblock.md) +7. [`Keeper`s](./keeper.md) +8. [Invariants](./invariants.md) +9. [Genesis](./genesis.md) +10. [Module Interfaces](./module-interfaces.md) +11. [Standard Module Structure](./structure.md) -See the [specification](https://github.com/cosmos/cosmos-sdk/tree/master/docs/spec/auth) - -# Bank - -The `x/bank` module is for transferring coins between accounts. - -See the [API docs](https://godoc.org/github.com/cosmos/cosmos-sdk/x/bank). - -See the [specification](https://github.com/cosmos/cosmos-sdk/tree/master/docs/spec/bank) - -# Stake - -The `x/staking` module is for Cosmos Delegated-Proof-of-Stake. - -See the [API docs](https://godoc.org/github.com/cosmos/cosmos-sdk/x/staking). - -See the -[specification](https://github.com/cosmos/cosmos-sdk/tree/master/docs/spec/staking) - -# Slashing - -The `x/slashing` module is for Cosmos Delegated-Proof-of-Stake. - -See the [API docs](https://godoc.org/github.com/cosmos/cosmos-sdk/x/slashing) - -See the -[specification](https://github.com/cosmos/cosmos-sdk/tree/master/docs/spec/slashing) - -# Distribution - -The `x/distribution` module is for distributing fees and inflation across bonded -stakeholders. - -See the [API docs](https://godoc.org/github.com/cosmos/cosmos-sdk/x/distribution) - -See the -[specification](https://github.com/cosmos/cosmos-sdk/tree/master/docs/spec/distribution) - -# Governance - -The `x/gov` module is for bonded stakeholders to make proposals and vote on them. - -See the [API docs](https://godoc.org/github.com/cosmos/cosmos-sdk/x/gov) - -See the -[specification](https://github.com/cosmos/cosmos-sdk/tree/master/docs/spec/governance) - -To keep up with the current status of IBC, follow and contribute to [ICS](https://github.com/cosmos/ics) - -# Crisis - -The `x/crisis` module is for halting the blockchain under certain circumstances. - -See the [API Docs](https://godoc.org/github.com/cosmos/cosmos-sdk/x/crisis) - -See the [specification](https://github.com/cosmos/cosmos-sdk/blob/master/docs/spec/crisis) - -# Mint - -The `x/mint` module is for flexible inflation rates and effect a balance between market liquidity and staked supply. - -See the [API Docs](https://godoc.org/github.com/cosmos/cosmos-sdk/x/mint) - -See the [specification](https://github.com/cosmos/cosmos-sdk/blob/master/docs/spec/mint) - -# Params - -The `x/params` module provides a globally available parameter store. - -See the [API Docs](https://godoc.org/github.com/cosmos/cosmos-sdk/x/params) - -See the [specification](https://github.com/cosmos/cosmos-sdk/blob/master/docs/spec/params) diff --git a/docs/building-modules/beginblock-endblock.md b/docs/building-modules/beginblock-endblock.md index 66d08e2858f5..4de61d9960d7 100644 --- a/docs/building-modules/beginblock-endblock.md +++ b/docs/building-modules/beginblock-endblock.md @@ -1,3 +1,7 @@ +--- +order: 6 +--- + # BeginBlocker and EndBlocker ## Pre-requisite Reading @@ -6,15 +10,15 @@ ## Synopsis -`BeginBlocker` and `EndBlocker` are optional methods module developers can implement in their module. They will be triggered at the beginning and at the end of each block respectively. +`BeginBlocker` and `EndBlocker` are optional methods module developers can implement in their module. They will be triggered at the beginning and at the end of each block respectively, when the [`BeginBlock`](../core/baseapp.md#beginblock) and [`EndBlock`](../core/baseapp.md#endblock) ABCI messages are received from the underlying consensus engine. ## BeginBlocker and EndBlocker `BeginBlocker` and `EndBlocker` are a way for module developers to add automatic execution of logic to their module. This is a powerful tool that should be used carefully, as complex automatic functions can slow down or even halt the chain. -When needed, `BeginBlocker` and `EndBlocker` are implemented as part of the [`AppModule` interface](./module-manager.md#appmodule). The `BeginBlock` and `EndBlock` methods of the interface implemented in `module.go` generally defer to `BeginBlocker` and `EndBlocker` methods respectively, which are usually implemented in a `abci.go` file. +When needed, `BeginBlocker` and `EndBlocker` are implemented as part of the [`AppModule` interface](./module-manager.md#appmodule). The `BeginBlock` and `EndBlock` methods of the interface implemented in `module.go` generally defer to `BeginBlocker` and `EndBlocker` methods respectively, which are usually implemented in a **`abci.go`** file. -The actual implementation of `BeginBlocker` and `EndBlocker` are very similar to that of a [`handler`](./handler.md): +The actual implementation of `BeginBlocker` and `EndBlocker` in `./abci.go` are very similar to that of a [`handler`](./handler.md): - They generally use the [`keeper`](./keeper.md) and [`ctx`](../core/context.md) to retrieve information about the latest state. - If needed, they use the `keeper` and `ctx` to trigger state-transitions. @@ -22,6 +26,8 @@ The actual implementation of `BeginBlocker` and `EndBlocker` are very similar to A specificity of the `EndBlocker` is that it can return validator updates to the underlying consensus engine in the form of an [`[]abci.ValidatorUpdates`](https://tendermint.com/docs/app-dev/abci-spec.html#validatorupdate). This is the preferred way to implement custom validator changes. +It is possible for developers to defined the order of execution between the `BeginBlocker`/`EndBlocker` functions of each of their application's modules via the module's manager `SetOrderBeginBlocker`/`SetOrderEndBlocker` methods. For more on the module manager, click [here](./module-manager.md#manager). + For more, see an [example implementation of `BeginBlocker` from the `distr` module](https://github.com/cosmos/cosmos-sdk/blob/master/x/distribution/abci.go) and an [example implementation of `EndBlocker`]( https://github.com/cosmos/cosmos-sdk/blob/master/x/staking/handler.go#L44) ## Next diff --git a/docs/building-modules/genesis.md b/docs/building-modules/genesis.md index fcff8ac2c69d..ea83beaf183e 100644 --- a/docs/building-modules/genesis.md +++ b/docs/building-modules/genesis.md @@ -1,3 +1,7 @@ +--- +order: 9 +--- + # Module Genesis ## Pre-requisite Reading @@ -9,18 +13,13 @@ Modules generally handle a subset of the state and, as such, they need to define the related subset of the genesis file as well as methods to initialize, verify and export it. -- [Type Definition](#type-definition) - + [InitGenesis](#initgenesis) - + [DefaultGenesis](#defaultgenesis) -- [Other Genesis Functions](#other-genesis-functions) - + [ValidateGenesis](#validategenesis) - + [ExportGenesis](#exportgenesis) - ## Type Definition -The subset of the genesis state defined from a given module is generally defined in a `internal/types/genesis.go` file, along with the `DefaultGenesis` and `ValidateGenesis` methods. The struct defining the subset of the genesis state defined by the module is usually called `GenesisState` and contains all the module-related values that need to be initialized during the genesis process. +The subset of the genesis state defined from a given module is generally defined in a `./internal/types/genesis.go` file, along with the `DefaultGenesis` and `ValidateGenesis` methods. The struct defining the module's subset of the genesis state is usually called `GenesisState` and contains all the module-related values that need to be initialized during the genesis process. -See an example of `GenesisState` type definition from the [nameservice tutoria](https://github.com/cosmos/sdk-application-tutorial/blob/master/x/nameservice/genesis.go#L10-L12). +See an example of `GenesisState` type definition from the [nameservice tutorial](https://github.com/cosmos/sdk-application-tutorial/blob/master/x/nameservice/genesis.go#L10-L12). + +Next we present the main genesis-related methods that need to be implemented by module developers in order for their module to be used in Cosmos SDK applications. ### `DefaultGenesis` @@ -38,6 +37,8 @@ Other than the methods related directly to `GenesisState`, module developers are The `InitGenesis` method is executed during [`InitChain`](../core/baseapp.md#initchain) when the application is first started. Given a `GenesisState`, it initializes the subset of the state managed by the module by using the module's [`keeper`](./keeper.md) setter function on each parameter within the `GenesisState`. +The [module manager](./module-manager.md#manager) of the application is responsible for calling the `InitGenesis` method of each of the application's modules, in order. This order is set by the application developer via the manager's `SetOrderGenesisMethod`, which is called in the [application's constructor function](../basics/app-anatomy.md#constructor-function) + See an [example of `InitGenesis` from the nameservice tutorial](https://github.com/cosmos/sdk-application-tutorial/blob/master/x/nameservice/genesis.go#L39-L44). ### `ExportGenesis` diff --git a/docs/building-modules/handler.md b/docs/building-modules/handler.md index 760f3a137b91..c1bdf602c6d7 100644 --- a/docs/building-modules/handler.md +++ b/docs/building-modules/handler.md @@ -1,3 +1,7 @@ +--- +order: 4 +--- + # Handlers ## Pre-requisite Reading @@ -9,9 +13,6 @@ A `Handler` designates a function that processes [`message`s](./messages-and-queries.md#messages). `Handler`s are specific to the module in which they are defined, and only process `message`s defined within the said module. They are called from `baseapp` during [`DeliverTx`](../core/baseapp.md#delivertx). -- [`handler` type](#handler-type) -- [Implementation of a module `handler`s](#implementation-of-a-module-handlers) - ## `handler` type The [`handler` type](https://github.com/cosmos/cosmos-sdk/blob/master/types/handler.go#L4) defined in the Cosmos SDK specifies the typical structure of a `handler` function: @@ -24,11 +25,11 @@ Let us break it down: - The [`Msg`](./messages-and-queries.md#messages) is the actual object being processed. - The [`Context`](../core/context.md) contains all the necessary information needed to process the `msg`, as well as a cache-wrapped copy of the latest state. If the `msg` is succesfully processed, the modified version of the temporary state contained in the `ctx` will be written to the main state. -- The [`Result`](https://github.com/cosmos/cosmos-sdk/blob/master/types/result.go#L14-L38) returned to `baseapp`, which contains (among other things) information on the execution of the `handler`, [`gas`](../basics/gas-fees.md) consumption and [`events`](./events.md). +- The [`Result`](https://github.com/cosmos/cosmos-sdk/blob/master/types/result.go#L14-L38) returned to `baseapp`, which contains (among other things) information on the execution of the `handler`, [`gas`](../basics/gas-fees.md) consumption and [`events`](../core/events.md). ## Implementation of a module `handler`s -Module `handler`s are typically implemented in a `handler.go` file inside the module's folder. The [module manager](./module-manager.md) is used to add the module's `handler`s to the [application's `router`](../core/baseapp.md#message-routing) via the `NewHandler()` method. Typically, the manager's `NewHandler()` method simply calls a `NewHandler()` method defined in `handler.go`, which looks like the following: +Module `handler`s are typically implemented in a `./handler.go` file inside the module's folder. The [module manager](./module-manager.md) is used to add the module's `handler`s to the [application's `router`](../core/baseapp.md#message-routing) via the `NewHandler()` method. Typically, the manager's `NewHandler()` method simply calls a `NewHandler()` method defined in `handler.go`, which looks like the following: ```go func NewHandler(keeper Keeper) sdk.Handler { diff --git a/docs/building-modules/intro.md b/docs/building-modules/intro.md index 0a2fb5902bc9..30d720dee83f 100644 --- a/docs/building-modules/intro.md +++ b/docs/building-modules/intro.md @@ -1,3 +1,7 @@ +--- +order: 1 +--- + # Introduction to SDK Modules ## Pre-requisite Reading @@ -7,19 +11,15 @@ ## Synopsis -Modules define most of the logic of any SDK application. Developers compose module together using the Cosmos SDK to build their custom application-specific blockchains. This document outlines the basic concepts behind SDK modules and how to approach module management. - -- [Role of Modules in an SDK application](#role-of-modules-in-an-sdk-application) -- [How to Approach Building Modules as a Developer](#how-to-approach-building-modules-as-a-developer) -- [Main Components of SDK Modules](#main-components-of-sdk-modules) +Modules define most of the logic of SDK applications. Developers compose module together using the Cosmos SDK to build their custom application-specific blockchains. This document outlines the basic concepts behind SDK modules and how to approach module management. ## Role of Modules in an SDK Application -The Cosmos SDK can be thought as the Ruby-on-Rails of blockchain development. It comes with a core that provides the basic functionalities every blockchain application need, like a boilerplate implementation of the ABCI to communicate with the underlying consensus engine, a multistore to persist state, a server to form a full-node and interfaces to handle queries. +The Cosmos SDK can be thought as the Ruby-on-Rails of blockchain development. It comes with a core that provides the basic functionalities every blockchain application needs, like a [boilerplate implementation of the ABCI](../core/baseapp.md) to communicate with the underlying consensus engine, a [`multistore`](../core/store.md#multistore) to persist state, a [server](../core/node.md) to form a full-node and [interfaces](../interfaces/interfaces-intro.md) to handle queries. -On top of this core, the SDK enables developers to build modules that implement the business logic of their application. In other words, SDK modules implement the bulk of the logic of applications, while the core does the wiring and enables modules to be composed together. The end goal is to build a robust ecosystem of open-source SDK modules, making it increasingly easier to build complex blockchain applications. +On top of this core, the Cosmos SDK enables developers to build modules that implement the business logic of their application. In other words, SDK modules implement the bulk of the logic of applications, while the core does the wiring and enables modules to be composed together. The end goal is to build a robust ecosystem of open-source SDK modules, making it increasingly easier to build complex blockchain applications. -SDK Modules can be seen as little state-machines within the state-machine. They generally define a subset of the state using one ore multiple `KVStore` in the [main multistore](../core/store.md), as well as a subset of [`message` types](./message.md). These `message`s are routed by one of the main component of SDK core, [`baseapp`](../core/baseapp.md), to the [`handler`](./handler.md) of the module that define them. +SDK Modules can be seen as little state-machines within the state-machine. They generally define a subset of the state using one ore multiple `KVStore` in the [main multistore](../core/store.md), as well as a subset of [`message` types](./messages-and-queries.md#messages). These `message`s are routed by one of the main component of SDK core, [`baseapp`](../core/baseapp.md), to the [`handler`](./handler.md) of the module that define them. ``` + @@ -74,13 +74,13 @@ While there is no definitive guidelines for writing modules, here are some impor - **Composability**: SDK applications are almost always composed of multiple modules. This means developers need to carefully consider the integration of their module not only with the core of the Cosmos SDK, but also with other modules. The former is achieved by following standard design patterns outlined [here](#main-components-of-sdk-modules), while the latter is achieved by properly exposing the store(s) of the module via the [`keeper`](./keeper.md). - **Specialization**: A direct consequence of the **composability** feature is that modules should be **specialized**. Developers should carefully establish the scope of their module and not batch multiple functionalities into the same module. This separation of concern enables modules to be re-used in other projects and improves the upgradability of the application. **Specialization** also plays an important role in the [object-capabilities model](../core/ocap.md) of the Cosmos SDK. -- **Capabilities**: Most modules need to read and/or write to the store(s) of other modules. However, in an open-source environment, it is possible for some module to be malicious. That is why module developers need to carefully think not only about how their module interracts with other modules, and how to give access to the module's store(s). The Cosmos SDK takes a capabilities-oriented approach to inter-module security. This means that each store defined by a module is accessed by a `key`, which is held by the module's [`keeper`](./keeper.md). This `keeper` defines how to access the store(s) and under what conditions. Access to the module's store(s) is done by passing a reference to the module's `keeper`. +- **Capabilities**: Most modules need to read and/or write to the store(s) of other modules. However, in an open-source environment, it is possible for some module to be malicious. That is why module developers need to carefully think not only about how their module interracts with other modules, but also about how to give access to the module's store(s). The Cosmos SDK takes a capabilities-oriented approach to inter-module security. This means that each store defined by a module is accessed by a `key`, which is held by the module's [`keeper`](./keeper.md). This `keeper` defines how to access the store(s) and under what conditions. Access to the module's store(s) is done by passing a reference to the module's `keeper`. ## Main Components of SDK Modules Modules are by convention defined in the `.x/` subfolder (e.g. the `bank` module will be defined in the `./x/bank` folder). They generally share the same core components: -- Custom [`message` types](./message.md) to trigger state-transitions. +- Custom [`message` types](./messages-and-queries.md#messages) to trigger state-transitions. - A [`handler`](./handler.md) used to process messages when they are routed to the module by [`baseapp`](../core/baseapp.md#message-routing). - A [`keeper`](./keeper.md), used to access the module's store(s) and update the state. - A [`querier`](./querier.md), used to process user queries when they are routed to the module by [`baseapp`](../core/baseapp.md#query-routing). @@ -88,6 +88,8 @@ Modules are by convention defined in the `.x/` subfolder (e.g. the `bank` module In addition to these components, modules implement the `AppModule` interface in order to be managed by the [`module manager`](./module-manager.md). +Please refer to the [structure document](./structure.md) to learn about the recommended structure of a module's directory. + ## Next Read more on the [`AppModule` interface and the `module manager`](./module-manager.md) diff --git a/docs/building-modules/invariants.md b/docs/building-modules/invariants.md index 7af843472db6..cc7888b8b9a2 100644 --- a/docs/building-modules/invariants.md +++ b/docs/building-modules/invariants.md @@ -1,3 +1,7 @@ +--- +order: 8 +--- + # Invariants ## Pre-requisite Reading @@ -6,10 +10,7 @@ ## Synopsis -An invariant is a property of the application that should always be true. An `Invariant` is a function that checks for a particular invariant. These functions are useful to detect bugs early on and act upon them to limit the potential consequences (e.g. by halting the chain). They are also useful in the development process of the application to detect bugs via simulations. - -- [Implementing `Invariant`s](#implementing-invariants) -- [Invariant Registry](#invariant-registry) +An invariant is a property of the application that should always be true. In the context of the Cosmos SDK, an `Invariant` is a function that checks for a particular invariant. These functions are useful to detect bugs early on and act upon them to limit their potential consequences (e.g. by halting the chain). They are also useful in the development process of the application to detect bugs via simulations. ## Implementing `Invariant`s @@ -21,7 +22,7 @@ type Invariant func(ctx Context) (string, bool) where the `string` return value is the invariant message, which can be used when printing logs, and the `bool` return value is the actual result of the invariant check. -In practice, each module implements `Invariant`s in a `internal/keeper/invariants.go` file within the module's folder. The standard is to implement one `Invariant` function per logical grouping of invariants with the following model: +In practice, each module implements `Invariant`s in a `./internal/keeper/invariants.go` file within the module's folder. The standard is to implement one `Invariant` function per logical grouping of invariants with the following model: ```go // Example for an Invariant that checks balance-related invariants @@ -69,9 +70,9 @@ For more, see an example of [`Invariant`s implementation from the `staking` modu ## Invariant Registry -The `InvariantRegistry` is a registry where the `Invariant`s of all the modules of an application are registered. There is only one `InvariantRegistry` per **application**, meaning module developers need not implement their own `InvariantRegistry` when building a module. All module developers need to do is to register their modules' invariants in the `InvariantRegistry`, as explained in the section above. +The `InvariantRegistry` is a registry where the `Invariant`s of all the modules of an application are registered. There is only one `InvariantRegistry` per **application**, meaning module developers need not implement their own `InvariantRegistry` when building a module. **All module developers need to do is to register their modules' invariants in the `InvariantRegistry`, as explained in the section above**. The rest of this section gives more information on the `InvariantRegistry` itself, and does not contain anything directly relevant to module developers. -Typically, the `InvariantRegistry` is implemented as a specific module (the most used implementation is that of the [`crisis` module](https://github.com/cosmos/cosmos-sdk/blob/master/x/crisis/)). This module must implement an object that follow the [`sdk.InvariantRegistry` interface](https://github.com/cosmos/cosmos-sdk/blob/master/types/invariant.go#L14-L17). +At its core, the `InvariantRegistry` is defined in the SDK as an [interface](https://github.com/cosmos/cosmos-sdk/blob/master/types/invariant.go#L14-L17). ```go type InvariantRegistry interface { @@ -79,9 +80,9 @@ type InvariantRegistry interface { } ``` -Typically, this interface is implemented in the module's `keeper`. You can see an example implementation of an `InvariantRegistry` from the `crisis` module [here](https://github.com/cosmos/cosmos-sdk/blob/master/x/crisis/internal/keeper/keeper.go). +Typically, this interface is implemented in the `keeper` of a specific module. The most used implementation of an `InvariantRegistry` can be found in the [`crisis` module](https://github.com/cosmos/cosmos-sdk/blob/master/x/crisis/internal/keeper/keeper.go). The `InvariantRegistry` is therefore typically instantiated by instantiating the `keeper` of the `crisis` module in the [application's constructor function](../basics/app-anatomy.md#constructor-function). -`Invariant`s can be checked manually via [`message`s](./messages-and-queries), but most often they are checked automatically at the end of each block (see an example [here](https://github.com/cosmos/cosmos-sdk/blob/master/x/crisis/abci.go)). In both cases, if one of the `Invariant`s returns false, the `InvariantRegistry` can trigger special logic (e.g. have the application panic and print the `Invariant`s message in the log). +`Invariant`s can be checked manually via [`message`s](./messages-and-queries.md), but most often they are checked automatically at the end of each block (see an example [here](https://github.com/cosmos/cosmos-sdk/blob/master/x/crisis/abci.go)). In both cases, if one of the `Invariant`s returns false, the `InvariantRegistry` can trigger special logic (e.g. have the application panic and print the `Invariant`s message in the log). ## Next diff --git a/docs/building-modules/keeper.md b/docs/building-modules/keeper.md index 1903d1f85ab4..06dbd1303dbd 100644 --- a/docs/building-modules/keeper.md +++ b/docs/building-modules/keeper.md @@ -1,3 +1,7 @@ +--- +order: 7 +--- + # Keepers ## Pre-requisite Reading @@ -8,17 +12,13 @@ `Keeper`s refer to a Cosmos SDK abstraction whose role is to manage access to the subset of the state defined by various modules. `Keeper`s are module-specific, i.e. the subset of state defined by a module can only be accessed by a `keeper` defined in said module. If a module needs to access the subset of state defined by another module, a reference to the second module's internal `keeper` needs to be passed to the first one. This is done in `app.go` during the instantiation of module keepers. -- [Motivation](#motivation) -- [Type Definition](#type-definition) -- [Implementing Methods](#implementing-methods) - ## Motivation -The Cosmos SDK is a framework that makes it easy for developers to build complex decentralised applications from scratch, mainly by composing modules together. As the ecosystem of open source modules for the Cosmos SDK expands, it will become increasingly likely that some contain vulnerabilities, as a result of the negligence or malice of their developer. +The Cosmos SDK is a framework that makes it easy for developers to build complex decentralised applications from scratch, mainly by composing modules together. As the ecosystem of open source modules for the Cosmos SDK expands, it will become increasingly likely that some of these modules contain vulnerabilities, as a result of the negligence or malice of their developer. -The Cosmos SDK adopts an [object-capabilities-based approach](./ocap.md) to help developers better protect their application from unwanted inter-module interactions, and `keeper`s are at the core of this approach. A `keeper` can be thought of quite literally as the gatekeeper of a module's store(s). Each store defined within a module comes with a `storeKey`, which grants unlimited access to it. The module's `keeper` holds this `storeKey` (which should otherwise remain unexposed), and defines [methods](#implementing-methods) for reading and writing to the store(s). +The Cosmos SDK adopts an [object-capabilities-based approach](../core/ocap.md) to help developers better protect their application from unwanted inter-module interactions, and `keeper`s are at the core of this approach. A `keeper` can be thought of quite literally as the gatekeeper of a module's store(s). Each store (typically an [`IAVL` Store](../core/store.md#iavl-store)) defined within a module comes with a `storeKey`, which grants unlimited access to it. The module's `keeper` holds this `storeKey` (which should otherwise remain unexposed), and defines [methods](#implementing-methods) for reading and writing to the store(s). -The core idea behind the object-capabilities approach is to only reveal what is necessary to get the work done. In practice, this means that instead of handling permissions of modules through access-control lists, module `keeper`s are passed a reference to the specific instance of the other modules' `keeper`s that they need to access. As a consequence, a module can only interact with the subset of state defined in another module via the methods exposed by the instance of the other module's `keeper`. This is a great way for developers to control the interactions that their own module can have with modules developed by external developers. +The core idea behind the object-capabilities approach is to only reveal what is necessary to get the work done. In practice, this means that instead of handling permissions of modules through access-control lists, module `keeper`s are passed a reference to the specific instance of the other modules' `keeper`s that they need to access (this is done in the [application's constructor function](../basics/app-anatomy.md#constructor-function)). As a consequence, a module can only interact with the subset of state defined in another module via the methods exposed by the instance of the other module's `keeper`. This is a great way for developers to control the interactions that their own module can have with modules developed by external developers. ## Type Definition @@ -52,11 +52,11 @@ Let us go through the different parameters: - `storeKey`s grant access to the store(s) of the [multistore](../core/store.md) managed by the module. They should always remain unexposed to external modules. - A [codec `cdc`](../core/encoding.md), used to marshall and unmarshall struct to/from `[]byte`. -Of course, it is possible to define different types of internal `keeper`s for the same module (e.g. a read-only `keeper`). Each type of `keeper` comes with its own constructor function, which is called from the [application's constructor function](../basics/app-anatomy.md). This is where `keeper`s are instanciated, and where developers make sure to pass correct instances of modules' `keeper`s to other modules that require it. +Of course, it is possible to define different types of internal `keeper`s for the same module (e.g. a read-only `keeper`). Each type of `keeper` comes with its own constructor function, which is called from the [application's constructor function](../basics/app-anatomy.md). This is where `keeper`s are instantiated, and where developers make sure to pass correct instances of modules' `keeper`s to other modules that require it. ## Implementing Methods -`Keeper`s primarily expose getter and setter methods for the store(s) managed by their module. These methods should remain as simple as possible and strictly be limited to getting or setting the requested value, as validity checks should have already been performed via the `ValidateBasic()` method of the [`message`](./messages-and-queries.md#messages) and the [`handler`](./handler.go) when `keeper`s' methods are called. +`Keeper`s primarily expose getter and setter methods for the store(s) managed by their module. These methods should remain as simple as possible and strictly be limited to getting or setting the requested value, as validity checks should have already been performed via the `ValidateBasic()` method of the [`message`](./messages-and-queries.md#messages) and the [`handler`](./handler.md) when `keeper`s' methods are called. Typically, a *getter* method will present with the following signature @@ -82,7 +82,7 @@ and go through the following steps: 2. Marhsall `value` to `[]byte` using the codec `cdc`. 3. Set the encoded value in the store at location `key` using the `Set(key []byte, value []byte)` method of the store. -For more, see an example of `keeper`'s [methods implementation from the nameservice tutorial](https://github.com/cosmos/sdk-application-tutorial/blob/master/x/nameservice/internal/keeper/keeper.go). +For more, see an example of `keeper`'s [methods implementation from the nameservice tutorial](https://github.com/cosmos/sdk-application-tutorial/blob/c6754a1e313eb1ed973c5c91dcc606f2fd288811/x/nameservice/internal/keeper/keeper.go). ## Next diff --git a/docs/building-modules/messages-and-queries.md b/docs/building-modules/messages-and-queries.md index 0bea947e2bb8..d023a8d95ff4 100644 --- a/docs/building-modules/messages-and-queries.md +++ b/docs/building-modules/messages-and-queries.md @@ -1,3 +1,8 @@ +--- +order: 3 +--- + + # Messages and Queries ## Pre-requisite Reading @@ -8,16 +13,13 @@ `Message`s and `Queries` are the two primary objects handled by modules. Most of the core components defined in a module, like `handler`s, `keeper`s and `querier`s, exist to process `message`s and `queries`. -- [Messages](#messages) -- [Queries](#queries) - ## Messages -`Message`s are objects whose end-goal is to trigger state-transitions. They are wrapped in [transactions], which may contain one or multiple of them. +`Message`s are objects whose end-goal is to trigger state-transitions. They are wrapped in [transactions](../core/transactions.md), which may contain one or multiple of them. -When a transaction is relayed from the underlying consensus engine to the SDK application, it is first decoded by [`baseapp`](../basics/baseapp.md). Then, each `message` contained in the transaction is extracted and routed to the appropriate module via `baseapp`'s `router` so that it can be processed by the module's [`handler`](./handler.md). For a more detailed explanation of the lifecycle of a transaction, click [here](../basics/tx-lifecycle.md). +When a transaction is relayed from the underlying consensus engine to the SDK application, it is first decoded by [`baseapp`](../core/baseapp.md). Then, each `message` contained in the transaction is extracted and routed to the appropriate module via `baseapp`'s `router` so that it can be processed by the module's [`handler`](./handler.md). For a more detailed explanation of the lifecycle of a transaction, click [here](../basics/tx-lifecycle.md). -Defining `message`s is the responsibility of module developers. Typically, they are defined in a `internal/types/msgs.go` file inside the module's folder. The `message`'s type definition usually includes a list of parameters needed to process the message that will be provided by end-users when they want to create a new transaction containing said `message`. +Defining `message`s is the responsibility of module developers. Typically, they are defined in a `./internal/types/msgs.go` file inside the module's folder. The `message`'s type definition usually includes a list of parameters needed to process the message that will be provided by end-users when they want to create a new transaction containing said `message`. ```go // Example of a message type definition @@ -29,10 +31,10 @@ type MsgSubmitProposal struct { } ``` -The `Msg` is typically accompagnied by a standard constructor function, that is called from one of the [module's interface](./module-interface). `message`s also need to implement the [`Msg`](https://github.com/cosmos/cosmos-sdk/blob/master/types/tx_msg.go#L7-L29) interface, which contains the following methods: +The `Msg` is typically accompanied by a standard constructor function, that is called from one of the [module's interface](./module-interfaces.md). `message`s also need to implement the [`Msg`](https://github.com/cosmos/cosmos-sdk/blob/master/types/tx_msg.go#L7-L29) interface, which contains the following methods: - `Route() string`: Name of the route for this message. Typically all `message`s in a module have the same route, which is most often the module's name. -- `Type() string`: Type of the message, used primarly in [events](./events.md). This should return a message-specific `string`, typically the denomination of the message itself. +- `Type() string`: Type of the message, used primarly in [events](../core/events.md). This should return a message-specific `string`, typically the denomination of the message itself. - `ValidateBasic() Error`: This method is called by `baseapp` very early in the processing of the `message` (in both [`CheckTx`](../core/baseapp.md#checktx) and [`DeliverTx`](../core/baseapp.md#delivertx)), in order to discard obviously invalid messages. `ValidateBasic` should only include *stateless* checks, i.e. checks that do not require access to the state. This usually consists in checking that the message's parameters are correctly formatted and valid (i.e. that the `amount` is strictly positive for a transfer). - `GetSignBytes() []byte`: Return the canonical byte representation of the message. Used to generate a signature. - `GetSigners() []AccAddress`: Return the list of signers. The SDK will make sure that each `message` contained in a transaction is signed by all the signers listed in the list returned by this method. @@ -64,4 +66,4 @@ The `path` for each `query` must be defined by the module developer in the modul ## Next -Learn about [`handler`s](./handler.go). \ No newline at end of file +Learn about [`handler`s](./handler.md). \ No newline at end of file diff --git a/docs/building-modules/module-interfaces.md b/docs/building-modules/module-interfaces.md index ff5a6564b751..ee3d870fafb2 100644 --- a/docs/building-modules/module-interfaces.md +++ b/docs/building-modules/module-interfaces.md @@ -1,3 +1,7 @@ +--- +order: 11 +--- + # Module Interfaces ## Prerequisites @@ -6,23 +10,15 @@ ## Synopsis -This document details how to build CLI and REST interfaces for a module. Examples from various SDK modules will be included. - -- [CLI](#cli) - + [Transaction Commands](#tx-commands) - + [Query Commands](#query-commands) -- [REST](#rest) - + [Request Types](#request-types) - + [Request Handlers](#request-handlers) - + [Register Routes](#register-routes) +This document details how to build CLI and REST interfaces for a module. Examples from various SDK modules are included. ## CLI -One of the main interfaces for an application is the [command-line interface](../interfaces/cli.md). This entrypoint created by the application developer will add commands from the application's modules to let end-users create [**messages**](./messages-and-queries.md#messages) and [**queries**](./messages-and-queries.md#queries). The CLI files are typically found in the `./x/moduleName/client/cli` folder. +One of the main interfaces for an application is the [command-line interface](../interfaces/cli.md). This entrypoint adds commands from the application's modules to let end-users create [**messages**](./messages-and-queries.md#messages) and [**queries**](./messages-and-queries.md#queries). The CLI files are typically found in the `./x/moduleName/client/cli` folder. ### Transaction Commands -[Transactions](../core/transactions.md) are created by users to wrap messages that trigger state changes when they get included in a valid block. Transaction commands typically have their own `tx.go` file in the module `./x/moduleName/client/cli` folder. The commands are specified in getter functions prefixed with `GetCmd` and include the name of the command. Here is an example from the [nameservice tutorial](https://cosmos.network/docs/tutorial/cli.html#transactions): +[Transactions](../core/transactions.md) are created by users to wrap messages that trigger state changes when they get included in a valid block. Transaction commands typically have their own `tx.go` file in the module `./x/moduleName/client/cli` folder. The commands are specified in getter functions prefixed with `GetCmd` and include the name of the command. Here is an example from the [nameservice tutorial](https://github.com/cosmos/sdk-application-tutorial/blob/c6754a1e313eb1ed973c5c91dcc606f2fd288811/tutorial/cli.md#transactions): ```go func GetCmdBuyName(cdc *codec.Codec) *cobra.Command { @@ -60,14 +56,13 @@ func GetCmdBuyName(cdc *codec.Codec) *cobra.Command { This getter function creates the command for the Buy Name transaction. It does the following: -- **`codec`**. The getter function takes in an application [`codec`](../core/encoding.md) as an argument and returns a reference to the `cobra.command`. Since a module is intended to be used by any application, the `codec` must be provided. - **Construct the command:** Read the [Cobra Documentation](https://github.com/spf13/cobra) for details on how to create commands. + **Use:** Specifies the format of a command-line entry users should type in order to invoke this command. In this case, the user uses `buy-name` as the name of the transaction command and provides the `name` the user wishes to buy and the `amount` the user is willing to pay. + **Args:** The number of arguments the user provides, in this case exactly two: `name` and `amount`. + **Short and Long:** A description for the function is provided here. A `Short` description is expected, and `Long` can be used to provide a more detailed description when a user uses the `--help` flag to ask for more information. + **RunE:** Defines a function that can return an error, called when the command is executed. Using `Run` would do the same thing, but would not allow for errors to be returned. - **`RunE` Function Body:** The function should be specified as a `RunE` to allow for errors to be returned. This function encapsulates all of the logic to create a new transaction that is ready to be relayed to nodes. - + The function should first initialize a [`TxBuilder`](../core/transactions.md#txbuilder) with the application `codec`'s `TxEncoder`, as well as a new [`CLIContext`](./query-lifecycle.md#clicontext) with the `codec` and `AccountDecoder`. These contexts contain all the information provided by the user and will be used to transfer this user-specific information between processes. To learn more about how contexts are used in a transaction, click [here](../core/transactions.md#transaction-generation). + + The function should first initialize a [`TxBuilder`](../core/transactions.md#txbuilder) with the application `codec`'s `TxEncoder`, as well as a new [`CLIContext`](../interfaces/query-lifecycle.md#clicontext) with the `codec` and `AccountDecoder`. These contexts contain all the information provided by the user and will be used to transfer this user-specific information between processes. To learn more about how contexts are used in a transaction, click [here](../core/transactions.md#transaction-generation). + If applicable, the command's arguments are parsed. Here, the `amount` given by the user is parsed into a denomination of `coins`. + If applicable, the `CLIContext` is used to retrieve any parameters such as the transaction originator's address to be used in the transaction. Here, the `from` address is retrieved by calling `cliCtx.getFromAddress()`. + A [message](./messages-and-queries.md) is created using all parameters parsed from the command arguments and `CLIContext`. The constructor function of the specific message type is called directly. It is good practice to call `ValidateBasic()` on the newly created message to run a sanity check and check for invalid arguments. @@ -95,7 +90,7 @@ func GetTxCmd(cdc *codec.Codec) *cobra.Command { ### Query Commands -[Queries](./messages-and-queries.md#queries) allow users to gather information about the application or network state; they are routed by the application and processed by the module in which they are defined. Query commands typically have their own `query.go` file in the module `x/moduleName/client/cli` folder. Like transaction commands, they are specified in getter functions and have the prefix `GetCmdQuery`. Here is an example of a query command from the [nameservice module CLI](https://cosmos.network/docs/tutorial/cli.html#queries): +[Queries](./messages-and-queries.md#queries) allow users to gather information about the application or network state; they are routed by the application and processed by the module in which they are defined. Query commands typically have their own `query.go` file in the module `x/moduleName/client/cli` folder. Like transaction commands, they are specified in getter functions and have the prefix `GetCmdQuery`. Here is an example of a query command from the [nameservice module CLI](https://github.com/cosmos/sdk-application-tutorial/blob/c6754a1e313eb1ed973c5c91dcc606f2fd288811/tutorial/cli.md#queries): ```go func GetCmdWhois(queryRoute string, cdc *codec.Codec) *cobra.Command { @@ -127,9 +122,9 @@ This query returns the address that owns a particular name. The getter function - **`codec` and `queryRoute`.** In addition to taking in the application `codec`, query command getters also take a `queryRoute` used to construct a path [Baseapp](../core/baseapp.md#query-routing) uses to route the query in the application. - **Construct the command.** Read the [Cobra Documentation](https://github.com/spf13/cobra) and the [transaction command](#transaction-commands) example above for more information. The user must type `whois` and provide the `name` they are querying for as the only argument. - **`RunE`.** The function should be specified as a `RunE` to allow for errors to be returned. This function encapsulates all of the logic to create a new query that is ready to be relayed to nodes. - + The function should first initialize a new [`CLIContext`](./query-lifecycle.md#clicontext) with the application `codec`. + + The function should first initialize a new [`CLIContext`](../interfaces/query-lifecycle.md#clicontext) with the application `codec`. + If applicable, the `CLIContext` is used to retrieve any parameters (e.g. the query originator's address to be used in the query) and marshal them with the query parameter type, in preparation to be relayed to a node. There are no `CLIContext` parameters in this case because the query does not involve any information about the user. - + The `queryRoute` is used to construct a `path` [`baseapp`](../basics/baseapp.md) will use to route the query to the appropriate [querier](./querier.md). The expected format for a query `path` is "queryCategory/queryRoute/queryType/arg1/arg2/...", where `queryCategory` can be `p2p`, `store`, `app`, or `custom`, `queryRoute` is the name of the module, and `queryType` is the name of the query type defined within the module. [`baseapp`](../basics/baseapp.md) can handle each type of `queryCategory` by routing it to a module querier or retrieving results directly from stores and functions for querying peer nodes. Module queries are `custom` type queries (some SDK modules have exceptions, such as `auth` and `gov` module queries). + + The `queryRoute` is used to construct a `path` [`baseapp`](../core/baseapp.md) will use to route the query to the appropriate [querier](./querier.md). The expected format for a query `path` is "queryCategory/queryRoute/queryType/arg1/arg2/...", where `queryCategory` can be `p2p`, `store`, `app`, or `custom`, `queryRoute` is the name of the module, and `queryType` is the name of the query type defined within the module. [`baseapp`](../core/baseapp.md) can handle each type of `queryCategory` by routing it to a module querier or retrieving results directly from stores and functions for querying peer nodes. Module queries are `custom` type queries (some SDK modules have exceptions, such as `auth` and `gov` module queries). + The `CLIContext` `QueryWithData()` function is used to relay the query to a node and retrieve the response. It requires the `path`. It returns the result and height of the query upon success or an error if the query fails. In addition, it will verify the returned proof if `TrustNode` is disabled. If proof verification fails or the query height is invalid, an error will be returned. + The `codec` is used to nmarshal the response and the `CLIContext` is used to print the output back to the user. - **Flags.** Add any [flags](#flags) to the command. @@ -163,7 +158,7 @@ Since `PostCommands()` includes all of the basic flags required for a transactio ## REST -Applications typically support web services that use HTTP requests (e.g. a web wallet like [Lunie.io](lunie.io)). Thus, application developers will also use REST Routes to route HTTP requests to the application's modules; these routes will be used by service providers. The module developer's responsibility is to define the REST client by defining [routes](#register-routes) for all possible [requests](#request-types) and [handlers](#request-handlers) for each of them. It's up to the module developer how to organize the REST interface files; there is typically a `rest.go` file found in the module's `./x/moduleName/client/rest` folder. +Applications typically support web services that use HTTP requests (e.g. a web wallet like [Lunie.io](https://lunie.io). Thus, application developers will also use REST Routes to route HTTP requests to the application's modules; these routes will be used by service providers. The module developer's responsibility is to define the REST client by defining [routes](#register-routes) for all possible [requests](#request-types) and [handlers](#request-handlers) for each of them. It's up to the module developer how to organize the REST interface files; there is typically a `rest.go` file found in the module's `./x/moduleName/client/rest` folder. To support HTTP requests, the module developer needs to define possible request types, how to handle them, and provide a way to register them with a provided router. @@ -171,7 +166,7 @@ To support HTTP requests, the module developer needs to define possible request Request types, which define structured interactions from users, must be defined for all *transaction* requests. Users using this method to interact with an application will send HTTP Requests with the required fields in order to trigger state changes in the application. Conventionally, each request is named with the suffix `Req`, e.g. `SendReq` for a Send transaction. Each struct should include a base request [`baseReq`](../interfaces/rest.md#basereq), the name of the transaction, and all the arguments the user must provide for the transaction. -Here is an example of a request to buy a name from the [nameservice](https://cosmos.network/docs/tutorial/rest.html) module: +Here is an example of a request to buy a name from the [nameservice](https://github.com/cosmos/sdk-application-tutorial/blob/c6754a1e313eb1ed973c5c91dcc606f2fd288811/tutorial/rest.md) module: ```go type buyNameReq struct { @@ -193,7 +188,7 @@ The `BaseReq` includes basic information that every request needs to have, simil * `ChainID` specifies the unique identifier of the blockchain the transaction pertains to. * `AccountNumber` is an identifier for the account. * `Sequence`is the value of a counter measuring how many transactions have been sent from the account. It is used to prevent replay attacks. -* `Gas` refers to how much [gas](../core/gas.md), which represents computational resources, Tx consumes. Gas is dependent on the transaction and is not precisely calculated until execution, but can be estimated by providing auto as the value for `Gas`. +* `Gas` refers to how much [gas](../basics/gas-fees.md), which represents computational resources, Tx consumes. Gas is dependent on the transaction and is not precisely calculated until execution, but can be estimated by providing auto as the value for `Gas`. * `GasAdjustment` can be used to scale gas up in order to avoid underestimating. For example, users can specify their gas adjustment as 1.5 to use 1.5 times the estimated gas. * `GasPrices` specifies how much the user is willing pay per unit of gas, which can be one or multiple denominations of tokens. For example, --gas-prices=0.025uatom, 0.025upho means the user is willing to pay 0.025uatom AND 0.025upho per unit of gas. * `Fees` specifies how much in [fees](../basics/gas-fees.md) the user is willing to pay in total. Note that the user only needs to provide either `gas-prices` or `fees`, but not both, because they can be derived from each other. diff --git a/docs/building-modules/module-manager.md b/docs/building-modules/module-manager.md index 68398c6a5fbb..98924bbe671d 100644 --- a/docs/building-modules/module-manager.md +++ b/docs/building-modules/module-manager.md @@ -1,4 +1,9 @@ -# Module Manager and `AppModule` Interface +--- +order: 2 +--- + + +# Module Manager ## Pre-requisite Reading @@ -6,16 +11,7 @@ ## Synopsis -Cosmos SDK modules need to implement the [`AppModule` interfaces](#application-module-interfaces), in order to be managed by the application's [module manager](#module-manager). The module manager plays an important role in [`message` and `query` routing](../core/baseapp.md#routing), and allows the application developer to set the order of execution of a variety of functions like [`BeginBlocker` and `EndBlocker`](../basics/app-anatomy.md#begingblocker-and-endblocker). - -- [Application Module Interfaces](#application-module-interfaces) - + [`AppModuleBasic`](#appmodulebasic) - + [`AppModuleGenesis`](#appmodulegenesis) - + [`AppModule`](#appmodule) - + [Implementing the Application Module Interfaces](#implementing-the-application-module-interfaces) -- [Module Managers](#module-managers) - + [`BasicManager`](#basicmanager) - + [`Manager`](#manager) +Cosmos SDK modules need to implement the [`AppModule` interfaces](#application-module-interfaces), in order to be managed by the application's [module manager](#module-manager). The module manager plays an important role in [`message` and `query` routing](../core/baseapp.md#routing), and allows application developers to set the order of execution of a variety of functions like [`BeginBlocker` and `EndBlocker`](../basics/app-anatomy.md#begingblocker-and-endblocker). ## Application Module Interfaces @@ -25,7 +21,7 @@ Cosmos SDK modules need to implement the [`AppModule` interfaces](#application-m - [`AppModule`](#appmodule) for inter-dependent module functionalities (except genesis-related functionalities). - [`AppModuleGenesis`](#appmodulegenesis) for inter-dependent genesis-related module functionalities. -The `AppModuleBasic` interface exists to define independent methods of the module, i.e. those that do not depend on other modules in the application. This allows for the construction of the basic application structure early in the application definition, generally in the `init()` function of the [main application file](../basics/app-antomy.md#core-application-file). +The `AppModuleBasic` interface exists to define independent methods of the module, i.e. those that do not depend on other modules in the application. This allows for the construction of the basic application structure early in the application definition, generally in the `init()` function of the [main application file](../basics/app-anatomy.md#core-application-file). The `AppModule` interface exists to define inter-dependent module methods. Many modules need to interract with other modules, typically through [`keeper`s](./keeper.md), which means there is a need for an interface where modules list their `keeper`s and other methods that require a reference to another module's object. `AppModule` interface also enables the module manager to set the order of execution between module's methods like `BeginBlock` and `EndBlock`, which is important in cases where the order of execution between modules matters in the context of the application. @@ -60,7 +56,7 @@ Let us go through the methods: - `ValidateGenesis(json.RawMessage)`: Used to validate the `GenesisState` defined by a module, given in its `json.RawMessage` form. It will usually unmarshall the `json` before running a custom [`ValidateGenesis`](./genesis.md#validategenesis) function defined by the module developer. - `RegisterRESTRoutes(context.CLIContext, *mux.Router)`: Registers the REST routes for the module. These routes will be used to map REST request to the module in order to process them. See [../interfaces/rest.md] for more. - `GetTxCmd(*codec.Codec)`: Returns the root [`Tx` command](./module-interfaces.md#tx) for the module. The subcommands of this root command are used by end-users to generate new transactions containing [`message`s](./messages-and-queries.md#queries) defined in the module. -- `GetQueryCmd(*codec.Codec)`: Return the root [`query` command](./module-intefaces.md#query) for the module. The subcommands of this root command are used by end-users to generate new queries to the subset of the state defined by the module. +- `GetQueryCmd(*codec.Codec)`: Return the root [`query` command](./module-interfaces.md#query) for the module. The subcommands of this root command are used by end-users to generate new queries to the subset of the state defined by the module. All the `AppModuleBasic` of an application are managed by the [`BasicManager`](#basicmanager). diff --git a/docs/building-modules/querier.md b/docs/building-modules/querier.md index ea6cfba984e1..81c7dd6c481e 100644 --- a/docs/building-modules/querier.md +++ b/docs/building-modules/querier.md @@ -1,3 +1,7 @@ +--- +order: 5 +--- + # Queriers ## Pre-requisite Reading @@ -9,9 +13,6 @@ A `Querier` designates a function that processes [`queries`](./messages-and-queries.md#queries). `querier`s are specific to the module in which they are defined, and only process `queries` defined within said module. They are called from `baseapp`'s [`Query` method](../core/baseapp.md#query). -- [`querier` type](#querier-type) -- [Implementation of a module `queriers`](#implementation-of-a-module-queriers) - ## `Querier` type The [`querier` type](https://github.com/cosmos/cosmos-sdk/blob/master/types/queryable.go#L6) defined in the Cosmos SDK specifies the typical structure of a `querier` function: @@ -29,7 +30,7 @@ Let us break it down: ## Implementation of a module `querier`s -Module `querier`s are typically implemented in a `internal/keeper/querier.go` file inside the module's folder. The [module manager](./module-manager.md) is used to add the module's `querier`s to the [application's `queryRouter`](../core/baseapp.md#query-routing) via the `NewQuerier()` method. Typically, the manager's `NewQuerier()` method simply calls a `NewQuerier()` method defined in `keeper/querier.go`, which looks like the following: +Module `querier`s are typically implemented in a `./internal/keeper/querier.go` file inside the module's folder. The [module manager](./module-manager.md) is used to add the module's `querier`s to the [application's `queryRouter`](../core/baseapp.md#query-routing) via the `NewQuerier()` method. Typically, the manager's `NewQuerier()` method simply calls a `NewQuerier()` method defined in `keeper/querier.go`, which looks like the following: ```go func NewQuerier(keeper Keeper) sdk.Querier { diff --git a/docs/building-modules/structure.md b/docs/building-modules/structure.md index 77934dfc5b2f..c039b3cbb3be 100644 --- a/docs/building-modules/structure.md +++ b/docs/building-modules/structure.md @@ -1,4 +1,8 @@ -# Module Structure Specification +--- +order: 12 +--- + +# Recommended Structure This document outlines the recommended structure of Cosmos SDK modules. These ideas are meant to be applied as suggestions. Application developers are encouraged diff --git a/docs/concepts/readme.md b/docs/concepts/readme.md deleted file mode 100644 index 67a1891d2af6..000000000000 --- a/docs/concepts/readme.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -order: false -parent: - title: Concepts ---- diff --git a/docs/core/README.md b/docs/core/README.md new file mode 100644 index 000000000000..8d9348350932 --- /dev/null +++ b/docs/core/README.md @@ -0,0 +1,20 @@ +--- +order: false +parent: + order: 3 +--- + +# Core + +This repository contains reference documentation on the core conepts of the Cosmos SDK. + +1. [`Baseapp`](./baseapp.md) +2. [Transaction](./transactions.md) +3. [Context](./context.md) +4. [Node Client](./node.md) +5. [Store](./store.md) +6. [Encoding](./encoding.md) +7. [Events](./events.md) +8. [Object-Capabilities](./ocap.md) + +After reading about the core concepts, head on to the [Building Modules documentation](../building-modules/README.md) to learn more about the process of building modules. \ No newline at end of file diff --git a/docs/core/baseapp.md b/docs/core/baseapp.md index 17717f74790d..2432572ce2b2 100644 --- a/docs/core/baseapp.md +++ b/docs/core/baseapp.md @@ -1,3 +1,7 @@ +--- +order: 1 +--- + # BaseApp ## Pre-requisite Reading @@ -10,37 +14,6 @@ This document describes `BaseApp`, the abstraction that implements the core functionalities of an SDK application. -- [BaseApp](#baseapp) - - [Pre-requisite Reading](#pre-requisite-reading) - - [Synopsis](#synopsis) - - [Introduction](#introduction) - - [Type Definition](#type-definition) - - [Constructor](#constructor) - - [State Updates](#state-updates) - - [InitChain State Updates](#initchain-state-updates) - - [CheckState State Updates-](#checktx-state-updates) - - [BeginBlock State Updates](#beginblock-state-updates) - - [DeliverTx State Updates](#delivertx-state-updates) - - [Commit State Updates](#commit-state-updates) - - [Routing](#routing) - - [Message Routing](#message-routing) - - [Query Routing](#query-routing) - - [Main ABCI Messages](#main-abci-messages) - - [CheckTx](#checktx) - - [RecheckTx](#rechecktx) - - [DeliverTx](#delivertx) - - [RunTx, AnteHandler and RunMsgs](#runtx-antehandler-and-runmsgs) - - [RunTx](#runtx) - - [AnteHandler](#antehandler) - - [RunMsgs](#runmsgs) - - [Other ABCI Messages](#other-abci-messages) - - [InitChain](#initchain) - - [BeginBlock](#beginblock) - - [EndBlock](#endblock) - - [Commit](#commit) - - [Info](#info) - - [Query](#query) - ## Introduction `BaseApp` is a base type that implements the core of an SDK application, namely: @@ -216,7 +189,7 @@ When messages and queries are received by the application, they must be routed t ### Message Routing -[`Message`s](#../building-modules/messages-and-queries.md#messages) need to be routed after they are extracted from transactions, which are sent from the underlying Tendermint engine via the [`CheckTx`](#checktx) and [`DeliverTx`](#delivertx) ABCI messages. To do so, `baseapp` holds a [`router`](https://github.com/cosmos/cosmos-sdk/blob/master/baseapp/router.go) which maps `paths` (`string`) to the appropriate module [`handler`](./handler.md). Usually, the `path` is the name of the module. +[`Message`s](#../building-modules/messages-and-queries.md#messages) need to be routed after they are extracted from transactions, which are sent from the underlying Tendermint engine via the [`CheckTx`](#checktx) and [`DeliverTx`](#delivertx) ABCI messages. To do so, `baseapp` holds a [`router`](https://github.com/cosmos/cosmos-sdk/blob/master/baseapp/router.go) which maps `paths` (`string`) to the appropriate module [`handler`](../building-modules/handler.md). Usually, the `path` is the name of the module. The application's `router` is initilalized with all the routes using the application's [module manager](../building-modules/module-manager.md#manager), which itself is initialized with all the application's modules in the application's [constructor](../basics/app-anatomy.md#app-constructor). @@ -257,14 +230,14 @@ to do the following checks: 3. Perform non-module related _stateful_ checks on the [account](../basics/accounts.md). This step is mainly about checking that the `message` signatures are valid, that enough fees are provided and that the sending account has enough funds to pay for said fees. Note that no precise [`gas`](../basics/gas-fees.md) counting occurs here, - as `message`s are not processed. Usually, the [`AnteHandler`](./gas-fees.md#antehandler) will check that the `gas` provided + as `message`s are not processed. Usually, the [`AnteHandler`](../basics/gas-fees.md#antehandler) will check that the `gas` provided with the transaction is superior to a minimum reference gas amount based on the raw transaction size, in order to avoid spam with transactions that provide 0 gas. 4. Ensure that a [`Route`](#message-routing) exists for each `message`, but do **not** actually process `message`s. `Message`s only need to be processed when the canonical state need to be updated, which happens during `DeliverTx`. -Steps 2. and 3. are performed by the [`AnteHandler`](./gas-fees.md#antehandler) in the [`RunTx()`](#runtx-antehandler-and-runmsgs) +Steps 2. and 3. are performed by the [`AnteHandler`](../basics/gas-fees.md#antehandler) in the [`RunTx()`](#runtx-antehandler-and-runmsgs) function, which `CheckTx()` calls with the `runTxModeCheck` mode. During each step of `CheckTx()`, a special [volatile state](#volatile-states) called `checkState` is updated. This state is used to keep track of the temporary changes triggered by the `CheckTx()` calls of each transaction without modifying @@ -283,9 +256,9 @@ The response contains: - `Data ([]byte)`: Result bytes, if any. - `Log (string):` The output of the application's logger. May be non-deterministic. - `Info (string):` Additional information. May be non-deterministic. -- `GasWanted (int64)`: Amount of gas requested for transaction. It is provided by users when they generate the transaction. -- `GasUsed (int64)`: Amount of gas consumed by transaction. During `CheckTx`, this value is computed by multiplying the standard cost of a transaction byte by the size of the raw transaction (click [here](https://github.com/cosmos/cosmos-sdk/blob/master/x/auth/ante.go#L101) for an example). -- `Events ([]Event)`: Key-Value events for filtering and indexing transactions (eg. by account or message type). +- `GasWanted (int64)`: Amount of gas requested for transaction. It is provided by users when they generate the transaction. +- `GasUsed (int64)`: Amount of gas consumed by transaction. During `CheckTx`, this value is computed by multiplying the standard cost of a transaction byte by the size of the raw transaction (click [here](https://github.com/cosmos/cosmos-sdk/blob/master/x/auth/ante/basic.go#L98) for an example). +- `Events ([]cmn.KVPair)`: Key-Value tags for filtering and indexing transactions (eg. by account). See [`event`s](./events.md) for more. - `Codespace (string)`: Namespace for the Code. #### RecheckTx @@ -317,7 +290,7 @@ During step 5., each read/write to the store increases the value of `GasConsumed - `Log (string):` The output of the application's logger. May be non-deterministic. - `Info (string):` Additional information. May be non-deterministic. - `GasWanted (int64)`: Amount of gas requested for transaction. It is provided by users when they generate the transaction. -- `GasUsed (int64)`: Amount of gas consumed by transaction. During `DeliverTx`, this value is computed by multiplying the standard cost of a transaction byte by the size of the raw transaction (click [here](https://github.com/cosmos/cosmos-sdk/blob/master/x/auth/ante.go#L101) for an example), and by adding gas each time a read/write to the store occurs. +- `GasUsed (int64)`: Amount of gas consumed by transaction. During `DeliverTx`, this value is computed by multiplying the standard cost of a transaction byte by the size of the raw transaction (click [here](https://github.com/cosmos/cosmos-sdk/blob/master/x/auth/ante/basic.go#L98) for an example), and by adding gas each time a read/write to the store occurs. - `Events ([]cmn.KVPair)`: Key-Value tags for filtering and indexing transactions (eg. by account). See [`event`s](./events.md) for more. - `Codespace (string)`: Namespace for the Code. @@ -327,7 +300,7 @@ During step 5., each read/write to the store increases the value of `GasConsumed `RunTx` is called from `CheckTx`/`DeliverTx` to handle the transaction, with `runTxModeCheck` or `runTxModeDeliver` as parameter to differentiate between the two modes of execution. Note that when `RunTx` receives a transaction, it has already been decoded. -The first thing `RunTx` does upon being called is to retrieve the `context`'s `CacheMultiStore` by calling the `getContextForTx()` function with the appropriate mode (either `runTxModeCheck` or `runTxModeDeliver`). This `CacheMultiStore` is a cached version of the main store instantiated during `BeginBlock` for `DeliverTx` and during the `Commit` of the previous block for `CheckTx`. After that, two `defer func()` are called for [`gas`](./gas-fees.md) management. They are executed when `runTx` returns and make sure `gas` is actually consumed, and will throw errors, if any. +The first thing `RunTx` does upon being called is to retrieve the `context`'s `CacheMultiStore` by calling the `getContextForTx()` function with the appropriate mode (either `runTxModeCheck` or `runTxModeDeliver`). This `CacheMultiStore` is a cached version of the main store instantiated during `BeginBlock` for `DeliverTx` and during the `Commit` of the previous block for `CheckTx`. After that, two `defer func()` are called for [`gas`](../basics/gas-fees.md) management. They are executed when `runTx` returns and make sure `gas` is actually consumed, and will throw errors, if any. After that, `RunTx()` calls `ValidateBasic()` on each `message`in the `Tx`, which runs preliminary _stateless_ validity checks. If any `message` fails to pass `ValidateBasic()`, `RunTx()` returns with an error. @@ -341,11 +314,13 @@ The `AnteHandler` is a special handler that implements the [`anteHandler` interf The `AnteHandler` is theoretically optional, but still a very important component of public blockchain networks. It serves 3 primary purposes: -- Be a primary line of defense against spam and second line of defense (the first one being the mempool) against transaction replay with fees deduction and [`sequence`](./tx-msgs.md#sequence) checking. +- Be a primary line of defense against spam and second line of defense (the first one being the mempool) against transaction replay with fees deduction and [`sequence`](./transactions.md#transaction-generation) checking. - Perform preliminary *stateful* validity checks like ensuring signatures are valid or that the sender has enough funds to pay for fees. - Play a role in the incentivisation of stakeholders via the collection of transaction fees. -`baseapp` holds an `anteHandler` as paraemter, which is initialized in the [application's constructor](../basics/app-anatomy.md#application-constructor). The most widely used `anteHandler` today is that of the [`auth` module](https://github.com/cosmos/cosmos-sdk/blob/master/x/auth/ante.go). +`baseapp` holds an `anteHandler` as paraemter, which is initialized in the [application's constructor](../basics/app-anatomy.md#application-constructor). The most widely used `anteHandler` today is that of the [`auth` module](https://github.com/cosmos/cosmos-sdk/blob/master/x/auth/ante/ante.go). + +Click [here](../basics/gas-fees.md#antehandler) for more on the `anteHandler`. ### RunMsgs @@ -363,7 +338,7 @@ The [`InitChain` ABCI message](https://tendermint.com/docs/app-dev/abci-spec.htm - [`checkState` and `deliverState`](#volatile-states) via `setCheckState` and `setDeliverState`. - The [block gas meter](../basics/gas-fees.md#block-gas-meter), with infinite gas to process genesis transactions. -Finally, the `InitChain(req abci.RequestInitChain)` method of `baseapp` calls the [`initChainer()`](../basics/app-anatomy.md#initchainer) of the application in order to initialize the main state of the application from the [`genesis file`](./genesis.md) and, if defined, call the [`InitGenesis`](../building-modules/genesis.md#initgenesis) function of each of the application's modules. +Finally, the `InitChain(req abci.RequestInitChain)` method of `baseapp` calls the [`initChainer()`](../basics/app-anatomy.md#initchainer) of the application in order to initialize the main state of the application from the `genesis file` and, if defined, call the [`InitGenesis`](../building-modules/genesis.md#initgenesis) function of each of the application's modules. ### BeginBlock diff --git a/docs/core/context.md b/docs/core/context.md index 25af7bbfc1d7..591481ec6fbc 100644 --- a/docs/core/context.md +++ b/docs/core/context.md @@ -1,29 +1,21 @@ -# Context - -## Synopsis - -This document details the SDK `Context` type. +--- +order: 3 +--- -- [Context](#context) - - [Synopsis](#synopsis) - - [Prerequisites](#prerequisites) - - [Context Definition](#context-definition) - - [Go Context Package](#go-context-package) - - [Cache Wrapping](#cache-wrapping) - - [Next](#next) +# Context -## Prerequisites +## Pre-requisites Readings - [Anatomy of an SDK Application](../basics/app-anatomy.md) - [Lifecycle of a Transaction](../basics/tx-lifecycle.md) +## Synopsis + +The `context` is a data structure intended to be passed from function to function that carries information about the current state of the application. It holds a cached copy of the entire state as well as useful objects and information like `gasMeter`, `block height`, `consensus parameters` and more. + ## Context Definition -The SDK `Context` is a custom data structure that contains Go's stdlib [`context`](https://golang.org/pkg/context) -as its base, and has many additional types within its definition that are specific to the Cosmos SDK -and Tendermint. The `Context` is directly passed between methods and functions as an argument. -The `Context` is integral to tx processing in that it allows modules to easily access their respective -[state](./multistore.md) and retrieve transactional context such as the block header and gas meter. +The SDK `Context` is a custom data structure that contains Go's stdlib [`context`](https://golang.org/pkg/context) as its base, and has many additional types within its definition that are specific to the Cosmos SDK. he `Context` is integral to transaction processing in that it allows modules to easily access their respective [store](./store.md#base-layer-kvstores) in the [`multistore`](./store.md#multistore) and retrieve transactional context such as the block header and gas meter. ```go type Context struct { @@ -44,21 +36,18 @@ type Context struct { ``` - **Context:** The base type is a Go [Context](https://golang.org/pkg/context), which is explained further in the [Go Context Package](#go-context-package) section below. -- **Multistore:** Every application's `BaseApp` contains a [`CommitMultiStore`](./multistore.md) which is provided when a `Context` is created. Calling the `KVStore()` and `TransientStore()` methods allows modules to fetch their -respective `KVStore` using their unique `StoreKey`. +- **Multistore:** Every application's `BaseApp` contains a [`CommitMultiStore`](./store.md#multistore) which is provided when a `Context` is created. Calling the `KVStore()` and `TransientStore()` methods allows modules to fetch their respective [`KVStore`](./store.md#base-layer-kvstores) using their unique `StoreKey`. - **ABCI Header:** The [header](https://tendermint.com/docs/spec/abci/abci.html#header) is an ABCI type. It carries important information about the state of the blockchain, such as block height and proposer of the current block. - **Chain ID:** The unique identification number of the blockchain a block pertains to. -- **Transaction Bytes:** The `[]byte` representation of a transaction being processed using the context. Every transaction is processed by various parts of the SDK and consensus engine (e.g. Tendermint) throughout its [lifecycle](../basics/tx-lifecycle.md), some of which to not have any understanding of transaction types. Thus, transactions are marshaled into the generic `[]byte` type using some kind of [encoding format](./encoding.md) such as [Amino](./amino.md). +- **Transaction Bytes:** The `[]byte` representation of a transaction being processed using the context. Every transaction is processed by various parts of the SDK and consensus engine (e.g. Tendermint) throughout its [lifecycle](../basics/tx-lifecycle.md), some of which to not have any understanding of transaction types. Thus, transactions are marshaled into the generic `[]byte` type using some kind of [encoding format](./encoding.md) such as [Amino](./encoding.md). - **Logger:** A [Logger](https://github.com/tendermint/tendermint/blob/bc572217c07b90ad9cee851f193aaa8e9557cbc7/libs/log/logger.go) from the Tendermint libraries. Learn more about logs [here](https://tendermint.com/docs/tendermint-core/how-to-read-logs.html#how-to-read-logs). Modules call this method to create their own unique module-specific logger. - **VoteInfo:** A list of the ABCI type [`VoteInfo`](https://tendermint.com/docs/spec/abci/abci.html#voteinfo), which includes the name of a validator and a boolean indicating whether they have signed the block. -- **Gas Meters:** Specifically, a `gasMeter` for the transaction currently being processed using the context and a `blockGasMeter` for the entire block it belongs to. Users specify how much in fees they wish to pay for the execution of their transaction; these gas meters keep track of how much [gas](../basics/gas-fees.md) has been used in the transaction or block so far. If the gas meter runs out, execution halts. +- **Gas Meters:** Specifically, a [`gasMeter`](../basics/gas-fees.md#main-gas-meter) for the transaction currently being processed using the context and a [`blockGasMeter`](../basics/gas-fees.md#block-gas-meter) for the entire block it belongs to. Users specify how much in fees they wish to pay for the execution of their transaction; these gas meters keep track of how much [gas](../basics/gas-fees.md) has been used in the transaction or block so far. If the gas meter runs out, execution halts. - **CheckTx Mode:** A boolean value indicating whether a transaction should be processed in `CheckTx` or `DeliverTx` mode. -- **Min Gas Price:** The minimum [gas](../basics/gas-fees.md) price a node is willing to take in order to include a transaction in its block. This price is a local value configured by each node individually. -- **Consensus Params:** The ABCI type [Consensus Parameters](https://tendermint.com/docs/spec/abci/apps.html#consensus-parameters), which enforce certain limits for the blockchain, such as maximum gas for a block. -- **Event Manager:** The event manager allows any caller with access to a `Context` to emit [`Events`](https://github.com/cosmos/cosmos-sdk/blob/master/types/events.go). Modules may define module specific -`Events` by defining various `Types` and `Attributes` or use the common definitions found in `types/`. Clients -can subscribe or query for these `Events`. These `Events` are collected throughout `DeliverTx`, `BeginBlock`, -and `EndBlock` and are returned to Tendermint for indexing. For example: +- **Min Gas Price:** The minimum [gas](../basics/gas-fees.md) price a node is willing to take in order to include a transaction in its block. This price is a local value configured by each node individually, and should therefore **not be used in any functions used in sequences leading to state-transitions**. +- **Consensus Params:** The ABCI type [Consensus Parameters](https://tendermint.com/docs/spec/abci/apps.html#consensus-parameters), which specify certain limits for the blockchain, such as maximum gas for a block. +- **Event Manager:** The event manager allows any caller with access to a `Context` to emit [`Events`](./events.md). Modules may define module specific +`Events` by defining various `Types` and `Attributes` or use the common definitions found in `types/`. Clients can subscribe or query for these `Events`. These `Events` are collected throughout `DeliverTx`, `BeginBlock`, and `EndBlock` and are returned to Tendermint for indexing. For example: ```go ctx.EventManager().EmitEvent(sdk.NewEvent( @@ -92,8 +81,7 @@ goes wrong. The pattern of usage for a Context is as follows: 1. A process receives a Context `ctx` from its parent process, which provides information needed to perform the process. -2. The `ctx.ms` is [**cache wrapped**](./multistore.md), i.e. a cached copy of the [multistore](./multistore.md) -is made so that the process can make changes to the state as it executes, without changing the original`ctx.ms` state. +2. The `ctx.ms` is **cache wrapped**, i.e. a cached copy of the [multistore](./store.md#multistore) is made so that the process can make changes to the state as it executes, without changing the original`ctx.ms`. This is useful to protect the underlying multistore in case the changes need to be reverted at some point in the execution. 3. The process may read and write from `ctx` as it is executing. It may call a subprocess and pass `ctx` to it as needed. 4. When a subprocess returns, it checks if the result is a success or failure. If a failure, nothing diff --git a/docs/core/encoding.md b/docs/core/encoding.md index b4cbb999eb45..f7f07f2c682b 100644 --- a/docs/core/encoding.md +++ b/docs/core/encoding.md @@ -1,3 +1,7 @@ +--- +order: 6 +--- + # Encoding ## Pre-requisite Reading diff --git a/docs/core/events.md b/docs/core/events.md index 4915c0b0aee2..0c7a272746a4 100644 --- a/docs/core/events.md +++ b/docs/core/events.md @@ -1,3 +1,7 @@ +--- +order: 7 +--- + # Events ## Pre-Requisite Reading @@ -8,14 +12,11 @@ `Event`s are objects that contain information about the execution of the application. They are mainly used by service providers like block explorers and wallet to track the execution of various messages and index transactions. -- [Events](#events) -- [EventManager](#eventmanager) - ## Events `Event`s are implemented in the Cosmos SDK as an alias of the [ABCI `event` type](https://github.com/tendermint/tendermint/blob/bc572217c07b90ad9cee851f193aaa8e9557cbc7/abci/types/types.pb.go#L2661-L2667). They contain: -- A **type** of type `string`, which can refer to the type of action that led to the `event`'s emission (e.g. a certain value going above a threshold), or to the type of `message` if the event is triggered at the end of that `message` processing. +- A **`type`** of type `string`, which can refer to the type of action that led to the `event`'s emission (e.g. a certain value going above a threshold), or to the type of `message` if the event is triggered at the end of that `message` processing. - A list of [`attributes`](https://github.com/cosmos/cosmos-sdk/blob/master/types/events.go#L53-L56), which are key-value pairs that give more information about the `event`. `Event`s are returned to the underlying consensus engine in the response of the following ABCI messages: [`CheckTx`](./baseapp.md#checktx), [`DeliverTx`](./baseapp.md#delivertx), [`BeginBlock`](./baseapp.md#beginblock) and [`EndBlock`](./baseapp.md#endblock). diff --git a/docs/core/node.md b/docs/core/node.md index 812eec3ac062..afc859da6ef5 100644 --- a/docs/core/node.md +++ b/docs/core/node.md @@ -1,3 +1,7 @@ +--- +order: 4 +--- + # Node Client (Daemon) ## Pre-requisite Reading @@ -8,17 +12,14 @@ The main endpoint of an SDK application is the daemon client, otherwise known as the full-node client. The full-node runs the state-machine, starting from a genesis file. It connects to peers running the same client in order to receive and relay transactions, block proposals and signatures. The full-node is constituted of the application, defined with the Cosmos SDK, and of a consensus engine connected to the application via the ABCI. -- [`main` function](#main-function) -- [`start` command](#start-command) - ## `main` function -The full-node client of any SDK application is built by running a `main` function. The client is generally named by appending the `-d` suffix to the application name (e.g. `appd` for an application named `app`), and the `main` function is defined in a `cmd/appd/main.go` file. Running this function creates an executable `.appd` that comes with a set of commands. For an app named `app`, the main command is [`appd start`](#start-command), which starts the full-node. +The full-node client of any SDK application is built by running a `main` function. The client is generally named by appending the `-d` suffix to the application name (e.g. `appd` for an application named `app`), and the `main` function is defined in a `./cmd/appd/main.go` file. Running this function creates an executable `.appd` that comes with a set of commands. For an app named `app`, the main command is [`appd start`](#start-command), which starts the full-node. In general, developers will implement the `main.go` function with the following structure: - First, a [`codec`](./encoding.md) is instanciated for the application. -- Then, the [`config`](https://github.com/cosmos/cosmos-sdk/blob/master/types/config.go) is retrieved and config parameters are set. This mainly involves setting the bech32 prefixes for [addresses and pubkeys](../basics/accounts-fees-gas.md#addresses-and-pubkeys). +- Then, the [`config`](https://github.com/cosmos/cosmos-sdk/blob/master/types/config.go) is retrieved and config parameters are set. This mainly involves setting the bech32 prefixes for [addresses and pubkeys](../basics/accounts.md#addresses-and-pubkeys). - Using [cobra](https://github.com/spf13/cobra), the root command of the full-node client is created. After that, all the custom commands of the application are added using the `AddCommand()` method of `rootCmd`. - Add default server commands to `rootCmd` using the `server.AddCommands(ctx, cdc, rootCmd, newApp, exportAppStateAndTMValidators)` method. These commands are separated from the ones added above since they are standard and defined at SDK level. They should be shared by all SDK-based applications. They include the most important command: the [`start` command](#start-command). - Prepare and execute the [`executor`](https://github.com/tendermint/tendermint/blob/bc572217c07b90ad9cee851f193aaa8e9557cbc7/libs/cli/setup.go#L75-L78). @@ -61,7 +62,7 @@ tmNode, err := node.NewNode( ) ``` -The Tendermint node can be created with `app` because the latter satisfies the [`abci.Application` interface](https://github.com/tendermint/tendermint/blob/bc572217c07b90ad9cee851f193aaa8e9557cbc7/abci/types/application.go#L11-L26) (given that `app` extends [`baseapp`](./baseapp.md)). As part of the `NewNode` method, Tendermint makes sure that the height of the application (i.e. number of blocks since genesis) is equal to the height of the Tendermint node. The difference between these two heights should always be negative or null. If it is strictly negative, `NewNode` will replay blocks until the height of the application reaches the height of the Tendermint node. Finally, if the height of the application is `0`, the Tendermint node will call [`InitChain`](./baseapp.md#initchain) on the application to initialize the state. +The Tendermint node can be created with `app` because the latter satisfies the [`abci.Application` interface](https://github.com/tendermint/tendermint/blob/bc572217c07b90ad9cee851f193aaa8e9557cbc7/abci/types/application.go#L11-L26) (given that `app` extends [`baseapp`](./baseapp.md)). As part of the `NewNode` method, Tendermint makes sure that the height of the application (i.e. number of blocks since genesis) is equal to the height of the Tendermint node. The difference between these two heights should always be negative or null. If it is strictly negative, `NewNode` will replay blocks until the height of the application reaches the height of the Tendermint node. Finally, if the height of the application is `0`, the Tendermint node will call [`InitChain`](./baseapp.md#initchain) on the application to initialize the state from the genesis file. Once the Tendermint node is instanciated and in sync with the application, the node can be started: diff --git a/docs/core/ocap.md b/docs/core/ocap.md index 3b27034c1e1a..61979f10572a 100644 --- a/docs/core/ocap.md +++ b/docs/core/ocap.md @@ -1,13 +1,16 @@ --- -order: false +order: 8 --- # Object-Capability Model +## Synopsis + +The Cosmos SDK uses an object-capabilities model + ## Intro -When thinking about security, it is good to start with a specific threat -model. Our threat model is the following: +When thinking about security, it is good to start with a specific threat model. Our threat model is the following: > We assume that a thriving ecosystem of Cosmos-SDK modules that are easy to compose into a blockchain application will contain faulty or malicious modules. @@ -81,7 +84,7 @@ var sumValue := externalModule.ComputeSumValue(*account) ``` In the Cosmos SDK, you can see the application of this principle in the -[gaia app](../gaia/app/app.go). +[gaia app](https://github.com/cosmos/gaia/blob/bd10ee5c62a1206c03a21d0f71a9e9308765cdb7/app/app.go). ```go // register message routes diff --git a/docs/core/readme.md b/docs/core/readme.md index 651ae8d4e000..8d9348350932 100644 --- a/docs/core/readme.md +++ b/docs/core/readme.md @@ -1,5 +1,20 @@ --- order: false parent: - title: Core + order: 3 --- + +# Core + +This repository contains reference documentation on the core conepts of the Cosmos SDK. + +1. [`Baseapp`](./baseapp.md) +2. [Transaction](./transactions.md) +3. [Context](./context.md) +4. [Node Client](./node.md) +5. [Store](./store.md) +6. [Encoding](./encoding.md) +7. [Events](./events.md) +8. [Object-Capabilities](./ocap.md) + +After reading about the core concepts, head on to the [Building Modules documentation](../building-modules/README.md) to learn more about the process of building modules. \ No newline at end of file diff --git a/docs/core/store.md b/docs/core/store.md index 86c59322d7a8..b052906f03c6 100644 --- a/docs/core/store.md +++ b/docs/core/store.md @@ -1,3 +1,7 @@ +--- +order: 5 +--- + # Store ## Pre-requisite Reading @@ -8,27 +12,9 @@ A store is a data structure that holds the state of the application. -- [Introduction to SDK Stores](#introduction-to-sdk-stores) - + [Store Interface](#store-interface) - + [Commit Store](#commit-store) -- [Multistore](#multistore) - + [Multistore Interface](#multistore-interface) - + [CommitMultiStore](#commitmultistore) - + [CacheMuliStore](#cachemultistore) -- [Base Layer KVStores](#base-layer-kvstores) - + [`KVStore` and `CommitKVStore` Interfaces](#kvstore-and-commitkvstore-interfaces) - + [`IAVL` Store](#iavl-store) - + [`DBAdapter` Store](#dbadapter-store) - + [`Transient` Store](#transient-store) -- [KVStore Wrappers](#kvstore-wrappers) - + [CacheKVStore](#cachekvstore) - + [`GasKv` Store](#gaskv-store) - + [`TraceKV` Store](#tracekv-store) - + [`Prefix` Store](#prefix-store) - ## Introduction to SDK Stores -The Cosmos SDK comes with a large set of stores to persist the state of applications. By default, the main store of SDK applications is a multistore, i.e. a store of stores. Developers can add any number of key-value stores to the multistore, depending on their application needs. The multistore exists to support the modularity of the Cosmos SDK, as it lets each module declare and manage their own subset of the state. Key-value stores in the multistore can only be accessed with a specific capability `key`, which is typically held in the [`keeper`](../building-modules/keeper.md) of the module that declared the store. +The Cosmos SDK comes with a large set of stores to persist the state of applications. By default, the main store of SDK applications is a `multistore`, i.e. a store of stores. Developers can add any number of key-value stores to the multistore, depending on their application needs. The multistore exists to support the modularity of the Cosmos SDK, as it lets each module declare and manage their own subset of the state. Key-value stores in the multistore can only be accessed with a specific capability `key`, which is typically held in the [`keeper`](../building-modules/keeper.md) of the module that declared the store. ``` +-----------------------------------------------------+ @@ -104,7 +90,7 @@ type CacheWrapper interface { } ``` -Cache-wrapping is used ubiquitously in the Cosmos SDK and required to be implemented on every store type. A cache-wrapper creates a light snapshot of a store that can be passed around and updated without affecting the main underlying store. This is used to trigger temporary state-transitions that may be reverted later should an error occur. If a state-transition sequence is performed without issue, the cached store can be comitted to the main store at the end of the sequence. +Cache-wrapping is used ubiquitously in the Cosmos SDK and required to be implemented on every store type. A cache-wrapper creates a light snapshot of a store that can be passed around and updated without affecting the main underlying store. This is used to trigger temporary state-transitions that may be reverted later should an error occur. If a state-transition sequence is performed without issue, the cached store can be comitted to the underlying store at the end of the sequence. ### Commit Store @@ -239,7 +225,7 @@ type Store struct { ### `KVStore` and `CommitKVStore` Interfaces -A `KVStore` is a simple key-value store used to store and retrieve data. A `CommitKVStore` is a `KVStore` that also implements a `Committer`. By default, stores mounted in `baseapp`'s main `CommitMultiStore` are `CommitKVStore`s. The `KVStore` interface is primarily used to restrict modules from accessing the committer . +A `KVStore` is a simple key-value store used to store and retrieve data. A `CommitKVStore` is a `KVStore` that also implements a `Committer`. By default, stores mounted in `baseapp`'s main `CommitMultiStore` are `CommitKVStore`s. The `KVStore` interface is primarily used to restrict modules from accessing the committer. Individual `KVStore`s are used by modules to manage a subset of the global state. `KVStores` can be accessed by objects that hold a specific key. This `key` should only be exposed to the [`keeper`](../building-modules/keeper.md) of the module that defines the store. diff --git a/docs/core/transactions.md b/docs/core/transactions.md index f9c27d6c2201..c5ef4a3b94c4 100644 --- a/docs/core/transactions.md +++ b/docs/core/transactions.md @@ -1,57 +1,57 @@ +--- +order: 2 +--- + # Transactions ## Prerequisites -* [Anatomy of an SDK Application](./app-anatomy.md) +* [Anatomy of an SDK Application](../basics/app-anatomy.md) ## Synopsis -This document describes how various components are defined to enable transactions. It also describes how transactions are generated. - -1. [Transactions](#transactions) -2. [Transaction Definition](#transaction-definition) -3. [CLI and REST Interfaces](#cli-and-rest-interfaces) -4. [Messages](#messages) -5. [Transaction Generation](#transaction-generation) -6. [Handlers](#handlers) - +`Transactions` are objects created by end-users to trigger state changes in the application. ## Transactions -[**Transactions**](https://github.com/cosmos/cosmos-sdk/blob/master/types/tx_msg.go#L36-L43) are objects created by end-users to trigger state changes in the application. Specifically, they are comprised of metadata held in [contexts](./context.md) and [messages](../building-modules/messages-and-queries.md) that trigger state changes within a module through the module's [Handler](../building-modules/handler.md). +Transactions are comprised of metadata held in [contexts](./context.md) and [messages](../building-modules/messages-and-queries.md) that trigger state changes within a module through the module's [Handler](../building-modules/handler.md). -When users want to interact with an application and make state changes (e.g. sending coins), they create transactions. Each of a transaction's messages must be signed using the private key associated with the appropriate account(s), and then the transaction is broadcasted to the network. A transaction must then be included in a block, validated, and approved by the network through the consensus process. To read more about the lifecycle of a transaction, click [here](../basics/tx-lifecycle.md). +When users want to interact with an application and make state changes (e.g. sending coins), they create transactions. Each of a transaction's `message`s must be signed using the private key associated with the appropriate account(s), before the transaction is broadcasted to the network. A transaction must then be included in a block, validated, and approved by the network through the consensus process. To read more about the lifecycle of a transaction, click [here](../basics/tx-lifecycle.md). -## Transaction Definition +## Type Definition -The transaction objects themselves are SDK types that implement the [`Tx`](https://github.com/cosmos/cosmos-sdk/blob/master/types/tx_msg.go#L34-L41) interface, which contains the following methods: +Transaction objects are SDK types that implement the [`Tx`](https://github.com/cosmos/cosmos-sdk/blob/master/types/tx_msg.go#L34-L41) interface, which contains the following methods: * **GetMsgs:** unwraps the transaction and returns a list of its message(s) - one transaction may have one or multiple [messages](../building-modules/messages-and-queries.md#messages), which are defined by module developers. -* **ValidateBasic:** includes lightweight, [*stateless*](../basics/tx-lifecycle.md#types-of-checks) checks used by ABCI messages [`CheckTx`](../basics/baseapp.md#checktx) and [`DeliverTx`](../basics/baseapp.md#delivertx) to make sure transactions are not invalid. For example, the [`auth`](https://github.com/cosmos/cosmos-sdk/tree/master/x/auth) module's `StdTx` `ValidateBasic` function checks that its transactions are signed by the correct number of signers and that the fees do not exceed what the user's maximum (see the full implementation of `StdTx` [here](https://github.com/cosmos/cosmos-sdk/blob/master/x/auth/types/stdtx.go)). Note that this function is to be distinct from the `ValidateBasic` functions for *messages*, which perform basic validity checks on messages only. For example, when [`runTx`](../basics/baseapp.md#runtx-and-runmsgs) is checking a transaction created from the [`auth`](https://github.com/cosmos/cosmos-sdk/blob/master/docs/spec/auth) module, it first runs `ValidateBasic` on each message, then runs the `auth` module AnteHandler which calls `ValidateBasic` for the transaction itself. +* **ValidateBasic:** includes lightweight, [*stateless*](../basics/tx-lifecycle.md#types-of-checks) checks used by ABCI messages [`CheckTx`](./baseapp.md#checktx) and [`DeliverTx`](./baseapp.md#delivertx) to make sure transactions are not invalid. For example, the [`auth`](https://github.com/cosmos/cosmos-sdk/tree/master/x/auth) module's `StdTx` `ValidateBasic` function checks that its transactions are signed by the correct number of signers and that the fees do not exceed what the user's maximum. Note that this function is to be distinct from the `ValidateBasic` functions for *`messages`*, which perform basic validity checks on messages only. For example, when [`runTx`](./baseapp.md#runtx) is checking a transaction created from the [`auth`](https://github.com/cosmos/cosmos-sdk/tree/master/x/auth/spec) module, it first runs `ValidateBasic` on each message, then runs the `auth` module AnteHandler which calls `ValidateBasic` for the transaction itself. * **TxEncoder:** Nodes running the consensus engine (e.g. Tendermint Core) are responsible for gossiping transactions and ordering them into blocks, but only handle them in the generic `[]byte` form. Transactions are always [marshaled](./encoding.md) (encoded) before they are relayed to nodes, which compacts them to facilitate gossiping and helps maintain the consensus engine's separation from from application logic. The Cosmos SDK allows developers to specify any deterministic encoding format for their applications; the default is Amino. * **TxDecoder:** [ABCI](https://tendermint.com/docs/spec/abci/) calls from the consensus engine to the application, such as `CheckTx` and `DeliverTx`, are used to process transaction data to determine validity and state changes. Since transactions are passed in as `txBytes []byte`, they need to first be unmarshaled (decoded) using `TxDecoder` before any logic is applied. +The most used implementation of the `Tx` interface is [`StdTx` from the `auth` module](https://github.com/cosmos/cosmos-sdk/blob/master/x/auth/types/stdtx.go). As a developer, using `StdTx` as your transaction format is as simple as importing the `auth` module in your application (which can be done in the [constructor of the application](../basics/app-anatomy.md#constructor-function)) + +## Transaction Process + A transaction is created by an end-user through one of the possible [interfaces](#interfaces). In the process, two contexts and an array of [messages](#messages) are created, which are then used to [generate](#transaction-generation) the transaction itself. The actual state changes triggered by transactions are enabled by the [handlers](#handlers). The rest of the document will describe each of these components, in this order. -## CLI and REST Interfaces +### CLI and REST Interfaces -Application developers create entrypoints to the application by creating a [command-line interface](../interfaces/cli.md) or [REST interface](../interfaces/rest.md), typically found in the application's `/cmd` folder. These interfaces allow users to interact with the application through command-line or through HTTP requests. +Application developers create entrypoints to the application by creating a [command-line interface](../interfaces/cli.md) and/or [REST interface](../interfaces/rest.md), typically found in the application's `./cmd` folder. These interfaces allow users to interact with the application through command-line or through HTTP requests. -In order for module messages to be utilized in transactions created through these interfaces, module developers must also specify possible user [interactions](../building-modules/interfaces.md), typically in the module's `/client` folder. For the [command-line interface](../building-modules/interfaces.md#cli), module developers create subcommands to add as children to the application top-level transaction command `TxCmd`. For [HTTP requests](../building-modules/interfaces.md#rest), module developers specify acceptable request types, register REST routes, and create HTTP Request Handlers. +For the [command-line interface](../building-modules/module-interfaces.md#cli), module developers create subcommands to add as children to the application top-level transaction command `TxCmd`. For [HTTP requests](../building-modules/module-interfaces.md#rest), module developers specify acceptable request types, register REST routes, and create HTTP Request Handlers. When users interact with the application's interfaces, they invoke the underlying modules' handlers or command functions, directly creating messages. -## Messages +### Messages -**Messages** are module-specific objects that trigger state transitions within the scope of the module they belong to. Module developers define the messages for their module by implementing the [`Msg`](https://github.com/cosmos/cosmos-sdk/blob/master/types/tx_msg.go#L10-L31) interface, and also define a [`Handler`](../building-modules/handler.md) to process them. Messages in a module are typically defined in a `msgs.go` file (though not always), and one handler with multiple functions to handle each of the module's messages is defined in a `handler.go` file. +**`Message`s** are module-specific objects that trigger state transitions within the scope of the module they belong to. Module developers define the `message`s for their module by implementing the [`Msg`](https://github.com/cosmos/cosmos-sdk/blob/master/types/tx_msg.go#L10-L31) interface, and also define a [`Handler`](../building-modules/handler.md) to process them. `Message`s in a module are typically defined in a `msgs.go` file (though not always), and one handler with multiple functions to handle each of the module's `message`s is defined in a `handler.go` file. -Note: module messages are not to be confused with [ABCI Messages](https://tendermint.com/docs/spec/abci/abci.html#messages) which define interactions between the Tendermint and application layers. While ABCI messages such as CheckTx and DeliverTx contain Transactions, which contain module Messages, they are not to be confused with the module level messages themselves +Note: module `messages` are not to be confused with [ABCI Messages](https://tendermint.com/docs/spec/abci/abci.html#messages) which define interactions between the Tendermint and application layers. -To learn more about messages, click [here](../building-modules/messages-and-queries.md#messages). +To learn more about `message`s, click [here](../building-modules/messages-and-queries.md#messages). While messages contain the information for state transition logic, a transaction's other metadata and relevant information are stored in the `TxBuilder` and `CLIContext`. -## Transaction Generation +### Transaction Generation Transactions are first created by end-users through an `appcli tx` command through the command-line or a POST request to an HTTPS server. For details about transaction creation, click [here](../basics/tx-lifecycle.md#transaction-creation). @@ -73,11 +73,11 @@ The [`TxBuilder`](https://github.com/cosmos/cosmos-sdk/blob/master/x/auth/types/ The `CLIContext` is initialized using the application's `codec` and data more closely related to the user interaction with the interface, holding data such as the output to the user and the broadcast mode. Read more about `CLIContext` [here](../interfaces/query-lifecycle.md#clicontext). -Every message in a transaction must be signed by the addresses specified by `GetSigners`. The signing process must be handled by a module, and the most widely used one is the [`auth`](https://github.com/cosmos/cosmos-sdk/blob/master/docs/spec/auth) module. Signing is automatically performed when the transaction is created, unless the user choses to generate and sign separately. The `TxBuilder` (namely, the `KeyBase`) is used to perform the signing operations, and the `CLIContext` is used to broadcast transactions. +Every message in a transaction must be signed by the addresses specified by `GetSigners`. The signing process must be handled by a module, and the most widely used one is the [`auth`](https://github.com/cosmos/cosmos-sdk/tree/master/x/auth/spec) module. Signing is automatically performed when the transaction is created, unless the user choses to generate and sign separately. The `TxBuilder` (namely, the `KeyBase`) is used to perform the signing operations, and the `CLIContext` is used to broadcast transactions. -## Handlers +### Handlers -The final components developers must implement to enable transactions are handlers and keepers. Since messages are module types, each module needs a Handler to process all of its message types and enact the state changes within the module's scope. This design puts more responsibility in module developers, allowing application developers to reuse common functionalities without having to implement state transition logic repetitively. To read more about handlers, visit the documentation for building modules [here](../building-modules/handler.md). +Since `message`s are module-specific types, each module needs a [`handler`](../building-modules/handler.md) to process all of its `message` types and trigger state changes within the module's scope. This design puts more responsibility on module developers, allowing application developers to reuse common functionalities without having to implement state transition logic repetitively. To read more about `handler`s, click [here](../building-modules/handler.md). ## Next diff --git a/docs/interfaces/README.md b/docs/interfaces/README.md new file mode 100644 index 000000000000..0e23c0478ae7 --- /dev/null +++ b/docs/interfaces/README.md @@ -0,0 +1,15 @@ +--- +order: false +parent: + order: 5 +--- + +# Interfaces + +This repository contains documentation on interfaces for Cosmos SDK applications. + +1. [Introduction to Interaces](./interfaces-intro.md) +2. [Lifecycle of a Query](./query-lifecycle.md) +3. [Command-Line Interface](./cli.md) +4. [Rest Interface](./rest.md) + diff --git a/docs/interfaces/cli.md b/docs/interfaces/cli.md index 6141f3ea8a29..f86144a561c9 100644 --- a/docs/interfaces/cli.md +++ b/docs/interfaces/cli.md @@ -1,3 +1,7 @@ +--- +order: 3 +--- + # Command-Line Interface ## Prerequisites @@ -6,18 +10,13 @@ ## Synopsis -This document describes how to create a commmand-line interface (CLI) for an [**application**](../basics/app-anatomy.md). A separate document for implementing a CLI for an SDK [**module**](../building-modules/intro.md) can be found [here](#../building-modules/interfaces.md#cli). - -- [Application CLI Components](#application-cli-components) -- [Commands](#commands) -- [Flags](#flags) -- [Configurations](#configurations) +This document describes how to create a commmand-line interface (CLI) for an [**application**](../basics/app-anatomy.md). A separate document for implementing a CLI for an SDK [**module**](../building-modules/intro.md) can be found [here](#../building-modules/module-interfaces.md#cli). -## Application CLI Components +## Command-Line Interface -One of the main entrypoints of an application is the command-line interface. This entrypoint is created as a `main.go` file which compiles to a binary, conventionally placed in the application's `./cmd/cli` folder. The CLI for an application is typically be referred to as the name of the application suffixed with `-cli`, e.g. `appcli`. Here is where the interfaces docs lie in the directory from the [nameservice tutorial](https://cosmos.network/docs/tutorial) +One of the main entrypoints of an application is the command-line interface. This entrypoint is created via a `main.go` file which compiles to a binary, conventionally placed in the application's `./cmd/cli` folder. The CLI for an application is typically be referred to as the name of the application suffixed with `-cli`, e.g. `appcli`. Here is where the interfaces docs lie in the directory from the [nameservice tutorial](https://cosmos.network/docs/tutorial) -### Cobra +### Example Command There is no set way to create a CLI, but SDK modules typically use the [Cobra Library](https://github.com/spf13/cobra). Building a CLI with Cobra entails defining commands, arguments, and flags. [**Commands**](#commands) understand the actions users wish to take, such as `tx` for creating a transaction and `query` for querying the application. Each command can also have nested subcommands, necessary for naming the specific transaction type. Users also supply **Arguments**, such as account numbers to send coins to, and [**Flags**](#flags) to modify various aspects of the commands, such as gas prices or which node to broadcast to. @@ -26,11 +25,19 @@ Here is an example of a command a user might enter to interact with the nameserv ```bash nscli tx nameservice buy-name --gas auto --gas-prices ``` -The first four strings specify the command: the root command for the entire application `nscli`, the subcommand `tx`, the subcommand `nameservice` to indicate which module to route the command to, and the type of transaction `buy-name`. The next two strings are arguments: the `name` the user wishes to buy and the `amount` they want to pay for it. Finally, the last few strings of the command are flags to indicate how much the user is willing to pay in fees (calculated using the amount of gas used to execute the transaction and the gas prices provided by the user). + +The first four strings specify the command: + +- The root command for the entire application `nscli`. +- The subcommand `tx`, which contains all commands that let users create transactions. +- The subcommand `nameservice` to indicate which module to route the command to (`nameservice` module in this case). +- The type of transaction `buy-name`. + +The next two strings are arguments: the `name` the user wishes to buy and the `amount` they want to pay for it. Finally, the last few strings of the command are flags to indicate how much the user is willing to pay in fees (calculated using the amount of gas used to execute the transaction and the gas prices provided by the user). The CLI interacts with a [node](../core/node.md) (running `nsd`) to handle this command. The interface itself is defined in a `main.go` file. -### Main Function +### Building the CLI The `main.go` file needs to have a `main()` function that does the following to run the command-line interface: @@ -42,7 +49,7 @@ The `main.go` file needs to have a `main()` function that does the following to An example of the `main()` function for the [nameservice tutorial](https://cosmos.network/docs/tutorial) CLI can be found [here](https://github.com/cosmos/sdk-application-tutorial/blob/c6754a1e313eb1ed973c5c91dcc606f2fd288811/cmd/nscli/main.go#L26-L67). The rest of the document will detail what needs to be implemented for each step and include smaller portions of code from the nameservice CLI `main.go` file. -## Commands +## Adding Commands to the CLI Every application CLI first constructs a root command, then adds functionality by aggregating subcommands (often with further nested subcommands) using `AddCommand()`. The bulk of an application's unique capabilities lies in its transaction and query commands, called `TxCmd` and `QueryCmd` respectively. @@ -50,7 +57,7 @@ Every application CLI first constructs a root command, then adds functionality b The root command (called `rootCmd`) is what the user first types into the command line to indicate which application they wish to interact with. The string used to invoke the command (the "Use" field) is typically the name of the application suffixed with `-cli`, e.g. `appcli`. The root command typically includes the following commands to support basic functionality in the application. -* **Status** command from the SDK rpc client tools, which prints information about the status of the connected [`Node`](,,/core/node.md). The Status of a node includes [`NodeInfo`](https://github.com/tendermint/tendermint/blob/master/p2p/node_info.go#L75-L92), `SyncInfo` and `ValidatorInfo`: this information includes the node ID, latest block hash, and the validator public key and voting power. Here is an example of what the `status command` outputs: +* **Status** command from the SDK rpc client tools, which prints information about the status of the connected [`Node`](../core/node.md). The Status of a node includes [`NodeInfo`](https://github.com/tendermint/tendermint/blob/master/p2p/node_info.go#L75-L92), `SyncInfo` and `ValidatorInfo`: this information includes the node ID, latest block hash, and the validator public key and voting power. Here is an example of what the `status command` outputs: ```json { "jsonrpc": "2.0", @@ -132,10 +139,10 @@ The root-level `status`, `config`, and `keys` subcommands are common across most [Transactions](#./transactions.md) are objects wrapping [messages](../building-modules/messages-and-queries.md) that trigger state changes. To enable the creation of transactions using the CLI interface, `TxCmd` typically adds the following commands: -* **Sign** [command](https://github.com/cosmos/cosmos-sdk/blob/master/x/auth/client/cli/tx_sign.go#L30-L83) from the [`auth`](https://github.com/cosmos/cosmos-sdk/blob/master/docs/spec/auth) module, the command that signs messages in a transaction. To enable multisig, add the `auth` module [`MultiSign`](https://github.com/cosmos/cosmos-sdk/blob/master/x/auth/client/cli/tx_multisign.go#L26-L151) command. Since every transaction requires some sort of signature in order to be valid, this command is necessary for every application. +* **Sign** [command](https://github.com/cosmos/cosmos-sdk/blob/master/x/auth/client/cli/tx_sign.go#L30-L83) from the [`auth`](https://github.com/cosmos/cosmos-sdk/tree/master/x/auth/spec) module, the command that signs messages in a transaction. To enable multisig, add the `auth` module [`MultiSign`](https://github.com/cosmos/cosmos-sdk/blob/master/x/auth/client/cli/tx_multisign.go#L26-L151) command. Since every transaction requires some sort of signature in order to be valid, this command is necessary for every application. * **Broadcast** [command](https://github.com/cosmos/cosmos-sdk/blob/master/client/context/broadcast.go) from the SDK client tools, which broadcasts transactions. -* **Send** [command](https://github.com/cosmos/cosmos-sdk/blob/master/x/bank/client/cli/tx.go#L31-L60) from the [`bank`](https://github.com/cosmos/cosmos-sdk/blob/master/docs/spec/bank) module, which is a transaction that allows accounts to send coins to one another, including gas and fees for transactions. -* All [module transaction commands](../building-modules/interfaces.md) the application is dependent on, retrieved by calling [`GetTxCmd()`](../building-modules/interfaces.md#GetTxCmd) on all the modules or using the Module Manager's [`AddTxCommands()`](../building-modules/module-manager.md) function. +* **Send** [command](https://github.com/cosmos/cosmos-sdk/blob/master/x/bank/client/cli/tx.go#L31-L60) from the [`bank`](https://github.com/cosmos/cosmos-sdk/tree/master/x/bank/spec) module, which is a transaction that allows accounts to send coins to one another, including gas and fees for transactions. +* All [module transaction commands](../building-modules/module-interfaces.md) the application is dependent on, retrieved by calling [`GetTxCmd()`](../building-modules/module-interfaces.md#GetTxCmd) on all the modules or using the Module Manager's [`AddTxCommands()`](../building-modules/module-manager.md) function. Here is an example of a `TxCmd` aggregating these subcommands from the [nameservice tutorial](https://cosmos.network/docs/tutorial). @@ -171,7 +178,7 @@ func txCmd(cdc *amino.Codec, mc []sdk.ModuleClients) *cobra.Command { * **Account** [command](https://github.com/cosmos/cosmos-sdk/blob/master/x/auth/client/cli/query.go#L45-L73) from the `auth` module, which displays the state (e.g. account balance) of an account given an address. * **Validator** [command](https://github.com/cosmos/cosmos-sdk/blob/master/client/rpc/validators.go) from the SDK rpc client tools, which displays the validator set of a given height. * **Block** [command](https://github.com/cosmos/cosmos-sdk/blob/master/client/rpc/block.go) from the SDK rpc client tools, which displays the block data for a given height. -* All [module query commands](../building-modules/interfaces.md) the application is dependent on, retrieved by calling [`GetQueryCmd()`](../building-modules/interfaces.md#GetqueryCmd) on all the modules or using the Module Manager's `AddQueryCommands()` function. +* All [module query commands](../building-modules/module-interfaces.md) the application is dependent on, retrieved by calling [`GetQueryCmd()`](../building-modules/module-interfaces.md#GetqueryCmd) on all the modules or using the Module Manager's `AddQueryCommands()` function. Here is an example of a `QueryCmd` aggregating subcommands, also from the nameservice tutorial (it is structurally identical to `TxCmd`): @@ -291,6 +298,3 @@ rootCmd.PersistentPreRunE = func(_ *cobra.Command, _ []string) error { } ``` -## Next - -Read about how to build a module CLI [here](./module-interfaces#cli) diff --git a/docs/interfaces/clients.md b/docs/interfaces/clients.md deleted file mode 100644 index ee972577c121..000000000000 --- a/docs/interfaces/clients.md +++ /dev/null @@ -1,26 +0,0 @@ -# Clients - -This section explains contains information on clients for SDK based blockchain. - ->*NOTE*: This section is a WIP. - -## Light-client - -Light-clients enable users to interact with your application without having to download the entire state history but with a good level of security. - -- [Overview of light clients](./lite/README.md) -- [Starting a light-client server](./lite/getting_started.md) -- [Light-client specification](./lite/specification.md) - -## Other clients - -- [Command-Line interface for SDK-based blockchain](./cli.md) -- [Service provider doc](./service-providers.md) - -## Genesis upgrade - -If you need to upgrade your node you could export the genesis and migrate it to the new version through this script: - -```bash - migrate v0.36 genesis_0_34.json [--time "2019-04-22T17:00:11Z"] [--chain-id test] > ~/.gaiad/genesis.json -``` diff --git a/docs/interfaces/interfaces-intro.md b/docs/interfaces/interfaces-intro.md index e457925acaad..1e12a1a89a7c 100644 --- a/docs/interfaces/interfaces-intro.md +++ b/docs/interfaces/interfaces-intro.md @@ -1,3 +1,7 @@ +--- +order: 1 +--- + # Interfaces ## Prerequisites @@ -5,39 +9,31 @@ * [Anatomy of an SDK Application](../basics/app-anatomy.md) * [Lifecycle of a Transaction](../basics/tx-lifecycle.md) - ## Synopsis -Typically, SDK applications include some type of interface that users interact with to utilize the application's functionalities. This document introduces user command-line and REST interfaces. - -- [Types of Application Interfaces](#types-of-application-interfaces) -- [Module vs Application Interfaces](#module-vs-application-interfaces) - + [Module Developer Responsibilities](#module-developer-responsibilities) - + [Application Developer Responsibilities](#application-developer-responsibilities) - +Typically, SDK applications include interfaces to let end-users interact with the application. This document introduces the different types of interfaces for SDK applications. ## Types of Application Interfaces -SDK applications generally have a Command-Line Interface (CLI) and REST Interface to support interactions with a [full-node](../core/node.md). The SDK is opinionated about how to create these two interfaces; all modules specify [Cobra commands](https://github.com/spf13/cobra) and register routes using [Gorilla Mux routers](https://github.com/gorilla/mux). The CLI and REST Interface are conventionally defined in the application `app/cmd/cli` folder. - +SDK applications generally have a Command-Line Interface (CLI) and REST Interface to support interactions with a [full-node](../core/node.md). The SDK is opinionated about how to create these two interfaces; all modules specify [Cobra commands](https://github.com/spf13/cobra) and register routes using [Gorilla Mux routers](https://github.com/gorilla/mux). The CLI and REST Interface are conventionally defined in the application `./app/cmd/cli` folder. ## Module vs Application Interfaces -The process of creating an application interface is distinct from creating a [module interface](../building-modules/interfaces.md), though the components are closely intertwined. As expected, the module interface handles the bulk of the underlying logic, defining ways for end-users to create [messages](../building-modules/messages-and-queries.md#messages) handled by the module and [queries](../building-modules/messages-and-queries.md#queries) to the subset of application state within the scope of the module. On the other hand, the application interfaces aggregate module-level interfaces in order to route messages and queries to the appropriate modules. Application interfaces also handle root-level responsibilities such as signing and broadcasting [transactions](../core/transactions.md) that wrap messages. +The process of creating an application interface is distinct from creating a [module interface](../building-modules/module-interfaces.md), though the two are closely intertwined. As expected, module interfaces handle the bulk of the underlying logic, defining ways for end-users to create [messages](../building-modules/messages-and-queries.md#messages) and [queries](../building-modules/messages-and-queries.md#queries) to the subset of application state within their scope. On the other hand, application interfaces aggregate module-level interfaces in order to route `messages` and `queries` to the appropriate modules. Application interfaces also handle root-level responsibilities such as signing and broadcasting [transactions](../core/transactions.md) that wrap messages. ### Module Developer Responsibilities -In regards to interfaces, module developers include the following definitions: +With regards to interfaces, module developers need to include the following definitions: -* **CLI commands:** Specifically, [Transaction commands](../building-modules/interfaces.md#transaction-commands) and [Query commands](../building-modules/interfaces.md#query-commands). These are commands that users will invoke when interacting with the application to create transactions and queries. For example, if an application enables sending coins through the [`auth`](https://github.com/cosmos/cosmos-sdk/tree/67f6b021180c7ef0bcf25b6597a629aca27766b8/docs/spec/auth) module, users will create `tx auth send` transactions. -* **Request Handlers:** Also categorized into Transaction and Query requests. Transactions will require HTTP [Request Types](../building-modules/interfaces.md#request-types) in addition to [Request Handlers](../building-modules/interfaces.md#request-handlers) in order to encapsulate all of the user's options (e.g. gas prices). -* **REST Routes:** Given a router, the module interface registers paths with the aforementioned [Request Handlers](../building-modules/interfaces.md#request-handlers) for each type of request. +* **CLI commands:** Specifically, [Transaction commands](../building-modules/module-interfaces.md#transaction-commands) and [Query commands](../building-modules/module-interfaces.md#query-commands). These are commands that users will invoke when interacting with the application to create transactions and queries. For example, if an application enables sending coins through the [`auth`](https://github.com/cosmos/cosmos-sdk/tree/67f6b021180c7ef0bcf25b6597a629aca27766b8/docs/spec/auth) module, users will create `tx auth send` transactions. +* **Request Handlers:** Also categorized into Transaction and Query requests. Transactions will require HTTP [Request Types](../building-modules/module-interfaces.md#request-types) in addition to [Request Handlers](../building-modules/module-interfaces.md#request-handlers) in order to encapsulate all of the user's options (e.g. gas prices). +* **REST Routes:** Given a router, the module interface registers paths with the aforementioned [Request Handlers](../building-modules/module-interfaces.md#request-handlers) for each type of request. -Module interfaces are designed to be generic. Both commands and request types include required user input (through flags or request body) which are different for each application. This section of documents will only detail application interfaces; to read about how to build module interfaces, click [here](../building-modules/interfaces.md). +Module interfaces are designed to be generic. Both commands and request types include required user input (through flags or request body) which are different for each application. This section of documents will only detail application interfaces; to read about how to build module interfaces, click [here](../building-modules/module-interfaces.md). ### Application Developer Responsibilities -In regards to interfaces, application developers include: +With regards to interfaces, application developers need to include: * **CLI Root Command:** The [root command](./cli.md#root-command) adds subcommands to include all of the functionality for the application, mainly module [transaction](./cli.md#transaction-commands) and [query](./cli.md#query-commands) commands from the application's module(s). * **App Configurations:** All application-specific values are the responsibility of the application developer, including the [`codec`](../core/encoding.md) used to marshal requests before relaying them to a node. diff --git a/docs/interfaces/lite/readme.md b/docs/interfaces/lite/readme.md index 23bcb2f93b26..e31ccd0752e5 100644 --- a/docs/interfaces/lite/readme.md +++ b/docs/interfaces/lite/readme.md @@ -1,3 +1,8 @@ +--- +parent: + order: false +--- + # Light Client Overview **See the Cosmos SDK Light Client RPC documentation [here](https://cosmos.network/rpc/)** diff --git a/docs/interfaces/lite/specification.md b/docs/interfaces/lite/specification.md index e252403731a2..4ce849acaa1d 100644 --- a/docs/interfaces/lite/specification.md +++ b/docs/interfaces/lite/specification.md @@ -14,7 +14,7 @@ tree is the AppHash which will be included in block header. ![Simple Merkle Tree](./pics/simpleMerkleTree.png) -As we have discussed in [LCD trust-propagation](https://github.com/irisnet/cosmos-sdk/tree/bianjie/lcd_spec/docs/spec/lcd#trust-propagation), +As we have discussed in LCD trust-propagation, the AppHash can be verified by checking voting power against a trusted validator set. Here we just need to build proof from ABCI state to AppHash. The proof contains two parts: diff --git a/docs/interfaces/query-lifecycle.md b/docs/interfaces/query-lifecycle.md index 6ccd612476a2..cebb86c26165 100644 --- a/docs/interfaces/query-lifecycle.md +++ b/docs/interfaces/query-lifecycle.md @@ -1,3 +1,7 @@ +--- +order: 2 +--- + # Query Lifecycle ## Prerequisites @@ -6,19 +10,13 @@ ## Synopsis -This document describes SDK interfaces in detail through the lifecycle of a query, from the user interface to application stores and back. The query will be referred to as `Query`. - -- [Query Creation](#query-creation) -- [Query Preparation](#query-preparation) -- [RPC](#rpc) -- [Application Query Handling](#application-query-handling) -- [Response](#response) +This document describes the lifecycle of a query in a SDK application, from the user interface to application stores and back. The query will be referred to as `Query`. ## Query Creation -A [**query**](../building-modules/messages-and-queries.md#queries) is a request for information made by end-users of applications through an interface and processed by a full-node. Users can query information about the network, the application itself, and application state directly from the application's stores or modules. Note that queries are different from [transactions](../core/transactions.md) (view the lifecycle [here](../basics/tx-lifecycle.md)), particularly in that they do not require consensus to be processed; they can be fully handled by one full-node. +A [**query**](../building-modules/messages-and-queries.md#queries) is a request for information made by end-users of applications through an interface and processed by a full-node. Users can query information about the network, the application itself, and application state directly from the application's stores or modules. Note that queries are different from [transactions](../core/transactions.md) (view the lifecycle [here](../basics/tx-lifecycle.md)), particularly in that they do not require consensus to be processed (as they do not trigger state-transitions); they can be fully handled by one full-node. -For the purpose of explaining a query lifecycle, let's say `Query` is requesting a list of delegations made by a certain delegator address in the application called `app`. As to be expected, the [`staking`](https://github.com/cosmos/cosmos-sdk/blob/master/docs/spec/staking) module handles this query. But first, there are a few ways `Query` can be created by users. +For the purpose of explaining the query lifecycle, let's say `Query` is requesting a list of delegations made by a certain delegator address in the application called `app`. As to be expected, the [`staking`](https://github.com/cosmos/cosmos-sdk/tree/master/x/staking/spec) module handles this query. But first, there are a few ways `Query` can be created by users. ### CLI @@ -28,15 +26,15 @@ The main interface for an application is the command-line interface. Users conne appcli query staking delegations ``` +This query command was defined by the [`staking`](https://github.com/cosmos/cosmos-sdk/tree/master/x/staking/spec) module developer and added to the list of subcommands by the application developer when creating the CLI. The code for this particular command can be found [here](https://github.com/cosmos/cosmos-sdk/blob/master/x/staking/client/cli/query.go#L253-L294). + Note that the general format is as follows: ```bash appcli query [moduleName] [command] --flag ``` -To provide values such as `--node` (the full-node the CLI connects to), the user must use the `config` command to set them or provide them as flags. - -This query command was defined by the [`staking`](https://github.com/cosmos/cosmos-sdk/blob/master/docs/spec/staking) module developer and added to the list of subcommands by the application developer when creating the CLI. The code for this particular command can be found [here](https://github.com/cosmos/cosmos-sdk/blob/master/x/staking/client/cli/query.go#L253-L294). +To provide values such as `--node` (the full-node the CLI connects to), the user can use the `config` command to set themn or provide them as flags. The CLI understands a specific set of commands, defined in a hierarchical structure by the application developer: from the [root command](./cli.md#root-command) (`appcli`), the type of command (`query`), the module that contains the command (`staking`), and command itself (`delegations`). Thus, the CLI knows exactly which module handles this command and directly passes the call there. @@ -62,8 +60,8 @@ The interactions from the users' perspective are a bit different, but the underl The first thing that is created in the execution of a CLI command is a `CLIContext`, while the REST Server directly provides a `CLIContext` for the REST Request handler. A [Context](../core/context.md) is an immutable object that stores all the data needed to process a request on the user side. In particular, a `CLIContext` stores the following: -* **Codec**: The [encoder/decoder](,./core/encoding.md) used by the application, used to marshal the parameters and query before making the Tendermint RPC request and unmarshal the returned response into a JSON object. -* **Account Decoder**: The account decoder from the [`auth`](.../spec/auth) module, which translates `[]byte`s into accounts. +* **Codec**: The [encoder/decoder](../core/encoding.md) used by the application, used to marshal the parameters and query before making the Tendermint RPC request and unmarshal the returned response into a JSON object. +* **Account Decoder**: The account decoder from the [`auth`](https://github.com/cosmos/cosmos-sdk/tree/master/x/auth/spec) module, which translates `[]byte`s into accounts. * **RPC Client**: The [Tendermint RPC Client](https://github.com/tendermint/tendermint/blob/bc572217c07b90ad9cee851f193aaa8e9557cbc7/rpc/client/interface.go), or node, to which the request will be relayed to. * **Keybase**: A [Key Manager](../basics/accounts.md#keybase) used to sign transactions and handle other operations with keys. * **Output Writer**: A [Writer](https://golang.org/pkg/io/#Writer) used to output the response. @@ -80,7 +78,7 @@ At this point in the lifecycle, the user has created a CLI command or HTTP Reque #### Parse Arguments -In this case, `Query` contains an [address](../basics/accounts.m#addresses) `delegatorAddress` as its only argument. However, the request can only contain `[]byte`s, as it will be relayed to a consensus engine (e.g. Tendermint Core) of a full-node that has no inherent knowledge of the application types. Thus, the `codec` of `CLIContext` is used to marshal the address as the type [`QueryDelegatorParams`](https://github.com/cosmos/cosmos-sdk/blob/master/x/staking/types/querier.go#L30-L38). All query arguments have their own types that the application `codec` understands how to encode and decode. For example, the [`staking`](https://github.com/cosmos/cosmos-sdk/blob/master/docs/spec/staking) module also has [`QueryValidatorParams`](https://github.com/cosmos/cosmos-sdk/blob/master/x/staking/types/querier.go#L45-L53) and [`QueryBondsParams`](https://github.com/cosmos/cosmos-sdk/blob/master/x/staking/types/querier.go#L59-L69). The module [`querier`](.//building-modules/querier.md) declares these types and the application registers the `codec`s. +In this case, `Query` contains an [address](../basics/accounts.md#addresses) `delegatorAddress` as its only argument. However, the request can only contain `[]byte`s, as it will be relayed to a consensus engine (e.g. Tendermint Core) of a full-node that has no inherent knowledge of the application types. Thus, the `codec` of `CLIContext` is used to marshal the address as the type [`QueryDelegatorParams`](https://github.com/cosmos/cosmos-sdk/blob/master/x/staking/types/querier.go#L30-L38). All query arguments have their own types that the application `codec` understands how to encode and decode. For example, the [`staking`](https://github.com/cosmos/cosmos-sdk/tree/master/x/staking/spec) module also has [`QueryValidatorParams`](https://github.com/cosmos/cosmos-sdk/blob/master/x/staking/types/querier.go#L45-L53) and [`QueryBondsParams`](https://github.com/cosmos/cosmos-sdk/blob/master/x/staking/types/querier.go#L59-L69). The module [`querier`](../building-modules/querier.md) declares these types and the application registers the `codec`s. Here is what the code looks like for the CLI command: diff --git a/docs/interfaces/readme.md b/docs/interfaces/readme.md index 22828fd0f070..0e23c0478ae7 100644 --- a/docs/interfaces/readme.md +++ b/docs/interfaces/readme.md @@ -1,5 +1,15 @@ --- order: false parent: - title: Interfaces + order: 5 --- + +# Interfaces + +This repository contains documentation on interfaces for Cosmos SDK applications. + +1. [Introduction to Interaces](./interfaces-intro.md) +2. [Lifecycle of a Query](./query-lifecycle.md) +3. [Command-Line Interface](./cli.md) +4. [Rest Interface](./rest.md) + diff --git a/docs/interfaces/rest.md b/docs/interfaces/rest.md index 298758377143..cad7d93e3b39 100644 --- a/docs/interfaces/rest.md +++ b/docs/interfaces/rest.md @@ -1,3 +1,7 @@ +--- +order: 4 +--- + # REST Interface ## Prerequisites @@ -9,13 +13,9 @@ This document describes how to create a REST interface for an SDK **application**. A separate document for creating a [**module**](../building-modules/intro.md) REST interface can be found [here](#../module-interfaces.md#rest). -- [Application REST Interface](#application-rest-interface) -- [REST Server](#rest-server) -- [Registering Routes](#registering-routes) - ## Application REST Interface -Building the REST Interface for an application involves creating a [REST server](./rest.md#rest-server) to route requests and output responses. The SDK has its own REST Server type used for [LCDs](../core/node.md) (light-client daemons). It has a `ServeCommand` that takes in an application's `codec` and `RegisterRoutes()` function, starts up a new REST Server, and registers routes using function provided from the application. To enable this command, it should be added as a subcommand of the root command in the `main()` function of the CLI interface: +Building the REST Interface for an application involves creating a [REST server](./rest.md#rest-server) to route requests and output responses. The SDK comes with its own REST Server by default called the LCDs (for Light-Client Daemon). To enable it, the `lcd.ServeCommand` command should be added as a subcommand of the `rootCmd` in the `main()` function of the CLI interface: ```go rootCmd.AddCommand(lcd.ServeCommand(cdc, registerRoutes)) @@ -27,10 +27,9 @@ Users can use the application CLI to start a new LCD, a local server through whi appcli rest-server --chain-id --trust-node ``` - ## REST Server -A REST Server is used to receive and route HTTP Requests, obtain the results from the application, and return the response to the user. The REST Server defined by the SDK LCD package contains the following: +A REST Server is used to receive and route HTTP Requests, obtain the results from the application, and return a response to the user. The REST Server defined by the SDK LCD package contains the following: * **Router:** A router for HTTP requests. A new router can be instantiated for an application and used to match routes based on path, request method, headers, etc. The SDK uses the [Gorilla Mux Router](https://github.com/gorilla/mux). * **CLIContext:** A [`CLIContext`](./query-lifecycle.md#clicontext) created for a user interaction. @@ -38,13 +37,13 @@ A REST Server is used to receive and route HTTP Requests, obtain the results fro * **Logger:** A logger from Tendermint `Log`, a log package structured around key-value pairs that allows logging level to be set differently for different keys. The logger takes `Debug()`, `Info()`, and `Error()`s. * **Listener:** A [listener](https://golang.org/pkg/net/#Listener) from the net package. -Of the five, the only attribute that developers will need to configure is the router. +Of the five, the only attribute that application developers need interact with is the `router`: they need to add routes to it so that the REST server can properly handle queries. See the next section for more information on registering routes. ## Registering Routes -To include routes for each module in an application, the CLI must have some kind of function to Register Routes in its REST Server. This `RegisterRoutes()` function is utilized by the `ServeCommand` and must include routes for each of the application's modules. Since each module used by an SDK application implements a [`RegisterRESTRoutes`](../building-modules.md/module-interfaces.md#rest) function, application developers simply use the Module Manager to call this function for each module. +To include routes for each module in an application, the CLI must have some kind of function to register routes in its REST Server. This function is called `RegisterRoutes()`, and is utilized by the `ServeCommand` and must include routes for each of the application's modules. Since each module used by an SDK application implements a [`RegisterRESTRoutes`](../building-modules/module-interfaces.md#rest) function, application developers simply use the [Module Manager](../building-modules/module-manager.md) to call this function for each module (this is done in the [application's constructor](../basics/app-anatomy.md#constructor-function)). -At the bare minimum, a `RegisterRoutes()` function should use the SDK client package `RegisterRoutes()` function to be able to route RPC calls, and instruct the application Module Manager to call `RegisterRESTRoutes()` for all of its modules: +At the bare minimum, a `RegisterRoutes()` function should use the SDK client package `RegisterRoutes()` function to be able to route RPC calls, and instruct the application Module Manager to call `RegisterRESTRoutes()` for all of its modules. This is done in the `main.go` file of the CLI (typically located in `./cmd/appcli/main.go`). ```go func registerRoutes(rs *lcd.RestServer) { diff --git a/docs/interfaces/service-providers.md b/docs/interfaces/service-providers.md deleted file mode 100644 index cc6280a2ac87..000000000000 --- a/docs/interfaces/service-providers.md +++ /dev/null @@ -1,195 +0,0 @@ -# Service Providers - -We define 'service providers' as entities providing services for end-users that involve some form of interaction with a Cosmos-SDK based blockchain (this includes the Cosmos Hub). More specifically, this document will be focused around interactions with tokens. - -This section does not concern wallet builders that want to provide [Light-Client](https://github.com/cosmos/cosmos-sdk/tree/master/docs/interfaces/lite) functionalities. Service providers are expected to act as trusted point of contact to the blockchain for their end-users. - -## High-level description of the architecture - -There are three main pieces to consider: - -- Full-nodes: To interact with the blockchain. -- Rest Server: This acts as a relayer for HTTP calls. -- Rest API: Define available endpoints for the Rest Server. - -## Running a Full-Node - -### Installation and configuration - -We will describe the steps to run and interact with a full-node for the Cosmos Hub. For other SDK-based blockchain, the process should be similar. - -First, you need to [install the software](../cosmos-hub/installation.md). - -Then, you can start [running a full-node](../cosmos-hub/join-testnet.md). - -### Command-Line interface - -Next you will find a few useful CLI commands to interact with the Full-Node. - -#### Creating a key-pair - -To generate a new key (default secp256k1 elliptic curve): - -```bash -gaiacli keys add -``` - -You will be asked to create a password (at least 8 characters) for this key-pair. This will return the information listed below: - -- `NAME`: Name of your key -- `TYPE`: Type of your key, always `local`. -- `ADDRESS`: Your address. Used to receive funds. -- `PUBKEY`: Your public key. Useful for validators. -- `MNEMONIC`: 24-words phrase. **Save this mnemonic somewhere safe**. It is used to recover your private key in case you forget the password. - -You can see all your available keys by typing: - -```bash -gaiacli keys list -``` - -#### Checking your balance - -After receiving tokens to your address, you can view your account's balance by typing: - -```bash -gaiacli account -``` - -*Note: When you query an account balance with zero tokens, you will get this error: No account with address was found in the state. This is expected! We're working on improving our error messages.* - -#### Sending coins via the CLI - -Here is the command to send coins via the CLI: - -```bash -gaiacli tx send \ - --chain-id= -``` - -Parameters: - -- ``: Key name or address of sending account. -- ``: Address of the recipient. -- ``: This parameter accepts the format ``, such as `10faucetToken`. - -Flags: - -- `--chain-id`: This flag allows you to specify the id of the chain. There will be different ids for different testnet chains and main chain. - -#### Help - -If you need to do something else, the best command you can run is: - -```bash -gaiacli -``` - -It will display all the available commands. For each command, you can use the `--help` flag to get further information. - -## Setting up the Rest Server - -The Rest Server acts as an intermediary between the front-end and the full-node. You don't need to run the Rest Server on the same machine as the full-node. - -To start the Rest server: - -```bash -gaiacli rest-server --node= -``` - -Flags: -- `--trust-node`: A boolean. If `true`, light-client verification is disabled. If `false`, it is disabled. For service providers, this should be set to `true`. By default, it set to `true`. -- `--node`: This is where you indicate the address and the port of your full-node. The format is ``. If the full-node is on the same machine, the address should be `tcp://localhost:26657`. -- `--laddr`: This flag allows you to specify the address and port for the Rest Server (default `1317`). You will mostly use this flag only to specify the port, in which case just input "localhost" for the address. The format is . - - -### Listening for incoming transaction - -The recommended way to listen for incoming transaction is to periodically query the blockchain through the following endpoint of the LCD: - -[`/bank/balance/{address}`](https://cosmos.network/rpc/#/ICS20/get_bank_balances__address_) - -## Rest API - -The Rest API documents all the available endpoints that you can use to interact -with your full node. It can be found [here](https://cosmos.network/rpc/). - -The API is divided into ICS standards for each category of endpoints. For -example, the [ICS20](https://cosmos.network/rpc/#/ICS20/) describes the API to -interact with tokens. - -To give more flexibility to developers, we have included the ability to -generate unsigned transactions, [sign](https://cosmos.network/rpc/#/ICS20/post_tx_sign) -and [broadcast](https://cosmos.network/rpc/#/ICS20/post_tx_broadcast) them with -different API endpoints. This allows service providers to use their own signing -mechanism for instance. - -In order to generate an unsigned transaction (example with -[coin transfer](https://cosmos.network/rpc/#/ICS20/post_bank_accounts__address__transfers)), -you need to use the field `generate_only` in the body of `base_req`. - -## Cosmos SDK Transaction Signing - -Cosmos SDK transaction signing is a fairly simple process. - -Every Cosmos SDK transaction has a canonical JSON representation. The `gaiacli` -and Stargate REST interfaces provide canonical JSON representations of transactions -and their "broadcast" functions will provide compact Amino (a protobuf-like wire format) -encoding translations. - -Things to know when signing messages: - -The format is as follows - -```json -{ - "account_number": XXX, - "chain_id": XXX, - "fee": XXX, - "sequence": XXX, - "memo": XXX, - "msgs": XXX -} -``` - -The signer must supply `"chain_id"`, `"account number"` and `"sequence number"`. - -The `"fee"`, `"msgs"` and `"memo"` fields will be supplied by the transaction -composer interface. - -The `"account_number"` and `"sequence"` fields can be queried directly from the -blockchain or cached locally. Getting these numbers wrong, along with the chainID, -is a common cause of invalid signature error. You can load the mempool of a full -node or validator with a sequence of uncommitted transactions with incrementing -sequence numbers and it will mostly do the correct thing. - -Before signing, all keys are lexicographically sorted and all white space is -removed from the JSON output. - -The signature encoding is the 64-byte concatenation of ECDSArands (i.e. `r || s`), -where `s` is lexicographically less than its inverse in order to prevent malleability. -This is like Ethereum, but without the extra byte for PubKey recovery, since -Tendermint assumes the PubKey is always provided anyway. - -Signatures and public key examples in a signed transaction: - -``` json -{ - "type": "auth/StdTx", - "value": { - "msg": [...], - "signatures": [ - { - "pub_key": { - "type": "tendermint/PubKeySecp256k1", - "value": XXX - }, - "signature": XXX - } - ], - } -} -``` - -Once signatures are properly generated, insert the JSON into into the generated -transaction and then use the broadcast endpoint. diff --git a/docs/intro/README.md b/docs/intro/README.md new file mode 100644 index 000000000000..3657cf102999 --- /dev/null +++ b/docs/intro/README.md @@ -0,0 +1,15 @@ +--- +parent: + order: 1 +--- + +# SDK - Intro Material + +This folder contains introduction material on the Cosmos SDK. + +1. [SDK Introduction](./intro.md) +2. [Application-Specific Blockchains](./why-app-specific.md) +3. [Architecture of an SDK Application](./sdk-app-architecture.md) +4. [Cosmos SDK Design Overview](./sdk-design.md) + +After reading the introduction material, head over to the [basics](../basics/README.md) to learn more. \ No newline at end of file diff --git a/docs/intro/intro.md b/docs/intro/intro.md index 1b1a6ff7ddd6..d530ae3c1892 100644 --- a/docs/intro/intro.md +++ b/docs/intro/intro.md @@ -8,7 +8,7 @@ order: 1 The [Cosmos-SDK](https://github.com/cosmos/cosmos-sdk) is an open-source framework for building multi-asset public Proof-of-Stake (PoS) blockchains, like the Cosmos Hub, as well as permissioned Proof-Of-Authority (PoA) blockchains. Blockchains built with the Cosmos SDK are generally referred to as **application-specific blockchains**. -The goal of the Cosmos SDK is to allow developers to easily create custom blockchains from scratch that can natively interoperate with other blockchains. We envision the SDK as the npm-like framework to build secure blockchain applications on top of [Tendermint](https://github.com/tendermint/tendermint). SDK-based blockchains are built out of composable modules, most of which are open source and readily available for any developers to use. Anyone can create a module for the Cosmos-SDK, and integrating already-built modules is as simple as importing them into your blockchain application. What's more, the Cosmos SDK is a capabilities-based system, which allows developers to better reason about the security of interactions between modules. For a deeper look at capabilities, jump to [this section](./ocap.md). +The goal of the Cosmos SDK is to allow developers to easily create custom blockchains from scratch that can natively interoperate with other blockchains. We envision the SDK as the npm-like framework to build secure blockchain applications on top of [Tendermint](https://github.com/tendermint/tendermint). SDK-based blockchains are built out of composable [modules](../building-modules/intro.md), most of which are open source and readily available for any developers to use. Anyone can create a module for the Cosmos-SDK, and integrating already-built modules is as simple as importing them into your blockchain application. What's more, the Cosmos SDK is a capabilities-based system, which allows developers to better reason about the security of interactions between modules. For a deeper look at capabilities, jump to [this section](../core/ocap.md). ## What are Application-Specific Blockchains? @@ -23,11 +23,15 @@ To learn more about application-specific blockchains, [click here](./why-app-spe The Cosmos SDK is the most advanced framework for building custom application-specific blockchains today. Here are a few reasons why you might want to consider building your decentralised application with the Cosmos SDK: - The default consensus engine available within the SDK is [Tendermint Core](https://github.com/tendermint/tendermint). Tendermint is the most (and only) mature BFT consensus engine in existence. It is widely used across the industry and is considered the gold standard consensus engine for building Proof-of-Stake systems. -- The SDK is open source and designed to make it easy to build blockchains out of composable modules. As the ecosystem of open source SDK modules grow, it will become increasingly easier to build complex decentralised platforms with it. +- The SDK is open source and designed to make it easy to build blockchains out of composable modules. As the ecosystem of open source SDK modules grows, it will become increasingly easier to build complex decentralised platforms with it. - The SDK is inspired by capabilities-based security, and informed by years of wrestling with blockchain state-machines. This makes the Cosmos SDK a very secure environment to build blockchains. - Most importantly, the Cosmos SDK has already been used to build many application-specific blockchains that are already in production. Among others, we can cite [Cosmos Hub](https://hub.cosmos.network), [IRIS Hub](https://irisnet.org), [Binance Chain](https://docs.binance.org/), [Terra](https://terra.money/) or [Lino](https://lino.network/). Many more are building on the Cosmos SDK. You can get a view of the ecosystem [here](https://cosmos.network/ecosystem). ## Getting started with the Cosmos SDK - Learn more about the [architecture of an SDK application](./sdk-app-architecture.md) -- Learn how to build an application-specific blockchain from scratch with the [SDK Tutorial](https://cosmos.network/docs/tutorial) \ No newline at end of file +- Learn how to build an application-specific blockchain from scratch with the [SDK Tutorial](https://cosmos.network/docs/tutorial) + +## Next + +Learn about [application-specific blockchains](./why-app-specific.md). \ No newline at end of file diff --git a/docs/intro/readme.md b/docs/intro/readme.md index 7d93bf5f6f76..3657cf102999 100644 --- a/docs/intro/readme.md +++ b/docs/intro/readme.md @@ -1,6 +1,15 @@ --- -order: false parent: - title: Introduction order: 1 --- + +# SDK - Intro Material + +This folder contains introduction material on the Cosmos SDK. + +1. [SDK Introduction](./intro.md) +2. [Application-Specific Blockchains](./why-app-specific.md) +3. [Architecture of an SDK Application](./sdk-app-architecture.md) +4. [Cosmos SDK Design Overview](./sdk-design.md) + +After reading the introduction material, head over to the [basics](../basics/README.md) to learn more. \ No newline at end of file diff --git a/docs/intro/sdk-app-architecture.md b/docs/intro/sdk-app-architecture.md index 9ec8ad0a2f9d..4a52d80c3c43 100644 --- a/docs/intro/sdk-app-architecture.md +++ b/docs/intro/sdk-app-architecture.md @@ -30,13 +30,13 @@ In practice, the transactions are bundled in blocks to make the process more eff +--------+ +--------+ ``` -In a blockchain context, the state machine is deterministic. This means that if you start at a given state and replay the same sequence of transactions, you will always end up with the same final state. +In a blockchain context, the state machine is deterministic. This means that if a node is started at a given state and replays the same sequence of transactions, it will always end up with the same final state. -The Cosmos SDK gives you maximum flexibility to define the state of your application, transaction types and state transition functions. The process of building the state-machine with the SDK will be described more in depth in the following sections. But first, let us see how it is replicated using **Tendermint**. +The Cosmos SDK gives developers maximum flexibility to define the state of their application, transaction types and state transition functions. The process of building state-machines with the SDK will be described more in depth in the following sections. But first, let us see how the state-machine is replicated using **Tendermint**. -### Tendermint +## Tendermint -As a developer, you just have to define the state machine using the Cosmos-SDK, and [*Tendermint*](https://tendermint.com/docs/introduction/what-is-tendermint.html) will handle replication over the network for you. +Thanks to the Cosmos SDK, develepers just have to define the state machine, and [*Tendermint*](https://tendermint.com/docs/introduction/what-is-tendermint.html) will handle replication over the network for them. ``` @@ -56,16 +56,13 @@ Blockchain node | | Consensus | | ``` -Tendermint is an application-agnostic engine that is responsible for handling the *networking* and *consensus* layers of your blockchain. In practice, this means that Tendermint is responsible for propagating and ordering transaction bytes. Tendermint Core relies on an eponymous Byzantine-Fault-Tolerant (BFT) algorithm to reach consensus on the order of transactions. For more on Tendermint, click [here](https://tendermint.com/docs/introduction/what-is-tendermint.html). +Tendermint is an application-agnostic engine that is responsible for handling the *networking* and *consensus* layers of a blockchain. In practice, this means that Tendermint is responsible for propagating and ordering transaction bytes. Tendermint Core relies on an eponymous Byzantine-Fault-Tolerant (BFT) algorithm to reach consensus on the order of transactions. For more on Tendermint, click [here](https://tendermint.com/docs/introduction/what-is-tendermint.html). The Tendermint consensus algorithm works with a set of special nodes called *Validators*. Validators are responsible for adding blocks of transactions to the blockchain. At any given block, there is a validator set V. A validator in V is chosen by the algorithm to be the proposer of the next block. This block is considered valid if more than two thirds of V signed a *[prevote](https://tendermint.com/docs/spec/consensus/consensus.html#prevote-step-height-h-round-r)* and a *[precommit](https://tendermint.com/docs/spec/consensus/consensus.html#precommit-step-height-h-round-r)* on it, and if all the transactions that it contains are valid. The validator set can be changed by rules written in the state-machine. For a deeper look at the algorithm, click [here](https://tendermint.com/docs/introduction/what-is-tendermint.html#consensus-overview). - -The main part of a Cosmos SDK application is a blockchain daemon that is run by each node in the network locally. If less than one third of the *validator set* is byzantine (i.e. malicious), then each node should obtain the same result when querying the state at the same time. - ## ABCI -Tendermint passes transactions from the network to the application through an interface called the [ABCI](https://github.com/tendermint/tendermint/tree/bc572217c07b90ad9cee851f193aaa8e9557cbc7/abci), which the application must implement. +Tendermint passes transactions to the application through an interface called the [ABCI](https://github.com/tendermint/tendermint/tree/bc572217c07b90ad9cee851f193aaa8e9557cbc7/abci), which the application must implement. ``` +---------------------+ @@ -89,12 +86,14 @@ Note that **Tendermint only handles transaction bytes**. It has no knowledge of Here are the most important messages of the ABCI: -- `CheckTx`: When a transaction is received by Tendermint Core, it is passed to the application to check if a few basic requirements are met. `CheckTx` is used to protect the mempool of full-nodes against spam. A special handler called the "Ante Handler" is used to execute a series of validation steps such as checking for sufficient fees and validating the signatures. If the check is valid, the transaction is added to the [mempool](https://tendermint.com/docs/spec/reactors/mempool/functionality.html#mempool-functionality) and relayed to peer nodes. Note that transactions are not processed (i.e. no modification of the state occurs) with `CheckTx` since they have not been included in a block yet. -- `DeliverTx`: When a [valid block](https://tendermint.com/docs/spec/blockchain/blockchain.html#validation) is received by Tendermint Core, each transaction in the given block is passed to the application via `DeliverTx` to be processed. It is during this stage that the state transitions occur. The "Ante Handler" executes again along with the actual handlers for each message in the transaction. +- `CheckTx`: When a transaction is received by Tendermint Core, it is passed to the application to check if a few basic requirements are met. `CheckTx` is used to protect the mempool of full-nodes against spam transactions. A special handler called the [`AnteHandler`](../basics/gas-fees.md#antehandler) is used to execute a series of validation steps such as checking for sufficient fees and validating the signatures. If the checks are valid, the transaction is added to the [mempool](https://tendermint.com/docs/spec/reactors/mempool/functionality.html#mempool-functionality) and relayed to peer nodes. Note that transactions are not processed (i.e. no modification of the state occurs) with `CheckTx` since they have not been included in a block yet. +- `DeliverTx`: When a [valid block](https://tendermint.com/docs/spec/blockchain/blockchain.html#validation) is received by Tendermint Core, each transaction in the block is passed to the application via `DeliverTx` in order to be processed. It is during this stage that the state transitions occur. The `AnteHandler` executes again along with the actual [`handler`s](../building-modules/handler.md) for each message in the transaction. - `BeginBlock`/`EndBlock`: These messages are executed at the beginning and the end of each block, whether the block contains transaction or not. It is useful to trigger automatic execution of logic. Proceed with caution though, as computationally expensive loops could slow down your blockchain, or even freeze it if the loop is infinite. For a more detailed view of the ABCI methods and types, click [here](https://tendermint.com/docs/spec/abci/abci.html#overview). Any application built on Tendermint needs to implement the ABCI interface in order to communicate with the underlying local Tendermint engine. Fortunately, you do not have to implement the ABCI interface. The Cosmos SDK provides a boilerplate implementation of it in the form of [baseapp](./sdk-design.md#baseapp). -### Next, let us go into the [high-level design principles of the SDK](./sdk-design.md) \ No newline at end of file +## Next + +Read about the [high-level design principles of the SDK](./sdk-design.md) \ No newline at end of file diff --git a/docs/intro/sdk-design.md b/docs/intro/sdk-design.md index bab16940fe69..544644061bad 100644 --- a/docs/intro/sdk-design.md +++ b/docs/intro/sdk-design.md @@ -4,7 +4,7 @@ order: 4 # Cosmos SDK design overview -The Cosmos SDK is a framework that facilitates the development of secure state-machines on top of Tendermint. At its core, the SDK is a boilerplate implementation of the ABCI in Golang. It comes with a `multistore` to persist data and a `router` to handle transactions. +The Cosmos SDK is a framework that facilitates the development of secure state-machines on top of Tendermint. At its core, the SDK is a boilerplate implementation of the [ABCI](./sdk-app-architecture.md#abci) in Golang. It comes with a [`multistore`](../core/store.md#multistore) to persist data and a [`router`](../core/baseapp.md#routing) to handle transactions. Here is a simplified view of how transactions are handled by an application built on top of the Cosmos SDK when transferred from Tendermint via `DeliverTx`: @@ -13,21 +13,19 @@ Here is a simplified view of how transactions are handled by an application buil 3. Route each message to the appropriate module so that it can be processed. 4. Commit state changes. -The application also enables you to generate transactions, encode them and pass them to the underlying Tendermint engine to broadcast them. - ## `baseapp` -`baseApp` is the boilerplate implementation of the ABCI of the Cosmos SDK. It comes with a `router` to route transactions to their respective module. The main `app.go` file of your application will define your custom `app` type that will embed `baseapp`. This way, your custom `app` type will automatically inherit all the ABCI methods of `baseapp`. See an example of this in the [SDK application tutorial](https://github.com/cosmos/sdk-application-tutorial/blob/c6754a1e313eb1ed973c5c91dcc606f2fd288811/app.go#L27). +`baseapp` is the boilerplate implementation of a Cosmos SDK application. It comes with an implementation of the ABCI to handle the connexion with the underlying consensus engine. Typically, a Cosmos SDK application extends `baseapp` by embedding it in [`app.go`](../basics/app-anatomy.md#core-application-file). See an example of this from the [SDK application tutorial](https://github.com/cosmos/sdk-application-tutorial/blob/c6754a1e313eb1ed973c5c91dcc606f2fd288811/app.go#L27). The goal of `baseapp` is to provide a secure interface between the store and the extensible state machine while defining as little about the state machine as possible (staying true to the ABCI). -For more on `baseapp`, please click [here](../concepts/baseapp.md). +For more on `baseapp`, please click [here](../core/baseapp.md). ## Multistore - The Cosmos SDK provides a multistore for persisting state. The multistore allows developers to declare any number of [`KVStores`](../core/store.md#base-layer-kvstores). These `KVStores` only accept the `[]byte` type as value and therefore any custom structure needs to be marshalled using [go-amino](https://github.com/tendermint/go-amino) before being stored. + The Cosmos SDK provides a [`multistore`](../core/store.md#multisotre) for persisting state. The multistore allows developers to declare any number of [`KVStores`](../core/store.md#base-layer-kvstores). These `KVStores` only accept the `[]byte` type as value and therefore any custom structure needs to be marshalled using [a codec](../core/encoding.md) before being stored. -The multistore abstraction is used to divide the state in distinct compartments, each managed by its own module. For more on the multistore, click [here](../concepts/store.md) +The multistore abstraction is used to divide the state in distinct compartments, each managed by its own module. For more on the multistore, click [here](../core/store.md#multistore) ## Modules @@ -80,7 +78,7 @@ Here is a simplified view of how a transaction is processed by the application o v ``` -Each module can be seen as a little state-machine. Developers need to define the subset of the state handled by the module, as well as custom message types that modify the state (*Note:* `messages` are extracted from `transactions` using `baseapp`). In general, each module declares its own `KVStore` in the multistore to persist the subset of the state it defines. Most developers will need to access other 3rd party modules when building their own modules. Given that the Cosmos-SDK is an open framework, some of the modules may be malicious, which means there is a need for security principles to reason about inter-module interactions. These principles are based on [object-capabilities](../coore/ocap.md). In practice, this means that instead of having each module keep an access control list for other modules, each module implements special objects called `keepers` that can be passed to other modules to grant a pre-defined set of capabilities. +Each module can be seen as a little state-machine. Developers need to define the subset of the state handled by the module, as well as custom message types that modify the state (*Note:* `messages` are extracted from `transactions` by `baseapp`). In general, each module declares its own `KVStore` in the `multistore` to persist the subset of the state it defines. Most developers will need to access other 3rd party modules when building their own modules. Given that the Cosmos-SDK is an open framework, some of the modules may be malicious, which means there is a need for security principles to reason about inter-module interactions. These principles are based on [object-capabilities](../core/ocap.md). In practice, this means that instead of having each module keep an access control list for other modules, each module implements special objects called `keepers` that can be passed to other modules to grant a pre-defined set of capabilities. SDK modules are defined in the `x/` folder of the SDK. Some core modules include: @@ -91,4 +89,6 @@ SDK modules are defined in the `x/` folder of the SDK. Some core modules include In addition to the already existing modules in `x/`, that anyone can use in their app, the SDK lets you build your own custom modules. You can check an [example of that in the tutorial](https://cosmos.network/docs/tutorial/keeper.html). -### Next, learn more about the security model of the Cosmos SDK, [ocap](./ocap.md) +## Next + +Learn more about the basics of the Cosmos SDK, starting with the [anatomy of an SDK application](../basics/app-anatomy.md) diff --git a/docs/intro/why-app-specific.md b/docs/intro/why-app-specific.md index 54f1169d0071..c4be10289add 100644 --- a/docs/intro/why-app-specific.md +++ b/docs/intro/why-app-specific.md @@ -30,11 +30,11 @@ Blockchain node | | Consensus | | Virtual-machine blockchains like Ethereum addressed the demand for more programmability back in 2014. At the time, the options available for building decentralised applications were quite limited. Most developers would build on top of the complex and limited Bitcoin scripting language, or fork the Bitcoin codebase which was hard to work with and customize. -Virtual-machine blockchains came in with a new value proposition. Their state-machine incorporates a virtual-machine that is able to interpret turing-complete programs called Smart Contracts. These Smart Contracts are very good for use cases like one-time events (e.g. ICOs), but they can fall short for building complex decentralised platforms: +Virtual-machine blockchains came in with a new value proposition. Their state-machine incorporates a virtual-machine that is able to interpret turing-complete programs called Smart Contracts. These Smart Contracts are very good for use cases like one-time events (e.g. ICOs), but they can fall short for building complex decentralised platforms. Here is why: -- Smart Contracts are generally developed with specific programming languages that can be interpreted by the underlying virtual-machine. These programming languages are often immature and inherently limited by the constraints of the virtual-machine. For example, the Ethereum Virtual Machine does not allow developers to implement automatic execution of code. Developers are also limited to the account-based system of the EVM, and they can only choose from a limited set of functions for their cryptographic operations. These are examples, but they hint at the lack of **flexibility** a smart contract environment often entails. +- Smart Contracts are generally developed with specific programming languages that can be interpreted by the underlying virtual-machine. These programming languages are often immature and inherently limited by the constraints of the virtual-machine itself. For example, the Ethereum Virtual Machine does not allow developers to implement automatic execution of code. Developers are also limited to the account-based system of the EVM, and they can only choose from a limited set of functions for their cryptographic operations. These are examples, but they hint at the lack of **flexibility** that a smart contract environment often entails. - Smart Contracts are all run by the same virtual machine. This means that they compete for resources, which can severly restrain **performance**. And even if the state-machine were to be split in multiple subsets (e.g. via sharding), Smart Contracts would still need to be interpeted by a virtual machine, which would limit performance compared to a native application implemented at state-machine level (our benchmarks show an improvement on the order of x10 in performance when the virtual-machine is removed). -- Another issue with the fact that Smart Contracts share the same underlying environment is the resulting limitation in **sovereignty**. A decentralised application is an ecosystem that involves multiple players. If the application is built on a general-purpose virtual-machine blockchain, these players have very limited sovereignty over it, and are ultimately superseded by the governance of the underlying blockchain. If there is a bug in the application, very little can be done about it. +- Another issue with the fact that Smart Contracts share the same underlying environment is the resulting limitation in **sovereignty**. A decentralised application is an ecosystem that involves multiple players. If the application is built on a general-purpose virtual-machine blockchain, stakeholders have very limited sovereignty over their application, and are ultimately superseded by the governance of the underlying blockchain. If there is a bug in the application, very little can be done about it. Application-Specific Blockchains are designed to address these shortcomings. @@ -46,7 +46,7 @@ Application-specific blockchains give maximum flexibility to developers: - In Cosmos blockchains, the state-machine is typically connected to the underlying consensus engine via an interface called the [ABCI](https://tendermint.com/docs/spec/abci/). This interface can be wrapped in any programming language, meaning developers can build their state-machine in the programming language of their choice. - Developers can choose among multiple frameworks to build their state-machine. The most widely used today is the Cosmos SDK, but others exist (e.g. [Lotion](https://github.com/nomic-io/lotion), [Weave](https://github.com/iov-one/weave), ...). The choice will most of the time be done based on the programming language they want to use (Cosmos SDK and Weave are in Golang, Lotion is in Javascript, ...). -- The ABCI also allows developers to swap the consensus engine of their application-specific blockchain. Today, only Tendermint is production-ready, but in the future other engines are expected to emerge. +- The ABCI also allows developers to swap the consensus engine of their application-specific blockchain. Today, only Tendermint is production-ready, but in the future other consensus engines are expected to emerge. - Even when they settle for a framework and consensus engine, developers still have the freedom to tweak them if they don't perfectly match their requirements in their pristine forms. - Developers are free to explore the full spectrum of tradeoffs (e.g. number of validators vs transaction throughput, safety vs availability in asynchrony, ...) and design choices (DB or IAVL tree for storage, UTXO or account model, ...). - Developers can implement automatic execution of code. In the Cosmos SDK, logic can be automatically triggered at the beginning and the end of each block. They are also free to choose the cryptographic library used in their application, as opposed to being constrained by what is made available by the underlying environment in the case of virtual-machine blockchains. @@ -55,7 +55,7 @@ The list above contains a few examples that show how much flexibility applicatio ### Performance -Decentralised applications built with Smart Contracts are inherently capped in performance by the underlying environment. For a decentralised application to optimise performance, it needs to be built as an application-specific blockchains. Here are the benefits of an application-specific blockchains with regards to performance: +Decentralised applications built with Smart Contracts are inherently capped in performance by the underlying environment. For a decentralised application to optimise performance, it needs to be built as an application-specific blockchains. Next are some of the benefits an application-specific blockchains brings in terms of performance: - Developers of application-specific blockchains can choose to operate with novel consensus engine such as Tendermint BFT. Compared to Proof-of-Work (used by most virtual-machine blockchains today), it offers significant gains in throuhgput. - An application-specific blockchain only operates a single application, so that the application does not compete with others for computation and storage. This is the opposite of most non-sharded virtual-machine blockchains today, where smart contracts all compete for computation and storage. @@ -71,13 +71,10 @@ Security is hard to quantify, and greatly varies from platform to platform. That ### Sovereignty -One of the major benefits of application-specific blockchains is sovereignty. A decentralised application is an ecosystem that involves many actors: users, developers, third-party services, and more. When developers build on virtual-machine blockchain where many decentralised applications coexist, the community of the application is different than the community of the underlying blockchain, and the latter supersedes the former. If there is a bug or if a new feature is needed, the community of the application has very little sovereignty to upgrade the code. If the community of the underlying blockchain refuses to act, nothing can happen. +One of the major benefits of application-specific blockchains is sovereignty. A decentralised application is an ecosystem that involves many actors: users, developers, third-party services, and more. When developers build on virtual-machine blockchain where many decentralised applications coexist, the community of the application is different than the community of the underlying blockchain, and the latter supersedes the former in the governance process. If there is a bug or if a new feature is needed, stakeholders of the application have very little leeway to upgrade the code. If the community of the underlying blockchain refuses to act, nothing can happen. -The fundamental issue here is that the governance of the application and the governance of the network are not aligned. This issue is solved by application-specific blockchains. Because application-specific blockchains specialize to operate a single application, the community of the application has full control over the entire chain. This ensures the community will not be stuck if a bug is discovered, and that it has the entire freedom to choose how it is going to evolve. +The fundamental issue here is that the governance of the application and the governance of the network are not aligned. This issue is solved by application-specific blockchains. Because application-specific blockchains specialize to operate a single application, stakeholders the application has full control over the entire chain. This ensures the community will not be stuck if a bug is discovered, and that it has the entire freedom to choose how it is going to evolve. -## Start Building Your Application-Specific Blockchain Today +## Next -Clearly, application-specific blockchains are awesome. The Cosmos SDK makes it easier than ever to build them. What are you waiting for? - -- Learn more about the [high-level architecture](./sdk-app-architecture) of an SDK application. -- Learn how to build an application-specific blockchain from scratch with the [SDK tutorial](https://cosmos.network/docs/tutorial) +- Learn more about the [high-level architecture](./sdk-app-architecture.md) of an SDK application. diff --git a/docs/modules/readme.md b/docs/modules/readme.md deleted file mode 100644 index f0c07cb68565..000000000000 --- a/docs/modules/readme.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -order: false -parent: - order: false ---- diff --git a/docs/readme.md b/docs/readme.md new file mode 100644 index 000000000000..0a277930bf31 --- /dev/null +++ b/docs/readme.md @@ -0,0 +1,37 @@ +# Cosmos SDK Documentation + +## Get Started + +- **[SDK Intro](./intro/intro.md)**: High-level overview of the Cosmos SDK. +- **[SDK Application Tutorial](https://github.com/cosmos/sdk-application-tutorial)**: A tutorial that showcases how to build an SDK-based blockchain from scratch and explains the basic principles of the SDK in the process. + +## Reference + +- **[Basics](./basics/README.md)**: Documentation on the basic concepts of the Cosmos SDK, like the standard anatomy of an application, the transaction lifecycle and accounts management. +- **[Core](./core/README.md)**: Documentation on the core concepts of the Cosmos SDK, like `baseapp`, the `store` or the `server`. +- **[Building Modules](./building-modules/README.md)**: Important concepts for module developers like `message`s, `keeper`s, `handler`s and `querier`s. +- **[Interfaces](./interfaces/README.md)**: Documentation on building interfaces for Cosmos SDK applications. + +## Other Resources + +- **[Module Directory](../x/README.md)**: Module implementations and their respective documentation. +- **[Specifications](./spec/README.md)**: Specifications of modules and other parts of the Cosmos SDK. +- **[SDK API Reference](https://godoc.org/github.com/cosmos/cosmos-sdk)**: Godocs of the Cosmos SDK. +- **[REST API spec](https://cosmos.network/rpc/)**: List of endpoints to interact with a `gaia` full-node through REST. + +## Cosmos Hub + +The Cosmos Hub (`gaia`) docs have moved [here](https://github.com/cosmos/gaia/tree/master/docs). + +## Languages + +The Cosmos-SDK is currently written in [Golang](https://golang.org/), though the +framework could be implemented similarly in other languages. +Contact us for information about funding an implementation in another language. + +## Contribute + +See [this file](https://github.com/cosmos/cosmos-sdk/blob/master/docs/DOCS_README.md) for details of the build process and +considerations when making changes. + + diff --git a/docs/spec/README.md b/docs/spec/README.md index 8c3f0cbc6502..2ee241f55f44 100644 --- a/docs/spec/README.md +++ b/docs/spec/README.md @@ -18,17 +18,9 @@ block. ## Modules specifications -- [Auth](../../x/authspec) - The structure and authentication of accounts and transactions. -- [Bank](../../x/bank/spec) - Sending tokens. -- [Governance](../../x/governance/spec) - Proposals and voting. -- [Staking](../../x/staking/spec) - Proof-of-stake bonding, delegation, etc. -- [Slashing](../../x/slashing/spec) - Validator punishment mechanisms. -- [Distribution](../../x/distribution/spec) - Fee distribution, and staking token provision distribution. -- [Crisis](.../../x/crisis/spec) - Halting the blockchain under certain circumstances. -- [Mint](../../x/mint/spec) - Staking token provision creation. -- [Params](../../x/params/spec) - Globally available parameter store. -- [Supply](../../x/supply/spec) - Total supply of the chain. -- [NFT](https://github.com/cosmos/modules/tree/master/incubator/nft/docs/spec) - Non-fungible tokens. +Go the [module directory](../x/README.md) + +## Tendermint For details on the underlying blockchain and p2p protocols, see the [Tendermint specification](https://github.com/tendermint/tendermint/tree/master/docs/spec). diff --git a/docs/using-the-sdk/README.md b/docs/using-the-sdk/README.md new file mode 100644 index 000000000000..a3b9882a5737 --- /dev/null +++ b/docs/using-the-sdk/README.md @@ -0,0 +1,10 @@ +--- +parent: + order: false +--- + +# Using the SDK + +- [Modules](../x/README.md) +- [Simulation](./simulation.md) + diff --git a/docs/concepts/using-the-sdk/simulation.md b/docs/using-the-sdk/simulation.md similarity index 100% rename from docs/concepts/using-the-sdk/simulation.md rename to docs/using-the-sdk/simulation.md diff --git a/x/README.md b/x/README.md new file mode 100644 index 000000000000..b81ce0e306d6 --- /dev/null +++ b/x/README.md @@ -0,0 +1,17 @@ +# Modules + +This repository contains a working implementation of modules that can be used in Cosmos SDK applications, along with their respective documentation. + +- [Auth](./x/auth/spec/README.md) - Authentication of accounts and transactions for Cosmos SDK application. +- [Bank](./x/bank/spec/README.md) - Token transfer functionalities. +- [Governance](./x/gov/spec/README.md) - On-chain proposals and voting. +- [Staking](./x/staking/spec/README.md) - Proof-of-stake layer for public blockchains. +- [Slashing](.x/slashing/spec/README.md) - Validator punishment mechanisms. +- [Distribution](.x/distribution/spec/README.md) - Fee distribution, and staking token provision distribution. +- [Crisis](./x/crisis/spec/README.md) - Halting the blockchain under certain circumstances (e.g. if an invariant is broken). +- [Mint](./x/mint/spec/README.md) - Creation of new units of staking token. +- [Params](./x/params/spec/README.md) - Globally available parameter store. +- [Supply](./x/supply/spec/README.md) - Total token supply of the chain. + +To learn more about the process of building modules, visit the [building modules reference documentation](../docs/building-modules/README.md). + diff --git a/x/auth/spec/README.md b/x/auth/spec/README.md index 1e57a39c095e..8dd0a2dd2209 100644 --- a/x/auth/spec/README.md +++ b/x/auth/spec/README.md @@ -1,4 +1,4 @@ -# Auth module specification +# `auth` ## Abstract diff --git a/x/bank/spec/README.md b/x/bank/spec/README.md index f4c583af98b6..1f5ad958a915 100644 --- a/x/bank/spec/README.md +++ b/x/bank/spec/README.md @@ -1,4 +1,4 @@ -# Bank module specification +# `bank` ## Abstract diff --git a/x/crisis/spec/README.md b/x/crisis/spec/README.md index 6fae6fe52e0f..48847155135a 100644 --- a/x/crisis/spec/README.md +++ b/x/crisis/spec/README.md @@ -1,4 +1,4 @@ -# Crisis +# `crisis` ## Overview diff --git a/x/distribution/spec/README.md b/x/distribution/spec/README.md index cf306c4e45e5..7540bcd8997f 100644 --- a/x/distribution/spec/README.md +++ b/x/distribution/spec/README.md @@ -1,4 +1,4 @@ -# Distribution +# `distribution` ## Overview diff --git a/x/gov/spec/README.md b/x/gov/spec/README.md index 5f9ebc31ca35..8276fa72ba2a 100644 --- a/x/gov/spec/README.md +++ b/x/gov/spec/README.md @@ -1,4 +1,4 @@ -# Governance module specification +# `gov` ## Abstract diff --git a/x/mint/spec/README.md b/x/mint/spec/README.md index b7e0ef9e065d..b4d9a1ddc86b 100644 --- a/x/mint/spec/README.md +++ b/x/mint/spec/README.md @@ -1,4 +1,4 @@ -# Mint Specification +# `mint` ## Contents diff --git a/x/params/spec/README.md b/x/params/spec/README.md index a7728e8680e8..503e6b51d24d 100644 --- a/x/params/spec/README.md +++ b/x/params/spec/README.md @@ -1,4 +1,4 @@ -# Params module specification +# `params` ## Abstract diff --git a/x/slashing/spec/README.md b/x/slashing/spec/README.md index fbcb704fff6f..195c8c7a0ba6 100644 --- a/x/slashing/spec/README.md +++ b/x/slashing/spec/README.md @@ -1,4 +1,4 @@ -# Slashing module specification +# `slashing` ## Abstract diff --git a/x/staking/spec/README.md b/x/staking/spec/README.md index a34274b7a112..9e4a9a99e677 100644 --- a/x/staking/spec/README.md +++ b/x/staking/spec/README.md @@ -1,4 +1,4 @@ -# Staking module specification +# `staking` ## Abstract diff --git a/x/supply/spec/README.md b/x/supply/spec/README.md index e637bc013187..d9ef2b1075d9 100644 --- a/x/supply/spec/README.md +++ b/x/supply/spec/README.md @@ -1,4 +1,4 @@ -# Supply Specification +# `supply` ## Contents From 834e14ba73982d93f7c63785a76216a577f92329 Mon Sep 17 00:00:00 2001 From: gamarin Date: Sat, 2 Nov 2019 22:49:29 +0100 Subject: [PATCH 130/196] fix links --- README.md | 2 +- docs/readme.md | 12 ++++++------ 2 files changed, 7 insertions(+), 7 deletions(-) diff --git a/README.md b/README.md index b239968141dc..6a9b409f6f46 100644 --- a/README.md +++ b/README.md @@ -25,7 +25,7 @@ To learn how the SDK works from a high-level perspective, go to the [SDK Intro]( If you want to get started quickly and learn how to build on top of the SDK, please follow the [SDK Application Tutorial](https://github.com/cosmos/sdk-application-tutorial). You can also fork the tutorial's repository to get started building your own Cosmos SDK application. -For more, please go to the [Cosmos SDK Docs](./docs/README.md). +For more, please go to the [Cosmos SDK Docs](./docs/). ## Cosmos Hub Mainnet diff --git a/docs/readme.md b/docs/readme.md index 0a277930bf31..036e73eab884 100644 --- a/docs/readme.md +++ b/docs/readme.md @@ -7,15 +7,15 @@ ## Reference -- **[Basics](./basics/README.md)**: Documentation on the basic concepts of the Cosmos SDK, like the standard anatomy of an application, the transaction lifecycle and accounts management. -- **[Core](./core/README.md)**: Documentation on the core concepts of the Cosmos SDK, like `baseapp`, the `store` or the `server`. -- **[Building Modules](./building-modules/README.md)**: Important concepts for module developers like `message`s, `keeper`s, `handler`s and `querier`s. -- **[Interfaces](./interfaces/README.md)**: Documentation on building interfaces for Cosmos SDK applications. +- **[Basics](./basics/)**: Documentation on the basic concepts of the Cosmos SDK, like the standard anatomy of an application, the transaction lifecycle and accounts management. +- **[Core](./core/)**: Documentation on the core concepts of the Cosmos SDK, like `baseapp`, the `store` or the `server`. +- **[Building Modules](./building-modules/)**: Important concepts for module developers like `message`s, `keeper`s, `handler`s and `querier`s. +- **[Interfaces](./interfaces/)**: Documentation on building interfaces for Cosmos SDK applications. ## Other Resources -- **[Module Directory](../x/README.md)**: Module implementations and their respective documentation. -- **[Specifications](./spec/README.md)**: Specifications of modules and other parts of the Cosmos SDK. +- **[Module Directory](../x/)**: Module implementations and their respective documentation. +- **[Specifications](./spec/)**: Specifications of modules and other parts of the Cosmos SDK. - **[SDK API Reference](https://godoc.org/github.com/cosmos/cosmos-sdk)**: Godocs of the Cosmos SDK. - **[REST API spec](https://cosmos.network/rpc/)**: List of endpoints to interact with a `gaia` full-node through REST. From 2b418b520e3415370566d8b9f54dc7f1b896af08 Mon Sep 17 00:00:00 2001 From: gamarin2 Date: Sat, 2 Nov 2019 23:06:19 +0100 Subject: [PATCH 131/196] remove dup --- docs/basics/readme.md | 16 ---------------- 1 file changed, 16 deletions(-) delete mode 100644 docs/basics/readme.md diff --git a/docs/basics/readme.md b/docs/basics/readme.md deleted file mode 100644 index c2e3e519fe76..000000000000 --- a/docs/basics/readme.md +++ /dev/null @@ -1,16 +0,0 @@ ---- -order: false -parent: - order: 2 ---- - -# Basics - -This repository contains reference documentation on the basic concepts of the Cosmos SDK. - -1. [Anatomy of an SDK Application](./app-anatomy.md) -2. [Lifecycle of a transaction](./tx-lifecycle.md) -3. [Accounts](./accounts.md) -4. [Gas and Fees](./gas-fees.md) - -After reading the basics, head on to the [Core Reference](../core/README.md) for more advanced material. \ No newline at end of file From 4521f3c436429b8cf054f34c6aa430a4ba4916a6 Mon Sep 17 00:00:00 2001 From: gamarin2 Date: Sat, 2 Nov 2019 23:06:48 +0100 Subject: [PATCH 132/196] remove dup --- docs/core/readme.md | 20 -------------------- 1 file changed, 20 deletions(-) delete mode 100644 docs/core/readme.md diff --git a/docs/core/readme.md b/docs/core/readme.md deleted file mode 100644 index 8d9348350932..000000000000 --- a/docs/core/readme.md +++ /dev/null @@ -1,20 +0,0 @@ ---- -order: false -parent: - order: 3 ---- - -# Core - -This repository contains reference documentation on the core conepts of the Cosmos SDK. - -1. [`Baseapp`](./baseapp.md) -2. [Transaction](./transactions.md) -3. [Context](./context.md) -4. [Node Client](./node.md) -5. [Store](./store.md) -6. [Encoding](./encoding.md) -7. [Events](./events.md) -8. [Object-Capabilities](./ocap.md) - -After reading about the core concepts, head on to the [Building Modules documentation](../building-modules/README.md) to learn more about the process of building modules. \ No newline at end of file From b97e615a61f0d07e6907c6765875490df972ea98 Mon Sep 17 00:00:00 2001 From: gamarin2 Date: Sat, 2 Nov 2019 23:07:08 +0100 Subject: [PATCH 133/196] remove dup --- docs/interfaces/readme.md | 15 --------------- 1 file changed, 15 deletions(-) delete mode 100644 docs/interfaces/readme.md diff --git a/docs/interfaces/readme.md b/docs/interfaces/readme.md deleted file mode 100644 index 0e23c0478ae7..000000000000 --- a/docs/interfaces/readme.md +++ /dev/null @@ -1,15 +0,0 @@ ---- -order: false -parent: - order: 5 ---- - -# Interfaces - -This repository contains documentation on interfaces for Cosmos SDK applications. - -1. [Introduction to Interaces](./interfaces-intro.md) -2. [Lifecycle of a Query](./query-lifecycle.md) -3. [Command-Line Interface](./cli.md) -4. [Rest Interface](./rest.md) - From f1cc432d86e013f41e20e2ab61f041d18c475903 Mon Sep 17 00:00:00 2001 From: gamarin2 Date: Sat, 2 Nov 2019 23:07:30 +0100 Subject: [PATCH 134/196] remove dup --- docs/intro/readme.md | 15 --------------- 1 file changed, 15 deletions(-) delete mode 100644 docs/intro/readme.md diff --git a/docs/intro/readme.md b/docs/intro/readme.md deleted file mode 100644 index 3657cf102999..000000000000 --- a/docs/intro/readme.md +++ /dev/null @@ -1,15 +0,0 @@ ---- -parent: - order: 1 ---- - -# SDK - Intro Material - -This folder contains introduction material on the Cosmos SDK. - -1. [SDK Introduction](./intro.md) -2. [Application-Specific Blockchains](./why-app-specific.md) -3. [Architecture of an SDK Application](./sdk-app-architecture.md) -4. [Cosmos SDK Design Overview](./sdk-design.md) - -After reading the introduction material, head over to the [basics](../basics/README.md) to learn more. \ No newline at end of file From f1ea40c7462d84033e3bcebcba4a3b9c62d1b6c7 Mon Sep 17 00:00:00 2001 From: gamarin2 Date: Sat, 2 Nov 2019 23:07:52 +0100 Subject: [PATCH 135/196] remove dup --- docs/readme.md | 37 ------------------------------------- 1 file changed, 37 deletions(-) delete mode 100644 docs/readme.md diff --git a/docs/readme.md b/docs/readme.md deleted file mode 100644 index 036e73eab884..000000000000 --- a/docs/readme.md +++ /dev/null @@ -1,37 +0,0 @@ -# Cosmos SDK Documentation - -## Get Started - -- **[SDK Intro](./intro/intro.md)**: High-level overview of the Cosmos SDK. -- **[SDK Application Tutorial](https://github.com/cosmos/sdk-application-tutorial)**: A tutorial that showcases how to build an SDK-based blockchain from scratch and explains the basic principles of the SDK in the process. - -## Reference - -- **[Basics](./basics/)**: Documentation on the basic concepts of the Cosmos SDK, like the standard anatomy of an application, the transaction lifecycle and accounts management. -- **[Core](./core/)**: Documentation on the core concepts of the Cosmos SDK, like `baseapp`, the `store` or the `server`. -- **[Building Modules](./building-modules/)**: Important concepts for module developers like `message`s, `keeper`s, `handler`s and `querier`s. -- **[Interfaces](./interfaces/)**: Documentation on building interfaces for Cosmos SDK applications. - -## Other Resources - -- **[Module Directory](../x/)**: Module implementations and their respective documentation. -- **[Specifications](./spec/)**: Specifications of modules and other parts of the Cosmos SDK. -- **[SDK API Reference](https://godoc.org/github.com/cosmos/cosmos-sdk)**: Godocs of the Cosmos SDK. -- **[REST API spec](https://cosmos.network/rpc/)**: List of endpoints to interact with a `gaia` full-node through REST. - -## Cosmos Hub - -The Cosmos Hub (`gaia`) docs have moved [here](https://github.com/cosmos/gaia/tree/master/docs). - -## Languages - -The Cosmos-SDK is currently written in [Golang](https://golang.org/), though the -framework could be implemented similarly in other languages. -Contact us for information about funding an implementation in another language. - -## Contribute - -See [this file](https://github.com/cosmos/cosmos-sdk/blob/master/docs/DOCS_README.md) for details of the build process and -considerations when making changes. - - From 5e4d9e99d3494b724b234dada5fd110d56b24c94 Mon Sep 17 00:00:00 2001 From: gamarin Date: Sat, 2 Nov 2019 23:09:36 +0100 Subject: [PATCH 136/196] fix links --- docs/README.md | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/docs/README.md b/docs/README.md index 0a277930bf31..036e73eab884 100644 --- a/docs/README.md +++ b/docs/README.md @@ -7,15 +7,15 @@ ## Reference -- **[Basics](./basics/README.md)**: Documentation on the basic concepts of the Cosmos SDK, like the standard anatomy of an application, the transaction lifecycle and accounts management. -- **[Core](./core/README.md)**: Documentation on the core concepts of the Cosmos SDK, like `baseapp`, the `store` or the `server`. -- **[Building Modules](./building-modules/README.md)**: Important concepts for module developers like `message`s, `keeper`s, `handler`s and `querier`s. -- **[Interfaces](./interfaces/README.md)**: Documentation on building interfaces for Cosmos SDK applications. +- **[Basics](./basics/)**: Documentation on the basic concepts of the Cosmos SDK, like the standard anatomy of an application, the transaction lifecycle and accounts management. +- **[Core](./core/)**: Documentation on the core concepts of the Cosmos SDK, like `baseapp`, the `store` or the `server`. +- **[Building Modules](./building-modules/)**: Important concepts for module developers like `message`s, `keeper`s, `handler`s and `querier`s. +- **[Interfaces](./interfaces/)**: Documentation on building interfaces for Cosmos SDK applications. ## Other Resources -- **[Module Directory](../x/README.md)**: Module implementations and their respective documentation. -- **[Specifications](./spec/README.md)**: Specifications of modules and other parts of the Cosmos SDK. +- **[Module Directory](../x/)**: Module implementations and their respective documentation. +- **[Specifications](./spec/)**: Specifications of modules and other parts of the Cosmos SDK. - **[SDK API Reference](https://godoc.org/github.com/cosmos/cosmos-sdk)**: Godocs of the Cosmos SDK. - **[REST API spec](https://cosmos.network/rpc/)**: List of endpoints to interact with a `gaia` full-node through REST. From 0103f64775a9464d9d5e272ed965c48f07d37395 Mon Sep 17 00:00:00 2001 From: gamarin Date: Tue, 5 Nov 2019 15:58:01 +0100 Subject: [PATCH 137/196] add subscribe events --- docs/Screen Shot 2019-10-17 at 15.07.22.png | Bin 0 -> 45486 bytes docs/core/events.md | 40 ++++++++++++++++++++ docs/interfaces/rest.md | 14 ++++--- docs/intro/intro.md | 2 +- 4 files changed, 49 insertions(+), 7 deletions(-) create mode 100644 docs/Screen Shot 2019-10-17 at 15.07.22.png diff --git a/docs/Screen Shot 2019-10-17 at 15.07.22.png b/docs/Screen Shot 2019-10-17 at 15.07.22.png new file mode 100644 index 0000000000000000000000000000000000000000..fc823b91ed22ddbb8cecc7e0b596457bebf5a2d6 GIT binary patch literal 45486 zcma%i1yCH#+BF&iB)GdvaCZpq?(XjH?(Vi&f)m``f-bfMg1fuB|Gf8pa;yHTe3|Om zneBPHdmfqY(`R}j739P}!{NYzfq{LNln_w@1A`%ZKezk%;r-X_z7QD<>=U}Bu&{!p zurQH=lf9XxjVTzIL}aQuj7l;PBe%OyNC=jQi2RyDB9Wf$njYUKgzPI7IBHN7zOIS` zU1@}osJaN6ZYoLi=k_|P`6FRuXj5I6fe#~DXp=XMSEpPYS347(?p-`@W7*hXDK-n9 zo(rYSU|c~yhA!V2SeU3YB@aJPVIiUg(0`rBQ_PiDQNapeUVPPEUHcGG*l9=yys3V9 zQ&nlc2PvC+ z1pTID2SC?yfSHK0YiA&U>Hf^p?2!!j+((IPf}qz2yHJbZOvFQgR~5tS(D9omyovr}rSdoeL|8^GQhdpOXfRB6$^!=BZ%lK_LA>@U2TIM<+Wh9o?>9m-Cw)$5gEXO*!fKSaezD$2Fxy zW~@ytg!GIHyaw_t3&e_-wX1tO;sYZs8&n@5Y1d&gzJ6ju-wu-Lu|Kmv4u3P@0}uEd zLWF-F(74QulSp)e+_Q$I@bNVu0!GBxv1>|?fGXgY!B}mfnoT147DIxxuE#mT*}--h z)qSXMy_!SCdl}jtKi2q5Y@F0Jj)=pAPD5-C zwg$2CL8!lLmctF79h%ZTn;s?vIs4 zN2t%NpYOAp?E^G3*x4ONzno^d%;Z03-DL`f#>;}0@z&;12O~3YKiE%)ydRoR&6WfozD02<(eOP`eQPJ~*iX z!ci@ZTo1knq(2e_i6E^61j~Aic>vz9Cwm5BT7Z!P+-y*+0sK6;Td?ms5hnzWAUr1| zeL(p-cMCK@kLxc;y+H7Df=|RBg@i0VLjDrEMn>(2s}#b9RV%_KHc+)(RvKp*f3FpIV}vfHdF&vEl$)$zkbf91yFr=MF62>kH+5!FAN*PqTmJmdL6`UfGd>%+1JA@oMA zi+!XZLz#lDhaCuU`l%^UJ$k{)+xAF2rK=f!tw)#Ee#;4D^&SyRuQC3sPv|!puni&pqi22 zqpne*@ZCXUBk3nQ~W%Uow`f4JKOrwrrJQZfUm} zw}}(qmL`J_bRJ2($U6g9CH*T!6qyw-6#?H>N>!>{R1N@2-OQp3Dw#!NYI>zQWj;C& zahKoVga_ovmB__SQ%C$#N56FbAX8OV^;fMrWS&|1VXoSajnx;?Yvh0>jqQ!Khs|dt z!p72Q&?wWW)EI1aVg-5l<1qR6*34e1`j0$?v#B0d8MYv{I<{F0yk9Mq7oORtoOzBN zjx<9vu}64!g3cYq%@p$WB3B8!bmJf`89M(;+DccgSgrU5M_cI=>c#rTX6wAUQ^IQY zRbO6nAK*Rd*4fcF?lkUS+*dAcM-2y`4i67L9PS?2&GMBmRhN9d|w!0clp!sf&z#jl`!B zRL@*%Aku2lFwwNBZ?TKi;?^?LP}9<@7plyzxK~@M;HE&LXpuvbDFrwTY5iIpYU^p6 zeT<9^lg*G#lr0!PiX22urmV{HaNJba7GJVi;%h=YRyh$mjyeXMtS)LVIv>-V*mFf2&N*u-Z53&)aBAI_ za=3BT-Co>$1dapg)=nap@=j+@HBX;byeYF}cV$;uT9^7JgHLKl3r3Rqkd> zqEA$JZhkKfXB~CUJ%z@H$`^yc^X9smx`fue)(~kqW+7%R1;!XAtNW{0^k)Pn{G;Et z!1@BN0~P}UzYg_y29^YW6#OoD6m$x8^uamEItWH6TNooG8(#HOEbI!(BkLHm4Av}O zTv&KWHKIS3AqsJXMGRD8Z{iUtp=hS)c+{gUoTJq5lo4uB!Abs}xPFXb|5(fd;T8WZ zhnwtiFy|GgqmFfl(sRQ-;2sgy57rb`Hxd;UlT1%`N^X;qjXXJNEBTHBQSK(M&Cv?P zI%GL8Z70u>#c%$&gT2U7XP%u=#+uA`WdTP_PHgHw!pM`PJ3t`wS#AZu-DBv;?x^S3 z*^1lZ%ZsRoeI^PJ*V5FoZxerfyzcr`9djAu#~Roqc z5tmw)xSPH0tCzmF7q|@Va;S(9DXt$BLLz30R9cYG)^tG->G>eT-M zJ)`@Sf0tA4SXH)AUGFbTr$tkB!ozsda}(?blXX~e|~aGC+Et-OhOO!`o0XxI1ESj<>mSxI^5B4Mj?{B-=Ld*NAa#b{E=Q|P51ko-G& zR4y+23on}o_nFIE<~7SoC5tv;wk)sr)pCmS$(}GszYWP@<5)B=x`f_S$Ex+%?cp9h zohDX2r;5FSt7+!#^xoUIUD>;jZO>YEPPdxFUFMW?;b6vdH*75yo+H>^uM^#|e9LY5 zq}{!E<)Ce}bIF_GX*KH!`YxP+)=$Di<5J>5@xeG}NcFAee&{=WNfoO6b8Z7)tmosm ztm&7-%>4xiP~Bd`-VVdH{_pF>yQXXCYh8b?8&gnuhq~~~fPd+8?M>suk+Hwm+X8z6 z=j4^xz1jB3kM4%oAATGMx<>}T*SGGt&cgXqe11Q+oF$KzMCYOMcVhwgWN@nPjV_8F ztoP@_Nx4W#J#C1!z0iBUARFEBp6(0<43CrZX5A2Khfb zxTF%sf!_zhpmmBGq(pH z$-gAH-_QTaW*{N@mxzlsABl#n0+F!2lPM7!Ju5vU2|pYW5fQJGi5a(&h}eG>fB(lv zV&UTAz|Fwm?(R_cV(39<=S=$VO8&bZ5mRSl zCrbwxOM5$_f9f?fvUhdiBO&>xq5s+beV?WtmjBz5o%4UG^{ybpKUWx-=ouOQr|$Qn zy#M5KD_DA%+GvPa+M3!qzqi59#L3Lb`>z83-=+U;@;{1d{zp+J#{Vq&A6NdXBrn51 z8vKVw|2EgZa^LO6568>!Kep$GYwh4~d3Oh%rHH)B`w`+F-@I=e?>p6h9pBISnpkG< zl;4j*k|KgC9^l70?mi~2ov(QZzRYD=<7V|aC$z^?$bw&?(a;jU_EpGfaq{rpjDIDMlGFzCSAO{lRU8`-vfc1~CQ$Tm{P-1$jLa4BuVN(NqYN%M zEYMQ895VXvydxoTNbpyt21m|dhd@c14pW1{_#4-NzdL=KPvJ{yf{b~>gh?WBCt(~t zVRTQC7Jaj)U`pS^YsA%HOq6N_3u&o+QSL z5ZjL|UCacKQs7xMpi$((DH|qi$JcRls0~3$e;7fDlOv^g__5B63s%*ksoxM%w00B- z+6wY?^plc|+JmnH&yWbk+SFee zKM)f?5HmD^m0VLf6Yti=&Dg*LN)FY3`ntB8 zdvfv|F>bGw(s&ip?Msq0xo7ej108(A%r~CrV7AjIwaKs>;Gdiw~tJV!; zO?4VyOMF$tzl!+tO``K4j3hA;vjzC6;Q_qSTDP0e-~0`b5Ge3vC1-qcJ4rO#*pkN! zy1Ec#T~%wiboU8k@;l2h5pF}r%<9t$8>QBe-; z$F6m;E`@xku>ysBmu;u0(O}`e{lf#%GKH_wqdGAZ;a@B+rp{)y1m(CZ z!NT+P)t}v(F-3*L1w@m-xj>HYvFG>h4N-~iZrSGS<4V?sl;aQ4*$I`Y^!sLM(IvLl z6(O+oB1L`Did($2I6C=xS&X5=#CG7OY^UUA^;b`E4}4A!yqrW_5edA6ve2%R=5|KH z80O`^ahcj6VPZrH6H2rZFlj)-Y-+yI95G2ofnKWysXPlu!KoEFHa?#NCpdQWTLkTt z6ooYXytE{3>1QMMBBP|CwN;J~IRb{EtqM&AkYA$Qv#&C)j*LDIu_o@P093(2)4r-I zUk#>qY}Hk;$4y136+2cj5-DkZ`L&v%MI*Ek#||4&I)HTtXqwjS)^cFK^~LAIre>NC z0S!7|^(qYF6X^fauLnM`2VP17$1$VWN5qYu;J#W@AR_AmL}ia z15Fx$6X^4S=LuB;J&{c?hmC#MVhPhk6iM zsEG^I2`T%h+KMCUSOgJ`A2)ODFp2J*4v!U#p@rdf(}R!kVhCQvYu;uPJOq% zta@*$H)>~-VKp%BI{wGbQ)~4}C;dm2pW8hB?+seULoR%nyy&a=KyQ?*xy4}zEPTuzGc5hCa31i7)pMyVq{yzpS4{#)p-j6_^?-7a=_{Ow-i?hFCS1NPR zqC_inJCh{)agI;$zxLV*^Fi-e5R~4wDUOv)Cc2Plj*%KU8#{J}n`)j!6kSG8WY(CJ zsk#M(M4x@GuREbK-OCSvaSr0&*35MsnnZF#L}$!~imR?SmXrPHezGqb6m&JVtMxmS zmlg)zqr>v}fMB4)0Usa??PBU#VFKs;0)AT$6v5-brd^I7wGPm2Gkc`^sL!q<8}(Z79S?2*V!%c^HF?LY~JA( zCS9*)`Qf0xfId7*5(v{XNBxhm#h?wggDAu#jk%5?_p7}M zy@0SERxY2!7UWSZ;-C^k;Rz_nm1QK{;?nN9VFZ>n^o|0jk3_!Yi2IX7(>}>_XB1p< zQ<1@Q#hlN>2kZTY_EED3o|=5B3@)IB$?B{7z@TOIqo$EE(l9MbR|)m2uj)r^ILT&? zc;6Q$sY#?=v1P0=bmYEKi?Vscx1BWH)Y+?{y zdpub~h;KfyKu&@7EB>nlws;oJxEs`J9xETYRCxbo)_~91S6tSIwO)3mmz9>4=M(i>4jUJ-DVrdW2mibI)E^Uh+}0ViVTR;gFO#f%cB4$Us`IL$VS#(m9TPNv z>_r(@pyE7;GmYYh<6eocuMzXByAeNs{*2~>7EvH6O+QgqEow^?ak^n>atY0<9=`6- zW=La3jU~MwSEM<}7A`X(CpfGZ#1DfP3Zc{rvDpymnv$s(4qs4_DM0#Hbltew7>jlp6)n79>?&g*52fGlzX7_ys;L164!Wk^MI?p zdwJdV_&*@4gn1vopU@L~T0A#2{}IggjFCHtzyoQaw{lPY8t!g;#mdqR8HN@mGJNkL zBpAmtXwKP`qZ)g`J{ZBKS;-o^sRq1k@}`7ZHq@>eW+yokC`a?O8xPks8?WmA{Mlxu zqKt>2Xf;u09T46-puyZbr^z}aGKotl66cGt$38>M4;UPb(@XQfA541m!eenKxV*;U zL;L2<^Ozuot}xKB-4TWp)1OqM$h$}-lbn)!MJ3+H->ixr# zt*Q9>(4>2gN~o^mg~gM;&Zc_h z_Sjq-csq2a8NHC4Vlu9%!C`DhdRaC|;TmzbD*a=gJvXD&o{a9`{Vd4sliqN@}!gCX#TJvZUye0*UEUbERh7Z4(CLpsb z(Jvm76o^O9TZPP#-Ms#7`e9;?`y%$ux?sPtZwu$B*OQUhQmTFR;wwi}ZON_yuQ;}K zy~z@6G)c>216M>%$yWbGeYn?o`_NP6OkSrGR~vQGnNJ}i;tBTd9-udUts#os{^b6W z@Qx``tAFserLmH0Ht2VAqk$9|zxKnwnq4C8ga zzlwZ(BHw%M!3!w+bu_Sipp@qT(&@Ol50-g<)2bYXoLr#Kz4@4jS--MFs{Yj^JHV#RuHJ&A#T zM1Ww}0Q)T1zQgrK5X6|cRNu+qSN|O(g<^jsrLlHrycg;?c!`tUd-+otIY}FMD1PT^ ztZx5PY6hUPm#^s;y-*%!=`r;jyY4qvnN@MapsN;4BX9W=v9UN3$)V) z>hX~+bX|$MY7^hdc(Ny%x)-vaXl}ddyG!9>zqqqS3f7{Pv&z?qOz6CdG!cd9Y zhVsUhfBwdi`I9{@-BpoOEmT-TReyYkL^)9uszWbICC!ZvBjcF1S3J^_>Y&8jTRN>s zbAGSinwq5hsu|&a0d$VZQ4xG#&FP3`=y-rRSCDRWzRdP{UhbEL$-Ifsr5Riw;W7tB zCI!Jz2Rrk_k-ctcn${Y)z5k88?L9wvB=+0WuIl|HViR$i(aO@xRJji%}DAh3*bO-6az3YTvPsb0AAU0VtYzl+Hb#iQ-?8s)>kzvVlb zWzTE5r;^sl#7v!YXG|00&t%e#8DsN(OmDx~8;6|rq~O=_zU7rx@xQq9u57mR9m0`r zlU+W|>|(#$C)fA*EtT7~6VsaZttus8&3}$bzU^*guXOv?<}?~l^x^Hf4P8t^j(ydC zRS2$!)$VO*{%&i@UI0fL2NK4{YV~O_ZwWzyMBUE7*2|h z(Vn-#WAz+lPm+&Rh~}!{we^kokffR|LWZdpgMnhfsDTjF z@6SX(p0pK@*P;t610J0B`Z7Uv@}`7g1x#p}T{?av(nzI0j34Ww>W1TNFBFesDHMj3 zY8Wib!q!sz3})keX)mmF)JW2MFK+my#!v{pV>K#Eus;fM{+Ja8LY3#~4)26z6=^yD zCMPGD>2-?KgZsKfobu6^{mwuWfKBWPFPebNDaP%$t_p7$GT3i8CG&RKXFGdX&0=_~ zk0zT83w$&72gcWd3bA8pRlRx_H8r?-41irvZU|eiy27*G(&jK1vQb?liqyeY!FD3R zn?mv#jsEKbNw}`Z`41Fi_$}r~-^kCqw5qZ!T%#=I}4j|}x z{V-6y_@%L4j(Z72G^^%frqky(lhg6o{KiVOsp{F5_;M0hm!4S$j(mBBT2!Q3*Z61S zh)B3J06bWjm_nMCMmmjy|p-Ia-pZ067%ZD$Ve_~zbzV$&yqPZtoxdt zh7vomYwevxog(nCHW&)Xu*@DyQCQ9B>4T!aUWDA zwwc^oexdFdYiZb@kyxVmdIV|`ECt5Zad*b|gyZ-DWb?Hl8G86`5UAlhWH4HItqMw+ z2u@=xTZS@7sVulJVzBgKUc0VnwwF1_Sz%}_604#+%6H{t-g*KaV8 zw;Xx$sV9nhTugDw7sRKOFW0{Z`k7GU?Lqyh{WdZHMd_{2OpNWKAmPLp-FwN4z=@sR zp!gxfsT#CHCCx(m#qXte>!MmyZx%V~C^^I0{mc->J0m8< z*RPU?{JGdYPf|EF+)~wiD!>%mI3%1}RFfc;dH7=@Zl;CK46mA6Lx=2x=MO%z5|Sk= zDhInAHuZ^t!sDvvkq^=&xS4Ku;qnX$ zuUf;c4vz&%#rx^Y6MpN8La89~P*? z4^pb&GDC?TR@(fmEQT5PqrwkzSb*drPNXv$fh@W4(t^j%er&Lb`3ZBN|UCFSCJw)<%L1 zevtvBGPY9$u}tvdV(MOe_&sJT$ly&pNR5v+6#R1h#hM3pON92-4srBAJ5>_Z>&jMytg$x83{gZ)n82`e=*cRl^;B4yhqx;ErWHf zmu%Wv*1ZpB=ytn46JdG|tM?}L`5En&mYkieC~X>|f|<3RylHnHbFAm|nO5b>nxh)L zOnm3%eLu)84!$B!ryHX_!;1!ylxehx!M?+40Q~YOvnD$#!KXOJ@5X|V-+9i?`UlLB zEVq!OJ9ToaSO>t7Go(;58t}Um8}*Dhx%B0<)0jNazRL_h z4BJ-*uNaPY`q0IQDtX{5ZRjWH4catE-R1ocxY9=6F;g`u!m=)u?5}J37jrOY0~36e zSSI!(zibdRi6dt}@`?fhX`!4K4a$zQR%TyOse)b~S4DhlyyY&)Y_MJ8rgd>j>J3z%6Qh-PE#`lRv9&EZ^T;BIN z6gHY{;ZRP?fK(4=>sV>vfg{(OBE$-5ti-p<&s?J6;a5HsLQ})(B4O03#WJy_kH21w zU#?#FMt0N|#DsfdE- zL)Q9jY4p<<0Iu&yKGl@pp3@#YriUi}Nps>dxH&#@^Deg@3^VV%-}~%g0;6J$$EfJQ z?{U>t?Mq|F8jB$pI`M-Hw(6}-HkI_KGb?Dvq)IcFicCPV)m(~>&_+iD0~NJF|FKUm z#hdbVePyT)>I}70!2O28aeQvDaL(l5t8=cD9q1ZBBmMhzZfBI@q}O6X(Q`cYUAHMG zY@_5V)*@X>1X6;vVW`sYO4MjHp(du?!;w$%WLF;exZ z_P!=8E~t)!JEp6*G?lTU67GB1cLGhj{`?Y$R6L38X&J0G#-B-57alklG6;52UBv+~ z28 z#QPtw!l|o5*|$7PRd_w@V9{>Z7Se|#EJd#b7o4+5E}+3)U_N7u_#CqxP}LP0@!$l3 z6O8uqd-gdnA#=5-b)Vn0Z#Z*piU6YXEvH|^eRg@1}8bq@ca66 z&LJbLeDd`_9Z>GbYm8U~fz7kwR=^D8tWPsdcw)2I2Y^cn^|%gKvA5kWKSy3OHYHuv zpm{a#{WHy8k?9}l=Ds{xA`_$ zSv>){jP8U;iCrQ-auJQ&Mu0D6d8@6hFB^^(?#6DLfh*RX?P>_&$_>nKHoBjpZ!VBl zYB>QP)WPXCkZx;2%170{8cznI?J2%@Gfuk~9w0^twCMV0w`05*Qr#LwF|YYEIw(rt zf|b)kMptKjIEj*2t(gfI?Z~9Yj~t`4{Fu~0U`XMCulcrm75C~-HW(X6s<~&TH0>9b(JFxBQ+wRNvep^+5Pf&4OuQN#aO6eyOm#Z^vMdZaBCpM+ ztP#k9oMaZx?gw*bQZ1pJG=D8!iMLyUna7Abm&fAobK?S%6>`FB#P|~zu^vI;Ao3CD z@nw`%cQ#4iZI)$RNzCQuy0-$PsOFVHZ&O-XoM4!#mZmDpxU%osHaWW%d^$n@n~mLo ze6;oUv*<5m{J=R(Gi)INvzf4qy`}CD2ESJt2hZi>z!tPMDFz9=r-<~zAXbe1aVA{868%7corHA7b zNy+%=(@e$9=3Wd)RZ|@wVRa`6)C$n zoK#f4c4>f|U8c+g){^JnIqlT#j}=PkVqd$SX2(4`=mvl5LHsh~i8N6}rkSMdr2 zdvuvjCku3FVr(!e;}yr=RK&1#v0J*$aW_!cS7G-j;c}ecu77}cb@Bu@`x#d-Y`)LZ zYiEo>5^LSI@ml$ykKK{RUyLd{KrSDF_RP9oORp{m=2aRK+q#85ZIHPF9#8Dc-J?D* zc{+7B0iR3G^O?VMhK@UOn{HE5lhX{TwBXD9R6FHiI?(cri+^#UeC_b;(Nd)*qw&_^ zPwlVdRr7qvgacms?Y4Sz1`plizmX;dDg97Wi`5J-wbtnA>u0LFWDBl^PW##%-JaTDL!_ zQ;nR&71CiBl99WdOvMDN(a#$-O#nBW5)G7{C<+9!b4WL&%|A_zuBOYC+mjVhBr90j zrJLo6@(h^vpXJ=9Z1;w2&sHgRyky~4w!bXa@AVe8j@_dTj9a2x)&WCIia2?kMd|o2 z+6pRsX$ZeayAZsy{EwGfK9@<9d866x+$P#PH!@8+X4b3TKM0aMSN-SwyiuDHTe0m0 z>Y?pDfOyuPn|-Pr_C5Toze^O){f;-uJ#Neijf7evnma3?)$?w*eZTC?o4}5YY{|or zDq~y=_;pQlk7v>xox@IeZZZNpXu3KKd1ZN+h`Ah}O1x|}vOy?K#T=VKUIJaWX|+nl z$tTWi-i){B%k+M8eh;s%AL}@*JY_FB7Ruw4#L46naL>QS@ihzJ6WiEYUC}=CQiU<&YgY z>Q9h%zw6Yu9B2pp;z%=;b>qXnU^->8icv9%U(!<`X+kvmlJfh!w9|P$Jl4wz7XCos zry$Rv=aBBJJN^=%4l2gV7|YKX|4x%Bk_5q|BY?S4Y{m+z8t}b)hRq^e3f@|~Fk@w_ z{Fxo_86j${g72d@eeA0V#LO$>C~$ESebg|elLGVMWq-Hh>KZ>VDaTa1^O(z0ssSS- z#3ks2V&l8YP7x8X!HgY*(jcRZvthN%kyAiBF7p7=_dmafl)GVv1J;qT*t3T4wQM~a zBT^A_WhVI8=zluvvaNTmNLQ42?S>Vay8hm=YaMS)#7|+2AS!_aesd`=V31SJe>@0U zZJ*G}y=TO)v)$yP=%TM@J3^!&(_YY?CVOCJ33okf=yPs zy7YUUe26xX$_GpVcJEQ8I{+soB(q~~W-{;bb9-0!vN@hY@KSnk*CJqRK4JM71@MbQ zJi}&UsC1+fs#6O1hja9pmd+Xt_no>LPdOI27f)||4X)OUfS;YfSu^{xj6gv~16?lJ zzUp>@Q=Yza-`lG2iZ^=nCA9EC4@=Ox&`P=zvAGVhDB84?Cj22d@a(yATFcZUx3fEZ zS0%I%IT|-3jCBhx%_LXNV%vxp zs8p@_-1)x5AoA0$sFeb$+jqwaxNPrVq4!&PuK`7rdEjrGTkAK4H5IMU;9^|vH+P28 zdyLcZGW>1uUninlQ!?nyVS`f~>V^1=d%*J2Bc*SPX?GUt$91gBhS7?H({+S+6PpUl z6KlEPe$9*`(2{$$*mu{lX30prnh6u~zl^SImG~Tu?rz4G;8S`0GsrOK++~Ji@tP`X z`Nf@ane*$7i0B98B~!~jrV5<)=|#0%a-tDi#$Di~g~y)C1F$`fpk#H2eFMH_AuOon zzV+sg+KfL@Tv%Xb85T;5vqF-Ry4QTNZUq(3?bLXI6Li;%EZWtLMvpOeXjddDj?dFE|cFPq54Cw_csO)PudhKf+)X-_;gtFVOK8nxH5q{|8~b9iR}SfAGJm(-q*zZ29C z7uLg{ah5~V>_T}~dX~$S8={ z)<4GhZMau%kth0}pBhh!B-#$Dgl?}K!&;j(VHd;fba$FDrLjX-&S`URwd~{~@J?}4 zL<)?*rW9{GdCKhlGtQ;_-{Tw|8N5wDRxArXaND3YFgK^R*Qhoi@E4~NEeODn(lY*0 zh~OWFCg{5m+KH(2`2ZDddw$$Kd4U#*{ z43?G1c%-=!m`QEZcLG7g8fycncm>AR6RwsV>=tLg3X3=*b5Mam;?M|yF)R~Hx=_g& zD5ICol3w6Z`J=lBv&X{tFu%E;C` zCnd>=4?bO9?pfqzqkAkMii3x>bcR0P_OOe-m%NR7^d!ZRHh6oVe(s^9!2t4yFCeys zOH+NV_^R*M$x6k_8@DP#Q-uKn=P$O$Ph4tY?whT$P9Er@m+5}pb6(c@39P`i_~lyT zj_TrtVH2|02zo@)r+5BE6eh(b=SKqT=2?NjLSVODbQ z-Lqvtk(@P&>T**6Z*l@Z1=-fK=;Qi2QZqxogfdr272pN0bAO*uOk5uk52(2OOh`Cb zS8SDim!w?lyT-rlf9880793GaW`iHE2r|y~Ul5(2TZ%vP*-FwaIsiuQX9|4p$8?Q>s-#i=7q43ijRL-0j&EfVjhFn>6fK1hyB~e#%bbY@Dt|Y1t5Lr=#$TD9VIBhxTYUKhM zoU4$aR|I)SHn?Z5+_D913Hpcp+xob>6Sa#AcN6*fUH9ysZ)^FFnEh_MTuaS?E0|M^ zLcgy2*nH*k#u-f$?ruven5&D`OC{3?stjK}3?dGcNXhY^gV^<_ik|H!dsctV*~B(P2~jl4!yfUFwhX_;UxOO%+q-58jlv1Q3K2?{G3xTwjd9UPwy z4Zs}f-D{Q)4FseSy;d|@9hiLh8Mq64HCV0LrDN)v$xPRYrqkWB5WBl}qUXIp)ebA# zRRg5{Z#1{ID{&R&{eEr*87Bzq{jNjCCkrKgb9G3qadO8?HPC``Ki71kja;GhiW#Jf zSiRgEm9QXkrB}mo?2!`#a3O&xud{h#As1t5Rv5W-i%4eJA{?W&O_XpMJ4F&TriojP zobwD*6Db+4wP;CkN%+uq=33jQh z!0cgG=|wim8sqAOT+506?v6FvYbGZ6I18vdNdKKo%a^u9x@JGJr z-OPd1NEx+4%;MDPj5}I)`XP$W>=aRWDoJBVN@{UNE-B>N3*C+>d{`_O88gDneYUp^ zrvnzep%T8IF<9Aq<(U@pBEB1v)NJIp0$Ez9AhMVb4L- z$*AGLVjprnb5-4t zgy3<4UAT#0ldtlbldts3L?J)Hh2__Q(O5lCs(8i})3(`~MD8e1q>!4%T52+_j(tS@ z*0uo4l{*`)+A=LS_R?!>m>gB3$p{^=%j^39r1p7T-2O;zFp~4m2sz#rgO?wdwZ@pr z3i@nSmYYALcb;V7YTmk6q;HZ_P7FR+<1)qJTicC=#eX!#2i$^AXOnparo~cUt3w?i-H- zz~1E^SNg8-4T+8s+A^dN_x-&$!DAqX5!hoIykazMIh`Efm67ae}x4&?~X{DYA77zMNDcxn3&o|#`3NPJW ztibU`#d|)F!MP%8qJ;f>mc!`aN2-U(3n|v=nYgns-|_}g8oh2*@?16)!*tTE=J@^z zj-We5+?Q^`@flYv!!{;)pvFLM8f-C7bPhkf|Koa2%Kg2@^D0HIZcz5!KPp=ABi>I4RyS+9M2fn3lbmM z$C28CdE5VaMnG8edj8F6b(~F4=OxLk!$~&hrnA&Xe)Rub_b*Nmh)qK#u30sM;vDly zYlSp6h4n&0tQ53EEAjdjQ5Gnc zypq{-UUQc%m4^7tnaF+5c7Mr>5bs8s8l!x2t|^*a+t^}dE(}oYX`xs15nnfF-_|yi zPG5*fB~-DP?C#o)c*uAnZzW{Cg3()q-C$+2@tjUSuFZH(F{+qpggu9-q}o=4r}R1v0Dm8COS3TJDvKX?iqTuxkPkC`x2DWTv1kw1y9o8lm&d9kN) z-LRDH!$W7p;N=s!e52U@u5sOqf6`B?|H5j+6$MK3++S^np-xj?S>Xz3y}}?)#}TDx z3Sk8uxOpcS_)8KhXK+bLP9UhVA*+aLV9a6;)-rIR)~8j9jb}g5if0NYZ8Cu_s|6>R zfP1-tel4x~u4E#LQpA$A0J{0a3C2!fVM&(KOdMg8wKjB(5uMgn~ zrkbM)i~*wzoOjU9sE0y-B9Q<4yC%Jsf4VW7qZ8pTnS<-=M4P02wB{q(WTH9Pq9a3i z-ZExzTxe8;(mwVnk;C7=6H9M$ozTSLq%ipE)+1ZSWpRCb zXEJyylerOinn*#+H7lCrlrm>Bl~nr+`Pll*066!_TXOdydz%fz@r6xYi}w2Oz7b=| z?1@27TDm%lu{!{`A|3Av! zDlD$3YZAuY-5Y`jcW*4XM{sw7ySpWLaCb?9ySqCy3GVLh(mkE``~R6|Zf3r@I=AQ9 z=j_^5wQB8!Yc2hoK(5Y;qb_+P0?D zPI{{%juZ(wBS7IQf6jQJ#r-=Ln$b=e2CDiv3Q_u~k7x>vZ-o~0LMp^8bwn9qtjiPx zaoPUg>8)dfc>6_fmLChWrRoNF_vD3R&wN*AL~x|JGy1K$2Z5=;j)&N^n6o0e{~K-k z4?#`u{kJhzn|zzUbp1)zkClC4BF6vu>sJ|t`Lujmo(u0Fy^ zGa6QEgE&gf2oMwp^Vlc|%bhH;lG)B{!=<2`nIHh(9pqZ2LPLWMY|#|@CPa%B11YVU8r6JC&n_*p4Aoq@&158xVu zb?;yNGG6m)!%Z5wF&&VoD!%++H_+ex#1oaFk^05mS?@l}T$g)lJ*j^d_9R_VQd^vRlM74qDJ}EH*jAcoQ$2eqt0aFV4617(J9u4)r+CiR|F_m*LK}`p zQ~umiihJ0l5-TapO{6tjRyZqSfjnYCk)H^M@>ot!j^%fGA3+M=YX-CiD)l~TQw;+g zM9l6R)XAvh!j~mkkPQDuUAII57YwsnN?`kyAmfzDg|+>wRp6Mi2ZB9$Q-ReS(Qf+Z ziDJ8NWpW8t@N$eraUSN%QN`Id8Nw=oW? zQ+4~WvnVZOV@A3FdD@QUxi19`{C5tF5BbWQ5O^3E2t=t}?*|Nw1kAr~>@$C4FRH=D zd-=LOv=-y9*1_a1pRAc5N@19H*PU8_y#~|K7307K>!XCF$Nee|RpI&@R2$pd^002- zI@U?tI-=5Kq1WUi1o2LzuxMDnKMVMJIC0~*{P+Ac+0$}rBAcIdpqIC|#(7*;nvY34 zwIGJ9tD3t~ubH2eA?rd(#lqtIQj0~W%^d%@+u8CG0U=@5j<5%xfpCsPTq;49v>aCY zd}W>T3qR%Kn?h+_)Z9n~7wO->`x0Bgxh^xgxQ(UJqPpv!%;l{7B^J=yi%r4k?ik^sw&6*51dJOUIdQeiS`P(2L z74$A2g$eGz^N=t=;LiLl;qo#?$%<0J{r5{mxLZnTTit}YMGXmOJ>Nq9ka@F>1qS*X zx6X*RrlDQa-UV0XvKwz%o(~Z^CXX^vchy$>O0D`#%?Mvoc!2#%qgAkFDl@bAh}1Y9 zkrUOh)Ob^A#BU*~6lOLyuD|qhDlb#R8GYV2lT{tD`|3L3zjkkFI9V;WXll)C8A9<7 z)P5^Qt9USEd=hTrW^{jvVHSFM=X%~8V7%-;#+&nd)ZD_twc)+A{uC=w9MS2z{rdUb zFzckj*EWxnufGK+6^UFt1kVKn@m5+l*lPg zB$u>Wg0EBdkvCp)TW_Y?kDH3YW&h1Z`?tKjk_ed<5-yNl_|k-Mr$PF?(nIU-%%Tl> zh|%V%!bj$F?Cm+Dmfy|VS^N7&-nkY(eq&~R&tg@Gn>AndN?69iBVt1IeogC;;4G+5qGq_=SK9kE}uuFpMX-xbU8IGVu zBDX{dlUzPCDv>ts&fLbCnbE-P_mh@}Ole0;*xXJ>UHv2}vEQ&;=k_o|(Hm;1yJh&3 z@`@%a34K#(1wS8O%8*kR@&jRdZNFT)yX`_cyFq*A7#cesUEG4x`|c6>v0fe^iwn^bF1jcHVGA& z5jTa|S;g6I{0L7aEiFC$w!@!7A7U4tJ_$Eb#NhdtwZ7aqP3Y}*IwMfz0?#93Ih74i zKDm|XU&^A#ms*2UPaT-@OQ$n8uOF{|h=T1sAH7_Bx@l8l#ZM+P&vL%fj%+r8=;(>> z5a$wTYqeG;WwQO0rR1TIl?U{XG?BE>%=pDrZQA?w$LN%Uyro^$Tq(sZWl)C&cEDvX2P4K@uR@!RF8}EAZcyy4z|&NYhzcJd#|5Oo=>PRT{7$2+ z*sU2jmJD9cXO5t8x;@nRq^)he++bs-3VhnFIaIlRD=WZK!CNHKW;#=1tC^Mlt-s-# zbKjbPG_w#TL55>p2dAJd=CIh55uYHsPGOEdTKQxfYYo{!Jc46ky?+@stO70!$Z9WDCvVu6lRfdObE)`%k9Dhw#01c;8?=(jX!tVsXHG zLv|U(g&62>Ee2xAYB*Z9qgV=M1**HjZBOGy;B6*hq&*({W!^H1a?MI^iwT~-TuM>W zONDI&&ra}5H$2+)aSf2{8WK^66i;8#Yo4Z5Zs(FFalqv zO*#g?=;2$!gaVI;lj?86@hC2PvALt`r-a9k9!Sa!mdq^vQ15WYtV?-tnGT?oiOn?S zBO5*TLHmqe0wL2nY6yG8C8{`y)%vZVqq(0e2fzm*S5)7H)0qNkb&$#nS7ky+zMl91^xK`>dOVe_A)udO%%C-He($W* z-S>Vrmd`+nx?H+W$7T(~~&rc?1!`r!h!9^wvHq)*7N*kLa z7Wy22E(cKa%G=+cD%26$IqHuy*U9rA=Yn~ey0Oy`}J_jBR z%&7*Dsh@mtd=M~Q(7J~SlHOa7^dBfU6l*( z9%0N_d6M3+UCCEHH~jC?KQ$CLJFFcWk7Jx!1N_j;!tZLCzGzYu<=<8d5)u*)L>KD{ z4`|Z5ZG{uh%eH`@PjWmdMLg)5QY-wc1fXZbB`O>s@U@mlR-1Y$KY>@X3sZO0XQZOF z^2;%72vN>1ardK)RY#pfoy>N=8|~ZVl%}C-o@uc8GrnUn!JI*v+ss;v#n)4RSf2au z;c=>ftL2-(1Cb3HO=Vzd31mkc-2Xsc?FM|k>^B4Tz-zYMsYGVn59Ed%`w0ZRdTl%! zKGhjFPCb}FI_{TkRi9Y}FJs2gc5mzR-X@wcSmo*O6}O)3XQYWF<`wY$f?8-Qu;c~4 ztnQ?i{PIg{=wb~kwyo}LYKrYaw?*wO=lJ_Tg3<4OdpL^_5ES!3uap|*pLp%78BnES zbbZwZMY$CLd(C2oOU90__Oqsy#}9Rx!W*UV3(tjW9+IK^ZIYo#f9Hw)l=+(qpsTw8 z7QJ0BpAHX5mI^CwfN{lR$^SDy=U{YiC#5EO73OF|R_OoAZ8b0(~& zUddiPgG*XVT`SQ97@v%O{G?+!VZ)d=bd+a3_I@SPS(-5uO9qjlJ<*`T@+u=)C&dy{ z;BTq*glY*<(8`Q`iOU@45TAZsXr8uet}(}=+i%gDd6=vNP%f?PDh84kf_VFIyC9G|*|hDOfMdaG%V z2J!+O%F;dc18FdFrmVc@a2#dC_mrpk<}Qo;SugO@fe2Cd3|t1M2^@e$asP2AUSI@0 zQ&NSdXEMo}xyOR7LTHT!mH)hfY#Sovx-aODW52Xm)!ycL;gIWpuj9JrzK{V6kHq`o zE=!+E<5^p~fN+>I?6@m3m6F9y5ZfDm+xqJbTr)pj!)NiwP57Hh$ACF~w^^CS={s5I zDG8L!uVsxRW7$xXZWm~794mvpDgB7tm|#Z{eO?Lz-)Y2g+D1H&)OXEQ#0%4xv^$Ug zNq>Q}e(v|dng6k9weE9L8TXgi3#R6)*HK9t1}i-HZ3D8lNrHR&M*n)|7|3J0P?Zws zU!BCL=JANMY0#q=im;2x!T9#_AW)%vrY&7}Ik#od1A?8;oM3gU5J>QZB1N_u@eP;g zgmJRDU-jjA7@&gA7#EKZLFZr-g+?>V4TLDWxze-DEF!W}J8?Ky7H`IeYKyO}Rmb`6 zW7Fj=9Ba?81QiNvf}3dH2gM#j=AT&3&Yl*tc3>4bf0I3UFmi{MLJ;5SPmQA84Yjks z|JjkZ@c5}CkjG*136|=PkBn&Obdd?7_BmmJ-CUZR3k0`bp95;adNcs`suUK#axwQSqVOOZ- zS_l;3$nm)O(j>zq{V3I4&%ayuQuVT5Ebq#gqt$gtWE}4Ta{^p%8gJtn0j0iq=Q3i@ z_n1lN;`O=yoLO%TtTgOS<=?k2yjy9SYkSRU_+Ckq=CG>F(sWup*^Xu{z3#ExWY2Oo zvLWj&(xg6ho$;srV(s?y#B){za90*gyM%UCwD5DIM!@FrQIhxTF-~TqU?dx5GYA_Z z9Cq&Q@m}n8m+3g*&GB%Fyt>rNp*;ia;mgtXoJw=sPYx^vta1iX1^NrC=yc^VuuhgK z`1yO@T9WZI=9Siz>}K;tTCcbD^VbIll<4WcPJJo7}Jk&Xw-s68C-Xot^RWtEIeaVwCT7|?+N z8B_IapEMclsYL6<-_GE68F*s@I4 z6@E_NPS*_;f7(q_?XItU_en|8j0KL3Jb0*1@N0#io`p;XGmy+8~&Pv zgJJs&H8*G7YbVw$(R9eMvMgU5@-#i%f$a-(qL`euHXbfhc>^2~KBx|SD^FrT$3oq6 zMc$-;qyFtl>v1H1YB;5!wG6*k#eqKhJhT?8U|y+fryE44 zA+G7|RB@&}3*@~fpj;icM1n11|pcRo87ZFvTbT_Sdz zYcHpBw-1bMpNu^4g-!biGPyi~mD-J&{PxRIS=yH^4&(ep%IAeCoyZ zr_+(dP$zLc_@FiWZOPaAw!@y+xtC!~Cq=Ei2~g_Z9ybG;M7G9)bbG3ct0x1qfmAepnD1-52VNbMW!7sIn&zGsEyx#ivznzJ1{|u}eW;NS0&Q zQuC8T%N7#j)Lxp=Ir;F#pjOv4;ej59VQ`CI=iB|t8<4RV2~MOXIGSt|gsVKjZqPv8nXZJfTf|*Ofb`u8t6?*PneX)`)~-C@1c%+lUgU z4CvfEKJ)oJ=}%f^M0S()S{q+&8j~D#FOl;U51~9#vr{71VG8#U_Yk5r8V2^`s=z^@ zs8X{;B3pM(!;*BimWEW`DD=?zsQ1kzaK!4puy@a!>-%2pe}vA^;wI|^)XOLxAbC4p zE~=47Uw}9wt$*By$zGVKsndv_}4NM<`S?mLsvj*{P9%!#AZ#eN!RU}?l5P; zkLAWW!8wWv^O2G=vX;el^?Gmogg{~}9j%iPmP;>SUO@?LQm$>vV!)`zF<6!_tl(?5 z9%<|E8KjZ=$KrIc_IyDF3}IkPK=7$2W-kdYVweqUMYmZj{>3Ump_W9%RO!y_T=_&`OD131*PPg zQM!`&+g0A-Go&N^yyM9Ec}FbiFs->mZDH+F)Zi{U@^E~kEwZZp4D(pTQVcVDBxJe~ zF-~ST(*Su1t}cxKl)0pY91B$F9^PPgL!;YOlE8n;c3?zbxjfc4dKTWWCxJN3R(98p z{pn)i1#~Cgp6Kv;^l&(vRaG#2(efjrhU4@Z>xe+UZXA2q@di|)L`&@Za(@;U&VxkA zi&_}ge%?0z{X%YW@ifb!?TEo@3q9}8%r|3C!~uq>+|hn1d~oR%3oGkwOg}Qp!VsG<%;C=Mh?0WCkqVPfXuZL;fuk?8w&-+{f>m@;6@vpU< zA^A;m@l;TshT^Q?^Rfh}zIqYioxKOV`imgDY9s0;CJ~03_#3Z3*Kg<(Djjxto^nEU-Oyqi4us3^uA$tADtU7AX~MxNPBw=nfPt`YCEpb z`~^lhp503UOw-WfnrNMZAXmQUtq19YX7Bwc*z^1W$Z{TL9~Scs{jLTFkV{2KM6X9^ z-7YsJMUIj$xYjk)tj~IvGq5c@oHBs^KE}G~F&AAg4hJHe;WuA6hn8aNFFa=wq*qLS z1jE?3L7=7ut;d}*iIKHlcI_sX=c;q$O^#N#G$|dmW3i)nlBb6ra;%C76;YybcFTi_0!fft<@$j(DGfY--d0AO00>6n+QVT=_}0dSGqs;MJ@YyoR??~Vq&^hzCt`WsF8pFt4I9@ zsQ*S~6mX5=KAb+_ZEjqeGw8}UgjnIe>h8uEavvE4=MR74;jy$k@#$W8`AuaJ@(biE zuqGdFsGvjk)t>2T6dFp6n%kf=^3ahH^SyVwm&~u!o(^pq%Up@~X4>#ISmWhCUY^X+ zT=izR$=TjKlJhK4RT!r`8fj!cMPKCmU4OAh`?XkmSijb=2Tb0zbY zZiTJOQa~9j63`Nlhl95eA!Q3m4-*e70#fCbY8KUJ-QF13ibx1@V=1#(jIA5EH7F zEsR#xVjB4LvH@8qEl)?U0U{cq`S#@FlyM-I5L;lBwnaqrBHZr^-eA)Fmf)W9F@~DM zQ!NNaOsdAjDN_&HYEOuIi(C7SPyYB}w!%lBe!Eh(|M8fg4d~G32(V5B5=TbRl^|N< zYs-gLL7@KSwe7nDq5H-j_2>6grS<*^hQG}y;iQr&UtqhbL%at19}{s>7>BDiazrov zXAHFw`ZsBoX}_U*R6FnegvV@e2Q-YL?)k~m3KE!n#n1|`pO%*1f{TOU=J@VdT|^Sq5F=S;|?uMHwPNm|{EGYvY8RV8aaY3r-s znW1iHQF?gNUcaDTiNpq5i&)+q^RMYHMk{HXHaNx9-a~6^@4Y)A1$9Y>b zB-!rblM?5#fPtI`!H(5)E9YmDvG-@;-<9+Y<-sn9uB7a4bj6_IUGfJ$LWAN{&+>YL`WbN8_5~u1EtuDAJga+)=!3 z)8iL{Cyqz!sV}DjJ<3^K-l&MpNlh*D6}1;q==v1;!;I7J4NmqIHd6JA7&u;-NS)s~ z3zju3P9bA2N`?853$)LpxLfNQJ4d8&6tNbE^L~j$BA<|N;4DyK=)-SbZ1>s|+xGd| z6U<;%xWm*p{qx?0YnP+HGw!vdug0&zsfwg$Ec@bi*QYQHl-mfcN}e&x`( z0jJYKGjM!QFFmjeihklA%;&jrHaYsPdUi<$0dPI*C3FrXh6Fm})_ zr^4;hQ6L>DY!kZft-~k=dA-?Pe;G@MmHwkfJ$hgybR-ol!iqwP)rTR9Nt(sPBlS7h zd{wv@{XwvS@-AA0e`m^G;RKx~q#auZSAM9M(SZ_Ci%C;K+{4J3ZZ2EM73VG;+U`M_ zlyFCFhcTohExl-hJi+x*tszP4TRT-y2oU;(9Xk^-{TWVBNf!(O63&wMxEc#uk}ajt zz`=|Y>X;u*mu+p{AO-0ClVpj>L_q=!C#KqXrDUMLz@LHHwe0@LFBaOiK8V2aMH{(_ z@Kb8nR;`ugR{^Fz8Z0jxNy$ffb&5J^eIMJht*%HX?V+N|O+cgS`RyrWkX~#a-$W5` z@2RraHHuExi_v*K<_KEg5YA$MTRu1fL0Z0bz1&3~y==4uowpqclYyUEcpD+@y#6yQ zycRQhynCSnHf|6qUXPI?)(XFzp@5m_Aq=m~{n!(wo3dLo*uC;wmkYf^z*==7r2P!p zZO*7$sd)p!LMH5u#HJmX?$Qh>_%+@HYO#1Zyu&3wEJcn0IfC!0+yfnO#dwWr-7k3J ztImMA0ReC0w@GlNSUL3V<{roASvJ{7jWA<-4r8P+b2lM%Kf#!5ZksZ zqZ|gQYSFs)9ZC1b-RyTVJ?hcOb76#Cy^Uwh?c?vQ0w{Rt>Dm%OUQr&EI6QVvXE&Pc5BDr1gUoTyRZa!Wp-njz*W2+CZssy?M=!lRUErFgyHK- z{dUibbH9`MuwLI=TpI!F+jjVduB-KV?&y`_gr){!21)Hh$;D6=7+&ug4;RfS`@0lH zfNPo&SPfBbwnAFRDBuZ-PJo63bxquJQ|S)-6@CREh%gJcmn;S+M&S=7x{3DA7}AUtZa>oY+mplJL_*55tJ-mPn=Ss3MUP~En@bk(Aa?ro%*kDf6aa%PqL!o7(d>L z=p}JRNpRcQDdq*;3#8Nbpf18e-_jV#0zQUvGaek-g)L08?D8%2ihxhPjici-U5Cw! zoFV+iNl43Bne-TrC}K071>Pw8Li;q@@4g3NC}N+_%(&wsi4))&&-$D-F5nS}%`j4D zw_FX8+aAG*A}rES!YS;&EKLW@L+8J7n}4GXi^Rc=5x<&%DKLL8xr}_EZ@i8;rM}wR z62>61EP>z{kXhk;;5WloP=uo>eT2GB?u6Ln6$v)6{iC!NHXk-i*WDQ9mpArG@4XV@ z&ZI7pkGRj+5V5C^KdbAGen^MeZ3~6NhVB1?LpyMANm?T2HE}7|KCZ|gtJYJ$j&npM z?el!c9c8WxHBK$F*UfB#TP~EW(>pd$-)p$1wutE&nj}{M)YpCJAG+EeCX`4sV?aq|z(a%r%qHl)|!eewTiwmVS95v%R?%2X1SMly~ zm76Do3jqwgB~V9r7{v_-`$e*t1r1J}y%!AQDm;&v{|RRwQO9BVX;ciMV4EAu5Pwzj z5dFFfS{Ti~6TRn2M=sF*evseU(sm%Z(ucJ1hMH3+sJ;6Ra2Z7R0au>km$a}` zywZxsaElqw`D$w1v*OAKpE5NmabAo2ht`?2*)&d%8lzq^a^J5gDCVNZ;x-p~R|bh) zVHcfJizLc*5luJf`0@-o*f7$YsNwt-zBRH)VlWZ;8u@xXi!41g@Eh9)?(EfXu@w&? z9W(N;oceQ;dD~O&P`T#r#Sf*2mt^#GXRgjR@*j0!GC9toTFKo*uF*uVjVt52V5eQR zBVpw{<>g+eCtJ)YsV;Y4WiJKK_$Avmk@Km3(jHqx{uC8zF&cirNk>9Ff*;{v4Vzu5 zxfqTi-AP8ZCCPH6Y*Y<63Kc+Kr#?nky4@$q?2y3AzrT3k_kXb^23c&hg>^yJ#t+9> z0wlVhM+4_vvDYPcUOFY`kUQk?k-8KB_x`a+HA)4U z@Ej^-#7GsTa_ia>*j@GC9nM-40{nK6-R?L5r5oTYo3^(&Nw*7W>7%Q((vKTIY;6{^ z{mA%SSuitda)Bh>;YezW0}tefpUNFdYMwGOf0DtJ;sch@OXfdEf9HaY=E8O z4zzdVlU0TbXC)cq9-u!@$kz0F+EwcY%IL%#WgU&~{^ScW4J)7=4s7c%tlG;Dm18~f}5XJ4nv|-ga zXs}m(f)i-$n=LXqhp0yewwZEh*5DL2Lxd%Qb}dk&G3i#PyzfG(0V^i%L<_{mb}jJV zgczJTE1Yqf^lXvgIFpz7)8e5Z+T1`~@nKCj-isqzy`g!<-#!@_!5bn)5@*VVww1rI z53qQI3WsB3xMp_^c%r&%%7&a?J2zyZN75L%+1uViMSXzD>|Wyt-VpqA%8Eq@XX8vn z&pf3%fHciX?gY!k3(5~7VpWdtjaOSqJ4_3rucecgD$QX`8ab()upIwTBZsz=QeBJb z2fR~TskBXOl28O2+EkP4Srv+rCTQOUc{yMO$E;O~b(z7S`1H$4rVma#X7atAU=`#)z=b2G+1Kb2`GFH#F!Qyr~SqN&L zhLVt?ZWIV?pJ03y=7#Mn^cs{Y_iJ4M4doSF=p7vba(@2^dV|U#Ie54W2aQl8 zl&R1QRjRfO-$H^@dCgaJm&VrhS91=>eauJx6;NMXsP9pzeE)?u`HVvc@&@dLJ*o-Z zXtBF|lrP>gdrR?{tpay5ePwk+v_Gb4!tfxY0%fg-tWgLa)qTZzkaO%+kl;O#&&J5* zfEI!rE4i6uj>+b|8Rb);`sl6m54A>WKjQ?LZ3+}myTT$PR^3@a$+BktaARuvC1WX>ZaD4K$f#orD(a5-x?Ti(z=2|=%eYFqb z)}Xdp8~03WEEZoRqi%R>dx=Zq7U?3ED|tjw74{~zsEg=}2)z#0Ho>i6HP$O#ZOu>M zJM99s4~z3_)#A$cnHe>9TusL624~UGQ;vcW-_0J_YHJm+PCbr%;oSQ3!^`2b9z;3N zH=ofx@R|_ldB{cfx*W}GwFr|bZpk@GCK4kXnlKkAg@I4ye*f?|JyVn zIhcek=LwfBk1yV(w5D-uGxC>K^~R@Z!!?`p-)s$0Yd@bA`xRe#k#{B+N@X&9u5NBPK;haV%Yv4#BwuK)w)F^4G-JXpD~~u z+v=>~sP)B$2q89laXT_R4iL8@dlA1Xae<*D=l`_OZp1DIabQQM7MP1P@f@WqWztP!1`{PhPhwV4)23uK$gmEQ}8%M~+#4VgV zM1z_r^cM=*?N7=N=7PO0#eLM)j? zb9ik;V+ZB#YTjr4_?3d?{{Qa~N6 zM!m#;ep%u_zbq+rbPanA5?Se*w0Sheau~Q0BE8S4T@dPh*c|YnsFuEbNdS8RYbd#I zdFn1PUBLOBk3GHVaSP01^b|GMU8^cf+6TAKsZ%XobBLw>Q=+rx{=U9r0Epr)D_ZT1 zV~Bf+wbQ4B0%w8E=|1=ZPe8f`>n$&2qGA@w8Eg&`rW+JPwO8Zjw~twcju?e{XKgoq z5J`+{x<{`)`st8k6bqW$QEGY%rU)}f$h@ATLSkHq2IxvXYf;>>Z^#(L*N|hBE&+-= zaR)R|1(^bCda)G|)8%?af`VCpg=fshC2%fbu*TS_6{uig}4s z?k0Y9#kVY|mtEif;nR`1e(GQ<@{^ z&)ygPD<-V3n~tq$eaN~e_;j91%PY*7horWm2v8d>if6Dd7Fc|~;=oob@y#WZ_7vsL z_7UYz%Jnt_ioHzfAHS`?^Rbvg^RXT9IiBtt?@d~mS@h1bzR&Dz2&-gIvu7(LT!{lE zsvz44>;1deF2%B9QAy|oYjyzfiPw1xHnYoAJXUW&YLq_wcKzqw?fuLiuLl^bX?0aD zT!zpv;m3J+pFVJ|=bpjfR8rya&z@3BTGA))A4sRFNEKPXxN|w1$CGiDJ!~ zHcCJGyc=GRGD4|w1ibj_3K?rU@72VanSPh2QU5c^wvulvaY7;yDB=51r430*yn=AR z0w+a@|0;&Gh?t$Sd2i^Te=@Z)bBlul{fMUnBAh3gAT5%8_+a5bs3F@S-qqtsLpJeJ zc(McBC&o9pFD_z4Gol-dKl~Q+xpg`QL!(&Ab#ZQl&E)59dlUkkrDxRc|8cp>8)!+) zoI{eu{(>Vr5@Wu%@N!gi)%`;HG{#{px@o0%0Hr!%z1T`_-7pI=Oe`dU|Die);+&hW zeeI_VMBZj^_)vtAxZz?7f(>n0Bkyl=-ePz3gW+!{W78>x+#P615nPO1^rct=n7)QO5)gc#;gN^M+=$$I?@d?o zKZ#6Q*gsQ#yNlv1D$h5E+MZf7=3A&oy)@|lyU4r-(ya#Ww?aEX7bIWvOVh0@xsF4L zrcF--jYVCVM~iR71e>s`PPb%6_sx>G^Kn)iW-&?z!8*B0LW^%mwer=N20G4;cN!Ktha!EPYCvtUo}$y`v_+fL>j*&% zdg8VEtJ(IHJAC-tHgF8IFLJcje37qZ)E4*L8Hn6@eZOHn@F$oxOtfb{A#&+`T>`Y? zZeg-ZquYK$y;s4O&&7)J>ZD8MFY1qsncJ2Up}Hb@5x*hdEZ!Mpxas=N$f9>A+HUXh zxn}Qnzvjyy&qW3wM>ncFE8Afco@<-2M0j4`zciWc`$4WqyJ#NB?eDPJO&(^syV$pG z-W}B3?PRAsCAT*Q5!taD2k*j?_01>uFZSV8=^2r=gdrA^+c3As%UC)5q=r)vQleos zs`fx4x(iIf*QYtgT0(dOl!E7pI>1MrqO# zv%rO0fWhneEZrRx&c>_LvpT%37D5qc*G}@o6Kb$`#exh2ocoA$KQ`st;>39vxy3Vk zX8wyZ&pFoO#^E`!GcB*2Q2fci*z;Sexp;oKxG2VcF!sRd4Nj}k*hU;g?L*%f-{+90 zCgtaUTh<$6B(rhoE$E16Ng$Y5RmPs37%15AkOvV#0TZdQ$UyVKe-)e-$AufYk9eo> zN2MYE6RteJCKNp`a$V2(6DKA8QRqzAa0muU1ojs>?M)TrmKl{fzui1YJV2A`6i|~#RUb~8gY)4 zbdUed;pYsZ{K8ftP4fX%Y(|At?B7`@L*> zO*4BH*^E2WT~f7Z2X9e@^j`EHL6LAX<`uZcKaR2fKS|WS3ut0=TNpndb{=8?Mf3cF zj&`a?@o$n;#DG!8zrxG6%rQWDDwmWx21@Ki!(^^>H>e!iB9oye^%R5A@6D=1jP+P= zi5x7B@n1P1=};KGp_W7e;Y4#+H&U$Ae(1eRO3!_Bz^q&!PH)|MNB#%-HF1ymq+KAIk$xFFHp*BKhlhRnYok$%*2 za18OXLau!`)FrMw%k*u1*=G4c%Blu{buw<^UN@IQ`luR_0Av5k`IkTOS#AF4Q((N$8p481z^Aw+p3Zs2H_IM@+6sPy5$oAStgYUDVGw4ZIrg+Q`7Re-V@7(IlExZgR?QHN{3JMbF-- z*z>gpq6@g{Jhot1Njh+t+D@42Hsg2W5vdc+ery`Z?ywfnGj=EoFl(CA>(`na@m{gs zEatmC&L8A8h7M?p!!UFzYlr7=lK5DGQm9*40CsV}`Bq=K2BUg4aHw*5UL#{g8ys%wWRS_gU_ZHnHd) z_E*oQ?zpsfC6e#kD{7%5YOdU_B80-L^2TBC&sZkb+z^Bt z9r~?=ht%CbjzAFrTNT4~|1VWK|NY(5b4~%>k3nI4o1h_CR1na?GVf&tn&lRywG#efq8$%>k{E6S7LqC#9Z1rogfM(p{z;=TXSAI+<;U`DH;e*pB#9lE1w7m)ZW{Hp2 zk%PYv8B`Q9*x>ogG5LfvQpY@0(0#ex%>!DyDs5vj`7 z!yL-Zd&k-pT=)C*6ZC92RxP~`WU_i^#I*X{`YG*c<*c-w|3~2ZNY^`Sst*}kzhLI$ zjQje?2yW%llegJlhsYf(l0@%6G93WGmyyELdw}-tVCOR|g_8t=hn9x5Dy{5VQcnjZ zT_XYTqtU&oq0~~#BlVh~d&7gruk4$s*Tj4JVw1?vL)2b~b*flxZ3{CV0sQv2cr$c5 z*o#jHYv|qhXhV2C8+|0hj$3`<*NZn%?pWLZ!ehA?SDa{7=kYr;jJ`2LIVXLO<_gc* z23>-@bj)l)#!Ab7Pfpd_F`W=dwhOZjX;fe6NKYcM0aZEup+f{=p)LqXzUNY6P;Btx zkW$k&LP9*13{p$);|4)Bi=p>7F7#b&jrk5JGTgL4Lo?Yf{ryX2G`uXqbTELKZh!&g z#0ZKF9%ZvdI@Ch8WR=FAmC;tJ#iaEI>Qle%d0qE3pN)^-kqNsJspJBq*IMHWR&4;F zpET2R#fbIR?(4W?YYp+5=bQEKv@R^i2Sk0W2GD#QCv?e#%|zN&*2bkK4U+2vu-Vr2 z4_ma(#KYOB%l4ty>+U^YQ4q;bEh&FWJu@w!)dM<+$e(xs3MXH%L8YB`Hls)T4#LXO z3zYfcC)hKlM2hTdE7!TYt*0rHfqay>8 zzrdYmd(RgI_=7*7uP4pZB#C<4+a5X_Y)YVk@9;`gQ9hiDh+a%YHC=)mOV#7K1=+!g zC9)oQ0F9u}%u_zxxV<|CQqYN3sm{sHrI1hQdwipePR- zPLNH$zmCR-3KOBXDiguNt{(bBb(>;JzT9N#)u^rP)X#9M&xN9f{(Y*$9Jwf1c9=dd zBCE)QsQpSL$TNPf$lV^we1`ry@`V&G{FT~9QRUbi9j}}o3&SjiAD_wo$ezD;g5#li zB+WlvRD6a6{~J>H<0;8bca>w`XcR$bG$KK!Xk3SqN7Qx%|L7y$(W2K2N-?;rrUw9$t(&yi-C1kVj66Z*rGJ>kL-SCJLtkzDPagxNWob zVp>D1sb~2?jH_f6$^KJ;t6I+An+`^SDyilX#$UTN<@6QOjMm8koOXhW)!T#wPx-yu z&jL+@iv;15a;YIH zNML9_S~K=2d#ziT}6)e(i4mT{P8U)M|-l3)8Yc?m(xN3 zl2C~)S{b|!G|;2R^(R?9?>4`tMXtHuT+Mw#Lt~ry?FAt4J*@E`z|wpdh=T$I0)gvH ztgNc75n9?1wcBN{f0Bg_G{dh!T`oF4CtWx>?J>gHD@;ys=6$Gd$F|m;Uolu#NYmIx zg$wZUA){)id@huM#C8C-7CAQ*PxOLt-DouT!BW7o({Wag{Kq5;-wD}E!Eb&S3g1t9 z&_(Qqt&L^5J+7cLcz z>rWZ^j17A2L|ooo^;dZUAZ~i9wr<+)OzXEF4y&0f@#RmmZzcSV&?Q2?LTMxk1r%_p?<)eAd)TtvSWtzX>ehX5#`IU@T6^oO(2#tw}hIb7x`2fT_584 z52*1_$Ve)0tZCCNqltr}{mUS%j7SI3fsDFMLCv8RRrmR0D|D`wXu8_eva(w$yKi$_ z02h9j8N`Rh8x%^|SHCadV&30 z@@s=ql5B)WAtKG3mc}=QMGLowWS6*LwfgG`NMZmBc5?3aVf`DO7r^4enqku`3S+(jmx&(cd0#Nul4DwgfzVx2L=b#0q_bu^e{Fbj0uEtkES5F+uu^ z6Z*$Z$3M}ka$NoyiTLXHh|yW@cZxRxi-GqVrr2^Pd#i0NGjeSrU8nR4)TU+>WL`eww3O%B{bw z1@PpNMR4#%_2M72_jUPJbm1`O-E?a7EuW-ZP^3v1UF3 zGN7OIlRZ}`Kkk^qIxbjtO$TG>FIpJ3EQMpVUKKOxW5u(afOIaqGO3X*1k|5zni;p1 zC7&=yb&!%9q}=E7SEPpQN@aao@8i%|+})fep5>!M$dA7ul0Mf>8LPobO^pAICT!4~ z?$C+{8Vqw7EL>TwY!E^n$xm2s`@?eHQVL)-algG*xX|BRmvZ|&xVW_uA|r`hTbHfS zI=ap)`30mm>H0AbQe)!EFASUTI*479QX9lhR9c)IId!7IFxfdZ<8ZM2QiR9*0UVjA z9rLN;9c)XkgsaEA7!{*Gt>;xMW!HmF-Qh!%N7NLoGO?hLOmVy+%y2bx1Bjk24rS}j zc=Mk+jY$Od1W+f}rbdh{E8cRr6r(3!n+_S7Tsx@(pO9L0^CJ-}wUI%{3KX}~sGD|> z&*t>BDd39Z$jIPOVz7Hq(Q9USKG`>Z($#azph_&)h%Mv$kIeZdDJ0%~vh?~`bx$-cb( z2Z@LTWe0%{iO1j5pXpcq5TxyEqvcJw6`TJ!8O~ELxVHZU+exM9m(q_!cQ#HlQ zBkj{qIe@;P{tJEa_neOz{bc4|iFiX1%5dx&K-({CFZv}56 z>T!B{QU`))cxQkye1vI%vPqO}YaB%xT8KJm&_Ykfq>-wiaD9OTq(8tM7R=S}%gZGE z1_=ZWd!>$mhA@fL!@5cn#%+w)1*am0U^sRK#7Hu8&Q-z%j6_ad%Cql$) z`poKo0~lcgw#!WfNDg?_N`MX?dh-G}yqXXy*0gE^_p6RJ?i zr^zIaN(F#=-ACs{N2^-41!W6a;y5yl zJTa|+Z77cjFyaMV}BJ8BbNg_}dJE%H3O4UxuW-`MmU-E){$M5@04b!)Q-< z!ZCznaH8QVb_nbUG=f=!)`o1`lNXftM;(&wSCI)0Ltz^tzP!Im9u;8Ka?B)Qx!cbr zy+rs;JsQrDe*1QmS{a1Q*|!F=9C}Jf-Qr3Um(dUkCk5HlgP18^$jWPo9TgX6T}iq; zO*^GZ5Po}9_!{IrjeLm`vH$KuE#t@$XWAHpt+gY}FaY<$%w)0KoeD!?iNx`7?ZSET z$)(rh>k?J8))bEk7UW+LnyFUdo2pa=BC@gLm(&=v7rQ&)BKFJrUxi)S2r>s-rw=YkD8cX<*?!#?G#T0^^V@J$fhz z?ea7AlP;924D;|N^}X4T(4g(I#$hb;oZc97Q}kn<#_7ncweiU zo}%H{$3m@Ap9cjI+$#AUwNN3|w82WGIQTE5Sr4tChvBUun`&~W`&M2?ZAU$>Ve&Vz z!sD)s=mE>ln(R*fzkWAt)^E&y&~5v8;vXT5H`#8;*z>f~sia0wWi93Bjw}axES_Iv z-<|%Dl}p2m7>x!EfwqhER-03@$PeMY-C(@J2VcB~qF#h9k{q*z^_6RG5Xr2s z^F%KFI`ZyFE~InUoCd@8u<=NW=@Pgq_7wmq()v+v@k{8pIG#kO*ydiFlXocnN>d~0 zD}{6`VNBRKp9rVT)^^Eml0ZL&Jz*F%@<1(!oy{~Vq+Z_es1%>|^spR3M8+h@p^(mg zfq&YGPb?K(TjQJ=eg)a_gAHLRlr4qRR!A0UnH|;i*b@v#tT*VtK5H|l16EQLhd)>!{m4_ULfz)U*G82NKWZY? zf8Cwm`*IS=1L#9M7v!$FUNv@f{pwD~91EG8%k8O|uTHhT88^H~0VA#`JnRXXgv5d> zN)NwpUXyZ$Mo&%ym8d!5;I9n7_{!L6X1fsh-72 z(nak(5RwQkR_F%!C$mYi&5FxHgz4P*Xo06INsF;Qci zHyQ&>8l)ZbSdp@=k6L-UcVW!%-Sut0;3nbYudHi>3zO@225(gEl3T8ih0W{NA1_=tKVWsf`Z!^E~nnD9B5>9N?vY=W>+)>L-%MV0i zCW5jD)&MfU5_*m#-;aNi*=8x%c796wYIED+V$wYsU}j2m6LNL;x^k1>4+!h-O;OlA znJ{qs@iG<=*B^XUBTh}U_%S`5LDQ%q1sUY zq6Xtjz#wJ*EzxPsYm6DakTu(T$8YKdpSkXkht(3ht($$thgL|3-S1}f*VU{&N+o+?p_o)t|SbEfK1dT`jv~WU&t=qn)y==EBBC26f>)`2Oy~UnX>2Y!0pXj!`0` z^Xxqkk3IcX;7w{)$40RXy6C=fa zK(fKVB0uyF@h*@+?&ZCPUmN?4R?Pfkpz;@{!PZu@Z2Y0WlJ!|af=s`2fN%4a(?=8{ z1uOer^=LD`L~W-@=VA#CSg>F+l?ZAl@?-iQNot*4wk#g9VEB(}=i7-r!$>9tW1BG@ zWhW36R4nKOjD{0`UO*|r`eNv@$N0RcZs)llw-ZI*2~NUIEY^he857)MMyp@1#gI6r zO|&OS_a~|>i{X~NdnWe7Y#I74U~-)R52!falACy}AP|VoM##b7LLpWg*5iBJb~WE@ z;00nWc*eUg9jhA)6J+mwh3615MMzCA+FJ}@9#8*TZW?b1oP*Du4(gcZEs^3-qA&(B z>=U`g>H^FpPJ?AhX*$p7m{NunP1TIV2y^>UfAlX6oQ3%b7F9$%+=lFmL&Ux?naK4e zM=hnChn>VvIqkO?)!z@^iS-?YBh!X|QUKbHE%MF-@(Bh7eTK^h9j&fR%)QOXTl~vT z#r+e)3zFlT9fg|3hqR+PI>xOBA4i^}u$Y(Y&f{J&C^KfnOR;u6;CIHshV|PfHEFtP zKQV_WRYLL4B(7QEEMaRx;7Ng+{~$ZM*>}WHYvl)zQA?MgarTtMQS(^Qw9o ze31X1=qD%seJ9g`Wjmhdo6>i6-VgZ2iU?AK)(53wtkUELdv#(V45C8Ii;`1h*^G35 z3vGeLkA0Lys3RbAwJ|m_2%Wde4PxWlAwdW)f_-foA>Z)+y8h{o#npYRf~)n|g>tkr zN{tM5GJcq&^_AqQ4-OHg8jjrPJ~A-)1?T=|~qhKEfcB)8kCp>c+Ato}HS0uO~|NuA`3{o%m}#H(@Z zOi6!wf{eDflB&fK{Ul%en{K*;lDeR`ry21)_2koMt^NqFPb6S&`T`>!5K_pE!i0aP zwq+iEF_ofuar8x0#6zFnB{NalL zMC>Zna0gS<`0YMJ1whAaPp)Wd7A`SRL4Nr>$A55kX5D;RiSE&pqqNsv$}v-zxOanwnRUd4wdk4}ky+rFOAcy?S(}Y6HcCL5aBVA#;=bPdYkwvGy|P?lKr}WLNvYisu_=k z%E8BBQBg_XbQ9IIsniVnVQA>fbeJyz^~Ya}4Cj zJK(7;3U#wkVm`+ab3=~y)IBfjT9I{~!pOvC;u^--z*{a^*xmNoCb1h&^Z0(Tw0RL-@?KJ-;2ujR^XP0ni58q4rxf7)PH*;wKJYPek#w=|{nXD$T=bQAmdkk&|Lf_Vb3ys#jJ^l#~rj{~a^ z8;59)QoaGI%e51-S(Bfp`eBM?7qVP!&nxPfsv$!4n-}5^MA=g@!au|6E#bHcpm(YX zUWFnN@}yJ)IlCv$K#S3DSfx+~7cz1I;a&}-aW_X(VdJIQ_Q5VlZVaJc1{@sPeeVe7 zheJ3#`dcD?YTvhQOOHl^EaCeUy*A8?W6r=EXbEzaa6tk(t^z!s;TSlSeea3J3%lJb zM%pmij{%1>_~!efV4h1gLxz5W$CycK0HBhnV!C|Fr&xx#O|IG;LqT@LhQuBG*>VK2 zn|d|K^NKvf!tY_46`Bg%k~-r3@L}W1GfloIZnPqPIbfuukpUyPr^c+c{0*%gYl86T zr;Qo03@qG|;gYVCpEEx;t(I}Rtr8<)_7FCv#c{V1P@Tedn>jHcv%-+Po-5dnw;u-+ z7ay7&jryx2FXgq)8cGGW;<2P`^jZWcF-R>W8ulF}kHXQRgMwjEYg}bc-urDkj;jC?ltO&*ddRSz(KtnV;9T&9T? zxYVwMlbo}%h*MWrnPq!YM z9U61#2BQWge{inm6#?i1UmywJM4h@`LZtOHDuu0CLZE`c(O+`yR7G;yoAfnYl)#aK z%C>~kR(5D>(7-l@+UyY}_{+neD$IokS>i9mTD$J^ri)hWF;_il|5)8G_*iW8%l%fy zM|-|z)s$djDzQLuzr>Hb4G`DOyKw_ugg7kVuoEAr!;HuuOs>i;7)$Th8fVl709B6R zv=Hl_)u1$YeCvr2FRp0olqSz=tKj_u?%tD-E+nu{bKwx zJAE_PY4itMaStmzd}>{MtgHQrWZ_6R%J zZc~w`dPpgQA!Oup8h@_%PCJ?v*=;1BJpPX8L5I;4hqDOd`_<7R(F(GS3WDk?Yi}Pd zxyoY{nXiR@eN(JWLm!?2K}agi0IR1O&JoPPH@hao+U1VR-uo(=U)8^K z`#2ov9@9^noH!t#Ojn;O8j=8H?w&^7>mncBHODUiU@?hPPv~vW!ZRi%{MNGM8peyS45Vo`~cBOln?PT#ujfsG)VC#wK9G-Ke*h;Y>2XkpikCA7BZhts2< z-p$;%ABfd3VsC$(j}~PdXCC@SKl;R9niZYNt;A~)rc<3FUJL)&@w_?5yGb(H#t>d> zoZ;nce1E1TsiWdP+_=FmSi6`@%J?fUHl3$PKypTgjj@ewdOTgcurk}+jvz>8sqTeU z8TXSd@!*bf!r7HR_tqr1ON$C4LFNkHA*WUnRCktBZgu5&#(`+bHEG%jiQ)%2fR= z1a+3yL5nhpdk;91j^Utt?L(1IMoFyY*IBmOQM2+IWw;`|7yy0{!KZvaM3AK@8@UAS zSBM%pa+3i~RPK((QVHXm^is>(A%){*^)ShT1DW!z_RS5y$4N?OghN23#|1exZaMBu`N4UDUYjwECnI?A@Xn zS--H;AlH>Wp`9%FD_}%UbJfd*VlG+ zNZF<<{V>AFcxoAcJUa0R45ED*Pu)-rkKhupqERoi zpfERbqRMcHfBUvpur@k8dEutHe-9gu+_nH`X-C)DV3!&UcMrl%ysG8hJ5Uob6ZZ{n zKcyi_*_wF-IH0%haC_y0CbVIujWxes-YKw5>D-N)ZMF*sY04TRPf&D^W#=RSXT!-y z#6i>O>FGN1@M>?WWxI}@=N$VDz={*9Hr#$BY4F2L z&*6aEWv8;7;_+(Rm~+F*&hkD35G7ny`2l?i6>6n_h}U1kM$Hhcog@E*ai!@+){v28 zaCnfY?acJ;PKAIeRH!A}wiz)Ym?MP{1x#y21%4%RZJo2VcszeGF4Gq3u+$v)!4{pp zChMu88aOTGW6a$1nTUx58DrDui=Km);&A5$(j?_nxZ&&|Y~xj3(ipc%LwAOqU{x4y z(y?K+(bFMCZP|U?T^)KT&&YI=oBP+HXQSKZzbYiRAJ#>C1Wn5kgrND2%K_dZ@x@)w zyjRG%CW_rEh>|ARoop85xnqaQj6yp5Z%SKAKem^xloX ztQ#xEHh!X?1qHG7BY#$CL9;R#eym`wN+nH)lf$aF&G!j^rR=9v*Jg%^)dQ>urWcyH6%+ zINa{EDVf;p`Tr!sUkBEh9RqOV!ltJ^*#~eX$sY%`bOvy~dj#-0=0sUc52s=x4Nb@& zZfrWHv(%W8ODDBP$JPBOeeJe|Z>{4MQ?2!aR&vfWXa1)AEYumQv}W$z{qS&Aq|GyM z%X9cf9u&$to-!IlQpBP+YQHj!a9kS)tf)6@nM|^%wQ4iNlb$-=;x<%EI10r~Bsi^P zPQ+UC4C4=5?2kU#U7(O#S};99B};0{sy+$*Lw)?$-tUtk#P%c@5QhnFu#n4=iKT3I zx}Cn0>5HE?SuZk#rSj|vDd>bE6ZEt209(ljIMYIP5+C!1TV2228IgWs@7pBNr&Kqs zNm%Jdw&q>vGbNrT^AUbTqf!r%-Rvn;-jQiB*{i4j zx90rs3iM|`853ggsWUo=?-#Ia+m4kyDA8!Bw3Rba1(Vy=F3qv{y()r*MZ--_e?4`g z&**Y7TA)6&XLDJ~cm$Szn@WC~k;qo^Y>ALJv0|Mfqr`b>eg}~(m9E=dFK(ATyNcNT zCHk+!^GDl!KDuBqPa=Y*JwlV3h=ETyGMf9*)Rdd9p7BPb)7a>+NQQ(`Qkf>~B^bms zqPcW1ztgy7oH085dNq+MN%29p=l&L@dlRrNwAEPRdmBiN$ z;zaxN6aMt0XY%O(oD_ebEB8roRg@{|C*Tp{Z;1o zu>eC1Uc(|o`)~g0CovHBTWC2K&wuo4h`$a5A3ZR{_1FCQX#Y*te2WC)zE5PLY4nG3 z`L74U{`B_{_j#jZ{o@+t--kk;jaccVb$^Wpy{N&bIo{ZF+1UsJ2|7mhzUx}Qq* SsR|nK1yR;|SgB|c@_zs#uux(E literal 0 HcmV?d00001 diff --git a/docs/core/events.md b/docs/core/events.md index 0c7a272746a4..7d9f6f28a465 100644 --- a/docs/core/events.md +++ b/docs/core/events.md @@ -21,6 +21,8 @@ order: 7 `Event`s are returned to the underlying consensus engine in the response of the following ABCI messages: [`CheckTx`](./baseapp.md#checktx), [`DeliverTx`](./baseapp.md#delivertx), [`BeginBlock`](./baseapp.md#beginblock) and [`EndBlock`](./baseapp.md#endblock). +Typically, `event` `type`s and `attributes` are defined on a **per-module basis** in the module's `/internal/types/events.go` file, and triggered from the module's [`handler`](../building-modules/handler.md) via the [`EventManager`](#eventmanager). + ## EventManager In Cosmos SDK applications, `event`s are generally managed by an object called the [`EventManager`](https://github.com/cosmos/cosmos-sdk/blob/master/types/events.go#L18-L20). It is implemented as a simple wrapper around a slice of `event`s: @@ -46,6 +48,44 @@ ctx.EventManager().EmitEvent( See the [`handler` concept doc](../building-modules/handler.md) for a more detailed view on how to typically implement `events` and use the `EventManager` in modules. +## Subscribing to `events` + +It is possible to subscribe to `events` via [Tendermint's Websocket](https://tendermint.com/docs/app-dev/subscribing-to-events-via-websocket.html#subscribing-to-events-via-websocket). This is done by calling the `subscribe` RPC method via Websocket: + +``` +{ + "jsonrpc": "2.0", + "method": "subscribe", + "id": "0", + "params": { + "query": "tm.event='eventCategory' AND type.attribute='attributeValue'" + } +} +``` + +The main `eventCategory` you can subscribe to are: + +- `NewBlock`: Contains `events` triggered during `BeginBlock` and `EndBlock`. +- `Tx`: Contains `events` triggered during `DeliverTx` (i.e. transaction processing). +- `ValidatorSetUpdates`: Contains validator set updates for the block. + +These events are triggered from the `state` package after a block is committed. You can get the full list of `event` categories [here](https://godoc.org/github.com/tendermint/tendermint/types#pkg-constants). + +The `type` and `attribute` value of the `query` allow you to filter the specific `event` you are looking for. For example, a `transfer` transaction triggers an `event` of type `Transfer` and has `Recipient` and `Sender` as `attributes` (as defined in the [`events` file of the `bank` module](https://github.com/cosmos/cosmos-sdk/blob/master/x/bank/internal/types/events.go)). Subscribing to this `event` would be done like so: + +``` +{ + "jsonrpc": "2.0", + "method": "subscribe", + "id": "0", + "params": { + "query": "tm.event='Tx' AND transfer.sender='senderAddress'" + } +} +``` + +where `senderAddress` is an address following the [`AccAddress`](../basics/accounts.md#addresses) format. + ## Next Learn about [object-capabilities](./ocap.md) \ No newline at end of file diff --git a/docs/interfaces/rest.md b/docs/interfaces/rest.md index cad7d93e3b39..c0e69e441266 100644 --- a/docs/interfaces/rest.md +++ b/docs/interfaces/rest.md @@ -15,21 +15,23 @@ This document describes how to create a REST interface for an SDK **application* ## Application REST Interface -Building the REST Interface for an application involves creating a [REST server](./rest.md#rest-server) to route requests and output responses. The SDK comes with its own REST Server by default called the LCDs (for Light-Client Daemon). To enable it, the `lcd.ServeCommand` command should be added as a subcommand of the `rootCmd` in the `main()` function of the CLI interface: +Building the REST Interface for an application involves creating a [REST server](./rest.md#rest-server) to route requests and output responses. The SDK comes with its own REST Server by default. To enable it, the `rest.ServeCommand` command should be added as a subcommand of the `rootCmd` in the `main()` function of the CLI interface: ```go -rootCmd.AddCommand(lcd.ServeCommand(cdc, registerRoutes)) +rootCmd.AddCommand(rest.ServeCommand(cdc, registerRoutes)) ``` -Users can use the application CLI to start a new LCD, a local server through which they can securely interact with the application without downloading the entire state. The command entered by users would look something like this: +Users can use the application CLI to start a new REST server, a local server through which they can securely interact with the application without downloading the entire state. The command entered by users would look something like this: ```bash appcli rest-server --chain-id --trust-node ``` +Note that if `trust-node` is set to `false`, the REST server will verify the query proof against the merkle root (contained in the block header). + ## REST Server -A REST Server is used to receive and route HTTP Requests, obtain the results from the application, and return a response to the user. The REST Server defined by the SDK LCD package contains the following: +A REST Server is used to receive and route HTTP Requests, obtain the results from the application, and return a response to the user. The REST Server defined by the SDK `rest` package contains the following: * **Router:** A router for HTTP requests. A new router can be instantiated for an application and used to match routes based on path, request method, headers, etc. The SDK uses the [Gorilla Mux Router](https://github.com/gorilla/mux). * **CLIContext:** A [`CLIContext`](./query-lifecycle.md#clicontext) created for a user interaction. @@ -46,7 +48,7 @@ To include routes for each module in an application, the CLI must have some kind At the bare minimum, a `RegisterRoutes()` function should use the SDK client package `RegisterRoutes()` function to be able to route RPC calls, and instruct the application Module Manager to call `RegisterRESTRoutes()` for all of its modules. This is done in the `main.go` file of the CLI (typically located in `./cmd/appcli/main.go`). ```go -func registerRoutes(rs *lcd.RestServer) { +func registerRoutes(rs *rest.RestServer) { client.RegisterRoutes(rs.CliCtx, rs.Mux) app.ModuleBasics.RegisterRESTRoutes(rs.CliCtx, rs.Mux) } @@ -55,5 +57,5 @@ func registerRoutes(rs *lcd.RestServer) { This function is specific to the application and passed in to the `ServeCommand`, which should be added to the `rootCmd` as such: ```go -rootCmd.AddCommand(lcd.ServeCommand(cdc, registerRoutes)) +rootCmd.AddCommand(rest.ServeCommand(cdc, registerRoutes)) ``` diff --git a/docs/intro/intro.md b/docs/intro/intro.md index d530ae3c1892..5d6a574d66ec 100644 --- a/docs/intro/intro.md +++ b/docs/intro/intro.md @@ -23,7 +23,7 @@ To learn more about application-specific blockchains, [click here](./why-app-spe The Cosmos SDK is the most advanced framework for building custom application-specific blockchains today. Here are a few reasons why you might want to consider building your decentralised application with the Cosmos SDK: - The default consensus engine available within the SDK is [Tendermint Core](https://github.com/tendermint/tendermint). Tendermint is the most (and only) mature BFT consensus engine in existence. It is widely used across the industry and is considered the gold standard consensus engine for building Proof-of-Stake systems. -- The SDK is open source and designed to make it easy to build blockchains out of composable modules. As the ecosystem of open source SDK modules grows, it will become increasingly easier to build complex decentralised platforms with it. +- The SDK is open source and designed to make it easy to build blockchains out of composable [modules](../../x/). As the ecosystem of open source SDK modules grows, it will become increasingly easier to build complex decentralised platforms with it. - The SDK is inspired by capabilities-based security, and informed by years of wrestling with blockchain state-machines. This makes the Cosmos SDK a very secure environment to build blockchains. - Most importantly, the Cosmos SDK has already been used to build many application-specific blockchains that are already in production. Among others, we can cite [Cosmos Hub](https://hub.cosmos.network), [IRIS Hub](https://irisnet.org), [Binance Chain](https://docs.binance.org/), [Terra](https://terra.money/) or [Lino](https://lino.network/). Many more are building on the Cosmos SDK. You can get a view of the ecosystem [here](https://cosmos.network/ecosystem). From 72b821a7fda2240ece4a04308820d1759a7c66f9 Mon Sep 17 00:00:00 2001 From: gamarin Date: Tue, 5 Nov 2019 21:01:17 +0100 Subject: [PATCH 138/196] refine rest --- docs/interfaces/rest.md | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/docs/interfaces/rest.md b/docs/interfaces/rest.md index c0e69e441266..ca64d3e24a00 100644 --- a/docs/interfaces/rest.md +++ b/docs/interfaces/rest.md @@ -15,13 +15,13 @@ This document describes how to create a REST interface for an SDK **application* ## Application REST Interface -Building the REST Interface for an application involves creating a [REST server](./rest.md#rest-server) to route requests and output responses. The SDK comes with its own REST Server by default. To enable it, the `rest.ServeCommand` command should be added as a subcommand of the `rootCmd` in the `main()` function of the CLI interface: +Building the REST Interface for an application is done by [aggregating REST Routes](#registering-routes) defined in the application's modules. This interface is served by a REST Server [REST server](#rest-server), which route requests and output responses in the application itself. The SDK comes with its own REST Server by default. To enable it, the `rest.ServeCommand` command needs to be added as a subcommand of the `rootCmd` in the `main()` function of the [CLI interface](./cli.md): ```go rootCmd.AddCommand(rest.ServeCommand(cdc, registerRoutes)) ``` -Users can use the application CLI to start a new REST server, a local server through which they can securely interact with the application without downloading the entire state. The command entered by users would look something like this: +Users will then be able to use the application CLI to start a new REST server, a local server through which they can securely interact with the application without downloading the entire state. The command entered by users would look something like this: ```bash appcli rest-server --chain-id --trust-node @@ -41,6 +41,8 @@ A REST Server is used to receive and route HTTP Requests, obtain the results fro Of the five, the only attribute that application developers need interact with is the `router`: they need to add routes to it so that the REST server can properly handle queries. See the next section for more information on registering routes. +In order to enable the REST Server in an SDK application, the `rest.ServeCommand` needs to be added to the application's command-line interface. See the [above section](#application-rest-interface) for more information. + ## Registering Routes To include routes for each module in an application, the CLI must have some kind of function to register routes in its REST Server. This function is called `RegisterRoutes()`, and is utilized by the `ServeCommand` and must include routes for each of the application's modules. Since each module used by an SDK application implements a [`RegisterRESTRoutes`](../building-modules/module-interfaces.md#rest) function, application developers simply use the [Module Manager](../building-modules/module-manager.md) to call this function for each module (this is done in the [application's constructor](../basics/app-anatomy.md#constructor-function)). From 3e55e780a8e4d31a25f2c9d2a663ea1035848ab3 Mon Sep 17 00:00:00 2001 From: Denis Fadeev Date: Thu, 7 Nov 2019 16:19:39 -0500 Subject: [PATCH 139/196] index page --- docs/.vuepress/config.js | 8 +- docs/README.md | 57 ++++ docs/modules/readme.md | 5 + docs/package-lock.json | 603 +++++++++++++++++++-------------------- docs/package.json | 3 +- 5 files changed, 360 insertions(+), 316 deletions(-) create mode 100644 docs/modules/readme.md diff --git a/docs/.vuepress/config.js b/docs/.vuepress/config.js index 50273aefb9d3..cf4a27961c39 100644 --- a/docs/.vuepress/config.js +++ b/docs/.vuepress/config.js @@ -35,14 +35,14 @@ module.exports = { children: [ { title: "Riot Chat", - text: "Chat with Tendermint developers on Riot Chat.", - highlighted: "500+ people chatting now" + text: "[Chat with Cosmos developers](https://riot.im/app/#/room/#cosmos-sdk:matrix.org) on Riot Chat.", + highlighted: "**500+** people chatting now" }, { title: "Cosmos SDK Forum", - text: "Found an Issue?", + text: "[Join the SDK Developer Forum](https://forum.cosmos.network/) to learn more.", highlighted: - "Help us improve this page by suggesting edits on GitHub." + "**1038** active developers." } ] }, diff --git a/docs/README.md b/docs/README.md index 036e73eab884..c2f667bd938d 100644 --- a/docs/README.md +++ b/docs/README.md @@ -1,3 +1,60 @@ +--- +layout: index +title: Documentation +description: The Cosmos-SDK is a framework for building blockchain applications in Golang. It is being used to build Gaia, the first implementation of the Cosmos Hub. +features: + - cta: Read + title: Introduction to Cosmos SDK + desc: Learn about all the parts of the Cosmos SDK. + label: 5 min + url: /intro/ + image: spaceship + - cta: Learn + title: SDK Tutorial + desc: Build a complete blockchain application from scratch. + label: 30-40 min + special: dark + h3: View tutorials + url: https://tutorials.cosmos.network/ + image: window +sections: + - title: Introduction + desc: Short sentence describing this section. + url: /intro + icon: introduction + - title: Basics + desc: Short sentence describing this section. + icon: basics + url: /basics + - title: SDK Core + desc: Short sentence describing this section. + icon: core + url: /core + - title: Building Modules + desc: Short sentence describing this section. + icon: modules + url: /building-modules + - title: Interfaces + desc: Short sentence describing this section. + icon: interfaces + url: /interfaces + - title: Specifications + desc: Short sentence describing this section. + icon: specifications + url: / +stack: + - title: Cosmos Hub + desc: Short description about Cosmos Hub, no longer than a few of lines. + color: "#BA3FD9" + label: hub + url: http://hub.cosmos.network + - title: Tendermint + desc: Short description about Tendermint, no longer than a few of lines. + color: "#00BB00" + label: core + url: http://docs.tendermint.com +--- + # Cosmos SDK Documentation ## Get Started diff --git a/docs/modules/readme.md b/docs/modules/readme.md new file mode 100644 index 000000000000..227820933900 --- /dev/null +++ b/docs/modules/readme.md @@ -0,0 +1,5 @@ +--- +order: false +parent: + order: false +--- \ No newline at end of file diff --git a/docs/package-lock.json b/docs/package-lock.json index 35e058c30c62..cdba55e6bda4 100644 --- a/docs/package-lock.json +++ b/docs/package-lock.json @@ -13,17 +13,17 @@ } }, "@babel/core": { - "version": "7.6.4", - "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.6.4.tgz", - "integrity": "sha512-Rm0HGw101GY8FTzpWSyRbki/jzq+/PkNQJ+nSulrdY6gFGOsNseCqD6KHRYe2E+EdzuBdr2pxCp6s4Uk6eJ+XQ==", + "version": "7.7.0", + "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.7.0.tgz", + "integrity": "sha512-Bb1NjZCaiwTQC/ARL+MwDpgocdnwWDCaugvkGt6cxfBzQa8Whv1JybBoUEiBDKl8Ni3H3c7Fykwk7QChUsHRlg==", "requires": { "@babel/code-frame": "^7.5.5", - "@babel/generator": "^7.6.4", - "@babel/helpers": "^7.6.2", - "@babel/parser": "^7.6.4", - "@babel/template": "^7.6.0", - "@babel/traverse": "^7.6.3", - "@babel/types": "^7.6.3", + "@babel/generator": "^7.7.0", + "@babel/helpers": "^7.7.0", + "@babel/parser": "^7.7.0", + "@babel/template": "^7.7.0", + "@babel/traverse": "^7.7.0", + "@babel/types": "^7.7.0", "convert-source-map": "^1.1.0", "debug": "^4.1.0", "json5": "^2.1.0", @@ -62,11 +62,11 @@ } }, "@babel/generator": { - "version": "7.6.4", - "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.6.4.tgz", - "integrity": "sha512-jsBuXkFoZxk0yWLyGI9llT9oiQ2FeTASmRFE32U+aaDTfoE92t78eroO7PTpU/OrYq38hlcDM6vbfLDaOLy+7w==", + "version": "7.7.0", + "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.7.0.tgz", + "integrity": "sha512-1wdJ6UxHyL1XoJQ119JmvuRX27LRih7iYStMPZOWAjQqeAabFg3dYXKMpgihma+to+0ADsTVVt6oRyUxWZw6Mw==", "requires": { - "@babel/types": "^7.6.3", + "@babel/types": "^7.7.0", "jsesc": "^2.5.1", "lodash": "^4.17.13", "source-map": "^0.5.0" @@ -80,125 +80,134 @@ } }, "@babel/helper-annotate-as-pure": { - "version": "7.0.0", - "resolved": "https://registry.npmjs.org/@babel/helper-annotate-as-pure/-/helper-annotate-as-pure-7.0.0.tgz", - "integrity": "sha512-3UYcJUj9kvSLbLbUIfQTqzcy5VX7GRZ/CCDrnOaZorFFM01aXp1+GJwuFGV4NDDoAS+mOUyHcO6UD/RfqOks3Q==", + "version": "7.7.0", + "resolved": "https://registry.npmjs.org/@babel/helper-annotate-as-pure/-/helper-annotate-as-pure-7.7.0.tgz", + "integrity": "sha512-k50CQxMlYTYo+GGyUGFwpxKVtxVJi9yh61sXZji3zYHccK9RYliZGSTOgci85T+r+0VFN2nWbGM04PIqwfrpMg==", "requires": { - "@babel/types": "^7.0.0" + "@babel/types": "^7.7.0" } }, "@babel/helper-builder-binary-assignment-operator-visitor": { - "version": "7.1.0", - "resolved": "https://registry.npmjs.org/@babel/helper-builder-binary-assignment-operator-visitor/-/helper-builder-binary-assignment-operator-visitor-7.1.0.tgz", - "integrity": "sha512-qNSR4jrmJ8M1VMM9tibvyRAHXQs2PmaksQF7c1CGJNipfe3D8p+wgNwgso/P2A2r2mdgBWAXljNWR0QRZAMW8w==", + "version": "7.7.0", + "resolved": "https://registry.npmjs.org/@babel/helper-builder-binary-assignment-operator-visitor/-/helper-builder-binary-assignment-operator-visitor-7.7.0.tgz", + "integrity": "sha512-Cd8r8zs4RKDwMG/92lpZcnn5WPQ3LAMQbCw42oqUh4s7vsSN5ANUZjMel0OOnxDLq57hoDDbai+ryygYfCTOsw==", "requires": { - "@babel/helper-explode-assignable-expression": "^7.1.0", - "@babel/types": "^7.0.0" + "@babel/helper-explode-assignable-expression": "^7.7.0", + "@babel/types": "^7.7.0" } }, "@babel/helper-call-delegate": { - "version": "7.4.4", - "resolved": "https://registry.npmjs.org/@babel/helper-call-delegate/-/helper-call-delegate-7.4.4.tgz", - "integrity": "sha512-l79boDFJ8S1c5hvQvG+rc+wHw6IuH7YldmRKsYtpbawsxURu/paVy57FZMomGK22/JckepaikOkY0MoAmdyOlQ==", + "version": "7.7.0", + "resolved": "https://registry.npmjs.org/@babel/helper-call-delegate/-/helper-call-delegate-7.7.0.tgz", + "integrity": "sha512-Su0Mdq7uSSWGZayGMMQ+z6lnL00mMCnGAbO/R0ZO9odIdB/WNU/VfQKqMQU0fdIsxQYbRjDM4BixIa93SQIpvw==", "requires": { - "@babel/helper-hoist-variables": "^7.4.4", - "@babel/traverse": "^7.4.4", - "@babel/types": "^7.4.4" + "@babel/helper-hoist-variables": "^7.7.0", + "@babel/traverse": "^7.7.0", + "@babel/types": "^7.7.0" } }, "@babel/helper-create-class-features-plugin": { - "version": "7.6.0", - "resolved": "https://registry.npmjs.org/@babel/helper-create-class-features-plugin/-/helper-create-class-features-plugin-7.6.0.tgz", - "integrity": "sha512-O1QWBko4fzGju6VoVvrZg0RROCVifcLxiApnGP3OWfWzvxRZFCoBD81K5ur5e3bVY2Vf/5rIJm8cqPKn8HUJng==", + "version": "7.7.0", + "resolved": "https://registry.npmjs.org/@babel/helper-create-class-features-plugin/-/helper-create-class-features-plugin-7.7.0.tgz", + "integrity": "sha512-MZiB5qvTWoyiFOgootmRSDV1udjIqJW/8lmxgzKq6oDqxdmHUjeP2ZUOmgHdYjmUVNABqRrHjYAYRvj8Eox/UA==", "requires": { - "@babel/helper-function-name": "^7.1.0", - "@babel/helper-member-expression-to-functions": "^7.5.5", - "@babel/helper-optimise-call-expression": "^7.0.0", + "@babel/helper-function-name": "^7.7.0", + "@babel/helper-member-expression-to-functions": "^7.7.0", + "@babel/helper-optimise-call-expression": "^7.7.0", "@babel/helper-plugin-utils": "^7.0.0", - "@babel/helper-replace-supers": "^7.5.5", - "@babel/helper-split-export-declaration": "^7.4.4" + "@babel/helper-replace-supers": "^7.7.0", + "@babel/helper-split-export-declaration": "^7.7.0" + } + }, + "@babel/helper-create-regexp-features-plugin": { + "version": "7.7.0", + "resolved": "https://registry.npmjs.org/@babel/helper-create-regexp-features-plugin/-/helper-create-regexp-features-plugin-7.7.0.tgz", + "integrity": "sha512-ZhagAAVGD3L6MPM9/zZi7RRteonfBFLVUz3kjsnYsMAtr9hOJCKI9BAKIMpqn3NyWicPieoX779UL+7/3BEAOA==", + "requires": { + "@babel/helper-regex": "^7.4.4", + "regexpu-core": "^4.6.0" } }, "@babel/helper-define-map": { - "version": "7.5.5", - "resolved": "https://registry.npmjs.org/@babel/helper-define-map/-/helper-define-map-7.5.5.tgz", - "integrity": "sha512-fTfxx7i0B5NJqvUOBBGREnrqbTxRh7zinBANpZXAVDlsZxYdclDp467G1sQ8VZYMnAURY3RpBUAgOYT9GfzHBg==", + "version": "7.7.0", + "resolved": "https://registry.npmjs.org/@babel/helper-define-map/-/helper-define-map-7.7.0.tgz", + "integrity": "sha512-kPKWPb0dMpZi+ov1hJiwse9dWweZsz3V9rP4KdytnX1E7z3cTNmFGglwklzFPuqIcHLIY3bgKSs4vkwXXdflQA==", "requires": { - "@babel/helper-function-name": "^7.1.0", - "@babel/types": "^7.5.5", + "@babel/helper-function-name": "^7.7.0", + "@babel/types": "^7.7.0", "lodash": "^4.17.13" } }, "@babel/helper-explode-assignable-expression": { - "version": "7.1.0", - "resolved": "https://registry.npmjs.org/@babel/helper-explode-assignable-expression/-/helper-explode-assignable-expression-7.1.0.tgz", - "integrity": "sha512-NRQpfHrJ1msCHtKjbzs9YcMmJZOg6mQMmGRB+hbamEdG5PNpaSm95275VD92DvJKuyl0s2sFiDmMZ+EnnvufqA==", + "version": "7.7.0", + "resolved": "https://registry.npmjs.org/@babel/helper-explode-assignable-expression/-/helper-explode-assignable-expression-7.7.0.tgz", + "integrity": "sha512-CDs26w2shdD1urNUAji2RJXyBFCaR+iBEGnFz3l7maizMkQe3saVw9WtjG1tz8CwbjvlFnaSLVhgnu1SWaherg==", "requires": { - "@babel/traverse": "^7.1.0", - "@babel/types": "^7.0.0" + "@babel/traverse": "^7.7.0", + "@babel/types": "^7.7.0" } }, "@babel/helper-function-name": { - "version": "7.1.0", - "resolved": "https://registry.npmjs.org/@babel/helper-function-name/-/helper-function-name-7.1.0.tgz", - "integrity": "sha512-A95XEoCpb3TO+KZzJ4S/5uW5fNe26DjBGqf1o9ucyLyCmi1dXq/B3c8iaWTfBk3VvetUxl16e8tIrd5teOCfGw==", + "version": "7.7.0", + "resolved": "https://registry.npmjs.org/@babel/helper-function-name/-/helper-function-name-7.7.0.tgz", + "integrity": "sha512-tDsJgMUAP00Ugv8O2aGEua5I2apkaQO7lBGUq1ocwN3G23JE5Dcq0uh3GvFTChPa4b40AWiAsLvCZOA2rdnQ7Q==", "requires": { - "@babel/helper-get-function-arity": "^7.0.0", - "@babel/template": "^7.1.0", - "@babel/types": "^7.0.0" + "@babel/helper-get-function-arity": "^7.7.0", + "@babel/template": "^7.7.0", + "@babel/types": "^7.7.0" } }, "@babel/helper-get-function-arity": { - "version": "7.0.0", - "resolved": "https://registry.npmjs.org/@babel/helper-get-function-arity/-/helper-get-function-arity-7.0.0.tgz", - "integrity": "sha512-r2DbJeg4svYvt3HOS74U4eWKsUAMRH01Z1ds1zx8KNTPtpTL5JAsdFv8BNyOpVqdFhHkkRDIg5B4AsxmkjAlmQ==", + "version": "7.7.0", + "resolved": "https://registry.npmjs.org/@babel/helper-get-function-arity/-/helper-get-function-arity-7.7.0.tgz", + "integrity": "sha512-tLdojOTz4vWcEnHWHCuPN5P85JLZWbm5Fx5ZsMEMPhF3Uoe3O7awrbM2nQ04bDOUToH/2tH/ezKEOR8zEYzqyw==", "requires": { - "@babel/types": "^7.0.0" + "@babel/types": "^7.7.0" } }, "@babel/helper-hoist-variables": { - "version": "7.4.4", - "resolved": "https://registry.npmjs.org/@babel/helper-hoist-variables/-/helper-hoist-variables-7.4.4.tgz", - "integrity": "sha512-VYk2/H/BnYbZDDg39hr3t2kKyifAm1W6zHRfhx8jGjIHpQEBv9dry7oQ2f3+J703TLu69nYdxsovl0XYfcnK4w==", + "version": "7.7.0", + "resolved": "https://registry.npmjs.org/@babel/helper-hoist-variables/-/helper-hoist-variables-7.7.0.tgz", + "integrity": "sha512-LUe/92NqsDAkJjjCEWkNe+/PcpnisvnqdlRe19FahVapa4jndeuJ+FBiTX1rcAKWKcJGE+C3Q3tuEuxkSmCEiQ==", "requires": { - "@babel/types": "^7.4.4" + "@babel/types": "^7.7.0" } }, "@babel/helper-member-expression-to-functions": { - "version": "7.5.5", - "resolved": "https://registry.npmjs.org/@babel/helper-member-expression-to-functions/-/helper-member-expression-to-functions-7.5.5.tgz", - "integrity": "sha512-5qZ3D1uMclSNqYcXqiHoA0meVdv+xUEex9em2fqMnrk/scphGlGgg66zjMrPJESPwrFJ6sbfFQYUSa0Mz7FabA==", + "version": "7.7.0", + "resolved": "https://registry.npmjs.org/@babel/helper-member-expression-to-functions/-/helper-member-expression-to-functions-7.7.0.tgz", + "integrity": "sha512-QaCZLO2RtBcmvO/ekOLp8p7R5X2JriKRizeDpm5ChATAFWrrYDcDxPuCIBXKyBjY+i1vYSdcUTMIb8psfxHDPA==", "requires": { - "@babel/types": "^7.5.5" + "@babel/types": "^7.7.0" } }, "@babel/helper-module-imports": { - "version": "7.0.0", - "resolved": "https://registry.npmjs.org/@babel/helper-module-imports/-/helper-module-imports-7.0.0.tgz", - "integrity": "sha512-aP/hlLq01DWNEiDg4Jn23i+CXxW/owM4WpDLFUbpjxe4NS3BhLVZQ5i7E0ZrxuQ/vwekIeciyamgB1UIYxxM6A==", + "version": "7.7.0", + "resolved": "https://registry.npmjs.org/@babel/helper-module-imports/-/helper-module-imports-7.7.0.tgz", + "integrity": "sha512-Dv3hLKIC1jyfTkClvyEkYP2OlkzNvWs5+Q8WgPbxM5LMeorons7iPP91JM+DU7tRbhqA1ZeooPaMFvQrn23RHw==", "requires": { - "@babel/types": "^7.0.0" + "@babel/types": "^7.7.0" } }, "@babel/helper-module-transforms": { - "version": "7.5.5", - "resolved": "https://registry.npmjs.org/@babel/helper-module-transforms/-/helper-module-transforms-7.5.5.tgz", - "integrity": "sha512-jBeCvETKuJqeiaCdyaheF40aXnnU1+wkSiUs/IQg3tB85up1LyL8x77ClY8qJpuRJUcXQo+ZtdNESmZl4j56Pw==", - "requires": { - "@babel/helper-module-imports": "^7.0.0", - "@babel/helper-simple-access": "^7.1.0", - "@babel/helper-split-export-declaration": "^7.4.4", - "@babel/template": "^7.4.4", - "@babel/types": "^7.5.5", + "version": "7.7.0", + "resolved": "https://registry.npmjs.org/@babel/helper-module-transforms/-/helper-module-transforms-7.7.0.tgz", + "integrity": "sha512-rXEefBuheUYQyX4WjV19tuknrJFwyKw0HgzRwbkyTbB+Dshlq7eqkWbyjzToLrMZk/5wKVKdWFluiAsVkHXvuQ==", + "requires": { + "@babel/helper-module-imports": "^7.7.0", + "@babel/helper-simple-access": "^7.7.0", + "@babel/helper-split-export-declaration": "^7.7.0", + "@babel/template": "^7.7.0", + "@babel/types": "^7.7.0", "lodash": "^4.17.13" } }, "@babel/helper-optimise-call-expression": { - "version": "7.0.0", - "resolved": "https://registry.npmjs.org/@babel/helper-optimise-call-expression/-/helper-optimise-call-expression-7.0.0.tgz", - "integrity": "sha512-u8nd9NQePYNQV8iPWu/pLLYBqZBa4ZaY1YWRFMuxrid94wKI1QNt67NEZ7GAe5Kc/0LLScbim05xZFWkAdrj9g==", + "version": "7.7.0", + "resolved": "https://registry.npmjs.org/@babel/helper-optimise-call-expression/-/helper-optimise-call-expression-7.7.0.tgz", + "integrity": "sha512-48TeqmbazjNU/65niiiJIJRc5JozB8acui1OS7bSd6PgxfuovWsvjfWSzlgx+gPFdVveNzUdpdIg5l56Pl5jqg==", "requires": { - "@babel/types": "^7.0.0" + "@babel/types": "^7.7.0" } }, "@babel/helper-plugin-utils": { @@ -215,64 +224,64 @@ } }, "@babel/helper-remap-async-to-generator": { - "version": "7.1.0", - "resolved": "https://registry.npmjs.org/@babel/helper-remap-async-to-generator/-/helper-remap-async-to-generator-7.1.0.tgz", - "integrity": "sha512-3fOK0L+Fdlg8S5al8u/hWE6vhufGSn0bN09xm2LXMy//REAF8kDCrYoOBKYmA8m5Nom+sV9LyLCwrFynA8/slg==", + "version": "7.7.0", + "resolved": "https://registry.npmjs.org/@babel/helper-remap-async-to-generator/-/helper-remap-async-to-generator-7.7.0.tgz", + "integrity": "sha512-pHx7RN8X0UNHPB/fnuDnRXVZ316ZigkO8y8D835JlZ2SSdFKb6yH9MIYRU4fy/KPe5sPHDFOPvf8QLdbAGGiyw==", "requires": { - "@babel/helper-annotate-as-pure": "^7.0.0", - "@babel/helper-wrap-function": "^7.1.0", - "@babel/template": "^7.1.0", - "@babel/traverse": "^7.1.0", - "@babel/types": "^7.0.0" + "@babel/helper-annotate-as-pure": "^7.7.0", + "@babel/helper-wrap-function": "^7.7.0", + "@babel/template": "^7.7.0", + "@babel/traverse": "^7.7.0", + "@babel/types": "^7.7.0" } }, "@babel/helper-replace-supers": { - "version": "7.5.5", - "resolved": "https://registry.npmjs.org/@babel/helper-replace-supers/-/helper-replace-supers-7.5.5.tgz", - "integrity": "sha512-XvRFWrNnlsow2u7jXDuH4jDDctkxbS7gXssrP4q2nUD606ukXHRvydj346wmNg+zAgpFx4MWf4+usfC93bElJg==", + "version": "7.7.0", + "resolved": "https://registry.npmjs.org/@babel/helper-replace-supers/-/helper-replace-supers-7.7.0.tgz", + "integrity": "sha512-5ALYEul5V8xNdxEeWvRsBzLMxQksT7MaStpxjJf9KsnLxpAKBtfw5NeMKZJSYDa0lKdOcy0g+JT/f5mPSulUgg==", "requires": { - "@babel/helper-member-expression-to-functions": "^7.5.5", - "@babel/helper-optimise-call-expression": "^7.0.0", - "@babel/traverse": "^7.5.5", - "@babel/types": "^7.5.5" + "@babel/helper-member-expression-to-functions": "^7.7.0", + "@babel/helper-optimise-call-expression": "^7.7.0", + "@babel/traverse": "^7.7.0", + "@babel/types": "^7.7.0" } }, "@babel/helper-simple-access": { - "version": "7.1.0", - "resolved": "https://registry.npmjs.org/@babel/helper-simple-access/-/helper-simple-access-7.1.0.tgz", - "integrity": "sha512-Vk+78hNjRbsiu49zAPALxTb+JUQCz1aolpd8osOF16BGnLtseD21nbHgLPGUwrXEurZgiCOUmvs3ExTu4F5x6w==", + "version": "7.7.0", + "resolved": "https://registry.npmjs.org/@babel/helper-simple-access/-/helper-simple-access-7.7.0.tgz", + "integrity": "sha512-AJ7IZD7Eem3zZRuj5JtzFAptBw7pMlS3y8Qv09vaBWoFsle0d1kAn5Wq6Q9MyBXITPOKnxwkZKoAm4bopmv26g==", "requires": { - "@babel/template": "^7.1.0", - "@babel/types": "^7.0.0" + "@babel/template": "^7.7.0", + "@babel/types": "^7.7.0" } }, "@babel/helper-split-export-declaration": { - "version": "7.4.4", - "resolved": "https://registry.npmjs.org/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.4.4.tgz", - "integrity": "sha512-Ro/XkzLf3JFITkW6b+hNxzZ1n5OQ80NvIUdmHspih1XAhtN3vPTuUFT4eQnela+2MaZ5ulH+iyP513KJrxbN7Q==", + "version": "7.7.0", + "resolved": "https://registry.npmjs.org/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.7.0.tgz", + "integrity": "sha512-HgYSI8rH08neWlAH3CcdkFg9qX9YsZysZI5GD8LjhQib/mM0jGOZOVkoUiiV2Hu978fRtjtsGsW6w0pKHUWtqA==", "requires": { - "@babel/types": "^7.4.4" + "@babel/types": "^7.7.0" } }, "@babel/helper-wrap-function": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/@babel/helper-wrap-function/-/helper-wrap-function-7.2.0.tgz", - "integrity": "sha512-o9fP1BZLLSrYlxYEYyl2aS+Flun5gtjTIG8iln+XuEzQTs0PLagAGSXUcqruJwD5fM48jzIEggCKpIfWTcR7pQ==", + "version": "7.7.0", + "resolved": "https://registry.npmjs.org/@babel/helper-wrap-function/-/helper-wrap-function-7.7.0.tgz", + "integrity": "sha512-sd4QjeMgQqzshSjecZjOp8uKfUtnpmCyQhKQrVJBBgeHAB/0FPi33h3AbVlVp07qQtMD4QgYSzaMI7VwncNK/w==", "requires": { - "@babel/helper-function-name": "^7.1.0", - "@babel/template": "^7.1.0", - "@babel/traverse": "^7.1.0", - "@babel/types": "^7.2.0" + "@babel/helper-function-name": "^7.7.0", + "@babel/template": "^7.7.0", + "@babel/traverse": "^7.7.0", + "@babel/types": "^7.7.0" } }, "@babel/helpers": { - "version": "7.6.2", - "resolved": "https://registry.npmjs.org/@babel/helpers/-/helpers-7.6.2.tgz", - "integrity": "sha512-3/bAUL8zZxYs1cdX2ilEE0WobqbCmKWr/889lf2SS0PpDcpEIY8pb1CCyz0pEcX3pEb+MCbks1jIokz2xLtGTA==", + "version": "7.7.0", + "resolved": "https://registry.npmjs.org/@babel/helpers/-/helpers-7.7.0.tgz", + "integrity": "sha512-VnNwL4YOhbejHb7x/b5F39Zdg5vIQpUUNzJwx0ww1EcVRt41bbGRZWhAURrfY32T5zTT3qwNOQFWpn+P0i0a2g==", "requires": { - "@babel/template": "^7.6.0", - "@babel/traverse": "^7.6.2", - "@babel/types": "^7.6.0" + "@babel/template": "^7.7.0", + "@babel/traverse": "^7.7.0", + "@babel/types": "^7.7.0" } }, "@babel/highlight": { @@ -286,35 +295,35 @@ } }, "@babel/parser": { - "version": "7.6.4", - "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.6.4.tgz", - "integrity": "sha512-D8RHPW5qd0Vbyo3qb+YjO5nvUVRTXFLQ/FsDxJU2Nqz4uB5EnUN0ZQSEYpvTIbRuttig1XbHWU5oMeQwQSAA+A==" + "version": "7.7.0", + "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.7.0.tgz", + "integrity": "sha512-GqL+Z0d7B7ADlQBMXlJgvXEbtt5qlqd1YQ5fr12hTSfh7O/vgrEIvJxU2e7aSVrEUn75zTZ6Nd0s8tthrlZnrQ==" }, "@babel/plugin-proposal-async-generator-functions": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-async-generator-functions/-/plugin-proposal-async-generator-functions-7.2.0.tgz", - "integrity": "sha512-+Dfo/SCQqrwx48ptLVGLdE39YtWRuKc/Y9I5Fy0P1DDBB9lsAHpjcEJQt+4IifuSOSTLBKJObJqMvaO1pIE8LQ==", + "version": "7.7.0", + "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-async-generator-functions/-/plugin-proposal-async-generator-functions-7.7.0.tgz", + "integrity": "sha512-ot/EZVvf3mXtZq0Pd0+tSOfGWMizqmOohXmNZg6LNFjHOV+wOPv7BvVYh8oPR8LhpIP3ye8nNooKL50YRWxpYA==", "requires": { "@babel/helper-plugin-utils": "^7.0.0", - "@babel/helper-remap-async-to-generator": "^7.1.0", + "@babel/helper-remap-async-to-generator": "^7.7.0", "@babel/plugin-syntax-async-generators": "^7.2.0" } }, "@babel/plugin-proposal-class-properties": { - "version": "7.5.5", - "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-class-properties/-/plugin-proposal-class-properties-7.5.5.tgz", - "integrity": "sha512-AF79FsnWFxjlaosgdi421vmYG6/jg79bVD0dpD44QdgobzHKuLZ6S3vl8la9qIeSwGi8i1fS0O1mfuDAAdo1/A==", + "version": "7.7.0", + "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-class-properties/-/plugin-proposal-class-properties-7.7.0.tgz", + "integrity": "sha512-tufDcFA1Vj+eWvwHN+jvMN6QsV5o+vUlytNKrbMiCeDL0F2j92RURzUsUMWE5EJkLyWxjdUslCsMQa9FWth16A==", "requires": { - "@babel/helper-create-class-features-plugin": "^7.5.5", + "@babel/helper-create-class-features-plugin": "^7.7.0", "@babel/helper-plugin-utils": "^7.0.0" } }, "@babel/plugin-proposal-decorators": { - "version": "7.6.0", - "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-decorators/-/plugin-proposal-decorators-7.6.0.tgz", - "integrity": "sha512-ZSyYw9trQI50sES6YxREXKu+4b7MAg6Qx2cvyDDYjP2Hpzd3FleOUwC9cqn1+za8d0A2ZU8SHujxFao956efUg==", + "version": "7.7.0", + "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-decorators/-/plugin-proposal-decorators-7.7.0.tgz", + "integrity": "sha512-dMCDKmbYFQQTn1+VJjl5hbqlweuHl5oDeMU9B1Q7oAWi0mHxjQQDHdJIK6iW76NE1KJT3zA6dDU3weR1WT5D4A==", "requires": { - "@babel/helper-create-class-features-plugin": "^7.6.0", + "@babel/helper-create-class-features-plugin": "^7.7.0", "@babel/helper-plugin-utils": "^7.0.0", "@babel/plugin-syntax-decorators": "^7.2.0" } @@ -347,13 +356,12 @@ } }, "@babel/plugin-proposal-unicode-property-regex": { - "version": "7.6.2", - "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-unicode-property-regex/-/plugin-proposal-unicode-property-regex-7.6.2.tgz", - "integrity": "sha512-NxHETdmpeSCtiatMRYWVJo7266rrvAC3DTeG5exQBIH/fMIUK7ejDNznBbn3HQl/o9peymRRg7Yqkx6PdUXmMw==", + "version": "7.7.0", + "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-unicode-property-regex/-/plugin-proposal-unicode-property-regex-7.7.0.tgz", + "integrity": "sha512-mk34H+hp7kRBWJOOAR0ZMGCydgKMD4iN9TpDRp3IIcbunltxEY89XSimc6WbtSLCDrwcdy/EEw7h5CFCzxTchw==", "requires": { - "@babel/helper-plugin-utils": "^7.0.0", - "@babel/helper-regex": "^7.4.4", - "regexpu-core": "^4.6.0" + "@babel/helper-create-regexp-features-plugin": "^7.7.0", + "@babel/helper-plugin-utils": "^7.0.0" } }, "@babel/plugin-syntax-async-generators": { @@ -421,13 +429,13 @@ } }, "@babel/plugin-transform-async-to-generator": { - "version": "7.5.0", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-async-to-generator/-/plugin-transform-async-to-generator-7.5.0.tgz", - "integrity": "sha512-mqvkzwIGkq0bEF1zLRRiTdjfomZJDV33AH3oQzHVGkI2VzEmXLpKKOBvEVaFZBJdN0XTyH38s9j/Kiqr68dggg==", + "version": "7.7.0", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-async-to-generator/-/plugin-transform-async-to-generator-7.7.0.tgz", + "integrity": "sha512-vLI2EFLVvRBL3d8roAMqtVY0Bm9C1QzLkdS57hiKrjUBSqsQYrBsMCeOg/0KK7B0eK9V71J5mWcha9yyoI2tZw==", "requires": { - "@babel/helper-module-imports": "^7.0.0", + "@babel/helper-module-imports": "^7.7.0", "@babel/helper-plugin-utils": "^7.0.0", - "@babel/helper-remap-async-to-generator": "^7.1.0" + "@babel/helper-remap-async-to-generator": "^7.7.0" } }, "@babel/plugin-transform-block-scoped-functions": { @@ -448,17 +456,17 @@ } }, "@babel/plugin-transform-classes": { - "version": "7.5.5", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-classes/-/plugin-transform-classes-7.5.5.tgz", - "integrity": "sha512-U2htCNK/6e9K7jGyJ++1p5XRU+LJjrwtoiVn9SzRlDT2KubcZ11OOwy3s24TjHxPgxNwonCYP7U2K51uVYCMDg==", - "requires": { - "@babel/helper-annotate-as-pure": "^7.0.0", - "@babel/helper-define-map": "^7.5.5", - "@babel/helper-function-name": "^7.1.0", - "@babel/helper-optimise-call-expression": "^7.0.0", + "version": "7.7.0", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-classes/-/plugin-transform-classes-7.7.0.tgz", + "integrity": "sha512-/b3cKIZwGeUesZheU9jNYcwrEA7f/Bo4IdPmvp7oHgvks2majB5BoT5byAql44fiNQYOPzhk2w8DbgfuafkMoA==", + "requires": { + "@babel/helper-annotate-as-pure": "^7.7.0", + "@babel/helper-define-map": "^7.7.0", + "@babel/helper-function-name": "^7.7.0", + "@babel/helper-optimise-call-expression": "^7.7.0", "@babel/helper-plugin-utils": "^7.0.0", - "@babel/helper-replace-supers": "^7.5.5", - "@babel/helper-split-export-declaration": "^7.4.4", + "@babel/helper-replace-supers": "^7.7.0", + "@babel/helper-split-export-declaration": "^7.7.0", "globals": "^11.1.0" } }, @@ -479,13 +487,12 @@ } }, "@babel/plugin-transform-dotall-regex": { - "version": "7.6.2", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-dotall-regex/-/plugin-transform-dotall-regex-7.6.2.tgz", - "integrity": "sha512-KGKT9aqKV+9YMZSkowzYoYEiHqgaDhGmPNZlZxX6UeHC4z30nC1J9IrZuGqbYFB1jaIGdv91ujpze0exiVK8bA==", + "version": "7.7.0", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-dotall-regex/-/plugin-transform-dotall-regex-7.7.0.tgz", + "integrity": "sha512-3QQlF7hSBnSuM1hQ0pS3pmAbWLax/uGNCbPBND9y+oJ4Y776jsyujG2k0Sn2Aj2a0QwVOiOFL5QVPA7spjvzSA==", "requires": { - "@babel/helper-plugin-utils": "^7.0.0", - "@babel/helper-regex": "^7.4.4", - "regexpu-core": "^4.6.0" + "@babel/helper-create-regexp-features-plugin": "^7.7.0", + "@babel/helper-plugin-utils": "^7.0.0" } }, "@babel/plugin-transform-duplicate-keys": { @@ -514,11 +521,11 @@ } }, "@babel/plugin-transform-function-name": { - "version": "7.4.4", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-function-name/-/plugin-transform-function-name-7.4.4.tgz", - "integrity": "sha512-iU9pv7U+2jC9ANQkKeNF6DrPy4GBa4NWQtl6dHB4Pb3izX2JOEvDTFarlNsBj/63ZEzNNIAMs3Qw4fNCcSOXJA==", + "version": "7.7.0", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-function-name/-/plugin-transform-function-name-7.7.0.tgz", + "integrity": "sha512-P5HKu0d9+CzZxP5jcrWdpe7ZlFDe24bmqP6a6X8BHEBl/eizAsY8K6LX8LASZL0Jxdjm5eEfzp+FIrxCm/p8bA==", "requires": { - "@babel/helper-function-name": "^7.1.0", + "@babel/helper-function-name": "^7.7.0", "@babel/helper-plugin-utils": "^7.0.0" } }, @@ -541,41 +548,41 @@ } }, "@babel/plugin-transform-modules-commonjs": { - "version": "7.6.0", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-commonjs/-/plugin-transform-modules-commonjs-7.6.0.tgz", - "integrity": "sha512-Ma93Ix95PNSEngqomy5LSBMAQvYKVe3dy+JlVJSHEXZR5ASL9lQBedMiCyVtmTLraIDVRE3ZjTZvmXXD2Ozw3g==", + "version": "7.7.0", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-commonjs/-/plugin-transform-modules-commonjs-7.7.0.tgz", + "integrity": "sha512-KEMyWNNWnjOom8vR/1+d+Ocz/mILZG/eyHHO06OuBQ2aNhxT62fr4y6fGOplRx+CxCSp3IFwesL8WdINfY/3kg==", "requires": { - "@babel/helper-module-transforms": "^7.4.4", + "@babel/helper-module-transforms": "^7.7.0", "@babel/helper-plugin-utils": "^7.0.0", - "@babel/helper-simple-access": "^7.1.0", + "@babel/helper-simple-access": "^7.7.0", "babel-plugin-dynamic-import-node": "^2.3.0" } }, "@babel/plugin-transform-modules-systemjs": { - "version": "7.5.0", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-systemjs/-/plugin-transform-modules-systemjs-7.5.0.tgz", - "integrity": "sha512-Q2m56tyoQWmuNGxEtUyeEkm6qJYFqs4c+XyXH5RAuYxObRNz9Zgj/1g2GMnjYp2EUyEy7YTrxliGCXzecl/vJg==", + "version": "7.7.0", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-systemjs/-/plugin-transform-modules-systemjs-7.7.0.tgz", + "integrity": "sha512-ZAuFgYjJzDNv77AjXRqzQGlQl4HdUM6j296ee4fwKVZfhDR9LAGxfvXjBkb06gNETPnN0sLqRm9Gxg4wZH6dXg==", "requires": { - "@babel/helper-hoist-variables": "^7.4.4", + "@babel/helper-hoist-variables": "^7.7.0", "@babel/helper-plugin-utils": "^7.0.0", "babel-plugin-dynamic-import-node": "^2.3.0" } }, "@babel/plugin-transform-modules-umd": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-umd/-/plugin-transform-modules-umd-7.2.0.tgz", - "integrity": "sha512-BV3bw6MyUH1iIsGhXlOK6sXhmSarZjtJ/vMiD9dNmpY8QXFFQTj+6v92pcfy1iqa8DeAfJFwoxcrS/TUZda6sw==", + "version": "7.7.0", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-umd/-/plugin-transform-modules-umd-7.7.0.tgz", + "integrity": "sha512-u7eBA03zmUswQ9LQ7Qw0/ieC1pcAkbp5OQatbWUzY1PaBccvuJXUkYzoN1g7cqp7dbTu6Dp9bXyalBvD04AANA==", "requires": { - "@babel/helper-module-transforms": "^7.1.0", + "@babel/helper-module-transforms": "^7.7.0", "@babel/helper-plugin-utils": "^7.0.0" } }, "@babel/plugin-transform-named-capturing-groups-regex": { - "version": "7.6.3", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-named-capturing-groups-regex/-/plugin-transform-named-capturing-groups-regex-7.6.3.tgz", - "integrity": "sha512-jTkk7/uE6H2s5w6VlMHeWuH+Pcy2lmdwFoeWCVnvIrDUnB5gQqTVI8WfmEAhF2CDEarGrknZcmSFg1+bkfCoSw==", + "version": "7.7.0", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-named-capturing-groups-regex/-/plugin-transform-named-capturing-groups-regex-7.7.0.tgz", + "integrity": "sha512-+SicSJoKouPctL+j1pqktRVCgy+xAch1hWWTMy13j0IflnyNjaoskj+DwRQFimHbLqO3sq2oN2CXMvXq3Bgapg==", "requires": { - "regexpu-core": "^4.6.0" + "@babel/helper-create-regexp-features-plugin": "^7.7.0" } }, "@babel/plugin-transform-new-target": { @@ -606,9 +613,9 @@ } }, "@babel/plugin-transform-regenerator": { - "version": "7.4.5", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-regenerator/-/plugin-transform-regenerator-7.4.5.tgz", - "integrity": "sha512-gBKRh5qAaCWntnd09S8QC7r3auLCqq5DI6O0DlfoyDjslSBVqBibrMdsqO+Uhmx3+BlOmE/Kw1HFxmGbv0N9dA==", + "version": "7.7.0", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-regenerator/-/plugin-transform-regenerator-7.7.0.tgz", + "integrity": "sha512-AXmvnC+0wuj/cFkkS/HFHIojxH3ffSXE+ttulrqWjZZRaUOonfJc60e1wSNT4rV8tIunvu/R3wCp71/tLAa9xg==", "requires": { "regenerator-transform": "^0.14.0" } @@ -667,13 +674,12 @@ } }, "@babel/plugin-transform-unicode-regex": { - "version": "7.6.2", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-unicode-regex/-/plugin-transform-unicode-regex-7.6.2.tgz", - "integrity": "sha512-orZI6cWlR3nk2YmYdb0gImrgCUwb5cBUwjf6Ks6dvNVvXERkwtJWOQaEOjPiu0Gu1Tq6Yq/hruCZZOOi9F34Dw==", + "version": "7.7.0", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-unicode-regex/-/plugin-transform-unicode-regex-7.7.0.tgz", + "integrity": "sha512-RrThb0gdrNwFAqEAAx9OWgtx6ICK69x7i9tCnMdVrxQwSDp/Abu9DXFU5Hh16VP33Rmxh04+NGW28NsIkFvFKA==", "requires": { - "@babel/helper-plugin-utils": "^7.0.0", - "@babel/helper-regex": "^7.4.4", - "regexpu-core": "^4.6.0" + "@babel/helper-create-regexp-features-plugin": "^7.7.0", + "@babel/helper-plugin-utils": "^7.0.0" } }, "@babel/preset-env": { @@ -727,9 +733,9 @@ } }, "@babel/runtime": { - "version": "7.6.3", - "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.6.3.tgz", - "integrity": "sha512-kq6anf9JGjW8Nt5rYfEuGRaEAaH1mkv3Bbu6rYvLOpPh/RusSJXuKPEAoZ7L7gybZkchE8+NV5g9vKF4AGAtsA==", + "version": "7.7.1", + "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.7.1.tgz", + "integrity": "sha512-SQ0sS7KUJDvgCI2cpZG0nJygO6002oTbhgSuw4WcocsnbxLwL5Q8I3fqbJdyBAc3uFrWZiR2JomseuxSuci3SQ==", "requires": { "regenerator-runtime": "^0.13.2" }, @@ -742,9 +748,9 @@ } }, "@babel/runtime-corejs2": { - "version": "7.6.3", - "resolved": "https://registry.npmjs.org/@babel/runtime-corejs2/-/runtime-corejs2-7.6.3.tgz", - "integrity": "sha512-nuA2o+rgX2+PrNTZ063ehncVcg7sn+tU71BB81SaWRVUbGwCOlb0+yQA1e0QqmzOfRSYOxfvf8cosYqFbJEiwQ==", + "version": "7.7.1", + "resolved": "https://registry.npmjs.org/@babel/runtime-corejs2/-/runtime-corejs2-7.7.1.tgz", + "integrity": "sha512-nlxajcFXWFyrFOyzOkphfby2izqoB9B4a3+rMqG4dBKMaHZUUS3BkgFBIAbNK6s+VOx0vaGJVgaQL0+3oWnxDQ==", "requires": { "core-js": "^2.6.5", "regenerator-runtime": "^0.13.2" @@ -758,26 +764,26 @@ } }, "@babel/template": { - "version": "7.6.0", - "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.6.0.tgz", - "integrity": "sha512-5AEH2EXD8euCk446b7edmgFdub/qfH1SN6Nii3+fyXP807QRx9Q73A2N5hNwRRslC2H9sNzaFhsPubkS4L8oNQ==", + "version": "7.7.0", + "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.7.0.tgz", + "integrity": "sha512-OKcwSYOW1mhWbnTBgQY5lvg1Fxg+VyfQGjcBduZFljfc044J5iDlnDSfhQ867O17XHiSCxYHUxHg2b7ryitbUQ==", "requires": { "@babel/code-frame": "^7.0.0", - "@babel/parser": "^7.6.0", - "@babel/types": "^7.6.0" + "@babel/parser": "^7.7.0", + "@babel/types": "^7.7.0" } }, "@babel/traverse": { - "version": "7.6.3", - "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.6.3.tgz", - "integrity": "sha512-unn7P4LGsijIxaAJo/wpoU11zN+2IaClkQAxcJWBNCMS6cmVh802IyLHNkAjQ0iYnRS3nnxk5O3fuXW28IMxTw==", + "version": "7.7.0", + "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.7.0.tgz", + "integrity": "sha512-ea/3wRZc//e/uwCpuBX2itrhI0U9l7+FsrKWyKGNyvWbuMcCG7ATKY2VI4wlg2b2TA39HHwIxnvmXvtiKsyn7w==", "requires": { "@babel/code-frame": "^7.5.5", - "@babel/generator": "^7.6.3", - "@babel/helper-function-name": "^7.1.0", - "@babel/helper-split-export-declaration": "^7.4.4", - "@babel/parser": "^7.6.3", - "@babel/types": "^7.6.3", + "@babel/generator": "^7.7.0", + "@babel/helper-function-name": "^7.7.0", + "@babel/helper-split-export-declaration": "^7.7.0", + "@babel/parser": "^7.7.0", + "@babel/types": "^7.7.0", "debug": "^4.1.0", "globals": "^11.1.0", "lodash": "^4.17.13" @@ -799,9 +805,9 @@ } }, "@babel/types": { - "version": "7.6.3", - "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.6.3.tgz", - "integrity": "sha512-CqbcpTxMcpuQTMhjI37ZHVgjBkysg5icREQIEZ0eG1yCNwg3oy+5AaLiOKmjsCj6nqOsa6Hf0ObjRVwokb7srA==", + "version": "7.7.1", + "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.7.1.tgz", + "integrity": "sha512-kN/XdANDab9x1z5gcjDc9ePpxexkt+1EQ2MQUiM4XnMvQfvp87/+6kY4Ko2maLXH+tei/DgJ/ybFITeqqRwDiA==", "requires": { "esutils": "^2.0.2", "lodash": "^4.17.13", @@ -816,9 +822,9 @@ } }, "@cosmos-ui/vue": { - "version": "0.5.12", - "resolved": "https://registry.npmjs.org/@cosmos-ui/vue/-/vue-0.5.12.tgz", - "integrity": "sha512-xMGrZtwCBgu7XQyXEHPacUbxZDl4rw7eM9saLhBvBWGb2NBSBZR+L8LFg64QMsR68jFLHj4wnXXsIRcvIHF/Dw==", + "version": "0.5.16", + "resolved": "https://registry.npmjs.org/@cosmos-ui/vue/-/vue-0.5.16.tgz", + "integrity": "sha512-Z4byEoZLkIbumm3SlnrzwuyvDi6vzWv2GfT36QuaPFWusCShGgc47ehXp2S55tKrNajOIiF9bfgasHRL6mfHFA==", "requires": { "vue": "^2.6.10" } @@ -871,9 +877,9 @@ "integrity": "sha512-tHq6qdbT9U1IRSGf14CL0pUlULksvY9OZ+5eEgl1N7t+OA3tGvNpxJCzuKQlsNgCVwbAs670L1vcVQi8j9HjnA==" }, "@types/node": { - "version": "12.11.6", - "resolved": "https://registry.npmjs.org/@types/node/-/node-12.11.6.tgz", - "integrity": "sha512-4uPUyY1Aofo1YzoypalYHNd2SnKYxH2b6LzXwpryZCJKA2XlagZSynXx5C8sfPH0r1cSltUpaVHV2q5sYXschQ==" + "version": "12.12.6", + "resolved": "https://registry.npmjs.org/@types/node/-/node-12.12.6.tgz", + "integrity": "sha512-FjsYUPzEJdGXjwKqSpE0/9QEh6kzhTAeObA54rn6j3rR4C/mzpI9L0KNfoeASSPMMdxIsoJuCLDWcM/rVjIsSA==" }, "@types/q": { "version": "1.5.2", @@ -985,9 +991,9 @@ } }, "@vue/component-compiler-utils": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/@vue/component-compiler-utils/-/component-compiler-utils-3.0.0.tgz", - "integrity": "sha512-am+04/0UX7ektcmvhYmrf84BDVAD8afFOf4asZjN84q8xzxFclbk5x0MtxuKGfp+zjN5WWPJn3fjFAWtDdIGSw==", + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/@vue/component-compiler-utils/-/component-compiler-utils-3.0.2.tgz", + "integrity": "sha512-BSnY2PmW4QwU1AOcGSNYAmEPLjdQ9itl1YpLCWtpwMA5Jy/aqWNuzZ9+ZZ8h6yZJ53W95tVkEP6yrXJ/zUHdEA==", "requires": { "consolidate": "^0.15.1", "hash-sum": "^1.0.2", @@ -995,7 +1001,7 @@ "merge-source-map": "^1.1.0", "postcss": "^7.0.14", "postcss-selector-parser": "^5.0.0", - "prettier": "1.16.3", + "prettier": "^1.18.2", "source-map": "~0.6.1", "vue-template-es2015-compiler": "^1.9.0" }, @@ -1669,16 +1675,16 @@ } }, "autoprefixer": { - "version": "9.7.0", - "resolved": "https://registry.npmjs.org/autoprefixer/-/autoprefixer-9.7.0.tgz", - "integrity": "sha512-j2IRvaCfrUxIiZun9ba4mhJ2omhw4OY88/yVzLO+lHhGBumAAK72PgM6gkbSN8iregPOn1ZlxGkmZh2CQ7X4AQ==", + "version": "9.7.1", + "resolved": "https://registry.npmjs.org/autoprefixer/-/autoprefixer-9.7.1.tgz", + "integrity": "sha512-w3b5y1PXWlhYulevrTJ0lizkQ5CyqfeU6BIRDbuhsMupstHQOeb1Ur80tcB1zxSu7AwyY/qCQ7Vvqklh31ZBFw==", "requires": { "browserslist": "^4.7.2", - "caniuse-lite": "^1.0.30001004", + "caniuse-lite": "^1.0.30001006", "chalk": "^2.4.2", "normalize-range": "^0.1.2", "num2fraction": "^1.2.2", - "postcss": "^7.0.19", + "postcss": "^7.0.21", "postcss-value-parser": "^4.0.2" } }, @@ -2159,9 +2165,9 @@ } }, "caniuse-lite": { - "version": "1.0.30001004", - "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001004.tgz", - "integrity": "sha512-3nfOR4O8Wa2RWoYfJkMtwRVOsK96TQ+eq57wd0iKaEWl8dwG4hKZ/g0MVBfCvysFvMLi9fQGR/DvozMdkEPl3g==" + "version": "1.0.30001008", + "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001008.tgz", + "integrity": "sha512-b8DJyb+VVXZGRgJUa30cbk8gKHZ3LOZTBLaUEEVr2P4xpmFigOCc62CO4uzquW641Ouq1Rm9N+rWLWdSYDaDIw==" }, "caseless": { "version": "0.12.0", @@ -2428,12 +2434,9 @@ "integrity": "sha512-4sxpH6SGFYLADfUip4vuY65f/gEogrzJoniVhNUYkJHtng0l8ZjnDCqxxrSVRHOHwKxsy8Vm5ONZh1wOR3/l/w==" }, "console-browserify": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/console-browserify/-/console-browserify-1.1.0.tgz", - "integrity": "sha1-8CQcRXMKn8YyOyBtvzjtx0HQuxA=", - "requires": { - "date-now": "^0.1.4" - } + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/console-browserify/-/console-browserify-1.2.0.tgz", + "integrity": "sha512-ZMkYO/LkF17QvCPqM0gxw8yUzigAOZOSWSHg91FH6orS7vcEj5dVZTidN2fQ14yBSdg97RqhSNwLUXInd52OTA==" }, "consolidate": { "version": "0.15.1", @@ -2473,9 +2476,9 @@ "integrity": "sha512-hIP3EEPs8tB9AT1L+NUqtwOAps4mk2Zob89MWXMHjHWg9milF/j4osnnQLXBCBFBk/tvIG/tUc9mOUJiPBhPXA==" }, "convert-source-map": { - "version": "1.6.0", - "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-1.6.0.tgz", - "integrity": "sha512-eFu7XigvxdZ1ETfbgPBohgyQ/Z++C0eEhTor0qRwBw9unw+L0/6V8wkSuGgzdThkiS5lSpdptOQPD8Ak40a+7A==", + "version": "1.7.0", + "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-1.7.0.tgz", + "integrity": "sha512-4FJkXzKXEDB1snCFZlLP4gpC3JILicCpGbzG9f9G7tGqGCzETQ2hWPrcinA9oU4wtf2biUaEH5065UnMeR33oA==", "requires": { "safe-buffer": "~5.1.1" } @@ -2735,19 +2738,12 @@ "integrity": "sha512-jQVeeRG70QI08vSTwf1jHxp74JoZsr2XSgETae8/xC8ovSnL2WF87GTLO86Sbwdt2lK4Umg4HnnwMO4YF3Ce7w==" }, "css-tree": { - "version": "1.0.0-alpha.33", - "resolved": "https://registry.npmjs.org/css-tree/-/css-tree-1.0.0-alpha.33.tgz", - "integrity": "sha512-SPt57bh5nQnpsTBsx/IXbO14sRc9xXu5MtMAVuo0BaQQmyf0NupNPPSoMaqiAF5tDFafYsTkfeH4Q/HCKXkg4w==", + "version": "1.0.0-alpha.37", + "resolved": "https://registry.npmjs.org/css-tree/-/css-tree-1.0.0-alpha.37.tgz", + "integrity": "sha512-DMxWJg0rnz7UgxKT0Q1HU/L9BeJI0M6ksor0OgqOnF+aRCDWg/N2641HmVyU9KVIu0OVVWOb2IpC9A+BJRnejg==", "requires": { "mdn-data": "2.0.4", - "source-map": "^0.5.3" - }, - "dependencies": { - "source-map": { - "version": "0.5.7", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz", - "integrity": "sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w=" - } + "source-map": "^0.6.1" } }, "css-unit-converter": { @@ -2837,32 +2833,11 @@ "integrity": "sha512-WcKx5OY+KoSIAxBW6UBBRay1U6vkYheCdjyVNDm85zt5K9mHoGOfsOsqIszfAqrQQFIIKgjh2+FDgIj/zsl21Q==" }, "csso": { - "version": "3.5.1", - "resolved": "https://registry.npmjs.org/csso/-/csso-3.5.1.tgz", - "integrity": "sha512-vrqULLffYU1Q2tLdJvaCYbONStnfkfimRxXNaGjxMldI0C7JPBC4rB1RyjhfdZ4m1frm8pM9uRPKH3d2knZ8gg==", + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/csso/-/csso-4.0.2.tgz", + "integrity": "sha512-kS7/oeNVXkHWxby5tHVxlhjizRCSv8QdU7hB2FpdAibDU8FjTAolhNjKNTiLzXtUrKT6HwClE81yXwEk1309wg==", "requires": { - "css-tree": "1.0.0-alpha.29" - }, - "dependencies": { - "css-tree": { - "version": "1.0.0-alpha.29", - "resolved": "https://registry.npmjs.org/css-tree/-/css-tree-1.0.0-alpha.29.tgz", - "integrity": "sha512-sRNb1XydwkW9IOci6iB2xmy8IGCj6r/fr+JWitvJ2JxQRPzN3T4AGGVWCMlVmVwM1gtgALJRmGIlWv5ppnGGkg==", - "requires": { - "mdn-data": "~1.1.0", - "source-map": "^0.5.3" - } - }, - "mdn-data": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/mdn-data/-/mdn-data-1.1.4.tgz", - "integrity": "sha512-FSYbp3lyKjyj3E7fMl6rYvUdX0FBXaluGqlFoYESWQlyUTq8R+wp0rkFxoYFqZlHCvsUXGjyJmLQSnXToYhOSA==" - }, - "source-map": { - "version": "0.5.7", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz", - "integrity": "sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w=" - } + "css-tree": "1.0.0-alpha.37" } }, "cyclist": { @@ -2878,11 +2853,6 @@ "assert-plus": "^1.0.0" } }, - "date-now": { - "version": "0.1.4", - "resolved": "https://registry.npmjs.org/date-now/-/date-now-0.1.4.tgz", - "integrity": "sha1-6vQ5/U1ISK105cx9vvIAZyueNFs=" - }, "de-indent": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/de-indent/-/de-indent-1.0.2.tgz", @@ -3212,9 +3182,9 @@ "integrity": "sha1-WQxhFWsK4vTwJVcyoViyZrxWsh0=" }, "electron-to-chromium": { - "version": "1.3.295", - "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.3.295.tgz", - "integrity": "sha512-KxlGE9GcZTv7xGwYJGMEABHJq2JuTMNF7jD8NwHk6sBY226mW+Dyp9kZmA2Od9tKHMCS7ltPnqFg+zq3jTWN7Q==" + "version": "1.3.304", + "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.3.304.tgz", + "integrity": "sha512-a5mqa13jCdBc+Crgk3Gyr7vpXCiFWfFq23YDCEmrPYeiDOQKZDVE6EX/Q4Xdv97n3XkcjiSBDOY0IS19yP2yeA==" }, "elliptic": { "version": "6.5.1", @@ -4855,6 +4825,11 @@ "ipaddr.js": "^1.9.0" } }, + "intersection-observer": { + "version": "0.7.0", + "resolved": "https://registry.npmjs.org/intersection-observer/-/intersection-observer-0.7.0.tgz", + "integrity": "sha512-Id0Fij0HsB/vKWGeBe9PxeY45ttRiBmhFyyt/geBdDHBYNctMRTE3dC1U3ujzz3lap+hVXlEcVaB56kZP/eEUg==" + }, "invariant": { "version": "2.2.4", "resolved": "https://registry.npmjs.org/invariant/-/invariant-2.2.4.tgz", @@ -5810,9 +5785,9 @@ } }, "node-releases": { - "version": "1.1.38", - "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-1.1.38.tgz", - "integrity": "sha512-/5NZAaOyTj134Oy5Cp/J8mso8OD/D9CSuL+6TOXXsTKO8yjc5e4up75SRPCganCjwFKMj2jbp5tR0dViVdox7g==", + "version": "1.1.39", + "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-1.1.39.tgz", + "integrity": "sha512-8MRC/ErwNCHOlAFycy9OPca46fQYUjbJRDcZTHVWIGXIjYLM73k70vv3WkYutVnM4cCo4hE0MqBVVZjP6vjISA==", "requires": { "semver": "^6.3.0" }, @@ -6327,9 +6302,9 @@ "integrity": "sha1-AerA/jta9xoqbAL+q7jB/vfgDqs=" }, "postcss": { - "version": "7.0.20", - "resolved": "https://registry.npmjs.org/postcss/-/postcss-7.0.20.tgz", - "integrity": "sha512-VOdO3a5nHVftPSEbG1zaG320b4mH5KAflH+pIeVAF5/hlw6YumELSgHZQBekjg29Oj4qw7XAyp9tIEBpeNWcyg==", + "version": "7.0.21", + "resolved": "https://registry.npmjs.org/postcss/-/postcss-7.0.21.tgz", + "integrity": "sha512-uIFtJElxJo29QC753JzhidoAhvp/e/Exezkdhfmt8AymWT6/5B7W1WmponYWkHk2eg6sONyTch0A3nkMPun3SQ==", "requires": { "chalk": "^2.4.2", "source-map": "^0.6.1", @@ -6883,9 +6858,9 @@ "integrity": "sha1-6SQ0v6XqjBn0HN/UAddBo8gZ2Jc=" }, "prettier": { - "version": "1.16.3", - "resolved": "https://registry.npmjs.org/prettier/-/prettier-1.16.3.tgz", - "integrity": "sha512-kn/GU6SMRYPxUakNXhpP0EedT/KmaPzr0H5lIsDogrykbaxOpOfAFfk5XA7DZrJyMAv1wlMV3CPcZruGXVVUZw==" + "version": "1.18.2", + "resolved": "https://registry.npmjs.org/prettier/-/prettier-1.18.2.tgz", + "integrity": "sha512-OeHeMc0JhFE9idD4ZdtNibzY0+TPHSpSSb9h8FqtP+YnoZZ1sl8Vc9b1sasjfymH3SonAF4QcA2+mzHPhMvIiw==" }, "pretty-error": { "version": "2.1.1", @@ -7959,9 +7934,9 @@ } }, "source-map-support": { - "version": "0.5.13", - "resolved": "https://registry.npmjs.org/source-map-support/-/source-map-support-0.5.13.tgz", - "integrity": "sha512-SHSKFHadjVA5oR4PPqhtAVdcBWwRYVd6g6cAXnIbRiIwc2EhPrTuKUBdSLvlEKyIP3GCf89fltvcZiP9MMFA1w==", + "version": "0.5.16", + "resolved": "https://registry.npmjs.org/source-map-support/-/source-map-support-0.5.16.tgz", + "integrity": "sha512-efyLRJDr68D9hBBNIPWFjhpFzURh+KJykQwvMyW5UiZzYwoF6l4YMMDIJJEyFWxWCqfyxLzz6tSfUFR+kXXsVQ==", "requires": { "buffer-from": "^1.0.0", "source-map": "^0.6.0" @@ -8297,16 +8272,16 @@ "integrity": "sha1-WPcc7jvVGbWdSyqEO2x95krAR2Q=" }, "svgo": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/svgo/-/svgo-1.3.0.tgz", - "integrity": "sha512-MLfUA6O+qauLDbym+mMZgtXCGRfIxyQoeH6IKVcFslyODEe/ElJNwr0FohQ3xG4C6HK6bk3KYPPXwHVJk3V5NQ==", + "version": "1.3.2", + "resolved": "https://registry.npmjs.org/svgo/-/svgo-1.3.2.tgz", + "integrity": "sha512-yhy/sQYxR5BkC98CY7o31VGsg014AKLEPxdfhora76l36hD9Rdy5NZA/Ocn6yayNPgSamYdtX2rFJdcv07AYVw==", "requires": { "chalk": "^2.4.1", "coa": "^2.0.2", "css-select": "^2.0.0", "css-select-base-adapter": "^0.1.1", - "css-tree": "1.0.0-alpha.33", - "csso": "^3.5.1", + "css-tree": "1.0.0-alpha.37", + "csso": "^4.0.2", "js-yaml": "^3.13.1", "mkdirp": "~0.5.1", "object.values": "^1.1.0", @@ -8818,9 +8793,9 @@ } }, "vm-browserify": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/vm-browserify/-/vm-browserify-1.1.0.tgz", - "integrity": "sha512-iq+S7vZJE60yejDYM0ek6zg308+UZsdtPExWP9VZoCFCz1zkJoXFnAX7aZfd/ZwrkidzdUZL0C/ryW+JwAiIGw==" + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/vm-browserify/-/vm-browserify-1.1.2.tgz", + "integrity": "sha512-2ham8XPWTONajOR0ohOKOHXkm3+gaBmGut3SRuu75xLd/RRaY6vqgh8NBYYk7+RW3u5AtzPQZG8F10LHkl0lAQ==" }, "void-elements": { "version": "2.0.1", @@ -8838,9 +8813,9 @@ "integrity": "sha512-BXq3jwIagosjgNVae6tkHzzIk6a8MHFtzAdwhnV5VlvPTFxDCvIttgSiHWjdGoTJvXtmRu5HacExfdarRcFhog==" }, "vue-loader": { - "version": "15.7.1", - "resolved": "https://registry.npmjs.org/vue-loader/-/vue-loader-15.7.1.tgz", - "integrity": "sha512-fwIKtA23Pl/rqfYP5TSGK7gkEuLhoTvRYW+TU7ER3q9GpNLt/PjG5NLv3XHRDiTg7OPM1JcckBgds+VnAc+HbA==", + "version": "15.7.2", + "resolved": "https://registry.npmjs.org/vue-loader/-/vue-loader-15.7.2.tgz", + "integrity": "sha512-H/P9xt/nkocyu4hZKg5TzPqyCT1oKOaCSk9zs0JCbJuy0Q8KtR0bjJpnT/5R5x/Ckd1GFkkLQnQ1C4x6xXeLZg==", "requires": { "@vue/component-compiler-utils": "^3.0.0", "hash-sum": "^1.0.2", @@ -8987,21 +8962,27 @@ } }, "vuepress-theme-cosmos": { - "version": "1.0.35", - "resolved": "https://registry.npmjs.org/vuepress-theme-cosmos/-/vuepress-theme-cosmos-1.0.35.tgz", - "integrity": "sha512-JB8674x4izaCMpRgG+GKYslA9KiiyhpfCjG8LpWg2//ynnZGUlPW9R+fzciM9+KIfU5eC4G7bquQwf19Nqi3Xg==", + "version": "1.0.41", + "resolved": "https://registry.npmjs.org/vuepress-theme-cosmos/-/vuepress-theme-cosmos-1.0.41.tgz", + "integrity": "sha512-C0X4rqSmsRPvWQXUvStf3FJvQDkRAQGsBdJryO+F2mLRsgK5Unp/YKBFvy02iPN/wD6TFr1ywaKISebQzj1w8w==", "requires": { - "@cosmos-ui/vue": "^0.5.11", + "@cosmos-ui/vue": "^0.5.16", "@vuepress/plugin-last-updated": "^1.2.0", "@vuepress/plugin-search": "^1.1.0", + "intersection-observer": "^0.7.0", "pug": "^2.0.4", "pug-plain-loader": "^1.0.0", "stylus": "^0.54.7", "stylus-loader": "^3.0.2", "tm-tooltip": "0.0.10", - "vuepress": "^1.1.0" + "vuepress": "^1.2.0" } }, + "vuepress-theme-docs": { + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/vuepress-theme-docs/-/vuepress-theme-docs-1.0.7.tgz", + "integrity": "sha512-OU1VvSuJaUg5nMSGiURE06T4P93DGbAm3W6zXkqWcSixEi4/B0RsLI61uzf15s1HeXOaU6CQECOs7bw8/7MHZw==" + }, "watchpack": { "version": "1.6.0", "resolved": "https://registry.npmjs.org/watchpack/-/watchpack-1.6.0.tgz", diff --git a/docs/package.json b/docs/package.json index f8f9d5b335af..fc1634b15f71 100644 --- a/docs/package.json +++ b/docs/package.json @@ -14,6 +14,7 @@ "author": "", "license": "ISC", "dependencies": { - "vuepress-theme-cosmos": "^1.0.35" + "vuepress-theme-cosmos": "^1.0.41", + "vuepress-theme-docs": "^1.0.7" } } From 1b4ce5253619b5ba8cd44a1935925a96e7abbd5f Mon Sep 17 00:00:00 2001 From: Denis Fadeev Date: Thu, 7 Nov 2019 16:43:40 -0500 Subject: [PATCH 140/196] sidebar --- docs/.vuepress/config.js | 17 +++++++++++++++-- 1 file changed, 15 insertions(+), 2 deletions(-) diff --git a/docs/.vuepress/config.js b/docs/.vuepress/config.js index cf4a27961c39..1dfcea7279a9 100644 --- a/docs/.vuepress/config.js +++ b/docs/.vuepress/config.js @@ -15,16 +15,29 @@ module.exports = { label: "sdk", sidebar: [ { - title: "Resources", + title: "Using the SDK", children: [ { title: "Modules", directory: true, path: "/modules/" - }, + } + ] + }, + { + title: "Resources", + children: [ { title: "Tutorials", path: "https://github.com/cosmos/sdk-application-tutorial" + }, + { + title: "SDK API Reference", + path: "https://godoc.org/github.com/cosmos/cosmos-sdk" + }, + { + title: "REST API Spec", + path: "https://cosmos.network/rpc/" } ] } From f0286af00a09ad89e69021dd74428b66b2944014 Mon Sep 17 00:00:00 2001 From: Denis Fadeev Date: Thu, 7 Nov 2019 16:46:12 -0500 Subject: [PATCH 141/196] theme version --- docs/package-lock.json | 200 ++++++++++++++++++++++------------------- docs/package.json | 5 +- 2 files changed, 112 insertions(+), 93 deletions(-) diff --git a/docs/package-lock.json b/docs/package-lock.json index cdba55e6bda4..f42f85fba211 100644 --- a/docs/package-lock.json +++ b/docs/package-lock.json @@ -13,18 +13,18 @@ } }, "@babel/core": { - "version": "7.7.0", - "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.7.0.tgz", - "integrity": "sha512-Bb1NjZCaiwTQC/ARL+MwDpgocdnwWDCaugvkGt6cxfBzQa8Whv1JybBoUEiBDKl8Ni3H3c7Fykwk7QChUsHRlg==", + "version": "7.7.2", + "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.7.2.tgz", + "integrity": "sha512-eeD7VEZKfhK1KUXGiyPFettgF3m513f8FoBSWiQ1xTvl1RAopLs42Wp9+Ze911I6H0N9lNqJMDgoZT7gHsipeQ==", "requires": { "@babel/code-frame": "^7.5.5", - "@babel/generator": "^7.7.0", + "@babel/generator": "^7.7.2", "@babel/helpers": "^7.7.0", - "@babel/parser": "^7.7.0", + "@babel/parser": "^7.7.2", "@babel/template": "^7.7.0", - "@babel/traverse": "^7.7.0", - "@babel/types": "^7.7.0", - "convert-source-map": "^1.1.0", + "@babel/traverse": "^7.7.2", + "@babel/types": "^7.7.2", + "convert-source-map": "^1.7.0", "debug": "^4.1.0", "json5": "^2.1.0", "lodash": "^4.17.13", @@ -62,11 +62,11 @@ } }, "@babel/generator": { - "version": "7.7.0", - "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.7.0.tgz", - "integrity": "sha512-1wdJ6UxHyL1XoJQ119JmvuRX27LRih7iYStMPZOWAjQqeAabFg3dYXKMpgihma+to+0ADsTVVt6oRyUxWZw6Mw==", + "version": "7.7.2", + "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.7.2.tgz", + "integrity": "sha512-WthSArvAjYLz4TcbKOi88me+KmDJdKSlfwwN8CnUYn9jBkzhq0ZEPuBfkAWIvjJ3AdEV1Cf/+eSQTnp3IDJKlQ==", "requires": { - "@babel/types": "^7.7.0", + "@babel/types": "^7.7.2", "jsesc": "^2.5.1", "lodash": "^4.17.13", "source-map": "^0.5.0" @@ -120,9 +120,9 @@ } }, "@babel/helper-create-regexp-features-plugin": { - "version": "7.7.0", - "resolved": "https://registry.npmjs.org/@babel/helper-create-regexp-features-plugin/-/helper-create-regexp-features-plugin-7.7.0.tgz", - "integrity": "sha512-ZhagAAVGD3L6MPM9/zZi7RRteonfBFLVUz3kjsnYsMAtr9hOJCKI9BAKIMpqn3NyWicPieoX779UL+7/3BEAOA==", + "version": "7.7.2", + "resolved": "https://registry.npmjs.org/@babel/helper-create-regexp-features-plugin/-/helper-create-regexp-features-plugin-7.7.2.tgz", + "integrity": "sha512-pAil/ZixjTlrzNpjx+l/C/wJk002Wo7XbbZ8oujH/AoJ3Juv0iN/UTcPUHXKMFLqsfS0Hy6Aow8M31brUYBlQQ==", "requires": { "@babel/helper-regex": "^7.4.4", "regexpu-core": "^4.6.0" @@ -295,9 +295,9 @@ } }, "@babel/parser": { - "version": "7.7.0", - "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.7.0.tgz", - "integrity": "sha512-GqL+Z0d7B7ADlQBMXlJgvXEbtt5qlqd1YQ5fr12hTSfh7O/vgrEIvJxU2e7aSVrEUn75zTZ6Nd0s8tthrlZnrQ==" + "version": "7.7.2", + "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.7.2.tgz", + "integrity": "sha512-DDaR5e0g4ZTb9aP7cpSZLkACEBdoLGwJDWgHtBhrGX7Q1RjhdoMOfexICj5cqTAtpowjGQWfcvfnQG7G2kAB5w==" }, "@babel/plugin-proposal-async-generator-functions": { "version": "7.7.0", @@ -733,9 +733,9 @@ } }, "@babel/runtime": { - "version": "7.7.1", - "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.7.1.tgz", - "integrity": "sha512-SQ0sS7KUJDvgCI2cpZG0nJygO6002oTbhgSuw4WcocsnbxLwL5Q8I3fqbJdyBAc3uFrWZiR2JomseuxSuci3SQ==", + "version": "7.7.2", + "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.7.2.tgz", + "integrity": "sha512-JONRbXbTXc9WQE2mAZd1p0Z3DZ/6vaQIkgYMSTP3KjRCyd7rCZCcfhCyX+YjwcKxcZ82UrxbRD358bpExNgrjw==", "requires": { "regenerator-runtime": "^0.13.2" }, @@ -748,9 +748,9 @@ } }, "@babel/runtime-corejs2": { - "version": "7.7.1", - "resolved": "https://registry.npmjs.org/@babel/runtime-corejs2/-/runtime-corejs2-7.7.1.tgz", - "integrity": "sha512-nlxajcFXWFyrFOyzOkphfby2izqoB9B4a3+rMqG4dBKMaHZUUS3BkgFBIAbNK6s+VOx0vaGJVgaQL0+3oWnxDQ==", + "version": "7.7.2", + "resolved": "https://registry.npmjs.org/@babel/runtime-corejs2/-/runtime-corejs2-7.7.2.tgz", + "integrity": "sha512-GfVnHchOBvIMsweQ13l4jd9lT4brkevnavnVOej5g2y7PpTRY+R4pcQlCjWMZoUla5rMLFzaS/Ll2s59cB1TqQ==", "requires": { "core-js": "^2.6.5", "regenerator-runtime": "^0.13.2" @@ -774,16 +774,16 @@ } }, "@babel/traverse": { - "version": "7.7.0", - "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.7.0.tgz", - "integrity": "sha512-ea/3wRZc//e/uwCpuBX2itrhI0U9l7+FsrKWyKGNyvWbuMcCG7ATKY2VI4wlg2b2TA39HHwIxnvmXvtiKsyn7w==", + "version": "7.7.2", + "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.7.2.tgz", + "integrity": "sha512-TM01cXib2+rgIZrGJOLaHV/iZUAxf4A0dt5auY6KNZ+cm6aschuJGqKJM3ROTt3raPUdIDk9siAufIFEleRwtw==", "requires": { "@babel/code-frame": "^7.5.5", - "@babel/generator": "^7.7.0", + "@babel/generator": "^7.7.2", "@babel/helper-function-name": "^7.7.0", "@babel/helper-split-export-declaration": "^7.7.0", - "@babel/parser": "^7.7.0", - "@babel/types": "^7.7.0", + "@babel/parser": "^7.7.2", + "@babel/types": "^7.7.2", "debug": "^4.1.0", "globals": "^11.1.0", "lodash": "^4.17.13" @@ -805,9 +805,9 @@ } }, "@babel/types": { - "version": "7.7.1", - "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.7.1.tgz", - "integrity": "sha512-kN/XdANDab9x1z5gcjDc9ePpxexkt+1EQ2MQUiM4XnMvQfvp87/+6kY4Ko2maLXH+tei/DgJ/ybFITeqqRwDiA==", + "version": "7.7.2", + "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.7.2.tgz", + "integrity": "sha512-YTf6PXoh3+eZgRCBzzP25Bugd2ngmpQVrk7kXX0i5N9BO7TFBtIgZYs7WtxtOGs8e6A4ZI7ECkbBCEHeXocvOA==", "requires": { "esutils": "^2.0.2", "lodash": "^4.17.13", @@ -1095,6 +1095,11 @@ "prismjs": "^1.13.0" }, "dependencies": { + "entities": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/entities/-/entities-1.1.2.tgz", + "integrity": "sha512-f2LZMYl1Fzu7YSBKg+RoROelpOaNrcGmE9AZubeDfrCEia483oW4MI4VyFd5VNHIgQ/7qm1I0wUHK1eJnn2y2w==" + }, "markdown-it": { "version": "8.4.2", "resolved": "https://registry.npmjs.org/markdown-it/-/markdown-it-8.4.2.tgz", @@ -2064,15 +2069,16 @@ "integrity": "sha512-wZfzSWVXuue1H3J7TDNjbzg4KTqPXCmh7F3QIzEYXfnhMCcOUrx99M7rpO2UDVJA9dqv3butGj2nHvCV47CmPg==" }, "cacache": { - "version": "11.3.3", - "resolved": "https://registry.npmjs.org/cacache/-/cacache-11.3.3.tgz", - "integrity": "sha512-p8WcneCytvzPxhDvYp31PD039vi77I12W+/KfR9S8AZbaiARFBCpsPJS+9uhWfeBfeAtW7o/4vt3MUqLkbY6nA==", + "version": "12.0.3", + "resolved": "https://registry.npmjs.org/cacache/-/cacache-12.0.3.tgz", + "integrity": "sha512-kqdmfXEGFepesTuROHMs3MpFLWrPkSSpRqOw80RCflZXy/khxaArvFrQ7uJxSUduzAufc6G0g1VUCOZXxWavPw==", "requires": { "bluebird": "^3.5.5", "chownr": "^1.1.1", "figgy-pudding": "^3.5.1", "glob": "^7.1.4", "graceful-fs": "^4.1.15", + "infer-owner": "^1.0.3", "lru-cache": "^5.1.1", "mississippi": "^3.0.0", "mkdirp": "^0.5.1", @@ -2512,11 +2518,11 @@ "integrity": "sha1-Z29us8OZl8LuGsOpJP1hJHSPV40=" }, "copy-webpack-plugin": { - "version": "5.0.4", - "resolved": "https://registry.npmjs.org/copy-webpack-plugin/-/copy-webpack-plugin-5.0.4.tgz", - "integrity": "sha512-YBuYGpSzoCHSSDGyHy6VJ7SHojKp6WHT4D7ItcQFNAYx2hrwkMe56e97xfVR0/ovDuMTrMffXUiltvQljtAGeg==", + "version": "5.0.5", + "resolved": "https://registry.npmjs.org/copy-webpack-plugin/-/copy-webpack-plugin-5.0.5.tgz", + "integrity": "sha512-7N68eIoQTyudAuxkfPT7HzGoQ+TsmArN/I3HFwG+lVE3FNzqvZKIiaxtYh4o3BIznioxUvx9j26+Rtsc9htQUQ==", "requires": { - "cacache": "^11.3.3", + "cacache": "^12.0.3", "find-cache-dir": "^2.1.0", "glob-parent": "^3.1.0", "globby": "^7.1.1", @@ -2524,9 +2530,9 @@ "loader-utils": "^1.2.3", "minimatch": "^3.0.4", "normalize-path": "^3.0.0", - "p-limit": "^2.2.0", + "p-limit": "^2.2.1", "schema-utils": "^1.0.0", - "serialize-javascript": "^1.7.0", + "serialize-javascript": "^2.1.0", "webpack-log": "^2.0.0" }, "dependencies": { @@ -3108,11 +3114,6 @@ "version": "2.0.1", "resolved": "https://registry.npmjs.org/domelementtype/-/domelementtype-2.0.1.tgz", "integrity": "sha512-5HOHUDsYZWV8FGWN0Njbr/Rn7f/eWSQi1v7+HsUVwXgn8nWWlL64zKDkS0n8ZmQ3mlWOMuXOnR+7Nx/5tMO5AQ==" - }, - "entities": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/entities/-/entities-2.0.0.tgz", - "integrity": "sha512-D9f7V0JSRwIxlRI2mjMqufDrRDnx8p+eEOz7aUM9SuvF8gsBzra0/6tbjl1m8eQHrZlYj6PxqE00hZ1SAIKPLw==" } } }, @@ -3182,9 +3183,9 @@ "integrity": "sha1-WQxhFWsK4vTwJVcyoViyZrxWsh0=" }, "electron-to-chromium": { - "version": "1.3.304", - "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.3.304.tgz", - "integrity": "sha512-a5mqa13jCdBc+Crgk3Gyr7vpXCiFWfFq23YDCEmrPYeiDOQKZDVE6EX/Q4Xdv97n3XkcjiSBDOY0IS19yP2yeA==" + "version": "1.3.305", + "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.3.305.tgz", + "integrity": "sha512-jBEhRZ3eeJWf3eAnGYB1vDy09uBQpZWshC5fxiiIRofA9L3vkpa3SxsXleVS2MvuYir15oTVxzWPsOwj7KBzUw==" }, "elliptic": { "version": "6.5.1", @@ -3245,9 +3246,9 @@ } }, "entities": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/entities/-/entities-1.1.2.tgz", - "integrity": "sha512-f2LZMYl1Fzu7YSBKg+RoROelpOaNrcGmE9AZubeDfrCEia483oW4MI4VyFd5VNHIgQ/7qm1I0wUHK1eJnn2y2w==" + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/entities/-/entities-2.0.0.tgz", + "integrity": "sha512-D9f7V0JSRwIxlRI2mjMqufDrRDnx8p+eEOz7aUM9SuvF8gsBzra0/6tbjl1m8eQHrZlYj6PxqE00hZ1SAIKPLw==" }, "envify": { "version": "4.1.0", @@ -4324,9 +4325,9 @@ } }, "glob": { - "version": "7.1.5", - "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.5.tgz", - "integrity": "sha512-J9dlskqUXK1OeTOYBEn5s8aMukWMwWfs+rPTn/jn50Ux4MNXVhubL1wu/j2t+H4NVI+cXEcCaYellqaPVGXNqQ==", + "version": "7.1.6", + "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.6.tgz", + "integrity": "sha512-LwaxwyZ72Lk7vZINtNNrywX0ZuLyStrdDtabefZKAY5ZGJhVtgdznluResxNmPitE0SAO+O26sWTHeKSI2wMBA==", "requires": { "fs.realpath": "^1.0.0", "inflight": "^1.0.4", @@ -4635,6 +4636,11 @@ "readable-stream": "^3.1.1" }, "dependencies": { + "entities": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/entities/-/entities-1.1.2.tgz", + "integrity": "sha512-f2LZMYl1Fzu7YSBKg+RoROelpOaNrcGmE9AZubeDfrCEia483oW4MI4VyFd5VNHIgQ/7qm1I0wUHK1eJnn2y2w==" + }, "readable-stream": { "version": "3.4.0", "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.4.0.tgz", @@ -5332,9 +5338,9 @@ "integrity": "sha1-0CJTc662Uq3BvILklFM5qEJ1R3M=" }, "loglevel": { - "version": "1.6.4", - "resolved": "https://registry.npmjs.org/loglevel/-/loglevel-1.6.4.tgz", - "integrity": "sha512-p0b6mOGKcGa+7nnmKbpzR6qloPbrgLcnio++E+14Vo/XffOGwZtRpUhr8dTH/x2oCMmEoIU0Zwm3ZauhvYD17g==" + "version": "1.6.6", + "resolved": "https://registry.npmjs.org/loglevel/-/loglevel-1.6.6.tgz", + "integrity": "sha512-Sgr5lbboAUBo3eXCSPL4/KoVz3ROKquOjcctxmHIt+vol2DrqTQe3SwkKKuYhEiWB5kYa13YyopJ69deJ1irzQ==" }, "longest": { "version": "1.0.1", @@ -5398,12 +5404,12 @@ } }, "markdown-it": { - "version": "9.1.0", - "resolved": "https://registry.npmjs.org/markdown-it/-/markdown-it-9.1.0.tgz", - "integrity": "sha512-xHKG4C8iPriyfu/jc2hsCC045fKrMQ0VexX2F1FGYiRxDxqMB2aAhF8WauJ3fltn2kb90moGBkiiEdooGIg55w==", + "version": "10.0.0", + "resolved": "https://registry.npmjs.org/markdown-it/-/markdown-it-10.0.0.tgz", + "integrity": "sha512-YWOP1j7UbDNz+TumYP1kpwnP0aEa711cJjrAQrzd0UXlbJfc5aAq0F/PZHjiioqDC1NKgvIMX+o+9Bk7yuM2dg==", "requires": { "argparse": "^1.0.7", - "entities": "~1.1.1", + "entities": "~2.0.0", "linkify-it": "^2.0.0", "mdurl": "^1.0.1", "uc.micro": "^1.0.5" @@ -7605,9 +7611,9 @@ } }, "serialize-javascript": { - "version": "1.9.1", - "resolved": "https://registry.npmjs.org/serialize-javascript/-/serialize-javascript-1.9.1.tgz", - "integrity": "sha512-0Vb/54WJ6k5v8sSWN09S0ora+Hnr+cX40r9F170nT+mSkaxltoE/7R3OrIdBSUv1OoiobH1QoWQbCnAO+e8J1A==" + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/serialize-javascript/-/serialize-javascript-2.1.0.tgz", + "integrity": "sha512-a/mxFfU00QT88umAJQsNWOnUKckhNCqOl028N48e7wFmo2/EHpTo9Wso+iJJCMrQnmFvcjto5RJdAHEvVhcyUQ==" }, "serve-index": { "version": "1.9.1", @@ -8329,27 +8335,10 @@ "worker-farm": "^1.7.0" }, "dependencies": { - "cacache": { - "version": "12.0.3", - "resolved": "https://registry.npmjs.org/cacache/-/cacache-12.0.3.tgz", - "integrity": "sha512-kqdmfXEGFepesTuROHMs3MpFLWrPkSSpRqOw80RCflZXy/khxaArvFrQ7uJxSUduzAufc6G0g1VUCOZXxWavPw==", - "requires": { - "bluebird": "^3.5.5", - "chownr": "^1.1.1", - "figgy-pudding": "^3.5.1", - "glob": "^7.1.4", - "graceful-fs": "^4.1.15", - "infer-owner": "^1.0.3", - "lru-cache": "^5.1.1", - "mississippi": "^3.0.0", - "mkdirp": "^0.5.1", - "move-concurrently": "^1.0.1", - "promise-inflight": "^1.0.1", - "rimraf": "^2.6.3", - "ssri": "^6.0.1", - "unique-filename": "^1.1.1", - "y18n": "^4.0.0" - } + "serialize-javascript": { + "version": "1.9.1", + "resolved": "https://registry.npmjs.org/serialize-javascript/-/serialize-javascript-1.9.1.tgz", + "integrity": "sha512-0Vb/54WJ6k5v8sSWN09S0ora+Hnr+cX40r9F170nT+mSkaxltoE/7R3OrIdBSUv1OoiobH1QoWQbCnAO+e8J1A==" } } }, @@ -8402,6 +8391,25 @@ "integrity": "sha512-ud+LicFlyhwLwO/nfGvtASg3TyUCjaEQC5GCZaE/JzXQmwK0ndb+4F0/ek8xr07rOENFUIT9N+1tmUDqCAtv1g==", "requires": { "markdown-it": "^9.1.0" + }, + "dependencies": { + "entities": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/entities/-/entities-1.1.2.tgz", + "integrity": "sha512-f2LZMYl1Fzu7YSBKg+RoROelpOaNrcGmE9AZubeDfrCEia483oW4MI4VyFd5VNHIgQ/7qm1I0wUHK1eJnn2y2w==" + }, + "markdown-it": { + "version": "9.1.0", + "resolved": "https://registry.npmjs.org/markdown-it/-/markdown-it-9.1.0.tgz", + "integrity": "sha512-xHKG4C8iPriyfu/jc2hsCC045fKrMQ0VexX2F1FGYiRxDxqMB2aAhF8WauJ3fltn2kb90moGBkiiEdooGIg55w==", + "requires": { + "argparse": "^1.0.7", + "entities": "~1.1.1", + "linkify-it": "^2.0.0", + "mdurl": "^1.0.1", + "uc.micro": "^1.0.5" + } + } } }, "to-arraybuffer": { @@ -8772,6 +8780,11 @@ "resolved": "https://registry.npmjs.org/uuid/-/uuid-3.3.3.tgz", "integrity": "sha512-pW0No1RGHgzlpHJO1nsVrHKpOEIxkGg1xB+v0ZmdNH5OAeAwzAVrCnI2/6Mtx+Uys6iaylxa+D3g4j63IKKjSQ==" }, + "v-runtime-template": { + "version": "1.10.0", + "resolved": "https://registry.npmjs.org/v-runtime-template/-/v-runtime-template-1.10.0.tgz", + "integrity": "sha512-WLlq9jUepSfUrMEenw3mn7FDXX6hhbl11JjC1OKhwLzifHzVrY5a696TUHDPyj9jke3GGnR7b+2T3od/RL5cww==" + }, "vary": { "version": "1.1.2", "resolved": "https://registry.npmjs.org/vary/-/vary-1.1.2.tgz", @@ -8861,6 +8874,11 @@ "supports-color": "^2.0.0" } }, + "serialize-javascript": { + "version": "1.9.1", + "resolved": "https://registry.npmjs.org/serialize-javascript/-/serialize-javascript-1.9.1.tgz", + "integrity": "sha512-0Vb/54WJ6k5v8sSWN09S0ora+Hnr+cX40r9F170nT+mSkaxltoE/7R3OrIdBSUv1OoiobH1QoWQbCnAO+e8J1A==" + }, "source-map": { "version": "0.5.6", "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.6.tgz", @@ -8962,19 +8980,21 @@ } }, "vuepress-theme-cosmos": { - "version": "1.0.41", - "resolved": "https://registry.npmjs.org/vuepress-theme-cosmos/-/vuepress-theme-cosmos-1.0.41.tgz", - "integrity": "sha512-C0X4rqSmsRPvWQXUvStf3FJvQDkRAQGsBdJryO+F2mLRsgK5Unp/YKBFvy02iPN/wD6TFr1ywaKISebQzj1w8w==", + "version": "1.0.43", + "resolved": "https://registry.npmjs.org/vuepress-theme-cosmos/-/vuepress-theme-cosmos-1.0.43.tgz", + "integrity": "sha512-A71acbWUV3yfxHwnXfo/UD8wP95bSQUclUWtw4brpOT6us7Co2S4BI+guki0jeA3AbWRtQeJFaiyKkTdkbHC4g==", "requires": { "@cosmos-ui/vue": "^0.5.16", "@vuepress/plugin-last-updated": "^1.2.0", "@vuepress/plugin-search": "^1.1.0", "intersection-observer": "^0.7.0", + "markdown-it": "^10.0.0", "pug": "^2.0.4", "pug-plain-loader": "^1.0.0", "stylus": "^0.54.7", "stylus-loader": "^3.0.2", "tm-tooltip": "0.0.10", + "v-runtime-template": "^1.10.0", "vuepress": "^1.2.0" } }, diff --git a/docs/package.json b/docs/package.json index fc1634b15f71..6012106d98ac 100644 --- a/docs/package.json +++ b/docs/package.json @@ -14,7 +14,6 @@ "author": "", "license": "ISC", "dependencies": { - "vuepress-theme-cosmos": "^1.0.41", - "vuepress-theme-docs": "^1.0.7" + "vuepress-theme-cosmos": "^1.0.43" } -} +} \ No newline at end of file From 1216369b97a23c37f4ad2d6095a9a4a9da577366 Mon Sep 17 00:00:00 2001 From: Denis Fadeev Date: Thu, 7 Nov 2019 17:02:08 -0500 Subject: [PATCH 142/196] theme version --- docs/package-lock.json | 11 +++-------- docs/package.json | 4 ++-- 2 files changed, 5 insertions(+), 10 deletions(-) diff --git a/docs/package-lock.json b/docs/package-lock.json index f42f85fba211..27bf14cc71cc 100644 --- a/docs/package-lock.json +++ b/docs/package-lock.json @@ -8980,9 +8980,9 @@ } }, "vuepress-theme-cosmos": { - "version": "1.0.43", - "resolved": "https://registry.npmjs.org/vuepress-theme-cosmos/-/vuepress-theme-cosmos-1.0.43.tgz", - "integrity": "sha512-A71acbWUV3yfxHwnXfo/UD8wP95bSQUclUWtw4brpOT6us7Co2S4BI+guki0jeA3AbWRtQeJFaiyKkTdkbHC4g==", + "version": "1.0.44", + "resolved": "https://registry.npmjs.org/vuepress-theme-cosmos/-/vuepress-theme-cosmos-1.0.44.tgz", + "integrity": "sha512-h0tPwBg+j5S2phAXJLuN6GaqOp/k1OI0knLU+24kOCnB2cD0kYOqGq8MX9/7opPNX/d42hdVB4v4bEdzBLzMIw==", "requires": { "@cosmos-ui/vue": "^0.5.16", "@vuepress/plugin-last-updated": "^1.2.0", @@ -8998,11 +8998,6 @@ "vuepress": "^1.2.0" } }, - "vuepress-theme-docs": { - "version": "1.0.7", - "resolved": "https://registry.npmjs.org/vuepress-theme-docs/-/vuepress-theme-docs-1.0.7.tgz", - "integrity": "sha512-OU1VvSuJaUg5nMSGiURE06T4P93DGbAm3W6zXkqWcSixEi4/B0RsLI61uzf15s1HeXOaU6CQECOs7bw8/7MHZw==" - }, "watchpack": { "version": "1.6.0", "resolved": "https://registry.npmjs.org/watchpack/-/watchpack-1.6.0.tgz", diff --git a/docs/package.json b/docs/package.json index 6012106d98ac..3047bc4da34b 100644 --- a/docs/package.json +++ b/docs/package.json @@ -14,6 +14,6 @@ "author": "", "license": "ISC", "dependencies": { - "vuepress-theme-cosmos": "^1.0.43" + "vuepress-theme-cosmos": "^1.0.44" } -} \ No newline at end of file +} From 1427288c3d1a3aa221add1166d4ee6aaca05858f Mon Sep 17 00:00:00 2001 From: Denis Fadeev Date: Thu, 7 Nov 2019 17:58:41 -0500 Subject: [PATCH 143/196] testing netlify --- docs/pre.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/pre.sh b/docs/pre.sh index cb027a843aa4..7a09e0bc1bb0 100755 --- a/docs/pre.sh +++ b/docs/pre.sh @@ -5,6 +5,6 @@ mkdir -p modules for D in ../x/*; do if [ -d "${D}" ]; then rm -rf "modules/$(echo $D | awk -F/ '{print $NF}')" - mkdir -p "modules/$(echo $D | awk -F/ '{print $NF}')" && cp -r $D/spec/ "$_" + mkdir -p "modules/$(echo $D | awk -F/ '{print $NF}')" && cp -r $D/spec/ "$_/" fi done \ No newline at end of file From fa048b8e32a352c2b17811da7bdd62d372a6df62 Mon Sep 17 00:00:00 2001 From: Denis Fadeev Date: Thu, 7 Nov 2019 18:38:21 -0500 Subject: [PATCH 144/196] theme version --- docs/package-lock.json | 6 +++--- docs/package.json | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/docs/package-lock.json b/docs/package-lock.json index 27bf14cc71cc..548e989ece2b 100644 --- a/docs/package-lock.json +++ b/docs/package-lock.json @@ -8980,9 +8980,9 @@ } }, "vuepress-theme-cosmos": { - "version": "1.0.44", - "resolved": "https://registry.npmjs.org/vuepress-theme-cosmos/-/vuepress-theme-cosmos-1.0.44.tgz", - "integrity": "sha512-h0tPwBg+j5S2phAXJLuN6GaqOp/k1OI0knLU+24kOCnB2cD0kYOqGq8MX9/7opPNX/d42hdVB4v4bEdzBLzMIw==", + "version": "1.0.46", + "resolved": "https://registry.npmjs.org/vuepress-theme-cosmos/-/vuepress-theme-cosmos-1.0.46.tgz", + "integrity": "sha512-xBYVe0Rv4ubBruO9tbd/2pIJFwq38CAR8PgzZHLWUrYchdk/GsH4ZKgmdbP6uizk5jt85AQDKFMnrr5BUekmPA==", "requires": { "@cosmos-ui/vue": "^0.5.16", "@vuepress/plugin-last-updated": "^1.2.0", diff --git a/docs/package.json b/docs/package.json index 3047bc4da34b..a7b4e8e9edd5 100644 --- a/docs/package.json +++ b/docs/package.json @@ -14,6 +14,6 @@ "author": "", "license": "ISC", "dependencies": { - "vuepress-theme-cosmos": "^1.0.44" + "vuepress-theme-cosmos": "^1.0.46" } } From 9b32df75fe79ca564858f81b90d495cea0f696c3 Mon Sep 17 00:00:00 2001 From: Denis Fadeev Date: Fri, 8 Nov 2019 10:52:26 -0500 Subject: [PATCH 145/196] tooltip example --- docs/intro/intro.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/intro/intro.md b/docs/intro/intro.md index 5d6a574d66ec..3436b90f551c 100644 --- a/docs/intro/intro.md +++ b/docs/intro/intro.md @@ -6,7 +6,7 @@ order: 1 ## What is the SDK? -The [Cosmos-SDK](https://github.com/cosmos/cosmos-sdk) is an open-source framework for building multi-asset public Proof-of-Stake (PoS) blockchains, like the Cosmos Hub, as well as permissioned Proof-Of-Authority (PoA) blockchains. Blockchains built with the Cosmos SDK are generally referred to as **application-specific blockchains**. +The [Cosmos-SDK](https://github.com/cosmos/cosmos-sdk) is an open-source framework for building multi-asset public Proof-of-Stake (PoS) blockchains, like the Cosmos Hub, as well as permissioned Proof-Of-Authority (PoA) blockchains. Blockchains built with the Cosmos SDK are generally referred to as **application-specific blockchains**. The goal of the Cosmos SDK is to allow developers to easily create custom blockchains from scratch that can natively interoperate with other blockchains. We envision the SDK as the npm-like framework to build secure blockchain applications on top of [Tendermint](https://github.com/tendermint/tendermint). SDK-based blockchains are built out of composable [modules](../building-modules/intro.md), most of which are open source and readily available for any developers to use. Anyone can create a module for the Cosmos-SDK, and integrating already-built modules is as simple as importing them into your blockchain application. What's more, the Cosmos SDK is a capabilities-based system, which allows developers to better reason about the security of interactions between modules. For a deeper look at capabilities, jump to [this section](../core/ocap.md). From f958a9b7a839979c4bf1984769f00f7c39ef3e98 Mon Sep 17 00:00:00 2001 From: Denis Fadeev Date: Sat, 9 Nov 2019 04:08:17 -0500 Subject: [PATCH 146/196] version --- docs/package-lock.json | 135 +++++++++++++++++++++++++---------------- docs/package.json | 2 +- 2 files changed, 83 insertions(+), 54 deletions(-) diff --git a/docs/package-lock.json b/docs/package-lock.json index 548e989ece2b..e77a898745ee 100644 --- a/docs/package-lock.json +++ b/docs/package-lock.json @@ -295,9 +295,9 @@ } }, "@babel/parser": { - "version": "7.7.2", - "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.7.2.tgz", - "integrity": "sha512-DDaR5e0g4ZTb9aP7cpSZLkACEBdoLGwJDWgHtBhrGX7Q1RjhdoMOfexICj5cqTAtpowjGQWfcvfnQG7G2kAB5w==" + "version": "7.7.3", + "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.7.3.tgz", + "integrity": "sha512-bqv+iCo9i+uLVbI0ILzKkvMorqxouI+GbV13ivcARXn9NNEabi2IEz912IgNpT/60BNXac5dgcfjb94NjsF33A==" }, "@babel/plugin-proposal-async-generator-functions": { "version": "7.7.0", @@ -877,9 +877,9 @@ "integrity": "sha512-tHq6qdbT9U1IRSGf14CL0pUlULksvY9OZ+5eEgl1N7t+OA3tGvNpxJCzuKQlsNgCVwbAs670L1vcVQi8j9HjnA==" }, "@types/node": { - "version": "12.12.6", - "resolved": "https://registry.npmjs.org/@types/node/-/node-12.12.6.tgz", - "integrity": "sha512-FjsYUPzEJdGXjwKqSpE0/9QEh6kzhTAeObA54rn6j3rR4C/mzpI9L0KNfoeASSPMMdxIsoJuCLDWcM/rVjIsSA==" + "version": "12.12.7", + "resolved": "https://registry.npmjs.org/@types/node/-/node-12.12.7.tgz", + "integrity": "sha512-E6Zn0rffhgd130zbCbAr/JdXfXkoOUFAKNs/rF8qnafSJ8KYaA/j3oz7dcwal+lYjLA7xvdd5J4wdYpCTlP8+w==" }, "@types/q": { "version": "1.5.2", @@ -892,9 +892,9 @@ "integrity": "sha512-6tyf5Cqm4m6v7buITuwS+jHzPlIPxbFzEhXR5JGZpbrvOcp1hiQKckd305/3C7C36wFekNTQSxAtgeM0j0yoUw==" }, "@vue/babel-plugin-transform-vue-jsx": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/@vue/babel-plugin-transform-vue-jsx/-/babel-plugin-transform-vue-jsx-1.0.0.tgz", - "integrity": "sha512-U+JNwVQSmaLKjO3lzCUC3cNXxprgezV1N+jOdqbP4xWNaqtWUCJnkjTVcgECM18A/AinDKPcUUeoyhU7yxUxXQ==", + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/@vue/babel-plugin-transform-vue-jsx/-/babel-plugin-transform-vue-jsx-1.1.2.tgz", + "integrity": "sha512-YfdaoSMvD1nj7+DsrwfTvTnhDXI7bsuh+Y5qWwvQXlD24uLgnsoww3qbiZvWf/EoviZMrvqkqN4CBw0W3BWUTQ==", "requires": { "@babel/helper-module-imports": "^7.0.0", "@babel/plugin-syntax-jsx": "^7.2.0", @@ -925,42 +925,42 @@ } }, "@vue/babel-preset-jsx": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/@vue/babel-preset-jsx/-/babel-preset-jsx-1.1.1.tgz", - "integrity": "sha512-SeyndwQZc8MAOkhbJaC34ocTwcKekKkwrwnTMC3YF8VmGp5IQWW5gPIU66bqO9WFBXFA3J3ANsUbP2pj8q8KdQ==", + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/@vue/babel-preset-jsx/-/babel-preset-jsx-1.1.2.tgz", + "integrity": "sha512-zDpVnFpeC9YXmvGIDSsKNdL7qCG2rA3gjywLYHPCKDT10erjxF4U+6ay9X6TW5fl4GsDlJp9bVfAVQAAVzxxvQ==", "requires": { "@vue/babel-helper-vue-jsx-merge-props": "^1.0.0", - "@vue/babel-plugin-transform-vue-jsx": "^1.0.0", - "@vue/babel-sugar-functional-vue": "^1.0.0", - "@vue/babel-sugar-inject-h": "^1.0.0", - "@vue/babel-sugar-v-model": "^1.1.1", - "@vue/babel-sugar-v-on": "^1.1.0" + "@vue/babel-plugin-transform-vue-jsx": "^1.1.2", + "@vue/babel-sugar-functional-vue": "^1.1.2", + "@vue/babel-sugar-inject-h": "^1.1.2", + "@vue/babel-sugar-v-model": "^1.1.2", + "@vue/babel-sugar-v-on": "^1.1.2" } }, "@vue/babel-sugar-functional-vue": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/@vue/babel-sugar-functional-vue/-/babel-sugar-functional-vue-1.0.0.tgz", - "integrity": "sha512-XE/jNaaorTuhWayCz+QClk5AB9OV5HzrwbzEC6sIUY0J60A28ONQKeTwxfidW42egOkqNH/UU6eE3KLfmiDj0Q==", + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/@vue/babel-sugar-functional-vue/-/babel-sugar-functional-vue-1.1.2.tgz", + "integrity": "sha512-YhmdJQSVEFF5ETJXzrMpj0nkCXEa39TvVxJTuVjzvP2rgKhdMmQzlJuMv/HpadhZaRVMCCF3AEjjJcK5q/cYzQ==", "requires": { "@babel/plugin-syntax-jsx": "^7.2.0" } }, "@vue/babel-sugar-inject-h": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/@vue/babel-sugar-inject-h/-/babel-sugar-inject-h-1.0.0.tgz", - "integrity": "sha512-NxWU+DqtbZgfGvd25GPoFMj+rvyQ8ZA1pHj8vIeqRij+vx3sXoKkObjA9ulZunvWw5F6uG9xYy4ytpxab/X+Hg==", + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/@vue/babel-sugar-inject-h/-/babel-sugar-inject-h-1.1.2.tgz", + "integrity": "sha512-VRSENdTvD5htpnVp7i7DNuChR5rVMcORdXjvv5HVvpdKHzDZAYiLSD+GhnhxLm3/dMuk8pSzV+k28ECkiN5m8w==", "requires": { "@babel/plugin-syntax-jsx": "^7.2.0" } }, "@vue/babel-sugar-v-model": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/@vue/babel-sugar-v-model/-/babel-sugar-v-model-1.1.1.tgz", - "integrity": "sha512-qiPbdUTiqNQdhXzvWQMVfrYGHCiMmscY7j/cudLxdxWZ8AFhgPRVlniVgaWIT7A1iOjs92e8U6qVyqkf0d4ZrA==", + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/@vue/babel-sugar-v-model/-/babel-sugar-v-model-1.1.2.tgz", + "integrity": "sha512-vLXPvNq8vDtt0u9LqFdpGM9W9IWDmCmCyJXuozlq4F4UYVleXJ2Fa+3JsnTZNJcG+pLjjfnEGHci2339Kj5sGg==", "requires": { "@babel/plugin-syntax-jsx": "^7.2.0", "@vue/babel-helper-vue-jsx-merge-props": "^1.0.0", - "@vue/babel-plugin-transform-vue-jsx": "^1.0.0", + "@vue/babel-plugin-transform-vue-jsx": "^1.1.2", "camelcase": "^5.0.0", "html-tags": "^2.0.0", "svg-tags": "^1.0.0" @@ -974,12 +974,12 @@ } }, "@vue/babel-sugar-v-on": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/@vue/babel-sugar-v-on/-/babel-sugar-v-on-1.1.0.tgz", - "integrity": "sha512-8DwAj/RLpmrDP4eZ3erJcKcyuLArLUYagNODTsSQrMdG5zmLJoFFtEjODfYRh/XxM2wXv9Wxe+HAB41FQxxwQA==", + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/@vue/babel-sugar-v-on/-/babel-sugar-v-on-1.1.2.tgz", + "integrity": "sha512-T8ZCwC8Jp2uRtcZ88YwZtZXe7eQrJcfRq0uTFy6ShbwYJyz5qWskRFoVsdTi9o0WEhmQXxhQUewodOSCUPVmsQ==", "requires": { "@babel/plugin-syntax-jsx": "^7.2.0", - "@vue/babel-plugin-transform-vue-jsx": "^1.0.0", + "@vue/babel-plugin-transform-vue-jsx": "^1.1.2", "camelcase": "^5.0.0" }, "dependencies": { @@ -1703,6 +1703,15 @@ "resolved": "https://registry.npmjs.org/aws4/-/aws4-1.8.0.tgz", "integrity": "sha512-ReZxvNHIOv88FlT7rxcXIIC0fPt4KZqZbOlivyWtXLt8ESx84zd3kMC6iK5jVeS2qt+g7ftS7ye4fi06X5rtRQ==" }, + "axios": { + "version": "0.19.0", + "resolved": "https://registry.npmjs.org/axios/-/axios-0.19.0.tgz", + "integrity": "sha512-1uvKqKQta3KBxIz14F2v06AEHZ/dIoeKfbTRkK1E5oqjDnuEerLmYTgJB5AiQZHJcljpg1TuRzdjDR06qNk0DQ==", + "requires": { + "follow-redirects": "1.5.10", + "is-buffer": "^2.0.2" + } + }, "babel-loader": { "version": "8.0.6", "resolved": "https://registry.npmjs.org/babel-loader/-/babel-loader-8.0.6.tgz", @@ -2024,9 +2033,9 @@ } }, "buffer": { - "version": "4.9.1", - "resolved": "https://registry.npmjs.org/buffer/-/buffer-4.9.1.tgz", - "integrity": "sha1-bRu2AbB6TvztlwlBMgkwJ8lbwpg=", + "version": "4.9.2", + "resolved": "https://registry.npmjs.org/buffer/-/buffer-4.9.2.tgz", + "integrity": "sha512-xq+q3SRMOxGivLhBNaUdC64hDTQwejJ+H0T/NB1XMtTVEwNTrfFF3gAxiyW0Bu/xWEGhjVKgUcMhCrUy2+uCWg==", "requires": { "base64-js": "^1.0.2", "ieee754": "^1.1.4", @@ -3183,9 +3192,9 @@ "integrity": "sha1-WQxhFWsK4vTwJVcyoViyZrxWsh0=" }, "electron-to-chromium": { - "version": "1.3.305", - "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.3.305.tgz", - "integrity": "sha512-jBEhRZ3eeJWf3eAnGYB1vDy09uBQpZWshC5fxiiIRofA9L3vkpa3SxsXleVS2MvuYir15oTVxzWPsOwj7KBzUw==" + "version": "1.3.306", + "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.3.306.tgz", + "integrity": "sha512-frDqXvrIROoYvikSKTIKbHbzO6M3/qC6kCIt/1FOa9kALe++c4VAJnwjSFvf1tYLEUsP2n9XZ4XSCyqc3l7A/A==" }, "elliptic": { "version": "6.5.1", @@ -3298,9 +3307,9 @@ } }, "es-to-primitive": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/es-to-primitive/-/es-to-primitive-1.2.0.tgz", - "integrity": "sha512-qZryBOJjV//LaxLTV6UC//WewneB3LcXOL9NP++ozKVXsIIIpm/2c13UDiD9Jp2eThsecw9m3jPqDwTyobcdbg==", + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/es-to-primitive/-/es-to-primitive-1.2.1.tgz", + "integrity": "sha512-QCOllgZJtaUo9miYBcLChTUaHNjJF3PYs1VidD7AwiEj1kYxKeQTctLAezAOH5ZKRH0g2IgPn6KwB4IT8iRpvA==", "requires": { "is-callable": "^1.1.4", "is-date-object": "^1.0.1", @@ -3727,11 +3736,11 @@ } }, "follow-redirects": { - "version": "1.9.0", - "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.9.0.tgz", - "integrity": "sha512-CRcPzsSIbXyVDl0QI01muNDu69S8trU4jArW9LpOt2WtC6LyUJetcIrmfHsRBx7/Jb6GHJUiuqyYxPooFfNt6A==", + "version": "1.5.10", + "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.5.10.tgz", + "integrity": "sha512-0V5l4Cizzvqt5D44aTXbFZz+FtyXV1vrDN6qrelxtfYQKW0KO0W2T/hkE8xvGa/540LkZlkaUjO4ailYTFtHVQ==", "requires": { - "debug": "^3.0.0" + "debug": "=3.1.0" } }, "for-in": { @@ -4486,6 +4495,11 @@ "kind-of": "^4.0.0" }, "dependencies": { + "is-buffer": { + "version": "1.1.6", + "resolved": "https://registry.npmjs.org/is-buffer/-/is-buffer-1.1.6.tgz", + "integrity": "sha512-NcdALwpXkTm5Zvvbk7owOUSvVvBKDgKP5/ewfXEznmQFfs4ZRmanOeKBTjRVjka3QFoN6XJ+9F3USqfHqTaU5w==" + }, "kind-of": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-4.0.0.tgz", @@ -4896,9 +4910,9 @@ } }, "is-buffer": { - "version": "1.1.6", - "resolved": "https://registry.npmjs.org/is-buffer/-/is-buffer-1.1.6.tgz", - "integrity": "sha512-NcdALwpXkTm5Zvvbk7owOUSvVvBKDgKP5/ewfXEznmQFfs4ZRmanOeKBTjRVjka3QFoN6XJ+9F3USqfHqTaU5w==" + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/is-buffer/-/is-buffer-2.0.4.tgz", + "integrity": "sha512-Kq1rokWXOPXWuaMAqZiJW4XxsmD9zGx9q4aePabbn3qCRGedtH7Cm+zV8WETitMfu1wdh+Rvd6w5egwSngUX2A==" }, "is-callable": { "version": "1.1.4", @@ -5224,6 +5238,13 @@ "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", "requires": { "is-buffer": "^1.1.5" + }, + "dependencies": { + "is-buffer": { + "version": "1.1.6", + "resolved": "https://registry.npmjs.org/is-buffer/-/is-buffer-1.1.6.tgz", + "integrity": "sha512-NcdALwpXkTm5Zvvbk7owOUSvVvBKDgKP5/ewfXEznmQFfs4ZRmanOeKBTjRVjka3QFoN6XJ+9F3USqfHqTaU5w==" + } } }, "last-call-webpack-plugin": { @@ -5438,6 +5459,11 @@ "resolved": "https://registry.npmjs.org/markdown-it-emoji/-/markdown-it-emoji-1.4.0.tgz", "integrity": "sha1-m+4OmpkKljupbfaYDE/dsF37Tcw=" }, + "markdown-it-ins": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/markdown-it-ins/-/markdown-it-ins-3.0.0.tgz", + "integrity": "sha512-+vyAdBuMGwmT2yMlAFJSx2VR/0QZ1onQ/Mkkmr4l9tDFOh5sVoAgRbkgbuSsk+sxJ9vaMH/IQ323ydfvQrPO/Q==" + }, "markdown-it-table-of-contents": { "version": "0.4.4", "resolved": "https://registry.npmjs.org/markdown-it-table-of-contents/-/markdown-it-table-of-contents-0.4.4.tgz", @@ -6864,9 +6890,9 @@ "integrity": "sha1-6SQ0v6XqjBn0HN/UAddBo8gZ2Jc=" }, "prettier": { - "version": "1.18.2", - "resolved": "https://registry.npmjs.org/prettier/-/prettier-1.18.2.tgz", - "integrity": "sha512-OeHeMc0JhFE9idD4ZdtNibzY0+TPHSpSSb9h8FqtP+YnoZZ1sl8Vc9b1sasjfymH3SonAF4QcA2+mzHPhMvIiw==" + "version": "1.19.0", + "resolved": "https://registry.npmjs.org/prettier/-/prettier-1.19.0.tgz", + "integrity": "sha512-GlAIjk6DjkNT6u/Bw5QCWrbzh9YlLKwwmJT//1YiCR3WDpZDnyss64aXHQZgF8VKeGlWnX6+tGsKSVxsZT/gtA==" }, "pretty-error": { "version": "2.1.1", @@ -8980,15 +9006,18 @@ } }, "vuepress-theme-cosmos": { - "version": "1.0.46", - "resolved": "https://registry.npmjs.org/vuepress-theme-cosmos/-/vuepress-theme-cosmos-1.0.46.tgz", - "integrity": "sha512-xBYVe0Rv4ubBruO9tbd/2pIJFwq38CAR8PgzZHLWUrYchdk/GsH4ZKgmdbP6uizk5jt85AQDKFMnrr5BUekmPA==", + "version": "1.0.47", + "resolved": "https://registry.npmjs.org/vuepress-theme-cosmos/-/vuepress-theme-cosmos-1.0.47.tgz", + "integrity": "sha512-wFwD0SKRPaya1HbdCnf28YXKReE8KyfV0K+LARm/ojl5zYRfwqOCU4hlhcHWVIcnC0jJn44zR7yKtASQjbHnVw==", "requires": { "@cosmos-ui/vue": "^0.5.16", "@vuepress/plugin-last-updated": "^1.2.0", "@vuepress/plugin-search": "^1.1.0", + "axios": "^0.19.0", "intersection-observer": "^0.7.0", "markdown-it": "^10.0.0", + "markdown-it-ins": "^3.0.0", + "prismjs": "^1.17.1", "pug": "^2.0.4", "pug-plain-loader": "^1.0.0", "stylus": "^0.54.7", diff --git a/docs/package.json b/docs/package.json index a7b4e8e9edd5..a17900e5ff9f 100644 --- a/docs/package.json +++ b/docs/package.json @@ -14,6 +14,6 @@ "author": "", "license": "ISC", "dependencies": { - "vuepress-theme-cosmos": "^1.0.46" + "vuepress-theme-cosmos": "^1.0.47" } } From eef7f629610792e1809db5b22626a2f7a639599f Mon Sep 17 00:00:00 2001 From: Denis Fadeev Date: Sun, 10 Nov 2019 11:24:03 -0500 Subject: [PATCH 147/196] testing code embedding --- docs/intro/intro.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/docs/intro/intro.md b/docs/intro/intro.md index 3436b90f551c..428973832b03 100644 --- a/docs/intro/intro.md +++ b/docs/intro/intro.md @@ -4,6 +4,8 @@ order: 1 # SDK Intro ++++ https://github.com/cosmos/cosmos-sdk/blob/master/baseapp/options.go#L21-L34 + ## What is the SDK? The [Cosmos-SDK](https://github.com/cosmos/cosmos-sdk) is an open-source framework for building multi-asset public Proof-of-Stake (PoS) blockchains, like the Cosmos Hub, as well as permissioned Proof-Of-Authority (PoA) blockchains. Blockchains built with the Cosmos SDK are generally referred to as **application-specific blockchains**. From 699d1f1cbf92e38da1b1f62e7d4aebfaf029eb80 Mon Sep 17 00:00:00 2001 From: Denis Fadeev Date: Sun, 10 Nov 2019 11:26:30 -0500 Subject: [PATCH 148/196] reverting back --- docs/intro/intro.md | 2 -- 1 file changed, 2 deletions(-) diff --git a/docs/intro/intro.md b/docs/intro/intro.md index 428973832b03..3436b90f551c 100644 --- a/docs/intro/intro.md +++ b/docs/intro/intro.md @@ -4,8 +4,6 @@ order: 1 # SDK Intro -+++ https://github.com/cosmos/cosmos-sdk/blob/master/baseapp/options.go#L21-L34 - ## What is the SDK? The [Cosmos-SDK](https://github.com/cosmos/cosmos-sdk) is an open-source framework for building multi-asset public Proof-of-Stake (PoS) blockchains, like the Cosmos Hub, as well as permissioned Proof-Of-Authority (PoA) blockchains. Blockchains built with the Cosmos SDK are generally referred to as **application-specific blockchains**. From 885b2f81855bd10ccf9f483774a75a333058c0ef Mon Sep 17 00:00:00 2001 From: Denis Fadeev Date: Sun, 10 Nov 2019 12:08:21 -0500 Subject: [PATCH 149/196] theme version --- docs/package-lock.json | 49 +++++++++++++++++++++++------------------- docs/package.json | 2 +- 2 files changed, 28 insertions(+), 23 deletions(-) diff --git a/docs/package-lock.json b/docs/package-lock.json index e77a898745ee..d5cb0853861a 100644 --- a/docs/package-lock.json +++ b/docs/package-lock.json @@ -2444,9 +2444,9 @@ "integrity": "sha512-e54B99q/OUoH64zYYRf3HBP5z24G38h5D3qXu23JGRoigpX5Ss4r9ZnDk3g0Z8uQC2x2lPaJ+UlWBc1ZWBWdLg==" }, "consola": { - "version": "2.10.1", - "resolved": "https://registry.npmjs.org/consola/-/consola-2.10.1.tgz", - "integrity": "sha512-4sxpH6SGFYLADfUip4vuY65f/gEogrzJoniVhNUYkJHtng0l8ZjnDCqxxrSVRHOHwKxsy8Vm5ONZh1wOR3/l/w==" + "version": "2.11.0", + "resolved": "https://registry.npmjs.org/consola/-/consola-2.11.0.tgz", + "integrity": "sha512-2bcAqHastlPSCvZ+ur8bgHInGAWvUnysWz3h3xRX+/XZoCY7avolJJnVXOPGoVoyCcg1b231XixonoArmgxaoA==" }, "console-browserify": { "version": "1.2.0", @@ -2737,12 +2737,12 @@ } }, "css-select": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/css-select/-/css-select-2.0.2.tgz", - "integrity": "sha512-dSpYaDVoWaELjvZ3mS6IKZM/y2PMPa/XYoEfYNZePL4U/XgyxZNroHEHReDx/d+VgXh9VbCTtFqLkFbmeqeaRQ==", + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/css-select/-/css-select-2.1.0.tgz", + "integrity": "sha512-Dqk7LQKpwLoH3VovzZnkzegqNSuAziQyNZUcrdDM401iY+R5NkGBXGmtO05/yaXQziALuPogeG0b7UAgjnTJTQ==", "requires": { "boolbase": "^1.0.0", - "css-what": "^2.1.2", + "css-what": "^3.2.1", "domutils": "^1.7.0", "nth-check": "^1.0.2" } @@ -2767,9 +2767,9 @@ "integrity": "sha1-2bkoGtz9jO2TW9urqDeGiX9k6ZY=" }, "css-what": { - "version": "2.1.3", - "resolved": "https://registry.npmjs.org/css-what/-/css-what-2.1.3.tgz", - "integrity": "sha512-a+EPoD+uZiNfh+5fxw2nO9QwFa6nJe2Or35fGY6Ipw1R3R4AGz1d1TEZrCegvw2YTmZ0jXirGYlzxxpYSHwpEg==" + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/css-what/-/css-what-3.2.1.tgz", + "integrity": "sha512-WwOrosiQTvyms+Ti5ZC5vGEK0Vod3FTt1ca+payZqvKuGJF+dq7bG63DstxtN0dpm6FxY27a/zS3Wten+gEtGw==" }, "cssesc": { "version": "3.0.0", @@ -3111,9 +3111,9 @@ } }, "dom-serializer": { - "version": "0.2.1", - "resolved": "https://registry.npmjs.org/dom-serializer/-/dom-serializer-0.2.1.tgz", - "integrity": "sha512-sK3ujri04WyjwQXVoK4PU3y8ula1stq10GJZpqHIUgoGZdsGzAGu65BnU3d08aTVSvO7mGPZUc0wTEDL+qGE0Q==", + "version": "0.2.2", + "resolved": "https://registry.npmjs.org/dom-serializer/-/dom-serializer-0.2.2.tgz", + "integrity": "sha512-2/xPb3ORsQ42nHYiSunXkDjPLBaEj/xTwUO4B7XCZQTRk7EBtTOPaygh10YAAh2OI1Qrp6NWfpAhzswj0ydt9g==", "requires": { "domelementtype": "^2.0.1", "entities": "^2.0.0" @@ -6890,9 +6890,9 @@ "integrity": "sha1-6SQ0v6XqjBn0HN/UAddBo8gZ2Jc=" }, "prettier": { - "version": "1.19.0", - "resolved": "https://registry.npmjs.org/prettier/-/prettier-1.19.0.tgz", - "integrity": "sha512-GlAIjk6DjkNT6u/Bw5QCWrbzh9YlLKwwmJT//1YiCR3WDpZDnyss64aXHQZgF8VKeGlWnX6+tGsKSVxsZT/gtA==" + "version": "1.19.1", + "resolved": "https://registry.npmjs.org/prettier/-/prettier-1.19.1.tgz", + "integrity": "sha512-s7PoyDv/II1ObgQunCbB9PdLmUcBZcnWOcxDh7O0N/UwDEsHyqkW+Qh28jW+mVuCdx7gLB0BotYI1Y6uI9iyew==" }, "pretty-error": { "version": "2.1.1", @@ -7354,6 +7354,11 @@ "nth-check": "~1.0.1" } }, + "css-what": { + "version": "2.1.3", + "resolved": "https://registry.npmjs.org/css-what/-/css-what-2.1.3.tgz", + "integrity": "sha512-a+EPoD+uZiNfh+5fxw2nO9QwFa6nJe2Or35fGY6Ipw1R3R4AGz1d1TEZrCegvw2YTmZ0jXirGYlzxxpYSHwpEg==" + }, "domutils": { "version": "1.5.1", "resolved": "https://registry.npmjs.org/domutils/-/domutils-1.5.1.tgz", @@ -8329,9 +8334,9 @@ "integrity": "sha512-4WK/bYZmj8xLr+HUCODHGF1ZFzsYffasLUgEiMBY4fgtltdO6B4WJtlSbPaDTLpYTcGVwM2qLnFTICEcNxs3kA==" }, "terser": { - "version": "4.3.9", - "resolved": "https://registry.npmjs.org/terser/-/terser-4.3.9.tgz", - "integrity": "sha512-NFGMpHjlzmyOtPL+fDw3G7+6Ueh/sz4mkaUYa4lJCxOPTNzd0Uj0aZJOmsDYoSQyfuVoWDMSWTPU3huyOm2zdA==", + "version": "4.3.11", + "resolved": "https://registry.npmjs.org/terser/-/terser-4.3.11.tgz", + "integrity": "sha512-gcQ1DgitjIOS/CRs9n55xhiDACHkmEirg+3GpozkLzIWgcbUvkAMdzlwbWe/hrwCVUq2Cxk5Tdd7wr4F2Eahsw==", "requires": { "commander": "^2.20.0", "source-map": "~0.6.1", @@ -9006,9 +9011,9 @@ } }, "vuepress-theme-cosmos": { - "version": "1.0.47", - "resolved": "https://registry.npmjs.org/vuepress-theme-cosmos/-/vuepress-theme-cosmos-1.0.47.tgz", - "integrity": "sha512-wFwD0SKRPaya1HbdCnf28YXKReE8KyfV0K+LARm/ojl5zYRfwqOCU4hlhcHWVIcnC0jJn44zR7yKtASQjbHnVw==", + "version": "1.0.48", + "resolved": "https://registry.npmjs.org/vuepress-theme-cosmos/-/vuepress-theme-cosmos-1.0.48.tgz", + "integrity": "sha512-g+uaJ9QDRPrCWnKu0A3PMydeVxWTimbqzGXCCw8CTbhuRxCBeeZprHXivNrXgpSwKV+eeagCBqG34kHnLnyeKg==", "requires": { "@cosmos-ui/vue": "^0.5.16", "@vuepress/plugin-last-updated": "^1.2.0", diff --git a/docs/package.json b/docs/package.json index a17900e5ff9f..df64be59740a 100644 --- a/docs/package.json +++ b/docs/package.json @@ -14,6 +14,6 @@ "author": "", "license": "ISC", "dependencies": { - "vuepress-theme-cosmos": "^1.0.47" + "vuepress-theme-cosmos": "^1.0.48" } } From dcdb101d9d60abea67985995908ec9d5857aa71f Mon Sep 17 00:00:00 2001 From: Denis Fadeev Date: Sun, 10 Nov 2019 15:54:19 -0500 Subject: [PATCH 150/196] version --- docs/.vuepress/config.js | 31 ++++++++++++++++++------------- docs/package-lock.json | 12 ++++++------ docs/package.json | 2 +- 3 files changed, 25 insertions(+), 20 deletions(-) diff --git a/docs/.vuepress/config.js b/docs/.vuepress/config.js index 1dfcea7279a9..837dbe9e638d 100644 --- a/docs/.vuepress/config.js +++ b/docs/.vuepress/config.js @@ -9,6 +9,7 @@ module.exports = { base: process.env.VUEPRESS_BASE || "/", themeConfig: { repo: "cosmos/cosmos-sdk", + docsRepo: "cosmos/cosmos-sdk", docsDir: "docs", editLinks: true, logo: "/logo.svg", @@ -45,19 +46,23 @@ module.exports = { gutter: { title: "Help & Support", editLink: true, - children: [ - { - title: "Riot Chat", - text: "[Chat with Cosmos developers](https://riot.im/app/#/room/#cosmos-sdk:matrix.org) on Riot Chat.", - highlighted: "**500+** people chatting now" - }, - { - title: "Cosmos SDK Forum", - text: "[Join the SDK Developer Forum](https://forum.cosmos.network/) to learn more.", - highlighted: - "**1038** active developers." - } - ] + chat: { + title: "Riot Chat", + text: "Chat with Cosmos developers on Riot Chat.", + url: "https://riot.im/app/#/room/#cosmos-sdk:matrix.org", + bg: "linear-gradient(225.11deg, #2E3148 0%, #161931 95.68%)" + }, + forum: { + title: "Cosmos SDK Forum", + text: "Join the SDK Developer Forum to learn more.", + url: "https://forum.cosmos.network/", + bg: "linear-gradient(225deg, #46509F -1.08%, #2F3564 95.88%)", + logo: "cosmos" + }, + github: { + title: "Found an Issue?", + text: "Help us improve this page by suggesting edits on GitHub." + } }, footer: { logo: "/logo-bw.svg", diff --git a/docs/package-lock.json b/docs/package-lock.json index d5cb0853861a..132249ff9f21 100644 --- a/docs/package-lock.json +++ b/docs/package-lock.json @@ -8334,9 +8334,9 @@ "integrity": "sha512-4WK/bYZmj8xLr+HUCODHGF1ZFzsYffasLUgEiMBY4fgtltdO6B4WJtlSbPaDTLpYTcGVwM2qLnFTICEcNxs3kA==" }, "terser": { - "version": "4.3.11", - "resolved": "https://registry.npmjs.org/terser/-/terser-4.3.11.tgz", - "integrity": "sha512-gcQ1DgitjIOS/CRs9n55xhiDACHkmEirg+3GpozkLzIWgcbUvkAMdzlwbWe/hrwCVUq2Cxk5Tdd7wr4F2Eahsw==", + "version": "4.4.0", + "resolved": "https://registry.npmjs.org/terser/-/terser-4.4.0.tgz", + "integrity": "sha512-oDG16n2WKm27JO8h4y/w3iqBGAOSCtq7k8dRmrn4Wf9NouL0b2WpMHGChFGZq4nFAQy1FsNJrVQHfurXOSTmOA==", "requires": { "commander": "^2.20.0", "source-map": "~0.6.1", @@ -9011,9 +9011,9 @@ } }, "vuepress-theme-cosmos": { - "version": "1.0.48", - "resolved": "https://registry.npmjs.org/vuepress-theme-cosmos/-/vuepress-theme-cosmos-1.0.48.tgz", - "integrity": "sha512-g+uaJ9QDRPrCWnKu0A3PMydeVxWTimbqzGXCCw8CTbhuRxCBeeZprHXivNrXgpSwKV+eeagCBqG34kHnLnyeKg==", + "version": "1.0.49", + "resolved": "https://registry.npmjs.org/vuepress-theme-cosmos/-/vuepress-theme-cosmos-1.0.49.tgz", + "integrity": "sha512-TLlneZgOhPlXCi9hnjGwS8Ecg7NC5oQ9x/bMNJCs7IWEjiZwraIqrwikCNhxfgWVMStXpRIGon+9ZJYJjL5vIw==", "requires": { "@cosmos-ui/vue": "^0.5.16", "@vuepress/plugin-last-updated": "^1.2.0", diff --git a/docs/package.json b/docs/package.json index df64be59740a..dc690f1d8dcc 100644 --- a/docs/package.json +++ b/docs/package.json @@ -14,6 +14,6 @@ "author": "", "license": "ISC", "dependencies": { - "vuepress-theme-cosmos": "^1.0.48" + "vuepress-theme-cosmos": "^1.0.49" } } From e0b216f56c916ccc593cbe4af1d085bb2f44203c Mon Sep 17 00:00:00 2001 From: Denis Fadeev Date: Sun, 10 Nov 2019 18:01:56 -0500 Subject: [PATCH 151/196] version --- docs/package-lock.json | 6 +++--- docs/package.json | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/docs/package-lock.json b/docs/package-lock.json index 132249ff9f21..551679f01d76 100644 --- a/docs/package-lock.json +++ b/docs/package-lock.json @@ -9011,9 +9011,9 @@ } }, "vuepress-theme-cosmos": { - "version": "1.0.49", - "resolved": "https://registry.npmjs.org/vuepress-theme-cosmos/-/vuepress-theme-cosmos-1.0.49.tgz", - "integrity": "sha512-TLlneZgOhPlXCi9hnjGwS8Ecg7NC5oQ9x/bMNJCs7IWEjiZwraIqrwikCNhxfgWVMStXpRIGon+9ZJYJjL5vIw==", + "version": "1.0.50", + "resolved": "https://registry.npmjs.org/vuepress-theme-cosmos/-/vuepress-theme-cosmos-1.0.50.tgz", + "integrity": "sha512-oIRFgDfzuHhcKW0yD5tP0M3iuhKQItTOFDl898KYw9i64nGg8605X7soK8z3H4jHkScxdCVKIAhqg+ab16tucg==", "requires": { "@cosmos-ui/vue": "^0.5.16", "@vuepress/plugin-last-updated": "^1.2.0", diff --git a/docs/package.json b/docs/package.json index dc690f1d8dcc..0d8a9786416a 100644 --- a/docs/package.json +++ b/docs/package.json @@ -14,6 +14,6 @@ "author": "", "license": "ISC", "dependencies": { - "vuepress-theme-cosmos": "^1.0.49" + "vuepress-theme-cosmos": "^1.0.50" } } From 3716b052550f3565fb0fa63281c68843d9775d2d Mon Sep 17 00:00:00 2001 From: Denis Fadeev Date: Sun, 10 Nov 2019 19:46:28 -0500 Subject: [PATCH 152/196] version --- docs/package-lock.json | 6 +++--- docs/package.json | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/docs/package-lock.json b/docs/package-lock.json index 551679f01d76..b243d49a480f 100644 --- a/docs/package-lock.json +++ b/docs/package-lock.json @@ -9011,9 +9011,9 @@ } }, "vuepress-theme-cosmos": { - "version": "1.0.50", - "resolved": "https://registry.npmjs.org/vuepress-theme-cosmos/-/vuepress-theme-cosmos-1.0.50.tgz", - "integrity": "sha512-oIRFgDfzuHhcKW0yD5tP0M3iuhKQItTOFDl898KYw9i64nGg8605X7soK8z3H4jHkScxdCVKIAhqg+ab16tucg==", + "version": "1.0.51", + "resolved": "https://registry.npmjs.org/vuepress-theme-cosmos/-/vuepress-theme-cosmos-1.0.51.tgz", + "integrity": "sha512-8/YDJTjaW1hJzC37JadfNm86gtXptWfLWHYLP+bV/AfEKoisA6CSIDrP0ZES5h1VLlM0cqMK45HNV/toP/RjYA==", "requires": { "@cosmos-ui/vue": "^0.5.16", "@vuepress/plugin-last-updated": "^1.2.0", diff --git a/docs/package.json b/docs/package.json index 0d8a9786416a..63bc0f275296 100644 --- a/docs/package.json +++ b/docs/package.json @@ -14,6 +14,6 @@ "author": "", "license": "ISC", "dependencies": { - "vuepress-theme-cosmos": "^1.0.50" + "vuepress-theme-cosmos": "^1.0.51" } } From 30dae649bc21f5aff3d6df069ba5205b6c4b6eb3 Mon Sep 17 00:00:00 2001 From: Denis Fadeev Date: Tue, 12 Nov 2019 11:06:25 -0500 Subject: [PATCH 153/196] readme and version --- docs/DOCS_README.md | 29 +++++++++++------------------ docs/package-lock.json | 26 +++++++++++++------------- docs/package.json | 2 +- 3 files changed, 25 insertions(+), 32 deletions(-) diff --git a/docs/DOCS_README.md b/docs/DOCS_README.md index 609044c5192f..c2b7e86ea409 100644 --- a/docs/DOCS_README.md +++ b/docs/DOCS_README.md @@ -59,34 +59,27 @@ to send users to the GitHub. ## Building Locally -To build and serve the documentation locally, run: +Make sure you are in the `docs` directory and run the following commands: -```bash -npm install -g vuepress +```sh +rm -rf node_modules ``` -then change the following line in the `config.js`: +This command will remove old version of the visual theme and required packages. This step is optional. -```js -base: "/docs/", +```sh +npm install ``` -to: +Install the theme and all dependencies. -```js -base: "/", +```sh +npm run serve ``` -Finally, go up one directory to the root of the repo and run: +Run `pre` and `post` hooks and start a hot-reloading web-server. See output of this command for the URL (it is often https://localhost:8080). -```bash -# from root of repo -vuepress build docs -cd dist/docs -python -m SimpleHTTPServer 8080 -``` - -then navigate to localhost:8080 in your browser. +To build documentation as a static website run `npm run build`. You will find the website in `.vuepress/dist` directory. ## Build RPC Docs diff --git a/docs/package-lock.json b/docs/package-lock.json index b243d49a480f..70325356b49a 100644 --- a/docs/package-lock.json +++ b/docs/package-lock.json @@ -5578,16 +5578,16 @@ "integrity": "sha512-LRxmNwziLPT828z+4YkNzloCFC2YM4wrB99k+AV5ZbEyfGNWfG8SO1FUXLmLDBSo89NrJZ4DIWeLjy1CHGhMGA==" }, "mime-db": { - "version": "1.40.0", - "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.40.0.tgz", - "integrity": "sha512-jYdeOMPy9vnxEqFRRo6ZvTZ8d9oPb+k18PKoYNYUe2stVEBPPwsln/qWzdbmaIvnhZ9v2P+CuecK+fpUfsV2mA==" + "version": "1.42.0", + "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.42.0.tgz", + "integrity": "sha512-UbfJCR4UAVRNgMpfImz05smAXK7+c+ZntjaA26ANtkXLlOe947Aag5zdIcKQULAiF9Cq4WxBi9jUs5zkA84bYQ==" }, "mime-types": { - "version": "2.1.24", - "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.24.tgz", - "integrity": "sha512-WaFHS3MCl5fapm3oLxU4eYDw77IQM2ACcxQ9RIxfaC3ooc6PFuBMGZZsYpvoXS5D5QTWPieo1jjLdAm3TBP3cQ==", + "version": "2.1.25", + "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.25.tgz", + "integrity": "sha512-5KhStqB5xpTAeGqKBAMgwaYMnQik7teQN4IAzC7npDv6kzeU6prfkR67bc87J1kWMPGkoaZSq1npmexMgkmEVg==", "requires": { - "mime-db": "1.40.0" + "mime-db": "1.42.0" } }, "mimic-fn": { @@ -5921,9 +5921,9 @@ } }, "object-inspect": { - "version": "1.6.0", - "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.6.0.tgz", - "integrity": "sha512-GJzfBZ6DgDAmnuaM3104jR4s1Myxr3Y3zfIyN4z3UdqN69oSRacNK8UhnobDdC+7J2AHCjGwxQubNJfE70SXXQ==" + "version": "1.7.0", + "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.7.0.tgz", + "integrity": "sha512-a7pEHdh1xKIAgTySUGgLMx/xwDZskN1Ud6egYYN3EdRW4ZMPNEDUTF+hwy2LUC+Bl+SyLXANnwz/jyh/qutKUw==" }, "object-is": { "version": "1.0.1", @@ -9011,9 +9011,9 @@ } }, "vuepress-theme-cosmos": { - "version": "1.0.51", - "resolved": "https://registry.npmjs.org/vuepress-theme-cosmos/-/vuepress-theme-cosmos-1.0.51.tgz", - "integrity": "sha512-8/YDJTjaW1hJzC37JadfNm86gtXptWfLWHYLP+bV/AfEKoisA6CSIDrP0ZES5h1VLlM0cqMK45HNV/toP/RjYA==", + "version": "1.0.55", + "resolved": "https://registry.npmjs.org/vuepress-theme-cosmos/-/vuepress-theme-cosmos-1.0.55.tgz", + "integrity": "sha512-Mag5YqSJ9/HUGxdty2Z95i7Nd+klrCvwyN5KD3uy4wRC3eTxj+7u/wyKkZNq/OYSoUAuwGlBzL9GFutmyZCbMA==", "requires": { "@cosmos-ui/vue": "^0.5.16", "@vuepress/plugin-last-updated": "^1.2.0", diff --git a/docs/package.json b/docs/package.json index 63bc0f275296..a73ddc349765 100644 --- a/docs/package.json +++ b/docs/package.json @@ -14,6 +14,6 @@ "author": "", "license": "ISC", "dependencies": { - "vuepress-theme-cosmos": "^1.0.51" + "vuepress-theme-cosmos": "^1.0.55" } } From 483d597443f6df869153f7fd6feafeb7d726ce52 Mon Sep 17 00:00:00 2001 From: gamarin Date: Wed, 13 Nov 2019 15:34:37 +0100 Subject: [PATCH 154/196] cleanup --- docs/core/README.md | 2 +- docs/intro/README.md | 5 +++-- docs/intro/{intro.md => overview.md} | 2 +- docs/intro/sdk-app-architecture.md | 4 ++-- docs/intro/sdk-design.md | 6 ++++-- 5 files changed, 11 insertions(+), 8 deletions(-) rename docs/intro/{intro.md => overview.md} (99%) diff --git a/docs/core/README.md b/docs/core/README.md index 8d9348350932..6d865e79a8ff 100644 --- a/docs/core/README.md +++ b/docs/core/README.md @@ -4,7 +4,7 @@ parent: order: 3 --- -# Core +# Core Concepts This repository contains reference documentation on the core conepts of the Cosmos SDK. diff --git a/docs/intro/README.md b/docs/intro/README.md index 3657cf102999..22ade6bf00a7 100644 --- a/docs/intro/README.md +++ b/docs/intro/README.md @@ -1,13 +1,14 @@ --- +order: false parent: order: 1 --- -# SDK - Intro Material +# Introduction This folder contains introduction material on the Cosmos SDK. -1. [SDK Introduction](./intro.md) +1. [Overview](./overview.md) 2. [Application-Specific Blockchains](./why-app-specific.md) 3. [Architecture of an SDK Application](./sdk-app-architecture.md) 4. [Cosmos SDK Design Overview](./sdk-design.md) diff --git a/docs/intro/intro.md b/docs/intro/overview.md similarity index 99% rename from docs/intro/intro.md rename to docs/intro/overview.md index 5d6a574d66ec..35247994967f 100644 --- a/docs/intro/intro.md +++ b/docs/intro/overview.md @@ -2,7 +2,7 @@ order: 1 --- -# SDK Intro +# High-level Overview ## What is the SDK? diff --git a/docs/intro/sdk-app-architecture.md b/docs/intro/sdk-app-architecture.md index 4a52d80c3c43..a88ae9ca45c9 100644 --- a/docs/intro/sdk-app-architecture.md +++ b/docs/intro/sdk-app-architecture.md @@ -2,7 +2,7 @@ order: 3 --- -# SDK Application Architecture +# Architecture of a Cosmos SDK Application ## State machine @@ -62,7 +62,7 @@ The Tendermint consensus algorithm works with a set of special nodes called *Val ## ABCI -Tendermint passes transactions to the application through an interface called the [ABCI](https://github.com/tendermint/tendermint/tree/bc572217c07b90ad9cee851f193aaa8e9557cbc7/abci), which the application must implement. +Tendermint passes transactions to the application through an interface called the [ABCI](https://tendermint.com/docs/spec/abci/), which the application must implement. ``` +---------------------+ diff --git a/docs/intro/sdk-design.md b/docs/intro/sdk-design.md index 544644061bad..8ed1c034731c 100644 --- a/docs/intro/sdk-design.md +++ b/docs/intro/sdk-design.md @@ -2,7 +2,7 @@ order: 4 --- -# Cosmos SDK design overview +# Main Components of the SDK The Cosmos SDK is a framework that facilitates the development of secure state-machines on top of Tendermint. At its core, the SDK is a boilerplate implementation of the [ABCI](./sdk-app-architecture.md#abci) in Golang. It comes with a [`multistore`](../core/store.md#multistore) to persist data and a [`router`](../core/baseapp.md#routing) to handle transactions. @@ -15,7 +15,9 @@ Here is a simplified view of how transactions are handled by an application buil ## `baseapp` -`baseapp` is the boilerplate implementation of a Cosmos SDK application. It comes with an implementation of the ABCI to handle the connexion with the underlying consensus engine. Typically, a Cosmos SDK application extends `baseapp` by embedding it in [`app.go`](../basics/app-anatomy.md#core-application-file). See an example of this from the [SDK application tutorial](https://github.com/cosmos/sdk-application-tutorial/blob/c6754a1e313eb1ed973c5c91dcc606f2fd288811/app.go#L27). +`baseapp` is the boilerplate implementation of a Cosmos SDK application. It comes with an implementation of the ABCI to handle the connexion with the underlying consensus engine. Typically, a Cosmos SDK application extends `baseapp` by embedding it in [`app.go`](../basics/app-anatomy.md#core-application-file). See an example of this from the SDK application tutorial: + ++++ https://github.com/cosmos/sdk-tutorials/blob/c6754a1e313eb1ed973c5c91dcc606f2fd288811/app.go#L72-L92 The goal of `baseapp` is to provide a secure interface between the store and the extensible state machine while defining as little about the state machine as possible (staying true to the ABCI). From deffa90e4e89dc2b58ed032857b643ecc96feabd Mon Sep 17 00:00:00 2001 From: gamarin Date: Wed, 13 Nov 2019 17:52:12 +0100 Subject: [PATCH 155/196] redo app anatomy --- docs/basics/app-anatomy.md | 75 +++++++++++++++++++++--------- docs/building-modules/structure.md | 2 +- docs/core/node.md | 24 +++------- docs/intro/sdk-app-architecture.md | 3 +- docs/intro/sdk-design.md | 4 +- 5 files changed, 63 insertions(+), 45 deletions(-) diff --git a/docs/basics/app-anatomy.md b/docs/basics/app-anatomy.md index 670a6a4042e7..f85b851c128e 100644 --- a/docs/basics/app-anatomy.md +++ b/docs/basics/app-anatomy.md @@ -37,11 +37,9 @@ Blockchain Node | | Consensus | | The blockchain full-node presents itself as a binary, generally suffixed by `-d` for "daemon" (e.g. `appd` for `app` or `gaiad` for `gaia`). This binary is built by running a simple [`main.go`]((../core/node.md#main-function)) function placed in `./cmd/appd/`. This operation usually happens through the [Makefile](#dependencies-and-makefile). -Once the main binary is built, the node can be started by running the `start` command. The core logic behind the `start` command is implemented in the SDK itself in the [`/server/start.go`](https://github.com/cosmos/cosmos-sdk/blob/master/server/start.go) file. The main [`start` command function](https://github.com/cosmos/cosmos-sdk/blob/master/server/start.go#L31) takes a [`context`](https://godoc.org/github.com/cosmos/cosmos-sdk/client/context) and [`appCreator`](<#constructor-function-(`appCreator`)>) as arguments. The `appCreator` is a constructor function for the SDK application, and is used in the starting process of the full-node. +Once the main binary is built, the node can be started by running the [`start` command](../core/node.md#start-command). This command function primarily does three things: -The `start` command function primarily does three things: - -1. Create an instance of the state-machine defined in [`app.go`](#core-application-file) using the `appCreator`. +1. Create an instance of the state-machine defined in [`app.go`](#core-application-file). 2. Initialize the state-machine with the latest known state, extracted from the `db` stored in the `~/.appd/data` folder. At this point, the state-machine is at height `appBlockHeight`. 3. Create and start a new Tendermint instance. Among other things, the node will perform a handshake with its peers. It will get the latest `blockHeight` from them, and replay blocks to sync to this height if it is greater than the local `appBlockHeight`. If `appBlockHeight` is `0`, the node is starting from genesis and Tendermint sends an `InitChain` message via the ABCI to the `app`, which triggers the [`InitChainer`](#initchainer). @@ -53,17 +51,23 @@ In general, the core of the state-machine is defined in a file called `app.go`. The first thing defined in `app.go` is the `type` of the application. It is generally comprised of the following parts: -- **A reference to [`baseapp`](../core/baseapp.md).** The custom application defined in `app.go` is an extension of `baseapp`. When a transaction is relayed by Tendermint to the application, `app` uses `baseapp`'s methods to route them to the appropriate module. `baseapp` implements most of the core logic for the application, including all the [ABCI methods](https://tendermint.com/docs/spec/abci/abci.html#overview) and the [routing logic](../core/baseapp.md#routing). Since `baseapp` implements ABCI methods and `app` extends `baseapp`, it means that `app` satisfies the [`abci.Application` interface](https://github.com/tendermint/tendermint/blob/bc572217c07b90ad9cee851f193aaa8e9557cbc7/abci/types/application.go#L11-L26), which is a must for the [full-node](../core/node.md) to work. +- **A reference to [`baseapp`](../core/baseapp.md).** The custom application defined in `app.go` is an extension of `baseapp`. When a transaction is relayed by Tendermint to the application, `app` uses `baseapp`'s methods to route them to the appropriate module. `baseapp` implements most of the core logic for the application, including all the [ABCI methods](https://tendermint.com/docs/spec/abci/abci.html#overview) and the [routing logic](../core/baseapp.md#routing). - **A list of store keys**. The [store](../core/store.md), which contains the entire state, is implemented as a [`multistore`](../core/store.md#multistore) (i.e. a store of stores) in the Cosmos SDK. Each module uses one or multiple stores in the multistore to persist their part of the state. These stores can be accessed with specific keys that are declared in the `app` type. These keys, along with the `keepers`, are at the heart of the [object-capabilities model](../core/ocap.md) of the Cosmos SDK. - **A list of module's `keeper`s.** Each module defines an abstraction called [`keeper`](../building-modules/keeper.md), which handles reads and writes for this module's store(s). The `keeper`'s methods of one module can be called from other modules (if authorized), which is why they are declared in the application's type and exported as interfaces to other modules so that the latter can only access the authorized functions. - **A reference to a [`codec`](../core/encoding.md).** The application's `codec` is used to serialize and deserialize data structures in order to store them, as stores can only persist `[]bytes`. The `codec` must be deterministic. The default codec is [amino](../core/encoding.md). - **A reference to a [module manager](../building-modules/module-manager.md#manager)** and a [basic module manager](../building-modules/module-manager.md#basicmanager). The module manager is an object that contains a list of the application's module. It facilitates operations related to these modules, like registering [`routes`](../core/baseapp.md#routing), [query routes](../core/baseapp.md#query-routing) or setting the order of execution between modules for various functions like [`InitChainer`](#initchainer), [`BeginBlocker` and `EndBlocker`](#beginblocker-and-endblocker). -You can see an example of application type definition [here](https://github.com/cosmos/gaia/blob/master/app/app.go#L73-L107). +See an example of application type definition from [`gaia`](https://github.com/cosmos/gaia) + ++++ https://github.com/cosmos/gaia/blob/5bc422e6868d04747e50b467e8eeb31ae2fe98a3/app/app.go#L87-L115 ### Constructor Function -This function constructs a new application of the type defined above. It is called every time the full-node is started with the [`start`](https://github.com/cosmos/cosmos-sdk/blob/master/server/start.go#L117) command. Here are the main actions performed by this function: +This function constructs a new application of the type defined in the section above. It must fulfill the `AppCreator` signature in order to be used in the [`start` command](../core/node.md#start-command) of the application's daemon command. + ++++ https://github.com/cosmos/cosmos-sdk/blob/master/server/constructors.go#L20 + +Here are the main actions performed by this function: - Instantiate a new [`codec`](../core/encoding.md) and initialize the `codec` of each of the application's module using the [basic manager](../building-modules/module-manager.md#basicmanager) - Instantiate a new application with a reference to a `baseapp` instance, a codec and all the appropriate store keys. @@ -81,25 +85,31 @@ This function constructs a new application of the type defined above. It is call Note that this function only creates an instance of the app, while the actual state is either carried over from the `~/.appd/data` folder if the node is restarted, or generated from the genesis file if the node is started for the first time. -You can see an example of application constructor [here](https://github.com/cosmos/gaia/blob/f41a660cdd5bea173139965ade55bd25d1ee3429/app/app.go#L110-L222). +See an example of application constructor from [`gaia`](https://github.com/cosmos/gaia): + ++++ https://github.com/cosmos/gaia/blob/f41a660cdd5bea173139965ade55bd25d1ee3429/app/app.go#L110-L222 ### InitChainer -The `InitChainer` is a function that initializes the state of the application from a genesis file (i.e. token balances of genesis accounts). It is called when the application receives the `InitChain` message from the Tendermint engine, which happens when the node is started at `appBlockHeight == 0` (i.e. on genesis). The application must set the `InitChainer` in its constructor via the [`SetInitChainer`](https://godoc.org/github.com/cosmos/cosmos-sdk/baseapp#BaseApp.SetInitChainer) method. +The `InitChainer` is a function that initializes the state of the application from a genesis file (i.e. token balances of genesis accounts). It is called when the application receives the `InitChain` message from the Tendermint engine, which happens when the node is started at `appBlockHeight == 0` (i.e. on genesis). The application must set the `InitChainer` in its [constructor](#constructor-function) via the [`SetInitChainer`](https://godoc.org/github.com/cosmos/cosmos-sdk/baseapp#BaseApp.SetInitChainer) method. In general, the `InitChainer` is mostly composed of the [`InitGenesis`](../building-modules/genesis.md#initgenesis) function of each of the application's modules. This is done by calling the `InitGenesis` function of the module manager, which in turn will call the `InitGenesis` function of each of the modules it contains. Note that the order in which the modules' `InitGenesis` functions must be called has to be set in the module manager using the [module manager's](../building-modules/module-manager.md) `SetOrderInitGenesis` method. This is done in the [application's constructor](#application-constructor), and the `SetOrderInitGenesis` has to be called before the `SetInitChainer`. -You can see an example of an `InitChainer` [here](https://github.com/cosmos/gaia/blob/f41a660cdd5bea173139965ade55bd25d1ee3429/app/app.go#L235-L239). +See an example of an `InitChainer` from [`gaia`](https://github.com/cosmos/gaia): + ++++ https://github.com/cosmos/gaia/blob/f41a660cdd5bea173139965ade55bd25d1ee3429/app/app.go#L235-L239 ### BeginBlocker and EndBlocker -The SDK offers developers the possibility to implement automatic execution of code as part of their application. This is implemented through two function called `BeginBlocker` and `EndBlocker`. They are called when the application receives respectively the `BeginBlock` and `EndBlock` messages from the Tendermint engine, which happens at the beginning and at the end of each block. The application must set the `BeginBlocker` and `EndBlocker` in its constructor via the [`SetBeginBlocker`](https://godoc.org/github.com/cosmos/cosmos-sdk/baseapp#BaseApp.SetBeginBlocker) and [`SetEndBlocker`](https://godoc.org/github.com/cosmos/cosmos-sdk/baseapp#BaseApp.SetEndBlocker) methods. +The SDK offers developers the possibility to implement automatic execution of code as part of their application. This is implemented through two function called `BeginBlocker` and `EndBlocker`. They are called when the application receives respectively the `BeginBlock` and `EndBlock` messages from the Tendermint engine, which happens at the beginning and at the end of each block. The application must set the `BeginBlocker` and `EndBlocker` in its [constructor](#constructor-function) via the [`SetBeginBlocker`](https://godoc.org/github.com/cosmos/cosmos-sdk/baseapp#BaseApp.SetBeginBlocker) and [`SetEndBlocker`](https://godoc.org/github.com/cosmos/cosmos-sdk/baseapp#BaseApp.SetEndBlocker) methods. In general, the `BeginBlocker` and `EndBlocker` functions are mostly composed of the [`BeginBlock` and `EndBlock`](../building-modules/beginblock-endblock.md) functions of each of the application's modules. This is done by calling the `BeginBlock` and `EndBlock` functions of the module manager, which in turn will call the `BeginBLock` and `EndBlock` functions of each of the modules it contains. Note that the order in which the modules' `BegingBlock` and `EndBlock` functions must be called has to be set in the module manager using the `SetOrderBeginBlock` and `SetOrderEndBlock` methods respectively. This is done via the [module manager](../building-modules/module-manager.md) in the [application's constructor](#application-constructor), and the `SetOrderBeginBlock` and `SetOrderEndBlock` methods have to be called before the `SetBeginBlocker` and `SetEndBlocker` functions. As a sidenote, it is important to remember that application-specific blockchains are deterministic. Developers must be careful not to introduce non-determinism in `BeginBlocker` or `EndBlocker`, and must also be careful not to make them too computationally expensive, as [gas](./gas-fees.md) does not constrain the cost of `BeginBlocker` and `EndBlocker` execution. -You can see an example of `BeginBlocker` and `EndBlocker` functions [here](https://github.com/cosmos/gaia/blob/f41a660cdd5bea173139965ade55bd25d1ee3429/app/app.go#L224-L232). +See an example of `BeginBlocker` and `EndBlocker` functions from [`gaia`](https://github.com/cosmos/gaia) + ++++ https://github.com/cosmos/gaia/blob/f41a660cdd5bea173139965ade55bd25d1ee3429/app/app.go#L224-L232 ### Register Codec @@ -107,7 +117,9 @@ The `MakeCodec` function is the last important function of the `app.go` file. Th To register the application's modules, the `MakeCodec` function calls `RegisterCodec` on `ModuleBasics`. `ModuleBasics` is a [basic manager](../building-modules/module-manager.md#basicmanager) which lists all of the application's modules. It is instanciated in the `init()` function, and only serves to easily register non-dependant elements of application's modules (such as codec). To learn more about the basic module manager, click [here](../building-modules/module-manager.md#basicmanager). -You can see an example of a `MakeCodec` [here](https://github.com/cosmos/gaia/blob/f41a660cdd5bea173139965ade55bd25d1ee3429/app/app.go#L64-L70) +See an example of a `MakeCodec` from [`gaia`](https://github.com/cosmos/gaia): + ++++ https://github.com/cosmos/gaia/blob/f41a660cdd5bea173139965ade55bd25d1ee3429/app/app.go#L64-L70 ## Modules @@ -131,12 +143,16 @@ When a valid block of transactions is received by the full-node, Tendermint rela 1. Upon receiving the transaction, the application first unmarshalls it from `[]bytes`. 2. Then, it verifies a few things about the transaction like [fee payment and signatures](#gas-fees.md#antehandler) before extracting the message(s) contained in the transaction. -3. With the [`Type()`](https://github.com/cosmos/cosmos-sdk/blob/master/types/tx_msg.go#L16) method, `baseapp` is able to know which modules defines the message. It is then able to route it to the appropriate module's [`handler`](#handler) in order for the message to be processed. +3. With the `Type()` method of the `message`, `baseapp` is able to route it to the appropriate module's [`handler`](#handler) in order for it to be processed. 4. If the message is successfully processed, the state is updated. For a more detailed look at a transaction lifecycle, click [here](./tx-lifecycle.md). -Module developers create custom message types when they build their own module. The general practice is to prefix the type declaration of the message with `Msg`. For example, the message type [`MsgSend`](https://github.com/cosmos/cosmos-sdk/blob/master/x/bank/internal/types/msgs.go#L11-L15) allows users to transfer tokens. It is processed by the `handler` of the `bank` module, which ultimately calls the `keeper` of the `auth` module in order to update the state. +Module developers create custom message types when they build their own module. The general practice is to prefix the type declaration of the message with `Msg`. For example, the message type `MsgSend` allows users to transfer tokens: + ++++ https://github.com/cosmos/cosmos-sdk/blob/master/x/bank/internal/types/msgs.go#L11-L15 + +It is processed by the `handler` of the `bank` module, which ultimately calls the `keeper` of the `auth` module in order to update the state. To learn more about messages, [click here](../building-modules/messages-and-queries.md#messages). @@ -146,10 +162,13 @@ The [`handler`](../building-modules/handler.md) refers to the part of the module The `handler` of a module is generally defined in a file called `handler.go` and consists of: -- A **switch function** `NewHandler` to route the message to the appropriate `handler` function. This function returns a `handler` function, and is registered in the [`AppModule`](#application-module-interface) to be used in the application's module manager to initialize the [application's router](../core/baseapp.md#routing). See an example of such a switch [here](https://github.com/cosmos/sdk-application-tutorial/blob/c6754a1e313eb1ed973c5c91dcc606f2fd288811/x/nameservice/handler.go#L10-L22). +- A **switch function** `NewHandler` to route the message to the appropriate `handler` function. This function returns a `handler` function, and is registered in the [`AppModule`](#application-module-interface) to be used in the application's module manager to initialize the [application's router](../core/baseapp.md#routing). Next is an example of such a switch from the [nameservice tutorial](https://github.com/cosmos/sdk-tutorials/tree/master/nameservice) + +++ https://github.com/cosmos/sdk-tutorials/blob/master/nameservice/x/nameservice/handler.go#L12-L26 - **One handler function for each message type defined by the module**. Developers write the message processing logic in these functions. This generally involves doing stateful checks to ensure the message is valid and calling [`keeper`](#keeper)'s methods to update the state. -Handler functions return a result of type [`sdk.Result`](https://github.com/cosmos/cosmos-sdk/blob/master/types/result.go#L14-L37), which informs the application on whether the message was successfully processed. +Handler functions return a result of type `sdk.Result`, which informs the application on whether the message was successfully processed: + ++++ https://github.com/cosmos/cosmos-sdk/blob/master/types/result.go#L14-L37 To learn more about handlers, [click here](../building-modules/handler.md). @@ -171,11 +190,14 @@ To learn more about `keepers`, [click here](../building-modules/keeper.md). ### Querier -[`Queriers`](../building-modules/querier.md) are very similar to `handlers`, except they serve user queries to the state as opposed to processing transactions. A [query](../building-modules/messages-and-queries.md#queries) is initiated from an [interface](#interfaces) by an end-user who provides a `queryRoute` and some `data`. The query is then routed to the correct application's `querier` by `baseapp`'s [`handleQueryCustom`](https://github.com/cosmos/cosmos-sdk/blob/master/baseapp/baseapp.go#L519-L556) method using `queryRoute`. +[`Queriers`](../building-modules/querier.md) are very similar to `handlers`, except they serve user queries to the state as opposed to processing transactions. A [query](../building-modules/messages-and-queries.md#queries) is initiated from an [interface](#interfaces) by an end-user who provides a `queryRoute` and some `data`. The query is then routed to the correct application's `querier` by `baseapp`'s `handleQueryCustom` method using `queryRoute`: + ++++ https://github.com/cosmos/cosmos-sdk/blob/master/baseapp/baseapp.go#L519-L556 The `Querier` of a module is defined in a file called `querier.go`, and consists of: -- A **switch function** `NewQuerier` to route the query to the appropriate `querier` function. This function returns a `querier` function, and is is registered in the [`AppModule`](#application-module-interface) to be used in the application's module manager to initialize the [application's query router](../core/baseapp.md#query-routing). See an example of such a switch [here](https://github.com/cosmos/sdk-application-tutorial/blob/c6754a1e313eb1ed973c5c91dcc606f2fd288811/x/nameservice/internal/keeper/querier.go#L19-L32). +- A **switch function** `NewQuerier` to route the query to the appropriate `querier` function. This function returns a `querier` function, and is is registered in the [`AppModule`](#application-module-interface) to be used in the application's module manager to initialize the [application's query router](../core/baseapp.md#query-routing). See an example of such a switch from the [nameservice tutorial](https://github.com/cosmos/sdk-tutorials/tree/master/nameservice): + +++ https://github.com/cosmos/sdk-tutorials/blob/86a27321cf89cc637581762e953d0c07f8c78ece/nameservice/x/nameservice/internal/keeper/querier.go#L19-L32 - - **One querier function for each data type defined by the module that needs to be queryable**. Developers write the query processing logic in these functions. This generally involves calling [`keeper`](#keeper)'s methods to query the state and marshalling it to JSON. To learn more about `queriers`, [click here](../building-modules/querier.md). @@ -198,7 +220,8 @@ To learn more about modules CLI, [click here](../building-modules/module-interfa The module's REST interface lets users generate transactions and query the state through REST calls to the application's [light client daemon](../core/node.md#lcd) (LCD). REST routes are defined in a file `client/rest/rest.go`, which is composed of: - A `RegisterRoutes` function, which registers each route defined in the file. This function is called from the [main application's interface](#application-interfaces) for each module used within the application. The router used in the SDK is [Gorilla's mux](https://github.com/gorilla/mux). -- Custom request type definitions for each query or transaction creation function that needs to be exposed. These custom request types build on the [base `request` type](https://github.com/cosmos/cosmos-sdk/blob/master/types/rest/rest.go#L32-L43) of the Cosmos SDK. +- Custom request type definitions for each query or transaction creation function that needs to be exposed. These custom request types build on the base `request` type of the Cosmos SDK: + +++ https://github.com/cosmos/cosmos-sdk/blob/master/types/rest/rest.go#L32-L43 - One handler function for each request that can be routed to the given module. These functions implement the core logic necessary to serve the request. To learn more about modules REST interface, [click here](../building-modules/module-interfaces.md#rest). @@ -214,15 +237,21 @@ The main interface is the [Command-Line Interface](../interfaces/cli.md). The CL - **Transaction commands** are added by calling the `txCmd` function. Similar to `queryCmd`, the function returns a Cobra command that contains the tx commands defined in each of the application's modules, as well as lower level tx commands like transaction signing or broadcasting. Tx commands are called by using the command `appcli tx [tx]` of the CLI. - **A `registerRoutes` function**, which is called from the `main()` function when initializing the [application's light-client daemon (LCD)](../core/node.md#lcd) (i.e. `rest-server`). `registerRoutes` calls the `RegisterRoutes` function of each of the application's module, thereby registering the routes of the module to the lcd's router. The LCD can be started by running the following command `appcli rest-server`. -See an example of an application's main command-line file [here](https://github.com/cosmos/sdk-application-tutorial/blob/c6754a1e313eb1ed973c5c91dcc606f2fd288811/cmd/nscli/main.go). +See an example of an application's main command-line file from the [nameservice tutorial](https://github.com/cosmos/sdk-tutorials/tree/master/nameservice) + ++++ https://github.com/cosmos/sdk-tutorials/blob/86a27321cf89cc637581762e953d0c07f8c78ece/nameservice/cmd/nscli/main.go To learn more about interfaces, [click here](../interfaces/interfaces-intro.md). ## Dependencies and Makefile -This section is optional, as developers are free to choose their dependency manager and project building method. That said, the current most used framework for versioning control is [`go.mod`](https://github.com/golang/go/wiki/Modules). It ensures each of the libraries used throughout the application are imported with the correct version. An example can be found [here](https://github.com/cosmos/sdk-application-tutorial/blob/c6754a1e313eb1ed973c5c91dcc606f2fd288811/go.mod). +This section is optional, as developers are free to choose their dependency manager and project building method. That said, the current most used framework for versioning control is [`go.mod`](https://github.com/golang/go/wiki/Modules). It ensures each of the libraries used throughout the application are imported with the correct version. See an example from the [nameservice tutorial](https://github.com/cosmos/sdk-tutorials/tree/master/nameservice): + ++++ https://github.com/cosmos/sdk-tutorials/blob/c6754a1e313eb1ed973c5c91dcc606f2fd288811/go.mod#L1-L18 + +For building the application, a [Makefile](https://en.wikipedia.org/wiki/Makefile) is generally used. The Makefile primarily ensures that the `go.mod` is run before building the two entrypoints to the application, [`appd`](#node-client) and [`appcli`](#application-interface). See an example of Makefile from the [nameservice tutorial]() -For building the application, a [Makefile](https://en.wikipedia.org/wiki/Makefile) is generally used. The Makefile primarily ensures that the `go.mod` is run before building the two entrypoints to the application, [`appd`](#node-client) and [`appcli`](#application-interface). An example of Makefile can be found [here](https://github.com/cosmos/sdk-application-tutorial/blob/c6754a1e313eb1ed973c5c91dcc606f2fd288811/Makefile). ++++ https://github.com/cosmos/sdk-tutorials/blob/86a27321cf89cc637581762e953d0c07f8c78ece/nameservice/Makefile ## Next diff --git a/docs/building-modules/structure.md b/docs/building-modules/structure.md index c039b3cbb3be..0883fefd2aeb 100644 --- a/docs/building-modules/structure.md +++ b/docs/building-modules/structure.md @@ -2,7 +2,7 @@ order: 12 --- -# Recommended Structure +# Recommended Folder Structure This document outlines the recommended structure of Cosmos SDK modules. These ideas are meant to be applied as suggestions. Application developers are encouraged diff --git a/docs/core/node.md b/docs/core/node.md index afc859da6ef5..3d1d12edc90e 100644 --- a/docs/core/node.md +++ b/docs/core/node.md @@ -40,27 +40,17 @@ As a reminder, the full-node is composed of three conceptual layers: the network The flow of the `start` command is pretty straightforward. First, it retrieves the `config` from the `context` in order to open the `db` (a [`leveldb`](https://github.com/syndtr/goleveldb) instance by default). This `db` contains the latest known state of the application (empty if the application is started from the first time. -With the `db`, the `start` command creates a new instance of the application using the [application's constructor function](../basics/app-anatomy.md#constructor-function). +With the `db`, the `start` command creates a new instance of the application using an `appCreator` function: -```go -app := appCreator(ctx.Logger, db, traceWriter) -``` ++++ https://github.com/cosmos/cosmos-sdk/blob/master/server/start.go#L144 -In the background, the `db` is used by the `appCreator` to mount the main [`CommitMultiStore`](./store.md#commitmultistore) of the application. Then, the instance of `app` is used to instanciate a new Tendermint node: +Note that an `appCreator` is a function that fulfills the `AppCreator` signature. In practice, the [constructor the application](../basics/app-anatomy.md#constructor-function) is passed as the `appCreator`. ++++ https://github.com/cosmos/cosmos-sdk/blob/master/server/constructors.go#L20 -```go -tmNode, err := node.NewNode( - cfg, - pvm.LoadOrGenFilePV(cfg.PrivValidatorKeyFile(), cfg.PrivValidatorStateFile()), - nodeKey, - proxy.NewLocalClientCreator(app), - node.DefaultGenesisDocProviderFunc(cfg), - node.DefaultDBProvider, - node.DefaultMetricsProvider(cfg.Instrumentation), - ctx.Logger.With("module", "node"), -) -``` +Then, the instance of `app` is used to instanciate a new Tendermint node: + ++++ https://github.com/cosmos/cosmos-sdk/blob/master/server/start.go#L153-L163 The Tendermint node can be created with `app` because the latter satisfies the [`abci.Application` interface](https://github.com/tendermint/tendermint/blob/bc572217c07b90ad9cee851f193aaa8e9557cbc7/abci/types/application.go#L11-L26) (given that `app` extends [`baseapp`](./baseapp.md)). As part of the `NewNode` method, Tendermint makes sure that the height of the application (i.e. number of blocks since genesis) is equal to the height of the Tendermint node. The difference between these two heights should always be negative or null. If it is strictly negative, `NewNode` will replay blocks until the height of the application reaches the height of the Tendermint node. Finally, if the height of the application is `0`, the Tendermint node will call [`InitChain`](./baseapp.md#initchain) on the application to initialize the state from the genesis file. diff --git a/docs/intro/sdk-app-architecture.md b/docs/intro/sdk-app-architecture.md index a88ae9ca45c9..47b1cfd32a03 100644 --- a/docs/intro/sdk-app-architecture.md +++ b/docs/intro/sdk-app-architecture.md @@ -2,7 +2,7 @@ order: 3 --- -# Architecture of a Cosmos SDK Application +# Blockchain Architecture ## State machine @@ -94,6 +94,7 @@ For a more detailed view of the ABCI methods and types, click [here](https://ten Any application built on Tendermint needs to implement the ABCI interface in order to communicate with the underlying local Tendermint engine. Fortunately, you do not have to implement the ABCI interface. The Cosmos SDK provides a boilerplate implementation of it in the form of [baseapp](./sdk-design.md#baseapp). + ## Next Read about the [high-level design principles of the SDK](./sdk-design.md) \ No newline at end of file diff --git a/docs/intro/sdk-design.md b/docs/intro/sdk-design.md index 8ed1c034731c..02abe6c5bb07 100644 --- a/docs/intro/sdk-design.md +++ b/docs/intro/sdk-design.md @@ -2,7 +2,7 @@ order: 4 --- -# Main Components of the SDK +# Main Components of the Cosmos SDK The Cosmos SDK is a framework that facilitates the development of secure state-machines on top of Tendermint. At its core, the SDK is a boilerplate implementation of the [ABCI](./sdk-app-architecture.md#abci) in Golang. It comes with a [`multistore`](../core/store.md#multistore) to persist data and a [`router`](../core/baseapp.md#routing) to handle transactions. @@ -91,6 +91,4 @@ SDK modules are defined in the `x/` folder of the SDK. Some core modules include In addition to the already existing modules in `x/`, that anyone can use in their app, the SDK lets you build your own custom modules. You can check an [example of that in the tutorial](https://cosmos.network/docs/tutorial/keeper.html). -## Next -Learn more about the basics of the Cosmos SDK, starting with the [anatomy of an SDK application](../basics/app-anatomy.md) From aae2d9f07113c6ee5917a467c51d436017d4ef61 Mon Sep 17 00:00:00 2001 From: Denis Fadeev Date: Wed, 13 Nov 2019 17:36:50 -0500 Subject: [PATCH 156/196] modules readme, theme version --- docs/.vuepress/config.js | 4 ++++ docs/modules/readme.md | 4 +++- 2 files changed, 7 insertions(+), 1 deletion(-) diff --git a/docs/.vuepress/config.js b/docs/.vuepress/config.js index 837dbe9e638d..4de4b6ee43bc 100644 --- a/docs/.vuepress/config.js +++ b/docs/.vuepress/config.js @@ -22,6 +22,10 @@ module.exports = { title: "Modules", directory: true, path: "/modules/" + }, + { + title: "Modules README", + path: "/modules/" } ] }, diff --git a/docs/modules/readme.md b/docs/modules/readme.md index 227820933900..d4995244ce21 100644 --- a/docs/modules/readme.md +++ b/docs/modules/readme.md @@ -2,4 +2,6 @@ order: false parent: order: false ---- \ No newline at end of file +--- + +# Modules README \ No newline at end of file From 14623ca3196a00dfed227bfb8c98fb790c043c29 Mon Sep 17 00:00:00 2001 From: Denis Fadeev Date: Wed, 13 Nov 2019 17:39:02 -0500 Subject: [PATCH 157/196] theme version --- docs/package-lock.json | 30 +++++++++++++++--------------- docs/package.json | 2 +- 2 files changed, 16 insertions(+), 16 deletions(-) diff --git a/docs/package-lock.json b/docs/package-lock.json index 70325356b49a..ef837fd7204e 100644 --- a/docs/package-lock.json +++ b/docs/package-lock.json @@ -2180,9 +2180,9 @@ } }, "caniuse-lite": { - "version": "1.0.30001008", - "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001008.tgz", - "integrity": "sha512-b8DJyb+VVXZGRgJUa30cbk8gKHZ3LOZTBLaUEEVr2P4xpmFigOCc62CO4uzquW641Ouq1Rm9N+rWLWdSYDaDIw==" + "version": "1.0.30001009", + "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001009.tgz", + "integrity": "sha512-M3rEqHN6SaVjgo4bIik7HsGcWXsi+lI9WA0p51RPMFx5gXfduyOXWJrc0R4xBkSK1pgNf4CNgy5M+6H+WiEP8g==" }, "caseless": { "version": "0.12.0", @@ -2892,9 +2892,9 @@ "integrity": "sha1-6zkTMzRYd1y4TNGh+uBiEGu4dUU=" }, "deep-equal": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/deep-equal/-/deep-equal-1.1.0.tgz", - "integrity": "sha512-ZbfWJq/wN1Z273o7mUSjILYqehAktR2NVoSrOukDkU9kg2v/Uv89yU4Cvz8seJeAmtN5oqiefKq8FPuXOboqLw==", + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/deep-equal/-/deep-equal-1.1.1.tgz", + "integrity": "sha512-yd9c5AdiqVcR+JjcwUQb9DkhJc8ngNr0MahEBGvDiJw8puWab2yZlh+nkasOnZP+EGTAP6rRp2JzJhJZzvNF8g==", "requires": { "is-arguments": "^1.0.4", "is-date-object": "^1.0.1", @@ -3020,9 +3020,9 @@ "integrity": "sha1-m81S4UwJd2PnSbJ0xDRu0uVgtak=" }, "des.js": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/des.js/-/des.js-1.0.0.tgz", - "integrity": "sha1-wHTS4qpqipoH29YfmhXCzYPsjsw=", + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/des.js/-/des.js-1.0.1.tgz", + "integrity": "sha512-Q0I4pfFrv2VPd34/vfLrFOoRmlYj3OV50i7fskps1jZWK1kApMWWT9G6RRUeYedLcBDIhnSDaUvJMb3AhUlaEA==", "requires": { "inherits": "^2.0.1", "minimalistic-assert": "^1.0.0" @@ -5817,9 +5817,9 @@ } }, "node-releases": { - "version": "1.1.39", - "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-1.1.39.tgz", - "integrity": "sha512-8MRC/ErwNCHOlAFycy9OPca46fQYUjbJRDcZTHVWIGXIjYLM73k70vv3WkYutVnM4cCo4hE0MqBVVZjP6vjISA==", + "version": "1.1.40", + "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-1.1.40.tgz", + "integrity": "sha512-r4LPcC5b/bS8BdtWH1fbeK88ib/wg9aqmg6/s3ngNLn2Ewkn/8J6Iw3P9RTlfIAdSdvYvQl2thCY5Y+qTAQ2iQ==", "requires": { "semver": "^6.3.0" }, @@ -9011,9 +9011,9 @@ } }, "vuepress-theme-cosmos": { - "version": "1.0.55", - "resolved": "https://registry.npmjs.org/vuepress-theme-cosmos/-/vuepress-theme-cosmos-1.0.55.tgz", - "integrity": "sha512-Mag5YqSJ9/HUGxdty2Z95i7Nd+klrCvwyN5KD3uy4wRC3eTxj+7u/wyKkZNq/OYSoUAuwGlBzL9GFutmyZCbMA==", + "version": "1.0.58", + "resolved": "https://registry.npmjs.org/vuepress-theme-cosmos/-/vuepress-theme-cosmos-1.0.58.tgz", + "integrity": "sha512-XPfMTBrTSYD3ti/n2pse0BHL80sMQ2eIasIiwFC+gh5dDGHXrdY9lxNz1HRwrVUdpqg79NWLFRfBFFWdnxtJyQ==", "requires": { "@cosmos-ui/vue": "^0.5.16", "@vuepress/plugin-last-updated": "^1.2.0", diff --git a/docs/package.json b/docs/package.json index a73ddc349765..67bf9607595d 100644 --- a/docs/package.json +++ b/docs/package.json @@ -14,6 +14,6 @@ "author": "", "license": "ISC", "dependencies": { - "vuepress-theme-cosmos": "^1.0.55" + "vuepress-theme-cosmos": "^1.0.58" } } From 604e4146215e512bc66010530c9f18e25d50566c Mon Sep 17 00:00:00 2001 From: Denis Fadeev Date: Wed, 13 Nov 2019 17:45:18 -0500 Subject: [PATCH 158/196] fix modules list --- docs/.vuepress/config.js | 2 +- docs/pre.sh | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/docs/.vuepress/config.js b/docs/.vuepress/config.js index 4de4b6ee43bc..147dfce58969 100644 --- a/docs/.vuepress/config.js +++ b/docs/.vuepress/config.js @@ -21,7 +21,7 @@ module.exports = { { title: "Modules", directory: true, - path: "/modules/" + path: "/modules" }, { title: "Modules README", diff --git a/docs/pre.sh b/docs/pre.sh index 7a09e0bc1bb0..c31142c184b3 100755 --- a/docs/pre.sh +++ b/docs/pre.sh @@ -5,6 +5,6 @@ mkdir -p modules for D in ../x/*; do if [ -d "${D}" ]; then rm -rf "modules/$(echo $D | awk -F/ '{print $NF}')" - mkdir -p "modules/$(echo $D | awk -F/ '{print $NF}')" && cp -r $D/spec/ "$_/" + mkdir -p "modules/$(echo $D | awk -F/ '{print $NF}')" && cp -r $D/spec/* "$_" fi done \ No newline at end of file From 9505e33db1da8d53c4ea6b1e8e3ef4e017bbd612 Mon Sep 17 00:00:00 2001 From: Denis Fadeev Date: Thu, 14 Nov 2019 11:28:47 -0500 Subject: [PATCH 159/196] theme version --- docs/package-lock.json | 12 ++++++------ docs/package.json | 2 +- 2 files changed, 7 insertions(+), 7 deletions(-) diff --git a/docs/package-lock.json b/docs/package-lock.json index ef837fd7204e..9ebc3e17e441 100644 --- a/docs/package-lock.json +++ b/docs/package-lock.json @@ -2180,9 +2180,9 @@ } }, "caniuse-lite": { - "version": "1.0.30001009", - "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001009.tgz", - "integrity": "sha512-M3rEqHN6SaVjgo4bIik7HsGcWXsi+lI9WA0p51RPMFx5gXfduyOXWJrc0R4xBkSK1pgNf4CNgy5M+6H+WiEP8g==" + "version": "1.0.30001010", + "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001010.tgz", + "integrity": "sha512-RA5GH9YjFNea4ZQszdWgh2SC+dpLiRAg4VDQS2b5JRI45OxmbGrYocYHTa9x0bKMQUE7uvHkNPNffUr+pCxSGw==" }, "caseless": { "version": "0.12.0", @@ -9011,9 +9011,9 @@ } }, "vuepress-theme-cosmos": { - "version": "1.0.58", - "resolved": "https://registry.npmjs.org/vuepress-theme-cosmos/-/vuepress-theme-cosmos-1.0.58.tgz", - "integrity": "sha512-XPfMTBrTSYD3ti/n2pse0BHL80sMQ2eIasIiwFC+gh5dDGHXrdY9lxNz1HRwrVUdpqg79NWLFRfBFFWdnxtJyQ==", + "version": "1.0.59", + "resolved": "https://registry.npmjs.org/vuepress-theme-cosmos/-/vuepress-theme-cosmos-1.0.59.tgz", + "integrity": "sha512-S190S5ogEoW+NMNF20hzNnT7GHOLGl86ZOHBusmudsILQMDJI5YsyAA+odtOrNPGaANOf/I9G5fhhAh7yKiBNQ==", "requires": { "@cosmos-ui/vue": "^0.5.16", "@vuepress/plugin-last-updated": "^1.2.0", diff --git a/docs/package.json b/docs/package.json index 67bf9607595d..54a6116be32c 100644 --- a/docs/package.json +++ b/docs/package.json @@ -14,6 +14,6 @@ "author": "", "license": "ISC", "dependencies": { - "vuepress-theme-cosmos": "^1.0.58" + "vuepress-theme-cosmos": "^1.0.59" } } From 50d853882ed47e5b5dca47ea0b92da248b2d10cc Mon Sep 17 00:00:00 2001 From: gamarin Date: Fri, 15 Nov 2019 15:37:26 +0100 Subject: [PATCH 160/196] new snippets --- docs/basics/accounts.md | 116 ++------ docs/basics/app-anatomy.md | 28 +- docs/basics/gas-fees.md | 22 +- docs/building-modules/beginblock-endblock.md | 8 +- docs/building-modules/genesis.md | 20 +- docs/building-modules/handler.md | 22 +- docs/building-modules/invariants.md | 26 +- docs/building-modules/keeper.md | 12 +- docs/building-modules/messages-and-queries.md | 16 +- docs/building-modules/module-interfaces.md | 143 ++------- docs/building-modules/module-manager.md | 62 +--- docs/building-modules/querier.md | 6 +- docs/core/baseapp.md | 42 ++- docs/core/context.md | 2 +- docs/core/encoding.md | 37 +-- docs/core/events.md | 21 +- docs/core/node.md | 10 +- docs/core/ocap.md | 12 +- docs/core/store.md | 278 +++--------------- docs/core/transactions.md | 40 ++- docs/interfaces/cli.md | 234 +++------------ docs/interfaces/interfaces-intro.md | 2 +- docs/interfaces/query-lifecycle.md | 42 +-- x/README.md | 2 +- 24 files changed, 316 insertions(+), 887 deletions(-) diff --git a/docs/basics/accounts.md b/docs/basics/accounts.md index 98e3344a9ab5..fb9eafe85ed4 100644 --- a/docs/basics/accounts.md +++ b/docs/basics/accounts.md @@ -58,81 +58,27 @@ In the Cosmos SDK, accounts are stored and managed via an object called a [`Keyb ## Keybase -A `Keybase` is an object that stores and manages accounts. In the Cosmos SDK, a `Keybase` implementation follows the [`Keybase` interface](https://github.com/cosmos/cosmos-sdk/blob/master/crypto/keys/types.go#L14-L60): +A `Keybase` is an object that stores and manages accounts. In the Cosmos SDK, a `Keybase` implementation follows the `Keybase` interface: -```go -type Keybase interface { - // CRUD on the keystore - List() ([]Info, error) - Get(name string) (Info, error) - GetByAddress(address types.AccAddress) (Info, error) - Delete(name, passphrase string, skipPass bool) error - - // Sign some bytes, looking up the private key to use - Sign(name, passphrase string, msg []byte) ([]byte, crypto.PubKey, error) - - // CreateMnemonic creates a new mnemonic, and derives a hierarchical deterministic - // key from that. - CreateMnemonic(name string, language Language, passwd string, algo SigningAlgo) (info Info, seed string, err error) - - // CreateAccount creates an account based using the BIP44 path (44'/118'/{account}'/0/{index} - CreateAccount(name, mnemonic, bip39Passwd, encryptPasswd string, account uint32, index uint32) (Info, error) - - // Derive computes a BIP39 seed from th mnemonic and bip39Passwd. - // Derive private key from the seed using the BIP44 params. - // Encrypt the key to disk using encryptPasswd. - // See https://github.com/cosmos/cosmos-sdk/issues/2095 - Derive(name, mnemonic, bip39Passwd, encryptPasswd string, params hd.BIP44Params) (Info, error) - - // CreateLedger creates, stores, and returns a new Ledger key reference - CreateLedger(name string, algo SigningAlgo, hrp string, account, index uint32) (info Info, err error) - - // CreateOffline creates, stores, and returns a new offline key reference - CreateOffline(name string, pubkey crypto.PubKey) (info Info, err error) - - // CreateMulti creates, stores, and returns a new multsig (offline) key reference - CreateMulti(name string, pubkey crypto.PubKey) (info Info, err error) - - // The following operations will *only* work on locally-stored keys - Update(name, oldpass string, getNewpass func() (string, error)) error - Import(name string, armor string) (err error) - ImportPrivKey(name, armor, passphrase string) error - ImportPubKey(name string, armor string) (err error) - Export(name string) (armor string, err error) - ExportPubKey(name string) (armor string, err error) - ExportPrivKey(name, decryptPassphrase, encryptPassphrase string) (armor string, err error) - - // ExportPrivateKeyObject *only* works on locally-stored keys. Temporary method until we redo the exporting API - ExportPrivateKeyObject(name string, passphrase string) (crypto.PrivKey, error) - - // CloseDB closes the database. - CloseDB() -} -``` ++++ https://github.com/cosmos/cosmos-sdk/blob/master/crypto/keys/types.go#L14-L60 -The default implementation of `Keybase` of the Cosmos SDK is [`dbKeybase`](https://github.com/cosmos/cosmos-sdk/blob/master/crypto/keys/keybase.go). A few notes on the `Keybase` methods as implemented in `dbKeybase`: - -- `Sign(name, passphrase string, msg []byte) ([]byte, crypto.PubKey, error)` strictly deals with the signature of the `message` bytes. Some preliminary work should be done beforehand to prepare and encode the `message` into a canonical `[]byte` form. See an example of `message` preparation from the `auth` module](https://github.com/cosmos/cosmos-sdk/blob/master/x/auth/types/txbuilder.go#L177-L207). Note that signature verification is not implemented in the SDK by default. It is deferred to the [`anteHandler`](#antehandler). -- `CreateMnemonic(name string, language Language, passwd string, algo SigningAlgo) (info Info, seed string, err error)` creates a new mnemonic and prints it in the logs, but it **does not persist it on disk**. -- `CreateAccount(name, mnemonic, bip39Passwd, encryptPasswd string, account uint32, index uint32) (Info, error)` creates a new account based on the [`bip44 path`](https://github.com/bitcoin/bips/blob/master/bip-0044.mediawiki) and persists it on disk (note that the `PrivKey` is [encrypted with a passphrase before being persisted](https://github.com/cosmos/cosmos-sdk/blob/master/crypto/keys/mintkey/mintkey.go), it is **never stored unencrypted**). In the context of this method, the `account` and `address` parameters refer to the segment of the BIP44 derivation path (e.g. `0`, `1`, `2`, ...) used to derive the `PrivKey` and `PubKey` from the mnemonic (note that given the same mnemonic and `account`, the same `PrivKey` will be generated, and given the same `account` and `address`, the same `PubKey` and `Address` will be generated). Finally, note that the `CreateAccount` method derives keys and addresses using `secp256k1` as implemented in the [Tendermint library](https://github.com/tendermint/tendermint/tree/bc572217c07b90ad9cee851f193aaa8e9557cbc7/crypto/secp256k1). As a result, it only works for creating account keys and addresses, not consensus keys. See [`Addresses`](#addresses) for more. +The default implementation of `Keybase` of the Cosmos SDK is `dbKeybase`. -The current implementation of `dbKeybase` is basic and does not offer on-demand locking. If an instance of `dbKeybase` is created, the underlying `db` is locked meaning no other process can access it besides the one in which it was instantiated. This is the reason why the [default SDK client](https://github.com/cosmos/cosmos-sdk/tree/master/client/keys) uses another implementation of the `Keybase` interface called [`lazyKeybase`](https://github.com/cosmos/cosmos-sdk/blob/master/crypto/keys/lazy_keybase.go). `lazyKeybase` is simple wrapper around `dbKeybase` which locks the database only when operations are to be performed and unlocks it immediately after: ++++ https://github.com/cosmos/cosmos-sdk/blob/master/crypto/keys/keybase.go -```go -// Example Get method of lazyKeybase +A few notes on the `Keybase` methods as implemented in `dbKeybase`: -func (lkb lazyKeybase) Get(name string) (Info, error) { - db, err := sdk.NewLevelDB(lkb.name, lkb.dir) - if err != nil { - return nil, err - } - defer db.Close() +- `Sign(name, passphrase string, msg []byte) ([]byte, crypto.PubKey, error)` strictly deals with the signature of the `message` bytes. Some preliminary work should be done beforehand to prepare and encode the `message` into a canonical `[]byte` form. See an example of `message` preparation from the `auth` module. Note that signature verification is not implemented in the SDK by default. It is deferred to the [`anteHandler`](#antehandler). + +++ https://github.com/cosmos/cosmos-sdk/blob/master/x/auth/types/txbuilder.go#L177-L207 +- `CreateMnemonic(name string, language Language, passwd string, algo SigningAlgo) (info Info, seed string, err error)` creates a new mnemonic and prints it in the logs, but it **does not persist it on disk**. +- `CreateAccount(name, mnemonic, bip39Passwd, encryptPasswd string, account uint32, index uint32) (Info, error)` creates a new account based on the [`bip44 path`](https://github.com/bitcoin/bips/blob/master/bip-0044.mediawiki) and persists it on disk (note that the `PrivKey` is [encrypted with a passphrase before being persisted](https://github.com/cosmos/cosmos-sdk/blob/master/crypto/keys/mintkey/mintkey.go), it is **never stored unencrypted**). In the context of this method, the `account` and `address` parameters refer to the segment of the BIP44 derivation path (e.g. `0`, `1`, `2`, ...) used to derive the `PrivKey` and `PubKey` from the mnemonic (note that given the same mnemonic and `account`, the same `PrivKey` will be generated, and given the same `account` and `address`, the same `PubKey` and `Address` will be generated). Finally, note that the `CreateAccount` method derives keys and addresses using `secp256k1` as implemented in the [Tendermint library](https://github.com/tendermint/tendermint/tree/bc572217c07b90ad9cee851f193aaa8e9557cbc7/crypto/secp256k1). As a result, it only works for creating account keys and addresses, not consensus keys. See [`Addresses`](#addresses) for more. - return newDbKeybase(db).Get(name) -} -``` +The current implementation of `dbKeybase` is basic and does not offer on-demand locking. If an instance of `dbKeybase` is created, the underlying `db` is locked meaning no other process can access it besides the one in which it was instantiated. This is the reason why the default SDK client uses another implementation of the `Keybase` interface called `lazyKeybase`: + + ++++ https://github.com/cosmos/cosmos-sdk/blob/master/crypto/keys/lazy_keybase.go -With the `lazyKeybase`, it is possible for the [command-line interface](../interfaces/cli.md) to create a new account while the [rest server](../interfaces/rest.md) is running. It is also possible to pipe multiple CLI commands. +`lazyKeybase` is simple wrapper around `dbKeybase` which locks the database only when operations are to be performed and unlocks it immediately after. With the `lazyKeybase`, it is possible for the [command-line interface](../interfaces/cli.md) to create a new account while the [rest server](../interfaces/rest.md) is running. It is also possible to pipe multiple CLI commands. ## Addresses and PubKeys @@ -150,21 +96,15 @@ With the `lazyKeybase`, it is possible for the [command-line interface](../inter ### PubKeys -`PubKey`s used in the Cosmos SDK follow the [`Pubkey` interface defined in [tendermint's `crypto` package](https://github.com/tendermint/tendermint/blob/bc572217c07b90ad9cee851f193aaa8e9557cbc7/crypto/crypto.go#L22-L27): - +`PubKey`s used in the Cosmos SDK follow the `Pubkey` interface defined in tendermint's `crypto` package: -```go -type PubKey interface { - Address() Address - Bytes() []byte - VerifyBytes(msg []byte, sig []byte) bool - Equals(PubKey) bool -} -``` ++++ https://github.com/tendermint/tendermint/blob/bc572217c07b90ad9cee851f193aaa8e9557cbc7/crypto/crypto.go#L22-L27 For `secp256k1` keys, the actual implementation can be found [here](https://github.com/tendermint/tendermint/blob/bc572217c07b90ad9cee851f193aaa8e9557cbc7/crypto/secp256k1/secp256k1.go#L140). For `ed25519` keys, it can be found [here](https://github.com/tendermint/tendermint/blob/bc572217c07b90ad9cee851f193aaa8e9557cbc7/crypto/ed25519/ed25519.go#L135). -Note that in the Cosmos SDK, `Pubkeys` are not manipulated in their raw form. Instead, they are double encoded using [`Amino`](../core/encoding.md#amino) and [`bech32`](https://en.bitcoin.it/wiki/Bech32). In the SDK is done by first calling the `Bytes()` method on the raw `Pubkey` (which applies amino encoding), and then the `ConvertAndEncode` method of `bech32`. You can check out the implementation [here](https://github.com/cosmos/cosmos-sdk/blob/master/types/address.go#L579-L729). +Note that in the Cosmos SDK, `Pubkeys` are not manipulated in their raw form. Instead, they are double encoded using [`Amino`](../core/encoding.md#amino) and [`bech32`](https://en.bitcoin.it/wiki/Bech32). In the SDK is done by first calling the `Bytes()` method on the raw `Pubkey` (which applies amino encoding), and then the `ConvertAndEncode` method of `bech32`. + ++++ https://github.com/cosmos/cosmos-sdk/blob/master/types/address.go#L579-L729 ### Addresses @@ -180,21 +120,13 @@ Each of these address types are an alias for an hex-encoded `[]byte` array of le aa := sdk.AccAddress(pub.Address().Bytes()) ``` -These addresses implement the [`Address` interface](https://github.com/cosmos/cosmos-sdk/blob/master/types/address.go#L72-L80): +These addresses implement the `Address` interface: -```go -type Address interface { - Equals(Address) bool - Empty() bool - Marshal() ([]byte, error) - MarshalJSON() ([]byte, error) - Bytes() []byte - String() string - Format(s fmt.State, verb rune) -} -``` ++++ https://github.com/cosmos/cosmos-sdk/blob/master/types/address.go#L72-L80 + +Of note, the `Marhsal()` and `Bytes()` method both return the same raw `[]byte` form of the address, the former being needed for Protobuff compatibility. Also, the `String()` method is used to return the `bech32` encoded form of the address, which should be the only address format with which end-user interract. Next is an example: -Of note, the `Marhsal()` and `Bytes()` method both return the same raw `[]byte` form of the address, the former being needed for Protobuff compatibility. Also, the `String()` method is used to return the `bech32` encoded form of the address, which should be the only address format with which end-user interract. See an example [here](https://github.com/cosmos/cosmos-sdk/blob/master/types/address.go#L230-L243). ++++ https://github.com/cosmos/cosmos-sdk/blob/master/types/address.go#L230-L243 ## Next diff --git a/docs/basics/app-anatomy.md b/docs/basics/app-anatomy.md index f85b851c128e..30329dca4821 100644 --- a/docs/basics/app-anatomy.md +++ b/docs/basics/app-anatomy.md @@ -172,6 +172,20 @@ Handler functions return a result of type `sdk.Result`, which informs the applic To learn more about handlers, [click here](../building-modules/handler.md). +### Querier + +[`Queriers`](../building-modules/querier.md) are very similar to `handlers`, except they serve user queries to the state as opposed to processing transactions. A [query](../building-modules/messages-and-queries.md#queries) is initiated from an [interface](#interfaces) by an end-user who provides a `queryRoute` and some `data`. The query is then routed to the correct application's `querier` by `baseapp`'s `handleQueryCustom` method using `queryRoute`: + ++++ https://github.com/cosmos/cosmos-sdk/blob/master/baseapp/baseapp.go#L519-L556 + +The `Querier` of a module is defined in a file called `querier.go`, and consists of: + +- A **switch function** `NewQuerier` to route the query to the appropriate `querier` function. This function returns a `querier` function, and is is registered in the [`AppModule`](#application-module-interface) to be used in the application's module manager to initialize the [application's query router](../core/baseapp.md#query-routing). See an example of such a switch from the [nameservice tutorial](https://github.com/cosmos/sdk-tutorials/tree/master/nameservice): + +++ https://github.com/cosmos/sdk-tutorials/blob/86a27321cf89cc637581762e953d0c07f8c78ece/nameservice/x/nameservice/internal/keeper/querier.go#L19-L32 +- - **One querier function for each data type defined by the module that needs to be queryable**. Developers write the query processing logic in these functions. This generally involves calling [`keeper`](#keeper)'s methods to query the state and marshalling it to JSON. + +To learn more about `queriers`, [click here](../building-modules/querier.md). + ### Keeper [`Keepers`](../building-modules/keeper.md) are the gatekeepers of their module's store(s). To read or write in a module's store, it is mandatory to go through one of its `keeper`'s methods. This is ensured by the [object-capabilities](../core/ocap.md) model of the Cosmos SDK. Only objects that hold the key to a store can access it, and only the module's `keeper` should hold the key(s) to the module's store(s). @@ -188,20 +202,6 @@ Along with the type definition, the next important component of the `keeper.go` To learn more about `keepers`, [click here](../building-modules/keeper.md). -### Querier - -[`Queriers`](../building-modules/querier.md) are very similar to `handlers`, except they serve user queries to the state as opposed to processing transactions. A [query](../building-modules/messages-and-queries.md#queries) is initiated from an [interface](#interfaces) by an end-user who provides a `queryRoute` and some `data`. The query is then routed to the correct application's `querier` by `baseapp`'s `handleQueryCustom` method using `queryRoute`: - -+++ https://github.com/cosmos/cosmos-sdk/blob/master/baseapp/baseapp.go#L519-L556 - -The `Querier` of a module is defined in a file called `querier.go`, and consists of: - -- A **switch function** `NewQuerier` to route the query to the appropriate `querier` function. This function returns a `querier` function, and is is registered in the [`AppModule`](#application-module-interface) to be used in the application's module manager to initialize the [application's query router](../core/baseapp.md#query-routing). See an example of such a switch from the [nameservice tutorial](https://github.com/cosmos/sdk-tutorials/tree/master/nameservice): - +++ https://github.com/cosmos/sdk-tutorials/blob/86a27321cf89cc637581762e953d0c07f8c78ece/nameservice/x/nameservice/internal/keeper/querier.go#L19-L32 -- - **One querier function for each data type defined by the module that needs to be queryable**. Developers write the query processing logic in these functions. This generally involves calling [`keeper`](#keeper)'s methods to query the state and marshalling it to JSON. - -To learn more about `queriers`, [click here](../building-modules/querier.md). - ### Command-Line and REST Interfaces Each module defines command-line commands and REST routes to be exposed to end-user via the [application's interfaces](#application-interfaces). This enables end-users to create messages of the types defined in the module, or to query the subset of the state managed by the module. diff --git a/docs/basics/gas-fees.md b/docs/basics/gas-fees.md index 49e19521479e..0e7d99aff8f8 100644 --- a/docs/basics/gas-fees.md +++ b/docs/basics/gas-fees.md @@ -17,18 +17,9 @@ In the Cosmos SDK, `gas` is a special unit that is used to track the consumption ## Gas Meter -In the Cosmos SDK, `gas` is a simple alias for `uint64`, and is managed by an object called a *gas meter*. Gas meters implement the [`GasMeter` interface](https://github.com/cosmos/cosmos-sdk/blob/master/store/types/gas.go#L32-L44): +In the Cosmos SDK, `gas` is a simple alias for `uint64`, and is managed by an object called a *gas meter*. Gas meters implement the `GasMeter` interface -```go -type GasMeter interface { - GasConsumed() Gas - GasConsumedToLimit() Gas - Limit() Gas - ConsumeGas(amount Gas, descriptor string) - IsPastLimit() bool - IsOutOfGas() bool -} -``` ++++ https://github.com/cosmos/cosmos-sdk/blob/master/store/types/gas.go#L32-L44 where: @@ -55,7 +46,9 @@ Gas comsumption can be done manually, generally by the module developer in the [ ### Block Gas Meter -`ctx.BlockGasMeter()` is the gas meter used to track gas consumption per block and make sure it does not go above a certain limit. A new instance of the `BlockGasMeter` is created each time [`BeginBlock`](../core/baseapp.md#beginblock) is called. The `BlockGasMeter` is finite, and the limit of gas per block is defined in the application's consensus parameters (by default Cosmos SDK applications use the [default consensus parameters provided by Tendermint](https://github.com/tendermint/tendermint/blob/f323c80cb3b78e123ea6238c8e136a30ff749ccc/types/params.go#L65-L72)). +`ctx.BlockGasMeter()` is the gas meter used to track gas consumption per block and make sure it does not go above a certain limit. A new instance of the `BlockGasMeter` is created each time [`BeginBlock`](../core/baseapp.md#beginblock) is called. The `BlockGasMeter` is finite, and the limit of gas per block is defined in the application's consensus parameters. By default Cosmos SDK applications use the default consensus parameters provided by Tendermint: + ++++ https://github.com/tendermint/tendermint/blob/f323c80cb3b78e123ea6238c8e136a30ff749ccc/types/params.go#L65-L72 When a new [transaction](../core/transactions.md) is being processed via `DeliverTx`, the current value of `BlockGasMeter` is checked to see if it is above the limit. If it is, `DeliverTx` returns immediately. This can happen even with the first transaction in a block, as `BeginBlock` itself can consume gas. If not, the transaction is processed normally. At the end of `DeliverTx`, the gas tracked by `ctx.BlockGasMeter()` is increased by the amount consumed to process the transaction: @@ -78,7 +71,10 @@ type AnteHandler func(ctx Context, tx Tx, simulate bool) (newCtx Context, result The `anteHandler` is not implemented in the core SDK but in a module. This gives the possibility to developers to choose which version of `AnteHandler` fits their application's needs. That said, most applications today use the default implementation defined in the [`auth` module](https://github.com/cosmos/cosmos-sdk/tree/master/x/auth). Here is what the `anteHandler` is intended to do in a normal Cosmos SDK application: -- Verify that the transaction are of the correct type. Transaction types are defined in the module that implements the `anteHandler`, and they follow the [transaction interface](https://github.com/cosmos/cosmos-sdk/blob/master/types/tx_msg.go#L34-L41). This enables developers to play with various types for the transaction of their application. In the default `auth` module, the standard transaction type is [`StdTx`](https://github.com/cosmos/cosmos-sdk/blob/master/x/auth/types/stdtx.go#L23-L28). +- Verify that the transaction are of the correct type. Transaction types are defined in the module that implements the `anteHandler`, and they follow the transaction interface: + +++ https://github.com/cosmos/cosmos-sdk/blob/master/types/tx_msg.go#L34-L41 +This enables developers to play with various types for the transaction of their application. In the default `auth` module, the standard transaction type is `StdTx`: + +++ https://github.com/cosmos/cosmos-sdk/blob/master/x/auth/types/stdtx.go#L23-L28 - Verify signatures for each [`message`](../building-modules/messages-and-queries.md#messages) contained in the transaction. Each `message` should be signed by one or multiple sender(s), and these signatures must be verified in the `anteHandler`. - During `CheckTx`, verify that the gas prices provided with the transaction is greater than the local `min-gas-prices` (as a reminder, gas-prices can be deducted from the following equation: `fees = gas * gas-prices`). `min-gas-prices` is a parameter local to each full-node and used during `CheckTx` to discard transactions that do not provide a minimum amount of fees. This ensure that the mempool cannot be spammed with garbage transactions. - Verify that the sender of the transaction has enough funds to cover for the `fees`. When the end-user generates a transaction, they must indicate 2 of the 3 following parameters (the third one being implicit): `fees`, `gas` and `gas-prices`. This signals how much they are willing to pay for nodes to execute their transaction. The provided `gas` value is stored in a parameter called `GasWanted` for later use. diff --git a/docs/building-modules/beginblock-endblock.md b/docs/building-modules/beginblock-endblock.md index 4de61d9960d7..d8959dba9490 100644 --- a/docs/building-modules/beginblock-endblock.md +++ b/docs/building-modules/beginblock-endblock.md @@ -28,7 +28,13 @@ A specificity of the `EndBlocker` is that it can return validator updates to the It is possible for developers to defined the order of execution between the `BeginBlocker`/`EndBlocker` functions of each of their application's modules via the module's manager `SetOrderBeginBlocker`/`SetOrderEndBlocker` methods. For more on the module manager, click [here](./module-manager.md#manager). -For more, see an [example implementation of `BeginBlocker` from the `distr` module](https://github.com/cosmos/cosmos-sdk/blob/master/x/distribution/abci.go) and an [example implementation of `EndBlocker`]( https://github.com/cosmos/cosmos-sdk/blob/master/x/staking/handler.go#L44) +See an example implementation of `BeginBlocker` from the `distr` module: + ++++ https://github.com/cosmos/cosmos-sdk/blob/master/x/distribution/abci.go#L10-L32 + +and an example implementation of `EndBlocker` from the `staking` module: + ++++ https://github.com/cosmos/cosmos-sdk/blob/master/x/staking/handler.go#L44-L96 ## Next diff --git a/docs/building-modules/genesis.md b/docs/building-modules/genesis.md index ea83beaf183e..a16037680740 100644 --- a/docs/building-modules/genesis.md +++ b/docs/building-modules/genesis.md @@ -17,17 +17,23 @@ Modules generally handle a subset of the state and, as such, they need to define The subset of the genesis state defined from a given module is generally defined in a `./internal/types/genesis.go` file, along with the `DefaultGenesis` and `ValidateGenesis` methods. The struct defining the module's subset of the genesis state is usually called `GenesisState` and contains all the module-related values that need to be initialized during the genesis process. -See an example of `GenesisState` type definition from the [nameservice tutorial](https://github.com/cosmos/sdk-application-tutorial/blob/master/x/nameservice/genesis.go#L10-L12). +See an example of `GenesisState` type definition from the nameservice tutorial + ++++ https://github.com/cosmos/sdk-tutorials/blob/86a27321cf89cc637581762e953d0c07f8c78ece/nameservice/x/nameservice/genesis.go#L10-L12 Next we present the main genesis-related methods that need to be implemented by module developers in order for their module to be used in Cosmos SDK applications. ### `DefaultGenesis` -The `DefaultGenesis()` method is a simple method that calls the constructor function for `GenesisState` with the default value for each parameter. See an example [here](https://github.com/cosmos/sdk-application-tutorial/blob/master/x/nameservice/genesis.go#L14-L16). +The `DefaultGenesis()` method is a simple method that calls the constructor function for `GenesisState` with the default value for each parameter. See an example from the `nameservice` module: + ++++ https://github.com/cosmos/sdk-tutorials/blob/86a27321cf89cc637581762e953d0c07f8c78ece/nameservice/x/nameservice/genesis.go#L33-L37 ### `ValidateGenesis` -The `ValidateGenesis(genesisState GenesisState)` method is called to verify that the provided `genesisState` is correct. It should perform validity checks on each of the parameter listed in `GenesisState`. See an example [here](https://github.com/cosmos/sdk-application-tutorial/blob/master/x/nameservice/genesis.go#L18-L31). +The `ValidateGenesis(genesisState GenesisState)` method is called to verify that the provided `genesisState` is correct. It should perform validity checks on each of the parameter listed in `GenesisState`. See an example from the `nameservice` module: + ++++ https://github.com/cosmos/sdk-tutorials/blob/86a27321cf89cc637581762e953d0c07f8c78ece/nameservice/x/nameservice/genesis.go#L18-L31 ## Other Genesis Methods @@ -39,13 +45,17 @@ The `InitGenesis` method is executed during [`InitChain`](../core/baseapp.md#ini The [module manager](./module-manager.md#manager) of the application is responsible for calling the `InitGenesis` method of each of the application's modules, in order. This order is set by the application developer via the manager's `SetOrderGenesisMethod`, which is called in the [application's constructor function](../basics/app-anatomy.md#constructor-function) -See an [example of `InitGenesis` from the nameservice tutorial](https://github.com/cosmos/sdk-application-tutorial/blob/master/x/nameservice/genesis.go#L39-L44). +See an example of `InitGenesis` from the nameservice tutorial + ++++ https://github.com/cosmos/sdk-tutorials/blob/86a27321cf89cc637581762e953d0c07f8c78ece/nameservice/x/nameservice/genesis.go#L39-L44 ### `ExportGenesis` The `ExportGenesis` method is executed whenever an export of the state is made. It takes the latest known version of the subset of the state managed by the module and creates a new `GenesisState` out of it. This is mainly used when the chain needs to be upgraded via a hard fork. -See an [example of `ExportGenesis` from the nameservice tutorial](https://github.com/cosmos/sdk-application-tutorial/blob/master/x/nameservice/genesis.go#L46-L57). +See an example of `ExportGenesis` from the nameservice tutorial. + ++++ https://github.com/cosmos/sdk-tutorials/blob/86a27321cf89cc637581762e953d0c07f8c78ece/nameservice/x/nameservice/genesis.go#L46-L57 ## Next diff --git a/docs/building-modules/handler.md b/docs/building-modules/handler.md index c1bdf602c6d7..5d573f598fdd 100644 --- a/docs/building-modules/handler.md +++ b/docs/building-modules/handler.md @@ -15,17 +15,16 @@ A `Handler` designates a function that processes [`message`s](./messages-and-que ## `handler` type -The [`handler` type](https://github.com/cosmos/cosmos-sdk/blob/master/types/handler.go#L4) defined in the Cosmos SDK specifies the typical structure of a `handler` function: +The `handler` type defined in the Cosmos SDK specifies the typical structure of a `handler` function. -```go -type Handler func(ctx Context, msg Msg) Result -``` ++++ https://github.com/cosmos/cosmos-sdk/blob/master/types/handler.go#L4 Let us break it down: - The [`Msg`](./messages-and-queries.md#messages) is the actual object being processed. - The [`Context`](../core/context.md) contains all the necessary information needed to process the `msg`, as well as a cache-wrapped copy of the latest state. If the `msg` is succesfully processed, the modified version of the temporary state contained in the `ctx` will be written to the main state. -- The [`Result`](https://github.com/cosmos/cosmos-sdk/blob/master/types/result.go#L14-L38) returned to `baseapp`, which contains (among other things) information on the execution of the `handler`, [`gas`](../basics/gas-fees.md) consumption and [`events`](../core/events.md). +- The [`Result`] returned to `baseapp`, which contains (among other things) information on the execution of the `handler`, [`gas`](../basics/gas-fees.md) consumption and [`events`](../core/events.md). + +++ https://github.com/cosmos/cosmos-sdk/blob/master/types/result.go#L14-L38 ## Implementation of a module `handler`s @@ -65,16 +64,13 @@ ctx.EventManager().EmitEvent( These `events` are relayed back to the underlying consensus engine and can be used by service providers to implement services around the application. Click [here](../core/events.md) to learn more about `events`. -Finally, the `handler` function returns a [`sdk.Result`](https://github.com/tendermint/tendermint/blob/master/abci/types/result.go) which contains the aforementioned `events` and an optional `Data` field. +Finally, the `handler` function returns a `sdk.Result` which contains the aforementioned `events` and an optional `Data` field. -```go -// Example handler result ++++ https://github.com/cosmos/cosmos-sdk/blob/master/types/result.go#L15-L40 -return sdk.Result{ - Data: GetProposalIDBytes(proposal.ProposalID), - Events: ctx.EventManager().Events(), - } -``` +Next is an example of how to return a `Result` from the `gov` module: + ++++ https://github.com/cosmos/cosmos-sdk/blob/master/x/gov/handler.go#L59-L62 For a deeper look at `handler`s, see this [example implementation of a `handler` function](https://github.com/cosmos/sdk-application-tutorial/blob/c6754a1e313eb1ed973c5c91dcc606f2fd288811/x/nameservice/handler.go) from the nameservice tutorial. diff --git a/docs/building-modules/invariants.md b/docs/building-modules/invariants.md index cc7888b8b9a2..f0152a07ff09 100644 --- a/docs/building-modules/invariants.md +++ b/docs/building-modules/invariants.md @@ -14,11 +14,9 @@ An invariant is a property of the application that should always be true. In the ## Implementing `Invariant`s -An `Invariant` is a function that checks for a particular invariant within a module. Module `Invariant`s must follow the [`Invariant`s type](https://github.com/cosmos/cosmos-sdk/blob/master/types/invariant.go#L9): +An `Invariant` is a function that checks for a particular invariant within a module. Module `Invariant`s must follow the `Invariant`s type: -```go -type Invariant func(ctx Context) (string, bool) -``` ++++ https://github.com/cosmos/cosmos-sdk/blob/master/types/invariant.go#L9 where the `string` return value is the invariant message, which can be used when printing logs, and the `bool` return value is the actual result of the invariant check. @@ -72,17 +70,21 @@ For more, see an example of [`Invariant`s implementation from the `staking` modu The `InvariantRegistry` is a registry where the `Invariant`s of all the modules of an application are registered. There is only one `InvariantRegistry` per **application**, meaning module developers need not implement their own `InvariantRegistry` when building a module. **All module developers need to do is to register their modules' invariants in the `InvariantRegistry`, as explained in the section above**. The rest of this section gives more information on the `InvariantRegistry` itself, and does not contain anything directly relevant to module developers. -At its core, the `InvariantRegistry` is defined in the SDK as an [interface](https://github.com/cosmos/cosmos-sdk/blob/master/types/invariant.go#L14-L17). +At its core, the `InvariantRegistry` is defined in the SDK as an interface: -```go -type InvariantRegistry interface { - RegisterRoute(moduleName, route string, invar Invariant) -} -``` ++++ https://github.com/cosmos/cosmos-sdk/blob/master/types/invariant.go#L14-L17 + +Typically, this interface is implemented in the `keeper` of a specific module. The most used implementation of an `InvariantRegistry` can be found in the `crisis` module: + ++++ https://github.com/cosmos/cosmos-sdk/blob/master/x/crisis/internal/keeper/keeper.go#L45-L49 + + The `InvariantRegistry` is therefore typically instantiated by instantiating the `keeper` of the `crisis` module in the [application's constructor function](../basics/app-anatomy.md#constructor-function). + +`Invariant`s can be checked manually via [`message`s](./messages-and-queries.md), but most often they are checked automatically at the end of each block. Here is an example from the `crisis` module: -Typically, this interface is implemented in the `keeper` of a specific module. The most used implementation of an `InvariantRegistry` can be found in the [`crisis` module](https://github.com/cosmos/cosmos-sdk/blob/master/x/crisis/internal/keeper/keeper.go). The `InvariantRegistry` is therefore typically instantiated by instantiating the `keeper` of the `crisis` module in the [application's constructor function](../basics/app-anatomy.md#constructor-function). ++++ https://github.com/cosmos/cosmos-sdk/blob/master/x/crisis/abci.go#L7-L14 -`Invariant`s can be checked manually via [`message`s](./messages-and-queries.md), but most often they are checked automatically at the end of each block (see an example [here](https://github.com/cosmos/cosmos-sdk/blob/master/x/crisis/abci.go)). In both cases, if one of the `Invariant`s returns false, the `InvariantRegistry` can trigger special logic (e.g. have the application panic and print the `Invariant`s message in the log). +In both cases, if one of the `Invariant`s returns false, the `InvariantRegistry` can trigger special logic (e.g. have the application panic and print the `Invariant`s message in the log). ## Next diff --git a/docs/building-modules/keeper.md b/docs/building-modules/keeper.md index 06dbd1303dbd..0928aac191d0 100644 --- a/docs/building-modules/keeper.md +++ b/docs/building-modules/keeper.md @@ -34,17 +34,9 @@ type Keeper struct { } ``` -For example, here is the [type definition of the `keeper` from the nameservice tutorial](https://github.com/cosmos/sdk-application-tutorial/blob/master/x/nameservice/internal/keeper/keeper.go#L10-L17): +For example, here is the [type definition of the `keeper` from the nameservice tutorial: -```go -type Keeper struct { - CoinKeeper types.CoinKeeper - - storeKey sdk.StoreKey // Unexposed key to access store from sdk.Context - - cdc *codec.Codec // The wire codec for binary encoding/decoding. -} -``` ++++ https://github.com/cosmos/sdk-tutorials/blob/86a27321cf89cc637581762e953d0c07f8c78ece/nameservice/x/nameservice/internal/keeper/keeper.go#L10-L17 Let us go through the different parameters: diff --git a/docs/building-modules/messages-and-queries.md b/docs/building-modules/messages-and-queries.md index d023a8d95ff4..87ae0899a555 100644 --- a/docs/building-modules/messages-and-queries.md +++ b/docs/building-modules/messages-and-queries.md @@ -31,7 +31,11 @@ type MsgSubmitProposal struct { } ``` -The `Msg` is typically accompanied by a standard constructor function, that is called from one of the [module's interface](./module-interfaces.md). `message`s also need to implement the [`Msg`](https://github.com/cosmos/cosmos-sdk/blob/master/types/tx_msg.go#L7-L29) interface, which contains the following methods: +The `Msg` is typically accompanied by a standard constructor function, that is called from one of the [module's interface](./module-interfaces.md). `message`s also need to implement the [`Msg`] interface: + ++++ https://github.com/cosmos/cosmos-sdk/blob/master/types/tx_msg.go#L7-L29 + +It contains the following methods: - `Route() string`: Name of the route for this message. Typically all `message`s in a module have the same route, which is most often the module's name. - `Type() string`: Type of the message, used primarly in [events](../core/events.md). This should return a message-specific `string`, typically the denomination of the message itself. @@ -39,7 +43,9 @@ The `Msg` is typically accompanied by a standard constructor function, that is c - `GetSignBytes() []byte`: Return the canonical byte representation of the message. Used to generate a signature. - `GetSigners() []AccAddress`: Return the list of signers. The SDK will make sure that each `message` contained in a transaction is signed by all the signers listed in the list returned by this method. -You can see an example implementation of a `message` from the *nameservice tutorial* [here](https://github.com/cosmos/cosmos-sdk/blob/master/types/tx_msg.go). +See an example implementation of a `message` from the `nameservice` module: + ++++ https://github.com/cosmos/sdk-tutorials/blob/86a27321cf89cc637581762e953d0c07f8c78ece/nameservice/x/nameservice/internal/types/msgs.go#L10-L51 ## Queries @@ -62,7 +68,11 @@ The `path` for each `query` must be defined by the module developer in the modul - A [`querier`](./querier.md), to process the `query` once it has been [routed to the module](../core/baseapp.md#query-routing). - [Query commands](./module-interfaces.md#query-commands) in the module's CLI file, where the `path` for each `query` is specified. -- `query` return types. Typically defined in a file `internal/types/querier.go`, they specify the result type of each of the module's `queries`. These custom types must implement the `String()` method of [`fmt.Stringer`](https://golang.org/pkg/fmt/#Stringer). See an example of `query` return types from the [nameservice tutorial](https://github.com/cosmos/sdk-application-tutorial/blob/c6754a1e313eb1ed973c5c91dcc606f2fd288811/x/nameservice/internal/types/querier.go). +- `query` return types. Typically defined in a file `internal/types/querier.go`, they specify the result type of each of the module's `queries`. These custom types must implement the `String()` method of [`fmt.Stringer`](https://golang.org/pkg/fmt/#Stringer). + +See an example of `query` return types from the `nameservice` module: + ++++ https://github.com/cosmos/sdk-tutorials/blob/c6754a1e313eb1ed973c5c91dcc606f2fd288811/x/nameservice/internal/types/querier.go#L5-L21 ## Next diff --git a/docs/building-modules/module-interfaces.md b/docs/building-modules/module-interfaces.md index ee3d870fafb2..b866a98f7d1e 100644 --- a/docs/building-modules/module-interfaces.md +++ b/docs/building-modules/module-interfaces.md @@ -18,41 +18,11 @@ One of the main interfaces for an application is the [command-line interface](.. ### Transaction Commands -[Transactions](../core/transactions.md) are created by users to wrap messages that trigger state changes when they get included in a valid block. Transaction commands typically have their own `tx.go` file in the module `./x/moduleName/client/cli` folder. The commands are specified in getter functions prefixed with `GetCmd` and include the name of the command. Here is an example from the [nameservice tutorial](https://github.com/cosmos/sdk-application-tutorial/blob/c6754a1e313eb1ed973c5c91dcc606f2fd288811/tutorial/cli.md#transactions): +[Transactions](../core/transactions.md) are created by users to wrap messages that trigger state changes when they get included in a valid block. Transaction commands typically have their own `tx.go` file in the module `./x/moduleName/client/cli` folder. The commands are specified in getter functions prefixed with `GetCmd` and include the name of the command. -```go -func GetCmdBuyName(cdc *codec.Codec) *cobra.Command { - return &cobra.Command{ - Use: "buy-name [name] [amount]", - Short: "bid for existing name or claim new name", - Args: cobra.ExactArgs(2), - RunE: func(cmd *cobra.Command, args []string) error { - cliCtx := context.NewCLIContext().WithCodec(cdc).WithAccountDecoder(cdc) - - txBldr := authtxb.NewTxBuilderFromCLI().WithTxEncoder(utils.GetTxEncoder(cdc)) - - if err := cliCtx.EnsureAccountExists(); err != nil { - return err - } - - coins, err := sdk.ParseCoins(args[1]) - if err != nil { - return err - } - - msg := nameservice.NewMsgBuyName(args[0], coins, cliCtx.GetFromAddress()) - err = msg.ValidateBasic() - if err != nil { - return err - } - - cliCtx.PrintResponse = true - - return utils.GenerateOrBroadcastMsgs(cliCtx, txBldr, []sdk.Msg{msg}, false) - }, - } -} -``` +Here is an example from the `nameservice` module: + ++++ https://github.com/cosmos/sdk-tutorials/blob/86a27321cf89cc637581762e953d0c07f8c78ece/nameservice/x/nameservice/client/cli/tx.go#L33-L58 This getter function creates the command for the Buy Name transaction. It does the following: @@ -69,53 +39,17 @@ This getter function creates the command for the Buy Name transaction. It does t + Depending on what the user wants, the transaction is either generated offline or signed and broadcasted to the preconfigured node using `GenerateOrBroadcastMsgs()`. - **Flags.** Add any [flags](#flags) to the command. No flags were specified here, but all transaction commands have flags to provide additional information from the user (e.g. amount of fees they are willing to pay). These *persistent* [transaction flags](../interfaces/cli.md#flags) can be added to a higher-level command so that they apply to all transaction commands. -Finally, the module needs to have a `GetTxCmd()`, which aggregates all of the transaction commands of the module. Often, each command getter function has its own file in the module's `cli` folder, and a separate `tx.go` file contains `GetTxCmd()`. Application developers wishing to include the module's transactions will call this function to add them as subcommands in their CLI. Here is the [`auth`](https://github.com/cosmos/cosmos-sdk/tree/67f6b021180c7ef0bcf25b6597a629aca27766b8/docs/spec/auth) `GetTxCmd()` function, which adds the `Sign` and `MultiSign` commands. An application using this module likely adds `auth` module commands to its root `TxCmd` command by calling `txCmd.AddCommand(authModuleClient.GetTxCmd())`. +Finally, the module needs to have a `GetTxCmd()`, which aggregates all of the transaction commands of the module. Often, each command getter function has its own file in the module's `cli` folder, and a separate `tx.go` file contains `GetTxCmd()`. Application developers wishing to include the module's transactions will call this function to add them as subcommands in their CLI. Here is the `auth` `GetTxCmd()` function, which adds the `Sign` and `MultiSign` commands. -```go -func GetTxCmd(cdc *codec.Codec) *cobra.Command { - txCmd := &cobra.Command{ - Use: types.ModuleName, - Short: "Auth transaction subcommands", - DisableFlagParsing: true, - SuggestionsMinimumDistance: 2, - RunE: client.ValidateCmd, - } - txCmd.AddCommand( - GetMultiSignCommand(cdc), - GetSignCommand(cdc), - ) - return txCmd -} -``` ++++ https://github.com/cosmos/cosmos-sdk/blob/67f6b021180c7ef0bcf25b6597a629aca27766b8/x/auth/client/cli/tx.go#L11-L25 -### Query Commands +An application using this module likely adds `auth` module commands to its root `TxCmd` command by calling `txCmd.AddCommand(authModuleClient.GetTxCmd())`. -[Queries](./messages-and-queries.md#queries) allow users to gather information about the application or network state; they are routed by the application and processed by the module in which they are defined. Query commands typically have their own `query.go` file in the module `x/moduleName/client/cli` folder. Like transaction commands, they are specified in getter functions and have the prefix `GetCmdQuery`. Here is an example of a query command from the [nameservice module CLI](https://github.com/cosmos/sdk-application-tutorial/blob/c6754a1e313eb1ed973c5c91dcc606f2fd288811/tutorial/cli.md#queries): +### Query Commands -```go -func GetCmdWhois(queryRoute string, cdc *codec.Codec) *cobra.Command { - return &cobra.Command{ - Use: "whois [name]", - Short: "Query whois info of name", - Args: cobra.ExactArgs(1), - RunE: func(cmd *cobra.Command, args []string) error { - cliCtx := context.NewCLIContext().WithCodec(cdc) - name := args[0] - - res, err := cliCtx.QueryWithData(fmt.Sprintf("custom/%s/whois/%s", queryRoute, name), nil) - if err != nil { - fmt.Printf("could not resolve whois - %s \n", string(name)) - return nil - } - - var out nameservice.Whois - cdc.MustUnmarshalJSON(res, &out) - return cliCtx.PrintOutput(out) - }, - } -} +[Queries](./messages-and-queries.md#queries) allow users to gather information about the application or network state; they are routed by the application and processed by the module in which they are defined. Query commands typically have their own `query.go` file in the module `x/moduleName/client/cli` folder. Like transaction commands, they are specified in getter functions and have the prefix `GetCmdQuery`. Here is an example of a query command from the `nameservice` module: -``` ++++ https://github.com/cosmos/sdk-tutorials/blob/86a27321cf89cc637581762e953d0c07f8c78ece/nameservice/x/nameservice/client/cli/query.go#L52-L73 This query returns the address that owns a particular name. The getter function does the following: @@ -140,7 +74,11 @@ The flags for a module are typically found in a `flags.go` file in the `./x/modu For full details on flags, visit the [Cobra Documentation](https://github.com/spf13/cobra). -For example, the SDK `./client/flags` package includes a [`PostCommands()`](https://github.com/cosmos/cosmos-sdk/blob/master/client/flags/flags.go#L85-L116) function that adds necessary flags to transaction commands, such as the `from` flag to indicate which address the transaction originates from. Here is an example of how to add a flag using the `from` flag from this function. +For example, the SDK `./client/flags` package includes a `PostCommands()` function that adds necessary flags to transaction commands, such as the `from` flag to indicate which address the transaction originates from. + ++++ https://github.com/cosmos/cosmos-sdk/blob/master/client/flags/flags.go#L85-L116 + +Here is an example of how to add a flag using the `from` flag from this function. ```go cmd.Flags().String(FlagFrom, "", "Name or address of private key with which to sign") @@ -166,16 +104,9 @@ To support HTTP requests, the module developer needs to define possible request Request types, which define structured interactions from users, must be defined for all *transaction* requests. Users using this method to interact with an application will send HTTP Requests with the required fields in order to trigger state changes in the application. Conventionally, each request is named with the suffix `Req`, e.g. `SendReq` for a Send transaction. Each struct should include a base request [`baseReq`](../interfaces/rest.md#basereq), the name of the transaction, and all the arguments the user must provide for the transaction. -Here is an example of a request to buy a name from the [nameservice](https://github.com/cosmos/sdk-application-tutorial/blob/c6754a1e313eb1ed973c5c91dcc606f2fd288811/tutorial/rest.md) module: +Here is an example of a request to buy a name from the `nameservice` module: -```go -type buyNameReq struct { - BaseReq rest.BaseReq `json:"base_req"` - Name string `json:"name"` - Amount string `json:"amount"` - Buyer string `json:"buyer"` -} -``` ++++ https://github.com/cosmos/sdk-tutorials/blob/master/nameservice/x/nameservice/client/rest/tx.go#L14-L19 The `BaseReq` includes basic information that every request needs to have, similar to required flags in a CLI. All of these values, including `GasPrices` and `AccountNumber`, will be provided in the request body. The user will also need to specify the arguments `Name` and `Amount` fields in the body and `Buyer` will be provided by the user's address. @@ -200,45 +131,7 @@ Request handlers must be defined for both transaction and query requests. Handle Here is an example of a request handler for the nameservice module `buyNameReq` request (the same one shown above): -```go -func buyNameHandler(cdc *codec.Codec, cliCtx context.CLIContext) http.HandlerFunc { - return func(w http.ResponseWriter, r *http.Request) { - var req buyNameReq - - if !rest.ReadRESTReq(w, r, cdc, &req) { - rest.WriteErrorResponse(w, http.StatusBadRequest, "failed to parse request") - return - } - - baseReq := req.BaseReq.Sanitize() - if !baseReq.ValidateBaic(w) { - return - } - - addr, err := sdk.AccAddressFromBech32(req.Buyer) - if err != nil { - rest.WriteErrorResponse(w, http.StatusBadRequest, err.Error()) - return - } - - coins, err := sdk.ParseCoins(req.Amount) - if err != nil { - rest.WriteErrorResponse(w, http.StatusBadRequest, err.Error()) - return - } - - //create message - msg := nameservice.NewMsgBuyName(req.Name, coins, addr) - err = msg.ValidateBasic() - if err != nil { - rest.WriteErrorResponse(w, http.StatusBadRequest, err.Error()) - return - } - clientrest.WriteGenerateStdTxResponse(w, cdc, cliCtx, baseReq, []sdk.Msg{msg}) - - } -} -``` ++++ https://github.com/cosmos/sdk-tutorials/blob/master/nameservice/x/nameservice/client/rest/tx.go#L21-L57 The request handler can be broken down as follows: diff --git a/docs/building-modules/module-manager.md b/docs/building-modules/module-manager.md index 98924bbe671d..06bde5009643 100644 --- a/docs/building-modules/module-manager.md +++ b/docs/building-modules/module-manager.md @@ -15,7 +15,7 @@ Cosmos SDK modules need to implement the [`AppModule` interfaces](#application-m ## Application Module Interfaces -[Application module interfaces](https://github.com/cosmos/cosmos-sdk/blob/master/types/module/module.go) exist to facilitate the composition of modules together to form a functional SDK application. There are 3 main application module interfaces: +Application module interfaces exist to facilitate the composition of modules together to form a functional SDK application. There are 3 main application module interfaces: - [`AppModuleBasic`](#appmodulebasic) for independent module functionalities. - [`AppModule`](#appmodule) for inter-dependent module functionalities (except genesis-related functionalities). @@ -30,23 +30,9 @@ are only used for genesis can take advantage of the `Module` patterns without ha ### `AppModuleBasic` -The [`AppModuleBasic`](https://github.com/cosmos/cosmos-sdk/blob/master/types/module/module.go#L45-L57) interface defines the independent methods modules need to implement. +The `AppModuleBasic` interface defines the independent methods modules need to implement. -```go -type AppModuleBasic interface { - Name() string - RegisterCodec(*codec.Codec) - - // genesis - DefaultGenesis() json.RawMessage - ValidateGenesis(json.RawMessage) error - - // client functionality - RegisterRESTRoutes(context.CLIContext, *mux.Router) - GetTxCmd(*codec.Codec) *cobra.Command - GetQueryCmd(*codec.Codec) *cobra.Command -} -``` ++++ https://github.com/cosmos/cosmos-sdk/blob/master/types/module/module.go#L45-L57 Let us go through the methods: @@ -62,15 +48,9 @@ All the `AppModuleBasic` of an application are managed by the [`BasicManager`](# ### `AppModuleGenesis` -The [`AppModuleGenesis`](https://github.com/cosmos/cosmos-sdk/blob/master/types/module/module.go#L123-L127) interface is a simple embedding of the `AppModuleBasic` interface with two added methods. +The `AppModuleGenesis` interface is a simple embedding of the `AppModuleBasic` interface with two added methods. -```go -type AppModuleGenesis interface { - AppModuleBasic - InitGenesis(sdk.Context, json.RawMessage) []abci.ValidatorUpdate - ExportGenesis(sdk.Context) json.RawMessage -} -``` ++++ https://github.com/cosmos/cosmos-sdk/blob/master/types/module/module.go#L123-L127 Let us go through the two added methods: @@ -81,25 +61,9 @@ It does not have its own manager, and exists separately from [`AppModule`](#appm ### `AppModule` -The [`AppModule`](https://github.com/cosmos/cosmos-sdk/blob/master/types/module/module.go#L130-L144) interface defines the inter-dependent methods modules need to implement. - -```go -type AppModule interface { - AppModuleGenesis - - // registers - RegisterInvariants(sdk.InvariantRegistry) +The `AppModule` interface defines the inter-dependent methods modules need to implement. - // routes - Route() string - NewHandler() sdk.Handler - QuerierRoute() string - NewQuerierHandler() sdk.Querier - - BeginBlock(sdk.Context, abci.RequestBeginBlock) - EndBlock(sdk.Context, abci.RequestEndBlock) []abci.ValidatorUpdate -} -``` ++++ https://github.com/cosmos/cosmos-sdk/blob/master/types/module/module.go#L130-L144 `AppModule`s are managed by the [module manager](#manager). This interface embeds the `AppModuleGenesis` interface so that the manager can access all the independent and genesis inter-dependent methods of the module. This means that a concrete type implementing the `AppModule` interface must either implement all the methods of `AppModuleGenesis` (and by extension `AppModuleBasic`), or include a concrete type that does as parameter. @@ -160,17 +124,9 @@ It implements the following methods: ### `Manager` -The [`Manager`](https://github.com/cosmos/cosmos-sdk/blob/master/types/module/module.go#L203-L209) is a structure that holds all the `AppModule` of an application, and defines the order of execution between several key components of these modules: +The `Manager` is a structure that holds all the `AppModule` of an application, and defines the order of execution between several key components of these modules: -```go -type Manager struct { - Modules map[string]AppModule - OrderInitGenesis []string - OrderExportGenesis []string - OrderBeginBlockers []string - OrderEndBlockers []string -} -``` ++++ https://github.com/cosmos/cosmos-sdk/blob/master/types/module/module.go#L203-L209 The module manager is used throughout the application whenever an action on a collection of modules is required. It implements the following methods: diff --git a/docs/building-modules/querier.md b/docs/building-modules/querier.md index 81c7dd6c481e..3942342ef46c 100644 --- a/docs/building-modules/querier.md +++ b/docs/building-modules/querier.md @@ -15,11 +15,9 @@ A `Querier` designates a function that processes [`queries`](./messages-and-quer ## `Querier` type -The [`querier` type](https://github.com/cosmos/cosmos-sdk/blob/master/types/queryable.go#L6) defined in the Cosmos SDK specifies the typical structure of a `querier` function: +The `querier` type defined in the Cosmos SDK specifies the typical structure of a `querier` function: -```go -type Querier = func(ctx Context, path []string, req abci.RequestQuery) (res []byte, err Error) -``` ++++ https://github.com/cosmos/cosmos-sdk/blob/master/types/queryable.go#L6 Let us break it down: diff --git a/docs/core/baseapp.md b/docs/core/baseapp.md index 2432572ce2b2..2bcd1d833c9e 100644 --- a/docs/core/baseapp.md +++ b/docs/core/baseapp.md @@ -2,7 +2,7 @@ order: 1 --- -# BaseApp +# Baseapp ## Pre-requisite Reading @@ -48,13 +48,14 @@ management logic. ## Type Definition -The [`BaseApp` type](https://github.com/cosmos/cosmos-sdk/blob/master/baseapp/baseapp.go#L53) holds -many important parameters for any Cosmos SDK based application. Let us go through the most -important components. +The `BaseApp` type holds many important parameters for any Cosmos SDK based application. + ++++ https://github.com/cosmos/cosmos-sdk/blob/master/baseapp/baseapp.go#L54-L108 + +Let us go through the most important components. > __Note__: Not all parameters are described, only the most important ones. Refer to the -[type definition](https://github.com/cosmos/cosmos-sdk/blob/master/baseapp/baseapp.go#L53) for the -full list. +type definition for the full list. First, the important parameters that are initialized during the bootstrapping of the application: @@ -189,13 +190,15 @@ When messages and queries are received by the application, they must be routed t ### Message Routing -[`Message`s](#../building-modules/messages-and-queries.md#messages) need to be routed after they are extracted from transactions, which are sent from the underlying Tendermint engine via the [`CheckTx`](#checktx) and [`DeliverTx`](#delivertx) ABCI messages. To do so, `baseapp` holds a [`router`](https://github.com/cosmos/cosmos-sdk/blob/master/baseapp/router.go) which maps `paths` (`string`) to the appropriate module [`handler`](../building-modules/handler.md). Usually, the `path` is the name of the module. +[`Message`s](#../building-modules/messages-and-queries.md#messages) need to be routed after they are extracted from transactions, which are sent from the underlying Tendermint engine via the [`CheckTx`](#checktx) and [`DeliverTx`](#delivertx) ABCI messages. To do so, `baseapp` holds a `router` which maps `paths` (`string`) to the appropriate module [`handler`](../building-modules/handler.md). Usually, the `path` is the name of the module. + ++++ https://github.com/cosmos/cosmos-sdk/blob/master/baseapp/router.go The application's `router` is initilalized with all the routes using the application's [module manager](../building-modules/module-manager.md#manager), which itself is initialized with all the application's modules in the application's [constructor](../basics/app-anatomy.md#app-constructor). ### Query Routing -Similar to `message`s, [`queries`](../building-modules/messages-and-queries.md#queries) need to be routed to the appropriate module's [querier](../building-modules/querier.md). To do so, `baseapp` holds a [`query router`](https://github.com/cosmos/cosmos-sdk/blob/master/baseapp/queryrouter.go), which maps module names to module `querier`s. The `queryRouter` is called during the initial stages of `query` processing, which is done via the [`Query` ABCI message](#query). +Similar to `message`s, [`queries`](../building-modules/messages-and-queries.md#queries) need to be routed to the appropriate module's [querier](../building-modules/querier.md). To do so, `baseapp` holds a `query router`, which maps module names to module `querier`s. The `queryRouter` is called during the initial stages of `query` processing, which is done via the [`Query` ABCI message](#query). Just like the `router`, the `query router` is initilalized with all the query routes using the application's [module manager](../building-modules/module-manager.md), which itself is initialized with all the application's modules in the application's [constructor](../basics/app-anatomy.md#app-constructor). @@ -257,7 +260,8 @@ The response contains: - `Log (string):` The output of the application's logger. May be non-deterministic. - `Info (string):` Additional information. May be non-deterministic. - `GasWanted (int64)`: Amount of gas requested for transaction. It is provided by users when they generate the transaction. -- `GasUsed (int64)`: Amount of gas consumed by transaction. During `CheckTx`, this value is computed by multiplying the standard cost of a transaction byte by the size of the raw transaction (click [here](https://github.com/cosmos/cosmos-sdk/blob/master/x/auth/ante/basic.go#L98) for an example). +- `GasUsed (int64)`: Amount of gas consumed by transaction. During `CheckTx`, this value is computed by multiplying the standard cost of a transaction byte by the size of the raw transaction. Next is an example: + +++ https://github.com/cosmos/cosmos-sdk/blob/master/x/auth/ante/basic.go#L98 - `Events ([]cmn.KVPair)`: Key-Value tags for filtering and indexing transactions (eg. by account). See [`event`s](./events.md) for more. - `Codespace (string)`: Namespace for the Code. @@ -281,7 +285,11 @@ Before the first transaction of a given block is processed, a [volatile state](# 1. The `AnteHandler` does **not** check that the transaction's `gas-prices` is sufficient. That is because the `min-gas-prices` value `gas-prices` is checked against is local to the node, and therefore what is enough for one full-node might not be for another. This means that the proposer can potentially include transactions for free, although they are not incentivised to do so, as they earn a bonus on the total fee of the block they propose. 2. For each `message` in the transaction, route to the appropriate module's [`handler`](../building-modules/handler.md). Additional _stateful_ checks are performed, and the cache-wrapped multistore held in `deliverState`'s `context` is updated by the module's `keeper`. If the `handler` returns successfully, the cache-wrapped multistore held in `context` is written to `deliverState` `CacheMultiStore`. -During step 5., each read/write to the store increases the value of `GasConsumed`. You can find the default cost of each operation [here](https://github.com/cosmos/cosmos-sdk/blob/master/store/types/gas.go#L142-L150). At any point, if `GasConsumed > GasWanted`, the function returns with `Code != 0` and `DeliverTx` fails. +During step 5., each read/write to the store increases the value of `GasConsumed`. You can find the default cost of each operation: + ++++ https://github.com/cosmos/cosmos-sdk/blob/master/store/types/gas.go#L142-L150 + +At any point, if `GasConsumed > GasWanted`, the function returns with `Code != 0` and `DeliverTx` fails. `DeliverTx` returns a response to the underlying consensus engine of type [`abci.ResponseDeliverTx`](https://tendermint.com/docs/spec/abci/abci.html#delivertx). The response contains: @@ -304,13 +312,19 @@ The first thing `RunTx` does upon being called is to retrieve the `context`'s `C After that, `RunTx()` calls `ValidateBasic()` on each `message`in the `Tx`, which runs preliminary _stateless_ validity checks. If any `message` fails to pass `ValidateBasic()`, `RunTx()` returns with an error. -Then, the [`anteHandler`](#antehandler) of the application is run (if it exists). In preparation of this step, both the `checkState`/`deliverState`'s `context` and `context`'s `CacheMultiStore` are cached-wrapped using the [`cacheTxContext()`](https://github.com/cosmos/cosmos-sdk/blob/master/baseapp/baseapp.go#L781-L798) function. This allows `RunTx` not to commit the changes made to the state during the execution of `anteHandler` if it ends up failing. It also prevents the module implementing the `anteHandler` from writing to state, which is an important part of the [object-capabilities](./ocap.md) of the Cosmos SDK. +Then, the [`anteHandler`](#antehandler) of the application is run (if it exists). In preparation of this step, both the `checkState`/`deliverState`'s `context` and `context`'s `CacheMultiStore` are cached-wrapped using the `cacheTxContext()` function. + ++++ https://github.com/cosmos/cosmos-sdk/blob/master/baseapp/baseapp.go#L781-L798 + +This allows `RunTx` not to commit the changes made to the state during the execution of `anteHandler` if it ends up failing. It also prevents the module implementing the `anteHandler` from writing to state, which is an important part of the [object-capabilities](./ocap.md) of the Cosmos SDK. Finally, the [`RunMsgs()`](#runmsgs) function is called to process the `messages`s in the `Tx`. In preparation of this step, just like with the `anteHandler`, both the `checkState`/`deliverState`'s `context` and `context`'s `CacheMultiStore` are cached-wrapped using the `cacheTxContext()` function. ### AnteHandler -The `AnteHandler` is a special handler that implements the [`anteHandler` interface](https://github.com/cosmos/cosmos-sdk/blob/master/types/handler.go#L8) and is used to authenticate the transaction before the transaction's internal messages are processed. +The `AnteHandler` is a special handler that implements the `anteHandler` interface and is used to authenticate the transaction before the transaction's internal messages are processed. + ++++ https://github.com/cosmos/cosmos-sdk/blob/master/types/handler.go#L8 The `AnteHandler` is theoretically optional, but still a very important component of public blockchain networks. It serves 3 primary purposes: @@ -344,7 +358,9 @@ Finally, the `InitChain(req abci.RequestInitChain)` method of `baseapp` calls th The [`BeginBlock` ABCI message](#https://tendermint.com/docs/app-dev/abci-spec.html#beginblock) is sent from the underlying Tendermint engine when a block proposal created by the correct proposer is received, before [`DeliverTx`](#delivertx) is run for each transaction in the block. It allows developers to have logic be executed at the beginning of each block. In the Cosmos SDK, the `BeginBlock(req abci.RequestBeginBlock)` method does the following: -- Initialize [`deliverState`](#volatile-states) with the latest header using the `req abci.RequestBeginBlock` passed as parameter via the [`setDeliverState`](https://github.com/cosmos/cosmos-sdk/blob/master/baseapp/baseapp.go#L283-L289) function. This function also resets the [main gas meter](../basics/gas-fees.md#main-gas-meter). +- Initialize [`deliverState`](#volatile-states) with the latest header using the `req abci.RequestBeginBlock` passed as parameter via the `setDeliverState` function. + +++ https://github.com/cosmos/cosmos-sdk/blob/master/baseapp/baseapp.go#L283-L289 +This function also resets the [main gas meter](../basics/gas-fees.md#main-gas-meter). - Initialize the [block gas meter](../basics/gas-fees.md#block-gas-meter) with the `maxGas` limit. The `gas` consumed within the block cannot go above `maxGas`. This parameter is defined in the application's consensus parameters. - Run the application's [`beginBlocker()`](../basics/app-anatomy.md#beginblocker-and-endblock), which mainly runs the [`BeginBlocker()`](../building-modules/beginblock-endblock.md#beginblock) method of each of the application's modules. - Set the [`VoteInfos`](https://tendermint.com/docs/app-dev/abci-spec.html#voteinfo) of the application, i.e. the list of validators whose *precommit* for the previous block was included by the proposer of the current block. This information is carried into the [`Context`](./context.md) so that it can be used during `DeliverTx` and `EndBlock`. diff --git a/docs/core/context.md b/docs/core/context.md index 591481ec6fbc..b0ca814d7906 100644 --- a/docs/core/context.md +++ b/docs/core/context.md @@ -40,7 +40,7 @@ type Context struct { - **ABCI Header:** The [header](https://tendermint.com/docs/spec/abci/abci.html#header) is an ABCI type. It carries important information about the state of the blockchain, such as block height and proposer of the current block. - **Chain ID:** The unique identification number of the blockchain a block pertains to. - **Transaction Bytes:** The `[]byte` representation of a transaction being processed using the context. Every transaction is processed by various parts of the SDK and consensus engine (e.g. Tendermint) throughout its [lifecycle](../basics/tx-lifecycle.md), some of which to not have any understanding of transaction types. Thus, transactions are marshaled into the generic `[]byte` type using some kind of [encoding format](./encoding.md) such as [Amino](./encoding.md). -- **Logger:** A [Logger](https://github.com/tendermint/tendermint/blob/bc572217c07b90ad9cee851f193aaa8e9557cbc7/libs/log/logger.go) from the Tendermint libraries. Learn more about logs [here](https://tendermint.com/docs/tendermint-core/how-to-read-logs.html#how-to-read-logs). Modules call this method to create their own unique module-specific logger. +- **Logger:** A `logger` from the Tendermint libraries. Learn more about logs [here](https://tendermint.com/docs/tendermint-core/how-to-read-logs.html#how-to-read-logs). Modules call this method to create their own unique module-specific logger. - **VoteInfo:** A list of the ABCI type [`VoteInfo`](https://tendermint.com/docs/spec/abci/abci.html#voteinfo), which includes the name of a validator and a boolean indicating whether they have signed the block. - **Gas Meters:** Specifically, a [`gasMeter`](../basics/gas-fees.md#main-gas-meter) for the transaction currently being processed using the context and a [`blockGasMeter`](../basics/gas-fees.md#block-gas-meter) for the entire block it belongs to. Users specify how much in fees they wish to pay for the execution of their transaction; these gas meters keep track of how much [gas](../basics/gas-fees.md) has been used in the transaction or block so far. If the gas meter runs out, execution halts. - **CheckTx Mode:** A boolean value indicating whether a transaction should be processed in `CheckTx` or `DeliverTx` mode. diff --git a/docs/core/encoding.md b/docs/core/encoding.md index f7f07f2c682b..62ee726eefea 100644 --- a/docs/core/encoding.md +++ b/docs/core/encoding.md @@ -34,36 +34,15 @@ keeper.cdc.MustUnmarshalBinaryBare(bz, &object) Alternatively, it is possible to use `MustMarshalBinaryLengthPrefixed`/`MustUnmarshalBinaryLengthPrefixed` instead of `MustMarshalBinaryBare`/`MustUnmarshalBinaryBare` for the same encoding prefixed by a `uvarint` encoding of the object to encode. -Another important use of the `codec` is the encoding and decoding of [transactions](./transactions.md). Transactions are defined at the Cosmos SDK level, but passed to the underlying consensus engine in order to be relayed to other peers. Since the underlying consensus engine is agnostic to the application, it only accepts transactions in the form of `[]byte`. The encoding is done by an object called [`TxEncoder`](https://github.com/cosmos/cosmos-sdk/blob/master/types/tx_msg.go#L48-L49) and the decoding by an object called [`TxDecoder`](https://github.com/cosmos/cosmos-sdk/blob/master/types/tx_msg.go#L45-L47). A [standard implementation](https://github.com/cosmos/cosmos-sdk/blob/master/x/auth/types/stdtx.go) of both these objects can be found in the `auth` module: +Another important use of the `codec` is the encoding and decoding of [transactions](./transactions.md). Transactions are defined at the Cosmos SDK level, but passed to the underlying consensus engine in order to be relayed to other peers. Since the underlying consensus engine is agnostic to the application, it only accepts transactions in the form of `[]byte`. The encoding is done by an object called `TxEncoder` and the decoding by an object called `TxDecoder`. -```go -// DefaultTxDecoder logic for standard transaction decoding -func DefaultTxDecoder(cdc *codec.Codec) sdk.TxDecoder { - return func(txBytes []byte) (sdk.Tx, sdk.Error) { - var tx = StdTx{} - - if len(txBytes) == 0 { - return nil, sdk.ErrTxDecode("txBytes are empty") - } - - // StdTx.Msg is an interface. The concrete types - // are registered by MakeTxCodec - err := cdc.UnmarshalBinaryLengthPrefixed(txBytes, &tx) - if err != nil { - return nil, sdk.ErrTxDecode("error decoding transaction").TraceSDK(err.Error()) - } - - return tx, nil - } -} - -// DefaultTxEncoder logic for standard transaction encoding -func DefaultTxEncoder(cdc *codec.Codec) sdk.TxEncoder { - return func(tx sdk.Tx) ([]byte, error) { - return cdc.MarshalBinaryLengthPrefixed(tx) - } -} -``` ++++ https://github.com/cosmos/cosmos-sdk/blob/master/types/tx_msg.go#L48-L49 + ++++ https://github.com/cosmos/cosmos-sdk/blob/master/types/tx_msg.go#L45-L47 + +A standard implementation of both these objects can be found in the [`auth` module](https://github.com/cosmos/cosmos-sdk/blob/master/x/auth): + ++++ https://github.com/cosmos/cosmos-sdk/blob/master/x/auth/types/stdtx.go#L241-L266 ## Next diff --git a/docs/core/events.md b/docs/core/events.md index 7d9f6f28a465..ce031a3b608e 100644 --- a/docs/core/events.md +++ b/docs/core/events.md @@ -14,10 +14,15 @@ order: 7 ## Events -`Event`s are implemented in the Cosmos SDK as an alias of the [ABCI `event` type](https://github.com/tendermint/tendermint/blob/bc572217c07b90ad9cee851f193aaa8e9557cbc7/abci/types/types.pb.go#L2661-L2667). They contain: +`Event`s are implemented in the Cosmos SDK as an alias of the ABCI `event` type. + ++++ https://github.com/tendermint/tendermint/blob/bc572217c07b90ad9cee851f193aaa8e9557cbc7/abci/types/types.pb.go#L2661-L2667 + +They contain: - A **`type`** of type `string`, which can refer to the type of action that led to the `event`'s emission (e.g. a certain value going above a threshold), or to the type of `message` if the event is triggered at the end of that `message` processing. -- A list of [`attributes`](https://github.com/cosmos/cosmos-sdk/blob/master/types/events.go#L53-L56), which are key-value pairs that give more information about the `event`. +- A list of `attributes`, which are key-value pairs that give more information about the `event`. + +++ https://github.com/cosmos/cosmos-sdk/blob/master/types/events.go#L53-L56 `Event`s are returned to the underlying consensus engine in the response of the following ABCI messages: [`CheckTx`](./baseapp.md#checktx), [`DeliverTx`](./baseapp.md#delivertx), [`BeginBlock`](./baseapp.md#beginblock) and [`EndBlock`](./baseapp.md#endblock). @@ -25,15 +30,13 @@ Typically, `event` `type`s and `attributes` are defined on a **per-module basis* ## EventManager -In Cosmos SDK applications, `event`s are generally managed by an object called the [`EventManager`](https://github.com/cosmos/cosmos-sdk/blob/master/types/events.go#L18-L20). It is implemented as a simple wrapper around a slice of `event`s: +In Cosmos SDK applications, `event`s are generally managed by an object called the `EventManager`. It is implemented as a simple wrapper around a slice of `event`s: -```go -type EventManager struct { - events Events -} -``` ++++ https://github.com/cosmos/cosmos-sdk/blob/master/types/events.go#L18-L20 + +The `EventManager` comes with a set of useful methods to manage `event`s. Among them, the one that is used the most by module and application developers is the `EmitEvent` method, which registers an `event` in the `EventManager`. -The `EventManager` comes with a set of useful methods to manage `event`s. Among them, the one that is used the most by module and application developers is the [`EmitEvent`](https://github.com/cosmos/cosmos-sdk/blob/master/types/events.go#L29-L31) method, which registers an `event` in the `EventManager`. ++++ https://github.com/cosmos/cosmos-sdk/blob/master/types/events.go#L29-L31 Typically, module developers will implement event emission via the `EventManager` in the [`handler`](../building-modules/handler.md) of modules, as well as in the [`BeginBlocker` and/or`EndBlocker` functions](../building-modules/beginblock-endblock.md). The `EventManager` is accessed via the context [`ctx`](./context.md), and event emission generally follows this pattern: diff --git a/docs/core/node.md b/docs/core/node.md index 3d1d12edc90e..8c4fb63c7c3b 100644 --- a/docs/core/node.md +++ b/docs/core/node.md @@ -19,12 +19,16 @@ The full-node client of any SDK application is built by running a `main` functio In general, developers will implement the `main.go` function with the following structure: - First, a [`codec`](./encoding.md) is instanciated for the application. -- Then, the [`config`](https://github.com/cosmos/cosmos-sdk/blob/master/types/config.go) is retrieved and config parameters are set. This mainly involves setting the bech32 prefixes for [addresses and pubkeys](../basics/accounts.md#addresses-and-pubkeys). +- Then, the [`config`] is retrieved and config parameters are set. This mainly involves setting the bech32 prefixes for [addresses and pubkeys](../basics/accounts.md#addresses-and-pubkeys). + +++ https://github.com/cosmos/cosmos-sdk/blob/master/types/config.go#L10-L21 - Using [cobra](https://github.com/spf13/cobra), the root command of the full-node client is created. After that, all the custom commands of the application are added using the `AddCommand()` method of `rootCmd`. - Add default server commands to `rootCmd` using the `server.AddCommands(ctx, cdc, rootCmd, newApp, exportAppStateAndTMValidators)` method. These commands are separated from the ones added above since they are standard and defined at SDK level. They should be shared by all SDK-based applications. They include the most important command: the [`start` command](#start-command). -- Prepare and execute the [`executor`](https://github.com/tendermint/tendermint/blob/bc572217c07b90ad9cee851f193aaa8e9557cbc7/libs/cli/setup.go#L75-L78). +- Prepare and execute the `executor`. + +++ https://github.com/tendermint/tendermint/blob/bc572217c07b90ad9cee851f193aaa8e9557cbc7/libs/cli/setup.go#L75-L78 -See an [example of `main` function](https://github.com/cosmos/gaia/blob/f41a660cdd5bea173139965ade55bd25d1ee3429/cmd/gaiad/main.go) from the `gaia` application. +See an example of `main` function from the [`gaia`](https://github.com/cosmos/gaia) application: + ++++ https://github.com/cosmos/gaia/blob/f41a660cdd5bea173139965ade55bd25d1ee3429/cmd/gaiad/main.go ## `start` command diff --git a/docs/core/ocap.md b/docs/core/ocap.md index 61979f10572a..af1350396119 100644 --- a/docs/core/ocap.md +++ b/docs/core/ocap.md @@ -84,17 +84,9 @@ var sumValue := externalModule.ComputeSumValue(*account) ``` In the Cosmos SDK, you can see the application of this principle in the -[gaia app](https://github.com/cosmos/gaia/blob/bd10ee5c62a1206c03a21d0f71a9e9308765cdb7/app/app.go). +gaia app. -```go -// register message routes -app.Router(). - AddRoute(bank.RouterKey, bank.NewHandler(app.bankKeeper)). - AddRoute(staking.RouterKey, staking.NewHandler(app.stakingKeeper)). - AddRoute(distr.RouterKey, distr.NewHandler(app.distrKeeper)). - AddRoute(slashing.RouterKey, slashing.NewHandler(app.slashingKeeper)). - AddRoute(gov.RouterKey, gov.NewHandler(app.govKeeper)) -``` ++++ https://github.com/cosmos/gaia/blob/master/app/app.go#L197-L209 ## Next diff --git a/docs/core/store.md b/docs/core/store.md index b052906f03c6..ed1f7349b9e1 100644 --- a/docs/core/store.md +++ b/docs/core/store.md @@ -60,35 +60,11 @@ The Cosmos SDK comes with a large set of stores to persist the state of applicat At its very core, a Cosmos SDK `store` is an object that holds a `CacheWrapper` and implements a `GetStoreType()` method: -```go -type Store interface { - GetStoreType() StoreType - CacheWrapper -} -``` ++++ https://github.com/cosmos/cosmos-sdk/blob/master/store/types/store.go#L12-L15 The `GetStoreType` is a simple method that returns the type of store, whereas a `CacheWrapper` is a simple interface that specifies cache-wrapping and `Write` methods: -```go -type CacheWrap interface { - // Write syncs with the underlying store. - Write() - - // CacheWrap recursively wraps again. - CacheWrap() CacheWrap - - // CacheWrapWithTrace recursively wraps again with tracing enabled. - CacheWrapWithTrace(w io.Writer, tc TraceContext) CacheWrap -} - -type CacheWrapper interface { - // CacheWrap cache wraps. - CacheWrap() CacheWrap - - // CacheWrapWithTrace cache wraps with tracing enabled. - CacheWrapWithTrace(w io.Writer, tc TraceContext) CacheWrap -} -``` ++++ https://github.com/cosmos/cosmos-sdk/blob/master/store/types/store.go#L217-L238 Cache-wrapping is used ubiquitously in the Cosmos SDK and required to be implemented on every store type. A cache-wrapper creates a light snapshot of a store that can be passed around and updated without affecting the main underlying store. This is used to trigger temporary state-transitions that may be reverted later should an error occur. If a state-transition sequence is performed without issue, the cached store can be comitted to the underlying store at the end of the sequence. @@ -96,24 +72,11 @@ Cache-wrapping is used ubiquitously in the Cosmos SDK and required to be impleme A commit store is a store that has the ability to commit changes made to the underlying tree or db. The Cosmos SDK differentiates simple stores from commit stores by extending the basic store interfaces with a `Committer`: -```go -// Stores of MultiStore must implement CommitStore. -type CommitStore interface { - Committer - Store -} -``` ++++ https://github.com/cosmos/cosmos-sdk/blob/master/store/types/store.go#L24-L28 The `Committer` is an interface that defines methods to persist changes to disk: -```go -// something that can persist to disk -type Committer interface { - Commit() CommitID - LastCommitID() CommitID - SetPruning(PruningOptions) -} -``` ++++ https://github.com/cosmos/cosmos-sdk/blob/master/store/types/store.go#L17-L22 The `CommitID` is a deterministic commit of the state tree. Its hash is returned to the underlying consensus engine and stored in the block header. Note that commit store interfaces exist for various purposes, one of which is to make sure not every object can commit the store. As part of the [object-capabilities model](./ocap.md) of the Cosmos SDK, only `baseapp` should have the ability to commit stores. For example, this is the reason why the `ctx.KVStore()` method by which modules typically access stores returns a `KVStore` and not a `CommitKVStore`. @@ -125,38 +88,7 @@ The Cosmos SDK comes with many types of stores, the most used being [`CommitMult Each Cosmos SDK application holds a multistore at its root to persist its state. The multistore is a store of `KVStores` that follows the `Multistore` interface: -```go -type MultiStore interface { - Store - - // Cache wrap MultiStore. - // NOTE: Caller should probably not call .Write() on each, but - // call CacheMultiStore.Write(). - CacheMultiStore() CacheMultiStore - - // CacheMultiStoreWithVersion cache-wraps the underlying MultiStore where - // each stored is loaded at a specific version (height). - CacheMultiStoreWithVersion(version int64) (CacheMultiStore, error) - - // Convenience for fetching substores. - // If the store does not exist, panics. - GetStore(StoreKey) Store - GetKVStore(StoreKey) KVStore - - // TracingEnabled returns if tracing is enabled for the MultiStore. - TracingEnabled() bool - - // SetTracer sets the tracer for the MultiStore that the underlying - // stores will utilize to trace operations. The modified MultiStore is - // returned. - SetTracer(w io.Writer) MultiStore - - // SetTracingContext sets the tracing context for a MultiStore. It is - // implied that the caller should update the context when necessary between - // tracing operations. The modified MultiStore is returned. - SetTracingContext(TraceContext) MultiStore -} -``` ++++ https://github.com/cosmos/cosmos-sdk/blob/master/store/types/store.go#L83-L112 If tracing is enabled, then cache-wrapping the multistore will wrap all the underlying `KVStore` in [`TraceKv.Store`](#tracekv-store) before caching them. @@ -164,60 +96,19 @@ If tracing is enabled, then cache-wrapping the multistore will wrap all the unde The main type of `Multistore` used in the Cosmos SDK is `CommitMultiStore`, which is an extension of the `Multistore` interface: -```go -// A non-cache MultiStore. -type CommitMultiStore interface { - Committer - MultiStore - - // Mount a store of type using the given db. - // If db == nil, the new store will use the CommitMultiStore db. - MountStoreWithDB(key StoreKey, typ StoreType, db dbm.DB) - - // Panics on a nil key. - GetCommitStore(key StoreKey) CommitStore - - // Panics on a nil key. - GetCommitKVStore(key StoreKey) CommitKVStore - - // Load the latest persisted version. Called once after all calls to - // Mount*Store() are complete. - LoadLatestVersion() error - - // LoadLatestVersionAndUpgrade will load the latest version, but also - // rename/delete/create sub-store keys, before registering all the keys - // in order to handle breaking formats in migrations - LoadLatestVersionAndUpgrade(upgrades *StoreUpgrades) error - - // LoadVersionAndUpgrade will load the named version, but also - // rename/delete/create sub-store keys, before registering all the keys - // in order to handle breaking formats in migrations - LoadVersionAndUpgrade(ver int64, upgrades *StoreUpgrades) error - - // Load a specific persisted version. When you load an old version, or when - // the last commit attempt didn't complete, the next commit after loading - // must be idempotent (return the same commit id). Otherwise the behavior is - // undefined. - LoadVersion(ver int64) error - - // Set an inter-block (persistent) cache that maintains a mapping from - // StoreKeys to CommitKVStores. - SetInterBlockCache(MultiStorePersistentCache) -} -``` ++++ https://github.com/cosmos/cosmos-sdk/blob/master/store/types/store.go#L120-L158 -As for concrete implementation, the [`rootMulti.Store`](https://github.com/cosmos/cosmos-sdk/blob/master/store/rootmulti/store.go) is the go-to implementation of the `CommitMultiStore` interface. The `rootMulti.Store` is a base-layer multistore built around a `db` on top of which multiple `KVStores` can be mounted, and is the default multistore store used in [`baseapp`](./baseapp.md). +As for concrete implementation, the [`rootMulti.Store`] is the go-to implementation of the `CommitMultiStore` interface. + ++++ https://github.com/cosmos/cosmos-sdk/blob/master/store/rootmulti/store.go#L27-L43 + +The `rootMulti.Store` is a base-layer multistore built around a `db` on top of which multiple `KVStores` can be mounted, and is the default multistore store used in [`baseapp`](./baseapp.md). ### CacheMultiStore Whenever the `rootMulti.Store` needs to be cached-wrapped, a [`cachemulti.Store`](https://github.com/cosmos/cosmos-sdk/blob/master/store/cachemulti/store.go) is used. -```go -type Store struct { - db types.CacheKVStore - stores map[types.StoreKey] types.CacheWrap -} -``` ++++ https://github.com/cosmos/cosmos-sdk/blob/master/store/cachemulti/store.go#L17-L28 `cachemulti.Store` cache wraps all substores in its constructor and hold them in `Store.stores`. `Store.GetKVStore()` returns the store from `Store.stores`, and `Store.Write()` recursively calls `CacheWrap.Write()` on all the substores. @@ -231,44 +122,9 @@ Individual `KVStore`s are used by modules to manage a subset of the global state `CommitKVStore`s are declared by proxy of their respective `key` and mounted on the application's [multistore](#multistore) in the [main application file](../basics/app-anatomy.md#core-application-file). In the same file, the `key` is also passed to the module's `keeper` that is responsible for managing the store. -```go -type KVStore interface { - Store - - // Get returns nil iff key doesn't exist. Panics on nil key. - Get(key []byte) []byte - - // Has checks if a key exists. Panics on nil key. - Has(key []byte) bool - - // Set sets the key. Panics on nil key or value. - Set(key, value []byte) - - // Delete deletes the key. Panics on nil key. - Delete(key []byte) - - // Iterator over a domain of keys in ascending order. End is exclusive. - // Start must be less than end, or the Iterator is invalid. - // Iterator must be closed by caller. - // To iterate over entire domain, use store.Iterator(nil, nil) - // CONTRACT: No writes may happen within a domain while an iterator exists over it. - // Exceptionally allowed for cachekv.Store, safe to write in the modules. - Iterator(start, end []byte) Iterator - - // Iterator over a domain of keys in descending order. End is exclusive. - // Start must be less than end, or the Iterator is invalid. - // Iterator must be closed by caller. - // CONTRACT: No writes may happen within a domain while an iterator exists over it. - // Exceptionally allowed for cachekv.Store, safe to write in the modules. - ReverseIterator(start, end []byte) Iterator -} ++++ https://github.com/cosmos/cosmos-sdk/blob/master/store/types/store.go#L163-L193 -// Stores of MultiStore must implement CommitStore. -type CommitKVStore interface { - Committer - KVStore -} -``` ++++ https://github.com/cosmos/cosmos-sdk/blob/master/store/types/store.go#L163-L193 Apart from the traditional `Get` and `Set` methods, a `KVStore` is expected to implement an `Iterator()` method which returns an `Iterator` object. The `Iterator()` method is used to iterate over a domain of keys, typically keys that share a common prefix. Here is a common pattern of using an `Iterator` that might be found in a module's `keeper`: @@ -289,7 +145,11 @@ for ; iterator.Valid(); iterator.Next() { ### `IAVL` Store -The default implementation of `KVStore` and `CommitKVStore` used in `baseapp` is the [`iavl.Store`](https://github.com/cosmos/cosmos-sdk/blob/master/store/iavl/store.go). `iavl` stores are based around an [IAVL Tree](https://github.com/tendermint/iavl), a self-balancing binary tree which guarantees that: +The default implementation of `KVStore` and `CommitKVStore` used in `baseapp` is the `iavl.Store`. + ++++ https://github.com/cosmos/cosmos-sdk/blob/master/store/iavl/store.go#L32-L47 + + `iavl` stores are based around an [IAVL Tree](https://github.com/tendermint/iavl), a self-balancing binary tree which guarantees that: - `Get` and `Set` operations are O(log n), where n is the number of elements in the tree. - Iteration efficiently returns the sorted elements within the range. @@ -299,11 +159,7 @@ The default implementation of `KVStore` and `CommitKVStore` used in `baseapp` is `dbadapter.Store` is a adapter for `dbm.DB` making it fulfilling the `KVStore` interface. -```go -type Store struct { - dbm.DB -} -``` ++++ https://github.com/cosmos/cosmos-sdk/blob/master/store/dbadapter/store.go#L13-L16 `dbadapter.Store` embeds `dbm.DB`, meaning most of the `KVStore` interface functions are implemented. The other functions (mostly miscellaneous) are manually implemented. This store is primarily used within [Transient Stores](#transient-stores) @@ -311,25 +167,17 @@ type Store struct { `Transient.Store` is a base-layer `KVStore` which is automatically discarded at the end of the block. -```go -type Store struct { - dbadapter.Store -} -``` ++++ https://github.com/cosmos/cosmos-sdk/blob/master/store/transient/store.go#L14-L17 `Transient.Store` is a `dbadapter.Store` with a `dbm.NewMemDB()`. All `KVStore` methods are reused. When `Store.Commit()` is called, a new `dbadapter.Store` is assigned, discarding previous reference and making it garbage collected. -This type of store is useful to persist information that is only relevant per-block. One example would be to store [parameter changes](https://github.com/cosmos/cosmos-sdk/blob/master/x/params/subspace/subspace.go#L27) (i.e. a bool set to `true` if a parameter changed in a block). +This type of store is useful to persist information that is only relevant per-block. One example would be to store parameter changes (i.e. a bool set to `true` if a parameter changed in a block). -Transient stores are typically accessed via the [`context`](./context.md) via the `TransientStore()` method: ++++ https://github.com/cosmos/cosmos-sdk/blob/master/x/params/subspace/subspace.go#L24-L32 -```go -// TransientStore fetches a TransientStore from the MultiStore. +Transient stores are typically accessed via the [`context`](./context.md) via the `TransientStore()` method: -func (c Context) TransientStore(key StoreKey) KVStore { - return gaskv.NewStore(c.MultiStore().GetKVStore(key), c.GasMeter(), stypes.TransientGasConfig()) -} -``` ++++ https://github.com/cosmos/cosmos-sdk/blob/master/types/context.go#L215-L218 ## KVStore Wrappers @@ -337,12 +185,7 @@ func (c Context) TransientStore(key StoreKey) KVStore { `cachekv.Store` is a wrapper `KVStore` which provides buffered writing / cached reading functionalities over the underlying `KVStore`. -```go -type Store struct { - cache map[string]cValue - parent types.KVStore -} -``` ++++ https://github.com/cosmos/cosmos-sdk/blob/master/store/cachekv/store.go#L26-L33 This is the type used whenever an IAVL Store needs to be cache-wrapped (typically when setting value that might be reverted later). @@ -362,88 +205,33 @@ This is the type used whenever an IAVL Store needs to be cache-wrapped (typicall Cosmos SDK applications use [`gas`](../basics/gas-fees.md) to track resources usage and prevent spam. [`GasKv.Store`](https://github.com/cosmos/cosmos-sdk/blob/master/store/gaskv/store.go) is a `KVStore` wrapper that enables automatic gas consumption each time a read or write to the store is made. It is the solution of choice to track storage usage in Cosmos SDK applications. -```go -type Store struct { - gasMeter types.GasMeter - gasConfig types.GasConfig - parent types.KVStore -} -``` ++++ https://github.com/cosmos/cosmos-sdk/blob/master/store/gaskv/store.go#L11-L17 When methods of the parent `KVStore` are called, `GasKv.Store` automatically consumes appropriate amount of gas depending on the `Store.gasConfig`: -```go -type GasConfig struct { - HasCost Gas - DeleteCost Gas - ReadCostFlat Gas - ReadCostPerByte Gas - WriteCostFlat Gas - WriteCostPerByte Gas - IterNextCostFlat Gas -} -``` ++++ https://github.com/cosmos/cosmos-sdk/blob/master/store/types/gas.go#L141-L150 By default, all `KVStores` are wrapped in `GasKv.Stores` when retrieved. This is done in the `KVStore()` method of the [`context`](./context.md): -```go -// KVStore fetches a KVStore from the MultiStore. -func (c Context) KVStore(key StoreKey) KVStore { - return gaskv.NewStore(c.MultiStore().GetKVStore(key), c.GasMeter(), stypes.KVGasConfig()) -} -``` ++++ https://github.com/cosmos/cosmos-sdk/blob/master/types/context.go#L210-L213 In this case, the default gas configuration is used: -```go -func KVGasConfig() GasConfig { - return GasConfig{ - HasCost: 1000, - DeleteCost: 1000, - ReadCostFlat: 1000, - ReadCostPerByte: 3, - WriteCostFlat: 2000, - WriteCostPerByte: 30, - IterNextCostFlat: 30, - } -} -``` ++++ https://github.com/cosmos/cosmos-sdk/blob/master/store/types/gas.go#L152-L163 ### `TraceKv` Store `tracekv.Store` is a wrapper `KVStore` which provides operation tracing functionalities over the underlying `KVStore`. It is applied automatically by the Cosmos SDK on all `KVStore` if tracing is enabled on the parent `MultiStore`. -```go -type Store struct { - parent types.KVStore - writer io.Writer - context types.TraceContext -} -``` - -When each `KVStore` methods are called, `tracekv.Store` automatically logs `traceOperation` to the `Store.writer`. - -```go -type traceOperation struct { - Operation operation - Key string - Value string - Metadata map[string]interface{} -} -``` ++++ https://github.com/cosmos/cosmos-sdk/blob/master/store/tracekv/store.go#L20-L43 -`traceOperation.Metadata` is filled with `Store.context` when it is not nil. `TraceContext` is a `map[string]interface{}`. +When each `KVStore` methods are called, `tracekv.Store` automatically logs `traceOperation` to the `Store.writer`. `traceOperation.Metadata` is filled with `Store.context` when it is not nil. `TraceContext` is a `map[string]interface{}`. ### `Prefix` Store `prefix.Store` is a wrapper `KVStore` which provides automatic key-prefixing functionalities over the underlying `KVStore`. -```go -type Store struct { - parent types.KVStore - prefix []byte -} -``` ++++ https://github.com/cosmos/cosmos-sdk/blob/master/store/prefix/store.go#L17-L20 When `Store.{Get, Set}()` is called, the store forwards the call to its parent, with the key prefixed with the `Store.prefix`. diff --git a/docs/core/transactions.md b/docs/core/transactions.md index c5ef4a3b94c4..1feeb473f430 100644 --- a/docs/core/transactions.md +++ b/docs/core/transactions.md @@ -20,7 +20,11 @@ When users want to interact with an application and make state changes (e.g. sen ## Type Definition -Transaction objects are SDK types that implement the [`Tx`](https://github.com/cosmos/cosmos-sdk/blob/master/types/tx_msg.go#L34-L41) interface, which contains the following methods: +Transaction objects are SDK types that implement the `Tx` interface + ++++ https://github.com/cosmos/cosmos-sdk/blob/master/types/tx_msg.go#L34-L41 + +It contains the following methods: * **GetMsgs:** unwraps the transaction and returns a list of its message(s) - one transaction may have one or multiple [messages](../building-modules/messages-and-queries.md#messages), which are defined by module developers. * **ValidateBasic:** includes lightweight, [*stateless*](../basics/tx-lifecycle.md#types-of-checks) checks used by ABCI messages [`CheckTx`](./baseapp.md#checktx) and [`DeliverTx`](./baseapp.md#delivertx) to make sure transactions are not invalid. For example, the [`auth`](https://github.com/cosmos/cosmos-sdk/tree/master/x/auth) module's `StdTx` `ValidateBasic` function checks that its transactions are signed by the correct number of signers and that the fees do not exceed what the user's maximum. Note that this function is to be distinct from the `ValidateBasic` functions for *`messages`*, which perform basic validity checks on messages only. For example, when [`runTx`](./baseapp.md#runtx) is checking a transaction created from the [`auth`](https://github.com/cosmos/cosmos-sdk/tree/master/x/auth/spec) module, it first runs `ValidateBasic` on each message, then runs the `auth` module AnteHandler which calls `ValidateBasic` for the transaction itself. @@ -43,7 +47,11 @@ When users interact with the application's interfaces, they invoke the underlyin ### Messages -**`Message`s** are module-specific objects that trigger state transitions within the scope of the module they belong to. Module developers define the `message`s for their module by implementing the [`Msg`](https://github.com/cosmos/cosmos-sdk/blob/master/types/tx_msg.go#L10-L31) interface, and also define a [`Handler`](../building-modules/handler.md) to process them. `Message`s in a module are typically defined in a `msgs.go` file (though not always), and one handler with multiple functions to handle each of the module's `message`s is defined in a `handler.go` file. +**`Message`s** are module-specific objects that trigger state transitions within the scope of the module they belong to. Module developers define the `message`s for their module by implementing the `Msg` interface, and also define a [`Handler`](../building-modules/handler.md) to process them. + ++++ https://github.com/cosmos/cosmos-sdk/blob/master/types/tx_msg.go#L10-L31 + +`Message`s in a module are typically defined in a `msgs.go` file (though not always), and one handler with multiple functions to handle each of the module's `message`s is defined in a `handler.go` file. Note: module `messages` are not to be confused with [ABCI Messages](https://tendermint.com/docs/spec/abci/abci.html#messages) which define interactions between the Tendermint and application layers. @@ -57,19 +65,21 @@ Transactions are first created by end-users through an `appcli tx` command throu [`Contexts`](https://godoc.org/context) are immutable objects that contain all the information needed to process a request. In the process of creating a transaction through the `auth` module (though it is not mandatory to create transactions this way), two contexts are created: the [`CLIContext`](../interfaces/query-lifecycle.md#clicontext) and `TxBuilder`. Both are automatically generated and do not need to be defined by application developers, but do require input from the transaction creator (e.g. using flags through the CLI). -The [`TxBuilder`](https://github.com/cosmos/cosmos-sdk/blob/master/x/auth/types/txbuilder.go) contains data closely related with the processing of transactions: - -* `TxEncoder` defined by the developer for this type of transaction. Used to encode messages before being processed by nodes running Tendermint. -* `Keybase` that manages the user's keys and is used to perform signing operations. -* `AccountNumber` from which this transaction originated. -* `Sequence`, the number of transactions that the user has sent out, used to prevent replay attacks. -* `Gas` option chosen by the users for how to calculate how much gas they will need to pay. A common option is "auto" which generates an automatic estimate. -* `GasAdjustment` to adjust the estimate of gas by a scalar value, used to avoid underestimating the amount of gas required. -* `SimulateAndExecute` option to simply simulate the transaction execution without broadcasting. -* `ChainID` representing which blockchain this transaction pertains to. -* `Memo` to send with the transaction. -* `Fees`, the maximum amount the user is willing to pay in fees. Alternative to specifying gas prices. -* `GasPrices`, the amount per unit of gas the user is willing to pay in fees. Alternative to specifying fees. +The `TxBuilder` contains data closely related with the processing of transactions. + ++++ https://github.com/cosmos/cosmos-sdk/blob/master/x/auth/types/txbuilder.go#L18-L31 + +- `TxEncoder` defined by the developer for this type of transaction. Used to encode messages before being processed by nodes running Tendermint. +- `Keybase` that manages the user's keys and is used to perform signing operations. +- `AccountNumber` from which this transaction originated. +- `Sequence`, the number of transactions that the user has sent out, used to prevent replay attacks. +- `Gas` option chosen by the users for how to calculate how much gas they will need to pay. A common option is "auto" which generates an automatic estimate. +- `GasAdjustment` to adjust the estimate of gas by a scalar value, used to avoid underestimating the amount of gas required. +- `SimulateAndExecute` option to simply simulate the transaction execution without broadcasting. +- `ChainID` representing which blockchain this transaction pertains to. +- `Memo` to send with the transaction. +- `Fees`, the maximum amount the user is willing to pay in fees. Alternative to specifying gas prices. +- `GasPrices`, the amount per unit of gas the user is willing to pay in fees. Alternative to specifying fees. The `CLIContext` is initialized using the application's `codec` and data more closely related to the user interaction with the interface, holding data such as the output to the user and the broadcast mode. Read more about `CLIContext` [here](../interfaces/query-lifecycle.md#clicontext). diff --git a/docs/interfaces/cli.md b/docs/interfaces/cli.md index f86144a561c9..cd36c46b06eb 100644 --- a/docs/interfaces/cli.md +++ b/docs/interfaces/cli.md @@ -14,7 +14,7 @@ This document describes how to create a commmand-line interface (CLI) for an [** ## Command-Line Interface -One of the main entrypoints of an application is the command-line interface. This entrypoint is created via a `main.go` file which compiles to a binary, conventionally placed in the application's `./cmd/cli` folder. The CLI for an application is typically be referred to as the name of the application suffixed with `-cli`, e.g. `appcli`. Here is where the interfaces docs lie in the directory from the [nameservice tutorial](https://cosmos.network/docs/tutorial) +One of the main entrypoints of an application is the command-line interface. This entrypoint is created via a `main.go` file which compiles to a binary, conventionally placed in the application's `./cmd/cli` folder. The CLI for an application is typically be referred to as the name of the application suffixed with `-cli`, e.g. `appcli`. Here is where the interfaces docs lie in the directory from the [nameservice tutorial](https://cosmos.network/docs/tutorial). ### Example Command @@ -47,57 +47,21 @@ The `main.go` file needs to have a `main()` function that does the following to * **Add subcommands** for all the possible user interactions, including [transaction commands](#transaction-commands) and [query commands](#query-commands). * **Create an Executor** and [execute](https://godoc.org/github.com/spf13/cobra#Command.Execute) the root command. -An example of the `main()` function for the [nameservice tutorial](https://cosmos.network/docs/tutorial) CLI can be found [here](https://github.com/cosmos/sdk-application-tutorial/blob/c6754a1e313eb1ed973c5c91dcc606f2fd288811/cmd/nscli/main.go#L26-L67). The rest of the document will detail what needs to be implemented for each step and include smaller portions of code from the nameservice CLI `main.go` file. +See an example of `main()` function from the `nameservice` application: + ++++ https://github.com/cosmos/sdk-tutorials/blob/86a27321cf89cc637581762e953d0c07f8c78ece/nameservice/cmd/nscli/main.go#L23-L66 + +The rest of the document will detail what needs to be implemented for each step and include smaller portions of code from the nameservice CLI `main.go` file. ## Adding Commands to the CLI -Every application CLI first constructs a root command, then adds functionality by aggregating subcommands (often with further nested subcommands) using `AddCommand()`. The bulk of an application's unique capabilities lies in its transaction and query commands, called `TxCmd` and `QueryCmd` respectively. +Every application CLI first constructs a root command, then adds functionality by aggregating subcommands (often with further nested subcommands) using `rootCmd.AddCommand()`. The bulk of an application's unique capabilities lies in its transaction and query commands, called `TxCmd` and `QueryCmd` respectively. ### Root Command The root command (called `rootCmd`) is what the user first types into the command line to indicate which application they wish to interact with. The string used to invoke the command (the "Use" field) is typically the name of the application suffixed with `-cli`, e.g. `appcli`. The root command typically includes the following commands to support basic functionality in the application. -* **Status** command from the SDK rpc client tools, which prints information about the status of the connected [`Node`](../core/node.md). The Status of a node includes [`NodeInfo`](https://github.com/tendermint/tendermint/blob/master/p2p/node_info.go#L75-L92), `SyncInfo` and `ValidatorInfo`: this information includes the node ID, latest block hash, and the validator public key and voting power. Here is an example of what the `status command` outputs: -```json -{ - "jsonrpc": "2.0", - "id": "", - "result": { - "node_info": { - "protocol_version": { - "p2p": "4", - "block": "7", - "app": "0" - }, - "id": "53729852020041b956e86685e24394e0bee4373f", - "listen_addr": "10.0.2.15:26656", - "network": "test-chain-Y1OHx6", - "version": "0.24.0-2ce1abc2", - "channels": "4020212223303800", - "moniker": "ubuntu-xenial", - "other": { - "tx_index": "on", - "rpc_addr": "tcp://0.0.0.0:26657" - } - }, - "sync_info": { - "latest_block_hash": "F51538DA498299F4C57AC8162AAFA0254CE08286", - "latest_app_hash": "0000000000000000", - "latest_block_height": "18", - "latest_block_time": "2018-09-17T11:42:19.149920551Z", - "catching_up": false - }, - "validator_info": { - "address": "D9F56456D7C5793815D0E9AF07C3A355D0FC64FD", - "pub_key": { - "type": "tendermint/PubKeyEd25519", - "value": "wVxKNtEsJmR4vvh651LrVoRguPs+6yJJ9Bz174gw9DM=" - }, - "voting_power": "10" - } - } -} -``` +* **Status** command from the SDK rpc client tools, which prints information about the status of the connected [`Node`](../core/node.md). The Status of a node includes `NodeInfo`,`SyncInfo` and `ValidatorInfo`. * **Config** [command](https://github.com/cosmos/cosmos-sdk/blob/master/client/config.go) from the SDK client tools, which allows the user to edit a `config.toml` file that sets values for [flags](#flags) such as `--chain-id` and which `--node` they wish to connect to. The `config` command can be invoked by typing `appcli config` with optional arguments ` [value]` and a `--get` flag to query configurations or `--home` flag to create a new configuration. * **Keys** [commands](https://github.com/cosmos/cosmos-sdk/blob/master/client/keys) from the SDK client tools, which includes a collection of subcommands for using the key functions in the SDK crypto tools, including adding a new key and saving it to disk, listing all public keys stored in the key manager, and deleting a key. @@ -105,154 +69,57 @@ For example, users can type `appcli keys add ` to add a new key and save a * [**Transaction**](#transaction-commands) commands. * [**Query**](#query-commands) commands. -Here is an example from the [nameservice tutorial](https://cosmos.network/docs/tutorial) CLI's `main()` function. It instantiates the root command, adds a [*persistent* flag](#flags) and `PreRun` function to be run before every execution, and adds all of the necessary subcommands. - - -```go -rootCmd := &cobra.Command{ - Use: "nscli", - Short: "nameservice Client", -} -rootCmd.AddCommand( - rpc.StatusCommand(), - client.ConfigCmd(defaultCLIHome), - queryCmd(cdc, mc), - txCmd(cdc, mc), - client.LineBreak, - lcd.ServeCommand(cdc, registerRoutes), - client.LineBreak, - keys.Commands(), - client.LineBreak, -) -``` - -All of these things are done within the `main()` function. At the end of the `main()` function, it is necessary to create an `executor` and `Execute()` the root command in the `main()` function: +Next is an example `main()` function from the `nameservice` application. It instantiates the root command, adds a [*persistent* flag](#flags) and `PreRun` function to be run before every execution, and adds all of the necessary subcommands. -```go -executor := cli.PrepareMainCmd(rootCmd, "NS", defaultCLIHome) -err := executor.Execute() -``` ++++ https://github.com/cosmos/sdk-tutorials/blob/86a27321cf89cc637581762e953d0c07f8c78ece/nameservice/cmd/nscli/main.go#L23-L66 The root-level `status`, `config`, and `keys` subcommands are common across most applications and do not interact with application state. The bulk of an application's functionality - what users can actually *do* with it - is enabled by its transaction commands. ### Transaction Commands -[Transactions](#./transactions.md) are objects wrapping [messages](../building-modules/messages-and-queries.md) that trigger state changes. To enable the creation of transactions using the CLI interface, `TxCmd` typically adds the following commands: +[Transactions](#./transactions.md) are objects wrapping [messages](../building-modules/messages-and-queries.md#messages) that trigger state changes. To enable the creation of transactions using the CLI interface, a function `txCmd` is generally added to the `rootCmd`: -* **Sign** [command](https://github.com/cosmos/cosmos-sdk/blob/master/x/auth/client/cli/tx_sign.go#L30-L83) from the [`auth`](https://github.com/cosmos/cosmos-sdk/tree/master/x/auth/spec) module, the command that signs messages in a transaction. To enable multisig, add the `auth` module [`MultiSign`](https://github.com/cosmos/cosmos-sdk/blob/master/x/auth/client/cli/tx_multisign.go#L26-L151) command. Since every transaction requires some sort of signature in order to be valid, this command is necessary for every application. -* **Broadcast** [command](https://github.com/cosmos/cosmos-sdk/blob/master/client/context/broadcast.go) from the SDK client tools, which broadcasts transactions. -* **Send** [command](https://github.com/cosmos/cosmos-sdk/blob/master/x/bank/client/cli/tx.go#L31-L60) from the [`bank`](https://github.com/cosmos/cosmos-sdk/tree/master/x/bank/spec) module, which is a transaction that allows accounts to send coins to one another, including gas and fees for transactions. -* All [module transaction commands](../building-modules/module-interfaces.md) the application is dependent on, retrieved by calling [`GetTxCmd()`](../building-modules/module-interfaces.md#GetTxCmd) on all the modules or using the Module Manager's [`AddTxCommands()`](../building-modules/module-manager.md) function. ++++ https://github.com/cosmos/sdk-tutorials/blob/86a27321cf89cc637581762e953d0c07f8c78ece/nameservice/cmd/nscli/main.go#L51 -Here is an example of a `TxCmd` aggregating these subcommands from the [nameservice tutorial](https://cosmos.network/docs/tutorial). +This `txCmd` function adds all the transaction available to end-users for the application. This typically includes: -```go -func txCmd(cdc *amino.Codec, mc []sdk.ModuleClients) *cobra.Command { - txCmd := &cobra.Command{ - Use: "tx", - Short: "Transactions subcommands", - } +* **Sign command** from the [`auth`](https://github.com/cosmos/cosmos-sdk/tree/master/x/auth/spec) module that signs messages in a transaction. To enable multisig, add the `auth` module's `MultiSign` command. Since every transaction requires some sort of signature in order to be valid, thithe signing command is necessary for every application. +* **Broadcast command** from the SDK client tools, to broadcast transactions. +* **Send command** from the [`bank`](https://github.com/cosmos/cosmos-sdk/tree/master/x/bank/spec) module, which is a transaction that allows accounts to send coins to one another, including gas and fees for transactions. +* **All [module transaction commands](../building-modules/module-interfaces.md#transaction-commands)** the application is dependent on, retrieved by using the [basic module manager's](../building-modules/module-manager.md#basic-manager) `AddTxCommands()` function. - txCmd.AddCommand( - bankcmd.SendTxCmd(cdc), - client.LineBreak, - authcmd.GetSignCommand(cdc), - tx.GetBroadcastCommand(cdc), - client.LineBreak, - ) +Here is an example of a `txCmd` aggregating these subcommands from the `nameservice` application: - for _, m := range mc { - txCmd.AddCommand(m.GetTxCmd()) - } - - return txCmd -} -``` ++++ https://github.com/cosmos/sdk-tutorials/blob/86a27321cf89cc637581762e953d0c07f8c78ece/nameservice/cmd/nscli/main.go#L97-L118 ### Query Commands -[**Queries**](../building-modules/messages-and-queries.md#queries) are objects that allow users to retrieve information about the application's state. To enable basic queries, `QueryCmd` typically adds the following commands: - -* **QueryTx** and/or other transaction [query commands](https://github.com/cosmos/cosmos-sdk/blob/master/x/auth/client/cli/query.go) from the `auth` module which allow the user to search for a transaction by inputting its hash, a list of tags, or a block height. These queries allow users to see if transactions have been included in a block. -* **Account** [command](https://github.com/cosmos/cosmos-sdk/blob/master/x/auth/client/cli/query.go#L45-L73) from the `auth` module, which displays the state (e.g. account balance) of an account given an address. -* **Validator** [command](https://github.com/cosmos/cosmos-sdk/blob/master/client/rpc/validators.go) from the SDK rpc client tools, which displays the validator set of a given height. -* **Block** [command](https://github.com/cosmos/cosmos-sdk/blob/master/client/rpc/block.go) from the SDK rpc client tools, which displays the block data for a given height. -* All [module query commands](../building-modules/module-interfaces.md) the application is dependent on, retrieved by calling [`GetQueryCmd()`](../building-modules/module-interfaces.md#GetqueryCmd) on all the modules or using the Module Manager's `AddQueryCommands()` function. - -Here is an example of a `QueryCmd` aggregating subcommands, also from the nameservice tutorial (it is structurally identical to `TxCmd`): - -```go -func queryCmd(cdc *amino.Codec, mc []sdk.ModuleClients) *cobra.Command { - queryCmd := &cobra.Command{ - Use: "query", - Aliases: []string{"q"}, - Short: "Querying subcommands", - } - - queryCmd.AddCommand( - rpc.ValidatorCommand(cdc), - rpc.BlockCommand(), - tx.SearchTxCmd(cdc), - tx.QueryTxCmd(cdc), - client.LineBreak, - authcmd.GetAccountCmd(storeAcc, cdc), - ) - - for _, m := range mc { - queryCmd.AddCommand(m.GetQueryCmd()) - } - - return queryCmd -} -``` - -## Flags - -Flags are used to modify commands; developers can include them in a `flags.go` file with their CLI. Users can explicitly include them in commands or pre-configure them by entering a command in the format `appcli config ` into their command line. Commonly pre-configured flags include the `--node` to connect to and `--chain-id` of the blockchain the user wishes to interact with. - -A *persistent* flag (as opposed to a _local_ flag) added to a command transcends all of its children: subcommands will inherit the configured values for these flags. Additionally, all flags have default values when they are added to commands; some toggle an option off but others are empty values that the user needs to override to create valid commands. A flag can be explicitly marked as _required_ so that an error is automatically thrown if the user does not provide a value, but it is also acceptable to handle unexpected missing flags differently. - -### Creating Flags - -Every flag has a name the user types to include the flag. For example, the commonly used `--from` flag is declared as a constant in the SDK [flags](https://github.com/cosmos/cosmos-sdk/blob/master/client/flags/flags.go) file: - -```go -const FlagFrom = "from" -``` - -The flag can be added to a command `cmd` right after the command is created, adding a default value and description: - -```go -cmd.Flags().String(FlagFrom, "", "Name or address of private key with which to sign") -``` +[**Queries**](../building-modules/messages-and-queries.md#queries) are objects that allow users to retrieve information about the application's state. To enable the creation of transactions using the CLI interface, a function `txCmd` is generally added to the `rootCmd`: -The SDK client package includes a list of [flags](https://github.com/cosmos/cosmos-sdk/blob/master/client/flags/flags.go) that are commonly used across existing commands. Developers are free to create their own custom flags, following this format. ++++ https://github.com/cosmos/sdk-tutorials/blob/86a27321cf89cc637581762e953d0c07f8c78ece/nameservice/cmd/nscli/main.go#L50 -### Root Command Flags +This `queryCmd` function adds all the queries available to end-users for the application. This typically includes: -It is common to add a _persistent_ flag for `--chain-id`, the unique identifier of the blockchain the application pertains to, to the root command. Adding this flag can be done in the `main()` function. Adding this flag makes sense as the chain ID should not be changing across commands in this application CLI. Here is what that looks like: +* **QueryTx** and/or other transaction query commands] from the `auth` module which allow the user to search for a transaction by inputting its hash, a list of tags, or a block height. These queries allow users to see if transactions have been included in a block. +* **Account command** from the `auth` module, which displays the state (e.g. account balance) of an account given an address. +* **Validator command** from the SDK rpc client tools, which displays the validator set of a given height. +* **Block command** from the SDK rpc client tools, which displays the block data for a given height. +* **All [module query commands](../building-modules/module-interfaces.md#query-commands)** the application is dependent on, retrieved by using the [basic module manager's](../building-modules/module-manager.md#basic-manager) `AddQueryCommands()` function. -```go -rootCmd.PersistentFlags().String(client.FlagChainID, "", "Chain ID of tendermint node") -``` +Here is an example of a `queryCmd` aggregating subcommands from the `nameservice` application: -### Transaction and Query Flags ++++ https://github.com/cosmos/sdk-tutorials/blob/86a27321cf89cc637581762e953d0c07f8c78ece/nameservice/cmd/nscli/main.go#L74-L95 -To create a transaction, users enter a `tx` command and provide several flags. The SDK `./client/flags` package [`PostCommands()`](https://github.com/cosmos/cosmos-sdk/blob/master/client/flags/flags.go#L85-L116) function adds a set of basic flags to every transaction command. For queries, the [`GetCommand()`](https://github.com/cosmos/cosmos-sdk/blob/master/client/flags/flags.go#L67-L82) function adds basic flags to query commands, such as the block `--height` to query from. +## Flags -For example, the following command creates a transaction to send 1000uatom from `sender-address` to `recipient-address`. The user is willing to pay 0.025uatom per unit gas but wants the transaction to be only generated offline (i.e. not broadcasted) and written, in JSON format, to the file `myUnsignedTx.json`. +Flags are used to modify commands; developers can include them in a `flags.go` file with their CLI. Users can explicitly include them in commands or pre-configure them by entering a command in the format `appcli config ` into their command line. Commonly pre-configured flags include the `--node` to connect to and `--chain-id` of the blockchain the user wishes to interact with. -```bash -appcli tx send 1000uatom --from --gas auto -gas-prices 0.025uatom --generate-only > myUnsignedTx.json -``` +A *persistent* flag (as opposed to a _local_ flag) added to a command transcends all of its children: subcommands will inherit the configured values for these flags. Additionally, all flags have default values when they are added to commands; some toggle an option off but others are empty values that the user needs to override to create valid commands. A flag can be explicitly marked as _required_ so that an error is automatically thrown if the user does not provide a value, but it is also acceptable to handle unexpected missing flags differently. -Here are the flags used: +Flags are added to commands directly (generally in the [module's CLI file](../building-modules/module-interfaces.md#flags) where module commands are defined) and no flag except for the `rootCmd` persistent flags has to be added at application level. It is common to add a _persistent_ flag for `--chain-id`, the unique identifier of the blockchain the application pertains to, to the root command. Adding this flag can be done in the `main()` function. Adding this flag makes sense as the chain ID should not be changing across commands in this application CLI. Here is an example from the `nameservice` application: -* `--from` indicates which [account](../basics/accounts.md) the transaction originates from. This account is used to sign the transaction. -* `--gas` refers to how much [gas](../basics/gas-fees.md), which represents computational resources, Tx consumes. Gas is dependent on the computational needs of the transaction and is not precisely calculated until execution, but can be estimated by providing auto as the value for --gas. -* `--gas-prices` specifies how much the user is willing pay per unit of gas, which can be one or multiple denominations of tokens. For example, --gas-prices=0.025uatom, 0.025upho means the user is willing to pay 0.025uatom AND 0.025upho per unit of gas. -* `--generate-only` (optional) instructs the application to simply generate the unsigned transaction and output or write to a file. Without this flag, the transaction is created, signed, and broadcasted all in one command. ++++ https://github.com/cosmos/sdk-tutorials/blob/86a27321cf89cc637581762e953d0c07f8c78ece/nameservice/cmd/nscli/main.go#L41 ## Configurations @@ -265,36 +132,9 @@ The last function to define in `main.go` is `initConfig`, which does exactly wha Here is an example of an `initConfig()` function from the [nameservice tutorial CLI](https://cosmos.network/docs/tutorial/entrypoint.html#nscli): -```go -func initConfig(cmd *cobra.Command) error { - home, err := cmd.PersistentFlags().GetString(cli.HomeFlag) - if err != nil { - return err - } - - cfgFile := path.Join(home, "config", "config.toml") - if _, err := os.Stat(cfgFile); err == nil { - viper.SetConfigFile(cfgFile) - - if err := viper.ReadInConfig(); err != nil { - return err - } - } - if err := viper.BindPFlag(client.FlagChainID, cmd.PersistentFlags().Lookup(client.FlagChainID)); err != nil { - return err - } - if err := viper.BindPFlag(cli.EncodingFlag, cmd.PersistentFlags().Lookup(cli.EncodingFlag)); err != nil { - return err - } - return viper.BindPFlag(cli.OutputFlag, cmd.PersistentFlags().Lookup(cli.OutputFlag)) -} -``` ++++ https://github.com/cosmos/sdk-tutorials/blob/86a27321cf89cc637581762e953d0c07f8c78ece/nameservice/cmd/nscli/main.go#L120-L141 -Here is an example of how to add `initConfig` as a `PersistentPreRunE` to the root command: +And an example of how to add `initConfig` as a `PersistentPreRunE` to the root command: -```go -rootCmd.PersistentPreRunE = func(_ *cobra.Command, _ []string) error { - return initConfig(rootCmd) -} -``` ++++ https://github.com/cosmos/sdk-tutorials/blob/86a27321cf89cc637581762e953d0c07f8c78ece/nameservice/cmd/nscli/main.go#L42-L44 diff --git a/docs/interfaces/interfaces-intro.md b/docs/interfaces/interfaces-intro.md index 1e12a1a89a7c..a94729f6b842 100644 --- a/docs/interfaces/interfaces-intro.md +++ b/docs/interfaces/interfaces-intro.md @@ -25,7 +25,7 @@ The process of creating an application interface is distinct from creating a [mo With regards to interfaces, module developers need to include the following definitions: -* **CLI commands:** Specifically, [Transaction commands](../building-modules/module-interfaces.md#transaction-commands) and [Query commands](../building-modules/module-interfaces.md#query-commands). These are commands that users will invoke when interacting with the application to create transactions and queries. For example, if an application enables sending coins through the [`auth`](https://github.com/cosmos/cosmos-sdk/tree/67f6b021180c7ef0bcf25b6597a629aca27766b8/docs/spec/auth) module, users will create `tx auth send` transactions. +* **CLI commands:** Specifically, [Transaction commands](../building-modules/module-interfaces.md#transaction-commands) and [Query commands](../building-modules/module-interfaces.md#query-commands). These are commands that users will invoke when interacting with the application to create transactions and queries. For example, if an application enables sending coins through the [`auth`](https://github.com/cosmos/cosmos-sdk/tree/master/x/auth/spec) module, users will create `tx auth send` transactions. * **Request Handlers:** Also categorized into Transaction and Query requests. Transactions will require HTTP [Request Types](../building-modules/module-interfaces.md#request-types) in addition to [Request Handlers](../building-modules/module-interfaces.md#request-handlers) in order to encapsulate all of the user's options (e.g. gas prices). * **REST Routes:** Given a router, the module interface registers paths with the aforementioned [Request Handlers](../building-modules/module-interfaces.md#request-handlers) for each type of request. diff --git a/docs/interfaces/query-lifecycle.md b/docs/interfaces/query-lifecycle.md index cebb86c26165..564c2078d9e6 100644 --- a/docs/interfaces/query-lifecycle.md +++ b/docs/interfaces/query-lifecycle.md @@ -26,7 +26,9 @@ The main interface for an application is the command-line interface. Users conne appcli query staking delegations ``` -This query command was defined by the [`staking`](https://github.com/cosmos/cosmos-sdk/tree/master/x/staking/spec) module developer and added to the list of subcommands by the application developer when creating the CLI. The code for this particular command can be found [here](https://github.com/cosmos/cosmos-sdk/blob/master/x/staking/client/cli/query.go#L253-L294). +This query command was defined by the [`staking`](https://github.com/cosmos/cosmos-sdk/tree/master/x/staking/spec) module developer and added to the list of subcommands by the application developer when creating the CLI. The code for this particular command is the following: + ++++ https://github.com/cosmos/cosmos-sdk/blob/master/x/staking/client/cli/query.go#L253-L294 Note that the general format is as follows: @@ -48,7 +50,11 @@ GET http://localhost:{PORT}/staking/delegators/{delegatorAddr}/delegations To provide values such as `--node` (the full-node the CLI connects to) that are required by [`baseReq`](../building-modules/module-interfaces.md#basereq), the user must configure their local REST server with the values or provide them in the request body. -The router automatically routes the `Query` HTTP request to the staking module `delegatorDelegationsHandlerFn()` function (to see the handler itself, click [here](https://github.com/cosmos/cosmos-sdk/blob/master/x/staking/client/rest/query.go#L103-L106)). Since this function is defined within the module and thus has no inherent knowledge of the application `Query` belongs to, it takes in the application `codec` and `CLIContext` as parameters. +The router automatically routes the `Query` HTTP request to the staking module `delegatorDelegationsHandlerFn()` function. + ++++ https://github.com/cosmos/cosmos-sdk/blob/master/x/staking/client/rest/query.go#L103-L106 + +Since this function is defined within the module and thus has no inherent knowledge of the application `Query` belongs to, it takes in the application `codec` and `CLIContext` as parameters. To summarize, when users interact with the interfaces, they create a CLI command or HTTP request. `Query` now exists in one of these two forms, but needs to be transformed into an object understood by a full-node. @@ -62,13 +68,14 @@ The first thing that is created in the execution of a CLI command is a `CLIConte * **Codec**: The [encoder/decoder](../core/encoding.md) used by the application, used to marshal the parameters and query before making the Tendermint RPC request and unmarshal the returned response into a JSON object. * **Account Decoder**: The account decoder from the [`auth`](https://github.com/cosmos/cosmos-sdk/tree/master/x/auth/spec) module, which translates `[]byte`s into accounts. -* **RPC Client**: The [Tendermint RPC Client](https://github.com/tendermint/tendermint/blob/bc572217c07b90ad9cee851f193aaa8e9557cbc7/rpc/client/interface.go), or node, to which the request will be relayed to. +* **RPC Client**: The Tendermint RPC Client, or node, to which the request will be relayed to. * **Keybase**: A [Key Manager](../basics/accounts.md#keybase) used to sign transactions and handle other operations with keys. * **Output Writer**: A [Writer](https://golang.org/pkg/io/#Writer) used to output the response. * **Configurations**: The flags configured by the user for this command, including `--height`, specifying the height of the blockchain to query and `--indent`, which indicates to add an indent to the JSON response. -The `CLIContext` also contains various functions such as `Query()` which retrieves the RPC Client and makes an ABCI call to relay a query to a full-node. For full specification of the `CLIContext` type, click [here](https://github.com/cosmos/cosmos-sdk/blob/master/client/context/context.go#L36-L59). +The `CLIContext` also contains various functions such as `Query()` which retrieves the RPC Client and makes an ABCI call to relay a query to a full-node. ++++ https://github.com/cosmos/cosmos-sdk/blob/master/client/context/context.go#L36-L59 The `CLIContext`'s primary role is to store data used during interactions with the end-user and provide methods to interact with this data - it is used before and after the query is processed by the full-node. Specifically, in handling `Query`, the `CLIContext` is utilized to encode the query parameters, retrieve the full-node, and write the output. Prior to being relayed to a full-node, the query needs to be encoded into a `[]byte` form, as full-nodes are application-agnostic and do not understand specific types. The full-node (RPC Client) itself is retrieved using the `CLIContext`, which knows which node the user CLI is connected to. The query is relayed to this full-node to be processed. Finally, the `CLIContext` contains a `Writer` to write output when the response is returned. These steps are further described in later sections. @@ -76,9 +83,9 @@ The `CLIContext`'s primary role is to store data used during interactions with t At this point in the lifecycle, the user has created a CLI command or HTTP Request with all of the data they wish to include in their `Query`. A `CLIContext` exists to assist in the rest of the `Query`'s journey. Now, the next step is to parse the command or request, extract the arguments, create a `queryRoute`, and encode everything. These steps all happen on the user side within the interface they are interacting with. -#### Parse Arguments +#### Encoding -In this case, `Query` contains an [address](../basics/accounts.md#addresses) `delegatorAddress` as its only argument. However, the request can only contain `[]byte`s, as it will be relayed to a consensus engine (e.g. Tendermint Core) of a full-node that has no inherent knowledge of the application types. Thus, the `codec` of `CLIContext` is used to marshal the address as the type [`QueryDelegatorParams`](https://github.com/cosmos/cosmos-sdk/blob/master/x/staking/types/querier.go#L30-L38). All query arguments have their own types that the application `codec` understands how to encode and decode. For example, the [`staking`](https://github.com/cosmos/cosmos-sdk/tree/master/x/staking/spec) module also has [`QueryValidatorParams`](https://github.com/cosmos/cosmos-sdk/blob/master/x/staking/types/querier.go#L45-L53) and [`QueryBondsParams`](https://github.com/cosmos/cosmos-sdk/blob/master/x/staking/types/querier.go#L59-L69). The module [`querier`](../building-modules/querier.md) declares these types and the application registers the `codec`s. +In this case, `Query` contains an [address](../basics/accounts.md#addresses) `delegatorAddress` as its only argument. However, the request can only contain `[]byte`s, as it will be relayed to a consensus engine (e.g. Tendermint Core) of a full-node that has no inherent knowledge of the application types. Thus, the `codec` of `CLIContext` is used to marshal the address. Here is what the code looks like for the CLI command: @@ -116,16 +123,9 @@ Now, `Query` exists as a set of encoded arguments and a route to a specific modu The `CLIContext` has a `Query()` function used to retrieve the pre-configured node and relay a query to it; the function takes the query `route` and arguments as parameters. It first retrieves the RPC Client (called the [**node**](../core/node.md)) configured by the user to relay this query to, and creates the `ABCIQueryOptions` (parameters formatted for the ABCI call). The node is then used to make the ABCI call, `ABCIQueryWithOptions()`. -Here is what the code looks like (for full specification of all `CLIContext` query functionality, click [here](https://github.com/cosmos/cosmos-sdk/blob/master/client/context/query.go)): +Here is what the code looks like: -```go -node, err := ctx.GetNode() -opts := rpcclient.ABCIQueryOptions{ - Height: ctx.Height, - Prove: !ctx.TrustNode, -} -result, err := node.ABCIQueryWithOptions(path, key, opts) -``` ++++ https://github.com/cosmos/cosmos-sdk/blob/master/client/context/query.go#L80-L112 ## RPC @@ -143,15 +143,21 @@ Once a result is received from the querier, `baseapp` begins the process of retu ## Response -Since `Query()` is an ABCI function, `baseapp` returns the response as an [`abci.ResponseQuery`](https://tendermint.com/docs/spec/abci/abci.html#messages) type. The `CLIContext` `Query()` routine receives the response and, if `--trust-node` is toggled to `false` and a proof needs to be verified, the response is verified with the `CLIContext` [`verifyProof()`](https://github.com/cosmos/cosmos-sdk/blob/master/client/context/query.go#L136-L173) function before the response is returned. +Since `Query()` is an ABCI function, `baseapp` returns the response as an [`abci.ResponseQuery`](https://tendermint.com/docs/spec/abci/abci.html#messages) type. The `CLIContext` `Query()` routine receives the response and, if `--trust-node` is toggled to `false` and a proof needs to be verified, the response is verified with the `CLIContext` `verifyProof()` function before the response is returned. + ++++ https://github.com/cosmos/cosmos-sdk/blob/master/client/context/query.go#L136-L173 ### CLI Response -The application [`codec`](../core/encoding.md) is used to unmarshal the response to a JSON and the `CLIContext` prints the output to the command line, applying any configurations such as `--indent`. To see the code, click [here](https://github.com/cosmos/cosmos-sdk/blob/master/x/staking/client/cli/query.go#L252-L293). +The application [`codec`](../core/encoding.md) is used to unmarshal the response to a JSON and the `CLIContext` prints the output to the command line, applying any configurations such as `--indent`. + ++++ https://github.com/cosmos/cosmos-sdk/blob/master/x/staking/client/cli/query.go#L252-L293 ### REST Response -The [REST server](./rest.md#rest-server) uses the `CLIContext` to format the response properly, then uses the HTTP package to write the appropriate response or error. To see the code, click [here](https://github.com/cosmos/cosmos-sdk/blob/master/x/staking/client/rest/utils.go#L115-L148). +The [REST server](./rest.md#rest-server) uses the `CLIContext` to format the response properly, then uses the HTTP package to write the appropriate response or error. + ++++ https://github.com/cosmos/cosmos-sdk/blob/master/x/staking/client/rest/utils.go#L115-L148 ## Next diff --git a/x/README.md b/x/README.md index b81ce0e306d6..bdb5ae2f4fc0 100644 --- a/x/README.md +++ b/x/README.md @@ -1,4 +1,4 @@ -# Modules +# List of Modules This repository contains a working implementation of modules that can be used in Cosmos SDK applications, along with their respective documentation. From 47d3115cafaf3120780e1c9bb3e21de5dd6a2b9e Mon Sep 17 00:00:00 2001 From: Denis Fadeev Date: Sat, 16 Nov 2019 11:10:35 +0500 Subject: [PATCH 161/196] modules readme --- docs/.vuepress/config.js | 4 ---- docs/modules/readme.md | 2 +- 2 files changed, 1 insertion(+), 5 deletions(-) diff --git a/docs/.vuepress/config.js b/docs/.vuepress/config.js index 147dfce58969..826f1739734b 100644 --- a/docs/.vuepress/config.js +++ b/docs/.vuepress/config.js @@ -23,10 +23,6 @@ module.exports = { directory: true, path: "/modules" }, - { - title: "Modules README", - path: "/modules/" - } ] }, { diff --git a/docs/modules/readme.md b/docs/modules/readme.md index d4995244ce21..a13b9980fd92 100644 --- a/docs/modules/readme.md +++ b/docs/modules/readme.md @@ -1,5 +1,5 @@ --- -order: false +order: 1 parent: order: false --- From d088829c6d904c5870a63e05cc789065c130ee04 Mon Sep 17 00:00:00 2001 From: gamarin Date: Mon, 18 Nov 2019 16:08:10 +0100 Subject: [PATCH 162/196] update docs readme --- CONTRIBUTING.md | 7 +++---- docs/DOCS_README.md | 9 ++++++++- docs/core/transactions.md | 2 +- 3 files changed, 12 insertions(+), 6 deletions(-) diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 07b8b3d94055..139c9a4576ec 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -92,10 +92,9 @@ All PRs require two Reviews before merge (except docs changes, or variable name- If you open a PR on the Cosmos SDK, it is mandatory to update the relevant documentation in /docs. -- If your change relates to the core SDK (baseapp, store, ...), please update the docs/cosmos-hub folder and possibly the docs/spec folder. -- If your changes relate specifically to the gaia application (not including modules), please modify the docs/cosmos-hub folder. -- If your changes relate to a module, please update the module's spec in docs/spec. If the module is used by gaia, you might also need to modify docs/cosmos-hub. -- If your changes relate to the core of the CLI or Light-client (not specifically to module's CLI/Rest), please modify the docs/clients folder. +- If your change relates to the core SDK (baseapp, store, ...), please update the `docs/basics/`, `docs/core/` and/or `docs/building-modules/` folders. +- If your changes relate to the core of the CLI or Light-client (not specifically to module's CLI/Rest), please modify the `docs/interfaces/` folder. +- If your changes relate to a module, please update the module's spec in `x/moduleName/docs/spec/`. ## Forking diff --git a/docs/DOCS_README.md b/docs/DOCS_README.md index c2b7e86ea409..96986bef8030 100644 --- a/docs/DOCS_README.md +++ b/docs/DOCS_README.md @@ -1,6 +1,13 @@ # Updating the docs -If you want to open a PR on the Cosmos SDK to update the documentation, please follow the guidelines in the [`CONTRIBUTING.md`](https://github.com/cosmos/cosmos-sdk/tree/master/CONTRIBUTING.md) +If you want to open a PR on the Cosmos SDK to update the documentation, please follow the guidelines in the [`CONTRIBUTING.md`](https://github.com/cosmos/cosmos-sdk/tree/master/CONTRIBUTING.md#updating-documentation) + +## Translating + +- Docs translations live in a `docs/country-code/` folder, where `country-code` stands for the country code of the language used (`cn` for Chinese, `kr` for Korea, `fr` for France, ...). +- Always translate content living on `master`. +- Only content under `/docs/intro/`, `/docs/basics/`, `/docs/core/`, `/docs/building-modules/` and `docs/interfaces` needs to be translated, as well as `docs/README.md`. It is also nice (but not mandatory) to translate `/docs/spec/`. +- Specify the release/tag of the translation in the README of your translation folder. Update the release/tag each time you update the translation. ## Docs Build Workflow diff --git a/docs/core/transactions.md b/docs/core/transactions.md index 1feeb473f430..b3670f283337 100644 --- a/docs/core/transactions.md +++ b/docs/core/transactions.md @@ -49,7 +49,7 @@ When users interact with the application's interfaces, they invoke the underlyin **`Message`s** are module-specific objects that trigger state transitions within the scope of the module they belong to. Module developers define the `message`s for their module by implementing the `Msg` interface, and also define a [`Handler`](../building-modules/handler.md) to process them. -+++ https://github.com/cosmos/cosmos-sdk/blob/master/types/tx_msg.go#L10-L31 ++++ https://github.com/cosmos/cosmos-sdk/blob/master/types/tx_msg.go#L8-L29 `Message`s in a module are typically defined in a `msgs.go` file (though not always), and one handler with multiple functions to handle each of the module's `message`s is defined in a `handler.go` file. From 6de6087aa1f9afd985facf0c3a26da1891e690ad Mon Sep 17 00:00:00 2001 From: gamarin Date: Mon, 18 Nov 2019 17:18:21 +0100 Subject: [PATCH 163/196] modify synopsis --- docs/basics/accounts.md | 13 +++++++------ docs/basics/app-anatomy.md | 10 ++++------ docs/basics/gas-fees.md | 13 +++++++------ docs/basics/tx-lifecycle.md | 9 +++------ docs/building-modules/beginblock-endblock.md | 9 +++------ docs/building-modules/genesis.md | 11 ++++------- docs/building-modules/handler.md | 11 ++++------- docs/building-modules/intro.md | 11 ++++------- docs/building-modules/invariants.md | 9 +++------ docs/building-modules/keeper.md | 9 +++------ docs/building-modules/messages-and-queries.md | 10 +++------- docs/building-modules/module-interfaces.md | 9 +++------ docs/building-modules/module-manager.md | 9 +++------ docs/building-modules/querier.md | 11 ++++------- docs/building-modules/structure.md | 7 +++---- docs/core/baseapp.md | 13 +++++-------- docs/core/context.md | 9 +++------ docs/core/encoding.md | 7 ++----- docs/core/events.md | 9 +++------ docs/core/node.md | 7 ++----- docs/core/ocap.md | 4 ---- docs/core/store.md | 9 +++------ docs/core/transactions.md | 9 +++------ docs/interfaces/cli.md | 9 +++------ docs/interfaces/interfaces-intro.md | 11 ++++------- docs/interfaces/query-lifecycle.md | 9 +++------ docs/interfaces/rest.md | 9 +++------ 27 files changed, 92 insertions(+), 164 deletions(-) diff --git a/docs/basics/accounts.md b/docs/basics/accounts.md index fb9eafe85ed4..da236468562b 100644 --- a/docs/basics/accounts.md +++ b/docs/basics/accounts.md @@ -1,12 +1,13 @@ -# Accounts - -## Pre-requisite Reading +--- +order: 3 +synopsis: This document describes the in-built accounts system of the Cosmos SDK. +--- -- [Anatomy of an SDK Application](./app-anatomy.md) +# Accounts -## Synopsis +## Pre-requisite Readings -This document describes the in-built accounts system of the Cosmos SDK. +- [Anatomy of an SDK Application](./app-anatomy.md) {prereq} ## Account Definition diff --git a/docs/basics/app-anatomy.md b/docs/basics/app-anatomy.md index 30329dca4821..2a6c5ad831d5 100644 --- a/docs/basics/app-anatomy.md +++ b/docs/basics/app-anatomy.md @@ -1,17 +1,15 @@ --- order: 1 +synopsis: This document describes the core parts of a Cosmos SDK application. Throughout the document, a placeholder application named `app` will be used. --- # Anatomy of an SDK Application -## Pre-requisite reading +## Pre-requisite Readings -- [High-level overview of the architecture of an SDK application](../intro/sdk-app-architecture.md) -- [Cosmos SDK design overview](../intro/sdk-design.md) +- [High-level overview of the architecture of an SDK application](../intro/sdk-app-architecture.md) {prereq} +- [Cosmos SDK design overview](../intro/sdk-design.md) {prereq} -## Synopsis - -This document describes the core parts of a Cosmos SDK application. Throughout the document, a placeholder application named `app` will be used. ## Node Client diff --git a/docs/basics/gas-fees.md b/docs/basics/gas-fees.md index 0e7d99aff8f8..d2ba585bfabe 100644 --- a/docs/basics/gas-fees.md +++ b/docs/basics/gas-fees.md @@ -1,12 +1,13 @@ -# Gas and Fees - -## Pre-requisite Reading +--- +order: 4 +synopsis: This document describes the default strategies to handle gas and fees within a Cosmos SDK application. +--- -- [Anatomy of an SDK Application](./app-anatomy.md) +# Gas and Fees -## Synopsis +## Pre-requisite Readings -This document describes the default strategies to handle gas and fees within a Cosmos SDK application. +- [Anatomy of an SDK Application](./app-anatomy.md) {prereq} ## Introduction to `Gas` and `Fees` diff --git a/docs/basics/tx-lifecycle.md b/docs/basics/tx-lifecycle.md index c964ad2addaf..c9c64cc895b1 100644 --- a/docs/basics/tx-lifecycle.md +++ b/docs/basics/tx-lifecycle.md @@ -1,16 +1,13 @@ --- order: 2 +synopsis: This document describes the lifecycle of a transaction from creation to committed state changes. Transaction definition is described in a [different doc](../core/transactions.md). The transaction will be referred to as `Tx`. --- # Transaction Lifecycle -## Prerequisite Reading +## Pre-requisite Readings -- [Anatomy of an SDK Application](./app-anatomy.md) - -## Synopsis - -This document describes the lifecycle of a transaction from creation to committed state changes. Transaction definition is described in a [different doc](../core/transactions.md). The transaction will be referred to as `Tx`. +- [Anatomy of an SDK Application](./app-anatomy.md) {prereq} ## Creation diff --git a/docs/building-modules/beginblock-endblock.md b/docs/building-modules/beginblock-endblock.md index d8959dba9490..baeb237c44e5 100644 --- a/docs/building-modules/beginblock-endblock.md +++ b/docs/building-modules/beginblock-endblock.md @@ -1,16 +1,13 @@ --- order: 6 +synopsis: `BeginBlocker` and `EndBlocker` are optional methods module developers can implement in their module. They will be triggered at the beginning and at the end of each block respectively, when the [`BeginBlock`](../core/baseapp.md#beginblock) and [`EndBlock`](../core/baseapp.md#endblock) ABCI messages are received from the underlying consensus engine. --- # BeginBlocker and EndBlocker -## Pre-requisite Reading +## Pre-requisite Readings -- [Module Manager](./module-manager.md) - -## Synopsis - -`BeginBlocker` and `EndBlocker` are optional methods module developers can implement in their module. They will be triggered at the beginning and at the end of each block respectively, when the [`BeginBlock`](../core/baseapp.md#beginblock) and [`EndBlock`](../core/baseapp.md#endblock) ABCI messages are received from the underlying consensus engine. +- [Module Manager](./module-manager.md) {prereq} ## BeginBlocker and EndBlocker diff --git a/docs/building-modules/genesis.md b/docs/building-modules/genesis.md index a16037680740..38a1a3715261 100644 --- a/docs/building-modules/genesis.md +++ b/docs/building-modules/genesis.md @@ -1,17 +1,14 @@ --- order: 9 +synopsis: Modules generally handle a subset of the state and, as such, they need to define the related subset of the genesis file as well as methods to initialize, verify and export it. --- # Module Genesis -## Pre-requisite Reading +## Pre-requisite Readings -- [Module Manager](./module-manager.md) -- [Keepers](./keeper.md) - -## Synopsis - -Modules generally handle a subset of the state and, as such, they need to define the related subset of the genesis file as well as methods to initialize, verify and export it. +- [Module Manager](./module-manager.md) {prereq} +- [Keepers](./keeper.md) {prereq} ## Type Definition diff --git a/docs/building-modules/handler.md b/docs/building-modules/handler.md index 5d573f598fdd..6f2d56d83b3f 100644 --- a/docs/building-modules/handler.md +++ b/docs/building-modules/handler.md @@ -1,17 +1,14 @@ --- order: 4 +synopsis: A `Handler` designates a function that processes [`message`s](./messages-and-queries.md#messages). `Handler`s are specific to the module in which they are defined, and only process `message`s defined within the said module. They are called from `baseapp` during [`DeliverTx`](../core/baseapp.md#delivertx). --- # Handlers -## Pre-requisite Reading +## Pre-requisite Readings -- [Module Manager](./module-manager.md) -- [Messages and Queries](./messages-and-queries.md) - -## Synopsis - -A `Handler` designates a function that processes [`message`s](./messages-and-queries.md#messages). `Handler`s are specific to the module in which they are defined, and only process `message`s defined within the said module. They are called from `baseapp` during [`DeliverTx`](../core/baseapp.md#delivertx). +- [Module Manager](./module-manager.md) {prereq} +- [Messages and Queries](./messages-and-queries.md) {prereq} ## `handler` type diff --git a/docs/building-modules/intro.md b/docs/building-modules/intro.md index 30d720dee83f..6a386ed60228 100644 --- a/docs/building-modules/intro.md +++ b/docs/building-modules/intro.md @@ -1,17 +1,14 @@ --- order: 1 +synopsis: Modules define most of the logic of SDK applications. Developers compose module together using the Cosmos SDK to build their custom application-specific blockchains. This document outlines the basic concepts behind SDK modules and how to approach module management. --- # Introduction to SDK Modules -## Pre-requisite Reading +## Pre-requisite Readings -- [Anatomy of an SDK application](../basics/app-anatomy.md) -- [Lifecycle of an SDK transaction](../basics/tx-lifecycle.md) - -## Synopsis - -Modules define most of the logic of SDK applications. Developers compose module together using the Cosmos SDK to build their custom application-specific blockchains. This document outlines the basic concepts behind SDK modules and how to approach module management. +- [Anatomy of an SDK application](../basics/app-anatomy.md) {prereq} +- [Lifecycle of an SDK transaction](../basics/tx-lifecycle.md) {prereq} ## Role of Modules in an SDK Application diff --git a/docs/building-modules/invariants.md b/docs/building-modules/invariants.md index f0152a07ff09..a80378469b75 100644 --- a/docs/building-modules/invariants.md +++ b/docs/building-modules/invariants.md @@ -1,16 +1,13 @@ --- order: 8 +synopsis: An invariant is a property of the application that should always be true. In the context of the Cosmos SDK, an `Invariant` is a function that checks for a particular invariant. These functions are useful to detect bugs early on and act upon them to limit their potential consequences (e.g. by halting the chain). They are also useful in the development process of the application to detect bugs via simulations. --- # Invariants -## Pre-requisite Reading +## Pre-requisite Readings -- [Keepers](./keeper.md) - -## Synopsis - -An invariant is a property of the application that should always be true. In the context of the Cosmos SDK, an `Invariant` is a function that checks for a particular invariant. These functions are useful to detect bugs early on and act upon them to limit their potential consequences (e.g. by halting the chain). They are also useful in the development process of the application to detect bugs via simulations. +- [Keepers](./keeper.md) {prereq} ## Implementing `Invariant`s diff --git a/docs/building-modules/keeper.md b/docs/building-modules/keeper.md index 0928aac191d0..d33df9445ce3 100644 --- a/docs/building-modules/keeper.md +++ b/docs/building-modules/keeper.md @@ -1,16 +1,13 @@ --- order: 7 +synopsis: `Keeper`s refer to a Cosmos SDK abstraction whose role is to manage access to the subset of the state defined by various modules. `Keeper`s are module-specific, i.e. the subset of state defined by a module can only be accessed by a `keeper` defined in said module. If a module needs to access the subset of state defined by another module, a reference to the second module's internal `keeper` needs to be passed to the first one. This is done in `app.go` during the instantiation of module keepers. --- # Keepers -## Pre-requisite Reading +## Pre-requisite Readings -- [Introduction to SDK Modules](./intro.md) - -## Synopsis - -`Keeper`s refer to a Cosmos SDK abstraction whose role is to manage access to the subset of the state defined by various modules. `Keeper`s are module-specific, i.e. the subset of state defined by a module can only be accessed by a `keeper` defined in said module. If a module needs to access the subset of state defined by another module, a reference to the second module's internal `keeper` needs to be passed to the first one. This is done in `app.go` during the instantiation of module keepers. +- [Introduction to SDK Modules](./intro.md) {prereq} ## Motivation diff --git a/docs/building-modules/messages-and-queries.md b/docs/building-modules/messages-and-queries.md index 87ae0899a555..229c8d77b34b 100644 --- a/docs/building-modules/messages-and-queries.md +++ b/docs/building-modules/messages-and-queries.md @@ -1,17 +1,13 @@ --- order: 3 +synopsis: `Message`s and `Queries` are the two primary objects handled by modules. Most of the core components defined in a module, like `handler`s, `keeper`s and `querier`s, exist to process `message`s and `queries`. --- - # Messages and Queries -## Pre-requisite Reading - -- [Introduction to SDK Modules](./intro.md) - -## Synopsis +## Pre-requisite Readings -`Message`s and `Queries` are the two primary objects handled by modules. Most of the core components defined in a module, like `handler`s, `keeper`s and `querier`s, exist to process `message`s and `queries`. +- [Introduction to SDK Modules](./intro.md) {prereq} ## Messages diff --git a/docs/building-modules/module-interfaces.md b/docs/building-modules/module-interfaces.md index b866a98f7d1e..a6d412d6a0b6 100644 --- a/docs/building-modules/module-interfaces.md +++ b/docs/building-modules/module-interfaces.md @@ -1,16 +1,13 @@ --- order: 11 +synopsis: This document details how to build CLI and REST interfaces for a module. Examples from various SDK modules are included. --- # Module Interfaces -## Prerequisites +## Pre-requisite Readings -* [Building Modules Intro](./intro.md) - -## Synopsis - -This document details how to build CLI and REST interfaces for a module. Examples from various SDK modules are included. +* [Building Modules Intro](./intro.md) {prereq} ## CLI diff --git a/docs/building-modules/module-manager.md b/docs/building-modules/module-manager.md index 06bde5009643..37174a8313c4 100644 --- a/docs/building-modules/module-manager.md +++ b/docs/building-modules/module-manager.md @@ -1,17 +1,14 @@ --- order: 2 +synopsis: Cosmos SDK modules need to implement the [`AppModule` interfaces](#application-module-interfaces), in order to be managed by the application's [module manager](#module-manager). The module manager plays an important role in [`message` and `query` routing](../core/baseapp.md#routing), and allows application developers to set the order of execution of a variety of functions like [`BeginBlocker` and `EndBlocker`](../basics/app-anatomy.md#begingblocker-and-endblocker). --- # Module Manager -## Pre-requisite Reading +## Pre-requisite Readings -- [Introduction to SDK Modules](./intro.md) - -## Synopsis - -Cosmos SDK modules need to implement the [`AppModule` interfaces](#application-module-interfaces), in order to be managed by the application's [module manager](#module-manager). The module manager plays an important role in [`message` and `query` routing](../core/baseapp.md#routing), and allows application developers to set the order of execution of a variety of functions like [`BeginBlocker` and `EndBlocker`](../basics/app-anatomy.md#begingblocker-and-endblocker). +- [Introduction to SDK Modules](./intro.md) {prereq} ## Application Module Interfaces diff --git a/docs/building-modules/querier.md b/docs/building-modules/querier.md index 3942342ef46c..8fbcafa59b40 100644 --- a/docs/building-modules/querier.md +++ b/docs/building-modules/querier.md @@ -1,17 +1,14 @@ --- order: 5 +synopsis: A `Querier` designates a function that processes [`queries`](./messages-and-queries.md#queries). `querier`s are specific to the module in which they are defined, and only process `queries` defined within said module. They are called from `baseapp`'s [`Query` method](../core/baseapp.md#query). --- # Queriers -## Pre-requisite Reading +## Pre-requisite Readings -- [Module Manager](./module-manager.md). -- [Messages and Queries](./messages-and-queries.md) - -## Synopsis - -A `Querier` designates a function that processes [`queries`](./messages-and-queries.md#queries). `querier`s are specific to the module in which they are defined, and only process `queries` defined within said module. They are called from `baseapp`'s [`Query` method](../core/baseapp.md#query). +- [Module Manager](./module-manager.md) {prereq} +- [Messages and Queries](./messages-and-queries.md) {prereq} ## `Querier` type diff --git a/docs/building-modules/structure.md b/docs/building-modules/structure.md index 0883fefd2aeb..c21bc2af119a 100644 --- a/docs/building-modules/structure.md +++ b/docs/building-modules/structure.md @@ -1,13 +1,12 @@ --- order: 12 +synopsis: This document outlines the recommended structure of Cosmos SDK modules. These +ideas are meant to be applied as suggestions. Application developers are encouraged +to improve upon and contribute to module structure and development design. --- # Recommended Folder Structure -This document outlines the recommended structure of Cosmos SDK modules. These -ideas are meant to be applied as suggestions. Application developers are encouraged -to improve upon and contribute to module structure and development design. - ## Structure A typical Cosmos SDK module can be structured as follows: diff --git a/docs/core/baseapp.md b/docs/core/baseapp.md index 2bcd1d833c9e..4e9951cbb411 100644 --- a/docs/core/baseapp.md +++ b/docs/core/baseapp.md @@ -1,18 +1,15 @@ --- order: 1 +synopsis: This document describes `BaseApp`, the abstraction that implements the core +functionalities of an SDK application. --- # Baseapp -## Pre-requisite Reading - -- [Anatomy of an SDK application](../basics/app-anatomy.md) -- [Lifecycle of an SDK transaction](../basics/tx-lifecycle.md) +## Pre-requisite Readings -## Synopsis - -This document describes `BaseApp`, the abstraction that implements the core -functionalities of an SDK application. +- [Anatomy of an SDK application](../basics/app-anatomy.md) {prereq} +- [Lifecycle of an SDK transaction](../basics/tx-lifecycle.md) {prereq} ## Introduction diff --git a/docs/core/context.md b/docs/core/context.md index b0ca814d7906..aefefdc3d1e6 100644 --- a/docs/core/context.md +++ b/docs/core/context.md @@ -1,17 +1,14 @@ --- order: 3 +synopsis: The `context` is a data structure intended to be passed from function to function that carries information about the current state of the application. It holds a cached copy of the entire state as well as useful objects and information like `gasMeter`, `block height`, `consensus parameters` and more. --- # Context ## Pre-requisites Readings -- [Anatomy of an SDK Application](../basics/app-anatomy.md) -- [Lifecycle of a Transaction](../basics/tx-lifecycle.md) - -## Synopsis - -The `context` is a data structure intended to be passed from function to function that carries information about the current state of the application. It holds a cached copy of the entire state as well as useful objects and information like `gasMeter`, `block height`, `consensus parameters` and more. +- [Anatomy of an SDK Application](../basics/app-anatomy.md) {prereq} +- [Lifecycle of a Transaction](../basics/tx-lifecycle.md) {prereq} ## Context Definition diff --git a/docs/core/encoding.md b/docs/core/encoding.md index 62ee726eefea..65ece87febe6 100644 --- a/docs/core/encoding.md +++ b/docs/core/encoding.md @@ -1,16 +1,13 @@ --- order: 6 +synopsis: The `codec` is used everywhere in the Cosmos SDK to encode and decode structs and interfaces. The specific codec used in the Cosmos SDK is called `go-amino` --- # Encoding ## Pre-requisite Reading -- [Anatomy of an SDK application](../basics/app-anatomy.md) - -## Synopsis - -The `codec` is used everywhere in the Cosmos SDK to encode and decode structs and interfaces. The specific codec used in the Cosmos SDK is called `go-amino`. +- [Anatomy of an SDK application](../basics/app-anatomy.md) {prereq} ## Encoding diff --git a/docs/core/events.md b/docs/core/events.md index ce031a3b608e..87cdd8770442 100644 --- a/docs/core/events.md +++ b/docs/core/events.md @@ -1,16 +1,13 @@ --- order: 7 +synopsis: `Event`s are objects that contain information about the execution of the application. They are mainly used by service providers like block explorers and wallet to track the execution of various messages and index transactions. --- # Events -## Pre-Requisite Reading +## Pre-Requisite Readings -- [Anatomy of an SDK application](../basics/app-anatomy.md) - -## Synopsis - -`Event`s are objects that contain information about the execution of the application. They are mainly used by service providers like block explorers and wallet to track the execution of various messages and index transactions. +- [Anatomy of an SDK application](../basics/app-anatomy.md) {prereq} ## Events diff --git a/docs/core/node.md b/docs/core/node.md index 8c4fb63c7c3b..f7b274095e49 100644 --- a/docs/core/node.md +++ b/docs/core/node.md @@ -1,16 +1,13 @@ --- order: 4 +synopsis: The main endpoint of an SDK application is the daemon client, otherwise known as the full-node client. The full-node runs the state-machine, starting from a genesis file. It connects to peers running the same client in order to receive and relay transactions, block proposals and signatures. The full-node is constituted of the application, defined with the Cosmos SDK, and of a consensus engine connected to the application via the ABCI. --- # Node Client (Daemon) ## Pre-requisite Reading -- [Anatomy of an SDK application](../basics/app-anatomy.md) - -## Synopsis - -The main endpoint of an SDK application is the daemon client, otherwise known as the full-node client. The full-node runs the state-machine, starting from a genesis file. It connects to peers running the same client in order to receive and relay transactions, block proposals and signatures. The full-node is constituted of the application, defined with the Cosmos SDK, and of a consensus engine connected to the application via the ABCI. +- [Anatomy of an SDK application](../basics/app-anatomy.md) {prereq} ## `main` function diff --git a/docs/core/ocap.md b/docs/core/ocap.md index af1350396119..3314d9ca2dcb 100644 --- a/docs/core/ocap.md +++ b/docs/core/ocap.md @@ -4,10 +4,6 @@ order: 8 # Object-Capability Model -## Synopsis - -The Cosmos SDK uses an object-capabilities model - ## Intro When thinking about security, it is good to start with a specific threat model. Our threat model is the following: diff --git a/docs/core/store.md b/docs/core/store.md index ed1f7349b9e1..dcf585fd35ef 100644 --- a/docs/core/store.md +++ b/docs/core/store.md @@ -1,16 +1,13 @@ --- order: 5 +synopsis: A store is a data structure that holds the state of the application. --- # Store -## Pre-requisite Reading +## Pre-requisite Readings -- [Anatomy of an SDK application](../basics/app-anatomy.md) - -## Synopsis - -A store is a data structure that holds the state of the application. +- [Anatomy of an SDK application](../basics/app-anatomy.md) {prereq} ## Introduction to SDK Stores diff --git a/docs/core/transactions.md b/docs/core/transactions.md index b3670f283337..f09b725b6c2e 100644 --- a/docs/core/transactions.md +++ b/docs/core/transactions.md @@ -1,16 +1,13 @@ --- order: 2 +synopsis: `Transactions` are objects created by end-users to trigger state changes in the application. --- # Transactions -## Prerequisites +## Pre-requisite Readings -* [Anatomy of an SDK Application](../basics/app-anatomy.md) - -## Synopsis - -`Transactions` are objects created by end-users to trigger state changes in the application. +* [Anatomy of an SDK Application](../basics/app-anatomy.md) {prereq} ## Transactions diff --git a/docs/interfaces/cli.md b/docs/interfaces/cli.md index cd36c46b06eb..b33c2229f941 100644 --- a/docs/interfaces/cli.md +++ b/docs/interfaces/cli.md @@ -1,16 +1,13 @@ --- order: 3 +synopsis: This document describes how to create a commmand-line interface (CLI) for an [**application**](../basics/app-anatomy.md). A separate document for implementing a CLI for an SDK [**module**](../building-modules/intro.md) can be found [here](#../building-modules/module-interfaces.md#cli). --- # Command-Line Interface -## Prerequisites +## Pre-requisite Readings -* [Lifecycle of a Query](./query-lifecycle.md) - -## Synopsis - -This document describes how to create a commmand-line interface (CLI) for an [**application**](../basics/app-anatomy.md). A separate document for implementing a CLI for an SDK [**module**](../building-modules/intro.md) can be found [here](#../building-modules/module-interfaces.md#cli). +* [Lifecycle of a Query](./query-lifecycle.md) {prereq} ## Command-Line Interface diff --git a/docs/interfaces/interfaces-intro.md b/docs/interfaces/interfaces-intro.md index a94729f6b842..fd9f6702706f 100644 --- a/docs/interfaces/interfaces-intro.md +++ b/docs/interfaces/interfaces-intro.md @@ -1,17 +1,14 @@ --- order: 1 +synopsis: Typically, SDK applications include interfaces to let end-users interact with the application. This document introduces the different types of interfaces for SDK applications. --- # Interfaces -## Prerequisites +## Pre-requisite Readings -* [Anatomy of an SDK Application](../basics/app-anatomy.md) -* [Lifecycle of a Transaction](../basics/tx-lifecycle.md) - -## Synopsis - -Typically, SDK applications include interfaces to let end-users interact with the application. This document introduces the different types of interfaces for SDK applications. +* [Anatomy of an SDK Application](../basics/app-anatomy.md) {prereq} +* [Lifecycle of a Transaction](../basics/tx-lifecycle.md) {prereq} ## Types of Application Interfaces diff --git a/docs/interfaces/query-lifecycle.md b/docs/interfaces/query-lifecycle.md index 564c2078d9e6..20f44cf83d00 100644 --- a/docs/interfaces/query-lifecycle.md +++ b/docs/interfaces/query-lifecycle.md @@ -1,16 +1,13 @@ --- order: 2 +synopsis: This document describes the lifecycle of a query in a SDK application, from the user interface to application stores and back. The query will be referred to as `Query`. --- # Query Lifecycle -## Prerequisites +## Pre-requisite Readings -* [Introduction to Interfaces](./interfaces-intro.md) - -## Synopsis - -This document describes the lifecycle of a query in a SDK application, from the user interface to application stores and back. The query will be referred to as `Query`. +* [Introduction to Interfaces](./interfaces-intro.md) {prereq} ## Query Creation diff --git a/docs/interfaces/rest.md b/docs/interfaces/rest.md index ca64d3e24a00..503e2c3dd394 100644 --- a/docs/interfaces/rest.md +++ b/docs/interfaces/rest.md @@ -1,17 +1,14 @@ --- order: 4 +synopsis: This document describes how to create a REST interface for an SDK **application**. A separate document for creating a [**module**](../building-modules/intro.md) REST interface can be found [here](#../module-interfaces.md#rest). --- # REST Interface ## Prerequisites -* [Query Lifecycle](./query-lifecycle.md) -* [Application CLI](./cli.md) - -## Synopsis - -This document describes how to create a REST interface for an SDK **application**. A separate document for creating a [**module**](../building-modules/intro.md) REST interface can be found [here](#../module-interfaces.md#rest). +* [Query Lifecycle](./query-lifecycle.md) {prereq} +* [Application CLI](./cli.md) {prereq} ## Application REST Interface From 7d62116c91f1d23644d81fd4b4dbbe003a84ee0c Mon Sep 17 00:00:00 2001 From: Denis Fadeev Date: Tue, 19 Nov 2019 12:31:25 +0500 Subject: [PATCH 164/196] version --- docs/.vuepress/config.js | 1 - docs/.vuepress/public/logo-bw.svg | 12 +++--- docs/.vuepress/public/logo.svg | 18 ++++---- docs/package-lock.json | 68 +++++++++++++++++-------------- docs/package.json | 2 +- 5 files changed, 53 insertions(+), 48 deletions(-) diff --git a/docs/.vuepress/config.js b/docs/.vuepress/config.js index 826f1739734b..5516c86f0b08 100644 --- a/docs/.vuepress/config.js +++ b/docs/.vuepress/config.js @@ -12,7 +12,6 @@ module.exports = { docsRepo: "cosmos/cosmos-sdk", docsDir: "docs", editLinks: true, - logo: "/logo.svg", label: "sdk", sidebar: [ { diff --git a/docs/.vuepress/public/logo-bw.svg b/docs/.vuepress/public/logo-bw.svg index e0dfe74053e2..f2575260a761 100644 --- a/docs/.vuepress/public/logo-bw.svg +++ b/docs/.vuepress/public/logo-bw.svg @@ -1,8 +1,8 @@ - - - - - - + + + + + + diff --git a/docs/.vuepress/public/logo.svg b/docs/.vuepress/public/logo.svg index 9e8a005bd9c3..95ca6d30da5b 100644 --- a/docs/.vuepress/public/logo.svg +++ b/docs/.vuepress/public/logo.svg @@ -1,13 +1,13 @@ - + - - - - - - - - + + + + + + + + diff --git a/docs/package-lock.json b/docs/package-lock.json index 9ebc3e17e441..b75b17caa445 100644 --- a/docs/package-lock.json +++ b/docs/package-lock.json @@ -877,9 +877,9 @@ "integrity": "sha512-tHq6qdbT9U1IRSGf14CL0pUlULksvY9OZ+5eEgl1N7t+OA3tGvNpxJCzuKQlsNgCVwbAs670L1vcVQi8j9HjnA==" }, "@types/node": { - "version": "12.12.7", - "resolved": "https://registry.npmjs.org/@types/node/-/node-12.12.7.tgz", - "integrity": "sha512-E6Zn0rffhgd130zbCbAr/JdXfXkoOUFAKNs/rF8qnafSJ8KYaA/j3oz7dcwal+lYjLA7xvdd5J4wdYpCTlP8+w==" + "version": "12.12.9", + "resolved": "https://registry.npmjs.org/@types/node/-/node-12.12.9.tgz", + "integrity": "sha512-kV3w4KeLsRBW+O2rKhktBwENNJuqAUQHS3kf4ia2wIaF/MN6U7ANgTsx7tGremcA0Pk3Yh0Hl0iKiLPuBdIgmw==" }, "@types/q": { "version": "1.5.2", @@ -1491,11 +1491,11 @@ "integrity": "sha512-hHUXGagefjN2iRrID63xckIvotOXOojhQKWIPUZ4mNUZ9nLZW+7FMNoE1lOkEhNWYsx/7ysGIuJYCiMAA9FnrA==" }, "ansi-escapes": { - "version": "4.2.1", - "resolved": "https://registry.npmjs.org/ansi-escapes/-/ansi-escapes-4.2.1.tgz", - "integrity": "sha512-Cg3ymMAdN10wOk/VYfLV7KCQyv7EDirJ64500sU7n9UlmioEtDuU5Gd+hj73hXSU/ex7tHJSssmyftDdkMLO8Q==", + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-escapes/-/ansi-escapes-4.3.0.tgz", + "integrity": "sha512-EiYhwo0v255HUL6eDyuLrXEkTi7WwVCLAw+SeOQ7M7qdun1z1pum4DEm/nuqIVbPvi9RPPc9k9LbyBv6H0DwVg==", "requires": { - "type-fest": "^0.5.2" + "type-fest": "^0.8.1" } }, "ansi-html": { @@ -1680,16 +1680,16 @@ } }, "autoprefixer": { - "version": "9.7.1", - "resolved": "https://registry.npmjs.org/autoprefixer/-/autoprefixer-9.7.1.tgz", - "integrity": "sha512-w3b5y1PXWlhYulevrTJ0lizkQ5CyqfeU6BIRDbuhsMupstHQOeb1Ur80tcB1zxSu7AwyY/qCQ7Vvqklh31ZBFw==", + "version": "9.7.2", + "resolved": "https://registry.npmjs.org/autoprefixer/-/autoprefixer-9.7.2.tgz", + "integrity": "sha512-LCAfcdej1182uVvPOZnytbq61AhnOZ/4JelDaJGDeNwewyU1AMaNthcHsyz1NRjTmd2FkurMckLWfkHg3Z//KA==", "requires": { - "browserslist": "^4.7.2", - "caniuse-lite": "^1.0.30001006", + "browserslist": "^4.7.3", + "caniuse-lite": "^1.0.30001010", "chalk": "^2.4.2", "normalize-range": "^0.1.2", "num2fraction": "^1.2.2", - "postcss": "^7.0.21", + "postcss": "^7.0.23", "postcss-value-parser": "^4.0.2" } }, @@ -2023,13 +2023,13 @@ } }, "browserslist": { - "version": "4.7.2", - "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.7.2.tgz", - "integrity": "sha512-uZavT/gZXJd2UTi9Ov7/Z340WOSQ3+m1iBVRUknf+okKxonL9P83S3ctiBDtuRmRu8PiCHjqyueqQ9HYlJhxiw==", + "version": "4.7.3", + "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.7.3.tgz", + "integrity": "sha512-jWvmhqYpx+9EZm/FxcZSbUZyDEvDTLDi3nSAKbzEkyWvtI0mNSmUosey+5awDW1RUlrgXbQb5A6qY1xQH9U6MQ==", "requires": { - "caniuse-lite": "^1.0.30001004", - "electron-to-chromium": "^1.3.295", - "node-releases": "^1.1.38" + "caniuse-lite": "^1.0.30001010", + "electron-to-chromium": "^1.3.306", + "node-releases": "^1.1.40" } }, "buffer": { @@ -4472,9 +4472,9 @@ "integrity": "sha1-tdRU3CGZriJWmfNGfloH87lVuv0=" }, "has-symbols": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.0.0.tgz", - "integrity": "sha1-uhqPGvKg/DllD1yFA2dwQSIGO0Q=" + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.0.1.tgz", + "integrity": "sha512-PLcsoqu++dmEIZB+6totNFKq/7Do+Z0u4oT0zKOJNl3lYK6vGwwu2hjHs+68OEZbTjiUE9bgOABXbP/GvrS0Kg==" }, "has-value": { "version": "1.0.0", @@ -5441,6 +5441,11 @@ "resolved": "https://registry.npmjs.org/markdown-it-anchor/-/markdown-it-anchor-5.2.5.tgz", "integrity": "sha512-xLIjLQmtym3QpoY9llBgApknl7pxAcN3WDRc2d3rwpl+/YvDZHPmKscGs+L6E05xf2KrCXPBvosWt7MZukwSpQ==" }, + "markdown-it-attrs": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/markdown-it-attrs/-/markdown-it-attrs-3.0.1.tgz", + "integrity": "sha512-fcpdmxdEsctDVJEunPyrirVtU/6zcTMxPxAu4Ofz51PKAa8vRMpmGQXsmXx1HTdIdUPoDonm/RhS/+jTNywj/Q==" + }, "markdown-it-chain": { "version": "1.3.0", "resolved": "https://registry.npmjs.org/markdown-it-chain/-/markdown-it-chain-1.3.0.tgz", @@ -6334,9 +6339,9 @@ "integrity": "sha1-AerA/jta9xoqbAL+q7jB/vfgDqs=" }, "postcss": { - "version": "7.0.21", - "resolved": "https://registry.npmjs.org/postcss/-/postcss-7.0.21.tgz", - "integrity": "sha512-uIFtJElxJo29QC753JzhidoAhvp/e/Exezkdhfmt8AymWT6/5B7W1WmponYWkHk2eg6sONyTch0A3nkMPun3SQ==", + "version": "7.0.23", + "resolved": "https://registry.npmjs.org/postcss/-/postcss-7.0.23.tgz", + "integrity": "sha512-hOlMf3ouRIFXD+j2VJecwssTwbvsPGJVMzupptg+85WA+i7MwyrydmQAgY3R+m0Bc0exunhbJmijy8u8+vufuQ==", "requires": { "chalk": "^2.4.2", "source-map": "^0.6.1", @@ -8546,9 +8551,9 @@ "integrity": "sha1-WuaBd/GS1EViadEIr6k/+HQ/T2Q=" }, "type-fest": { - "version": "0.5.2", - "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.5.2.tgz", - "integrity": "sha512-DWkS49EQKVX//Tbupb9TFa19c7+MK1XmzkrZUR8TAktmE/DizXoaoJV6TZ/tSIPXipqNiRI6CyAe7x69Jb6RSw==" + "version": "0.8.1", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.8.1.tgz", + "integrity": "sha512-4dbzIzqvjtgiM5rw1k5rEHtBANKmdudhGyBEajN01fEyhaAIhsoKNy6y7+IN93IfpFtwY9iqi7kD+xwKhQsNJA==" }, "type-is": { "version": "1.6.18", @@ -9011,9 +9016,9 @@ } }, "vuepress-theme-cosmos": { - "version": "1.0.59", - "resolved": "https://registry.npmjs.org/vuepress-theme-cosmos/-/vuepress-theme-cosmos-1.0.59.tgz", - "integrity": "sha512-S190S5ogEoW+NMNF20hzNnT7GHOLGl86ZOHBusmudsILQMDJI5YsyAA+odtOrNPGaANOf/I9G5fhhAh7yKiBNQ==", + "version": "1.0.60", + "resolved": "https://registry.npmjs.org/vuepress-theme-cosmos/-/vuepress-theme-cosmos-1.0.60.tgz", + "integrity": "sha512-+qNhKRES4Uxszl4vdnJ+GwBwXAEtVsB15IdUHjKy6M/sSOVtUpRGxMqFI5MsecmAAnbwCuImol5FwqK1RnOQ4Q==", "requires": { "@cosmos-ui/vue": "^0.5.16", "@vuepress/plugin-last-updated": "^1.2.0", @@ -9021,6 +9026,7 @@ "axios": "^0.19.0", "intersection-observer": "^0.7.0", "markdown-it": "^10.0.0", + "markdown-it-attrs": "^3.0.1", "markdown-it-ins": "^3.0.0", "prismjs": "^1.17.1", "pug": "^2.0.4", diff --git a/docs/package.json b/docs/package.json index 54a6116be32c..c8f14fa799e1 100644 --- a/docs/package.json +++ b/docs/package.json @@ -14,6 +14,6 @@ "author": "", "license": "ISC", "dependencies": { - "vuepress-theme-cosmos": "^1.0.59" + "vuepress-theme-cosmos": "^1.0.60" } } From 67bcf80dc83c87fdd87dcfa6724ae73e756099b8 Mon Sep 17 00:00:00 2001 From: Denis Fadeev Date: Tue, 19 Nov 2019 12:58:56 +0500 Subject: [PATCH 165/196] fix yaml --- docs/basics/app-anatomy.md | 2 +- docs/basics/tx-lifecycle.md | 2 +- docs/building-modules/beginblock-endblock.md | 2 +- docs/building-modules/handler.md | 2 +- docs/building-modules/invariants.md | 2 +- docs/building-modules/keeper.md | 2 +- docs/building-modules/messages-and-queries.md | 2 +- docs/building-modules/module-manager.md | 2 +- docs/building-modules/querier.md | 2 +- docs/building-modules/structure.md | 4 +--- docs/core/baseapp.md | 3 +-- docs/core/events.md | 2 +- docs/core/transactions.md | 2 +- docs/interfaces/cli.md | 2 +- docs/interfaces/query-lifecycle.md | 2 +- docs/interfaces/rest.md | 2 +- 16 files changed, 16 insertions(+), 19 deletions(-) diff --git a/docs/basics/app-anatomy.md b/docs/basics/app-anatomy.md index 2a6c5ad831d5..898fd5c1df47 100644 --- a/docs/basics/app-anatomy.md +++ b/docs/basics/app-anatomy.md @@ -1,6 +1,6 @@ --- order: 1 -synopsis: This document describes the core parts of a Cosmos SDK application. Throughout the document, a placeholder application named `app` will be used. +synopsis: "This document describes the core parts of a Cosmos SDK application. Throughout the document, a placeholder application named `app` will be used." --- # Anatomy of an SDK Application diff --git a/docs/basics/tx-lifecycle.md b/docs/basics/tx-lifecycle.md index c9c64cc895b1..6de6d61271e6 100644 --- a/docs/basics/tx-lifecycle.md +++ b/docs/basics/tx-lifecycle.md @@ -1,6 +1,6 @@ --- order: 2 -synopsis: This document describes the lifecycle of a transaction from creation to committed state changes. Transaction definition is described in a [different doc](../core/transactions.md). The transaction will be referred to as `Tx`. +synopsis: "This document describes the lifecycle of a transaction from creation to committed state changes. Transaction definition is described in a [different doc](../core/transactions.md). The transaction will be referred to as `Tx`." --- # Transaction Lifecycle diff --git a/docs/building-modules/beginblock-endblock.md b/docs/building-modules/beginblock-endblock.md index baeb237c44e5..22e57a17cd10 100644 --- a/docs/building-modules/beginblock-endblock.md +++ b/docs/building-modules/beginblock-endblock.md @@ -1,6 +1,6 @@ --- order: 6 -synopsis: `BeginBlocker` and `EndBlocker` are optional methods module developers can implement in their module. They will be triggered at the beginning and at the end of each block respectively, when the [`BeginBlock`](../core/baseapp.md#beginblock) and [`EndBlock`](../core/baseapp.md#endblock) ABCI messages are received from the underlying consensus engine. +synopsis: "`BeginBlocker` and `EndBlocker` are optional methods module developers can implement in their module. They will be triggered at the beginning and at the end of each block respectively, when the [`BeginBlock`](../core/baseapp.md#beginblock) and [`EndBlock`](../core/baseapp.md#endblock) ABCI messages are received from the underlying consensus engine." --- # BeginBlocker and EndBlocker diff --git a/docs/building-modules/handler.md b/docs/building-modules/handler.md index 6f2d56d83b3f..d368a24b8803 100644 --- a/docs/building-modules/handler.md +++ b/docs/building-modules/handler.md @@ -1,6 +1,6 @@ --- order: 4 -synopsis: A `Handler` designates a function that processes [`message`s](./messages-and-queries.md#messages). `Handler`s are specific to the module in which they are defined, and only process `message`s defined within the said module. They are called from `baseapp` during [`DeliverTx`](../core/baseapp.md#delivertx). +synopsis: "A `Handler` designates a function that processes [`message`s](./messages-and-queries.md#messages). `Handler`s are specific to the module in which they are defined, and only process `message`s defined within the said module. They are called from `baseapp` during [`DeliverTx`](../core/baseapp.md#delivertx)." --- # Handlers diff --git a/docs/building-modules/invariants.md b/docs/building-modules/invariants.md index a80378469b75..950853997253 100644 --- a/docs/building-modules/invariants.md +++ b/docs/building-modules/invariants.md @@ -1,6 +1,6 @@ --- order: 8 -synopsis: An invariant is a property of the application that should always be true. In the context of the Cosmos SDK, an `Invariant` is a function that checks for a particular invariant. These functions are useful to detect bugs early on and act upon them to limit their potential consequences (e.g. by halting the chain). They are also useful in the development process of the application to detect bugs via simulations. +synopsis: "An invariant is a property of the application that should always be true. In the context of the Cosmos SDK, an `Invariant` is a function that checks for a particular invariant. These functions are useful to detect bugs early on and act upon them to limit their potential consequences (e.g. by halting the chain). They are also useful in the development process of the application to detect bugs via simulations." --- # Invariants diff --git a/docs/building-modules/keeper.md b/docs/building-modules/keeper.md index d33df9445ce3..4e735caa159d 100644 --- a/docs/building-modules/keeper.md +++ b/docs/building-modules/keeper.md @@ -1,6 +1,6 @@ --- order: 7 -synopsis: `Keeper`s refer to a Cosmos SDK abstraction whose role is to manage access to the subset of the state defined by various modules. `Keeper`s are module-specific, i.e. the subset of state defined by a module can only be accessed by a `keeper` defined in said module. If a module needs to access the subset of state defined by another module, a reference to the second module's internal `keeper` needs to be passed to the first one. This is done in `app.go` during the instantiation of module keepers. +synopsis: "`Keeper`s refer to a Cosmos SDK abstraction whose role is to manage access to the subset of the state defined by various modules. `Keeper`s are module-specific, i.e. the subset of state defined by a module can only be accessed by a `keeper` defined in said module. If a module needs to access the subset of state defined by another module, a reference to the second module's internal `keeper` needs to be passed to the first one. This is done in `app.go` during the instantiation of module keepers." --- # Keepers diff --git a/docs/building-modules/messages-and-queries.md b/docs/building-modules/messages-and-queries.md index 229c8d77b34b..f91293c9ae32 100644 --- a/docs/building-modules/messages-and-queries.md +++ b/docs/building-modules/messages-and-queries.md @@ -1,6 +1,6 @@ --- order: 3 -synopsis: `Message`s and `Queries` are the two primary objects handled by modules. Most of the core components defined in a module, like `handler`s, `keeper`s and `querier`s, exist to process `message`s and `queries`. +synopsis: "`Message`s and `Queries` are the two primary objects handled by modules. Most of the core components defined in a module, like `handler`s, `keeper`s and `querier`s, exist to process `message`s and `queries`." --- # Messages and Queries diff --git a/docs/building-modules/module-manager.md b/docs/building-modules/module-manager.md index 37174a8313c4..acf117999bd8 100644 --- a/docs/building-modules/module-manager.md +++ b/docs/building-modules/module-manager.md @@ -1,6 +1,6 @@ --- order: 2 -synopsis: Cosmos SDK modules need to implement the [`AppModule` interfaces](#application-module-interfaces), in order to be managed by the application's [module manager](#module-manager). The module manager plays an important role in [`message` and `query` routing](../core/baseapp.md#routing), and allows application developers to set the order of execution of a variety of functions like [`BeginBlocker` and `EndBlocker`](../basics/app-anatomy.md#begingblocker-and-endblocker). +synopsis: "Cosmos SDK modules need to implement the [`AppModule` interfaces](#application-module-interfaces), in order to be managed by the application's [module manager](#module-manager). The module manager plays an important role in [`message` and `query` routing](../core/baseapp.md#routing), and allows application developers to set the order of execution of a variety of functions like [`BeginBlocker` and `EndBlocker`](../basics/app-anatomy.md#begingblocker-and-endblocker)." --- diff --git a/docs/building-modules/querier.md b/docs/building-modules/querier.md index 8fbcafa59b40..f1056cbbca84 100644 --- a/docs/building-modules/querier.md +++ b/docs/building-modules/querier.md @@ -1,6 +1,6 @@ --- order: 5 -synopsis: A `Querier` designates a function that processes [`queries`](./messages-and-queries.md#queries). `querier`s are specific to the module in which they are defined, and only process `queries` defined within said module. They are called from `baseapp`'s [`Query` method](../core/baseapp.md#query). +synopsis: "A `Querier` designates a function that processes [`queries`](./messages-and-queries.md#queries). `querier`s are specific to the module in which they are defined, and only process `queries` defined within said module. They are called from `baseapp`'s [`Query` method](../core/baseapp.md#query)." --- # Queriers diff --git a/docs/building-modules/structure.md b/docs/building-modules/structure.md index c21bc2af119a..4191d1e405b9 100644 --- a/docs/building-modules/structure.md +++ b/docs/building-modules/structure.md @@ -1,8 +1,6 @@ --- order: 12 -synopsis: This document outlines the recommended structure of Cosmos SDK modules. These -ideas are meant to be applied as suggestions. Application developers are encouraged -to improve upon and contribute to module structure and development design. +synopsis: This document outlines the recommended structure of Cosmos SDK modules. These ideas are meant to be applied as suggestions. Application developers are encouraged to improve upon and contribute to module structure and development design. --- # Recommended Folder Structure diff --git a/docs/core/baseapp.md b/docs/core/baseapp.md index 4e9951cbb411..a4eabf1969f9 100644 --- a/docs/core/baseapp.md +++ b/docs/core/baseapp.md @@ -1,7 +1,6 @@ --- order: 1 -synopsis: This document describes `BaseApp`, the abstraction that implements the core -functionalities of an SDK application. +synopsis: This document describes `BaseApp`, the abstraction that implements the core functionalities of an SDK application. --- # Baseapp diff --git a/docs/core/events.md b/docs/core/events.md index 87cdd8770442..5a05275961cd 100644 --- a/docs/core/events.md +++ b/docs/core/events.md @@ -1,6 +1,6 @@ --- order: 7 -synopsis: `Event`s are objects that contain information about the execution of the application. They are mainly used by service providers like block explorers and wallet to track the execution of various messages and index transactions. +synopsis: "`Event`s are objects that contain information about the execution of the application. They are mainly used by service providers like block explorers and wallet to track the execution of various messages and index transactions." --- # Events diff --git a/docs/core/transactions.md b/docs/core/transactions.md index f09b725b6c2e..da4d885dd5b5 100644 --- a/docs/core/transactions.md +++ b/docs/core/transactions.md @@ -1,6 +1,6 @@ --- order: 2 -synopsis: `Transactions` are objects created by end-users to trigger state changes in the application. +synopsis: "`Transactions` are objects created by end-users to trigger state changes in the application." --- # Transactions diff --git a/docs/interfaces/cli.md b/docs/interfaces/cli.md index b33c2229f941..7b50a45d060f 100644 --- a/docs/interfaces/cli.md +++ b/docs/interfaces/cli.md @@ -1,6 +1,6 @@ --- order: 3 -synopsis: This document describes how to create a commmand-line interface (CLI) for an [**application**](../basics/app-anatomy.md). A separate document for implementing a CLI for an SDK [**module**](../building-modules/intro.md) can be found [here](#../building-modules/module-interfaces.md#cli). +synopsis: "This document describes how to create a commmand-line interface (CLI) for an [**application**](../basics/app-anatomy.md). A separate document for implementing a CLI for an SDK [**module**](../building-modules/intro.md) can be found [here](#../building-modules/module-interfaces.md#cli)." --- # Command-Line Interface diff --git a/docs/interfaces/query-lifecycle.md b/docs/interfaces/query-lifecycle.md index 20f44cf83d00..40fada642c24 100644 --- a/docs/interfaces/query-lifecycle.md +++ b/docs/interfaces/query-lifecycle.md @@ -1,6 +1,6 @@ --- order: 2 -synopsis: This document describes the lifecycle of a query in a SDK application, from the user interface to application stores and back. The query will be referred to as `Query`. +synopsis: "This document describes the lifecycle of a query in a SDK application, from the user interface to application stores and back. The query will be referred to as `Query`." --- # Query Lifecycle diff --git a/docs/interfaces/rest.md b/docs/interfaces/rest.md index 503e2c3dd394..3f602d18958a 100644 --- a/docs/interfaces/rest.md +++ b/docs/interfaces/rest.md @@ -1,6 +1,6 @@ --- order: 4 -synopsis: This document describes how to create a REST interface for an SDK **application**. A separate document for creating a [**module**](../building-modules/intro.md) REST interface can be found [here](#../module-interfaces.md#rest). +synopsis: "This document describes how to create a REST interface for an SDK **application**. A separate document for creating a [**module**](../building-modules/intro.md) REST interface can be found [here](#../module-interfaces.md#rest)." --- # REST Interface From 990a4d425b60f3b3fd818ab87e700ed172850042 Mon Sep 17 00:00:00 2001 From: Denis Fadeev Date: Tue, 19 Nov 2019 13:27:54 +0500 Subject: [PATCH 166/196] version --- docs/package-lock.json | 6 +++--- docs/package.json | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/docs/package-lock.json b/docs/package-lock.json index b75b17caa445..2dec81285618 100644 --- a/docs/package-lock.json +++ b/docs/package-lock.json @@ -9016,9 +9016,9 @@ } }, "vuepress-theme-cosmos": { - "version": "1.0.60", - "resolved": "https://registry.npmjs.org/vuepress-theme-cosmos/-/vuepress-theme-cosmos-1.0.60.tgz", - "integrity": "sha512-+qNhKRES4Uxszl4vdnJ+GwBwXAEtVsB15IdUHjKy6M/sSOVtUpRGxMqFI5MsecmAAnbwCuImol5FwqK1RnOQ4Q==", + "version": "1.0.61", + "resolved": "https://registry.npmjs.org/vuepress-theme-cosmos/-/vuepress-theme-cosmos-1.0.61.tgz", + "integrity": "sha512-jkmR7zqQLeUfUf6+l590aWc5Jj0cJjdSoulDy+jgvv/5UO6V8eSh+1FI95liqG5rZ8+wPPlEGt4KbT/5oYqdRw==", "requires": { "@cosmos-ui/vue": "^0.5.16", "@vuepress/plugin-last-updated": "^1.2.0", diff --git a/docs/package.json b/docs/package.json index c8f14fa799e1..481ba963b5e2 100644 --- a/docs/package.json +++ b/docs/package.json @@ -14,6 +14,6 @@ "author": "", "license": "ISC", "dependencies": { - "vuepress-theme-cosmos": "^1.0.60" + "vuepress-theme-cosmos": "^1.0.61" } } From dbedb9256430e5a226419a8ccdc5f2e7c37bb287 Mon Sep 17 00:00:00 2001 From: Denis Fadeev Date: Tue, 19 Nov 2019 13:40:54 +0500 Subject: [PATCH 167/196] version --- docs/package-lock.json | 6 +++--- docs/package.json | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/docs/package-lock.json b/docs/package-lock.json index 2dec81285618..7e21db1f3c93 100644 --- a/docs/package-lock.json +++ b/docs/package-lock.json @@ -9016,9 +9016,9 @@ } }, "vuepress-theme-cosmos": { - "version": "1.0.61", - "resolved": "https://registry.npmjs.org/vuepress-theme-cosmos/-/vuepress-theme-cosmos-1.0.61.tgz", - "integrity": "sha512-jkmR7zqQLeUfUf6+l590aWc5Jj0cJjdSoulDy+jgvv/5UO6V8eSh+1FI95liqG5rZ8+wPPlEGt4KbT/5oYqdRw==", + "version": "1.0.62", + "resolved": "https://registry.npmjs.org/vuepress-theme-cosmos/-/vuepress-theme-cosmos-1.0.62.tgz", + "integrity": "sha512-NaEyVkIJT22AVFGagV/OYYtWfyV53lTCXb9kZM9H2+V0pSGJqhtwQ6IlzVcMMBUclLvQT9yJzpLvGOhsn97Fow==", "requires": { "@cosmos-ui/vue": "^0.5.16", "@vuepress/plugin-last-updated": "^1.2.0", diff --git a/docs/package.json b/docs/package.json index 481ba963b5e2..d3c1bab20e2a 100644 --- a/docs/package.json +++ b/docs/package.json @@ -14,6 +14,6 @@ "author": "", "license": "ISC", "dependencies": { - "vuepress-theme-cosmos": "^1.0.61" + "vuepress-theme-cosmos": "^1.0.62" } } From 150566fdd57eac7adc16bd415ff616699d86dd32 Mon Sep 17 00:00:00 2001 From: Denis Fadeev Date: Tue, 19 Nov 2019 13:52:51 +0500 Subject: [PATCH 168/196] version --- docs/package-lock.json | 6 +++--- docs/package.json | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/docs/package-lock.json b/docs/package-lock.json index 7e21db1f3c93..84272152dd12 100644 --- a/docs/package-lock.json +++ b/docs/package-lock.json @@ -9016,9 +9016,9 @@ } }, "vuepress-theme-cosmos": { - "version": "1.0.62", - "resolved": "https://registry.npmjs.org/vuepress-theme-cosmos/-/vuepress-theme-cosmos-1.0.62.tgz", - "integrity": "sha512-NaEyVkIJT22AVFGagV/OYYtWfyV53lTCXb9kZM9H2+V0pSGJqhtwQ6IlzVcMMBUclLvQT9yJzpLvGOhsn97Fow==", + "version": "1.0.63", + "resolved": "https://registry.npmjs.org/vuepress-theme-cosmos/-/vuepress-theme-cosmos-1.0.63.tgz", + "integrity": "sha512-LiwZnSKmlPyfzPxEvp7eV69G7Qh31iB5mfAa3oHVamXxzIjzMO8FchoVpmapAFiURZf44mYEFikytk2nvwzaRw==", "requires": { "@cosmos-ui/vue": "^0.5.16", "@vuepress/plugin-last-updated": "^1.2.0", diff --git a/docs/package.json b/docs/package.json index d3c1bab20e2a..8fc1bad0dbc8 100644 --- a/docs/package.json +++ b/docs/package.json @@ -14,6 +14,6 @@ "author": "", "license": "ISC", "dependencies": { - "vuepress-theme-cosmos": "^1.0.62" + "vuepress-theme-cosmos": "^1.0.63" } } From 1a8278f738cebb3af7f125df50c014306c3edeb7 Mon Sep 17 00:00:00 2001 From: Denis Fadeev Date: Tue, 19 Nov 2019 20:32:39 +0500 Subject: [PATCH 169/196] version --- docs/package-lock.json | 6 +++--- docs/package.json | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/docs/package-lock.json b/docs/package-lock.json index 84272152dd12..968dcf28a2c4 100644 --- a/docs/package-lock.json +++ b/docs/package-lock.json @@ -9016,9 +9016,9 @@ } }, "vuepress-theme-cosmos": { - "version": "1.0.63", - "resolved": "https://registry.npmjs.org/vuepress-theme-cosmos/-/vuepress-theme-cosmos-1.0.63.tgz", - "integrity": "sha512-LiwZnSKmlPyfzPxEvp7eV69G7Qh31iB5mfAa3oHVamXxzIjzMO8FchoVpmapAFiURZf44mYEFikytk2nvwzaRw==", + "version": "1.0.65", + "resolved": "https://registry.npmjs.org/vuepress-theme-cosmos/-/vuepress-theme-cosmos-1.0.65.tgz", + "integrity": "sha512-KvsRiYXvR214zasznV7RsoULYQNolO7gjIVvD79YTpoWeqdMeJSb6TISZzPW8Tg9O5DnPpsfjgg/FZ8WJiQgUQ==", "requires": { "@cosmos-ui/vue": "^0.5.16", "@vuepress/plugin-last-updated": "^1.2.0", diff --git a/docs/package.json b/docs/package.json index 8fc1bad0dbc8..16ff0127cdcc 100644 --- a/docs/package.json +++ b/docs/package.json @@ -14,6 +14,6 @@ "author": "", "license": "ISC", "dependencies": { - "vuepress-theme-cosmos": "^1.0.63" + "vuepress-theme-cosmos": "^1.0.65" } } From 29956aad6485a3aa00401feea15643a172b1db8a Mon Sep 17 00:00:00 2001 From: Denis Fadeev Date: Thu, 21 Nov 2019 01:05:55 +0500 Subject: [PATCH 170/196] version --- docs/package-lock.json | 42 ++++++++++++++++++++++++------------------ docs/package.json | 2 +- 2 files changed, 25 insertions(+), 19 deletions(-) diff --git a/docs/package-lock.json b/docs/package-lock.json index 968dcf28a2c4..2d904e1cd500 100644 --- a/docs/package-lock.json +++ b/docs/package-lock.json @@ -877,9 +877,9 @@ "integrity": "sha512-tHq6qdbT9U1IRSGf14CL0pUlULksvY9OZ+5eEgl1N7t+OA3tGvNpxJCzuKQlsNgCVwbAs670L1vcVQi8j9HjnA==" }, "@types/node": { - "version": "12.12.9", - "resolved": "https://registry.npmjs.org/@types/node/-/node-12.12.9.tgz", - "integrity": "sha512-kV3w4KeLsRBW+O2rKhktBwENNJuqAUQHS3kf4ia2wIaF/MN6U7ANgTsx7tGremcA0Pk3Yh0Hl0iKiLPuBdIgmw==" + "version": "12.12.11", + "resolved": "https://registry.npmjs.org/@types/node/-/node-12.12.11.tgz", + "integrity": "sha512-O+x6uIpa6oMNTkPuHDa9MhMMehlxLAd5QcOvKRjAFsBVpeFWTOPnXbDvILvFgFFZfQ1xh1EZi1FbXxUix+zpsQ==" }, "@types/q": { "version": "1.5.2", @@ -2180,9 +2180,9 @@ } }, "caniuse-lite": { - "version": "1.0.30001010", - "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001010.tgz", - "integrity": "sha512-RA5GH9YjFNea4ZQszdWgh2SC+dpLiRAg4VDQS2b5JRI45OxmbGrYocYHTa9x0bKMQUE7uvHkNPNffUr+pCxSGw==" + "version": "1.0.30001011", + "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001011.tgz", + "integrity": "sha512-h+Eqyn/YA6o6ZTqpS86PyRmNWOs1r54EBDcd2NTwwfsXQ8re1B38SnB+p2RKF8OUsyEIjeDU8XGec1RGO/wYCg==" }, "caseless": { "version": "0.12.0", @@ -3192,9 +3192,9 @@ "integrity": "sha1-WQxhFWsK4vTwJVcyoViyZrxWsh0=" }, "electron-to-chromium": { - "version": "1.3.306", - "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.3.306.tgz", - "integrity": "sha512-frDqXvrIROoYvikSKTIKbHbzO6M3/qC6kCIt/1FOa9kALe++c4VAJnwjSFvf1tYLEUsP2n9XZ4XSCyqc3l7A/A==" + "version": "1.3.307", + "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.3.307.tgz", + "integrity": "sha512-01rTsAqHwf3D2X6NtlUvzB2hxDj67kiTVIO5GWdFb2unA0QvFvrjyrtc993ByRLF+surlr+9AvJdD0UYs5HzwA==" }, "elliptic": { "version": "6.5.1", @@ -3269,9 +3269,9 @@ } }, "envinfo": { - "version": "7.4.0", - "resolved": "https://registry.npmjs.org/envinfo/-/envinfo-7.4.0.tgz", - "integrity": "sha512-FdDfnWnCVjxTTpWE3d6Jgh5JDIA3Cw7LCgpM/pI7kK1ORkjaqI2r6NqQ+ln2j0dfpgxY00AWieSvtkiZQKIItA==" + "version": "7.5.0", + "resolved": "https://registry.npmjs.org/envinfo/-/envinfo-7.5.0.tgz", + "integrity": "sha512-jDgnJaF/Btomk+m3PZDTTCb5XIIIX3zYItnCRfF73zVgvinLoRomuhi75Y4su0PtQxWz4v66XnLLckyvyJTOIQ==" }, "errno": { "version": "0.1.7", @@ -5389,6 +5389,11 @@ "yallist": "^3.0.2" } }, + "lunr": { + "version": "2.3.8", + "resolved": "https://registry.npmjs.org/lunr/-/lunr-2.3.8.tgz", + "integrity": "sha512-oxMeX/Y35PNFuZoHp+jUj5OSEmLCaIH4KTFJh7a93cHBoFmpw2IoPs22VIz7vyO2YUnx2Tn9dzIwO2P/4quIRg==" + }, "make-dir": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/make-dir/-/make-dir-2.1.0.tgz", @@ -9000,9 +9005,9 @@ } }, "vuepress-plugin-container": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/vuepress-plugin-container/-/vuepress-plugin-container-2.1.0.tgz", - "integrity": "sha512-i4p7S1cqYUrg/3pt+xSghZtKSHVI3VXMQNept8ILxA+lMK1XJkdRkjNovZzwpXlrErQssvrUOTWBV0hdBv7eXQ==", + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/vuepress-plugin-container/-/vuepress-plugin-container-2.1.1.tgz", + "integrity": "sha512-1hKZZ9DzVvgNZiSZfiTGiAzbq9bYww64kFz5yv3BRLKdEYX7rSIxKW6lFrbyaTCPQkT1qWgr95sM+GVetpcQFw==", "requires": { "markdown-it-container": "^2.0.0" } @@ -9016,15 +9021,16 @@ } }, "vuepress-theme-cosmos": { - "version": "1.0.65", - "resolved": "https://registry.npmjs.org/vuepress-theme-cosmos/-/vuepress-theme-cosmos-1.0.65.tgz", - "integrity": "sha512-KvsRiYXvR214zasznV7RsoULYQNolO7gjIVvD79YTpoWeqdMeJSb6TISZzPW8Tg9O5DnPpsfjgg/FZ8WJiQgUQ==", + "version": "1.0.67", + "resolved": "https://registry.npmjs.org/vuepress-theme-cosmos/-/vuepress-theme-cosmos-1.0.67.tgz", + "integrity": "sha512-qfXVOYPFc7Gf+JWP8lVbhWiym3pywwisWnIE4uDzvV9Fq/JDCFGlpMyJkH/xtFTkVdGQCx8qtLbo4l/eJMLmzw==", "requires": { "@cosmos-ui/vue": "^0.5.16", "@vuepress/plugin-last-updated": "^1.2.0", "@vuepress/plugin-search": "^1.1.0", "axios": "^0.19.0", "intersection-observer": "^0.7.0", + "lunr": "^2.3.8", "markdown-it": "^10.0.0", "markdown-it-attrs": "^3.0.1", "markdown-it-ins": "^3.0.0", diff --git a/docs/package.json b/docs/package.json index 16ff0127cdcc..3067258d21b4 100644 --- a/docs/package.json +++ b/docs/package.json @@ -14,6 +14,6 @@ "author": "", "license": "ISC", "dependencies": { - "vuepress-theme-cosmos": "^1.0.65" + "vuepress-theme-cosmos": "^1.0.67" } } From 5a4d4392f865e29b3be828a2cd7012af4fc795be Mon Sep 17 00:00:00 2001 From: Denis Fadeev Date: Thu, 21 Nov 2019 17:20:36 +0500 Subject: [PATCH 171/196] version --- docs/package-lock.json | 212 +++++++++++++++++++---------------------- docs/package.json | 2 +- 2 files changed, 100 insertions(+), 114 deletions(-) diff --git a/docs/package-lock.json b/docs/package-lock.json index 2d904e1cd500..aaebdf7c38e9 100644 --- a/docs/package-lock.json +++ b/docs/package-lock.json @@ -1448,26 +1448,6 @@ "reduce": "^1.0.1", "semver": "^5.1.0", "tunnel-agent": "^0.6.0" - }, - "dependencies": { - "debug": { - "version": "2.6.9", - "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", - "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", - "requires": { - "ms": "2.0.0" - } - }, - "events": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/events/-/events-1.1.1.tgz", - "integrity": "sha1-nr23Y1rQmccNzEwqH1AEKI6L2SQ=" - }, - "isarray": { - "version": "2.0.5", - "resolved": "https://registry.npmjs.org/isarray/-/isarray-2.0.5.tgz", - "integrity": "sha512-xHjhDr3cNBK0BzdUJSPXZntQUx/mwMS5Rw4A7lPJ90XGAO6ISP/ePDNuo0vhqOZU+UD5JoodwCAAoZQd3FeAKw==" - } } }, "align-text": { @@ -1887,14 +1867,6 @@ "version": "3.1.0", "resolved": "https://registry.npmjs.org/bytes/-/bytes-3.1.0.tgz", "integrity": "sha512-zauLjrfCG+xvoyaqLoV8bLVXXNGC4JqlxFCutSDWA6fJrTo2ZuvLYTqZ7aHBLZSMOopbzwv8f+wZcVzfVTI2Dg==" - }, - "debug": { - "version": "2.6.9", - "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", - "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", - "requires": { - "ms": "2.0.0" - } } } }, @@ -2040,6 +2012,13 @@ "base64-js": "^1.0.2", "ieee754": "^1.1.4", "isarray": "^1.0.0" + }, + "dependencies": { + "isarray": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", + "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=" + } } }, "buffer-from": { @@ -2412,13 +2391,10 @@ "vary": "~1.1.2" }, "dependencies": { - "debug": { - "version": "2.6.9", - "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", - "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", - "requires": { - "ms": "2.0.0" - } + "safe-buffer": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", + "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==" } } }, @@ -2483,6 +2459,13 @@ "integrity": "sha512-ExO0774ikEObIAEV9kDo50o+79VCUdEB6n6lzKgGwupcVeRlhrj3qGAfwq8G6uBJjkqLrhT0qEYFcWng8z1z0g==", "requires": { "safe-buffer": "5.1.2" + }, + "dependencies": { + "safe-buffer": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", + "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==" + } } }, "content-type": { @@ -2496,6 +2479,13 @@ "integrity": "sha512-4FJkXzKXEDB1snCFZlLP4gpC3JILicCpGbzG9f9G7tGqGCzETQ2hWPrcinA9oU4wtf2biUaEH5065UnMeR33oA==", "requires": { "safe-buffer": "~5.1.1" + }, + "dependencies": { + "safe-buffer": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", + "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==" + } } }, "cookie": { @@ -2874,9 +2864,9 @@ "integrity": "sha1-sgOOhG3DO6pXlhKNCAS0VbjB4h0=" }, "debug": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/debug/-/debug-3.1.0.tgz", - "integrity": "sha512-OX8XqP7/1a9cqkxYw2yXss15f26NKWBpDXQd0/uK/KPqdQhxbPa994hnzjcE2VqQpDslf55723cKPUOGSmMY3g==", + "version": "2.6.9", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", + "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", "requires": { "ms": "2.0.0" } @@ -3192,9 +3182,9 @@ "integrity": "sha1-WQxhFWsK4vTwJVcyoViyZrxWsh0=" }, "electron-to-chromium": { - "version": "1.3.307", - "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.3.307.tgz", - "integrity": "sha512-01rTsAqHwf3D2X6NtlUvzB2hxDj67kiTVIO5GWdFb2unA0QvFvrjyrtc993ByRLF+surlr+9AvJdD0UYs5HzwA==" + "version": "1.3.309", + "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.3.309.tgz", + "integrity": "sha512-NZd91XD15v2UPLjYXoN/gLnkwIUQjdH4SQLpRCCQiYJH6BBkfgp5pWemBJPr1rZ2dl8Ee3o91O9Sa1QuAfZmog==" }, "elliptic": { "version": "6.5.1", @@ -3374,9 +3364,9 @@ "integrity": "sha512-qerSRB0p+UDEssxTtm6EDKcE7W4OaoisfIMl4CngyEhjpYglocpNg6UEqCvemdGhosAsg4sO2dXJOdyBifPGCg==" }, "events": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/events/-/events-3.0.0.tgz", - "integrity": "sha512-Dc381HFWJzEOhQ+d8pkNon++bk9h6cdAoAj4iE6Q4y6xgTzySWXlKn05/TVNpjnfRqi/X0EpJEJohPjNI3zpVA==" + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/events/-/events-1.1.1.tgz", + "integrity": "sha1-nr23Y1rQmccNzEwqH1AEKI6L2SQ=" }, "eventsource": { "version": "1.0.7", @@ -3423,14 +3413,6 @@ "to-regex": "^3.0.1" }, "dependencies": { - "debug": { - "version": "2.6.9", - "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", - "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", - "requires": { - "ms": "2.0.0" - } - }, "define-property": { "version": "0.2.5", "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz", @@ -3491,13 +3473,10 @@ "resolved": "https://registry.npmjs.org/array-flatten/-/array-flatten-1.1.1.tgz", "integrity": "sha1-ml9pkFGx5wczKPKgCJaLZOopVdI=" }, - "debug": { - "version": "2.6.9", - "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", - "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", - "requires": { - "ms": "2.0.0" - } + "safe-buffer": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", + "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==" } } }, @@ -3680,16 +3659,6 @@ "parseurl": "~1.3.3", "statuses": "~1.5.0", "unpipe": "~1.0.0" - }, - "dependencies": { - "debug": { - "version": "2.6.9", - "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", - "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", - "requires": { - "ms": "2.0.0" - } - } } }, "find-babel-config": { @@ -3741,6 +3710,16 @@ "integrity": "sha512-0V5l4Cizzvqt5D44aTXbFZz+FtyXV1vrDN6qrelxtfYQKW0KO0W2T/hkE8xvGa/540LkZlkaUjO4ailYTFtHVQ==", "requires": { "debug": "=3.1.0" + }, + "dependencies": { + "debug": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/debug/-/debug-3.1.0.tgz", + "integrity": "sha512-OX8XqP7/1a9cqkxYw2yXss15f26NKWBpDXQd0/uK/KPqdQhxbPa994hnzjcE2VqQpDslf55723cKPUOGSmMY3g==", + "requires": { + "ms": "2.0.0" + } + } } }, "for-in": { @@ -5085,11 +5064,11 @@ } }, "is-symbol": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/is-symbol/-/is-symbol-1.0.2.tgz", - "integrity": "sha512-HS8bZ9ox60yCJLH9snBpIwv9pYUAkcuLhSA1oero1UB5y9aiQpRA8y2ex945AOtCZL1lJDeIk3G5LthswI46Lw==", + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/is-symbol/-/is-symbol-1.0.3.tgz", + "integrity": "sha512-OwijhaRSgqvhm/0ZdAcXNZt9lYdKFpcRDT5ULUuYXPoT794UNOdU+gpT6Rzo7b4V2HUl/op6GqY894AZwv9faQ==", "requires": { - "has-symbols": "^1.0.0" + "has-symbols": "^1.0.1" } }, "is-typedarray": { @@ -5108,9 +5087,9 @@ "integrity": "sha1-HxbkqiKwTRM2tmGIpmrzxgDDpm0=" }, "isarray": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", - "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=" + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/isarray/-/isarray-2.0.5.tgz", + "integrity": "sha512-xHjhDr3cNBK0BzdUJSPXZntQUx/mwMS5Rw4A7lPJ90XGAO6ISP/ePDNuo0vhqOZU+UD5JoodwCAAoZQd3FeAKw==" }, "isexe": { "version": "2.0.0", @@ -5819,6 +5798,11 @@ "vm-browserify": "^1.0.1" }, "dependencies": { + "events": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/events/-/events-3.0.0.tgz", + "integrity": "sha512-Dc381HFWJzEOhQ+d8pkNon++bk9h6cdAoAj4iE6Q4y6xgTzySWXlKn05/TVNpjnfRqi/X0EpJEJohPjNI3zpVA==" + }, "punycode": { "version": "1.4.1", "resolved": "https://registry.npmjs.org/punycode/-/punycode-1.4.1.tgz", @@ -7235,6 +7219,18 @@ "safe-buffer": "~5.1.1", "string_decoder": "~1.1.1", "util-deprecate": "~1.0.1" + }, + "dependencies": { + "isarray": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", + "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=" + }, + "safe-buffer": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", + "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==" + } } }, "readdirp": { @@ -7524,9 +7520,9 @@ } }, "safe-buffer": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", - "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==" + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.0.tgz", + "integrity": "sha512-fZEwUGbVl7kouZs1jCdMLdt95hdIv0ZeHg6L7qPeciMZhZ+/gdesW4wgTARkrFWEpspjEATAzUGPG8N2jJiwbg==" }, "safe-regex": { "version": "1.1.0", @@ -7624,21 +7620,6 @@ "statuses": "~1.5.0" }, "dependencies": { - "debug": { - "version": "2.6.9", - "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", - "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", - "requires": { - "ms": "2.0.0" - }, - "dependencies": { - "ms": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", - "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=" - } - } - }, "mime": { "version": "1.6.0", "resolved": "https://registry.npmjs.org/mime/-/mime-1.6.0.tgz", @@ -7670,14 +7651,6 @@ "parseurl": "~1.3.2" }, "dependencies": { - "debug": { - "version": "2.6.9", - "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", - "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", - "requires": { - "ms": "2.0.0" - } - }, "http-errors": { "version": "1.6.3", "resolved": "https://registry.npmjs.org/http-errors/-/http-errors-1.6.3.tgz", @@ -7815,14 +7788,6 @@ "use": "^3.1.0" }, "dependencies": { - "debug": { - "version": "2.6.9", - "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", - "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", - "requires": { - "ms": "2.0.0" - } - }, "define-property": { "version": "0.2.5", "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz", @@ -8226,6 +8191,13 @@ "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", "requires": { "safe-buffer": "~5.1.0" + }, + "dependencies": { + "safe-buffer": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", + "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==" + } } }, "strip-ansi": { @@ -8283,6 +8255,14 @@ "source-map": "^0.7.3" }, "dependencies": { + "debug": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/debug/-/debug-3.1.0.tgz", + "integrity": "sha512-OX8XqP7/1a9cqkxYw2yXss15f26NKWBpDXQd0/uK/KPqdQhxbPa994hnzjcE2VqQpDslf55723cKPUOGSmMY3g==", + "requires": { + "ms": "2.0.0" + } + }, "semver": { "version": "6.3.0", "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", @@ -8711,6 +8691,11 @@ "version": "0.1.4", "resolved": "https://registry.npmjs.org/has-values/-/has-values-0.1.4.tgz", "integrity": "sha1-bWHeldkd/Km5oCCJrThL/49it3E=" + }, + "isarray": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", + "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=" } } }, @@ -9021,13 +9006,14 @@ } }, "vuepress-theme-cosmos": { - "version": "1.0.67", - "resolved": "https://registry.npmjs.org/vuepress-theme-cosmos/-/vuepress-theme-cosmos-1.0.67.tgz", - "integrity": "sha512-qfXVOYPFc7Gf+JWP8lVbhWiym3pywwisWnIE4uDzvV9Fq/JDCFGlpMyJkH/xtFTkVdGQCx8qtLbo4l/eJMLmzw==", + "version": "1.0.68", + "resolved": "https://registry.npmjs.org/vuepress-theme-cosmos/-/vuepress-theme-cosmos-1.0.68.tgz", + "integrity": "sha512-UCb5f1zgAaQkirlsLrbGFbCKO0EYnNN0ubUrgUljsvqOk7TOfDJNJiPKee3NS8Iye24IB6he2oFvjElpEufiwg==", "requires": { "@cosmos-ui/vue": "^0.5.16", "@vuepress/plugin-last-updated": "^1.2.0", "@vuepress/plugin-search": "^1.1.0", + "algoliasearch": "^3.35.1", "axios": "^0.19.0", "intersection-observer": "^0.7.0", "lunr": "^2.3.8", diff --git a/docs/package.json b/docs/package.json index 3067258d21b4..75a346d7d1db 100644 --- a/docs/package.json +++ b/docs/package.json @@ -14,6 +14,6 @@ "author": "", "license": "ISC", "dependencies": { - "vuepress-theme-cosmos": "^1.0.67" + "vuepress-theme-cosmos": "^1.0.68" } } From cc57ed46178f87f18ae0625df4d818bda5ce5ea3 Mon Sep 17 00:00:00 2001 From: Denis Fadeev Date: Thu, 21 Nov 2019 17:29:38 +0500 Subject: [PATCH 172/196] version --- docs/package-lock.json | 197 ++++++++++++++++++++++++++++++++++------- docs/package.json | 2 +- 2 files changed, 165 insertions(+), 34 deletions(-) diff --git a/docs/package-lock.json b/docs/package-lock.json index aaebdf7c38e9..95dc3d4ea5d8 100644 --- a/docs/package-lock.json +++ b/docs/package-lock.json @@ -1701,6 +1701,21 @@ "loader-utils": "^1.0.2", "mkdirp": "^0.5.1", "pify": "^4.0.1" + }, + "dependencies": { + "minimist": { + "version": "0.0.8", + "resolved": "https://registry.npmjs.org/minimist/-/minimist-0.0.8.tgz", + "integrity": "sha1-hX/Kv8M5fSYluCKCYuhqp6ARsF0=" + }, + "mkdirp": { + "version": "0.5.1", + "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.1.tgz", + "integrity": "sha1-MAV0OOrGz3+MR2fzhkjWaX11yQM=", + "requires": { + "minimist": "0.0.8" + } + } } }, "babel-plugin-dynamic-import-node": { @@ -1867,6 +1882,11 @@ "version": "3.1.0", "resolved": "https://registry.npmjs.org/bytes/-/bytes-3.1.0.tgz", "integrity": "sha512-zauLjrfCG+xvoyaqLoV8bLVXXNGC4JqlxFCutSDWA6fJrTo2ZuvLYTqZ7aHBLZSMOopbzwv8f+wZcVzfVTI2Dg==" + }, + "qs": { + "version": "6.7.0", + "resolved": "https://registry.npmjs.org/qs/-/qs-6.7.0.tgz", + "integrity": "sha512-VCdBRNFTX1fyE7Nb6FYoURo/SPe62QCaAyzJvUjwRaIsc+NePBEniHlvxFmmX56+HZphIGtV0XeCirBtpDrTyQ==" } } }, @@ -2076,6 +2096,21 @@ "ssri": "^6.0.1", "unique-filename": "^1.1.1", "y18n": "^4.0.0" + }, + "dependencies": { + "minimist": { + "version": "0.0.8", + "resolved": "https://registry.npmjs.org/minimist/-/minimist-0.0.8.tgz", + "integrity": "sha1-hX/Kv8M5fSYluCKCYuhqp6ARsF0=" + }, + "mkdirp": { + "version": "0.5.1", + "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.1.tgz", + "integrity": "sha1-MAV0OOrGz3+MR2fzhkjWaX11yQM=", + "requires": { + "minimist": "0.0.8" + } + } } }, "cache-base": { @@ -2105,6 +2140,21 @@ "mkdirp": "^0.5.1", "neo-async": "^2.6.1", "schema-utils": "^1.0.0" + }, + "dependencies": { + "minimist": { + "version": "0.0.8", + "resolved": "https://registry.npmjs.org/minimist/-/minimist-0.0.8.tgz", + "integrity": "sha1-hX/Kv8M5fSYluCKCYuhqp6ARsF0=" + }, + "mkdirp": { + "version": "0.5.1", + "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.1.tgz", + "integrity": "sha1-MAV0OOrGz3+MR2fzhkjWaX11yQM=", + "requires": { + "minimist": "0.0.8" + } + } } }, "call-me-maybe": { @@ -2509,6 +2559,21 @@ "mkdirp": "^0.5.1", "rimraf": "^2.5.4", "run-queue": "^1.0.0" + }, + "dependencies": { + "minimist": { + "version": "0.0.8", + "resolved": "https://registry.npmjs.org/minimist/-/minimist-0.0.8.tgz", + "integrity": "sha1-hX/Kv8M5fSYluCKCYuhqp6ARsF0=" + }, + "mkdirp": { + "version": "0.5.1", + "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.1.tgz", + "integrity": "sha1-MAV0OOrGz3+MR2fzhkjWaX11yQM=", + "requires": { + "minimist": "0.0.8" + } + } } }, "copy-descriptor": { @@ -3473,6 +3538,11 @@ "resolved": "https://registry.npmjs.org/array-flatten/-/array-flatten-1.1.1.tgz", "integrity": "sha1-ml9pkFGx5wczKPKgCJaLZOopVdI=" }, + "qs": { + "version": "6.7.0", + "resolved": "https://registry.npmjs.org/qs/-/qs-6.7.0.tgz", + "integrity": "sha512-VCdBRNFTX1fyE7Nb6FYoURo/SPe62QCaAyzJvUjwRaIsc+NePBEniHlvxFmmX56+HZphIGtV0XeCirBtpDrTyQ==" + }, "safe-buffer": { "version": "5.1.2", "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", @@ -4539,13 +4609,6 @@ "requires": { "mkdirp": "0.3.0", "nopt": "1.0.10" - }, - "dependencies": { - "mkdirp": { - "version": "0.3.0", - "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.3.0.tgz", - "integrity": "sha1-G79asbqCevI1dRQ0kEJkVfSB/h4=" - } } }, "hpack.js": { @@ -5663,19 +5726,9 @@ } }, "mkdirp": { - "version": "0.5.1", - "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.1.tgz", - "integrity": "sha1-MAV0OOrGz3+MR2fzhkjWaX11yQM=", - "requires": { - "minimist": "0.0.8" - }, - "dependencies": { - "minimist": { - "version": "0.0.8", - "resolved": "https://registry.npmjs.org/minimist/-/minimist-0.0.8.tgz", - "integrity": "sha1-hX/Kv8M5fSYluCKCYuhqp6ARsF0=" - } - } + "version": "0.3.0", + "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.3.0.tgz", + "integrity": "sha1-G79asbqCevI1dRQ0kEJkVfSB/h4=" }, "move-concurrently": { "version": "1.0.1", @@ -5688,6 +5741,21 @@ "mkdirp": "^0.5.1", "rimraf": "^2.5.4", "run-queue": "^1.0.3" + }, + "dependencies": { + "minimist": { + "version": "0.0.8", + "resolved": "https://registry.npmjs.org/minimist/-/minimist-0.0.8.tgz", + "integrity": "sha1-hX/Kv8M5fSYluCKCYuhqp6ARsF0=" + }, + "mkdirp": { + "version": "0.5.1", + "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.1.tgz", + "integrity": "sha1-MAV0OOrGz3+MR2fzhkjWaX11yQM=", + "requires": { + "minimist": "0.0.8" + } + } } }, "ms": { @@ -6315,6 +6383,19 @@ "ms": "^2.1.1" } }, + "minimist": { + "version": "0.0.8", + "resolved": "https://registry.npmjs.org/minimist/-/minimist-0.0.8.tgz", + "integrity": "sha1-hX/Kv8M5fSYluCKCYuhqp6ARsF0=" + }, + "mkdirp": { + "version": "0.5.1", + "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.1.tgz", + "integrity": "sha1-MAV0OOrGz3+MR2fzhkjWaX11yQM=", + "requires": { + "minimist": "0.0.8" + } + }, "ms": { "version": "2.1.2", "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", @@ -7138,9 +7219,9 @@ "integrity": "sha1-fjL3W0E4EpHQRhHxvxQQmsAGUdc=" }, "qs": { - "version": "6.7.0", - "resolved": "https://registry.npmjs.org/qs/-/qs-6.7.0.tgz", - "integrity": "sha512-VCdBRNFTX1fyE7Nb6FYoURo/SPe62QCaAyzJvUjwRaIsc+NePBEniHlvxFmmX56+HZphIGtV0XeCirBtpDrTyQ==" + "version": "6.5.2", + "resolved": "https://registry.npmjs.org/qs/-/qs-6.5.2.tgz", + "integrity": "sha512-N5ZAX4/LxJmF+7wN74pUD6qAh9/wnvdQcjq9TZjevvXzSUo7bfmw91saqMjzGS2xq91/odN2dW/WOl7qQHNDGA==" }, "query-string": { "version": "5.1.1", @@ -7411,13 +7492,6 @@ "tough-cookie": "~2.4.3", "tunnel-agent": "^0.6.0", "uuid": "^3.3.2" - }, - "dependencies": { - "qs": { - "version": "6.5.2", - "resolved": "https://registry.npmjs.org/qs/-/qs-6.5.2.tgz", - "integrity": "sha512-N5ZAX4/LxJmF+7wN74pUD6qAh9/wnvdQcjq9TZjevvXzSUo7bfmw91saqMjzGS2xq91/odN2dW/WOl7qQHNDGA==" - } } }, "require-directory": { @@ -8263,6 +8337,19 @@ "ms": "2.0.0" } }, + "minimist": { + "version": "0.0.8", + "resolved": "https://registry.npmjs.org/minimist/-/minimist-0.0.8.tgz", + "integrity": "sha1-hX/Kv8M5fSYluCKCYuhqp6ARsF0=" + }, + "mkdirp": { + "version": "0.5.1", + "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.1.tgz", + "integrity": "sha1-MAV0OOrGz3+MR2fzhkjWaX11yQM=", + "requires": { + "minimist": "0.0.8" + } + }, "semver": { "version": "6.3.0", "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", @@ -8316,6 +8403,21 @@ "stable": "^0.1.8", "unquote": "~1.1.1", "util.promisify": "~1.0.0" + }, + "dependencies": { + "minimist": { + "version": "0.0.8", + "resolved": "https://registry.npmjs.org/minimist/-/minimist-0.0.8.tgz", + "integrity": "sha1-hX/Kv8M5fSYluCKCYuhqp6ARsF0=" + }, + "mkdirp": { + "version": "0.5.1", + "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.1.tgz", + "integrity": "sha1-MAV0OOrGz3+MR2fzhkjWaX11yQM=", + "requires": { + "minimist": "0.0.8" + } + } } }, "tapable": { @@ -9006,15 +9108,16 @@ } }, "vuepress-theme-cosmos": { - "version": "1.0.68", - "resolved": "https://registry.npmjs.org/vuepress-theme-cosmos/-/vuepress-theme-cosmos-1.0.68.tgz", - "integrity": "sha512-UCb5f1zgAaQkirlsLrbGFbCKO0EYnNN0ubUrgUljsvqOk7TOfDJNJiPKee3NS8Iye24IB6he2oFvjElpEufiwg==", + "version": "1.0.69", + "resolved": "https://registry.npmjs.org/vuepress-theme-cosmos/-/vuepress-theme-cosmos-1.0.69.tgz", + "integrity": "sha512-f7zOQg4S2CcQhI6YrVxiJaEyHYMx9stl1zyRVNmoBusT96SMBwJFzi8yDSuGfsIRX/vWHi840PJYogKv9VvUtA==", "requires": { "@cosmos-ui/vue": "^0.5.16", "@vuepress/plugin-last-updated": "^1.2.0", "@vuepress/plugin-search": "^1.1.0", "algoliasearch": "^3.35.1", "axios": "^0.19.0", + "docsearch.js": "^2.6.3", "intersection-observer": "^0.7.0", "lunr": "^2.3.8", "markdown-it": "^10.0.0", @@ -9082,6 +9185,19 @@ "version": "6.3.0", "resolved": "https://registry.npmjs.org/acorn/-/acorn-6.3.0.tgz", "integrity": "sha512-/czfa8BwS88b9gWQVhc8eknunSA2DoJpJyTQkhheIf5E48u1N0R4q/YxxsAeqRrmK9TQ/uYfgLDfZo91UlANIA==" + }, + "minimist": { + "version": "0.0.8", + "resolved": "https://registry.npmjs.org/minimist/-/minimist-0.0.8.tgz", + "integrity": "sha1-hX/Kv8M5fSYluCKCYuhqp6ARsF0=" + }, + "mkdirp": { + "version": "0.5.1", + "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.1.tgz", + "integrity": "sha1-MAV0OOrGz3+MR2fzhkjWaX11yQM=", + "requires": { + "minimist": "0.0.8" + } } } }, @@ -9104,6 +9220,21 @@ "mkdirp": "^0.5.1", "range-parser": "^1.2.1", "webpack-log": "^2.0.0" + }, + "dependencies": { + "minimist": { + "version": "0.0.8", + "resolved": "https://registry.npmjs.org/minimist/-/minimist-0.0.8.tgz", + "integrity": "sha1-hX/Kv8M5fSYluCKCYuhqp6ARsF0=" + }, + "mkdirp": { + "version": "0.5.1", + "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.1.tgz", + "integrity": "sha1-MAV0OOrGz3+MR2fzhkjWaX11yQM=", + "requires": { + "minimist": "0.0.8" + } + } } }, "webpack-dev-server": { diff --git a/docs/package.json b/docs/package.json index 75a346d7d1db..ce5124e33f51 100644 --- a/docs/package.json +++ b/docs/package.json @@ -14,6 +14,6 @@ "author": "", "license": "ISC", "dependencies": { - "vuepress-theme-cosmos": "^1.0.68" + "vuepress-theme-cosmos": "^1.0.69" } } From 132aa2744d0485f3e38c483da2d6b52c3dc21dbb Mon Sep 17 00:00:00 2001 From: Denis Fadeev Date: Thu, 21 Nov 2019 18:54:36 +0500 Subject: [PATCH 173/196] version --- docs/package-lock.json | 6 +++--- docs/package.json | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/docs/package-lock.json b/docs/package-lock.json index 95dc3d4ea5d8..a0fb9162997e 100644 --- a/docs/package-lock.json +++ b/docs/package-lock.json @@ -9108,9 +9108,9 @@ } }, "vuepress-theme-cosmos": { - "version": "1.0.69", - "resolved": "https://registry.npmjs.org/vuepress-theme-cosmos/-/vuepress-theme-cosmos-1.0.69.tgz", - "integrity": "sha512-f7zOQg4S2CcQhI6YrVxiJaEyHYMx9stl1zyRVNmoBusT96SMBwJFzi8yDSuGfsIRX/vWHi840PJYogKv9VvUtA==", + "version": "1.0.71", + "resolved": "https://registry.npmjs.org/vuepress-theme-cosmos/-/vuepress-theme-cosmos-1.0.71.tgz", + "integrity": "sha512-0e3BhxaUmIjO7O74vbUZTxyfDh29w3vrpWft2HImKLLXpKk4xo8LvxdeUJXPhqDPJp653tFYPBtjj1ggTecwFw==", "requires": { "@cosmos-ui/vue": "^0.5.16", "@vuepress/plugin-last-updated": "^1.2.0", diff --git a/docs/package.json b/docs/package.json index ce5124e33f51..304ac4672d49 100644 --- a/docs/package.json +++ b/docs/package.json @@ -14,6 +14,6 @@ "author": "", "license": "ISC", "dependencies": { - "vuepress-theme-cosmos": "^1.0.69" + "vuepress-theme-cosmos": "^1.0.71" } } From d152ffe0de22a25c5f0a190a0e11270036792a0b Mon Sep 17 00:00:00 2001 From: Denis Fadeev Date: Fri, 22 Nov 2019 20:42:48 +0500 Subject: [PATCH 174/196] version --- docs/package-lock.json | 24 ++++++++++++------------ docs/package.json | 2 +- 2 files changed, 13 insertions(+), 13 deletions(-) diff --git a/docs/package-lock.json b/docs/package-lock.json index a0fb9162997e..5699c617ae3e 100644 --- a/docs/package-lock.json +++ b/docs/package-lock.json @@ -3247,9 +3247,9 @@ "integrity": "sha1-WQxhFWsK4vTwJVcyoViyZrxWsh0=" }, "electron-to-chromium": { - "version": "1.3.309", - "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.3.309.tgz", - "integrity": "sha512-NZd91XD15v2UPLjYXoN/gLnkwIUQjdH4SQLpRCCQiYJH6BBkfgp5pWemBJPr1rZ2dl8Ee3o91O9Sa1QuAfZmog==" + "version": "1.3.310", + "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.3.310.tgz", + "integrity": "sha512-ixvxy46JrDv5c8k1+th66Z+xDZD8zShNs6oh7hgyMpNZUgaoRBisXgFZKAyyhQTAj7oU2Y/uZ0AAsj/TY4N0tA==" }, "elliptic": { "version": "6.5.1", @@ -5879,9 +5879,9 @@ } }, "node-releases": { - "version": "1.1.40", - "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-1.1.40.tgz", - "integrity": "sha512-r4LPcC5b/bS8BdtWH1fbeK88ib/wg9aqmg6/s3ngNLn2Ewkn/8J6Iw3P9RTlfIAdSdvYvQl2thCY5Y+qTAQ2iQ==", + "version": "1.1.41", + "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-1.1.41.tgz", + "integrity": "sha512-+IctMa7wIs8Cfsa8iYzeaLTFwv5Y4r5jZud+4AnfymzeEXKBCavFX0KBgzVaPVqf0ywa6PrO8/b+bPqdwjGBSg==", "requires": { "semver": "^6.3.0" }, @@ -7515,9 +7515,9 @@ "integrity": "sha1-79qpjqdFEyTQkrKyFjpqHXqaIUc=" }, "resolve": { - "version": "1.12.0", - "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.12.0.tgz", - "integrity": "sha512-B/dOmuoAik5bKcD6s6nXDCjzUKnaDvdkRyAk6rsmsKLipWj4797iothd7jmmUhWTfinVMU+wc56rYKsit2Qy4w==", + "version": "1.12.2", + "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.12.2.tgz", + "integrity": "sha512-cAVTI2VLHWYsGOirfeYVVQ7ZDejtQ9fp4YhYckWDEkFfqbVjaT11iM8k6xSAfGFMM+gDpZjMnFssPu8we+mqFw==", "requires": { "path-parse": "^1.0.6" } @@ -9108,9 +9108,9 @@ } }, "vuepress-theme-cosmos": { - "version": "1.0.71", - "resolved": "https://registry.npmjs.org/vuepress-theme-cosmos/-/vuepress-theme-cosmos-1.0.71.tgz", - "integrity": "sha512-0e3BhxaUmIjO7O74vbUZTxyfDh29w3vrpWft2HImKLLXpKk4xo8LvxdeUJXPhqDPJp653tFYPBtjj1ggTecwFw==", + "version": "1.0.73", + "resolved": "https://registry.npmjs.org/vuepress-theme-cosmos/-/vuepress-theme-cosmos-1.0.73.tgz", + "integrity": "sha512-WXuld8UBxRG89WpKtmfjOdilARxF6jgcpYdwy7nWe6kv3PA1MNT0S7hDL9nztCwRk/6GAs6rtkhKyAn5WGfvxQ==", "requires": { "@cosmos-ui/vue": "^0.5.16", "@vuepress/plugin-last-updated": "^1.2.0", diff --git a/docs/package.json b/docs/package.json index 304ac4672d49..cae26a7c3b00 100644 --- a/docs/package.json +++ b/docs/package.json @@ -14,6 +14,6 @@ "author": "", "license": "ISC", "dependencies": { - "vuepress-theme-cosmos": "^1.0.71" + "vuepress-theme-cosmos": "^1.0.73" } } From 90b184c792f472aeed30ae433efb86410656aa31 Mon Sep 17 00:00:00 2001 From: Denis Fadeev Date: Sat, 23 Nov 2019 22:28:37 +0500 Subject: [PATCH 175/196] version --- docs/package-lock.json | 646 +++++++++++++++++++++-------------------- docs/package.json | 3 +- 2 files changed, 328 insertions(+), 321 deletions(-) diff --git a/docs/package-lock.json b/docs/package-lock.json index 5699c617ae3e..d89904401d23 100644 --- a/docs/package-lock.json +++ b/docs/package-lock.json @@ -13,17 +13,17 @@ } }, "@babel/core": { - "version": "7.7.2", - "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.7.2.tgz", - "integrity": "sha512-eeD7VEZKfhK1KUXGiyPFettgF3m513f8FoBSWiQ1xTvl1RAopLs42Wp9+Ze911I6H0N9lNqJMDgoZT7gHsipeQ==", + "version": "7.7.4", + "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.7.4.tgz", + "integrity": "sha512-+bYbx56j4nYBmpsWtnPUsKW3NdnYxbqyfrP2w9wILBuHzdfIKz9prieZK0DFPyIzkjYVUe4QkusGL07r5pXznQ==", "requires": { "@babel/code-frame": "^7.5.5", - "@babel/generator": "^7.7.2", - "@babel/helpers": "^7.7.0", - "@babel/parser": "^7.7.2", - "@babel/template": "^7.7.0", - "@babel/traverse": "^7.7.2", - "@babel/types": "^7.7.2", + "@babel/generator": "^7.7.4", + "@babel/helpers": "^7.7.4", + "@babel/parser": "^7.7.4", + "@babel/template": "^7.7.4", + "@babel/traverse": "^7.7.4", + "@babel/types": "^7.7.4", "convert-source-map": "^1.7.0", "debug": "^4.1.0", "json5": "^2.1.0", @@ -62,11 +62,11 @@ } }, "@babel/generator": { - "version": "7.7.2", - "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.7.2.tgz", - "integrity": "sha512-WthSArvAjYLz4TcbKOi88me+KmDJdKSlfwwN8CnUYn9jBkzhq0ZEPuBfkAWIvjJ3AdEV1Cf/+eSQTnp3IDJKlQ==", + "version": "7.7.4", + "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.7.4.tgz", + "integrity": "sha512-m5qo2WgdOJeyYngKImbkyQrnUN1mPceaG5BV+G0E3gWsa4l/jCSryWJdM2x8OuGAOyh+3d5pVYfZWCiNFtynxg==", "requires": { - "@babel/types": "^7.7.2", + "@babel/types": "^7.7.4", "jsesc": "^2.5.1", "lodash": "^4.17.13", "source-map": "^0.5.0" @@ -80,134 +80,134 @@ } }, "@babel/helper-annotate-as-pure": { - "version": "7.7.0", - "resolved": "https://registry.npmjs.org/@babel/helper-annotate-as-pure/-/helper-annotate-as-pure-7.7.0.tgz", - "integrity": "sha512-k50CQxMlYTYo+GGyUGFwpxKVtxVJi9yh61sXZji3zYHccK9RYliZGSTOgci85T+r+0VFN2nWbGM04PIqwfrpMg==", + "version": "7.7.4", + "resolved": "https://registry.npmjs.org/@babel/helper-annotate-as-pure/-/helper-annotate-as-pure-7.7.4.tgz", + "integrity": "sha512-2BQmQgECKzYKFPpiycoF9tlb5HA4lrVyAmLLVK177EcQAqjVLciUb2/R+n1boQ9y5ENV3uz2ZqiNw7QMBBw1Og==", "requires": { - "@babel/types": "^7.7.0" + "@babel/types": "^7.7.4" } }, "@babel/helper-builder-binary-assignment-operator-visitor": { - "version": "7.7.0", - "resolved": "https://registry.npmjs.org/@babel/helper-builder-binary-assignment-operator-visitor/-/helper-builder-binary-assignment-operator-visitor-7.7.0.tgz", - "integrity": "sha512-Cd8r8zs4RKDwMG/92lpZcnn5WPQ3LAMQbCw42oqUh4s7vsSN5ANUZjMel0OOnxDLq57hoDDbai+ryygYfCTOsw==", + "version": "7.7.4", + "resolved": "https://registry.npmjs.org/@babel/helper-builder-binary-assignment-operator-visitor/-/helper-builder-binary-assignment-operator-visitor-7.7.4.tgz", + "integrity": "sha512-Biq/d/WtvfftWZ9Uf39hbPBYDUo986m5Bb4zhkeYDGUllF43D+nUe5M6Vuo6/8JDK/0YX/uBdeoQpyaNhNugZQ==", "requires": { - "@babel/helper-explode-assignable-expression": "^7.7.0", - "@babel/types": "^7.7.0" + "@babel/helper-explode-assignable-expression": "^7.7.4", + "@babel/types": "^7.7.4" } }, "@babel/helper-call-delegate": { - "version": "7.7.0", - "resolved": "https://registry.npmjs.org/@babel/helper-call-delegate/-/helper-call-delegate-7.7.0.tgz", - "integrity": "sha512-Su0Mdq7uSSWGZayGMMQ+z6lnL00mMCnGAbO/R0ZO9odIdB/WNU/VfQKqMQU0fdIsxQYbRjDM4BixIa93SQIpvw==", + "version": "7.7.4", + "resolved": "https://registry.npmjs.org/@babel/helper-call-delegate/-/helper-call-delegate-7.7.4.tgz", + "integrity": "sha512-8JH9/B7J7tCYJ2PpWVpw9JhPuEVHztagNVuQAFBVFYluRMlpG7F1CgKEgGeL6KFqcsIa92ZYVj6DSc0XwmN1ZA==", "requires": { - "@babel/helper-hoist-variables": "^7.7.0", - "@babel/traverse": "^7.7.0", - "@babel/types": "^7.7.0" + "@babel/helper-hoist-variables": "^7.7.4", + "@babel/traverse": "^7.7.4", + "@babel/types": "^7.7.4" } }, "@babel/helper-create-class-features-plugin": { - "version": "7.7.0", - "resolved": "https://registry.npmjs.org/@babel/helper-create-class-features-plugin/-/helper-create-class-features-plugin-7.7.0.tgz", - "integrity": "sha512-MZiB5qvTWoyiFOgootmRSDV1udjIqJW/8lmxgzKq6oDqxdmHUjeP2ZUOmgHdYjmUVNABqRrHjYAYRvj8Eox/UA==", + "version": "7.7.4", + "resolved": "https://registry.npmjs.org/@babel/helper-create-class-features-plugin/-/helper-create-class-features-plugin-7.7.4.tgz", + "integrity": "sha512-l+OnKACG4uiDHQ/aJT8dwpR+LhCJALxL0mJ6nzjB25e5IPwqV1VOsY7ah6UB1DG+VOXAIMtuC54rFJGiHkxjgA==", "requires": { - "@babel/helper-function-name": "^7.7.0", - "@babel/helper-member-expression-to-functions": "^7.7.0", - "@babel/helper-optimise-call-expression": "^7.7.0", + "@babel/helper-function-name": "^7.7.4", + "@babel/helper-member-expression-to-functions": "^7.7.4", + "@babel/helper-optimise-call-expression": "^7.7.4", "@babel/helper-plugin-utils": "^7.0.0", - "@babel/helper-replace-supers": "^7.7.0", - "@babel/helper-split-export-declaration": "^7.7.0" + "@babel/helper-replace-supers": "^7.7.4", + "@babel/helper-split-export-declaration": "^7.7.4" } }, "@babel/helper-create-regexp-features-plugin": { - "version": "7.7.2", - "resolved": "https://registry.npmjs.org/@babel/helper-create-regexp-features-plugin/-/helper-create-regexp-features-plugin-7.7.2.tgz", - "integrity": "sha512-pAil/ZixjTlrzNpjx+l/C/wJk002Wo7XbbZ8oujH/AoJ3Juv0iN/UTcPUHXKMFLqsfS0Hy6Aow8M31brUYBlQQ==", + "version": "7.7.4", + "resolved": "https://registry.npmjs.org/@babel/helper-create-regexp-features-plugin/-/helper-create-regexp-features-plugin-7.7.4.tgz", + "integrity": "sha512-Mt+jBKaxL0zfOIWrfQpnfYCN7/rS6GKx6CCCfuoqVVd+17R8zNDlzVYmIi9qyb2wOk002NsmSTDymkIygDUH7A==", "requires": { "@babel/helper-regex": "^7.4.4", "regexpu-core": "^4.6.0" } }, "@babel/helper-define-map": { - "version": "7.7.0", - "resolved": "https://registry.npmjs.org/@babel/helper-define-map/-/helper-define-map-7.7.0.tgz", - "integrity": "sha512-kPKWPb0dMpZi+ov1hJiwse9dWweZsz3V9rP4KdytnX1E7z3cTNmFGglwklzFPuqIcHLIY3bgKSs4vkwXXdflQA==", + "version": "7.7.4", + "resolved": "https://registry.npmjs.org/@babel/helper-define-map/-/helper-define-map-7.7.4.tgz", + "integrity": "sha512-v5LorqOa0nVQUvAUTUF3KPastvUt/HzByXNamKQ6RdJRTV7j8rLL+WB5C/MzzWAwOomxDhYFb1wLLxHqox86lg==", "requires": { - "@babel/helper-function-name": "^7.7.0", - "@babel/types": "^7.7.0", + "@babel/helper-function-name": "^7.7.4", + "@babel/types": "^7.7.4", "lodash": "^4.17.13" } }, "@babel/helper-explode-assignable-expression": { - "version": "7.7.0", - "resolved": "https://registry.npmjs.org/@babel/helper-explode-assignable-expression/-/helper-explode-assignable-expression-7.7.0.tgz", - "integrity": "sha512-CDs26w2shdD1urNUAji2RJXyBFCaR+iBEGnFz3l7maizMkQe3saVw9WtjG1tz8CwbjvlFnaSLVhgnu1SWaherg==", + "version": "7.7.4", + "resolved": "https://registry.npmjs.org/@babel/helper-explode-assignable-expression/-/helper-explode-assignable-expression-7.7.4.tgz", + "integrity": "sha512-2/SicuFrNSXsZNBxe5UGdLr+HZg+raWBLE9vC98bdYOKX/U6PY0mdGlYUJdtTDPSU0Lw0PNbKKDpwYHJLn2jLg==", "requires": { - "@babel/traverse": "^7.7.0", - "@babel/types": "^7.7.0" + "@babel/traverse": "^7.7.4", + "@babel/types": "^7.7.4" } }, "@babel/helper-function-name": { - "version": "7.7.0", - "resolved": "https://registry.npmjs.org/@babel/helper-function-name/-/helper-function-name-7.7.0.tgz", - "integrity": "sha512-tDsJgMUAP00Ugv8O2aGEua5I2apkaQO7lBGUq1ocwN3G23JE5Dcq0uh3GvFTChPa4b40AWiAsLvCZOA2rdnQ7Q==", + "version": "7.7.4", + "resolved": "https://registry.npmjs.org/@babel/helper-function-name/-/helper-function-name-7.7.4.tgz", + "integrity": "sha512-AnkGIdiBhEuiwdoMnKm7jfPfqItZhgRaZfMg1XX3bS25INOnLPjPG1Ppnajh8eqgt5kPJnfqrRHqFqmjKDZLzQ==", "requires": { - "@babel/helper-get-function-arity": "^7.7.0", - "@babel/template": "^7.7.0", - "@babel/types": "^7.7.0" + "@babel/helper-get-function-arity": "^7.7.4", + "@babel/template": "^7.7.4", + "@babel/types": "^7.7.4" } }, "@babel/helper-get-function-arity": { - "version": "7.7.0", - "resolved": "https://registry.npmjs.org/@babel/helper-get-function-arity/-/helper-get-function-arity-7.7.0.tgz", - "integrity": "sha512-tLdojOTz4vWcEnHWHCuPN5P85JLZWbm5Fx5ZsMEMPhF3Uoe3O7awrbM2nQ04bDOUToH/2tH/ezKEOR8zEYzqyw==", + "version": "7.7.4", + "resolved": "https://registry.npmjs.org/@babel/helper-get-function-arity/-/helper-get-function-arity-7.7.4.tgz", + "integrity": "sha512-QTGKEdCkjgzgfJ3bAyRwF4yyT3pg+vDgan8DSivq1eS0gwi+KGKE5x8kRcbeFTb/673mkO5SN1IZfmCfA5o+EA==", "requires": { - "@babel/types": "^7.7.0" + "@babel/types": "^7.7.4" } }, "@babel/helper-hoist-variables": { - "version": "7.7.0", - "resolved": "https://registry.npmjs.org/@babel/helper-hoist-variables/-/helper-hoist-variables-7.7.0.tgz", - "integrity": "sha512-LUe/92NqsDAkJjjCEWkNe+/PcpnisvnqdlRe19FahVapa4jndeuJ+FBiTX1rcAKWKcJGE+C3Q3tuEuxkSmCEiQ==", + "version": "7.7.4", + "resolved": "https://registry.npmjs.org/@babel/helper-hoist-variables/-/helper-hoist-variables-7.7.4.tgz", + "integrity": "sha512-wQC4xyvc1Jo/FnLirL6CEgPgPCa8M74tOdjWpRhQYapz5JC7u3NYU1zCVoVAGCE3EaIP9T1A3iW0WLJ+reZlpQ==", "requires": { - "@babel/types": "^7.7.0" + "@babel/types": "^7.7.4" } }, "@babel/helper-member-expression-to-functions": { - "version": "7.7.0", - "resolved": "https://registry.npmjs.org/@babel/helper-member-expression-to-functions/-/helper-member-expression-to-functions-7.7.0.tgz", - "integrity": "sha512-QaCZLO2RtBcmvO/ekOLp8p7R5X2JriKRizeDpm5ChATAFWrrYDcDxPuCIBXKyBjY+i1vYSdcUTMIb8psfxHDPA==", + "version": "7.7.4", + "resolved": "https://registry.npmjs.org/@babel/helper-member-expression-to-functions/-/helper-member-expression-to-functions-7.7.4.tgz", + "integrity": "sha512-9KcA1X2E3OjXl/ykfMMInBK+uVdfIVakVe7W7Lg3wfXUNyS3Q1HWLFRwZIjhqiCGbslummPDnmb7vIekS0C1vw==", "requires": { - "@babel/types": "^7.7.0" + "@babel/types": "^7.7.4" } }, "@babel/helper-module-imports": { - "version": "7.7.0", - "resolved": "https://registry.npmjs.org/@babel/helper-module-imports/-/helper-module-imports-7.7.0.tgz", - "integrity": "sha512-Dv3hLKIC1jyfTkClvyEkYP2OlkzNvWs5+Q8WgPbxM5LMeorons7iPP91JM+DU7tRbhqA1ZeooPaMFvQrn23RHw==", + "version": "7.7.4", + "resolved": "https://registry.npmjs.org/@babel/helper-module-imports/-/helper-module-imports-7.7.4.tgz", + "integrity": "sha512-dGcrX6K9l8258WFjyDLJwuVKxR4XZfU0/vTUgOQYWEnRD8mgr+p4d6fCUMq/ys0h4CCt/S5JhbvtyErjWouAUQ==", "requires": { - "@babel/types": "^7.7.0" + "@babel/types": "^7.7.4" } }, "@babel/helper-module-transforms": { - "version": "7.7.0", - "resolved": "https://registry.npmjs.org/@babel/helper-module-transforms/-/helper-module-transforms-7.7.0.tgz", - "integrity": "sha512-rXEefBuheUYQyX4WjV19tuknrJFwyKw0HgzRwbkyTbB+Dshlq7eqkWbyjzToLrMZk/5wKVKdWFluiAsVkHXvuQ==", - "requires": { - "@babel/helper-module-imports": "^7.7.0", - "@babel/helper-simple-access": "^7.7.0", - "@babel/helper-split-export-declaration": "^7.7.0", - "@babel/template": "^7.7.0", - "@babel/types": "^7.7.0", + "version": "7.7.4", + "resolved": "https://registry.npmjs.org/@babel/helper-module-transforms/-/helper-module-transforms-7.7.4.tgz", + "integrity": "sha512-ehGBu4mXrhs0FxAqN8tWkzF8GSIGAiEumu4ONZ/hD9M88uHcD+Yu2ttKfOCgwzoesJOJrtQh7trI5YPbRtMmnA==", + "requires": { + "@babel/helper-module-imports": "^7.7.4", + "@babel/helper-simple-access": "^7.7.4", + "@babel/helper-split-export-declaration": "^7.7.4", + "@babel/template": "^7.7.4", + "@babel/types": "^7.7.4", "lodash": "^4.17.13" } }, "@babel/helper-optimise-call-expression": { - "version": "7.7.0", - "resolved": "https://registry.npmjs.org/@babel/helper-optimise-call-expression/-/helper-optimise-call-expression-7.7.0.tgz", - "integrity": "sha512-48TeqmbazjNU/65niiiJIJRc5JozB8acui1OS7bSd6PgxfuovWsvjfWSzlgx+gPFdVveNzUdpdIg5l56Pl5jqg==", + "version": "7.7.4", + "resolved": "https://registry.npmjs.org/@babel/helper-optimise-call-expression/-/helper-optimise-call-expression-7.7.4.tgz", + "integrity": "sha512-VB7gWZ2fDkSuqW6b1AKXkJWO5NyNI3bFL/kK79/30moK57blr6NbH8xcl2XcKCwOmJosftWunZqfO84IGq3ZZg==", "requires": { - "@babel/types": "^7.7.0" + "@babel/types": "^7.7.4" } }, "@babel/helper-plugin-utils": { @@ -224,64 +224,64 @@ } }, "@babel/helper-remap-async-to-generator": { - "version": "7.7.0", - "resolved": "https://registry.npmjs.org/@babel/helper-remap-async-to-generator/-/helper-remap-async-to-generator-7.7.0.tgz", - "integrity": "sha512-pHx7RN8X0UNHPB/fnuDnRXVZ316ZigkO8y8D835JlZ2SSdFKb6yH9MIYRU4fy/KPe5sPHDFOPvf8QLdbAGGiyw==", + "version": "7.7.4", + "resolved": "https://registry.npmjs.org/@babel/helper-remap-async-to-generator/-/helper-remap-async-to-generator-7.7.4.tgz", + "integrity": "sha512-Sk4xmtVdM9sA/jCI80f+KS+Md+ZHIpjuqmYPk1M7F/upHou5e4ReYmExAiu6PVe65BhJPZA2CY9x9k4BqE5klw==", "requires": { - "@babel/helper-annotate-as-pure": "^7.7.0", - "@babel/helper-wrap-function": "^7.7.0", - "@babel/template": "^7.7.0", - "@babel/traverse": "^7.7.0", - "@babel/types": "^7.7.0" + "@babel/helper-annotate-as-pure": "^7.7.4", + "@babel/helper-wrap-function": "^7.7.4", + "@babel/template": "^7.7.4", + "@babel/traverse": "^7.7.4", + "@babel/types": "^7.7.4" } }, "@babel/helper-replace-supers": { - "version": "7.7.0", - "resolved": "https://registry.npmjs.org/@babel/helper-replace-supers/-/helper-replace-supers-7.7.0.tgz", - "integrity": "sha512-5ALYEul5V8xNdxEeWvRsBzLMxQksT7MaStpxjJf9KsnLxpAKBtfw5NeMKZJSYDa0lKdOcy0g+JT/f5mPSulUgg==", + "version": "7.7.4", + "resolved": "https://registry.npmjs.org/@babel/helper-replace-supers/-/helper-replace-supers-7.7.4.tgz", + "integrity": "sha512-pP0tfgg9hsZWo5ZboYGuBn/bbYT/hdLPVSS4NMmiRJdwWhP0IznPwN9AE1JwyGsjSPLC364I0Qh5p+EPkGPNpg==", "requires": { - "@babel/helper-member-expression-to-functions": "^7.7.0", - "@babel/helper-optimise-call-expression": "^7.7.0", - "@babel/traverse": "^7.7.0", - "@babel/types": "^7.7.0" + "@babel/helper-member-expression-to-functions": "^7.7.4", + "@babel/helper-optimise-call-expression": "^7.7.4", + "@babel/traverse": "^7.7.4", + "@babel/types": "^7.7.4" } }, "@babel/helper-simple-access": { - "version": "7.7.0", - "resolved": "https://registry.npmjs.org/@babel/helper-simple-access/-/helper-simple-access-7.7.0.tgz", - "integrity": "sha512-AJ7IZD7Eem3zZRuj5JtzFAptBw7pMlS3y8Qv09vaBWoFsle0d1kAn5Wq6Q9MyBXITPOKnxwkZKoAm4bopmv26g==", + "version": "7.7.4", + "resolved": "https://registry.npmjs.org/@babel/helper-simple-access/-/helper-simple-access-7.7.4.tgz", + "integrity": "sha512-zK7THeEXfan7UlWsG2A6CI/L9jVnI5+xxKZOdej39Y0YtDYKx9raHk5F2EtK9K8DHRTihYwg20ADt9S36GR78A==", "requires": { - "@babel/template": "^7.7.0", - "@babel/types": "^7.7.0" + "@babel/template": "^7.7.4", + "@babel/types": "^7.7.4" } }, "@babel/helper-split-export-declaration": { - "version": "7.7.0", - "resolved": "https://registry.npmjs.org/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.7.0.tgz", - "integrity": "sha512-HgYSI8rH08neWlAH3CcdkFg9qX9YsZysZI5GD8LjhQib/mM0jGOZOVkoUiiV2Hu978fRtjtsGsW6w0pKHUWtqA==", + "version": "7.7.4", + "resolved": "https://registry.npmjs.org/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.7.4.tgz", + "integrity": "sha512-guAg1SXFcVr04Guk9eq0S4/rWS++sbmyqosJzVs8+1fH5NI+ZcmkaSkc7dmtAFbHFva6yRJnjW3yAcGxjueDug==", "requires": { - "@babel/types": "^7.7.0" + "@babel/types": "^7.7.4" } }, "@babel/helper-wrap-function": { - "version": "7.7.0", - "resolved": "https://registry.npmjs.org/@babel/helper-wrap-function/-/helper-wrap-function-7.7.0.tgz", - "integrity": "sha512-sd4QjeMgQqzshSjecZjOp8uKfUtnpmCyQhKQrVJBBgeHAB/0FPi33h3AbVlVp07qQtMD4QgYSzaMI7VwncNK/w==", + "version": "7.7.4", + "resolved": "https://registry.npmjs.org/@babel/helper-wrap-function/-/helper-wrap-function-7.7.4.tgz", + "integrity": "sha512-VsfzZt6wmsocOaVU0OokwrIytHND55yvyT4BPB9AIIgwr8+x7617hetdJTsuGwygN5RC6mxA9EJztTjuwm2ofg==", "requires": { - "@babel/helper-function-name": "^7.7.0", - "@babel/template": "^7.7.0", - "@babel/traverse": "^7.7.0", - "@babel/types": "^7.7.0" + "@babel/helper-function-name": "^7.7.4", + "@babel/template": "^7.7.4", + "@babel/traverse": "^7.7.4", + "@babel/types": "^7.7.4" } }, "@babel/helpers": { - "version": "7.7.0", - "resolved": "https://registry.npmjs.org/@babel/helpers/-/helpers-7.7.0.tgz", - "integrity": "sha512-VnNwL4YOhbejHb7x/b5F39Zdg5vIQpUUNzJwx0ww1EcVRt41bbGRZWhAURrfY32T5zTT3qwNOQFWpn+P0i0a2g==", + "version": "7.7.4", + "resolved": "https://registry.npmjs.org/@babel/helpers/-/helpers-7.7.4.tgz", + "integrity": "sha512-ak5NGZGJ6LV85Q1Zc9gn2n+ayXOizryhjSUBTdu5ih1tlVCJeuQENzc4ItyCVhINVXvIT/ZQ4mheGIsfBkpskg==", "requires": { - "@babel/template": "^7.7.0", - "@babel/traverse": "^7.7.0", - "@babel/types": "^7.7.0" + "@babel/template": "^7.7.4", + "@babel/traverse": "^7.7.4", + "@babel/types": "^7.7.4" } }, "@babel/highlight": { @@ -295,390 +295,390 @@ } }, "@babel/parser": { - "version": "7.7.3", - "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.7.3.tgz", - "integrity": "sha512-bqv+iCo9i+uLVbI0ILzKkvMorqxouI+GbV13ivcARXn9NNEabi2IEz912IgNpT/60BNXac5dgcfjb94NjsF33A==" + "version": "7.7.4", + "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.7.4.tgz", + "integrity": "sha512-jIwvLO0zCL+O/LmEJQjWA75MQTWwx3c3u2JOTDK5D3/9egrWRRA0/0hk9XXywYnXZVVpzrBYeIQTmhwUaePI9g==" }, "@babel/plugin-proposal-async-generator-functions": { - "version": "7.7.0", - "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-async-generator-functions/-/plugin-proposal-async-generator-functions-7.7.0.tgz", - "integrity": "sha512-ot/EZVvf3mXtZq0Pd0+tSOfGWMizqmOohXmNZg6LNFjHOV+wOPv7BvVYh8oPR8LhpIP3ye8nNooKL50YRWxpYA==", + "version": "7.7.4", + "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-async-generator-functions/-/plugin-proposal-async-generator-functions-7.7.4.tgz", + "integrity": "sha512-1ypyZvGRXriY/QP668+s8sFr2mqinhkRDMPSQLNghCQE+GAkFtp+wkHVvg2+Hdki8gwP+NFzJBJ/N1BfzCCDEw==", "requires": { "@babel/helper-plugin-utils": "^7.0.0", - "@babel/helper-remap-async-to-generator": "^7.7.0", - "@babel/plugin-syntax-async-generators": "^7.2.0" + "@babel/helper-remap-async-to-generator": "^7.7.4", + "@babel/plugin-syntax-async-generators": "^7.7.4" } }, "@babel/plugin-proposal-class-properties": { - "version": "7.7.0", - "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-class-properties/-/plugin-proposal-class-properties-7.7.0.tgz", - "integrity": "sha512-tufDcFA1Vj+eWvwHN+jvMN6QsV5o+vUlytNKrbMiCeDL0F2j92RURzUsUMWE5EJkLyWxjdUslCsMQa9FWth16A==", + "version": "7.7.4", + "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-class-properties/-/plugin-proposal-class-properties-7.7.4.tgz", + "integrity": "sha512-EcuXeV4Hv1X3+Q1TsuOmyyxeTRiSqurGJ26+I/FW1WbymmRRapVORm6x1Zl3iDIHyRxEs+VXWp6qnlcfcJSbbw==", "requires": { - "@babel/helper-create-class-features-plugin": "^7.7.0", + "@babel/helper-create-class-features-plugin": "^7.7.4", "@babel/helper-plugin-utils": "^7.0.0" } }, "@babel/plugin-proposal-decorators": { - "version": "7.7.0", - "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-decorators/-/plugin-proposal-decorators-7.7.0.tgz", - "integrity": "sha512-dMCDKmbYFQQTn1+VJjl5hbqlweuHl5oDeMU9B1Q7oAWi0mHxjQQDHdJIK6iW76NE1KJT3zA6dDU3weR1WT5D4A==", + "version": "7.7.4", + "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-decorators/-/plugin-proposal-decorators-7.7.4.tgz", + "integrity": "sha512-GftcVDcLCwVdzKmwOBDjATd548+IE+mBo7ttgatqNDR7VG7GqIuZPtRWlMLHbhTXhcnFZiGER8iIYl1n/imtsg==", "requires": { - "@babel/helper-create-class-features-plugin": "^7.7.0", + "@babel/helper-create-class-features-plugin": "^7.7.4", "@babel/helper-plugin-utils": "^7.0.0", - "@babel/plugin-syntax-decorators": "^7.2.0" + "@babel/plugin-syntax-decorators": "^7.7.4" } }, "@babel/plugin-proposal-json-strings": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-json-strings/-/plugin-proposal-json-strings-7.2.0.tgz", - "integrity": "sha512-MAFV1CA/YVmYwZG0fBQyXhmj0BHCB5egZHCKWIFVv/XCxAeVGIHfos3SwDck4LvCllENIAg7xMKOG5kH0dzyUg==", + "version": "7.7.4", + "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-json-strings/-/plugin-proposal-json-strings-7.7.4.tgz", + "integrity": "sha512-wQvt3akcBTfLU/wYoqm/ws7YOAQKu8EVJEvHip/mzkNtjaclQoCCIqKXFP5/eyfnfbQCDV3OLRIK3mIVyXuZlw==", "requires": { "@babel/helper-plugin-utils": "^7.0.0", - "@babel/plugin-syntax-json-strings": "^7.2.0" + "@babel/plugin-syntax-json-strings": "^7.7.4" } }, "@babel/plugin-proposal-object-rest-spread": { - "version": "7.6.2", - "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-object-rest-spread/-/plugin-proposal-object-rest-spread-7.6.2.tgz", - "integrity": "sha512-LDBXlmADCsMZV1Y9OQwMc0MyGZ8Ta/zlD9N67BfQT8uYwkRswiu2hU6nJKrjrt/58aH/vqfQlR/9yId/7A2gWw==", + "version": "7.7.4", + "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-object-rest-spread/-/plugin-proposal-object-rest-spread-7.7.4.tgz", + "integrity": "sha512-rnpnZR3/iWKmiQyJ3LKJpSwLDcX/nSXhdLk4Aq/tXOApIvyu7qoabrige0ylsAJffaUC51WiBu209Q0U+86OWQ==", "requires": { "@babel/helper-plugin-utils": "^7.0.0", - "@babel/plugin-syntax-object-rest-spread": "^7.2.0" + "@babel/plugin-syntax-object-rest-spread": "^7.7.4" } }, "@babel/plugin-proposal-optional-catch-binding": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-optional-catch-binding/-/plugin-proposal-optional-catch-binding-7.2.0.tgz", - "integrity": "sha512-mgYj3jCcxug6KUcX4OBoOJz3CMrwRfQELPQ5560F70YQUBZB7uac9fqaWamKR1iWUzGiK2t0ygzjTScZnVz75g==", + "version": "7.7.4", + "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-optional-catch-binding/-/plugin-proposal-optional-catch-binding-7.7.4.tgz", + "integrity": "sha512-DyM7U2bnsQerCQ+sejcTNZh8KQEUuC3ufzdnVnSiUv/qoGJp2Z3hanKL18KDhsBT5Wj6a7CMT5mdyCNJsEaA9w==", "requires": { "@babel/helper-plugin-utils": "^7.0.0", - "@babel/plugin-syntax-optional-catch-binding": "^7.2.0" + "@babel/plugin-syntax-optional-catch-binding": "^7.7.4" } }, "@babel/plugin-proposal-unicode-property-regex": { - "version": "7.7.0", - "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-unicode-property-regex/-/plugin-proposal-unicode-property-regex-7.7.0.tgz", - "integrity": "sha512-mk34H+hp7kRBWJOOAR0ZMGCydgKMD4iN9TpDRp3IIcbunltxEY89XSimc6WbtSLCDrwcdy/EEw7h5CFCzxTchw==", + "version": "7.7.4", + "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-unicode-property-regex/-/plugin-proposal-unicode-property-regex-7.7.4.tgz", + "integrity": "sha512-cHgqHgYvffluZk85dJ02vloErm3Y6xtH+2noOBOJ2kXOJH3aVCDnj5eR/lVNlTnYu4hndAPJD3rTFjW3qee0PA==", "requires": { - "@babel/helper-create-regexp-features-plugin": "^7.7.0", + "@babel/helper-create-regexp-features-plugin": "^7.7.4", "@babel/helper-plugin-utils": "^7.0.0" } }, "@babel/plugin-syntax-async-generators": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-async-generators/-/plugin-syntax-async-generators-7.2.0.tgz", - "integrity": "sha512-1ZrIRBv2t0GSlcwVoQ6VgSLpLgiN/FVQUzt9znxo7v2Ov4jJrs8RY8tv0wvDmFN3qIdMKWrmMMW6yZ0G19MfGg==", + "version": "7.7.4", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-async-generators/-/plugin-syntax-async-generators-7.7.4.tgz", + "integrity": "sha512-Li4+EjSpBgxcsmeEF8IFcfV/+yJGxHXDirDkEoyFjumuwbmfCVHUt0HuowD/iGM7OhIRyXJH9YXxqiH6N815+g==", "requires": { "@babel/helper-plugin-utils": "^7.0.0" } }, "@babel/plugin-syntax-decorators": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-decorators/-/plugin-syntax-decorators-7.2.0.tgz", - "integrity": "sha512-38QdqVoXdHUQfTpZo3rQwqQdWtCn5tMv4uV6r2RMfTqNBuv4ZBhz79SfaQWKTVmxHjeFv/DnXVC/+agHCklYWA==", + "version": "7.7.4", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-decorators/-/plugin-syntax-decorators-7.7.4.tgz", + "integrity": "sha512-0oNLWNH4k5ZbBVfAwiTU53rKFWIeTh6ZlaWOXWJc4ywxs0tjz5fc3uZ6jKAnZSxN98eXVgg7bJIuzjX+3SXY+A==", "requires": { "@babel/helper-plugin-utils": "^7.0.0" } }, "@babel/plugin-syntax-dynamic-import": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-dynamic-import/-/plugin-syntax-dynamic-import-7.2.0.tgz", - "integrity": "sha512-mVxuJ0YroI/h/tbFTPGZR8cv6ai+STMKNBq0f8hFxsxWjl94qqhsb+wXbpNMDPU3cfR1TIsVFzU3nXyZMqyK4w==", + "version": "7.7.4", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-dynamic-import/-/plugin-syntax-dynamic-import-7.7.4.tgz", + "integrity": "sha512-jHQW0vbRGvwQNgyVxwDh4yuXu4bH1f5/EICJLAhl1SblLs2CDhrsmCk+v5XLdE9wxtAFRyxx+P//Iw+a5L/tTg==", "requires": { "@babel/helper-plugin-utils": "^7.0.0" } }, "@babel/plugin-syntax-json-strings": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-json-strings/-/plugin-syntax-json-strings-7.2.0.tgz", - "integrity": "sha512-5UGYnMSLRE1dqqZwug+1LISpA403HzlSfsg6P9VXU6TBjcSHeNlw4DxDx7LgpF+iKZoOG/+uzqoRHTdcUpiZNg==", + "version": "7.7.4", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-json-strings/-/plugin-syntax-json-strings-7.7.4.tgz", + "integrity": "sha512-QpGupahTQW1mHRXddMG5srgpHWqRLwJnJZKXTigB9RPFCCGbDGCgBeM/iC82ICXp414WeYx/tD54w7M2qRqTMg==", "requires": { "@babel/helper-plugin-utils": "^7.0.0" } }, "@babel/plugin-syntax-jsx": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-jsx/-/plugin-syntax-jsx-7.2.0.tgz", - "integrity": "sha512-VyN4QANJkRW6lDBmENzRszvZf3/4AXaj9YR7GwrWeeN9tEBPuXbmDYVU9bYBN0D70zCWVwUy0HWq2553VCb6Hw==", + "version": "7.7.4", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-jsx/-/plugin-syntax-jsx-7.7.4.tgz", + "integrity": "sha512-wuy6fiMe9y7HeZBWXYCGt2RGxZOj0BImZ9EyXJVnVGBKO/Br592rbR3rtIQn0eQhAk9vqaKP5n8tVqEFBQMfLg==", "requires": { "@babel/helper-plugin-utils": "^7.0.0" } }, "@babel/plugin-syntax-object-rest-spread": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-object-rest-spread/-/plugin-syntax-object-rest-spread-7.2.0.tgz", - "integrity": "sha512-t0JKGgqk2We+9may3t0xDdmneaXmyxq0xieYcKHxIsrJO64n1OiMWNUtc5gQK1PA0NpdCRrtZp4z+IUaKugrSA==", + "version": "7.7.4", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-object-rest-spread/-/plugin-syntax-object-rest-spread-7.7.4.tgz", + "integrity": "sha512-mObR+r+KZq0XhRVS2BrBKBpr5jqrqzlPvS9C9vuOf5ilSwzloAl7RPWLrgKdWS6IreaVrjHxTjtyqFiOisaCwg==", "requires": { "@babel/helper-plugin-utils": "^7.0.0" } }, "@babel/plugin-syntax-optional-catch-binding": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-optional-catch-binding/-/plugin-syntax-optional-catch-binding-7.2.0.tgz", - "integrity": "sha512-bDe4xKNhb0LI7IvZHiA13kff0KEfaGX/Hv4lMA9+7TEc63hMNvfKo6ZFpXhKuEp+II/q35Gc4NoMeDZyaUbj9w==", + "version": "7.7.4", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-optional-catch-binding/-/plugin-syntax-optional-catch-binding-7.7.4.tgz", + "integrity": "sha512-4ZSuzWgFxqHRE31Glu+fEr/MirNZOMYmD/0BhBWyLyOOQz/gTAl7QmWm2hX1QxEIXsr2vkdlwxIzTyiYRC4xcQ==", "requires": { "@babel/helper-plugin-utils": "^7.0.0" } }, "@babel/plugin-transform-arrow-functions": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-arrow-functions/-/plugin-transform-arrow-functions-7.2.0.tgz", - "integrity": "sha512-ER77Cax1+8/8jCB9fo4Ud161OZzWN5qawi4GusDuRLcDbDG+bIGYY20zb2dfAFdTRGzrfq2xZPvF0R64EHnimg==", + "version": "7.7.4", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-arrow-functions/-/plugin-transform-arrow-functions-7.7.4.tgz", + "integrity": "sha512-zUXy3e8jBNPiffmqkHRNDdZM2r8DWhCB7HhcoyZjiK1TxYEluLHAvQuYnTT+ARqRpabWqy/NHkO6e3MsYB5YfA==", "requires": { "@babel/helper-plugin-utils": "^7.0.0" } }, "@babel/plugin-transform-async-to-generator": { - "version": "7.7.0", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-async-to-generator/-/plugin-transform-async-to-generator-7.7.0.tgz", - "integrity": "sha512-vLI2EFLVvRBL3d8roAMqtVY0Bm9C1QzLkdS57hiKrjUBSqsQYrBsMCeOg/0KK7B0eK9V71J5mWcha9yyoI2tZw==", + "version": "7.7.4", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-async-to-generator/-/plugin-transform-async-to-generator-7.7.4.tgz", + "integrity": "sha512-zpUTZphp5nHokuy8yLlyafxCJ0rSlFoSHypTUWgpdwoDXWQcseaect7cJ8Ppk6nunOM6+5rPMkod4OYKPR5MUg==", "requires": { - "@babel/helper-module-imports": "^7.7.0", + "@babel/helper-module-imports": "^7.7.4", "@babel/helper-plugin-utils": "^7.0.0", - "@babel/helper-remap-async-to-generator": "^7.7.0" + "@babel/helper-remap-async-to-generator": "^7.7.4" } }, "@babel/plugin-transform-block-scoped-functions": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-block-scoped-functions/-/plugin-transform-block-scoped-functions-7.2.0.tgz", - "integrity": "sha512-ntQPR6q1/NKuphly49+QiQiTN0O63uOwjdD6dhIjSWBI5xlrbUFh720TIpzBhpnrLfv2tNH/BXvLIab1+BAI0w==", + "version": "7.7.4", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-block-scoped-functions/-/plugin-transform-block-scoped-functions-7.7.4.tgz", + "integrity": "sha512-kqtQzwtKcpPclHYjLK//3lH8OFsCDuDJBaFhVwf8kqdnF6MN4l618UDlcA7TfRs3FayrHj+svYnSX8MC9zmUyQ==", "requires": { "@babel/helper-plugin-utils": "^7.0.0" } }, "@babel/plugin-transform-block-scoping": { - "version": "7.6.3", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-block-scoping/-/plugin-transform-block-scoping-7.6.3.tgz", - "integrity": "sha512-7hvrg75dubcO3ZI2rjYTzUrEuh1E9IyDEhhB6qfcooxhDA33xx2MasuLVgdxzcP6R/lipAC6n9ub9maNW6RKdw==", + "version": "7.7.4", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-block-scoping/-/plugin-transform-block-scoping-7.7.4.tgz", + "integrity": "sha512-2VBe9u0G+fDt9B5OV5DQH4KBf5DoiNkwFKOz0TCvBWvdAN2rOykCTkrL+jTLxfCAm76l9Qo5OqL7HBOx2dWggg==", "requires": { "@babel/helper-plugin-utils": "^7.0.0", "lodash": "^4.17.13" } }, "@babel/plugin-transform-classes": { - "version": "7.7.0", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-classes/-/plugin-transform-classes-7.7.0.tgz", - "integrity": "sha512-/b3cKIZwGeUesZheU9jNYcwrEA7f/Bo4IdPmvp7oHgvks2majB5BoT5byAql44fiNQYOPzhk2w8DbgfuafkMoA==", - "requires": { - "@babel/helper-annotate-as-pure": "^7.7.0", - "@babel/helper-define-map": "^7.7.0", - "@babel/helper-function-name": "^7.7.0", - "@babel/helper-optimise-call-expression": "^7.7.0", + "version": "7.7.4", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-classes/-/plugin-transform-classes-7.7.4.tgz", + "integrity": "sha512-sK1mjWat7K+buWRuImEzjNf68qrKcrddtpQo3swi9j7dUcG6y6R6+Di039QN2bD1dykeswlagupEmpOatFHHUg==", + "requires": { + "@babel/helper-annotate-as-pure": "^7.7.4", + "@babel/helper-define-map": "^7.7.4", + "@babel/helper-function-name": "^7.7.4", + "@babel/helper-optimise-call-expression": "^7.7.4", "@babel/helper-plugin-utils": "^7.0.0", - "@babel/helper-replace-supers": "^7.7.0", - "@babel/helper-split-export-declaration": "^7.7.0", + "@babel/helper-replace-supers": "^7.7.4", + "@babel/helper-split-export-declaration": "^7.7.4", "globals": "^11.1.0" } }, "@babel/plugin-transform-computed-properties": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-computed-properties/-/plugin-transform-computed-properties-7.2.0.tgz", - "integrity": "sha512-kP/drqTxY6Xt3NNpKiMomfgkNn4o7+vKxK2DDKcBG9sHj51vHqMBGy8wbDS/J4lMxnqs153/T3+DmCEAkC5cpA==", + "version": "7.7.4", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-computed-properties/-/plugin-transform-computed-properties-7.7.4.tgz", + "integrity": "sha512-bSNsOsZnlpLLyQew35rl4Fma3yKWqK3ImWMSC/Nc+6nGjC9s5NFWAer1YQ899/6s9HxO2zQC1WoFNfkOqRkqRQ==", "requires": { "@babel/helper-plugin-utils": "^7.0.0" } }, "@babel/plugin-transform-destructuring": { - "version": "7.6.0", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-destructuring/-/plugin-transform-destructuring-7.6.0.tgz", - "integrity": "sha512-2bGIS5P1v4+sWTCnKNDZDxbGvEqi0ijeqM/YqHtVGrvG2y0ySgnEEhXErvE9dA0bnIzY9bIzdFK0jFA46ASIIQ==", + "version": "7.7.4", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-destructuring/-/plugin-transform-destructuring-7.7.4.tgz", + "integrity": "sha512-4jFMXI1Cu2aXbcXXl8Lr6YubCn6Oc7k9lLsu8v61TZh+1jny2BWmdtvY9zSUlLdGUvcy9DMAWyZEOqjsbeg/wA==", "requires": { "@babel/helper-plugin-utils": "^7.0.0" } }, "@babel/plugin-transform-dotall-regex": { - "version": "7.7.0", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-dotall-regex/-/plugin-transform-dotall-regex-7.7.0.tgz", - "integrity": "sha512-3QQlF7hSBnSuM1hQ0pS3pmAbWLax/uGNCbPBND9y+oJ4Y776jsyujG2k0Sn2Aj2a0QwVOiOFL5QVPA7spjvzSA==", + "version": "7.7.4", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-dotall-regex/-/plugin-transform-dotall-regex-7.7.4.tgz", + "integrity": "sha512-mk0cH1zyMa/XHeb6LOTXTbG7uIJ8Rrjlzu91pUx/KS3JpcgaTDwMS8kM+ar8SLOvlL2Lofi4CGBAjCo3a2x+lw==", "requires": { - "@babel/helper-create-regexp-features-plugin": "^7.7.0", + "@babel/helper-create-regexp-features-plugin": "^7.7.4", "@babel/helper-plugin-utils": "^7.0.0" } }, "@babel/plugin-transform-duplicate-keys": { - "version": "7.5.0", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-duplicate-keys/-/plugin-transform-duplicate-keys-7.5.0.tgz", - "integrity": "sha512-igcziksHizyQPlX9gfSjHkE2wmoCH3evvD2qR5w29/Dk0SMKE/eOI7f1HhBdNhR/zxJDqrgpoDTq5YSLH/XMsQ==", + "version": "7.7.4", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-duplicate-keys/-/plugin-transform-duplicate-keys-7.7.4.tgz", + "integrity": "sha512-g1y4/G6xGWMD85Tlft5XedGaZBCIVN+/P0bs6eabmcPP9egFleMAo65OOjlhcz1njpwagyY3t0nsQC9oTFegJA==", "requires": { "@babel/helper-plugin-utils": "^7.0.0" } }, "@babel/plugin-transform-exponentiation-operator": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-exponentiation-operator/-/plugin-transform-exponentiation-operator-7.2.0.tgz", - "integrity": "sha512-umh4hR6N7mu4Elq9GG8TOu9M0bakvlsREEC+ialrQN6ABS4oDQ69qJv1VtR3uxlKMCQMCvzk7vr17RHKcjx68A==", + "version": "7.7.4", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-exponentiation-operator/-/plugin-transform-exponentiation-operator-7.7.4.tgz", + "integrity": "sha512-MCqiLfCKm6KEA1dglf6Uqq1ElDIZwFuzz1WH5mTf8k2uQSxEJMbOIEh7IZv7uichr7PMfi5YVSrr1vz+ipp7AQ==", "requires": { - "@babel/helper-builder-binary-assignment-operator-visitor": "^7.1.0", + "@babel/helper-builder-binary-assignment-operator-visitor": "^7.7.4", "@babel/helper-plugin-utils": "^7.0.0" } }, "@babel/plugin-transform-for-of": { - "version": "7.4.4", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-for-of/-/plugin-transform-for-of-7.4.4.tgz", - "integrity": "sha512-9T/5Dlr14Z9TIEXLXkt8T1DU7F24cbhwhMNUziN3hB1AXoZcdzPcTiKGRn/6iOymDqtTKWnr/BtRKN9JwbKtdQ==", + "version": "7.7.4", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-for-of/-/plugin-transform-for-of-7.7.4.tgz", + "integrity": "sha512-zZ1fD1B8keYtEcKF+M1TROfeHTKnijcVQm0yO/Yu1f7qoDoxEIc/+GX6Go430Bg84eM/xwPFp0+h4EbZg7epAA==", "requires": { "@babel/helper-plugin-utils": "^7.0.0" } }, "@babel/plugin-transform-function-name": { - "version": "7.7.0", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-function-name/-/plugin-transform-function-name-7.7.0.tgz", - "integrity": "sha512-P5HKu0d9+CzZxP5jcrWdpe7ZlFDe24bmqP6a6X8BHEBl/eizAsY8K6LX8LASZL0Jxdjm5eEfzp+FIrxCm/p8bA==", + "version": "7.7.4", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-function-name/-/plugin-transform-function-name-7.7.4.tgz", + "integrity": "sha512-E/x09TvjHNhsULs2IusN+aJNRV5zKwxu1cpirZyRPw+FyyIKEHPXTsadj48bVpc1R5Qq1B5ZkzumuFLytnbT6g==", "requires": { - "@babel/helper-function-name": "^7.7.0", + "@babel/helper-function-name": "^7.7.4", "@babel/helper-plugin-utils": "^7.0.0" } }, "@babel/plugin-transform-literals": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-literals/-/plugin-transform-literals-7.2.0.tgz", - "integrity": "sha512-2ThDhm4lI4oV7fVQ6pNNK+sx+c/GM5/SaML0w/r4ZB7sAneD/piDJtwdKlNckXeyGK7wlwg2E2w33C/Hh+VFCg==", + "version": "7.7.4", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-literals/-/plugin-transform-literals-7.7.4.tgz", + "integrity": "sha512-X2MSV7LfJFm4aZfxd0yLVFrEXAgPqYoDG53Br/tCKiKYfX0MjVjQeWPIhPHHsCqzwQANq+FLN786fF5rgLS+gw==", "requires": { "@babel/helper-plugin-utils": "^7.0.0" } }, "@babel/plugin-transform-modules-amd": { - "version": "7.5.0", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-amd/-/plugin-transform-modules-amd-7.5.0.tgz", - "integrity": "sha512-n20UsQMKnWrltocZZm24cRURxQnWIvsABPJlw/fvoy9c6AgHZzoelAIzajDHAQrDpuKFFPPcFGd7ChsYuIUMpg==", + "version": "7.7.4", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-amd/-/plugin-transform-modules-amd-7.7.4.tgz", + "integrity": "sha512-/542/5LNA18YDtg1F+QHvvUSlxdvjZoD/aldQwkq+E3WCkbEjNSN9zdrOXaSlfg3IfGi22ijzecklF/A7kVZFQ==", "requires": { - "@babel/helper-module-transforms": "^7.1.0", + "@babel/helper-module-transforms": "^7.7.4", "@babel/helper-plugin-utils": "^7.0.0", "babel-plugin-dynamic-import-node": "^2.3.0" } }, "@babel/plugin-transform-modules-commonjs": { - "version": "7.7.0", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-commonjs/-/plugin-transform-modules-commonjs-7.7.0.tgz", - "integrity": "sha512-KEMyWNNWnjOom8vR/1+d+Ocz/mILZG/eyHHO06OuBQ2aNhxT62fr4y6fGOplRx+CxCSp3IFwesL8WdINfY/3kg==", + "version": "7.7.4", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-commonjs/-/plugin-transform-modules-commonjs-7.7.4.tgz", + "integrity": "sha512-k8iVS7Jhc367IcNF53KCwIXtKAH7czev866ThsTgy8CwlXjnKZna2VHwChglzLleYrcHz1eQEIJlGRQxB53nqA==", "requires": { - "@babel/helper-module-transforms": "^7.7.0", + "@babel/helper-module-transforms": "^7.7.4", "@babel/helper-plugin-utils": "^7.0.0", - "@babel/helper-simple-access": "^7.7.0", + "@babel/helper-simple-access": "^7.7.4", "babel-plugin-dynamic-import-node": "^2.3.0" } }, "@babel/plugin-transform-modules-systemjs": { - "version": "7.7.0", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-systemjs/-/plugin-transform-modules-systemjs-7.7.0.tgz", - "integrity": "sha512-ZAuFgYjJzDNv77AjXRqzQGlQl4HdUM6j296ee4fwKVZfhDR9LAGxfvXjBkb06gNETPnN0sLqRm9Gxg4wZH6dXg==", + "version": "7.7.4", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-systemjs/-/plugin-transform-modules-systemjs-7.7.4.tgz", + "integrity": "sha512-y2c96hmcsUi6LrMqvmNDPBBiGCiQu0aYqpHatVVu6kD4mFEXKjyNxd/drc18XXAf9dv7UXjrZwBVmTTGaGP8iw==", "requires": { - "@babel/helper-hoist-variables": "^7.7.0", + "@babel/helper-hoist-variables": "^7.7.4", "@babel/helper-plugin-utils": "^7.0.0", "babel-plugin-dynamic-import-node": "^2.3.0" } }, "@babel/plugin-transform-modules-umd": { - "version": "7.7.0", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-umd/-/plugin-transform-modules-umd-7.7.0.tgz", - "integrity": "sha512-u7eBA03zmUswQ9LQ7Qw0/ieC1pcAkbp5OQatbWUzY1PaBccvuJXUkYzoN1g7cqp7dbTu6Dp9bXyalBvD04AANA==", + "version": "7.7.4", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-umd/-/plugin-transform-modules-umd-7.7.4.tgz", + "integrity": "sha512-u2B8TIi0qZI4j8q4C51ktfO7E3cQ0qnaXFI1/OXITordD40tt17g/sXqgNNCcMTcBFKrUPcGDx+TBJuZxLx7tw==", "requires": { - "@babel/helper-module-transforms": "^7.7.0", + "@babel/helper-module-transforms": "^7.7.4", "@babel/helper-plugin-utils": "^7.0.0" } }, "@babel/plugin-transform-named-capturing-groups-regex": { - "version": "7.7.0", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-named-capturing-groups-regex/-/plugin-transform-named-capturing-groups-regex-7.7.0.tgz", - "integrity": "sha512-+SicSJoKouPctL+j1pqktRVCgy+xAch1hWWTMy13j0IflnyNjaoskj+DwRQFimHbLqO3sq2oN2CXMvXq3Bgapg==", + "version": "7.7.4", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-named-capturing-groups-regex/-/plugin-transform-named-capturing-groups-regex-7.7.4.tgz", + "integrity": "sha512-jBUkiqLKvUWpv9GLSuHUFYdmHg0ujC1JEYoZUfeOOfNydZXp1sXObgyPatpcwjWgsdBGsagWW0cdJpX/DO2jMw==", "requires": { - "@babel/helper-create-regexp-features-plugin": "^7.7.0" + "@babel/helper-create-regexp-features-plugin": "^7.7.4" } }, "@babel/plugin-transform-new-target": { - "version": "7.4.4", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-new-target/-/plugin-transform-new-target-7.4.4.tgz", - "integrity": "sha512-r1z3T2DNGQwwe2vPGZMBNjioT2scgWzK9BCnDEh+46z8EEwXBq24uRzd65I7pjtugzPSj921aM15RpESgzsSuA==", + "version": "7.7.4", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-new-target/-/plugin-transform-new-target-7.7.4.tgz", + "integrity": "sha512-CnPRiNtOG1vRodnsyGX37bHQleHE14B9dnnlgSeEs3ek3fHN1A1SScglTCg1sfbe7sRQ2BUcpgpTpWSfMKz3gg==", "requires": { "@babel/helper-plugin-utils": "^7.0.0" } }, "@babel/plugin-transform-object-super": { - "version": "7.5.5", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-object-super/-/plugin-transform-object-super-7.5.5.tgz", - "integrity": "sha512-un1zJQAhSosGFBduPgN/YFNvWVpRuHKU7IHBglLoLZsGmruJPOo6pbInneflUdmq7YvSVqhpPs5zdBvLnteltQ==", + "version": "7.7.4", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-object-super/-/plugin-transform-object-super-7.7.4.tgz", + "integrity": "sha512-ho+dAEhC2aRnff2JCA0SAK7V2R62zJd/7dmtoe7MHcso4C2mS+vZjn1Pb1pCVZvJs1mgsvv5+7sT+m3Bysb6eg==", "requires": { "@babel/helper-plugin-utils": "^7.0.0", - "@babel/helper-replace-supers": "^7.5.5" + "@babel/helper-replace-supers": "^7.7.4" } }, "@babel/plugin-transform-parameters": { - "version": "7.4.4", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-parameters/-/plugin-transform-parameters-7.4.4.tgz", - "integrity": "sha512-oMh5DUO1V63nZcu/ZVLQFqiihBGo4OpxJxR1otF50GMeCLiRx5nUdtokd+u9SuVJrvvuIh9OosRFPP4pIPnwmw==", + "version": "7.7.4", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-parameters/-/plugin-transform-parameters-7.7.4.tgz", + "integrity": "sha512-VJwhVePWPa0DqE9vcfptaJSzNDKrWU/4FbYCjZERtmqEs05g3UMXnYMZoXja7JAJ7Y7sPZipwm/pGApZt7wHlw==", "requires": { - "@babel/helper-call-delegate": "^7.4.4", - "@babel/helper-get-function-arity": "^7.0.0", + "@babel/helper-call-delegate": "^7.7.4", + "@babel/helper-get-function-arity": "^7.7.4", "@babel/helper-plugin-utils": "^7.0.0" } }, "@babel/plugin-transform-regenerator": { - "version": "7.7.0", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-regenerator/-/plugin-transform-regenerator-7.7.0.tgz", - "integrity": "sha512-AXmvnC+0wuj/cFkkS/HFHIojxH3ffSXE+ttulrqWjZZRaUOonfJc60e1wSNT4rV8tIunvu/R3wCp71/tLAa9xg==", + "version": "7.7.4", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-regenerator/-/plugin-transform-regenerator-7.7.4.tgz", + "integrity": "sha512-e7MWl5UJvmPEwFJTwkBlPmqixCtr9yAASBqff4ggXTNicZiwbF8Eefzm6NVgfiBp7JdAGItecnctKTgH44q2Jw==", "requires": { "regenerator-transform": "^0.14.0" } }, "@babel/plugin-transform-runtime": { - "version": "7.6.2", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-runtime/-/plugin-transform-runtime-7.6.2.tgz", - "integrity": "sha512-cqULw/QB4yl73cS5Y0TZlQSjDvNkzDbu0FurTZyHlJpWE5T3PCMdnyV+xXoH1opr1ldyHODe3QAX3OMAii5NxA==", + "version": "7.7.4", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-runtime/-/plugin-transform-runtime-7.7.4.tgz", + "integrity": "sha512-O8kSkS5fP74Ad/8pfsCMGa8sBRdLxYoSReaARRNSz3FbFQj3z/QUvoUmJ28gn9BO93YfnXc3j+Xyaqe8cKDNBQ==", "requires": { - "@babel/helper-module-imports": "^7.0.0", + "@babel/helper-module-imports": "^7.7.4", "@babel/helper-plugin-utils": "^7.0.0", "resolve": "^1.8.1", "semver": "^5.5.1" } }, "@babel/plugin-transform-shorthand-properties": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-shorthand-properties/-/plugin-transform-shorthand-properties-7.2.0.tgz", - "integrity": "sha512-QP4eUM83ha9zmYtpbnyjTLAGKQritA5XW/iG9cjtuOI8s1RuL/3V6a3DeSHfKutJQ+ayUfeZJPcnCYEQzaPQqg==", + "version": "7.7.4", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-shorthand-properties/-/plugin-transform-shorthand-properties-7.7.4.tgz", + "integrity": "sha512-q+suddWRfIcnyG5YiDP58sT65AJDZSUhXQDZE3r04AuqD6d/XLaQPPXSBzP2zGerkgBivqtQm9XKGLuHqBID6Q==", "requires": { "@babel/helper-plugin-utils": "^7.0.0" } }, "@babel/plugin-transform-spread": { - "version": "7.6.2", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-spread/-/plugin-transform-spread-7.6.2.tgz", - "integrity": "sha512-DpSvPFryKdK1x+EDJYCy28nmAaIMdxmhot62jAXF/o99iA33Zj2Lmcp3vDmz+MUh0LNYVPvfj5iC3feb3/+PFg==", + "version": "7.7.4", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-spread/-/plugin-transform-spread-7.7.4.tgz", + "integrity": "sha512-8OSs0FLe5/80cndziPlg4R0K6HcWSM0zyNhHhLsmw/Nc5MaA49cAsnoJ/t/YZf8qkG7fD+UjTRaApVDB526d7Q==", "requires": { "@babel/helper-plugin-utils": "^7.0.0" } }, "@babel/plugin-transform-sticky-regex": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-sticky-regex/-/plugin-transform-sticky-regex-7.2.0.tgz", - "integrity": "sha512-KKYCoGaRAf+ckH8gEL3JHUaFVyNHKe3ASNsZ+AlktgHevvxGigoIttrEJb8iKN03Q7Eazlv1s6cx2B2cQ3Jabw==", + "version": "7.7.4", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-sticky-regex/-/plugin-transform-sticky-regex-7.7.4.tgz", + "integrity": "sha512-Ls2NASyL6qtVe1H1hXts9yuEeONV2TJZmplLONkMPUG158CtmnrzW5Q5teibM5UVOFjG0D3IC5mzXR6pPpUY7A==", "requires": { "@babel/helper-plugin-utils": "^7.0.0", "@babel/helper-regex": "^7.0.0" } }, "@babel/plugin-transform-template-literals": { - "version": "7.4.4", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-template-literals/-/plugin-transform-template-literals-7.4.4.tgz", - "integrity": "sha512-mQrEC4TWkhLN0z8ygIvEL9ZEToPhG5K7KDW3pzGqOfIGZ28Jb0POUkeWcoz8HnHvhFy6dwAT1j8OzqN8s804+g==", + "version": "7.7.4", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-template-literals/-/plugin-transform-template-literals-7.7.4.tgz", + "integrity": "sha512-sA+KxLwF3QwGj5abMHkHgshp9+rRz+oY9uoRil4CyLtgEuE/88dpkeWgNk5qKVsJE9iSfly3nvHapdRiIS2wnQ==", "requires": { - "@babel/helper-annotate-as-pure": "^7.0.0", + "@babel/helper-annotate-as-pure": "^7.7.4", "@babel/helper-plugin-utils": "^7.0.0" } }, "@babel/plugin-transform-typeof-symbol": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-typeof-symbol/-/plugin-transform-typeof-symbol-7.2.0.tgz", - "integrity": "sha512-2LNhETWYxiYysBtrBTqL8+La0jIoQQnIScUJc74OYvUGRmkskNY4EzLCnjHBzdmb38wqtTaixpo1NctEcvMDZw==", + "version": "7.7.4", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-typeof-symbol/-/plugin-transform-typeof-symbol-7.7.4.tgz", + "integrity": "sha512-KQPUQ/7mqe2m0B8VecdyaW5XcQYaePyl9R7IsKd+irzj6jvbhoGnRE+M0aNkyAzI07VfUQ9266L5xMARitV3wg==", "requires": { "@babel/helper-plugin-utils": "^7.0.0" } }, "@babel/plugin-transform-unicode-regex": { - "version": "7.7.0", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-unicode-regex/-/plugin-transform-unicode-regex-7.7.0.tgz", - "integrity": "sha512-RrThb0gdrNwFAqEAAx9OWgtx6ICK69x7i9tCnMdVrxQwSDp/Abu9DXFU5Hh16VP33Rmxh04+NGW28NsIkFvFKA==", + "version": "7.7.4", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-unicode-regex/-/plugin-transform-unicode-regex-7.7.4.tgz", + "integrity": "sha512-N77UUIV+WCvE+5yHw+oks3m18/umd7y392Zv7mYTpFqHtkpcc+QUz+gLJNTWVlWROIWeLqY0f3OjZxV5TcXnRw==", "requires": { - "@babel/helper-create-regexp-features-plugin": "^7.7.0", + "@babel/helper-create-regexp-features-plugin": "^7.7.4", "@babel/helper-plugin-utils": "^7.0.0" } }, @@ -733,9 +733,9 @@ } }, "@babel/runtime": { - "version": "7.7.2", - "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.7.2.tgz", - "integrity": "sha512-JONRbXbTXc9WQE2mAZd1p0Z3DZ/6vaQIkgYMSTP3KjRCyd7rCZCcfhCyX+YjwcKxcZ82UrxbRD358bpExNgrjw==", + "version": "7.7.4", + "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.7.4.tgz", + "integrity": "sha512-r24eVUUr0QqNZa+qrImUk8fn5SPhHq+IfYvIoIMg0do3GdK9sMdiLKP3GYVVaxpPKORgm8KRKaNTEhAjgIpLMw==", "requires": { "regenerator-runtime": "^0.13.2" }, @@ -748,9 +748,9 @@ } }, "@babel/runtime-corejs2": { - "version": "7.7.2", - "resolved": "https://registry.npmjs.org/@babel/runtime-corejs2/-/runtime-corejs2-7.7.2.tgz", - "integrity": "sha512-GfVnHchOBvIMsweQ13l4jd9lT4brkevnavnVOej5g2y7PpTRY+R4pcQlCjWMZoUla5rMLFzaS/Ll2s59cB1TqQ==", + "version": "7.7.4", + "resolved": "https://registry.npmjs.org/@babel/runtime-corejs2/-/runtime-corejs2-7.7.4.tgz", + "integrity": "sha512-hKNcmHQbBSJFnZ82ewYtWDZ3fXkP/l1XcfRtm7c8gHPM/DMecJtFFBEp7KMLZTuHwwb7RfemHdsEnd7L916Z6A==", "requires": { "core-js": "^2.6.5", "regenerator-runtime": "^0.13.2" @@ -764,26 +764,26 @@ } }, "@babel/template": { - "version": "7.7.0", - "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.7.0.tgz", - "integrity": "sha512-OKcwSYOW1mhWbnTBgQY5lvg1Fxg+VyfQGjcBduZFljfc044J5iDlnDSfhQ867O17XHiSCxYHUxHg2b7ryitbUQ==", + "version": "7.7.4", + "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.7.4.tgz", + "integrity": "sha512-qUzihgVPguAzXCK7WXw8pqs6cEwi54s3E+HrejlkuWO6ivMKx9hZl3Y2fSXp9i5HgyWmj7RKP+ulaYnKM4yYxw==", "requires": { "@babel/code-frame": "^7.0.0", - "@babel/parser": "^7.7.0", - "@babel/types": "^7.7.0" + "@babel/parser": "^7.7.4", + "@babel/types": "^7.7.4" } }, "@babel/traverse": { - "version": "7.7.2", - "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.7.2.tgz", - "integrity": "sha512-TM01cXib2+rgIZrGJOLaHV/iZUAxf4A0dt5auY6KNZ+cm6aschuJGqKJM3ROTt3raPUdIDk9siAufIFEleRwtw==", + "version": "7.7.4", + "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.7.4.tgz", + "integrity": "sha512-P1L58hQyupn8+ezVA2z5KBm4/Zr4lCC8dwKCMYzsa5jFMDMQAzaBNy9W5VjB+KAmBjb40U7a/H6ao+Xo+9saIw==", "requires": { "@babel/code-frame": "^7.5.5", - "@babel/generator": "^7.7.2", - "@babel/helper-function-name": "^7.7.0", - "@babel/helper-split-export-declaration": "^7.7.0", - "@babel/parser": "^7.7.2", - "@babel/types": "^7.7.2", + "@babel/generator": "^7.7.4", + "@babel/helper-function-name": "^7.7.4", + "@babel/helper-split-export-declaration": "^7.7.4", + "@babel/parser": "^7.7.4", + "@babel/types": "^7.7.4", "debug": "^4.1.0", "globals": "^11.1.0", "lodash": "^4.17.13" @@ -805,9 +805,9 @@ } }, "@babel/types": { - "version": "7.7.2", - "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.7.2.tgz", - "integrity": "sha512-YTf6PXoh3+eZgRCBzzP25Bugd2ngmpQVrk7kXX0i5N9BO7TFBtIgZYs7WtxtOGs8e6A4ZI7ECkbBCEHeXocvOA==", + "version": "7.7.4", + "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.7.4.tgz", + "integrity": "sha512-cz5Ji23KCi4T+YIE/BolWosrJuSmoZeN1EFnRtBwF+KKLi8GG/Z2c2hOJJeCXPk4mwk4QFvTmwIodJowXgttRA==", "requires": { "esutils": "^2.0.2", "lodash": "^4.17.13", @@ -877,9 +877,9 @@ "integrity": "sha512-tHq6qdbT9U1IRSGf14CL0pUlULksvY9OZ+5eEgl1N7t+OA3tGvNpxJCzuKQlsNgCVwbAs670L1vcVQi8j9HjnA==" }, "@types/node": { - "version": "12.12.11", - "resolved": "https://registry.npmjs.org/@types/node/-/node-12.12.11.tgz", - "integrity": "sha512-O+x6uIpa6oMNTkPuHDa9MhMMehlxLAd5QcOvKRjAFsBVpeFWTOPnXbDvILvFgFFZfQ1xh1EZi1FbXxUix+zpsQ==" + "version": "12.12.12", + "resolved": "https://registry.npmjs.org/@types/node/-/node-12.12.12.tgz", + "integrity": "sha512-MGuvYJrPU0HUwqF7LqvIj50RZUX23Z+m583KBygKYUZLlZ88n6w28XRNJRJgsHukLEnLz6w6SvxZoLgbr5wLqQ==" }, "@types/q": { "version": "1.5.2", @@ -3247,14 +3247,14 @@ "integrity": "sha1-WQxhFWsK4vTwJVcyoViyZrxWsh0=" }, "electron-to-chromium": { - "version": "1.3.310", - "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.3.310.tgz", - "integrity": "sha512-ixvxy46JrDv5c8k1+th66Z+xDZD8zShNs6oh7hgyMpNZUgaoRBisXgFZKAyyhQTAj7oU2Y/uZ0AAsj/TY4N0tA==" + "version": "1.3.311", + "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.3.311.tgz", + "integrity": "sha512-7GH6RKCzziLzJ9ejmbiBEdzHZsc6C3eRpav14dmRfTWMpNgMqpP1ukw/FU/Le2fR+ep642naq7a23xNdmh2s+A==" }, "elliptic": { - "version": "6.5.1", - "resolved": "https://registry.npmjs.org/elliptic/-/elliptic-6.5.1.tgz", - "integrity": "sha512-xvJINNLbTeWQjrl6X+7eQCrIy/YPv5XCpKW6kB5mKvtnGILoLDcySuwomfdzt0BMdLNVnuRNTuzKNHj0bva1Cg==", + "version": "6.5.2", + "resolved": "https://registry.npmjs.org/elliptic/-/elliptic-6.5.2.tgz", + "integrity": "sha512-f4x70okzZbIQl/NSRLkI/+tteV/9WqL98zx+SQ69KbXxmVrmjwsNUPn/gYJJ0sHvEak24cZgHIPegRePAtA/xw==", "requires": { "bn.js": "^4.4.0", "brorand": "^1.0.1", @@ -4611,6 +4611,11 @@ "nopt": "1.0.10" } }, + "hotkeys-js": { + "version": "3.7.3", + "resolved": "https://registry.npmjs.org/hotkeys-js/-/hotkeys-js-3.7.3.tgz", + "integrity": "sha512-CSaeVPAKEEYNexYR35znMJnCqoofk7oqG/AOOqWow1qDT0Yxy+g+Y8Hs/LhGlsZaSJ7973YN6/N41LAr3t30QQ==" + }, "hpack.js": { "version": "2.1.6", "resolved": "https://registry.npmjs.org/hpack.js/-/hpack.js-2.1.6.tgz", @@ -9108,9 +9113,9 @@ } }, "vuepress-theme-cosmos": { - "version": "1.0.73", - "resolved": "https://registry.npmjs.org/vuepress-theme-cosmos/-/vuepress-theme-cosmos-1.0.73.tgz", - "integrity": "sha512-WXuld8UBxRG89WpKtmfjOdilARxF6jgcpYdwy7nWe6kv3PA1MNT0S7hDL9nztCwRk/6GAs6rtkhKyAn5WGfvxQ==", + "version": "1.0.75", + "resolved": "https://registry.npmjs.org/vuepress-theme-cosmos/-/vuepress-theme-cosmos-1.0.75.tgz", + "integrity": "sha512-nsWIJ0EtiyEKrVBzzU5qA6Iz5HJDdSskqKUZY/Ihqq7DFzpreI+46M+TZQeBCbfnIrBdXzeDcP3Jfjm63e/iow==", "requires": { "@cosmos-ui/vue": "^0.5.16", "@vuepress/plugin-last-updated": "^1.2.0", @@ -9118,6 +9123,7 @@ "algoliasearch": "^3.35.1", "axios": "^0.19.0", "docsearch.js": "^2.6.3", + "hotkeys-js": "^3.7.3", "intersection-observer": "^0.7.0", "lunr": "^2.3.8", "markdown-it": "^10.0.0", diff --git a/docs/package.json b/docs/package.json index cae26a7c3b00..d3d005ee552b 100644 --- a/docs/package.json +++ b/docs/package.json @@ -14,6 +14,7 @@ "author": "", "license": "ISC", "dependencies": { - "vuepress-theme-cosmos": "^1.0.73" + "hotkeys-js": "^3.7.3", + "vuepress-theme-cosmos": "^1.0.75" } } From 6aabc5a4bf914c495a230808ab1246a3a9328e34 Mon Sep 17 00:00:00 2001 From: gamarin Date: Mon, 25 Nov 2019 14:35:06 +0100 Subject: [PATCH 176/196] add hide banner --- docs/basics/accounts.md | 4 ++-- docs/basics/app-anatomy.md | 6 +++--- docs/basics/gas-fees.md | 6 +++--- docs/basics/tx-lifecycle.md | 4 ++-- docs/building-modules/beginblock-endblock.md | 4 ++-- docs/building-modules/genesis.md | 4 ++-- docs/building-modules/handler.md | 4 ++-- docs/building-modules/intro.md | 4 ++-- docs/building-modules/invariants.md | 4 ++-- docs/building-modules/keeper.md | 4 ++-- docs/building-modules/messages-and-queries.md | 4 ++-- docs/building-modules/module-interfaces.md | 4 ++-- docs/building-modules/module-manager.md | 4 ++-- docs/building-modules/querier.md | 4 ++-- docs/building-modules/structure.md | 2 +- docs/core/baseapp.md | 4 ++-- docs/core/context.md | 4 ++-- docs/core/encoding.md | 4 ++-- docs/core/events.md | 4 ++-- docs/core/node.md | 4 ++-- docs/core/store.md | 4 ++-- docs/core/transactions.md | 4 ++-- docs/interfaces/cli.md | 4 ++-- docs/interfaces/interfaces-intro.md | 4 ++-- docs/interfaces/query-lifecycle.md | 4 ++-- docs/interfaces/rest.md | 4 ++-- docs/modules/readme.md | 7 ------- 27 files changed, 53 insertions(+), 60 deletions(-) delete mode 100644 docs/modules/readme.md diff --git a/docs/basics/accounts.md b/docs/basics/accounts.md index da236468562b..7ad873680d4d 100644 --- a/docs/basics/accounts.md +++ b/docs/basics/accounts.md @@ -5,7 +5,7 @@ synopsis: This document describes the in-built accounts system of the Cosmos SDK # Accounts -## Pre-requisite Readings +## Pre-requisite Readings {hide} - [Anatomy of an SDK Application](./app-anatomy.md) {prereq} @@ -129,6 +129,6 @@ Of note, the `Marhsal()` and `Bytes()` method both return the same raw `[]byte` +++ https://github.com/cosmos/cosmos-sdk/blob/master/types/address.go#L230-L243 -## Next +## Next {hide} Learn about [gas and fees](./gas-fees.md). \ No newline at end of file diff --git a/docs/basics/app-anatomy.md b/docs/basics/app-anatomy.md index 2a6c5ad831d5..496273f47993 100644 --- a/docs/basics/app-anatomy.md +++ b/docs/basics/app-anatomy.md @@ -3,9 +3,9 @@ order: 1 synopsis: This document describes the core parts of a Cosmos SDK application. Throughout the document, a placeholder application named `app` will be used. --- -# Anatomy of an SDK Application +# Anatomy of an SDK Application -## Pre-requisite Readings +## Pre-requisite Readings {hide} - [High-level overview of the architecture of an SDK application](../intro/sdk-app-architecture.md) {prereq} - [Cosmos SDK design overview](../intro/sdk-design.md) {prereq} @@ -251,6 +251,6 @@ For building the application, a [Makefile](https://en.wikipedia.org/wiki/Makefil +++ https://github.com/cosmos/sdk-tutorials/blob/86a27321cf89cc637581762e953d0c07f8c78ece/nameservice/Makefile -## Next +## Next {hide} Learn more about the [Lifecycle of a transaction](./tx-lifecycle.md). diff --git a/docs/basics/gas-fees.md b/docs/basics/gas-fees.md index d2ba585bfabe..6c14ef733e88 100644 --- a/docs/basics/gas-fees.md +++ b/docs/basics/gas-fees.md @@ -3,9 +3,9 @@ order: 4 synopsis: This document describes the default strategies to handle gas and fees within a Cosmos SDK application. --- -# Gas and Fees +# Gas and Fees -## Pre-requisite Readings +## Pre-requisite Readings {hide} - [Anatomy of an SDK Application](./app-anatomy.md) {prereq} @@ -83,6 +83,6 @@ This enables developers to play with various types for the transaction of their As explained above, the `anteHandler` returns a maximum limit of `gas` the transaction can consume during execution called `GasWanted`. The actual amount consumed in the end is denominated `GasUsed`, and we must therefore have `GasUsed =< GasWanted`. Both `GasWanted` and `GasUsed` are relayed to the underlying consensus engine when [`DeliverTx`](../core/baseapp.md#delivertx) returns. -## Next +## Next {hide} Learn about [baseapp](../core/baseapp.md). \ No newline at end of file diff --git a/docs/basics/tx-lifecycle.md b/docs/basics/tx-lifecycle.md index c9c64cc895b1..b130a4e97ab9 100644 --- a/docs/basics/tx-lifecycle.md +++ b/docs/basics/tx-lifecycle.md @@ -5,7 +5,7 @@ synopsis: This document describes the lifecycle of a transaction from creation t # Transaction Lifecycle -## Pre-requisite Readings +## Pre-requisite Readings {hide} - [Anatomy of an SDK Application](./app-anatomy.md) {prereq} @@ -240,6 +240,6 @@ At this point, the transaction lifecycle of a `Tx` is over: nodes have verified delivered it by executing its state changes, and committed those changes. The `Tx` itself, in `[]byte` form, is stored in a block and appended to the blockchain. -## Next +## Next {hide} Learn about [accounts](./accounts.md). diff --git a/docs/building-modules/beginblock-endblock.md b/docs/building-modules/beginblock-endblock.md index baeb237c44e5..6f84da93088e 100644 --- a/docs/building-modules/beginblock-endblock.md +++ b/docs/building-modules/beginblock-endblock.md @@ -5,7 +5,7 @@ synopsis: `BeginBlocker` and `EndBlocker` are optional methods module developers # BeginBlocker and EndBlocker -## Pre-requisite Readings +## Pre-requisite Readings {hide} - [Module Manager](./module-manager.md) {prereq} @@ -33,6 +33,6 @@ and an example implementation of `EndBlocker` from the `staking` module: +++ https://github.com/cosmos/cosmos-sdk/blob/master/x/staking/handler.go#L44-L96 -## Next +## Next {hide} Learn about [`keeper`s](./keeper.md). diff --git a/docs/building-modules/genesis.md b/docs/building-modules/genesis.md index 38a1a3715261..09bd4c8795a6 100644 --- a/docs/building-modules/genesis.md +++ b/docs/building-modules/genesis.md @@ -5,7 +5,7 @@ synopsis: Modules generally handle a subset of the state and, as such, they need # Module Genesis -## Pre-requisite Readings +## Pre-requisite Readings {hide} - [Module Manager](./module-manager.md) {prereq} - [Keepers](./keeper.md) {prereq} @@ -54,6 +54,6 @@ See an example of `ExportGenesis` from the nameservice tutorial. +++ https://github.com/cosmos/sdk-tutorials/blob/86a27321cf89cc637581762e953d0c07f8c78ece/nameservice/x/nameservice/genesis.go#L46-L57 -## Next +## Next {hide} Learn about [modules interfaces](#module-interfaces.md). \ No newline at end of file diff --git a/docs/building-modules/handler.md b/docs/building-modules/handler.md index 6f2d56d83b3f..b714b4db0ea8 100644 --- a/docs/building-modules/handler.md +++ b/docs/building-modules/handler.md @@ -5,7 +5,7 @@ synopsis: A `Handler` designates a function that processes [`message`s](./messag # Handlers -## Pre-requisite Readings +## Pre-requisite Readings {hide} - [Module Manager](./module-manager.md) {prereq} - [Messages and Queries](./messages-and-queries.md) {prereq} @@ -71,6 +71,6 @@ Next is an example of how to return a `Result` from the `gov` module: For a deeper look at `handler`s, see this [example implementation of a `handler` function](https://github.com/cosmos/sdk-application-tutorial/blob/c6754a1e313eb1ed973c5c91dcc606f2fd288811/x/nameservice/handler.go) from the nameservice tutorial. -## Next +## Next {hide} Learn about [queriers](./querier.md). diff --git a/docs/building-modules/intro.md b/docs/building-modules/intro.md index 6a386ed60228..06c985a1177b 100644 --- a/docs/building-modules/intro.md +++ b/docs/building-modules/intro.md @@ -5,7 +5,7 @@ synopsis: Modules define most of the logic of SDK applications. Developers compo # Introduction to SDK Modules -## Pre-requisite Readings +## Pre-requisite Readings {hide} - [Anatomy of an SDK application](../basics/app-anatomy.md) {prereq} - [Lifecycle of an SDK transaction](../basics/tx-lifecycle.md) {prereq} @@ -87,7 +87,7 @@ In addition to these components, modules implement the `AppModule` interface in Please refer to the [structure document](./structure.md) to learn about the recommended structure of a module's directory. -## Next +## Next {hide} Read more on the [`AppModule` interface and the `module manager`](./module-manager.md) diff --git a/docs/building-modules/invariants.md b/docs/building-modules/invariants.md index a80378469b75..54e53cdaf894 100644 --- a/docs/building-modules/invariants.md +++ b/docs/building-modules/invariants.md @@ -5,7 +5,7 @@ synopsis: An invariant is a property of the application that should always be tr # Invariants -## Pre-requisite Readings +## Pre-requisite Readings {hide} - [Keepers](./keeper.md) {prereq} @@ -83,6 +83,6 @@ Typically, this interface is implemented in the `keeper` of a specific module. T In both cases, if one of the `Invariant`s returns false, the `InvariantRegistry` can trigger special logic (e.g. have the application panic and print the `Invariant`s message in the log). -## Next +## Next {hide} Learn about [genesis functionalities](./genesis.md). diff --git a/docs/building-modules/keeper.md b/docs/building-modules/keeper.md index d33df9445ce3..8fb4cd27be2e 100644 --- a/docs/building-modules/keeper.md +++ b/docs/building-modules/keeper.md @@ -5,7 +5,7 @@ synopsis: `Keeper`s refer to a Cosmos SDK abstraction whose role is to manage ac # Keepers -## Pre-requisite Readings +## Pre-requisite Readings {hide} - [Introduction to SDK Modules](./intro.md) {prereq} @@ -73,6 +73,6 @@ and go through the following steps: For more, see an example of `keeper`'s [methods implementation from the nameservice tutorial](https://github.com/cosmos/sdk-application-tutorial/blob/c6754a1e313eb1ed973c5c91dcc606f2fd288811/x/nameservice/internal/keeper/keeper.go). -## Next +## Next {hide} Learn about [invariants](./invariants.md). diff --git a/docs/building-modules/messages-and-queries.md b/docs/building-modules/messages-and-queries.md index 229c8d77b34b..38daa55bfc1a 100644 --- a/docs/building-modules/messages-and-queries.md +++ b/docs/building-modules/messages-and-queries.md @@ -5,7 +5,7 @@ synopsis: `Message`s and `Queries` are the two primary objects handled by module # Messages and Queries -## Pre-requisite Readings +## Pre-requisite Readings {hide} - [Introduction to SDK Modules](./intro.md) {prereq} @@ -70,6 +70,6 @@ See an example of `query` return types from the `nameservice` module: +++ https://github.com/cosmos/sdk-tutorials/blob/c6754a1e313eb1ed973c5c91dcc606f2fd288811/x/nameservice/internal/types/querier.go#L5-L21 -## Next +## Next {hide} Learn about [`handler`s](./handler.md). \ No newline at end of file diff --git a/docs/building-modules/module-interfaces.md b/docs/building-modules/module-interfaces.md index a6d412d6a0b6..ddc565ccf580 100644 --- a/docs/building-modules/module-interfaces.md +++ b/docs/building-modules/module-interfaces.md @@ -5,7 +5,7 @@ synopsis: This document details how to build CLI and REST interfaces for a modul # Module Interfaces -## Pre-requisite Readings +## Pre-requisite Readings {hide} * [Building Modules Intro](./intro.md) {prereq} @@ -162,6 +162,6 @@ A few things to note: * `"GET"` is the HTTP Request method. As to be expected, queries are typically GET requests. Transactions are typically POST and PUT requests. -## Next +## Next {hide} Read about the recommended [module structure](./structure.md). diff --git a/docs/building-modules/module-manager.md b/docs/building-modules/module-manager.md index 37174a8313c4..daac6a55aeeb 100644 --- a/docs/building-modules/module-manager.md +++ b/docs/building-modules/module-manager.md @@ -6,7 +6,7 @@ synopsis: Cosmos SDK modules need to implement the [`AppModule` interfaces](#app # Module Manager -## Pre-requisite Readings +## Pre-requisite Readings {hide} - [Introduction to SDK Modules](./intro.md) {prereq} @@ -139,6 +139,6 @@ The module manager is used throughout the application whenever an action on a co - `BeginBlock(ctx sdk.Context, req abci.RequestBeginBlock)`: At the beginning of each block, this function is called from [`baseapp`](../core/baseapp.md#beginblock) and, in turn, calls the [`BeginBlock`](./beginblock-endblock.md) function of each module, in the order defined in `OrderBeginBlockers`. It creates a child [context](../core/context.md) with an event manager to aggregate [events](../core/events.md) emitted from all modules. The function returns an `abci.ResponseBeginBlock` which contains the aforementioned events. - `EndBlock(ctx sdk.Context, req abci.RequestEndBlock)`: At the end of each block, this function is called from [`baseapp`](../core/baseapp.md#endblock) and, in turn, calls the [`EndBlock`](./beginblock-endblock.md) function of each module, in the order defined in `OrderEndBlockers`. It creates a child [context](../core/context.md) with an event manager to aggregate [events](../core/events.md) emitted from all modules. The function returns an `abci.ResponseEndBlock` which contains the aforementioned events, as well as validator set updates (if any). -## Next +## Next {hide} Learn more about [`message`s and `queries`](./messages-and-queries.md). diff --git a/docs/building-modules/querier.md b/docs/building-modules/querier.md index 8fbcafa59b40..7704fcee2522 100644 --- a/docs/building-modules/querier.md +++ b/docs/building-modules/querier.md @@ -5,7 +5,7 @@ synopsis: A `Querier` designates a function that processes [`queries`](./message # Queriers -## Pre-requisite Readings +## Pre-requisite Readings {hide} - [Module Manager](./module-manager.md) {prereq} - [Messages and Queries](./messages-and-queries.md) {prereq} @@ -48,6 +48,6 @@ The `querier` functions themselves are pretty straighforward. They generally fet For a deeper look at `querier`s, see this [example implementation of a `querier` function](https://github.com/cosmos/sdk-application-tutorial/blob/c6754a1e313eb1ed973c5c91dcc606f2fd288811/x/nameservice/internal/keeper/querier.go) from the nameservice tutorial. -## Next +## Next {hide} Learn about [`BeginBlocker` and `EndBlocker`](./beginblock-endblock.md). diff --git a/docs/building-modules/structure.md b/docs/building-modules/structure.md index c21bc2af119a..2064d0e35217 100644 --- a/docs/building-modules/structure.md +++ b/docs/building-modules/structure.md @@ -83,6 +83,6 @@ allows for greater freedom of development while maintaining API stability. interfaces. - `simulation.go`: The module's simulation messages and related types (if any). -## Next +## Next {hide} Learn about [interfaces](../interfaces/interfaces-intro.md). \ No newline at end of file diff --git a/docs/core/baseapp.md b/docs/core/baseapp.md index 4e9951cbb411..ffb1bb4a93f5 100644 --- a/docs/core/baseapp.md +++ b/docs/core/baseapp.md @@ -6,7 +6,7 @@ functionalities of an SDK application. # Baseapp -## Pre-requisite Readings +## Pre-requisite Readings {hide} - [Anatomy of an SDK application](../basics/app-anatomy.md) {prereq} - [Lifecycle of an SDK transaction](../basics/tx-lifecycle.md) {prereq} @@ -389,6 +389,6 @@ Each `query` comes with a `path`, which contains multiple `string`s. By conventi - P2P queries, which are served via the `handleQueryP2P` method. These queries return either `app.addrPeerFilter` or `app.ipPeerFilter` that contain the list of peers filtered by address or IP respectively. These lists are first initialized via `options` in `baseapp`'s [constructor](#constructor). - Custom queries, which encompass most queries, are served via the `handleQueryCustom` method. The `handleQueryCustom` cache-wraps the multistore before using the `queryRoute` obtained from [`app.queryRouter`](#query-routing) to map the query to the appropriate module's `querier`. -## Next +## Next {hide} Learn more about [transactions](./transactions.md). \ No newline at end of file diff --git a/docs/core/context.md b/docs/core/context.md index aefefdc3d1e6..1c265b8e8caf 100644 --- a/docs/core/context.md +++ b/docs/core/context.md @@ -5,7 +5,7 @@ synopsis: The `context` is a data structure intended to be passed from function # Context -## Pre-requisites Readings +## Pre-requisites Readings {hide} - [Anatomy of an SDK Application](../basics/app-anatomy.md) {prereq} - [Lifecycle of a Transaction](../basics/tx-lifecycle.md) {prereq} @@ -112,6 +112,6 @@ changes - the result is returned immediately. 4. If the process is running in [`deliverTxMode`](./baseapp.md#delivertx) and the result indicates a successful run over all the messages, the cached multistore is written back to the original. -## Next +## Next {hide} Learn about the [node client](./node.md) diff --git a/docs/core/encoding.md b/docs/core/encoding.md index 65ece87febe6..6e924e379b6e 100644 --- a/docs/core/encoding.md +++ b/docs/core/encoding.md @@ -5,7 +5,7 @@ synopsis: The `codec` is used everywhere in the Cosmos SDK to encode and decode # Encoding -## Pre-requisite Reading +## Pre-requisite Readings {hide} - [Anatomy of an SDK application](../basics/app-anatomy.md) {prereq} @@ -41,6 +41,6 @@ A standard implementation of both these objects can be found in the [`auth` modu +++ https://github.com/cosmos/cosmos-sdk/blob/master/x/auth/types/stdtx.go#L241-L266 -## Next +## Next {hide} Learn about [events](./events.md). \ No newline at end of file diff --git a/docs/core/events.md b/docs/core/events.md index 87cdd8770442..ed33a1de4bac 100644 --- a/docs/core/events.md +++ b/docs/core/events.md @@ -5,7 +5,7 @@ synopsis: `Event`s are objects that contain information about the execution of t # Events -## Pre-Requisite Readings +## Pre-Requisite Readings {hide} - [Anatomy of an SDK application](../basics/app-anatomy.md) {prereq} @@ -86,6 +86,6 @@ The `type` and `attribute` value of the `query` allow you to filter the specific where `senderAddress` is an address following the [`AccAddress`](../basics/accounts.md#addresses) format. -## Next +## Next {hide} Learn about [object-capabilities](./ocap.md) \ No newline at end of file diff --git a/docs/core/node.md b/docs/core/node.md index f7b274095e49..62f9011fbe89 100644 --- a/docs/core/node.md +++ b/docs/core/node.md @@ -5,7 +5,7 @@ synopsis: The main endpoint of an SDK application is the daemon client, otherwis # Node Client (Daemon) -## Pre-requisite Reading +## Pre-requisite Readings {hide} - [Anatomy of an SDK application](../basics/app-anatomy.md) {prereq} @@ -65,6 +65,6 @@ if err := tmNode.Start(); err != nil { Upon starting, the node will bootstrap its RPC and P2P server and start dialing peers. During handshake with its peers, if the node realizes they are ahead, it will query all the blocks sequentially in order to catch up. Then, it will wait for new block proposals and block signatures from validators in order to make progress. -## Next +## Next {hide} Learn about the [store](./store.md). \ No newline at end of file diff --git a/docs/core/store.md b/docs/core/store.md index dcf585fd35ef..f46569e9222b 100644 --- a/docs/core/store.md +++ b/docs/core/store.md @@ -5,7 +5,7 @@ synopsis: A store is a data structure that holds the state of the application. # Store -## Pre-requisite Readings +## Pre-requisite Readings {hide} - [Anatomy of an SDK application](../basics/app-anatomy.md) {prereq} @@ -234,6 +234,6 @@ When `Store.{Get, Set}()` is called, the store forwards the call to its parent, When `Store.Iterator()` is called, it does not simply prefix the `Store.prefix`, since it does not work as intended. In that case, some of the elements are traversed even they are not starting with the prefix. -## Next +## Next {hide} Learn about [encoding](./encoding.md). \ No newline at end of file diff --git a/docs/core/transactions.md b/docs/core/transactions.md index f09b725b6c2e..19b6bd8a784e 100644 --- a/docs/core/transactions.md +++ b/docs/core/transactions.md @@ -5,7 +5,7 @@ synopsis: `Transactions` are objects created by end-users to trigger state chang # Transactions -## Pre-requisite Readings +## Pre-requisite Readings {hide} * [Anatomy of an SDK Application](../basics/app-anatomy.md) {prereq} @@ -86,6 +86,6 @@ Every message in a transaction must be signed by the addresses specified by `Get Since `message`s are module-specific types, each module needs a [`handler`](../building-modules/handler.md) to process all of its `message` types and trigger state changes within the module's scope. This design puts more responsibility on module developers, allowing application developers to reuse common functionalities without having to implement state transition logic repetitively. To read more about `handler`s, click [here](../building-modules/handler.md). -## Next +## Next {hide} Learn about the [context](./context.md). \ No newline at end of file diff --git a/docs/interfaces/cli.md b/docs/interfaces/cli.md index b33c2229f941..77f86406912a 100644 --- a/docs/interfaces/cli.md +++ b/docs/interfaces/cli.md @@ -3,9 +3,9 @@ order: 3 synopsis: This document describes how to create a commmand-line interface (CLI) for an [**application**](../basics/app-anatomy.md). A separate document for implementing a CLI for an SDK [**module**](../building-modules/intro.md) can be found [here](#../building-modules/module-interfaces.md#cli). --- -# Command-Line Interface +# Command-Line Interface -## Pre-requisite Readings +## Pre-requisite Readings {hide} * [Lifecycle of a Query](./query-lifecycle.md) {prereq} diff --git a/docs/interfaces/interfaces-intro.md b/docs/interfaces/interfaces-intro.md index fd9f6702706f..784a3b119f6e 100644 --- a/docs/interfaces/interfaces-intro.md +++ b/docs/interfaces/interfaces-intro.md @@ -5,7 +5,7 @@ synopsis: Typically, SDK applications include interfaces to let end-users intera # Interfaces -## Pre-requisite Readings +## Pre-requisite Readings {hide} * [Anatomy of an SDK Application](../basics/app-anatomy.md) {prereq} * [Lifecycle of a Transaction](../basics/tx-lifecycle.md) {prereq} @@ -38,6 +38,6 @@ With regards to interfaces, application developers need to include: * **RegisterRoutes Function:** [Routes](./rest.md#registerroutes) must be registered and passed to an instantiated [REST server](./rest.md#rest-server) so that it knows how to route requests for this particular application. -## Next +## Next {hide} Read about the [Lifecycle of a Query](./query-lifecycle.md). diff --git a/docs/interfaces/query-lifecycle.md b/docs/interfaces/query-lifecycle.md index 20f44cf83d00..d9fccbd82e2c 100644 --- a/docs/interfaces/query-lifecycle.md +++ b/docs/interfaces/query-lifecycle.md @@ -5,7 +5,7 @@ synopsis: This document describes the lifecycle of a query in a SDK application, # Query Lifecycle -## Pre-requisite Readings +## Pre-requisite Readings {hide} * [Introduction to Interfaces](./interfaces-intro.md) {prereq} @@ -156,6 +156,6 @@ The [REST server](./rest.md#rest-server) uses the `CLIContext` to format the res +++ https://github.com/cosmos/cosmos-sdk/blob/master/x/staking/client/rest/utils.go#L115-L148 -## Next +## Next {hide} Read about how to build a [Command-Line Interface](./cli.md), or a [REST Interface](./rest.md). diff --git a/docs/interfaces/rest.md b/docs/interfaces/rest.md index 503e2c3dd394..24a4dbcd5b58 100644 --- a/docs/interfaces/rest.md +++ b/docs/interfaces/rest.md @@ -5,12 +5,12 @@ synopsis: This document describes how to create a REST interface for an SDK **ap # REST Interface -## Prerequisites +## Prerequisites {hide} * [Query Lifecycle](./query-lifecycle.md) {prereq} * [Application CLI](./cli.md) {prereq} -## Application REST Interface +## Application REST Interface Building the REST Interface for an application is done by [aggregating REST Routes](#registering-routes) defined in the application's modules. This interface is served by a REST Server [REST server](#rest-server), which route requests and output responses in the application itself. The SDK comes with its own REST Server by default. To enable it, the `rest.ServeCommand` command needs to be added as a subcommand of the `rootCmd` in the `main()` function of the [CLI interface](./cli.md): diff --git a/docs/modules/readme.md b/docs/modules/readme.md deleted file mode 100644 index a13b9980fd92..000000000000 --- a/docs/modules/readme.md +++ /dev/null @@ -1,7 +0,0 @@ ---- -order: 1 -parent: - order: false ---- - -# Modules README \ No newline at end of file From 01cd19ba60c9c0da810fe93aab1ee9c157123ebc Mon Sep 17 00:00:00 2001 From: Denis Fadeev Date: Mon, 25 Nov 2019 19:26:34 +0500 Subject: [PATCH 177/196] version --- docs/package-lock.json | 101 ++++++++++++++++++++++++++++++++++------- docs/package.json | 2 +- 2 files changed, 86 insertions(+), 17 deletions(-) diff --git a/docs/package-lock.json b/docs/package-lock.json index d89904401d23..19123ba8c332 100644 --- a/docs/package-lock.json +++ b/docs/package-lock.json @@ -2209,9 +2209,9 @@ } }, "caniuse-lite": { - "version": "1.0.30001011", - "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001011.tgz", - "integrity": "sha512-h+Eqyn/YA6o6ZTqpS86PyRmNWOs1r54EBDcd2NTwwfsXQ8re1B38SnB+p2RKF8OUsyEIjeDU8XGec1RGO/wYCg==" + "version": "1.0.30001012", + "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001012.tgz", + "integrity": "sha512-7RR4Uh04t9K1uYRWzOJmzplgEOAXbfK72oVNokCdMzA67trrhPzy93ahKk1AWHiA0c58tD2P+NHqxrA8FZ+Trg==" }, "caseless": { "version": "0.12.0", @@ -2331,6 +2331,11 @@ "tiny-emitter": "^2.0.0" } }, + "clipboard-copy": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/clipboard-copy/-/clipboard-copy-3.1.0.tgz", + "integrity": "sha512-Xsu1NddBXB89IUauda5BIq3Zq73UWkjkaQlPQbLNvNsd5WBMnTWPNKYR6HGaySOxGYZ+BKxP2E9X4ElnI3yiPA==" + }, "cliui": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/cliui/-/cliui-2.1.0.tgz", @@ -3247,9 +3252,9 @@ "integrity": "sha1-WQxhFWsK4vTwJVcyoViyZrxWsh0=" }, "electron-to-chromium": { - "version": "1.3.311", - "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.3.311.tgz", - "integrity": "sha512-7GH6RKCzziLzJ9ejmbiBEdzHZsc6C3eRpav14dmRfTWMpNgMqpP1ukw/FU/Le2fR+ep642naq7a23xNdmh2s+A==" + "version": "1.3.314", + "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.3.314.tgz", + "integrity": "sha512-IKDR/xCxKFhPts7h+VaSXS02Z1mznP3fli1BbXWXeN89i2gCzKraU8qLpEid8YzKcmZdZD3Mly3cn5/lY9xsBQ==" }, "elliptic": { "version": "6.5.2", @@ -3345,17 +3350,17 @@ } }, "es-abstract": { - "version": "1.16.0", - "resolved": "https://registry.npmjs.org/es-abstract/-/es-abstract-1.16.0.tgz", - "integrity": "sha512-xdQnfykZ9JMEiasTAJZJdMWCQ1Vm00NBw79/AWi7ELfZuuPCSOMDZbT9mkOfSctVtfhb+sAAzrm+j//GjjLHLg==", + "version": "1.16.2", + "resolved": "https://registry.npmjs.org/es-abstract/-/es-abstract-1.16.2.tgz", + "integrity": "sha512-jYo/J8XU2emLXl3OLwfwtuFfuF2w6DYPs+xy9ZfVyPkDcrauu6LYrw/q2TyCtrbc/KUdCiC5e9UajRhgNkVopA==", "requires": { - "es-to-primitive": "^1.2.0", + "es-to-primitive": "^1.2.1", "function-bind": "^1.1.1", "has": "^1.0.3", - "has-symbols": "^1.0.0", + "has-symbols": "^1.0.1", "is-callable": "^1.1.4", "is-regex": "^1.0.4", - "object-inspect": "^1.6.0", + "object-inspect": "^1.7.0", "object-keys": "^1.1.1", "string.prototype.trimleft": "^2.1.0", "string.prototype.trimright": "^2.1.0" @@ -5363,6 +5368,11 @@ "resolved": "https://registry.npmjs.org/lodash._reinterpolate/-/lodash._reinterpolate-3.0.0.tgz", "integrity": "sha1-DM8tiRZq8Ds2Y8eWU4t1rG4RTZ0=" }, + "lodash.chunk": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/lodash.chunk/-/lodash.chunk-4.2.0.tgz", + "integrity": "sha1-ZuXOH3btJ7QwPYxlEujRIW6BBrw=" + }, "lodash.clonedeep": { "version": "4.5.0", "resolved": "https://registry.npmjs.org/lodash.clonedeep/-/lodash.clonedeep-4.5.0.tgz", @@ -5383,6 +5393,16 @@ "resolved": "https://registry.npmjs.org/lodash.memoize/-/lodash.memoize-4.1.2.tgz", "integrity": "sha1-vMbEmkKihA7Zl/Mj6tpezRguC/4=" }, + "lodash.padstart": { + "version": "4.6.1", + "resolved": "https://registry.npmjs.org/lodash.padstart/-/lodash.padstart-4.6.1.tgz", + "integrity": "sha1-0uPuv/DZ05rVD1y9G1KnvOa7YRs=" + }, + "lodash.sortby": { + "version": "4.7.0", + "resolved": "https://registry.npmjs.org/lodash.sortby/-/lodash.sortby-4.7.0.tgz", + "integrity": "sha1-7dFMgk4sycHgsKG0K7UhBRakJDg=" + }, "lodash.template": { "version": "4.5.0", "resolved": "https://registry.npmjs.org/lodash.template/-/lodash.template-4.5.0.tgz", @@ -7842,6 +7862,17 @@ } } }, + "sitemap": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/sitemap/-/sitemap-3.2.2.tgz", + "integrity": "sha512-TModL/WU4m2q/mQcrDgNANn0P4LwprM9MMvG4hu5zP4c6IIKs2YLTu6nXXnNr8ODW/WFtxKggiJ1EGn2W0GNmg==", + "requires": { + "lodash.chunk": "^4.2.0", + "lodash.padstart": "^4.6.1", + "whatwg-url": "^7.0.0", + "xmlbuilder": "^13.0.0" + } + }, "slash": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/slash/-/slash-2.0.0.tgz", @@ -8619,6 +8650,14 @@ } } }, + "tr46": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/tr46/-/tr46-1.0.1.tgz", + "integrity": "sha1-qLE/1r/SSJUZZ0zN5VujaTtwbQk=", + "requires": { + "punycode": "^2.1.0" + } + }, "tslib": { "version": "1.10.0", "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.10.0.tgz", @@ -9104,6 +9143,14 @@ "markdown-it-container": "^2.0.0" } }, + "vuepress-plugin-sitemap": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/vuepress-plugin-sitemap/-/vuepress-plugin-sitemap-2.3.1.tgz", + "integrity": "sha512-n+8lbukhrKrsI9H/EX0EBgkE1pn85LAQFvQ5dIvrZP4Kz6JxPOPPNTQmZMhahQV1tXbLZQCEN7A1WZH4x+arJQ==", + "requires": { + "sitemap": "^3.0.0" + } + }, "vuepress-plugin-smooth-scroll": { "version": "0.0.3", "resolved": "https://registry.npmjs.org/vuepress-plugin-smooth-scroll/-/vuepress-plugin-smooth-scroll-0.0.3.tgz", @@ -9113,15 +9160,16 @@ } }, "vuepress-theme-cosmos": { - "version": "1.0.75", - "resolved": "https://registry.npmjs.org/vuepress-theme-cosmos/-/vuepress-theme-cosmos-1.0.75.tgz", - "integrity": "sha512-nsWIJ0EtiyEKrVBzzU5qA6Iz5HJDdSskqKUZY/Ihqq7DFzpreI+46M+TZQeBCbfnIrBdXzeDcP3Jfjm63e/iow==", + "version": "1.0.76", + "resolved": "https://registry.npmjs.org/vuepress-theme-cosmos/-/vuepress-theme-cosmos-1.0.76.tgz", + "integrity": "sha512-9Amke7aPag7ylkuxULCa5hzn35sy8LHQreFtu76EwONkw/h5kqCQZXo1cY6XkQdJgfFD2BfqkDqdStlxDYn4vA==", "requires": { "@cosmos-ui/vue": "^0.5.16", "@vuepress/plugin-last-updated": "^1.2.0", "@vuepress/plugin-search": "^1.1.0", "algoliasearch": "^3.35.1", "axios": "^0.19.0", + "clipboard-copy": "^3.1.0", "docsearch.js": "^2.6.3", "hotkeys-js": "^3.7.3", "intersection-observer": "^0.7.0", @@ -9136,7 +9184,8 @@ "stylus-loader": "^3.0.2", "tm-tooltip": "0.0.10", "v-runtime-template": "^1.10.0", - "vuepress": "^1.2.0" + "vuepress": "^1.2.0", + "vuepress-plugin-sitemap": "^2.3.1" } }, "watchpack": { @@ -9157,6 +9206,11 @@ "minimalistic-assert": "^1.0.0" } }, + "webidl-conversions": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-4.0.2.tgz", + "integrity": "sha512-YQ+BmxuTgd6UXZW3+ICGfyqRyHXVlD5GtQr5+qjiNW7bF0cqrzX500HVXPBOvgXb5YnzDd+h0zqyv61KUD7+Sg==" + }, "webpack": { "version": "4.41.2", "resolved": "https://registry.npmjs.org/webpack/-/webpack-4.41.2.tgz", @@ -9489,6 +9543,16 @@ "resolved": "https://registry.npmjs.org/websocket-extensions/-/websocket-extensions-0.1.3.tgz", "integrity": "sha512-nqHUnMXmBzT0w570r2JpJxfiSD1IzoI+HGVdd3aZ0yNi3ngvQ4jv1dtHt5VGxfI2yj5yqImPhOK4vmIh2xMbGg==" }, + "whatwg-url": { + "version": "7.1.0", + "resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-7.1.0.tgz", + "integrity": "sha512-WUu7Rg1DroM7oQvGWfOiAK21n74Gg+T4elXEQYkOhtyLeWiJFoOGLXPKI/9gzIie9CtwVLm8wtw6YJdKyxSjeg==", + "requires": { + "lodash.sortby": "^4.7.0", + "tr46": "^1.0.1", + "webidl-conversions": "^4.0.2" + } + }, "when": { "version": "3.6.4", "resolved": "https://registry.npmjs.org/when/-/when-3.6.4.tgz", @@ -9576,6 +9640,11 @@ "async-limiter": "~1.0.0" } }, + "xmlbuilder": { + "version": "13.0.2", + "resolved": "https://registry.npmjs.org/xmlbuilder/-/xmlbuilder-13.0.2.tgz", + "integrity": "sha512-Eux0i2QdDYKbdbA6AM6xE4m6ZTZr4G4xF9kahI2ukSEMCzwce2eX9WlTI5J3s+NU7hpasFsr8hWIONae7LluAQ==" + }, "xtend": { "version": "4.0.2", "resolved": "https://registry.npmjs.org/xtend/-/xtend-4.0.2.tgz", diff --git a/docs/package.json b/docs/package.json index d3d005ee552b..5b178914d337 100644 --- a/docs/package.json +++ b/docs/package.json @@ -15,6 +15,6 @@ "license": "ISC", "dependencies": { "hotkeys-js": "^3.7.3", - "vuepress-theme-cosmos": "^1.0.75" + "vuepress-theme-cosmos": "^1.0.76" } } From 2fa42e10fbd43d258ab0f159e8b5478b51e20a72 Mon Sep 17 00:00:00 2001 From: Denis Fadeev Date: Thu, 28 Nov 2019 07:08:30 +0500 Subject: [PATCH 178/196] version --- docs/README.md | 2 ++ docs/package-lock.json | 30 +++++++++++++++--------------- docs/package.json | 2 +- 3 files changed, 18 insertions(+), 16 deletions(-) diff --git a/docs/README.md b/docs/README.md index c2f667bd938d..4e50473bb7f3 100644 --- a/docs/README.md +++ b/docs/README.md @@ -53,6 +53,8 @@ stack: color: "#00BB00" label: core url: http://docs.tendermint.com +footer: + newsletter: false --- # Cosmos SDK Documentation diff --git a/docs/package-lock.json b/docs/package-lock.json index 19123ba8c332..e2f774ace6b7 100644 --- a/docs/package-lock.json +++ b/docs/package-lock.json @@ -877,9 +877,9 @@ "integrity": "sha512-tHq6qdbT9U1IRSGf14CL0pUlULksvY9OZ+5eEgl1N7t+OA3tGvNpxJCzuKQlsNgCVwbAs670L1vcVQi8j9HjnA==" }, "@types/node": { - "version": "12.12.12", - "resolved": "https://registry.npmjs.org/@types/node/-/node-12.12.12.tgz", - "integrity": "sha512-MGuvYJrPU0HUwqF7LqvIj50RZUX23Z+m583KBygKYUZLlZ88n6w28XRNJRJgsHukLEnLz6w6SvxZoLgbr5wLqQ==" + "version": "12.12.14", + "resolved": "https://registry.npmjs.org/@types/node/-/node-12.12.14.tgz", + "integrity": "sha512-u/SJDyXwuihpwjXy7hOOghagLEV1KdAST6syfnOk6QZAMzZuWZqXy5aYYZbh8Jdpd4escVFP0MvftHNDb9pruA==" }, "@types/q": { "version": "1.5.2", @@ -1679,9 +1679,9 @@ "integrity": "sha1-tG6JCTSpWR8tL2+G1+ap8bP+dqg=" }, "aws4": { - "version": "1.8.0", - "resolved": "https://registry.npmjs.org/aws4/-/aws4-1.8.0.tgz", - "integrity": "sha512-ReZxvNHIOv88FlT7rxcXIIC0fPt4KZqZbOlivyWtXLt8ESx84zd3kMC6iK5jVeS2qt+g7ftS7ye4fi06X5rtRQ==" + "version": "1.9.0", + "resolved": "https://registry.npmjs.org/aws4/-/aws4-1.9.0.tgz", + "integrity": "sha512-Uvq6hVe90D0B2WEnUqtdgY1bATGz3mw33nH9Y+dmA+w5DHvUmBgkr5rM/KCHpCsiFNRUfokW/szpPPgMK2hm4A==" }, "axios": { "version": "0.19.0", @@ -7540,9 +7540,9 @@ "integrity": "sha1-79qpjqdFEyTQkrKyFjpqHXqaIUc=" }, "resolve": { - "version": "1.12.2", - "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.12.2.tgz", - "integrity": "sha512-cAVTI2VLHWYsGOirfeYVVQ7ZDejtQ9fp4YhYckWDEkFfqbVjaT11iM8k6xSAfGFMM+gDpZjMnFssPu8we+mqFw==", + "version": "1.13.1", + "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.13.1.tgz", + "integrity": "sha512-CxqObCX8K8YtAhOBRg+lrcdn+LK+WYOS8tSjqSFbjtrI5PnS63QPhZl4+yKfrU9tdsbMu9Anr/amegT87M9Z6w==", "requires": { "path-parse": "^1.0.6" } @@ -9160,9 +9160,9 @@ } }, "vuepress-theme-cosmos": { - "version": "1.0.76", - "resolved": "https://registry.npmjs.org/vuepress-theme-cosmos/-/vuepress-theme-cosmos-1.0.76.tgz", - "integrity": "sha512-9Amke7aPag7ylkuxULCa5hzn35sy8LHQreFtu76EwONkw/h5kqCQZXo1cY6XkQdJgfFD2BfqkDqdStlxDYn4vA==", + "version": "1.0.77", + "resolved": "https://registry.npmjs.org/vuepress-theme-cosmos/-/vuepress-theme-cosmos-1.0.77.tgz", + "integrity": "sha512-gOvNC2g5rJoHYPBrYQmM3uX9lxR5Oh9G2SWaMPF7SBx7u2dxIOa9PM0iH3SssuPGf2iD7UscnW0z4pSEHwgWwg==", "requires": { "@cosmos-ui/vue": "^0.5.16", "@vuepress/plugin-last-updated": "^1.2.0", @@ -9242,9 +9242,9 @@ }, "dependencies": { "acorn": { - "version": "6.3.0", - "resolved": "https://registry.npmjs.org/acorn/-/acorn-6.3.0.tgz", - "integrity": "sha512-/czfa8BwS88b9gWQVhc8eknunSA2DoJpJyTQkhheIf5E48u1N0R4q/YxxsAeqRrmK9TQ/uYfgLDfZo91UlANIA==" + "version": "6.4.0", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-6.4.0.tgz", + "integrity": "sha512-gac8OEcQ2Li1dxIEWGZzsp2BitJxwkwcOm0zHAJLcPJaVvm58FRnk6RkuLRpU1EujipU2ZFODv2P9DLMfnV8mw==" }, "minimist": { "version": "0.0.8", diff --git a/docs/package.json b/docs/package.json index 5b178914d337..07ac45d1b15b 100644 --- a/docs/package.json +++ b/docs/package.json @@ -15,6 +15,6 @@ "license": "ISC", "dependencies": { "hotkeys-js": "^3.7.3", - "vuepress-theme-cosmos": "^1.0.76" + "vuepress-theme-cosmos": "^1.0.77" } } From 0ada884d6b38c8d2a96ef3101c33c0dd470849f4 Mon Sep 17 00:00:00 2001 From: Denis Fadeev Date: Mon, 2 Dec 2019 17:10:30 +0500 Subject: [PATCH 179/196] version --- docs/package-lock.json | 76 +++++++++++++++++++++++------------------- docs/package.json | 2 +- 2 files changed, 42 insertions(+), 36 deletions(-) diff --git a/docs/package-lock.json b/docs/package-lock.json index e2f774ace6b7..a0e8deda214b 100644 --- a/docs/package-lock.json +++ b/docs/package-lock.json @@ -1660,12 +1660,12 @@ } }, "autoprefixer": { - "version": "9.7.2", - "resolved": "https://registry.npmjs.org/autoprefixer/-/autoprefixer-9.7.2.tgz", - "integrity": "sha512-LCAfcdej1182uVvPOZnytbq61AhnOZ/4JelDaJGDeNwewyU1AMaNthcHsyz1NRjTmd2FkurMckLWfkHg3Z//KA==", + "version": "9.7.3", + "resolved": "https://registry.npmjs.org/autoprefixer/-/autoprefixer-9.7.3.tgz", + "integrity": "sha512-8T5Y1C5Iyj6PgkPSFd0ODvK9DIleuPKUPYniNxybS47g2k2wFgLZ46lGQHlBuGKIAEV8fbCDfKCCRS1tvOgc3Q==", "requires": { - "browserslist": "^4.7.3", - "caniuse-lite": "^1.0.30001010", + "browserslist": "^4.8.0", + "caniuse-lite": "^1.0.30001012", "chalk": "^2.4.2", "normalize-range": "^0.1.2", "num2fraction": "^1.2.2", @@ -1852,9 +1852,9 @@ "integrity": "sha512-Un7MIEDdUC5gNpcGDV97op1Ywk748MpHcFTHoYs6qnj1Z3j7I53VG3nwZhKzoBZmbdRNnb6WRdFlwl7tSDuZGw==" }, "bluebird": { - "version": "3.7.1", - "resolved": "https://registry.npmjs.org/bluebird/-/bluebird-3.7.1.tgz", - "integrity": "sha512-DdmyoGCleJnkbp3nkbxTLJ18rjDsE4yCggEwKNXkeV123sPNfOCYeDoeuOY+F2FrSjO1YXcTU+dsy96KMy+gcg==" + "version": "3.7.2", + "resolved": "https://registry.npmjs.org/bluebird/-/bluebird-3.7.2.tgz", + "integrity": "sha512-XpNj6GDQzdfW+r2Wnn7xiSAd7TM3jzkxGXBGTtWKuSXv1xUV+azxAm8jdWZN06QTQk+2N2XB9jRDkvbmQmcRtg==" }, "bn.js": { "version": "4.11.8", @@ -2015,13 +2015,13 @@ } }, "browserslist": { - "version": "4.7.3", - "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.7.3.tgz", - "integrity": "sha512-jWvmhqYpx+9EZm/FxcZSbUZyDEvDTLDi3nSAKbzEkyWvtI0mNSmUosey+5awDW1RUlrgXbQb5A6qY1xQH9U6MQ==", + "version": "4.8.0", + "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.8.0.tgz", + "integrity": "sha512-HYnxc/oLRWvJ3TsGegR0SRL/UDnknGq2s/a8dYYEO+kOQ9m9apKoS5oiathLKZdh/e9uE+/J3j92qPlGD/vTqA==", "requires": { - "caniuse-lite": "^1.0.30001010", - "electron-to-chromium": "^1.3.306", - "node-releases": "^1.1.40" + "caniuse-lite": "^1.0.30001012", + "electron-to-chromium": "^1.3.317", + "node-releases": "^1.1.41" } }, "buffer": { @@ -2209,9 +2209,9 @@ } }, "caniuse-lite": { - "version": "1.0.30001012", - "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001012.tgz", - "integrity": "sha512-7RR4Uh04t9K1uYRWzOJmzplgEOAXbfK72oVNokCdMzA67trrhPzy93ahKk1AWHiA0c58tD2P+NHqxrA8FZ+Trg==" + "version": "1.0.30001013", + "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001013.tgz", + "integrity": "sha512-hOAXaWKuq/UVFgYawxIOdPdyMQdYcwOCDOjnZcKn7wCgFUrhP7smuNZjGLuJlPSgE6aRA4cRJ+bGSrhtEt7ZAg==" }, "caseless": { "version": "0.12.0", @@ -3252,9 +3252,9 @@ "integrity": "sha1-WQxhFWsK4vTwJVcyoViyZrxWsh0=" }, "electron-to-chromium": { - "version": "1.3.314", - "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.3.314.tgz", - "integrity": "sha512-IKDR/xCxKFhPts7h+VaSXS02Z1mznP3fli1BbXWXeN89i2gCzKraU8qLpEid8YzKcmZdZD3Mly3cn5/lY9xsBQ==" + "version": "1.3.321", + "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.3.321.tgz", + "integrity": "sha512-jJy/BZK2s2eAjMPXVMSaCmo7/pSY2aKkfQ+LoAb5Wk39qAhyP9r8KU74c4qTgr9cD/lPUhJgReZxxqU0n5puog==" }, "elliptic": { "version": "6.5.2", @@ -4361,6 +4361,11 @@ "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.1.tgz", "integrity": "sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A==" }, + "fuzzyjs": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/fuzzyjs/-/fuzzyjs-4.0.3.tgz", + "integrity": "sha512-/QEZMkAcC96UxBDE6Bal4Fdb4EbxjhXLZB+jvbwiNeLWMjN1eoqsKv/25iMJddAfL5LUpTBSg4Vp2rci6VLS/A==" + }, "get-caller-file": { "version": "1.0.3", "resolved": "https://registry.npmjs.org/get-caller-file/-/get-caller-file-1.0.3.tgz", @@ -6719,9 +6724,9 @@ } }, "postcss-modules-scope": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/postcss-modules-scope/-/postcss-modules-scope-2.1.0.tgz", - "integrity": "sha512-91Rjps0JnmtUB0cujlc8KIKCsJXWjzuxGeT/+Q2i2HXKZ7nBUeF9YQTZZTNvHVoNYj1AthsjnGLtqDUE0Op79A==", + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/postcss-modules-scope/-/postcss-modules-scope-2.1.1.tgz", + "integrity": "sha512-OXRUPecnHCg8b9xWvldG/jUpRIGPNRka0r4D4j0ESUU2/5IOnpsjfPPmDprM3Ih8CgZ8FXjWqaniK5v4rWt3oQ==", "requires": { "postcss": "^7.0.6", "postcss-selector-parser": "^6.0.0" @@ -7064,9 +7069,9 @@ "integrity": "sha1-8FKijacOYYkX7wqKw0wa5aaChrM=" }, "psl": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/psl/-/psl-1.4.0.tgz", - "integrity": "sha512-HZzqCGPecFLyoRj5HLfuDSKYTJkAfB5thKBIkRHtGjWwY7p1dAyveIbXIq4tO0KYfDF2tHqPUgY9SDnGm00uFw==" + "version": "1.5.0", + "resolved": "https://registry.npmjs.org/psl/-/psl-1.5.0.tgz", + "integrity": "sha512-4vqUjKi2huMu1OJiLhi3jN6jeeKvMZdI1tYgi/njW5zV52jNLgSAZSdN16m9bJFe61/cT8ulmw4qFitV9QRsEA==" }, "public-encrypt": { "version": "4.0.3", @@ -8462,9 +8467,9 @@ "integrity": "sha512-4WK/bYZmj8xLr+HUCODHGF1ZFzsYffasLUgEiMBY4fgtltdO6B4WJtlSbPaDTLpYTcGVwM2qLnFTICEcNxs3kA==" }, "terser": { - "version": "4.4.0", - "resolved": "https://registry.npmjs.org/terser/-/terser-4.4.0.tgz", - "integrity": "sha512-oDG16n2WKm27JO8h4y/w3iqBGAOSCtq7k8dRmrn4Wf9NouL0b2WpMHGChFGZq4nFAQy1FsNJrVQHfurXOSTmOA==", + "version": "4.4.1", + "resolved": "https://registry.npmjs.org/terser/-/terser-4.4.1.tgz", + "integrity": "sha512-e05giplw+8sIYh50qXYHZmr0b76O5dOSm9JwSDebGFLri4ItYzxsnumiAK+yuI56R+H7uIjT9KbVEKNkrprzHw==", "requires": { "commander": "^2.20.0", "source-map": "~0.6.1", @@ -9136,9 +9141,9 @@ } }, "vuepress-plugin-container": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/vuepress-plugin-container/-/vuepress-plugin-container-2.1.1.tgz", - "integrity": "sha512-1hKZZ9DzVvgNZiSZfiTGiAzbq9bYww64kFz5yv3BRLKdEYX7rSIxKW6lFrbyaTCPQkT1qWgr95sM+GVetpcQFw==", + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/vuepress-plugin-container/-/vuepress-plugin-container-2.1.2.tgz", + "integrity": "sha512-Df5KoIDMYiFg45GTfFw2hIiLGSsjhms4f3ppl2UIBf5nWMxi2lfifcoo8MooMSfxboxRZjoDccqQfu0fypaKrQ==", "requires": { "markdown-it-container": "^2.0.0" } @@ -9160,9 +9165,9 @@ } }, "vuepress-theme-cosmos": { - "version": "1.0.77", - "resolved": "https://registry.npmjs.org/vuepress-theme-cosmos/-/vuepress-theme-cosmos-1.0.77.tgz", - "integrity": "sha512-gOvNC2g5rJoHYPBrYQmM3uX9lxR5Oh9G2SWaMPF7SBx7u2dxIOa9PM0iH3SssuPGf2iD7UscnW0z4pSEHwgWwg==", + "version": "1.0.79", + "resolved": "https://registry.npmjs.org/vuepress-theme-cosmos/-/vuepress-theme-cosmos-1.0.79.tgz", + "integrity": "sha512-uRVVpl9FKVnAZ6YB+Thw0hZyEEgxa2DQ+aouI2x1ujuZcObqa1ZMrlmbiMz1WVTe6SApnafXKWIN2rZ0C9RbQA==", "requires": { "@cosmos-ui/vue": "^0.5.16", "@vuepress/plugin-last-updated": "^1.2.0", @@ -9171,6 +9176,7 @@ "axios": "^0.19.0", "clipboard-copy": "^3.1.0", "docsearch.js": "^2.6.3", + "fuzzyjs": "^4.0.3", "hotkeys-js": "^3.7.3", "intersection-observer": "^0.7.0", "lunr": "^2.3.8", diff --git a/docs/package.json b/docs/package.json index 07ac45d1b15b..406da581f67b 100644 --- a/docs/package.json +++ b/docs/package.json @@ -15,6 +15,6 @@ "license": "ISC", "dependencies": { "hotkeys-js": "^3.7.3", - "vuepress-theme-cosmos": "^1.0.77" + "vuepress-theme-cosmos": "^1.0.79" } } From d63bf84e85bf1dbe0b24bff49b8d53678bdb7daa Mon Sep 17 00:00:00 2001 From: gamarin Date: Mon, 2 Dec 2019 18:33:59 +0100 Subject: [PATCH 180/196] small fixes --- docs/core/node.md | 2 +- docs/intro/overview.md | 2 +- docs/intro/sdk-app-architecture.md | 2 +- docs/intro/why-app-specific.md | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) diff --git a/docs/core/node.md b/docs/core/node.md index 62f9011fbe89..788c9f424658 100644 --- a/docs/core/node.md +++ b/docs/core/node.md @@ -16,7 +16,7 @@ The full-node client of any SDK application is built by running a `main` functio In general, developers will implement the `main.go` function with the following structure: - First, a [`codec`](./encoding.md) is instanciated for the application. -- Then, the [`config`] is retrieved and config parameters are set. This mainly involves setting the bech32 prefixes for [addresses and pubkeys](../basics/accounts.md#addresses-and-pubkeys). +- Then, the `config` is retrieved and config parameters are set. This mainly involves setting the bech32 prefixes for [addresses and pubkeys](../basics/accounts.md#addresses-and-pubkeys). +++ https://github.com/cosmos/cosmos-sdk/blob/master/types/config.go#L10-L21 - Using [cobra](https://github.com/spf13/cobra), the root command of the full-node client is created. After that, all the custom commands of the application are added using the `AddCommand()` method of `rootCmd`. - Add default server commands to `rootCmd` using the `server.AddCommands(ctx, cdc, rootCmd, newApp, exportAppStateAndTMValidators)` method. These commands are separated from the ones added above since they are standard and defined at SDK level. They should be shared by all SDK-based applications. They include the most important command: the [`start` command](#start-command). diff --git a/docs/intro/overview.md b/docs/intro/overview.md index 742f4a993b9d..3ada29edadbc 100644 --- a/docs/intro/overview.md +++ b/docs/intro/overview.md @@ -32,6 +32,6 @@ The Cosmos SDK is the most advanced framework for building custom application-sp - Learn more about the [architecture of an SDK application](./sdk-app-architecture.md) - Learn how to build an application-specific blockchain from scratch with the [SDK Tutorial](https://cosmos.network/docs/tutorial) -## Next +## Next {hide} Learn about [application-specific blockchains](./why-app-specific.md). \ No newline at end of file diff --git a/docs/intro/sdk-app-architecture.md b/docs/intro/sdk-app-architecture.md index 47b1cfd32a03..d0c6b0805559 100644 --- a/docs/intro/sdk-app-architecture.md +++ b/docs/intro/sdk-app-architecture.md @@ -95,6 +95,6 @@ For a more detailed view of the ABCI methods and types, click [here](https://ten Any application built on Tendermint needs to implement the ABCI interface in order to communicate with the underlying local Tendermint engine. Fortunately, you do not have to implement the ABCI interface. The Cosmos SDK provides a boilerplate implementation of it in the form of [baseapp](./sdk-design.md#baseapp). -## Next +## Next {hide} Read about the [high-level design principles of the SDK](./sdk-design.md) \ No newline at end of file diff --git a/docs/intro/why-app-specific.md b/docs/intro/why-app-specific.md index c4be10289add..1497e0f03ca1 100644 --- a/docs/intro/why-app-specific.md +++ b/docs/intro/why-app-specific.md @@ -75,6 +75,6 @@ One of the major benefits of application-specific blockchains is sovereignty. A The fundamental issue here is that the governance of the application and the governance of the network are not aligned. This issue is solved by application-specific blockchains. Because application-specific blockchains specialize to operate a single application, stakeholders the application has full control over the entire chain. This ensures the community will not be stuck if a bug is discovered, and that it has the entire freedom to choose how it is going to evolve. -## Next +## Next {hide} - Learn more about the [high-level architecture](./sdk-app-architecture.md) of an SDK application. From 9dd99f11fc7a56faf6a1a27f4b18a9b08bad089f Mon Sep 17 00:00:00 2001 From: Denis Fadeev Date: Fri, 6 Dec 2019 13:50:45 +0500 Subject: [PATCH 181/196] modules readme, version --- README.md | 5 ++++ docs/README.md | 16 +++++------ docs/package-lock.json | 60 +++++++++++++++++++++--------------------- docs/package.json | 2 +- docs/post.sh | 6 +---- docs/pre.sh | 4 ++- x/README.md | 5 ++++ 7 files changed, 53 insertions(+), 45 deletions(-) diff --git a/README.md b/README.md index 6a9b409f6f46..83a5736d1379 100644 --- a/README.md +++ b/README.md @@ -1,3 +1,8 @@ +--- +parent: + order: false +--- + # Cosmos SDK ![banner](docs/cosmos-sdk-image.jpg) diff --git a/docs/README.md b/docs/README.md index 4e50473bb7f3..a85579c4d32f 100644 --- a/docs/README.md +++ b/docs/README.md @@ -19,29 +19,29 @@ features: image: window sections: - title: Introduction - desc: Short sentence describing this section. + desc: High-level overview of the Cosmos SDK. url: /intro icon: introduction - title: Basics - desc: Short sentence describing this section. + desc: Anatomy of a blockchain, transaction lifecycle, accounts and more. icon: basics url: /basics - title: SDK Core - desc: Short sentence describing this section. + desc: Read about the core concepts like `baseapp`, the store, or the server. icon: core url: /core - title: Building Modules - desc: Short sentence describing this section. + desc: Discover how to build modules for the Cosmos SDK. icon: modules url: /building-modules - title: Interfaces - desc: Short sentence describing this section. + desc: Build interfaces for Cosmos SDK applications. icon: interfaces url: /interfaces - - title: Specifications - desc: Short sentence describing this section. + - title: Modules + desc: Explore existing modules to build your application with. icon: specifications - url: / + url: /modules stack: - title: Cosmos Hub desc: Short description about Cosmos Hub, no longer than a few of lines. diff --git a/docs/package-lock.json b/docs/package-lock.json index a0e8deda214b..400bd2cf1eb8 100644 --- a/docs/package-lock.json +++ b/docs/package-lock.json @@ -2015,13 +2015,13 @@ } }, "browserslist": { - "version": "4.8.0", - "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.8.0.tgz", - "integrity": "sha512-HYnxc/oLRWvJ3TsGegR0SRL/UDnknGq2s/a8dYYEO+kOQ9m9apKoS5oiathLKZdh/e9uE+/J3j92qPlGD/vTqA==", + "version": "4.8.2", + "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.8.2.tgz", + "integrity": "sha512-+M4oeaTplPm/f1pXDw84YohEv7B1i/2Aisei8s4s6k3QsoSHa7i5sz8u/cGQkkatCPxMASKxPualR4wwYgVboA==", "requires": { - "caniuse-lite": "^1.0.30001012", - "electron-to-chromium": "^1.3.317", - "node-releases": "^1.1.41" + "caniuse-lite": "^1.0.30001015", + "electron-to-chromium": "^1.3.322", + "node-releases": "^1.1.42" } }, "buffer": { @@ -2209,9 +2209,9 @@ } }, "caniuse-lite": { - "version": "1.0.30001013", - "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001013.tgz", - "integrity": "sha512-hOAXaWKuq/UVFgYawxIOdPdyMQdYcwOCDOjnZcKn7wCgFUrhP7smuNZjGLuJlPSgE6aRA4cRJ+bGSrhtEt7ZAg==" + "version": "1.0.30001015", + "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001015.tgz", + "integrity": "sha512-/xL2AbW/XWHNu1gnIrO8UitBGoFthcsDgU9VLK1/dpsoxbaD5LscHozKze05R6WLsBvLhqv78dAPozMFQBYLbQ==" }, "caseless": { "version": "0.12.0", @@ -3252,9 +3252,9 @@ "integrity": "sha1-WQxhFWsK4vTwJVcyoViyZrxWsh0=" }, "electron-to-chromium": { - "version": "1.3.321", - "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.3.321.tgz", - "integrity": "sha512-jJy/BZK2s2eAjMPXVMSaCmo7/pSY2aKkfQ+LoAb5Wk39qAhyP9r8KU74c4qTgr9cD/lPUhJgReZxxqU0n5puog==" + "version": "1.3.322", + "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.3.322.tgz", + "integrity": "sha512-Tc8JQEfGQ1MzfSzI/bTlSr7btJv/FFO7Yh6tanqVmIWOuNCu6/D1MilIEgLtmWqIrsv+o4IjpLAhgMBr/ncNAA==" }, "elliptic": { "version": "6.5.2", @@ -3350,9 +3350,9 @@ } }, "es-abstract": { - "version": "1.16.2", - "resolved": "https://registry.npmjs.org/es-abstract/-/es-abstract-1.16.2.tgz", - "integrity": "sha512-jYo/J8XU2emLXl3OLwfwtuFfuF2w6DYPs+xy9ZfVyPkDcrauu6LYrw/q2TyCtrbc/KUdCiC5e9UajRhgNkVopA==", + "version": "1.16.3", + "resolved": "https://registry.npmjs.org/es-abstract/-/es-abstract-1.16.3.tgz", + "integrity": "sha512-WtY7Fx5LiOnSYgF5eg/1T+GONaGmpvpPdCpSnYij+U2gDTL0UPfWrhDw7b2IYb+9NQJsYpCA0wOQvZfsd6YwRw==", "requires": { "es-to-primitive": "^1.2.1", "function-bind": "^1.1.1", @@ -5909,9 +5909,9 @@ } }, "node-releases": { - "version": "1.1.41", - "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-1.1.41.tgz", - "integrity": "sha512-+IctMa7wIs8Cfsa8iYzeaLTFwv5Y4r5jZud+4AnfymzeEXKBCavFX0KBgzVaPVqf0ywa6PrO8/b+bPqdwjGBSg==", + "version": "1.1.42", + "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-1.1.42.tgz", + "integrity": "sha512-OQ/ESmUqGawI2PRX+XIRao44qWYBBfN54ImQYdWVTQqUckuejOg76ysSqDBK8NG3zwySRVnX36JwDQ6x+9GxzA==", "requires": { "semver": "^6.3.0" }, @@ -7069,9 +7069,9 @@ "integrity": "sha1-8FKijacOYYkX7wqKw0wa5aaChrM=" }, "psl": { - "version": "1.5.0", - "resolved": "https://registry.npmjs.org/psl/-/psl-1.5.0.tgz", - "integrity": "sha512-4vqUjKi2huMu1OJiLhi3jN6jeeKvMZdI1tYgi/njW5zV52jNLgSAZSdN16m9bJFe61/cT8ulmw4qFitV9QRsEA==" + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/psl/-/psl-1.6.0.tgz", + "integrity": "sha512-SYKKmVel98NCOYXpkwUqZqh0ahZeeKfmisiLIcEZdsb+WbLv02g/dI5BUmZnIyOe7RzZtLax81nnb2HbvC2tzA==" }, "public-encrypt": { "version": "4.0.3", @@ -7737,9 +7737,9 @@ } }, "serialize-javascript": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/serialize-javascript/-/serialize-javascript-2.1.0.tgz", - "integrity": "sha512-a/mxFfU00QT88umAJQsNWOnUKckhNCqOl028N48e7wFmo2/EHpTo9Wso+iJJCMrQnmFvcjto5RJdAHEvVhcyUQ==" + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/serialize-javascript/-/serialize-javascript-2.1.1.tgz", + "integrity": "sha512-MPLPRpD4FNqWq9tTIjYG5LesFouDhdyH0EPY3gVK4DRD5+g4aDqdNSzLIwceulo3Yj+PL1bPh6laE5+H6LTcrQ==" }, "serve-index": { "version": "1.9.1", @@ -8467,9 +8467,9 @@ "integrity": "sha512-4WK/bYZmj8xLr+HUCODHGF1ZFzsYffasLUgEiMBY4fgtltdO6B4WJtlSbPaDTLpYTcGVwM2qLnFTICEcNxs3kA==" }, "terser": { - "version": "4.4.1", - "resolved": "https://registry.npmjs.org/terser/-/terser-4.4.1.tgz", - "integrity": "sha512-e05giplw+8sIYh50qXYHZmr0b76O5dOSm9JwSDebGFLri4ItYzxsnumiAK+yuI56R+H7uIjT9KbVEKNkrprzHw==", + "version": "4.4.2", + "resolved": "https://registry.npmjs.org/terser/-/terser-4.4.2.tgz", + "integrity": "sha512-Uufrsvhj9O1ikwgITGsZ5EZS6qPokUOkCegS7fYOdGTv+OA90vndUbU6PEjr5ePqHfNUbGyMO7xyIZv2MhsALQ==", "requires": { "commander": "^2.20.0", "source-map": "~0.6.1", @@ -9165,9 +9165,9 @@ } }, "vuepress-theme-cosmos": { - "version": "1.0.79", - "resolved": "https://registry.npmjs.org/vuepress-theme-cosmos/-/vuepress-theme-cosmos-1.0.79.tgz", - "integrity": "sha512-uRVVpl9FKVnAZ6YB+Thw0hZyEEgxa2DQ+aouI2x1ujuZcObqa1ZMrlmbiMz1WVTe6SApnafXKWIN2rZ0C9RbQA==", + "version": "1.0.80", + "resolved": "https://registry.npmjs.org/vuepress-theme-cosmos/-/vuepress-theme-cosmos-1.0.80.tgz", + "integrity": "sha512-XNC38wmyn7ZoUklYfZb7tpj4A+mo04zFhPIpJK/Tok1TcXmMK0ZIRICTtADXttq865bK27yc3UAADkB9j9AYmw==", "requires": { "@cosmos-ui/vue": "^0.5.16", "@vuepress/plugin-last-updated": "^1.2.0", diff --git a/docs/package.json b/docs/package.json index 406da581f67b..d3e551c69de7 100644 --- a/docs/package.json +++ b/docs/package.json @@ -15,6 +15,6 @@ "license": "ISC", "dependencies": { "hotkeys-js": "^3.7.3", - "vuepress-theme-cosmos": "^1.0.79" + "vuepress-theme-cosmos": "^1.0.80" } } diff --git a/docs/post.sh b/docs/post.sh index fa6afe440f43..5d8c7ed48737 100755 --- a/docs/post.sh +++ b/docs/post.sh @@ -1,7 +1,3 @@ #!/usr/bin/env bash -for D in ../x/*; do - if [ -d "${D}" ]; then - rm -rf "modules/$(echo $D | awk -F/ '{print $NF}')" - fi -done \ No newline at end of file +rm -rf modules \ No newline at end of file diff --git a/docs/pre.sh b/docs/pre.sh index c31142c184b3..a71ac0b65d5e 100755 --- a/docs/pre.sh +++ b/docs/pre.sh @@ -7,4 +7,6 @@ for D in ../x/*; do rm -rf "modules/$(echo $D | awk -F/ '{print $NF}')" mkdir -p "modules/$(echo $D | awk -F/ '{print $NF}')" && cp -r $D/spec/* "$_" fi -done \ No newline at end of file +done + +cp ../x/README.md modules/ \ No newline at end of file diff --git a/x/README.md b/x/README.md index bdb5ae2f4fc0..b46a2dd138a6 100644 --- a/x/README.md +++ b/x/README.md @@ -1,3 +1,8 @@ +--- +parent: + order: false +--- + # List of Modules This repository contains a working implementation of modules that can be used in Cosmos SDK applications, along with their respective documentation. From f38805731c7774d854336e0154088c7bfb2db956 Mon Sep 17 00:00:00 2001 From: Denis Fadeev Date: Fri, 6 Dec 2019 13:53:49 +0500 Subject: [PATCH 182/196] remove hotkeys dep, version --- docs/package-lock.json | 6 +++--- docs/package.json | 3 +-- 2 files changed, 4 insertions(+), 5 deletions(-) diff --git a/docs/package-lock.json b/docs/package-lock.json index 400bd2cf1eb8..6458ca4eb889 100644 --- a/docs/package-lock.json +++ b/docs/package-lock.json @@ -9165,9 +9165,9 @@ } }, "vuepress-theme-cosmos": { - "version": "1.0.80", - "resolved": "https://registry.npmjs.org/vuepress-theme-cosmos/-/vuepress-theme-cosmos-1.0.80.tgz", - "integrity": "sha512-XNC38wmyn7ZoUklYfZb7tpj4A+mo04zFhPIpJK/Tok1TcXmMK0ZIRICTtADXttq865bK27yc3UAADkB9j9AYmw==", + "version": "1.0.82", + "resolved": "https://registry.npmjs.org/vuepress-theme-cosmos/-/vuepress-theme-cosmos-1.0.82.tgz", + "integrity": "sha512-0LM7RI69wMKVY4FFEZzcmYIPfzfHHUXr+xyhd/1I19KNO1ZwcLgsGUg9lEaTfd3W1gDfuwxaqzuCDnNyn27MRA==", "requires": { "@cosmos-ui/vue": "^0.5.16", "@vuepress/plugin-last-updated": "^1.2.0", diff --git a/docs/package.json b/docs/package.json index d3e551c69de7..e69fc13f5032 100644 --- a/docs/package.json +++ b/docs/package.json @@ -14,7 +14,6 @@ "author": "", "license": "ISC", "dependencies": { - "hotkeys-js": "^3.7.3", - "vuepress-theme-cosmos": "^1.0.80" + "vuepress-theme-cosmos": "^1.0.82" } } From 097d05ea9adff426680e1a56f3786facdbe5f9ad Mon Sep 17 00:00:00 2001 From: Denis Fadeev Date: Fri, 6 Dec 2019 17:42:36 +0500 Subject: [PATCH 183/196] version --- docs/package-lock.json | 6 +++--- docs/package.json | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/docs/package-lock.json b/docs/package-lock.json index 6458ca4eb889..bd5690dea6a2 100644 --- a/docs/package-lock.json +++ b/docs/package-lock.json @@ -9165,9 +9165,9 @@ } }, "vuepress-theme-cosmos": { - "version": "1.0.82", - "resolved": "https://registry.npmjs.org/vuepress-theme-cosmos/-/vuepress-theme-cosmos-1.0.82.tgz", - "integrity": "sha512-0LM7RI69wMKVY4FFEZzcmYIPfzfHHUXr+xyhd/1I19KNO1ZwcLgsGUg9lEaTfd3W1gDfuwxaqzuCDnNyn27MRA==", + "version": "1.0.83", + "resolved": "https://registry.npmjs.org/vuepress-theme-cosmos/-/vuepress-theme-cosmos-1.0.83.tgz", + "integrity": "sha512-SjDGCvpR2P1gWbkiDQT0yD60CS/hg9FhZvJ17WT/zhpLfeiU7RljhyAK1R4uIFtuvM2XHlUEskW5wVRubIqbQQ==", "requires": { "@cosmos-ui/vue": "^0.5.16", "@vuepress/plugin-last-updated": "^1.2.0", diff --git a/docs/package.json b/docs/package.json index e69fc13f5032..c2e823920e3a 100644 --- a/docs/package.json +++ b/docs/package.json @@ -14,6 +14,6 @@ "author": "", "license": "ISC", "dependencies": { - "vuepress-theme-cosmos": "^1.0.82" + "vuepress-theme-cosmos": "^1.0.83" } } From a7d55232482402acf83ef316028ed8ab89ed5913 Mon Sep 17 00:00:00 2001 From: Denis Fadeev Date: Fri, 6 Dec 2019 19:58:46 +0500 Subject: [PATCH 184/196] version --- docs/package-lock.json | 81 +++++++++++++++++++----------------------- docs/package.json | 2 +- 2 files changed, 38 insertions(+), 45 deletions(-) diff --git a/docs/package-lock.json b/docs/package-lock.json index bd5690dea6a2..972406f13e85 100644 --- a/docs/package-lock.json +++ b/docs/package-lock.json @@ -13,14 +13,14 @@ } }, "@babel/core": { - "version": "7.7.4", - "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.7.4.tgz", - "integrity": "sha512-+bYbx56j4nYBmpsWtnPUsKW3NdnYxbqyfrP2w9wILBuHzdfIKz9prieZK0DFPyIzkjYVUe4QkusGL07r5pXznQ==", + "version": "7.7.5", + "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.7.5.tgz", + "integrity": "sha512-M42+ScN4+1S9iB6f+TL7QBpoQETxbclx+KNoKJABghnKYE+fMzSGqst0BZJc8CpI625bwPwYgUyRvxZ+0mZzpw==", "requires": { "@babel/code-frame": "^7.5.5", "@babel/generator": "^7.7.4", "@babel/helpers": "^7.7.4", - "@babel/parser": "^7.7.4", + "@babel/parser": "^7.7.5", "@babel/template": "^7.7.4", "@babel/traverse": "^7.7.4", "@babel/types": "^7.7.4", @@ -190,9 +190,9 @@ } }, "@babel/helper-module-transforms": { - "version": "7.7.4", - "resolved": "https://registry.npmjs.org/@babel/helper-module-transforms/-/helper-module-transforms-7.7.4.tgz", - "integrity": "sha512-ehGBu4mXrhs0FxAqN8tWkzF8GSIGAiEumu4ONZ/hD9M88uHcD+Yu2ttKfOCgwzoesJOJrtQh7trI5YPbRtMmnA==", + "version": "7.7.5", + "resolved": "https://registry.npmjs.org/@babel/helper-module-transforms/-/helper-module-transforms-7.7.5.tgz", + "integrity": "sha512-A7pSxyJf1gN5qXVcidwLWydjftUN878VkalhXX5iQDuGyiGK3sOrrKKHF4/A4fwHtnsotv/NipwAeLzY4KQPvw==", "requires": { "@babel/helper-module-imports": "^7.7.4", "@babel/helper-simple-access": "^7.7.4", @@ -295,9 +295,9 @@ } }, "@babel/parser": { - "version": "7.7.4", - "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.7.4.tgz", - "integrity": "sha512-jIwvLO0zCL+O/LmEJQjWA75MQTWwx3c3u2JOTDK5D3/9egrWRRA0/0hk9XXywYnXZVVpzrBYeIQTmhwUaePI9g==" + "version": "7.7.5", + "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.7.5.tgz", + "integrity": "sha512-KNlOe9+/nk4i29g0VXgl8PEXIRms5xKLJeuZ6UptN0fHv+jDiriG+y94X6qAgWTR0h3KaoM1wK5G5h7MHFRSig==" }, "@babel/plugin-proposal-async-generator-functions": { "version": "7.7.4", @@ -538,21 +538,21 @@ } }, "@babel/plugin-transform-modules-amd": { - "version": "7.7.4", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-amd/-/plugin-transform-modules-amd-7.7.4.tgz", - "integrity": "sha512-/542/5LNA18YDtg1F+QHvvUSlxdvjZoD/aldQwkq+E3WCkbEjNSN9zdrOXaSlfg3IfGi22ijzecklF/A7kVZFQ==", + "version": "7.7.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-amd/-/plugin-transform-modules-amd-7.7.5.tgz", + "integrity": "sha512-CT57FG4A2ZUNU1v+HdvDSDrjNWBrtCmSH6YbbgN3Lrf0Di/q/lWRxZrE72p3+HCCz9UjfZOEBdphgC0nzOS6DQ==", "requires": { - "@babel/helper-module-transforms": "^7.7.4", + "@babel/helper-module-transforms": "^7.7.5", "@babel/helper-plugin-utils": "^7.0.0", "babel-plugin-dynamic-import-node": "^2.3.0" } }, "@babel/plugin-transform-modules-commonjs": { - "version": "7.7.4", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-commonjs/-/plugin-transform-modules-commonjs-7.7.4.tgz", - "integrity": "sha512-k8iVS7Jhc367IcNF53KCwIXtKAH7czev866ThsTgy8CwlXjnKZna2VHwChglzLleYrcHz1eQEIJlGRQxB53nqA==", + "version": "7.7.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-commonjs/-/plugin-transform-modules-commonjs-7.7.5.tgz", + "integrity": "sha512-9Cq4zTFExwFhQI6MT1aFxgqhIsMWQWDVwOgLzl7PTWJHsNaqFvklAU+Oz6AQLAS0dJKTwZSOCo20INwktxpi3Q==", "requires": { - "@babel/helper-module-transforms": "^7.7.4", + "@babel/helper-module-transforms": "^7.7.5", "@babel/helper-plugin-utils": "^7.0.0", "@babel/helper-simple-access": "^7.7.4", "babel-plugin-dynamic-import-node": "^2.3.0" @@ -613,17 +613,17 @@ } }, "@babel/plugin-transform-regenerator": { - "version": "7.7.4", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-regenerator/-/plugin-transform-regenerator-7.7.4.tgz", - "integrity": "sha512-e7MWl5UJvmPEwFJTwkBlPmqixCtr9yAASBqff4ggXTNicZiwbF8Eefzm6NVgfiBp7JdAGItecnctKTgH44q2Jw==", + "version": "7.7.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-regenerator/-/plugin-transform-regenerator-7.7.5.tgz", + "integrity": "sha512-/8I8tPvX2FkuEyWbjRCt4qTAgZK0DVy8QRguhA524UH48RfGJy94On2ri+dCuwOpcerPRl9O4ebQkRcVzIaGBw==", "requires": { "regenerator-transform": "^0.14.0" } }, "@babel/plugin-transform-runtime": { - "version": "7.7.4", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-runtime/-/plugin-transform-runtime-7.7.4.tgz", - "integrity": "sha512-O8kSkS5fP74Ad/8pfsCMGa8sBRdLxYoSReaARRNSz3FbFQj3z/QUvoUmJ28gn9BO93YfnXc3j+Xyaqe8cKDNBQ==", + "version": "7.7.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-runtime/-/plugin-transform-runtime-7.7.5.tgz", + "integrity": "sha512-X+w9wJRzOoAPBfTEcFJisVppQ8OTQMxrVgmi7ZLVWehqVd8ciHN09A1XjB91Iw+Sgf77Y9Oy7CfxKNr1tVkK7g==", "requires": { "@babel/helper-module-imports": "^7.7.4", "@babel/helper-plugin-utils": "^7.0.0", @@ -733,9 +733,9 @@ } }, "@babel/runtime": { - "version": "7.7.4", - "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.7.4.tgz", - "integrity": "sha512-r24eVUUr0QqNZa+qrImUk8fn5SPhHq+IfYvIoIMg0do3GdK9sMdiLKP3GYVVaxpPKORgm8KRKaNTEhAjgIpLMw==", + "version": "7.7.5", + "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.7.5.tgz", + "integrity": "sha512-UXhClKWTL7/vlYX49kETXti6VbpPJK/pdsIOqUMhUUES/lqThpNTsmC/0aU/IW4uozDUx17axjeqel7SCYF6EQ==", "requires": { "regenerator-runtime": "^0.13.2" }, @@ -748,9 +748,9 @@ } }, "@babel/runtime-corejs2": { - "version": "7.7.4", - "resolved": "https://registry.npmjs.org/@babel/runtime-corejs2/-/runtime-corejs2-7.7.4.tgz", - "integrity": "sha512-hKNcmHQbBSJFnZ82ewYtWDZ3fXkP/l1XcfRtm7c8gHPM/DMecJtFFBEp7KMLZTuHwwb7RfemHdsEnd7L916Z6A==", + "version": "7.7.5", + "resolved": "https://registry.npmjs.org/@babel/runtime-corejs2/-/runtime-corejs2-7.7.5.tgz", + "integrity": "sha512-cN5YmGR1PKMRIeOgwaxp7Y003BEGoUmtPQyECaSvXgwMW1Em2U1xuJSac9NGOJDBn7I82TRmJl0UGieCWkUYbQ==", "requires": { "core-js": "^2.6.5", "regenerator-runtime": "^0.13.2" @@ -8484,26 +8484,19 @@ } }, "terser-webpack-plugin": { - "version": "1.4.1", - "resolved": "https://registry.npmjs.org/terser-webpack-plugin/-/terser-webpack-plugin-1.4.1.tgz", - "integrity": "sha512-ZXmmfiwtCLfz8WKZyYUuuHf3dMYEjg8NrjHMb0JqHVHVOSkzp3cW2/XG1fP3tRhqEqSzMwzzRQGtAPbs4Cncxg==", + "version": "1.4.2", + "resolved": "https://registry.npmjs.org/terser-webpack-plugin/-/terser-webpack-plugin-1.4.2.tgz", + "integrity": "sha512-fdEb91kR2l+BVgES77N/NTXWZlpX6vX+pYPjnX5grcDYBF2CMnzJiXX4NNlna4l04lvCW39lZ+O/jSvUhHH/ew==", "requires": { "cacache": "^12.0.2", "find-cache-dir": "^2.1.0", "is-wsl": "^1.1.0", "schema-utils": "^1.0.0", - "serialize-javascript": "^1.7.0", + "serialize-javascript": "^2.1.1", "source-map": "^0.6.1", "terser": "^4.1.2", "webpack-sources": "^1.4.0", "worker-farm": "^1.7.0" - }, - "dependencies": { - "serialize-javascript": { - "version": "1.9.1", - "resolved": "https://registry.npmjs.org/serialize-javascript/-/serialize-javascript-1.9.1.tgz", - "integrity": "sha512-0Vb/54WJ6k5v8sSWN09S0ora+Hnr+cX40r9F170nT+mSkaxltoE/7R3OrIdBSUv1OoiobH1QoWQbCnAO+e8J1A==" - } } }, "text-table": { @@ -9165,9 +9158,9 @@ } }, "vuepress-theme-cosmos": { - "version": "1.0.83", - "resolved": "https://registry.npmjs.org/vuepress-theme-cosmos/-/vuepress-theme-cosmos-1.0.83.tgz", - "integrity": "sha512-SjDGCvpR2P1gWbkiDQT0yD60CS/hg9FhZvJ17WT/zhpLfeiU7RljhyAK1R4uIFtuvM2XHlUEskW5wVRubIqbQQ==", + "version": "1.0.84", + "resolved": "https://registry.npmjs.org/vuepress-theme-cosmos/-/vuepress-theme-cosmos-1.0.84.tgz", + "integrity": "sha512-4+XjdJI8bIcR2ZPRjkUX10XyFCfM5WXn2Z7Wqc0jtsZE0btnn2H6An9HZ5D/wJapK258mlchMWVJ4Y4CG9qEHw==", "requires": { "@cosmos-ui/vue": "^0.5.16", "@vuepress/plugin-last-updated": "^1.2.0", diff --git a/docs/package.json b/docs/package.json index c2e823920e3a..26bc01bec0ec 100644 --- a/docs/package.json +++ b/docs/package.json @@ -14,6 +14,6 @@ "author": "", "license": "ISC", "dependencies": { - "vuepress-theme-cosmos": "^1.0.83" + "vuepress-theme-cosmos": "^1.0.84" } } From f4e319defddf57af9266316cc2d115cf4e26ff8b Mon Sep 17 00:00:00 2001 From: Denis Fadeev Date: Fri, 6 Dec 2019 23:50:25 +0500 Subject: [PATCH 185/196] version --- docs/package-lock.json | 6 +++--- docs/package.json | 4 ++-- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/docs/package-lock.json b/docs/package-lock.json index 972406f13e85..112a0d45e879 100644 --- a/docs/package-lock.json +++ b/docs/package-lock.json @@ -9158,9 +9158,9 @@ } }, "vuepress-theme-cosmos": { - "version": "1.0.84", - "resolved": "https://registry.npmjs.org/vuepress-theme-cosmos/-/vuepress-theme-cosmos-1.0.84.tgz", - "integrity": "sha512-4+XjdJI8bIcR2ZPRjkUX10XyFCfM5WXn2Z7Wqc0jtsZE0btnn2H6An9HZ5D/wJapK258mlchMWVJ4Y4CG9qEHw==", + "version": "1.0.85", + "resolved": "https://registry.npmjs.org/vuepress-theme-cosmos/-/vuepress-theme-cosmos-1.0.85.tgz", + "integrity": "sha512-3K3nF/I95Kdb2WH5KVh4UOy7blF4p+R9tfS8+tPEDXRn3taJP0jDyoKCBQwWFaSAlRTGywwDzZwO5jiw0cmErg==", "requires": { "@cosmos-ui/vue": "^0.5.16", "@vuepress/plugin-last-updated": "^1.2.0", diff --git a/docs/package.json b/docs/package.json index 26bc01bec0ec..cb8e19a7336f 100644 --- a/docs/package.json +++ b/docs/package.json @@ -8,12 +8,12 @@ "serve": "trap 'exit 0' SIGINT; vuepress dev", "postserve": "./post.sh", "prebuild": "./pre.sh", - "build": "trap 'exit 0' SIGINT; vuepress build", + "build": "trap 'exit 0' SIGINT; vuepress build --no-cache", "postbuild": "./post.sh" }, "author": "", "license": "ISC", "dependencies": { - "vuepress-theme-cosmos": "^1.0.84" + "vuepress-theme-cosmos": "^1.0.85" } } From a664b8de155df9357d7acef922f32b706bd43f58 Mon Sep 17 00:00:00 2001 From: Denis Fadeev Date: Sun, 8 Dec 2019 23:13:45 +0500 Subject: [PATCH 186/196] version --- docs/basics/app-anatomy.md | 4 ---- docs/package-lock.json | 36 ++++++++++++++++++------------------ docs/package.json | 4 ++-- 3 files changed, 20 insertions(+), 24 deletions(-) diff --git a/docs/basics/app-anatomy.md b/docs/basics/app-anatomy.md index 820f07246607..aebe9e2fdff7 100644 --- a/docs/basics/app-anatomy.md +++ b/docs/basics/app-anatomy.md @@ -5,10 +5,6 @@ synopsis: "This document describes the core parts of a Cosmos SDK application. T # Anatomy of an SDK Application -## Pre-requisite Readings {hide} - -- [High-level overview of the architecture of an SDK application](../intro/sdk-app-architecture.md) {prereq} -- [Cosmos SDK design overview](../intro/sdk-design.md) {prereq} ## Node Client diff --git a/docs/package-lock.json b/docs/package-lock.json index 112a0d45e879..1a356c9a0d39 100644 --- a/docs/package-lock.json +++ b/docs/package-lock.json @@ -621,9 +621,9 @@ } }, "@babel/plugin-transform-runtime": { - "version": "7.7.5", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-runtime/-/plugin-transform-runtime-7.7.5.tgz", - "integrity": "sha512-X+w9wJRzOoAPBfTEcFJisVppQ8OTQMxrVgmi7ZLVWehqVd8ciHN09A1XjB91Iw+Sgf77Y9Oy7CfxKNr1tVkK7g==", + "version": "7.7.6", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-runtime/-/plugin-transform-runtime-7.7.6.tgz", + "integrity": "sha512-tajQY+YmXR7JjTwRvwL4HePqoL3DYxpYXIHKVvrOIvJmeHe2y1w4tz5qz9ObUDC9m76rCzIMPyn4eERuwA4a4A==", "requires": { "@babel/helper-module-imports": "^7.7.4", "@babel/helper-plugin-utils": "^7.0.0", @@ -733,9 +733,9 @@ } }, "@babel/runtime": { - "version": "7.7.5", - "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.7.5.tgz", - "integrity": "sha512-UXhClKWTL7/vlYX49kETXti6VbpPJK/pdsIOqUMhUUES/lqThpNTsmC/0aU/IW4uozDUx17axjeqel7SCYF6EQ==", + "version": "7.7.6", + "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.7.6.tgz", + "integrity": "sha512-BWAJxpNVa0QlE5gZdWjSxXtemZyZ9RmrmVozxt3NUXeZhVIJ5ANyqmMc0JDrivBZyxUuQvFxlvH4OWWOogGfUw==", "requires": { "regenerator-runtime": "^0.13.2" }, @@ -748,9 +748,9 @@ } }, "@babel/runtime-corejs2": { - "version": "7.7.5", - "resolved": "https://registry.npmjs.org/@babel/runtime-corejs2/-/runtime-corejs2-7.7.5.tgz", - "integrity": "sha512-cN5YmGR1PKMRIeOgwaxp7Y003BEGoUmtPQyECaSvXgwMW1Em2U1xuJSac9NGOJDBn7I82TRmJl0UGieCWkUYbQ==", + "version": "7.7.6", + "resolved": "https://registry.npmjs.org/@babel/runtime-corejs2/-/runtime-corejs2-7.7.6.tgz", + "integrity": "sha512-QYp/8xdH8iMin3pH5gtT/rUuttVfIcOhWBC3wh9Eh/qs4jEe39+3DpCDLgWXhMQgiCTOH8mrLSvQ0OHOCcox9g==", "requires": { "core-js": "^2.6.5", "regenerator-runtime": "^0.13.2" @@ -991,9 +991,9 @@ } }, "@vue/component-compiler-utils": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/@vue/component-compiler-utils/-/component-compiler-utils-3.0.2.tgz", - "integrity": "sha512-BSnY2PmW4QwU1AOcGSNYAmEPLjdQ9itl1YpLCWtpwMA5Jy/aqWNuzZ9+ZZ8h6yZJ53W95tVkEP6yrXJ/zUHdEA==", + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/@vue/component-compiler-utils/-/component-compiler-utils-3.1.0.tgz", + "integrity": "sha512-OJ7swvl8LtKtX5aYP8jHhO6fQBIRIGkU6rvWzK+CGJiNOnvg16nzcBkd9qMZzW8trI2AsqAKx263nv7kb5rhZw==", "requires": { "consolidate": "^0.15.1", "hash-sum": "^1.0.2", @@ -6439,9 +6439,9 @@ "integrity": "sha1-AerA/jta9xoqbAL+q7jB/vfgDqs=" }, "postcss": { - "version": "7.0.23", - "resolved": "https://registry.npmjs.org/postcss/-/postcss-7.0.23.tgz", - "integrity": "sha512-hOlMf3ouRIFXD+j2VJecwssTwbvsPGJVMzupptg+85WA+i7MwyrydmQAgY3R+m0Bc0exunhbJmijy8u8+vufuQ==", + "version": "7.0.24", + "resolved": "https://registry.npmjs.org/postcss/-/postcss-7.0.24.tgz", + "integrity": "sha512-Xl0XvdNWg+CblAXzNvbSOUvgJXwSjmbAKORqyw9V2AlHrm1js2gFw9y3jibBAhpKZi8b5JzJCVh/FyzPsTtgTA==", "requires": { "chalk": "^2.4.2", "source-map": "^0.6.1", @@ -9158,9 +9158,9 @@ } }, "vuepress-theme-cosmos": { - "version": "1.0.85", - "resolved": "https://registry.npmjs.org/vuepress-theme-cosmos/-/vuepress-theme-cosmos-1.0.85.tgz", - "integrity": "sha512-3K3nF/I95Kdb2WH5KVh4UOy7blF4p+R9tfS8+tPEDXRn3taJP0jDyoKCBQwWFaSAlRTGywwDzZwO5jiw0cmErg==", + "version": "1.0.86", + "resolved": "https://registry.npmjs.org/vuepress-theme-cosmos/-/vuepress-theme-cosmos-1.0.86.tgz", + "integrity": "sha512-MngxNJiH6F6pNdmeTAhoOMbTo74O3vLTNO856krxwPp/8jSaEssUsMGmygTq54ik0y+xpexs5sf1C+Vt/qH09A==", "requires": { "@cosmos-ui/vue": "^0.5.16", "@vuepress/plugin-last-updated": "^1.2.0", diff --git a/docs/package.json b/docs/package.json index cb8e19a7336f..eb2e558b9085 100644 --- a/docs/package.json +++ b/docs/package.json @@ -5,7 +5,7 @@ "main": "index.js", "scripts": { "preserve": "./pre.sh", - "serve": "trap 'exit 0' SIGINT; vuepress dev", + "serve": "trap 'exit 0' SIGINT; vuepress dev --no-cache", "postserve": "./post.sh", "prebuild": "./pre.sh", "build": "trap 'exit 0' SIGINT; vuepress build --no-cache", @@ -14,6 +14,6 @@ "author": "", "license": "ISC", "dependencies": { - "vuepress-theme-cosmos": "^1.0.85" + "vuepress-theme-cosmos": "^1.0.86" } } From 786e71960b112e7d736d738b3fd1e9388a1c7194 Mon Sep 17 00:00:00 2001 From: Denis Fadeev Date: Mon, 9 Dec 2019 13:35:40 +0500 Subject: [PATCH 187/196] version --- docs/.vuepress/config.js | 14 ++++++++++++++ docs/package-lock.json | 22 +++++++++++----------- docs/package.json | 4 ++-- 3 files changed, 27 insertions(+), 13 deletions(-) diff --git a/docs/.vuepress/config.js b/docs/.vuepress/config.js index 5516c86f0b08..19d953c1720c 100644 --- a/docs/.vuepress/config.js +++ b/docs/.vuepress/config.js @@ -6,6 +6,20 @@ module.exports = { permalinkSymbol: "" } }, + locales: { + '/': { + lang: 'en-US' + }, + 'kr': { + lang: "kr" + }, + 'cn': { + lang: 'cn' + }, + 'ru': { + lang: 'ru' + } + }, base: process.env.VUEPRESS_BASE || "/", themeConfig: { repo: "cosmos/cosmos-sdk", diff --git a/docs/package-lock.json b/docs/package-lock.json index 1a356c9a0d39..e60e0019040d 100644 --- a/docs/package-lock.json +++ b/docs/package-lock.json @@ -2649,9 +2649,9 @@ } }, "core-js": { - "version": "2.6.10", - "resolved": "https://registry.npmjs.org/core-js/-/core-js-2.6.10.tgz", - "integrity": "sha512-I39t74+4t+zau64EN1fE5v2W31Adtc/REhzWN+gWRRXg6WH5qAsZm62DHpQ1+Yhe4047T55jvzz7MUqF/dBBlA==" + "version": "2.6.11", + "resolved": "https://registry.npmjs.org/core-js/-/core-js-2.6.11.tgz", + "integrity": "sha512-5wjnpaT/3dV+XB4borEsnAYQchn00XSgTAWKDkEqv+K8KevjbzmofK6hfJ9TZIlpj2N0xQpazy7PiRQiWHqzWg==" }, "core-util-is": { "version": "1.0.2", @@ -4361,10 +4361,10 @@ "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.1.tgz", "integrity": "sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A==" }, - "fuzzyjs": { - "version": "4.0.3", - "resolved": "https://registry.npmjs.org/fuzzyjs/-/fuzzyjs-4.0.3.tgz", - "integrity": "sha512-/QEZMkAcC96UxBDE6Bal4Fdb4EbxjhXLZB+jvbwiNeLWMjN1eoqsKv/25iMJddAfL5LUpTBSg4Vp2rci6VLS/A==" + "fuse.js": { + "version": "3.4.6", + "resolved": "https://registry.npmjs.org/fuse.js/-/fuse.js-3.4.6.tgz", + "integrity": "sha512-H6aJY4UpLFwxj1+5nAvufom5b2BT2v45P1MkPvdGIK8fWjQx/7o6tTT1+ALV0yawQvbmvCF0ufl2et8eJ7v7Cg==" }, "get-caller-file": { "version": "1.0.3", @@ -9158,9 +9158,9 @@ } }, "vuepress-theme-cosmos": { - "version": "1.0.86", - "resolved": "https://registry.npmjs.org/vuepress-theme-cosmos/-/vuepress-theme-cosmos-1.0.86.tgz", - "integrity": "sha512-MngxNJiH6F6pNdmeTAhoOMbTo74O3vLTNO856krxwPp/8jSaEssUsMGmygTq54ik0y+xpexs5sf1C+Vt/qH09A==", + "version": "1.0.89", + "resolved": "https://registry.npmjs.org/vuepress-theme-cosmos/-/vuepress-theme-cosmos-1.0.89.tgz", + "integrity": "sha512-hwYhZ8XuHWqGi6AsKdRu8H7b8QU98SDr+2a/gFQ8oIMxFRgUNS1vm9HTczSYwEO/ehsgqnxoniEF5GNI/2GlGw==", "requires": { "@cosmos-ui/vue": "^0.5.16", "@vuepress/plugin-last-updated": "^1.2.0", @@ -9169,7 +9169,7 @@ "axios": "^0.19.0", "clipboard-copy": "^3.1.0", "docsearch.js": "^2.6.3", - "fuzzyjs": "^4.0.3", + "fuse.js": "^3.4.6", "hotkeys-js": "^3.7.3", "intersection-observer": "^0.7.0", "lunr": "^2.3.8", diff --git a/docs/package.json b/docs/package.json index eb2e558b9085..1e6910e5202b 100644 --- a/docs/package.json +++ b/docs/package.json @@ -5,7 +5,7 @@ "main": "index.js", "scripts": { "preserve": "./pre.sh", - "serve": "trap 'exit 0' SIGINT; vuepress dev --no-cache", + "serve": "trap 'exit 0' SIGINT; vuepress dev", "postserve": "./post.sh", "prebuild": "./pre.sh", "build": "trap 'exit 0' SIGINT; vuepress build --no-cache", @@ -14,6 +14,6 @@ "author": "", "license": "ISC", "dependencies": { - "vuepress-theme-cosmos": "^1.0.86" + "vuepress-theme-cosmos": "^1.0.89" } } From c1c13a3b90be815a8d412edbe235107fc472ccb3 Mon Sep 17 00:00:00 2001 From: Denis Fadeev Date: Mon, 9 Dec 2019 13:56:27 +0500 Subject: [PATCH 188/196] version --- docs/package-lock.json | 6 +++--- docs/package.json | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/docs/package-lock.json b/docs/package-lock.json index e60e0019040d..0cb039ee1ec4 100644 --- a/docs/package-lock.json +++ b/docs/package-lock.json @@ -9158,9 +9158,9 @@ } }, "vuepress-theme-cosmos": { - "version": "1.0.89", - "resolved": "https://registry.npmjs.org/vuepress-theme-cosmos/-/vuepress-theme-cosmos-1.0.89.tgz", - "integrity": "sha512-hwYhZ8XuHWqGi6AsKdRu8H7b8QU98SDr+2a/gFQ8oIMxFRgUNS1vm9HTczSYwEO/ehsgqnxoniEF5GNI/2GlGw==", + "version": "1.0.90", + "resolved": "https://registry.npmjs.org/vuepress-theme-cosmos/-/vuepress-theme-cosmos-1.0.90.tgz", + "integrity": "sha512-oKbOFUwW4UH/TiIW0SCYREkL33VI4BaaxQwfAotSyBhnFlL9WT87w072F3OST07Lki0Gr6KYBrVDx9gE5eYBYQ==", "requires": { "@cosmos-ui/vue": "^0.5.16", "@vuepress/plugin-last-updated": "^1.2.0", diff --git a/docs/package.json b/docs/package.json index 1e6910e5202b..6183f9aa1b16 100644 --- a/docs/package.json +++ b/docs/package.json @@ -14,6 +14,6 @@ "author": "", "license": "ISC", "dependencies": { - "vuepress-theme-cosmos": "^1.0.89" + "vuepress-theme-cosmos": "^1.0.90" } } From efe58c98bbc5124abb5de45c537f1512baab3785 Mon Sep 17 00:00:00 2001 From: Denis Fadeev Date: Mon, 9 Dec 2019 19:05:42 +0500 Subject: [PATCH 189/196] version --- docs/package-lock.json | 18 +++++++++--------- docs/package.json | 2 +- 2 files changed, 10 insertions(+), 10 deletions(-) diff --git a/docs/package-lock.json b/docs/package-lock.json index 0cb039ee1ec4..4a5f489b3e1d 100644 --- a/docs/package-lock.json +++ b/docs/package-lock.json @@ -877,9 +877,9 @@ "integrity": "sha512-tHq6qdbT9U1IRSGf14CL0pUlULksvY9OZ+5eEgl1N7t+OA3tGvNpxJCzuKQlsNgCVwbAs670L1vcVQi8j9HjnA==" }, "@types/node": { - "version": "12.12.14", - "resolved": "https://registry.npmjs.org/@types/node/-/node-12.12.14.tgz", - "integrity": "sha512-u/SJDyXwuihpwjXy7hOOghagLEV1KdAST6syfnOk6QZAMzZuWZqXy5aYYZbh8Jdpd4escVFP0MvftHNDb9pruA==" + "version": "12.12.15", + "resolved": "https://registry.npmjs.org/@types/node/-/node-12.12.15.tgz", + "integrity": "sha512-Pv+vWicyFd07Hw/SmNnTUguqrHgDfMtjabvD9sQyxeqbpCEg8CmViLBaVPHtNsoBgZECrRf5/pgV6FJIBrGSjw==" }, "@types/q": { "version": "1.5.2", @@ -7737,9 +7737,9 @@ } }, "serialize-javascript": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/serialize-javascript/-/serialize-javascript-2.1.1.tgz", - "integrity": "sha512-MPLPRpD4FNqWq9tTIjYG5LesFouDhdyH0EPY3gVK4DRD5+g4aDqdNSzLIwceulo3Yj+PL1bPh6laE5+H6LTcrQ==" + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/serialize-javascript/-/serialize-javascript-2.1.2.tgz", + "integrity": "sha512-rs9OggEUF0V4jUSecXazOYsLfu7OGK2qIn3c7IPBiffz32XniEp/TX9Xmc9LQfK2nQ2QKHvZ2oygKUGU0lG4jQ==" }, "serve-index": { "version": "1.9.1", @@ -9158,9 +9158,9 @@ } }, "vuepress-theme-cosmos": { - "version": "1.0.90", - "resolved": "https://registry.npmjs.org/vuepress-theme-cosmos/-/vuepress-theme-cosmos-1.0.90.tgz", - "integrity": "sha512-oKbOFUwW4UH/TiIW0SCYREkL33VI4BaaxQwfAotSyBhnFlL9WT87w072F3OST07Lki0Gr6KYBrVDx9gE5eYBYQ==", + "version": "1.0.93", + "resolved": "https://registry.npmjs.org/vuepress-theme-cosmos/-/vuepress-theme-cosmos-1.0.93.tgz", + "integrity": "sha512-P8I8RSydfW/cetx0ruYegeDPuX3PkD/M9I8F7LX54rnA9wPrTM4fLo3fl2MYJmY9jh9uStVLGx95IlHqxtwsOA==", "requires": { "@cosmos-ui/vue": "^0.5.16", "@vuepress/plugin-last-updated": "^1.2.0", diff --git a/docs/package.json b/docs/package.json index 6183f9aa1b16..a8d32367076f 100644 --- a/docs/package.json +++ b/docs/package.json @@ -14,6 +14,6 @@ "author": "", "license": "ISC", "dependencies": { - "vuepress-theme-cosmos": "^1.0.90" + "vuepress-theme-cosmos": "^1.0.93" } } From e3d62d825b3d3e9cbfe545b8ff62fe07ec7033ba Mon Sep 17 00:00:00 2001 From: gamarin Date: Mon, 9 Dec 2019 16:29:31 +0100 Subject: [PATCH 190/196] slight notice --- x/README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/x/README.md b/x/README.md index bdb5ae2f4fc0..5093fe86fe7c 100644 --- a/x/README.md +++ b/x/README.md @@ -1,6 +1,6 @@ # List of Modules -This repository contains a working implementation of modules that can be used in Cosmos SDK applications, along with their respective documentation. +Here are some production-grade modules that can be used in Cosmos SDK applications, along with their respective documentation: - [Auth](./x/auth/spec/README.md) - Authentication of accounts and transactions for Cosmos SDK application. - [Bank](./x/bank/spec/README.md) - Token transfer functionalities. From 55dcc498f8509a71cbfc49b9136ebc0ddd3eff43 Mon Sep 17 00:00:00 2001 From: gamarin Date: Mon, 9 Dec 2019 18:10:43 +0100 Subject: [PATCH 191/196] fix links and hide --- docs/README.md | 2 +- docs/basics/accounts.md | 2 +- docs/basics/app-anatomy.md | 4 ++-- docs/basics/gas-fees.md | 2 +- docs/basics/tx-lifecycle.md | 2 +- docs/building-modules/beginblock-endblock.md | 2 +- docs/building-modules/genesis.md | 2 +- docs/building-modules/handler.md | 2 +- docs/building-modules/intro.md | 2 +- docs/building-modules/invariants.md | 2 +- docs/building-modules/keeper.md | 2 +- docs/building-modules/messages-and-queries.md | 2 +- docs/building-modules/module-interfaces.md | 2 +- docs/building-modules/module-manager.md | 2 +- docs/building-modules/querier.md | 2 +- docs/building-modules/structure.md | 2 +- docs/core/baseapp.md | 2 +- docs/core/context.md | 2 +- docs/core/encoding.md | 2 +- docs/core/events.md | 2 +- docs/core/node.md | 2 +- docs/core/ocap.md | 2 +- docs/core/store.md | 2 +- docs/core/transactions.md | 2 +- docs/interfaces/interfaces-intro.md | 2 +- docs/interfaces/query-lifecycle.md | 2 +- docs/intro/overview.md | 2 +- docs/intro/sdk-app-architecture.md | 2 +- docs/intro/sdk-design.md | 2 ++ docs/intro/why-app-specific.md | 2 +- docs/spec/README.md | 2 +- docs/using-the-sdk/README.md | 2 +- 32 files changed, 34 insertions(+), 32 deletions(-) diff --git a/docs/README.md b/docs/README.md index c2f667bd938d..281c7d54cc14 100644 --- a/docs/README.md +++ b/docs/README.md @@ -59,7 +59,7 @@ stack: ## Get Started -- **[SDK Intro](./intro/intro.md)**: High-level overview of the Cosmos SDK. +- **[SDK Intro](./intro/overview.md)**: High-level overview of the Cosmos SDK. - **[SDK Application Tutorial](https://github.com/cosmos/sdk-application-tutorial)**: A tutorial that showcases how to build an SDK-based blockchain from scratch and explains the basic principles of the SDK in the process. ## Reference diff --git a/docs/basics/accounts.md b/docs/basics/accounts.md index 7ad873680d4d..8cb4b4990f2f 100644 --- a/docs/basics/accounts.md +++ b/docs/basics/accounts.md @@ -131,4 +131,4 @@ Of note, the `Marhsal()` and `Bytes()` method both return the same raw `[]byte` ## Next {hide} -Learn about [gas and fees](./gas-fees.md). \ No newline at end of file +Learn about [gas and fees](./gas-fees.md) {hide} \ No newline at end of file diff --git a/docs/basics/app-anatomy.md b/docs/basics/app-anatomy.md index 496273f47993..5437956e5092 100644 --- a/docs/basics/app-anatomy.md +++ b/docs/basics/app-anatomy.md @@ -33,7 +33,7 @@ Blockchain Node | | Consensus | | v +-------------------------------+ v ``` -The blockchain full-node presents itself as a binary, generally suffixed by `-d` for "daemon" (e.g. `appd` for `app` or `gaiad` for `gaia`). This binary is built by running a simple [`main.go`]((../core/node.md#main-function)) function placed in `./cmd/appd/`. This operation usually happens through the [Makefile](#dependencies-and-makefile). +The blockchain full-node presents itself as a binary, generally suffixed by `-d` for "daemon" (e.g. `appd` for `app` or `gaiad` for `gaia`). This binary is built by running a simple [`main.go`](../core/node.md#main-function) function placed in `./cmd/appd/`. This operation usually happens through the [Makefile](#dependencies-and-makefile). Once the main binary is built, the node can be started by running the [`start` command](../core/node.md#start-command). This command function primarily does three things: @@ -253,4 +253,4 @@ For building the application, a [Makefile](https://en.wikipedia.org/wiki/Makefil ## Next {hide} -Learn more about the [Lifecycle of a transaction](./tx-lifecycle.md). +Learn more about the [Lifecycle of a transaction](./tx-lifecycle.md) {hide} diff --git a/docs/basics/gas-fees.md b/docs/basics/gas-fees.md index 6c14ef733e88..a904f4e73ce6 100644 --- a/docs/basics/gas-fees.md +++ b/docs/basics/gas-fees.md @@ -85,4 +85,4 @@ As explained above, the `anteHandler` returns a maximum limit of `gas` the trans ## Next {hide} -Learn about [baseapp](../core/baseapp.md). \ No newline at end of file +Learn about [baseapp](../core/baseapp.md) {hide} \ No newline at end of file diff --git a/docs/basics/tx-lifecycle.md b/docs/basics/tx-lifecycle.md index b130a4e97ab9..b8a938706714 100644 --- a/docs/basics/tx-lifecycle.md +++ b/docs/basics/tx-lifecycle.md @@ -242,4 +242,4 @@ in `[]byte` form, is stored in a block and appended to the blockchain. ## Next {hide} -Learn about [accounts](./accounts.md). +Learn about [accounts](./accounts.md) {hide} diff --git a/docs/building-modules/beginblock-endblock.md b/docs/building-modules/beginblock-endblock.md index 6f84da93088e..79dd9c53163f 100644 --- a/docs/building-modules/beginblock-endblock.md +++ b/docs/building-modules/beginblock-endblock.md @@ -35,4 +35,4 @@ and an example implementation of `EndBlocker` from the `staking` module: ## Next {hide} -Learn about [`keeper`s](./keeper.md). +Learn about [`keeper`s](./keeper.md) {hide} diff --git a/docs/building-modules/genesis.md b/docs/building-modules/genesis.md index 09bd4c8795a6..0d4ddec93e77 100644 --- a/docs/building-modules/genesis.md +++ b/docs/building-modules/genesis.md @@ -56,4 +56,4 @@ See an example of `ExportGenesis` from the nameservice tutorial. ## Next {hide} -Learn about [modules interfaces](#module-interfaces.md). \ No newline at end of file +Learn about [modules interfaces](#module-interfaces.md) {hide} \ No newline at end of file diff --git a/docs/building-modules/handler.md b/docs/building-modules/handler.md index b714b4db0ea8..6f0292347eb4 100644 --- a/docs/building-modules/handler.md +++ b/docs/building-modules/handler.md @@ -73,4 +73,4 @@ For a deeper look at `handler`s, see this [example implementation of a `handler` ## Next {hide} -Learn about [queriers](./querier.md). +Learn about [queriers](./querier.md) {hide} diff --git a/docs/building-modules/intro.md b/docs/building-modules/intro.md index 06c985a1177b..8ad43da48ece 100644 --- a/docs/building-modules/intro.md +++ b/docs/building-modules/intro.md @@ -89,5 +89,5 @@ Please refer to the [structure document](./structure.md) to learn about the reco ## Next {hide} -Read more on the [`AppModule` interface and the `module manager`](./module-manager.md) +Read more on the [`AppModule` interface and the `module manager`](./module-manager.md) {hide} diff --git a/docs/building-modules/invariants.md b/docs/building-modules/invariants.md index 54e53cdaf894..638e120d5869 100644 --- a/docs/building-modules/invariants.md +++ b/docs/building-modules/invariants.md @@ -85,4 +85,4 @@ In both cases, if one of the `Invariant`s returns false, the `InvariantRegistry` ## Next {hide} -Learn about [genesis functionalities](./genesis.md). +Learn about [genesis functionalities](./genesis.md) {hide} diff --git a/docs/building-modules/keeper.md b/docs/building-modules/keeper.md index 8fb4cd27be2e..cc87914b3c19 100644 --- a/docs/building-modules/keeper.md +++ b/docs/building-modules/keeper.md @@ -75,4 +75,4 @@ For more, see an example of `keeper`'s [methods implementation from the nameserv ## Next {hide} -Learn about [invariants](./invariants.md). +Learn about [invariants](./invariants.md) {hide} diff --git a/docs/building-modules/messages-and-queries.md b/docs/building-modules/messages-and-queries.md index 38daa55bfc1a..c6ca4145874f 100644 --- a/docs/building-modules/messages-and-queries.md +++ b/docs/building-modules/messages-and-queries.md @@ -72,4 +72,4 @@ See an example of `query` return types from the `nameservice` module: ## Next {hide} -Learn about [`handler`s](./handler.md). \ No newline at end of file +Learn about [`handler`s](./handler.md) {hide} \ No newline at end of file diff --git a/docs/building-modules/module-interfaces.md b/docs/building-modules/module-interfaces.md index ddc565ccf580..343baba2df19 100644 --- a/docs/building-modules/module-interfaces.md +++ b/docs/building-modules/module-interfaces.md @@ -164,4 +164,4 @@ A few things to note: ## Next {hide} -Read about the recommended [module structure](./structure.md). +Read about the recommended [module structure](./structure.md) {hide} diff --git a/docs/building-modules/module-manager.md b/docs/building-modules/module-manager.md index daac6a55aeeb..f081c12d4de5 100644 --- a/docs/building-modules/module-manager.md +++ b/docs/building-modules/module-manager.md @@ -141,4 +141,4 @@ The module manager is used throughout the application whenever an action on a co ## Next {hide} -Learn more about [`message`s and `queries`](./messages-and-queries.md). +Learn more about [`message`s and `queries`](./messages-and-queries.md) {hide} diff --git a/docs/building-modules/querier.md b/docs/building-modules/querier.md index 7704fcee2522..817ac5025a52 100644 --- a/docs/building-modules/querier.md +++ b/docs/building-modules/querier.md @@ -50,4 +50,4 @@ For a deeper look at `querier`s, see this [example implementation of a `querier` ## Next {hide} -Learn about [`BeginBlocker` and `EndBlocker`](./beginblock-endblock.md). +Learn about [`BeginBlocker` and `EndBlocker`](./beginblock-endblock.md) {hide} diff --git a/docs/building-modules/structure.md b/docs/building-modules/structure.md index 2064d0e35217..2d09aa0a18bb 100644 --- a/docs/building-modules/structure.md +++ b/docs/building-modules/structure.md @@ -85,4 +85,4 @@ interfaces. ## Next {hide} -Learn about [interfaces](../interfaces/interfaces-intro.md). \ No newline at end of file +Learn about [interfaces](../interfaces/interfaces-intro.md) {hide} \ No newline at end of file diff --git a/docs/core/baseapp.md b/docs/core/baseapp.md index ffb1bb4a93f5..e3e592159cc7 100644 --- a/docs/core/baseapp.md +++ b/docs/core/baseapp.md @@ -391,4 +391,4 @@ Each `query` comes with a `path`, which contains multiple `string`s. By conventi ## Next {hide} -Learn more about [transactions](./transactions.md). \ No newline at end of file +Learn more about [transactions](./transactions.md) {hide} \ No newline at end of file diff --git a/docs/core/context.md b/docs/core/context.md index 1c265b8e8caf..e501834a911f 100644 --- a/docs/core/context.md +++ b/docs/core/context.md @@ -114,4 +114,4 @@ a successful run over all the messages, the cached multistore is written back to ## Next {hide} -Learn about the [node client](./node.md) +Learn about the [node client](./node.md) {hide} diff --git a/docs/core/encoding.md b/docs/core/encoding.md index 6e924e379b6e..601b7aef6954 100644 --- a/docs/core/encoding.md +++ b/docs/core/encoding.md @@ -43,4 +43,4 @@ A standard implementation of both these objects can be found in the [`auth` modu ## Next {hide} -Learn about [events](./events.md). \ No newline at end of file +Learn about [events](./events.md) {hide} \ No newline at end of file diff --git a/docs/core/events.md b/docs/core/events.md index ed33a1de4bac..5c5398b0b563 100644 --- a/docs/core/events.md +++ b/docs/core/events.md @@ -88,4 +88,4 @@ where `senderAddress` is an address following the [`AccAddress`](../basics/accou ## Next {hide} -Learn about [object-capabilities](./ocap.md) \ No newline at end of file +Learn about [object-capabilities](./ocap.md) {hide} \ No newline at end of file diff --git a/docs/core/node.md b/docs/core/node.md index 788c9f424658..0cbc2caa2a1e 100644 --- a/docs/core/node.md +++ b/docs/core/node.md @@ -67,4 +67,4 @@ Upon starting, the node will bootstrap its RPC and P2P server and start dialing ## Next {hide} -Learn about the [store](./store.md). \ No newline at end of file +Learn about the [store](./store.md) {hide} \ No newline at end of file diff --git a/docs/core/ocap.md b/docs/core/ocap.md index 3314d9ca2dcb..f0bb294305a8 100644 --- a/docs/core/ocap.md +++ b/docs/core/ocap.md @@ -86,4 +86,4 @@ gaia app. ## Next -Learn about [building modules](../building-modules/intro.md). \ No newline at end of file +Learn about [building modules](../building-modules/intro.md) {hide} \ No newline at end of file diff --git a/docs/core/store.md b/docs/core/store.md index f46569e9222b..eaa139ba41be 100644 --- a/docs/core/store.md +++ b/docs/core/store.md @@ -236,4 +236,4 @@ When `Store.Iterator()` is called, it does not simply prefix the `Store.prefix`, ## Next {hide} -Learn about [encoding](./encoding.md). \ No newline at end of file +Learn about [encoding](./encoding.md) {hide} \ No newline at end of file diff --git a/docs/core/transactions.md b/docs/core/transactions.md index 19b6bd8a784e..4b322f8c30ef 100644 --- a/docs/core/transactions.md +++ b/docs/core/transactions.md @@ -88,4 +88,4 @@ Since `message`s are module-specific types, each module needs a [`handler`](../b ## Next {hide} -Learn about the [context](./context.md). \ No newline at end of file +Learn about the [context](./context.md) {hide} \ No newline at end of file diff --git a/docs/interfaces/interfaces-intro.md b/docs/interfaces/interfaces-intro.md index 784a3b119f6e..eb807d0025e8 100644 --- a/docs/interfaces/interfaces-intro.md +++ b/docs/interfaces/interfaces-intro.md @@ -40,4 +40,4 @@ With regards to interfaces, application developers need to include: ## Next {hide} -Read about the [Lifecycle of a Query](./query-lifecycle.md). +Read about the [Lifecycle of a Query](./query-lifecycle.md) {hide} diff --git a/docs/interfaces/query-lifecycle.md b/docs/interfaces/query-lifecycle.md index d9fccbd82e2c..78b05da70ba1 100644 --- a/docs/interfaces/query-lifecycle.md +++ b/docs/interfaces/query-lifecycle.md @@ -158,4 +158,4 @@ The [REST server](./rest.md#rest-server) uses the `CLIContext` to format the res ## Next {hide} -Read about how to build a [Command-Line Interface](./cli.md), or a [REST Interface](./rest.md). +Read about how to build a [Command-Line Interface](./cli.md), or a [REST Interface](./rest.md) {hide} diff --git a/docs/intro/overview.md b/docs/intro/overview.md index 3ada29edadbc..e568eff6748e 100644 --- a/docs/intro/overview.md +++ b/docs/intro/overview.md @@ -34,4 +34,4 @@ The Cosmos SDK is the most advanced framework for building custom application-sp ## Next {hide} -Learn about [application-specific blockchains](./why-app-specific.md). \ No newline at end of file +Learn about [application-specific blockchains](./why-app-specific.md) {hide} \ No newline at end of file diff --git a/docs/intro/sdk-app-architecture.md b/docs/intro/sdk-app-architecture.md index d0c6b0805559..5667e5c5d55c 100644 --- a/docs/intro/sdk-app-architecture.md +++ b/docs/intro/sdk-app-architecture.md @@ -97,4 +97,4 @@ Any application built on Tendermint needs to implement the ABCI interface in ord ## Next {hide} -Read about the [high-level design principles of the SDK](./sdk-design.md) \ No newline at end of file +Read about the [high-level design principles of the SDK](./sdk-design.md) {hide} \ No newline at end of file diff --git a/docs/intro/sdk-design.md b/docs/intro/sdk-design.md index 02abe6c5bb07..0b4f9689f6ed 100644 --- a/docs/intro/sdk-design.md +++ b/docs/intro/sdk-design.md @@ -90,5 +90,7 @@ SDK modules are defined in the `x/` folder of the SDK. Some core modules include In addition to the already existing modules in `x/`, that anyone can use in their app, the SDK lets you build your own custom modules. You can check an [example of that in the tutorial](https://cosmos.network/docs/tutorial/keeper.html). +## Next {hide} +Learn more about the [anatomy of an SDK application](../basics/app-anatomy.md) {hide} diff --git a/docs/intro/why-app-specific.md b/docs/intro/why-app-specific.md index 1497e0f03ca1..cd37b562126c 100644 --- a/docs/intro/why-app-specific.md +++ b/docs/intro/why-app-specific.md @@ -77,4 +77,4 @@ The fundamental issue here is that the governance of the application and the gov ## Next {hide} -- Learn more about the [high-level architecture](./sdk-app-architecture.md) of an SDK application. +Learn more about the [high-level architecture](./sdk-app-architecture.md) of an SDK application {hide} diff --git a/docs/spec/README.md b/docs/spec/README.md index 2ee241f55f44..2dd2321be23c 100644 --- a/docs/spec/README.md +++ b/docs/spec/README.md @@ -18,7 +18,7 @@ block. ## Modules specifications -Go the [module directory](../x/README.md) +Go the [module directory](../../x/README.md) ## Tendermint diff --git a/docs/using-the-sdk/README.md b/docs/using-the-sdk/README.md index a3b9882a5737..ef0f84c16fb2 100644 --- a/docs/using-the-sdk/README.md +++ b/docs/using-the-sdk/README.md @@ -5,6 +5,6 @@ parent: # Using the SDK -- [Modules](../x/README.md) +- [Modules](../../x/README.md) - [Simulation](./simulation.md) From 565101d050c348219d20ed61910c51176185fa52 Mon Sep 17 00:00:00 2001 From: gamarin Date: Mon, 9 Dec 2019 19:52:24 +0100 Subject: [PATCH 192/196] permalinks --- docs/basics/accounts.md | 16 +++---- docs/basics/app-anatomy.md | 10 ++--- docs/basics/gas-fees.md | 6 +-- docs/building-modules/beginblock-endblock.md | 4 +- docs/building-modules/handler.md | 8 ++-- docs/building-modules/invariants.md | 10 ++--- docs/building-modules/messages-and-queries.md | 2 +- docs/building-modules/module-interfaces.md | 2 +- docs/building-modules/module-manager.md | 14 +++--- docs/building-modules/querier.md | 2 +- docs/core/baseapp.md | 20 ++++----- docs/core/encoding.md | 6 +-- docs/core/events.md | 6 +-- docs/core/node.md | 8 ++-- docs/core/store.md | 44 +++++++++---------- docs/core/transactions.md | 6 +-- docs/interfaces/query-lifecycle.md | 14 +++--- 17 files changed, 85 insertions(+), 93 deletions(-) diff --git a/docs/basics/accounts.md b/docs/basics/accounts.md index 8cb4b4990f2f..ae69c081f549 100644 --- a/docs/basics/accounts.md +++ b/docs/basics/accounts.md @@ -61,23 +61,23 @@ In the Cosmos SDK, accounts are stored and managed via an object called a [`Keyb A `Keybase` is an object that stores and manages accounts. In the Cosmos SDK, a `Keybase` implementation follows the `Keybase` interface: -+++ https://github.com/cosmos/cosmos-sdk/blob/master/crypto/keys/types.go#L14-L60 ++++ https://github.com/cosmos/cosmos-sdk/blob/7d7821b9af132b0f6131640195326aa02b6751db/crypto/keys/types.go#L13-L86 The default implementation of `Keybase` of the Cosmos SDK is `dbKeybase`. -+++ https://github.com/cosmos/cosmos-sdk/blob/master/crypto/keys/keybase.go ++++ https://github.com/cosmos/cosmos-sdk/blob/7d7821b9af132b0f6131640195326aa02b6751db/crypto/keys/keybase.go A few notes on the `Keybase` methods as implemented in `dbKeybase`: - `Sign(name, passphrase string, msg []byte) ([]byte, crypto.PubKey, error)` strictly deals with the signature of the `message` bytes. Some preliminary work should be done beforehand to prepare and encode the `message` into a canonical `[]byte` form. See an example of `message` preparation from the `auth` module. Note that signature verification is not implemented in the SDK by default. It is deferred to the [`anteHandler`](#antehandler). - +++ https://github.com/cosmos/cosmos-sdk/blob/master/x/auth/types/txbuilder.go#L177-L207 + +++ https://github.com/cosmos/cosmos-sdk/blob/7d7821b9af132b0f6131640195326aa02b6751db/x/auth/types/txbuilder.go#L176-L209 - `CreateMnemonic(name string, language Language, passwd string, algo SigningAlgo) (info Info, seed string, err error)` creates a new mnemonic and prints it in the logs, but it **does not persist it on disk**. -- `CreateAccount(name, mnemonic, bip39Passwd, encryptPasswd string, account uint32, index uint32) (Info, error)` creates a new account based on the [`bip44 path`](https://github.com/bitcoin/bips/blob/master/bip-0044.mediawiki) and persists it on disk (note that the `PrivKey` is [encrypted with a passphrase before being persisted](https://github.com/cosmos/cosmos-sdk/blob/master/crypto/keys/mintkey/mintkey.go), it is **never stored unencrypted**). In the context of this method, the `account` and `address` parameters refer to the segment of the BIP44 derivation path (e.g. `0`, `1`, `2`, ...) used to derive the `PrivKey` and `PubKey` from the mnemonic (note that given the same mnemonic and `account`, the same `PrivKey` will be generated, and given the same `account` and `address`, the same `PubKey` and `Address` will be generated). Finally, note that the `CreateAccount` method derives keys and addresses using `secp256k1` as implemented in the [Tendermint library](https://github.com/tendermint/tendermint/tree/bc572217c07b90ad9cee851f193aaa8e9557cbc7/crypto/secp256k1). As a result, it only works for creating account keys and addresses, not consensus keys. See [`Addresses`](#addresses) for more. +- `CreateAccount(name, mnemonic, bip39Passwd, encryptPasswd string, account uint32, index uint32) (Info, error)` creates a new account based on the [`bip44 path`](https://github.com/bitcoin/bips/blob/master/bip-0044.mediawiki) and persists it on disk (note that the `PrivKey` is [encrypted with a passphrase before being persisted](https://github.com/cosmos/cosmos-sdk/blob/7d7821b9af132b0f6131640195326aa02b6751db/crypto/keys/mintkey/mintkey.go), it is **never stored unencrypted**). In the context of this method, the `account` and `address` parameters refer to the segment of the BIP44 derivation path (e.g. `0`, `1`, `2`, ...) used to derive the `PrivKey` and `PubKey` from the mnemonic (note that given the same mnemonic and `account`, the same `PrivKey` will be generated, and given the same `account` and `address`, the same `PubKey` and `Address` will be generated). Finally, note that the `CreateAccount` method derives keys and addresses using `secp256k1` as implemented in the [Tendermint library](https://github.com/tendermint/tendermint/tree/bc572217c07b90ad9cee851f193aaa8e9557cbc7/crypto/secp256k1). As a result, it only works for creating account keys and addresses, not consensus keys. See [`Addresses`](#addresses) for more. The current implementation of `dbKeybase` is basic and does not offer on-demand locking. If an instance of `dbKeybase` is created, the underlying `db` is locked meaning no other process can access it besides the one in which it was instantiated. This is the reason why the default SDK client uses another implementation of the `Keybase` interface called `lazyKeybase`: -+++ https://github.com/cosmos/cosmos-sdk/blob/master/crypto/keys/lazy_keybase.go ++++ https://github.com/cosmos/cosmos-sdk/blob/7d7821b9af132b0f6131640195326aa02b6751db/crypto/keys/lazy_keybase.go `lazyKeybase` is simple wrapper around `dbKeybase` which locks the database only when operations are to be performed and unlocks it immediately after. With the `lazyKeybase`, it is possible for the [command-line interface](../interfaces/cli.md) to create a new account while the [rest server](../interfaces/rest.md) is running. It is also possible to pipe multiple CLI commands. @@ -105,7 +105,7 @@ For `secp256k1` keys, the actual implementation can be found [here](https://gith Note that in the Cosmos SDK, `Pubkeys` are not manipulated in their raw form. Instead, they are double encoded using [`Amino`](../core/encoding.md#amino) and [`bech32`](https://en.bitcoin.it/wiki/Bech32). In the SDK is done by first calling the `Bytes()` method on the raw `Pubkey` (which applies amino encoding), and then the `ConvertAndEncode` method of `bech32`. -+++ https://github.com/cosmos/cosmos-sdk/blob/master/types/address.go#L579-L729 ++++ https://github.com/cosmos/cosmos-sdk/blob/7d7821b9af132b0f6131640195326aa02b6751db/types/address.go#L579-L729 ### Addresses @@ -123,11 +123,11 @@ aa := sdk.AccAddress(pub.Address().Bytes()) These addresses implement the `Address` interface: -+++ https://github.com/cosmos/cosmos-sdk/blob/master/types/address.go#L72-L80 ++++ https://github.com/cosmos/cosmos-sdk/blob/7d7821b9af132b0f6131640195326aa02b6751db/types/address.go#L71-L80 Of note, the `Marhsal()` and `Bytes()` method both return the same raw `[]byte` form of the address, the former being needed for Protobuff compatibility. Also, the `String()` method is used to return the `bech32` encoded form of the address, which should be the only address format with which end-user interract. Next is an example: -+++ https://github.com/cosmos/cosmos-sdk/blob/master/types/address.go#L230-L243 ++++ https://github.com/cosmos/cosmos-sdk/blob/7d7821b9af132b0f6131640195326aa02b6751db/types/address.go#L229-L243 ## Next {hide} diff --git a/docs/basics/app-anatomy.md b/docs/basics/app-anatomy.md index 5437956e5092..a9a4588d2820 100644 --- a/docs/basics/app-anatomy.md +++ b/docs/basics/app-anatomy.md @@ -63,7 +63,7 @@ See an example of application type definition from [`gaia`](https://github.com/c This function constructs a new application of the type defined in the section above. It must fulfill the `AppCreator` signature in order to be used in the [`start` command](../core/node.md#start-command) of the application's daemon command. -+++ https://github.com/cosmos/cosmos-sdk/blob/master/server/constructors.go#L20 ++++ https://github.com/cosmos/cosmos-sdk/blob/7d7821b9af132b0f6131640195326aa02b6751db/server/constructors.go#L20 Here are the main actions performed by this function: @@ -148,7 +148,7 @@ For a more detailed look at a transaction lifecycle, click [here](./tx-lifecycle Module developers create custom message types when they build their own module. The general practice is to prefix the type declaration of the message with `Msg`. For example, the message type `MsgSend` allows users to transfer tokens: -+++ https://github.com/cosmos/cosmos-sdk/blob/master/x/bank/internal/types/msgs.go#L11-L15 ++++ https://github.com/cosmos/cosmos-sdk/blob/7d7821b9af132b0f6131640195326aa02b6751db/x/bank/internal/types/msgs.go#L10-L15 It is processed by the `handler` of the `bank` module, which ultimately calls the `keeper` of the `auth` module in order to update the state. @@ -166,7 +166,7 @@ The `handler` of a module is generally defined in a file called `handler.go` and Handler functions return a result of type `sdk.Result`, which informs the application on whether the message was successfully processed: -+++ https://github.com/cosmos/cosmos-sdk/blob/master/types/result.go#L14-L37 ++++ https://github.com/cosmos/cosmos-sdk/blob/7d7821b9af132b0f6131640195326aa02b6751db/types/result.go#L15-L40 To learn more about handlers, [click here](../building-modules/handler.md). @@ -174,7 +174,7 @@ To learn more about handlers, [click here](../building-modules/handler.md). [`Queriers`](../building-modules/querier.md) are very similar to `handlers`, except they serve user queries to the state as opposed to processing transactions. A [query](../building-modules/messages-and-queries.md#queries) is initiated from an [interface](#interfaces) by an end-user who provides a `queryRoute` and some `data`. The query is then routed to the correct application's `querier` by `baseapp`'s `handleQueryCustom` method using `queryRoute`: -+++ https://github.com/cosmos/cosmos-sdk/blob/master/baseapp/baseapp.go#L519-L556 ++++ https://github.com/cosmos/cosmos-sdk/blob/7d7821b9af132b0f6131640195326aa02b6751db/baseapp/abci.go#L395-L453 The `Querier` of a module is defined in a file called `querier.go`, and consists of: @@ -219,7 +219,7 @@ The module's REST interface lets users generate transactions and query the state - A `RegisterRoutes` function, which registers each route defined in the file. This function is called from the [main application's interface](#application-interfaces) for each module used within the application. The router used in the SDK is [Gorilla's mux](https://github.com/gorilla/mux). - Custom request type definitions for each query or transaction creation function that needs to be exposed. These custom request types build on the base `request` type of the Cosmos SDK: - +++ https://github.com/cosmos/cosmos-sdk/blob/master/types/rest/rest.go#L32-L43 + +++ https://github.com/cosmos/cosmos-sdk/blob/7d7821b9af132b0f6131640195326aa02b6751db/types/rest/rest.go#L47-L60 - One handler function for each request that can be routed to the given module. These functions implement the core logic necessary to serve the request. To learn more about modules REST interface, [click here](../building-modules/module-interfaces.md#rest). diff --git a/docs/basics/gas-fees.md b/docs/basics/gas-fees.md index a904f4e73ce6..b54a7f19be60 100644 --- a/docs/basics/gas-fees.md +++ b/docs/basics/gas-fees.md @@ -20,7 +20,7 @@ In the Cosmos SDK, `gas` is a special unit that is used to track the consumption In the Cosmos SDK, `gas` is a simple alias for `uint64`, and is managed by an object called a *gas meter*. Gas meters implement the `GasMeter` interface -+++ https://github.com/cosmos/cosmos-sdk/blob/master/store/types/gas.go#L32-L44 ++++ https://github.com/cosmos/cosmos-sdk/blob/7d7821b9af132b0f6131640195326aa02b6751db/store/types/gas.go#L31-L39 where: @@ -73,9 +73,9 @@ type AnteHandler func(ctx Context, tx Tx, simulate bool) (newCtx Context, result The `anteHandler` is not implemented in the core SDK but in a module. This gives the possibility to developers to choose which version of `AnteHandler` fits their application's needs. That said, most applications today use the default implementation defined in the [`auth` module](https://github.com/cosmos/cosmos-sdk/tree/master/x/auth). Here is what the `anteHandler` is intended to do in a normal Cosmos SDK application: - Verify that the transaction are of the correct type. Transaction types are defined in the module that implements the `anteHandler`, and they follow the transaction interface: - +++ https://github.com/cosmos/cosmos-sdk/blob/master/types/tx_msg.go#L34-L41 + +++ https://github.com/cosmos/cosmos-sdk/blob/7d7821b9af132b0f6131640195326aa02b6751db/types/tx_msg.go#L33-L41 This enables developers to play with various types for the transaction of their application. In the default `auth` module, the standard transaction type is `StdTx`: - +++ https://github.com/cosmos/cosmos-sdk/blob/master/x/auth/types/stdtx.go#L23-L28 + +++ https://github.com/cosmos/cosmos-sdk/blob/7d7821b9af132b0f6131640195326aa02b6751db/x/auth/types/stdtx.go#L22-L29 - Verify signatures for each [`message`](../building-modules/messages-and-queries.md#messages) contained in the transaction. Each `message` should be signed by one or multiple sender(s), and these signatures must be verified in the `anteHandler`. - During `CheckTx`, verify that the gas prices provided with the transaction is greater than the local `min-gas-prices` (as a reminder, gas-prices can be deducted from the following equation: `fees = gas * gas-prices`). `min-gas-prices` is a parameter local to each full-node and used during `CheckTx` to discard transactions that do not provide a minimum amount of fees. This ensure that the mempool cannot be spammed with garbage transactions. - Verify that the sender of the transaction has enough funds to cover for the `fees`. When the end-user generates a transaction, they must indicate 2 of the 3 following parameters (the third one being implicit): `fees`, `gas` and `gas-prices`. This signals how much they are willing to pay for nodes to execute their transaction. The provided `gas` value is stored in a parameter called `GasWanted` for later use. diff --git a/docs/building-modules/beginblock-endblock.md b/docs/building-modules/beginblock-endblock.md index 79dd9c53163f..1000c7a5fd68 100644 --- a/docs/building-modules/beginblock-endblock.md +++ b/docs/building-modules/beginblock-endblock.md @@ -27,11 +27,11 @@ It is possible for developers to defined the order of execution between the `Beg See an example implementation of `BeginBlocker` from the `distr` module: -+++ https://github.com/cosmos/cosmos-sdk/blob/master/x/distribution/abci.go#L10-L32 ++++ https://github.com/cosmos/cosmos-sdk/blob/7d7821b9af132b0f6131640195326aa02b6751db/x/distribution/abci.go#L10-L32 and an example implementation of `EndBlocker` from the `staking` module: -+++ https://github.com/cosmos/cosmos-sdk/blob/master/x/staking/handler.go#L44-L96 ++++ https://github.com/cosmos/cosmos-sdk/blob/7d7821b9af132b0f6131640195326aa02b6751db/x/staking/handler.go#L44-L96 ## Next {hide} diff --git a/docs/building-modules/handler.md b/docs/building-modules/handler.md index 6f0292347eb4..1b1e8e46adcb 100644 --- a/docs/building-modules/handler.md +++ b/docs/building-modules/handler.md @@ -14,14 +14,14 @@ synopsis: A `Handler` designates a function that processes [`message`s](./messag The `handler` type defined in the Cosmos SDK specifies the typical structure of a `handler` function. -+++ https://github.com/cosmos/cosmos-sdk/blob/master/types/handler.go#L4 ++++ https://github.com/cosmos/cosmos-sdk/blob/7d7821b9af132b0f6131640195326aa02b6751db/types/handler.go#L4 Let us break it down: - The [`Msg`](./messages-and-queries.md#messages) is the actual object being processed. - The [`Context`](../core/context.md) contains all the necessary information needed to process the `msg`, as well as a cache-wrapped copy of the latest state. If the `msg` is succesfully processed, the modified version of the temporary state contained in the `ctx` will be written to the main state. - The [`Result`] returned to `baseapp`, which contains (among other things) information on the execution of the `handler`, [`gas`](../basics/gas-fees.md) consumption and [`events`](../core/events.md). - +++ https://github.com/cosmos/cosmos-sdk/blob/master/types/result.go#L14-L38 + +++ https://github.com/cosmos/cosmos-sdk/blob/7d7821b9af132b0f6131640195326aa02b6751db/types/result.go#L15-L40 ## Implementation of a module `handler`s @@ -63,11 +63,11 @@ These `events` are relayed back to the underlying consensus engine and can be us Finally, the `handler` function returns a `sdk.Result` which contains the aforementioned `events` and an optional `Data` field. -+++ https://github.com/cosmos/cosmos-sdk/blob/master/types/result.go#L15-L40 ++++ https://github.com/cosmos/cosmos-sdk/blob/7d7821b9af132b0f6131640195326aa02b6751db/types/result.go#L15-L40 Next is an example of how to return a `Result` from the `gov` module: -+++ https://github.com/cosmos/cosmos-sdk/blob/master/x/gov/handler.go#L59-L62 ++++ https://github.com/cosmos/cosmos-sdk/blob/7d7821b9af132b0f6131640195326aa02b6751db/x/gov/handler.go#L59-L62 For a deeper look at `handler`s, see this [example implementation of a `handler` function](https://github.com/cosmos/sdk-application-tutorial/blob/c6754a1e313eb1ed973c5c91dcc606f2fd288811/x/nameservice/handler.go) from the nameservice tutorial. diff --git a/docs/building-modules/invariants.md b/docs/building-modules/invariants.md index 638e120d5869..42c469c60baa 100644 --- a/docs/building-modules/invariants.md +++ b/docs/building-modules/invariants.md @@ -13,7 +13,7 @@ synopsis: An invariant is a property of the application that should always be tr An `Invariant` is a function that checks for a particular invariant within a module. Module `Invariant`s must follow the `Invariant`s type: -+++ https://github.com/cosmos/cosmos-sdk/blob/master/types/invariant.go#L9 ++++ https://github.com/cosmos/cosmos-sdk/blob/7d7821b9af132b0f6131640195326aa02b6751db/types/invariant.go#L9 where the `string` return value is the invariant message, which can be used when printing logs, and the `bool` return value is the actual result of the invariant check. @@ -61,7 +61,7 @@ func RegisterInvariants(ir sdk.InvariantRegistry, k Keeper) { } ``` -For more, see an example of [`Invariant`s implementation from the `staking` module](https://github.com/cosmos/cosmos-sdk/blob/master/x/staking/keeper/invariants.go). +For more, see an example of [`Invariant`s implementation from the `staking` module](https://github.com/cosmos/cosmos-sdk/blob/7d7821b9af132b0f6131640195326aa02b6751db/x/staking/keeper/invariants.go). ## Invariant Registry @@ -69,17 +69,17 @@ The `InvariantRegistry` is a registry where the `Invariant`s of all the modules At its core, the `InvariantRegistry` is defined in the SDK as an interface: -+++ https://github.com/cosmos/cosmos-sdk/blob/master/types/invariant.go#L14-L17 ++++ https://github.com/cosmos/cosmos-sdk/blob/7d7821b9af132b0f6131640195326aa02b6751db/types/invariant.go#L14-L17 Typically, this interface is implemented in the `keeper` of a specific module. The most used implementation of an `InvariantRegistry` can be found in the `crisis` module: -+++ https://github.com/cosmos/cosmos-sdk/blob/master/x/crisis/internal/keeper/keeper.go#L45-L49 ++++ https://github.com/cosmos/cosmos-sdk/blob/7d7821b9af132b0f6131640195326aa02b6751db/x/crisis/internal/keeper/keeper.go#L45-L49 The `InvariantRegistry` is therefore typically instantiated by instantiating the `keeper` of the `crisis` module in the [application's constructor function](../basics/app-anatomy.md#constructor-function). `Invariant`s can be checked manually via [`message`s](./messages-and-queries.md), but most often they are checked automatically at the end of each block. Here is an example from the `crisis` module: -+++ https://github.com/cosmos/cosmos-sdk/blob/master/x/crisis/abci.go#L7-L14 ++++ https://github.com/cosmos/cosmos-sdk/blob/7d7821b9af132b0f6131640195326aa02b6751db/x/crisis/abci.go#L7-L14 In both cases, if one of the `Invariant`s returns false, the `InvariantRegistry` can trigger special logic (e.g. have the application panic and print the `Invariant`s message in the log). diff --git a/docs/building-modules/messages-and-queries.md b/docs/building-modules/messages-and-queries.md index c6ca4145874f..cb1f67ce34bb 100644 --- a/docs/building-modules/messages-and-queries.md +++ b/docs/building-modules/messages-and-queries.md @@ -29,7 +29,7 @@ type MsgSubmitProposal struct { The `Msg` is typically accompanied by a standard constructor function, that is called from one of the [module's interface](./module-interfaces.md). `message`s also need to implement the [`Msg`] interface: -+++ https://github.com/cosmos/cosmos-sdk/blob/master/types/tx_msg.go#L7-L29 ++++ https://github.com/cosmos/cosmos-sdk/blob/7d7821b9af132b0f6131640195326aa02b6751db/types/tx_msg.go#L7-L29 It contains the following methods: diff --git a/docs/building-modules/module-interfaces.md b/docs/building-modules/module-interfaces.md index 343baba2df19..5b1352621a42 100644 --- a/docs/building-modules/module-interfaces.md +++ b/docs/building-modules/module-interfaces.md @@ -73,7 +73,7 @@ For full details on flags, visit the [Cobra Documentation](https://github.com/sp For example, the SDK `./client/flags` package includes a `PostCommands()` function that adds necessary flags to transaction commands, such as the `from` flag to indicate which address the transaction originates from. -+++ https://github.com/cosmos/cosmos-sdk/blob/master/client/flags/flags.go#L85-L116 ++++ https://github.com/cosmos/cosmos-sdk/blob/7d7821b9af132b0f6131640195326aa02b6751db/client/flags/flags.go#L85-L116 Here is an example of how to add a flag using the `from` flag from this function. diff --git a/docs/building-modules/module-manager.md b/docs/building-modules/module-manager.md index f081c12d4de5..b22b28cb627c 100644 --- a/docs/building-modules/module-manager.md +++ b/docs/building-modules/module-manager.md @@ -29,7 +29,7 @@ are only used for genesis can take advantage of the `Module` patterns without ha The `AppModuleBasic` interface defines the independent methods modules need to implement. -+++ https://github.com/cosmos/cosmos-sdk/blob/master/types/module/module.go#L45-L57 ++++ https://github.com/cosmos/cosmos-sdk/blob/7d7821b9af132b0f6131640195326aa02b6751db/types/module/module.go#L46-L59 Let us go through the methods: @@ -47,7 +47,7 @@ All the `AppModuleBasic` of an application are managed by the [`BasicManager`](# The `AppModuleGenesis` interface is a simple embedding of the `AppModuleBasic` interface with two added methods. -+++ https://github.com/cosmos/cosmos-sdk/blob/master/types/module/module.go#L123-L127 ++++ https://github.com/cosmos/cosmos-sdk/blob/7d7821b9af132b0f6131640195326aa02b6751db/types/module/module.go#L126-L131 Let us go through the two added methods: @@ -60,7 +60,7 @@ It does not have its own manager, and exists separately from [`AppModule`](#appm The `AppModule` interface defines the inter-dependent methods modules need to implement. -+++ https://github.com/cosmos/cosmos-sdk/blob/master/types/module/module.go#L130-L144 ++++ https://github.com/cosmos/cosmos-sdk/blob/7d7821b9af132b0f6131640195326aa02b6751db/types/module/module.go#L133-L149 `AppModule`s are managed by the [module manager](#manager). This interface embeds the `AppModuleGenesis` interface so that the manager can access all the independent and genesis inter-dependent methods of the module. This means that a concrete type implementing the `AppModule` interface must either implement all the methods of `AppModuleGenesis` (and by extension `AppModuleBasic`), or include a concrete type that does as parameter. @@ -102,11 +102,9 @@ Module managers are used to manage collections of `AppModuleBasic` and `AppModul ### `BasicManager` -The [`BasicManager`](https://github.com/cosmos/cosmos-sdk/blob/master/types/module/module.go#L60) is a structure that lists all the `AppModuleBasic` of an application: +The `BasicManager` is a structure that lists all the `AppModuleBasic` of an application: -```go -type BasicManager map[string]AppModuleBasic -``` ++++ https://github.com/cosmos/cosmos-sdk/blob/7d7821b9af132b0f6131640195326aa02b6751db/types/module/module.go#L61-L63 It implements the following methods: @@ -123,7 +121,7 @@ It implements the following methods: The `Manager` is a structure that holds all the `AppModule` of an application, and defines the order of execution between several key components of these modules: -+++ https://github.com/cosmos/cosmos-sdk/blob/master/types/module/module.go#L203-L209 ++++ https://github.com/cosmos/cosmos-sdk/blob/7d7821b9af132b0f6131640195326aa02b6751db/types/module/module.go#L190-L198 The module manager is used throughout the application whenever an action on a collection of modules is required. It implements the following methods: diff --git a/docs/building-modules/querier.md b/docs/building-modules/querier.md index 817ac5025a52..1455f04797c9 100644 --- a/docs/building-modules/querier.md +++ b/docs/building-modules/querier.md @@ -14,7 +14,7 @@ synopsis: A `Querier` designates a function that processes [`queries`](./message The `querier` type defined in the Cosmos SDK specifies the typical structure of a `querier` function: -+++ https://github.com/cosmos/cosmos-sdk/blob/master/types/queryable.go#L6 ++++ https://github.com/cosmos/cosmos-sdk/blob/7d7821b9af132b0f6131640195326aa02b6751db/types/queryable.go#L6 Let us break it down: diff --git a/docs/core/baseapp.md b/docs/core/baseapp.md index e3e592159cc7..46ef849bc94d 100644 --- a/docs/core/baseapp.md +++ b/docs/core/baseapp.md @@ -47,7 +47,7 @@ management logic. The `BaseApp` type holds many important parameters for any Cosmos SDK based application. -+++ https://github.com/cosmos/cosmos-sdk/blob/master/baseapp/baseapp.go#L54-L108 ++++ https://github.com/cosmos/cosmos-sdk/blob/7d7821b9af132b0f6131640195326aa02b6751db/baseapp/baseapp.go#L54-L108 Let us go through the most important components. @@ -115,14 +115,12 @@ func NewBaseApp( ``` The `BaseApp` constructor function is pretty straightforward. The only thing worth noting is the -possibility to provide additional [`options`](https://github.com/cosmos/cosmos-sdk/blob/master/baseapp/options.go) +possibility to provide additional [`options`](https://github.com/cosmos/cosmos-sdk/blob/7d7821b9af132b0f6131640195326aa02b6751db/baseapp/options.go) to the `BaseApp`, which will execute them in order. The `options` are generally `setter` functions for important parameters, like `SetPruning()` to set pruning options or `SetMinGasPrices()` to set the node's `min-gas-prices`. -A list of `options` examples can be found -[here](https://github.com/cosmos/cosmos-sdk/blob/master/baseapp/options.go). Naturally, developers -can add additional `options` based on their application's needs. +Naturally, developers can add additional `options` based on their application's needs. ## State Updates @@ -258,7 +256,7 @@ The response contains: - `Info (string):` Additional information. May be non-deterministic. - `GasWanted (int64)`: Amount of gas requested for transaction. It is provided by users when they generate the transaction. - `GasUsed (int64)`: Amount of gas consumed by transaction. During `CheckTx`, this value is computed by multiplying the standard cost of a transaction byte by the size of the raw transaction. Next is an example: - +++ https://github.com/cosmos/cosmos-sdk/blob/master/x/auth/ante/basic.go#L98 + +++ https://github.com/cosmos/cosmos-sdk/blob/7d7821b9af132b0f6131640195326aa02b6751db/x/auth/ante/basic.go#L104 - `Events ([]cmn.KVPair)`: Key-Value tags for filtering and indexing transactions (eg. by account). See [`event`s](./events.md) for more. - `Codespace (string)`: Namespace for the Code. @@ -284,7 +282,7 @@ Before the first transaction of a given block is processed, a [volatile state](# During step 5., each read/write to the store increases the value of `GasConsumed`. You can find the default cost of each operation: -+++ https://github.com/cosmos/cosmos-sdk/blob/master/store/types/gas.go#L142-L150 ++++ https://github.com/cosmos/cosmos-sdk/blob/7d7821b9af132b0f6131640195326aa02b6751db/store/types/gas.go#L142-L150 At any point, if `GasConsumed > GasWanted`, the function returns with `Code != 0` and `DeliverTx` fails. @@ -295,7 +293,7 @@ At any point, if `GasConsumed > GasWanted`, the function returns with `Code != 0 - `Log (string):` The output of the application's logger. May be non-deterministic. - `Info (string):` Additional information. May be non-deterministic. - `GasWanted (int64)`: Amount of gas requested for transaction. It is provided by users when they generate the transaction. -- `GasUsed (int64)`: Amount of gas consumed by transaction. During `DeliverTx`, this value is computed by multiplying the standard cost of a transaction byte by the size of the raw transaction (click [here](https://github.com/cosmos/cosmos-sdk/blob/master/x/auth/ante/basic.go#L98) for an example), and by adding gas each time a read/write to the store occurs. +- `GasUsed (int64)`: Amount of gas consumed by transaction. During `DeliverTx`, this value is computed by multiplying the standard cost of a transaction byte by the size of the raw transaction, and by adding gas each time a read/write to the store occurs. - `Events ([]cmn.KVPair)`: Key-Value tags for filtering and indexing transactions (eg. by account). See [`event`s](./events.md) for more. - `Codespace (string)`: Namespace for the Code. @@ -311,7 +309,7 @@ After that, `RunTx()` calls `ValidateBasic()` on each `message`in the `Tx`, whic Then, the [`anteHandler`](#antehandler) of the application is run (if it exists). In preparation of this step, both the `checkState`/`deliverState`'s `context` and `context`'s `CacheMultiStore` are cached-wrapped using the `cacheTxContext()` function. -+++ https://github.com/cosmos/cosmos-sdk/blob/master/baseapp/baseapp.go#L781-L798 ++++ https://github.com/cosmos/cosmos-sdk/blob/7d7821b9af132b0f6131640195326aa02b6751db/baseapp/baseapp.go#L587 This allows `RunTx` not to commit the changes made to the state during the execution of `anteHandler` if it ends up failing. It also prevents the module implementing the `anteHandler` from writing to state, which is an important part of the [object-capabilities](./ocap.md) of the Cosmos SDK. @@ -321,7 +319,7 @@ Finally, the [`RunMsgs()`](#runmsgs) function is called to process the `messages The `AnteHandler` is a special handler that implements the `anteHandler` interface and is used to authenticate the transaction before the transaction's internal messages are processed. -+++ https://github.com/cosmos/cosmos-sdk/blob/master/types/handler.go#L8 ++++ https://github.com/cosmos/cosmos-sdk/blob/7d7821b9af132b0f6131640195326aa02b6751db/types/handler.go#L8 The `AnteHandler` is theoretically optional, but still a very important component of public blockchain networks. It serves 3 primary purposes: @@ -356,7 +354,7 @@ Finally, the `InitChain(req abci.RequestInitChain)` method of `baseapp` calls th The [`BeginBlock` ABCI message](#https://tendermint.com/docs/app-dev/abci-spec.html#beginblock) is sent from the underlying Tendermint engine when a block proposal created by the correct proposer is received, before [`DeliverTx`](#delivertx) is run for each transaction in the block. It allows developers to have logic be executed at the beginning of each block. In the Cosmos SDK, the `BeginBlock(req abci.RequestBeginBlock)` method does the following: - Initialize [`deliverState`](#volatile-states) with the latest header using the `req abci.RequestBeginBlock` passed as parameter via the `setDeliverState` function. - +++ https://github.com/cosmos/cosmos-sdk/blob/master/baseapp/baseapp.go#L283-L289 + +++ https://github.com/cosmos/cosmos-sdk/blob/7d7821b9af132b0f6131640195326aa02b6751db/baseapp/baseapp.go#L387-L397 This function also resets the [main gas meter](../basics/gas-fees.md#main-gas-meter). - Initialize the [block gas meter](../basics/gas-fees.md#block-gas-meter) with the `maxGas` limit. The `gas` consumed within the block cannot go above `maxGas`. This parameter is defined in the application's consensus parameters. - Run the application's [`beginBlocker()`](../basics/app-anatomy.md#beginblocker-and-endblock), which mainly runs the [`BeginBlocker()`](../building-modules/beginblock-endblock.md#beginblock) method of each of the application's modules. diff --git a/docs/core/encoding.md b/docs/core/encoding.md index 601b7aef6954..caf445511799 100644 --- a/docs/core/encoding.md +++ b/docs/core/encoding.md @@ -33,13 +33,11 @@ Alternatively, it is possible to use `MustMarshalBinaryLengthPrefixed`/`MustUnma Another important use of the `codec` is the encoding and decoding of [transactions](./transactions.md). Transactions are defined at the Cosmos SDK level, but passed to the underlying consensus engine in order to be relayed to other peers. Since the underlying consensus engine is agnostic to the application, it only accepts transactions in the form of `[]byte`. The encoding is done by an object called `TxEncoder` and the decoding by an object called `TxDecoder`. -+++ https://github.com/cosmos/cosmos-sdk/blob/master/types/tx_msg.go#L48-L49 - -+++ https://github.com/cosmos/cosmos-sdk/blob/master/types/tx_msg.go#L45-L47 ++++ https://github.com/cosmos/cosmos-sdk/blob/7d7821b9af132b0f6131640195326aa02b6751db/types/tx_msg.go#L45-L49 A standard implementation of both these objects can be found in the [`auth` module](https://github.com/cosmos/cosmos-sdk/blob/master/x/auth): -+++ https://github.com/cosmos/cosmos-sdk/blob/master/x/auth/types/stdtx.go#L241-L266 ++++ https://github.com/cosmos/cosmos-sdk/blob/7d7821b9af132b0f6131640195326aa02b6751db/x/auth/types/stdtx.go#L241-L266 ## Next {hide} diff --git a/docs/core/events.md b/docs/core/events.md index 5c5398b0b563..58f2230e5a67 100644 --- a/docs/core/events.md +++ b/docs/core/events.md @@ -19,7 +19,7 @@ They contain: - A **`type`** of type `string`, which can refer to the type of action that led to the `event`'s emission (e.g. a certain value going above a threshold), or to the type of `message` if the event is triggered at the end of that `message` processing. - A list of `attributes`, which are key-value pairs that give more information about the `event`. - +++ https://github.com/cosmos/cosmos-sdk/blob/master/types/events.go#L53-L56 + +++ https://github.com/cosmos/cosmos-sdk/blob/7d7821b9af132b0f6131640195326aa02b6751db/types/events.go#L51-L56 `Event`s are returned to the underlying consensus engine in the response of the following ABCI messages: [`CheckTx`](./baseapp.md#checktx), [`DeliverTx`](./baseapp.md#delivertx), [`BeginBlock`](./baseapp.md#beginblock) and [`EndBlock`](./baseapp.md#endblock). @@ -29,11 +29,11 @@ Typically, `event` `type`s and `attributes` are defined on a **per-module basis* In Cosmos SDK applications, `event`s are generally managed by an object called the `EventManager`. It is implemented as a simple wrapper around a slice of `event`s: -+++ https://github.com/cosmos/cosmos-sdk/blob/master/types/events.go#L18-L20 ++++ https://github.com/cosmos/cosmos-sdk/blob/7d7821b9af132b0f6131640195326aa02b6751db/types/events.go#L16-L20 The `EventManager` comes with a set of useful methods to manage `event`s. Among them, the one that is used the most by module and application developers is the `EmitEvent` method, which registers an `event` in the `EventManager`. -+++ https://github.com/cosmos/cosmos-sdk/blob/master/types/events.go#L29-L31 ++++ https://github.com/cosmos/cosmos-sdk/blob/7d7821b9af132b0f6131640195326aa02b6751db/types/events.go#L29-L31 Typically, module developers will implement event emission via the `EventManager` in the [`handler`](../building-modules/handler.md) of modules, as well as in the [`BeginBlocker` and/or`EndBlocker` functions](../building-modules/beginblock-endblock.md). The `EventManager` is accessed via the context [`ctx`](./context.md), and event emission generally follows this pattern: diff --git a/docs/core/node.md b/docs/core/node.md index 0cbc2caa2a1e..5da50d6080a4 100644 --- a/docs/core/node.md +++ b/docs/core/node.md @@ -17,7 +17,7 @@ In general, developers will implement the `main.go` function with the following - First, a [`codec`](./encoding.md) is instanciated for the application. - Then, the `config` is retrieved and config parameters are set. This mainly involves setting the bech32 prefixes for [addresses and pubkeys](../basics/accounts.md#addresses-and-pubkeys). - +++ https://github.com/cosmos/cosmos-sdk/blob/master/types/config.go#L10-L21 + +++ https://github.com/cosmos/cosmos-sdk/blob/7d7821b9af132b0f6131640195326aa02b6751db/types/config.go#L10-L21 - Using [cobra](https://github.com/spf13/cobra), the root command of the full-node client is created. After that, all the custom commands of the application are added using the `AddCommand()` method of `rootCmd`. - Add default server commands to `rootCmd` using the `server.AddCommands(ctx, cdc, rootCmd, newApp, exportAppStateAndTMValidators)` method. These commands are separated from the ones added above since they are standard and defined at SDK level. They should be shared by all SDK-based applications. They include the most important command: the [`start` command](#start-command). - Prepare and execute the `executor`. @@ -43,15 +43,15 @@ The flow of the `start` command is pretty straightforward. First, it retrieves t With the `db`, the `start` command creates a new instance of the application using an `appCreator` function: -+++ https://github.com/cosmos/cosmos-sdk/blob/master/server/start.go#L144 ++++ https://github.com/cosmos/cosmos-sdk/blob/7d7821b9af132b0f6131640195326aa02b6751db/server/start.go#L144 Note that an `appCreator` is a function that fulfills the `AppCreator` signature. In practice, the [constructor the application](../basics/app-anatomy.md#constructor-function) is passed as the `appCreator`. -+++ https://github.com/cosmos/cosmos-sdk/blob/master/server/constructors.go#L20 ++++ https://github.com/cosmos/cosmos-sdk/blob/7d7821b9af132b0f6131640195326aa02b6751db/server/constructors.go#L17-L25 Then, the instance of `app` is used to instanciate a new Tendermint node: -+++ https://github.com/cosmos/cosmos-sdk/blob/master/server/start.go#L153-L163 ++++ https://github.com/cosmos/cosmos-sdk/blob/7d7821b9af132b0f6131640195326aa02b6751db/server/start.go#L153-L163 The Tendermint node can be created with `app` because the latter satisfies the [`abci.Application` interface](https://github.com/tendermint/tendermint/blob/bc572217c07b90ad9cee851f193aaa8e9557cbc7/abci/types/application.go#L11-L26) (given that `app` extends [`baseapp`](./baseapp.md)). As part of the `NewNode` method, Tendermint makes sure that the height of the application (i.e. number of blocks since genesis) is equal to the height of the Tendermint node. The difference between these two heights should always be negative or null. If it is strictly negative, `NewNode` will replay blocks until the height of the application reaches the height of the Tendermint node. Finally, if the height of the application is `0`, the Tendermint node will call [`InitChain`](./baseapp.md#initchain) on the application to initialize the state from the genesis file. diff --git a/docs/core/store.md b/docs/core/store.md index eaa139ba41be..9eb5e886c0bf 100644 --- a/docs/core/store.md +++ b/docs/core/store.md @@ -57,11 +57,11 @@ The Cosmos SDK comes with a large set of stores to persist the state of applicat At its very core, a Cosmos SDK `store` is an object that holds a `CacheWrapper` and implements a `GetStoreType()` method: -+++ https://github.com/cosmos/cosmos-sdk/blob/master/store/types/store.go#L12-L15 ++++ https://github.com/cosmos/cosmos-sdk/blob/7d7821b9af132b0f6131640195326aa02b6751db/store/types/store.go#L12-L15 The `GetStoreType` is a simple method that returns the type of store, whereas a `CacheWrapper` is a simple interface that specifies cache-wrapping and `Write` methods: -+++ https://github.com/cosmos/cosmos-sdk/blob/master/store/types/store.go#L217-L238 ++++ https://github.com/cosmos/cosmos-sdk/blob/7d7821b9af132b0f6131640195326aa02b6751db/store/types/store.go#L217-L238 Cache-wrapping is used ubiquitously in the Cosmos SDK and required to be implemented on every store type. A cache-wrapper creates a light snapshot of a store that can be passed around and updated without affecting the main underlying store. This is used to trigger temporary state-transitions that may be reverted later should an error occur. If a state-transition sequence is performed without issue, the cached store can be comitted to the underlying store at the end of the sequence. @@ -69,11 +69,11 @@ Cache-wrapping is used ubiquitously in the Cosmos SDK and required to be impleme A commit store is a store that has the ability to commit changes made to the underlying tree or db. The Cosmos SDK differentiates simple stores from commit stores by extending the basic store interfaces with a `Committer`: -+++ https://github.com/cosmos/cosmos-sdk/blob/master/store/types/store.go#L24-L28 ++++ https://github.com/cosmos/cosmos-sdk/blob/7d7821b9af132b0f6131640195326aa02b6751db/store/types/store.go#L24-L28 The `Committer` is an interface that defines methods to persist changes to disk: -+++ https://github.com/cosmos/cosmos-sdk/blob/master/store/types/store.go#L17-L22 ++++ https://github.com/cosmos/cosmos-sdk/blob/7d7821b9af132b0f6131640195326aa02b6751db/store/types/store.go#L17-L22 The `CommitID` is a deterministic commit of the state tree. Its hash is returned to the underlying consensus engine and stored in the block header. Note that commit store interfaces exist for various purposes, one of which is to make sure not every object can commit the store. As part of the [object-capabilities model](./ocap.md) of the Cosmos SDK, only `baseapp` should have the ability to commit stores. For example, this is the reason why the `ctx.KVStore()` method by which modules typically access stores returns a `KVStore` and not a `CommitKVStore`. @@ -85,7 +85,7 @@ The Cosmos SDK comes with many types of stores, the most used being [`CommitMult Each Cosmos SDK application holds a multistore at its root to persist its state. The multistore is a store of `KVStores` that follows the `Multistore` interface: -+++ https://github.com/cosmos/cosmos-sdk/blob/master/store/types/store.go#L83-L112 ++++ https://github.com/cosmos/cosmos-sdk/blob/7d7821b9af132b0f6131640195326aa02b6751db/store/types/store.go#L83-L112 If tracing is enabled, then cache-wrapping the multistore will wrap all the underlying `KVStore` in [`TraceKv.Store`](#tracekv-store) before caching them. @@ -93,11 +93,11 @@ If tracing is enabled, then cache-wrapping the multistore will wrap all the unde The main type of `Multistore` used in the Cosmos SDK is `CommitMultiStore`, which is an extension of the `Multistore` interface: -+++ https://github.com/cosmos/cosmos-sdk/blob/master/store/types/store.go#L120-L158 ++++ https://github.com/cosmos/cosmos-sdk/blob/7d7821b9af132b0f6131640195326aa02b6751db/store/types/store.go#L120-L158 As for concrete implementation, the [`rootMulti.Store`] is the go-to implementation of the `CommitMultiStore` interface. -+++ https://github.com/cosmos/cosmos-sdk/blob/master/store/rootmulti/store.go#L27-L43 ++++ https://github.com/cosmos/cosmos-sdk/blob/7d7821b9af132b0f6131640195326aa02b6751db/store/rootmulti/store.go#L27-L43 The `rootMulti.Store` is a base-layer multistore built around a `db` on top of which multiple `KVStores` can be mounted, and is the default multistore store used in [`baseapp`](./baseapp.md). @@ -105,7 +105,7 @@ The `rootMulti.Store` is a base-layer multistore built around a `db` on top of w Whenever the `rootMulti.Store` needs to be cached-wrapped, a [`cachemulti.Store`](https://github.com/cosmos/cosmos-sdk/blob/master/store/cachemulti/store.go) is used. -+++ https://github.com/cosmos/cosmos-sdk/blob/master/store/cachemulti/store.go#L17-L28 ++++ https://github.com/cosmos/cosmos-sdk/blob/7d7821b9af132b0f6131640195326aa02b6751db/store/cachemulti/store.go#L17-L28 `cachemulti.Store` cache wraps all substores in its constructor and hold them in `Store.stores`. `Store.GetKVStore()` returns the store from `Store.stores`, and `Store.Write()` recursively calls `CacheWrap.Write()` on all the substores. @@ -119,9 +119,7 @@ Individual `KVStore`s are used by modules to manage a subset of the global state `CommitKVStore`s are declared by proxy of their respective `key` and mounted on the application's [multistore](#multistore) in the [main application file](../basics/app-anatomy.md#core-application-file). In the same file, the `key` is also passed to the module's `keeper` that is responsible for managing the store. -+++ https://github.com/cosmos/cosmos-sdk/blob/master/store/types/store.go#L163-L193 - -+++ https://github.com/cosmos/cosmos-sdk/blob/master/store/types/store.go#L163-L193 ++++ https://github.com/cosmos/cosmos-sdk/blob/7d7821b9af132b0f6131640195326aa02b6751db/store/types/store.go#L163-L193 Apart from the traditional `Get` and `Set` methods, a `KVStore` is expected to implement an `Iterator()` method which returns an `Iterator` object. The `Iterator()` method is used to iterate over a domain of keys, typically keys that share a common prefix. Here is a common pattern of using an `Iterator` that might be found in a module's `keeper`: @@ -144,7 +142,7 @@ for ; iterator.Valid(); iterator.Next() { The default implementation of `KVStore` and `CommitKVStore` used in `baseapp` is the `iavl.Store`. -+++ https://github.com/cosmos/cosmos-sdk/blob/master/store/iavl/store.go#L32-L47 ++++ https://github.com/cosmos/cosmos-sdk/blob/7d7821b9af132b0f6131640195326aa02b6751db/store/iavl/store.go#L32-L47 `iavl` stores are based around an [IAVL Tree](https://github.com/tendermint/iavl), a self-balancing binary tree which guarantees that: @@ -156,7 +154,7 @@ The default implementation of `KVStore` and `CommitKVStore` used in `baseapp` is `dbadapter.Store` is a adapter for `dbm.DB` making it fulfilling the `KVStore` interface. -+++ https://github.com/cosmos/cosmos-sdk/blob/master/store/dbadapter/store.go#L13-L16 ++++ https://github.com/cosmos/cosmos-sdk/blob/7d7821b9af132b0f6131640195326aa02b6751db/store/dbadapter/store.go#L13-L16 `dbadapter.Store` embeds `dbm.DB`, meaning most of the `KVStore` interface functions are implemented. The other functions (mostly miscellaneous) are manually implemented. This store is primarily used within [Transient Stores](#transient-stores) @@ -164,17 +162,17 @@ The default implementation of `KVStore` and `CommitKVStore` used in `baseapp` is `Transient.Store` is a base-layer `KVStore` which is automatically discarded at the end of the block. -+++ https://github.com/cosmos/cosmos-sdk/blob/master/store/transient/store.go#L14-L17 ++++ https://github.com/cosmos/cosmos-sdk/blob/7d7821b9af132b0f6131640195326aa02b6751db/store/transient/store.go#L14-L17 `Transient.Store` is a `dbadapter.Store` with a `dbm.NewMemDB()`. All `KVStore` methods are reused. When `Store.Commit()` is called, a new `dbadapter.Store` is assigned, discarding previous reference and making it garbage collected. This type of store is useful to persist information that is only relevant per-block. One example would be to store parameter changes (i.e. a bool set to `true` if a parameter changed in a block). -+++ https://github.com/cosmos/cosmos-sdk/blob/master/x/params/subspace/subspace.go#L24-L32 ++++ https://github.com/cosmos/cosmos-sdk/blob/7d7821b9af132b0f6131640195326aa02b6751db/x/params/subspace/subspace.go#L24-L32 Transient stores are typically accessed via the [`context`](./context.md) via the `TransientStore()` method: -+++ https://github.com/cosmos/cosmos-sdk/blob/master/types/context.go#L215-L218 ++++ https://github.com/cosmos/cosmos-sdk/blob/7d7821b9af132b0f6131640195326aa02b6751db/types/context.go#L215-L218 ## KVStore Wrappers @@ -182,7 +180,7 @@ Transient stores are typically accessed via the [`context`](./context.md) via th `cachekv.Store` is a wrapper `KVStore` which provides buffered writing / cached reading functionalities over the underlying `KVStore`. -+++ https://github.com/cosmos/cosmos-sdk/blob/master/store/cachekv/store.go#L26-L33 ++++ https://github.com/cosmos/cosmos-sdk/blob/7d7821b9af132b0f6131640195326aa02b6751db/store/cachekv/store.go#L26-L33 This is the type used whenever an IAVL Store needs to be cache-wrapped (typically when setting value that might be reverted later). @@ -202,25 +200,25 @@ This is the type used whenever an IAVL Store needs to be cache-wrapped (typicall Cosmos SDK applications use [`gas`](../basics/gas-fees.md) to track resources usage and prevent spam. [`GasKv.Store`](https://github.com/cosmos/cosmos-sdk/blob/master/store/gaskv/store.go) is a `KVStore` wrapper that enables automatic gas consumption each time a read or write to the store is made. It is the solution of choice to track storage usage in Cosmos SDK applications. -+++ https://github.com/cosmos/cosmos-sdk/blob/master/store/gaskv/store.go#L11-L17 ++++ https://github.com/cosmos/cosmos-sdk/blob/7d7821b9af132b0f6131640195326aa02b6751db/store/gaskv/store.go#L11-L17 When methods of the parent `KVStore` are called, `GasKv.Store` automatically consumes appropriate amount of gas depending on the `Store.gasConfig`: -+++ https://github.com/cosmos/cosmos-sdk/blob/master/store/types/gas.go#L141-L150 ++++ https://github.com/cosmos/cosmos-sdk/blob/7d7821b9af132b0f6131640195326aa02b6751db/store/types/gas.go#L141-L150 By default, all `KVStores` are wrapped in `GasKv.Stores` when retrieved. This is done in the `KVStore()` method of the [`context`](./context.md): -+++ https://github.com/cosmos/cosmos-sdk/blob/master/types/context.go#L210-L213 ++++ https://github.com/cosmos/cosmos-sdk/blob/7d7821b9af132b0f6131640195326aa02b6751db/types/context.go#L210-L213 In this case, the default gas configuration is used: -+++ https://github.com/cosmos/cosmos-sdk/blob/master/store/types/gas.go#L152-L163 ++++ https://github.com/cosmos/cosmos-sdk/blob/7d7821b9af132b0f6131640195326aa02b6751db/store/types/gas.go#L152-L163 ### `TraceKv` Store `tracekv.Store` is a wrapper `KVStore` which provides operation tracing functionalities over the underlying `KVStore`. It is applied automatically by the Cosmos SDK on all `KVStore` if tracing is enabled on the parent `MultiStore`. -+++ https://github.com/cosmos/cosmos-sdk/blob/master/store/tracekv/store.go#L20-L43 ++++ https://github.com/cosmos/cosmos-sdk/blob/7d7821b9af132b0f6131640195326aa02b6751db/store/tracekv/store.go#L20-L43 When each `KVStore` methods are called, `tracekv.Store` automatically logs `traceOperation` to the `Store.writer`. `traceOperation.Metadata` is filled with `Store.context` when it is not nil. `TraceContext` is a `map[string]interface{}`. @@ -228,7 +226,7 @@ When each `KVStore` methods are called, `tracekv.Store` automatically logs `trac `prefix.Store` is a wrapper `KVStore` which provides automatic key-prefixing functionalities over the underlying `KVStore`. -+++ https://github.com/cosmos/cosmos-sdk/blob/master/store/prefix/store.go#L17-L20 ++++ https://github.com/cosmos/cosmos-sdk/blob/7d7821b9af132b0f6131640195326aa02b6751db/store/prefix/store.go#L17-L20 When `Store.{Get, Set}()` is called, the store forwards the call to its parent, with the key prefixed with the `Store.prefix`. diff --git a/docs/core/transactions.md b/docs/core/transactions.md index 4b322f8c30ef..89854f2db6e0 100644 --- a/docs/core/transactions.md +++ b/docs/core/transactions.md @@ -19,7 +19,7 @@ When users want to interact with an application and make state changes (e.g. sen Transaction objects are SDK types that implement the `Tx` interface -+++ https://github.com/cosmos/cosmos-sdk/blob/master/types/tx_msg.go#L34-L41 ++++ https://github.com/cosmos/cosmos-sdk/blob/7d7821b9af132b0f6131640195326aa02b6751db/types/tx_msg.go#L34-L41 It contains the following methods: @@ -46,7 +46,7 @@ When users interact with the application's interfaces, they invoke the underlyin **`Message`s** are module-specific objects that trigger state transitions within the scope of the module they belong to. Module developers define the `message`s for their module by implementing the `Msg` interface, and also define a [`Handler`](../building-modules/handler.md) to process them. -+++ https://github.com/cosmos/cosmos-sdk/blob/master/types/tx_msg.go#L8-L29 ++++ https://github.com/cosmos/cosmos-sdk/blob/7d7821b9af132b0f6131640195326aa02b6751db/types/tx_msg.go#L8-L29 `Message`s in a module are typically defined in a `msgs.go` file (though not always), and one handler with multiple functions to handle each of the module's `message`s is defined in a `handler.go` file. @@ -64,7 +64,7 @@ Transactions are first created by end-users through an `appcli tx` command throu The `TxBuilder` contains data closely related with the processing of transactions. -+++ https://github.com/cosmos/cosmos-sdk/blob/master/x/auth/types/txbuilder.go#L18-L31 ++++ https://github.com/cosmos/cosmos-sdk/blob/7d7821b9af132b0f6131640195326aa02b6751db/x/auth/types/txbuilder.go#L18-L31 - `TxEncoder` defined by the developer for this type of transaction. Used to encode messages before being processed by nodes running Tendermint. - `Keybase` that manages the user's keys and is used to perform signing operations. diff --git a/docs/interfaces/query-lifecycle.md b/docs/interfaces/query-lifecycle.md index 78b05da70ba1..27e2d6519066 100644 --- a/docs/interfaces/query-lifecycle.md +++ b/docs/interfaces/query-lifecycle.md @@ -25,7 +25,7 @@ appcli query staking delegations This query command was defined by the [`staking`](https://github.com/cosmos/cosmos-sdk/tree/master/x/staking/spec) module developer and added to the list of subcommands by the application developer when creating the CLI. The code for this particular command is the following: -+++ https://github.com/cosmos/cosmos-sdk/blob/master/x/staking/client/cli/query.go#L253-L294 ++++ https://github.com/cosmos/cosmos-sdk/blob/7d7821b9af132b0f6131640195326aa02b6751db/x/staking/client/cli/query.go#L250-L293 Note that the general format is as follows: @@ -49,7 +49,7 @@ To provide values such as `--node` (the full-node the CLI connects to) that are The router automatically routes the `Query` HTTP request to the staking module `delegatorDelegationsHandlerFn()` function. -+++ https://github.com/cosmos/cosmos-sdk/blob/master/x/staking/client/rest/query.go#L103-L106 ++++ https://github.com/cosmos/cosmos-sdk/blob/7d7821b9af132b0f6131640195326aa02b6751db/x/staking/client/rest/query.go#L103-L106 Since this function is defined within the module and thus has no inherent knowledge of the application `Query` belongs to, it takes in the application `codec` and `CLIContext` as parameters. @@ -72,7 +72,7 @@ The first thing that is created in the execution of a CLI command is a `CLIConte The `CLIContext` also contains various functions such as `Query()` which retrieves the RPC Client and makes an ABCI call to relay a query to a full-node. -+++ https://github.com/cosmos/cosmos-sdk/blob/master/client/context/context.go#L36-L59 ++++ https://github.com/cosmos/cosmos-sdk/blob/7d7821b9af132b0f6131640195326aa02b6751db/client/context/context.go#L23-L47 The `CLIContext`'s primary role is to store data used during interactions with the end-user and provide methods to interact with this data - it is used before and after the query is processed by the full-node. Specifically, in handling `Query`, the `CLIContext` is utilized to encode the query parameters, retrieve the full-node, and write the output. Prior to being relayed to a full-node, the query needs to be encoded into a `[]byte` form, as full-nodes are application-agnostic and do not understand specific types. The full-node (RPC Client) itself is retrieved using the `CLIContext`, which knows which node the user CLI is connected to. The query is relayed to this full-node to be processed. Finally, the `CLIContext` contains a `Writer` to write output when the response is returned. These steps are further described in later sections. @@ -122,7 +122,7 @@ The `CLIContext` has a `Query()` function used to retrieve the pre-configured no Here is what the code looks like: -+++ https://github.com/cosmos/cosmos-sdk/blob/master/client/context/query.go#L80-L112 ++++ https://github.com/cosmos/cosmos-sdk/blob/7d7821b9af132b0f6131640195326aa02b6751db/client/context/query.go#L75-L112 ## RPC @@ -142,19 +142,19 @@ Once a result is received from the querier, `baseapp` begins the process of retu Since `Query()` is an ABCI function, `baseapp` returns the response as an [`abci.ResponseQuery`](https://tendermint.com/docs/spec/abci/abci.html#messages) type. The `CLIContext` `Query()` routine receives the response and, if `--trust-node` is toggled to `false` and a proof needs to be verified, the response is verified with the `CLIContext` `verifyProof()` function before the response is returned. -+++ https://github.com/cosmos/cosmos-sdk/blob/master/client/context/query.go#L136-L173 ++++ https://github.com/cosmos/cosmos-sdk/blob/7d7821b9af132b0f6131640195326aa02b6751db/client/context/query.go#L127-L165 ### CLI Response The application [`codec`](../core/encoding.md) is used to unmarshal the response to a JSON and the `CLIContext` prints the output to the command line, applying any configurations such as `--indent`. -+++ https://github.com/cosmos/cosmos-sdk/blob/master/x/staking/client/cli/query.go#L252-L293 ++++ https://github.com/cosmos/cosmos-sdk/blob/7d7821b9af132b0f6131640195326aa02b6751db/x/staking/client/cli/query.go#L252-L293 ### REST Response The [REST server](./rest.md#rest-server) uses the `CLIContext` to format the response properly, then uses the HTTP package to write the appropriate response or error. -+++ https://github.com/cosmos/cosmos-sdk/blob/master/x/staking/client/rest/utils.go#L115-L148 ++++ https://github.com/cosmos/cosmos-sdk/blob/7d7821b9af132b0f6131640195326aa02b6751db/x/staking/client/rest/utils.go#L115-L148 ## Next {hide} From f7a7f26692c0276b73d509b61ed11c71de32818b Mon Sep 17 00:00:00 2001 From: gamarin Date: Mon, 9 Dec 2019 20:17:54 +0100 Subject: [PATCH 193/196] small clean --- docs/basics/app-anatomy.md | 31 +++++++----------------------- docs/intro/overview.md | 4 ++-- docs/intro/sdk-app-architecture.md | 6 +++--- 3 files changed, 12 insertions(+), 29 deletions(-) diff --git a/docs/basics/app-anatomy.md b/docs/basics/app-anatomy.md index a9a4588d2820..646e6dad93c4 100644 --- a/docs/basics/app-anatomy.md +++ b/docs/basics/app-anatomy.md @@ -121,21 +121,17 @@ See an example of a `MakeCodec` from [`gaia`](https://github.com/cosmos/gaia): ## Modules -Modules are the heart and soul of SDK applications. They can be considered as state-machines within the state-machine. When a transaction is relayed from the underlying Tendermint engine via the ABCI to the application, it is routed by [`baseapp`](../core/baseapp.md) to the appropriate module in order to be processed. This paradigm enables developers to easily build complex state-machines, as most of the modules they need often already exist. For developers, most of the work involved in building an SDK application revolves around building custom modules required by their application that do not exist yet, and integrating them with modules that do already exist into one coherent application. In the application directory, the standard practice is to store modules in the `x/` folder (not to be confused with the SDK's `x/` folder, which contains already-built modules). - -To learn more about modules, [click here](../building-modules/intro.md) +[Modules](../building-modules/intro.md) are the heart and soul of SDK applications. They can be considered as state-machines within the state-machine. When a transaction is relayed from the underlying Tendermint engine via the ABCI to the application, it is routed by [`baseapp`](../core/baseapp.md) to the appropriate module in order to be processed. This paradigm enables developers to easily build complex state-machines, as most of the modules they need often already exist. For developers, most of the work involved in building an SDK application revolves around building custom modules required by their application that do not exist yet, and integrating them with modules that do already exist into one coherent application. In the application directory, the standard practice is to store modules in the `x/` folder (not to be confused with the SDK's `x/` folder, which contains already-built modules). ### Application Module Interface -Modules must implement two interfaces defined in the Cosmos SDK, [`AppModuleBasic`](../building-modules/module-manager.md#appmodulebasic) and [`AppModule`](../building-modules/module-manager.md#appmodule). The former implements basic non-dependant elements of the module, such as the `codec`, while the latter handles the bulk of the module methods (including methods that require references to other modules' `keeper`s). Both the `AppModule` and `AppModuleBasic` types are defined in a file called `./module.go`. +Modules must implement [interfaces](../building-modules/module-manager.md#application-module-interfaces) defined in the Cosmos SDK, [`AppModuleBasic`](../building-modules/module-manager.md#appmodulebasic) and [`AppModule`](../building-modules/module-manager.md#appmodule). The former implements basic non-dependant elements of the module, such as the `codec`, while the latter handles the bulk of the module methods (including methods that require references to other modules' `keeper`s). Both the `AppModule` and `AppModuleBasic` types are defined in a file called `./module.go`. `AppModule` exposes a collection of useful methods on the module that facilitates the composition of modules into a coherent application. These methods are are called from the `module manager`(../building-modules/module-manager.md#manager), which manages the application's collection of modules. -To learn more about the application module interface, [click here](../building-modules/module-manager.md#application-module-interfaces). - ### Message Types -`Message`s are objects defined by each module that implement the [`message`](../building-modules/messages-and-queries.md#messages) interface. Each [`transaction`](../core/transactions.md) contains one or multiple `messages`. +[`Message`s](../building-modules/messages-and-queries.md#messages) are objects defined by each module that implement the [`message`](../building-modules/messages-and-queries.md#messages) interface. Each [`transaction`](../core/transactions.md) contains one or multiple `messages`. When a valid block of transactions is received by the full-node, Tendermint relays each one to the application via [`DeliverTx`](https://tendermint.com/docs/app-dev/abci-spec.html#delivertx). Then, the application handles the transaction: @@ -152,8 +148,6 @@ Module developers create custom message types when they build their own module. It is processed by the `handler` of the `bank` module, which ultimately calls the `keeper` of the `auth` module in order to update the state. -To learn more about messages, [click here](../building-modules/messages-and-queries.md#messages). - ### Handler The [`handler`](../building-modules/handler.md) refers to the part of the module responsible for processing the `message` after it is routed by `baseapp`. `handler` functions of modules are only executed if the transaction is relayed from Tendermint by the `DeliverTx` ABCI message. If the transaction is relayed by `CheckTx`, only stateless checks and fee-related stateful checks are performed. To better understand the difference between `DeliverTx`and `CheckTx`, as well as the difference between stateful and stateless checks, click [here](./tx-lifecycle.md). @@ -168,8 +162,6 @@ Handler functions return a result of type `sdk.Result`, which informs the applic +++ https://github.com/cosmos/cosmos-sdk/blob/7d7821b9af132b0f6131640195326aa02b6751db/types/result.go#L15-L40 -To learn more about handlers, [click here](../building-modules/handler.md). - ### Querier [`Queriers`](../building-modules/querier.md) are very similar to `handlers`, except they serve user queries to the state as opposed to processing transactions. A [query](../building-modules/messages-and-queries.md#queries) is initiated from an [interface](#interfaces) by an end-user who provides a `queryRoute` and some `data`. The query is then routed to the correct application's `querier` by `baseapp`'s `handleQueryCustom` method using `queryRoute`: @@ -180,9 +172,8 @@ The `Querier` of a module is defined in a file called `querier.go`, and consists - A **switch function** `NewQuerier` to route the query to the appropriate `querier` function. This function returns a `querier` function, and is is registered in the [`AppModule`](#application-module-interface) to be used in the application's module manager to initialize the [application's query router](../core/baseapp.md#query-routing). See an example of such a switch from the [nameservice tutorial](https://github.com/cosmos/sdk-tutorials/tree/master/nameservice): +++ https://github.com/cosmos/sdk-tutorials/blob/86a27321cf89cc637581762e953d0c07f8c78ece/nameservice/x/nameservice/internal/keeper/querier.go#L19-L32 -- - **One querier function for each data type defined by the module that needs to be queryable**. Developers write the query processing logic in these functions. This generally involves calling [`keeper`](#keeper)'s methods to query the state and marshalling it to JSON. +- **One querier function for each data type defined by the module that needs to be queryable**. Developers write the query processing logic in these functions. This generally involves calling [`keeper`](#keeper)'s methods to query the state and marshalling it to JSON. -To learn more about `queriers`, [click here](../building-modules/querier.md). ### Keeper @@ -198,35 +189,29 @@ The `keeper` type definition generally consists of: Along with the type definition, the next important component of the `keeper.go` file is the `keeper`'s constructor function, `NewKeeper`. This function instantiates a new `keeper` of the type defined above, with a `codec`, store `keys` and potentially references to other modules' `keeper`s as parameters. The `NewKeeper` function is called from the [application's constructor](#constructor-function). The rest of the file defines the `keeper`'s methods, primarily getters and setters. -To learn more about `keepers`, [click here](../building-modules/keeper.md). - ### Command-Line and REST Interfaces Each module defines command-line commands and REST routes to be exposed to end-user via the [application's interfaces](#application-interfaces). This enables end-users to create messages of the types defined in the module, or to query the subset of the state managed by the module. #### CLI -Generally, the commands related to a module are defined in a folder called `client/cli` in the module's folder. The CLI divides commands in two category, transactions and queries, defined in `client/cli/tx.go` and `client/cli/query.go` respectively. Both commands are built on top of the [Cobra Library](https://github.com/spf13/cobra): +Generally, the [commands related to a module](../building-modules/module-interfaces.md#cli) are defined in a folder called `client/cli` in the module's folder. The CLI divides commands in two category, transactions and queries, defined in `client/cli/tx.go` and `client/cli/query.go` respectively. Both commands are built on top of the [Cobra Library](https://github.com/spf13/cobra): - Transactions commands let users generate new transactions so that they can be included in a block and eventually update the state. One command should be created for each [message type](#message-types) defined in the module. The command calls the constructor of the message with the parameters provided by the end-user, and wraps it into a transaction. The SDK handles signing and the addition of other transaction metadata. - Queries let users query the subset of the state defined by the module. Query commands forward queries to the [application's query router](../core/baseapp.md#query-routing), which routes them to the appropriate [querier](#querier) the `queryRoute` parameter supplied. -To learn more about modules CLI, [click here](../building-modules/module-interfaces.md#cli). - #### REST -The module's REST interface lets users generate transactions and query the state through REST calls to the application's [light client daemon](../core/node.md#lcd) (LCD). REST routes are defined in a file `client/rest/rest.go`, which is composed of: +The [module's REST interface](../building-modules/module-interfaces.md#rest) lets users generate transactions and query the state through REST calls to the application's [light client daemon](../core/node.md#lcd) (LCD). REST routes are defined in a file `client/rest/rest.go`, which is composed of: - A `RegisterRoutes` function, which registers each route defined in the file. This function is called from the [main application's interface](#application-interfaces) for each module used within the application. The router used in the SDK is [Gorilla's mux](https://github.com/gorilla/mux). - Custom request type definitions for each query or transaction creation function that needs to be exposed. These custom request types build on the base `request` type of the Cosmos SDK: +++ https://github.com/cosmos/cosmos-sdk/blob/7d7821b9af132b0f6131640195326aa02b6751db/types/rest/rest.go#L47-L60 - One handler function for each request that can be routed to the given module. These functions implement the core logic necessary to serve the request. -To learn more about modules REST interface, [click here](../building-modules/module-interfaces.md#rest). - ## Application Interface -Interfaces let end-users interact with full-node clients. This means querying data from the full-node or creating and sending new transactions to be relayed by the full-node and eventually included in a block. +[Interfaces](../interfaces/interfaces-intro.md) let end-users interact with full-node clients. This means querying data from the full-node or creating and sending new transactions to be relayed by the full-node and eventually included in a block. The main interface is the [Command-Line Interface](../interfaces/cli.md). The CLI of an SDK application is built by aggregating [CLI commands](#cli) defined in each of the modules used by the application. The CLI of an application generally has the `-cli` suffix (e.g. `appcli`), and defined in a file called `cmd/appcli/main.go`. The file contains: @@ -239,8 +224,6 @@ See an example of an application's main command-line file from the [nameservice +++ https://github.com/cosmos/sdk-tutorials/blob/86a27321cf89cc637581762e953d0c07f8c78ece/nameservice/cmd/nscli/main.go -To learn more about interfaces, [click here](../interfaces/interfaces-intro.md). - ## Dependencies and Makefile This section is optional, as developers are free to choose their dependency manager and project building method. That said, the current most used framework for versioning control is [`go.mod`](https://github.com/golang/go/wiki/Modules). It ensures each of the libraries used throughout the application are imported with the correct version. See an example from the [nameservice tutorial](https://github.com/cosmos/sdk-tutorials/tree/master/nameservice): diff --git a/docs/intro/overview.md b/docs/intro/overview.md index e568eff6748e..94e6d3d6df40 100644 --- a/docs/intro/overview.md +++ b/docs/intro/overview.md @@ -16,7 +16,7 @@ One development paradigm in the blockchain world today is that of virtual-machin Application-specific blockchains offer a radically different development paradigm than virtual-machine blockchains. An application-specific blockchain is a blockchain customized to operate a single application: developers have all the freedom to make the design decisions required for the application to run optimally. They can also provide better sovereignty, security and performance. -To learn more about application-specific blockchains, [click here](./why-app-specific.md). +Learn more about [application-specific blockchains](./why-app-specific.md). ## Why the Cosmos SDK? @@ -25,7 +25,7 @@ The Cosmos SDK is the most advanced framework for building custom application-sp - The default consensus engine available within the SDK is [Tendermint Core](https://github.com/tendermint/tendermint). Tendermint is the most (and only) mature BFT consensus engine in existence. It is widely used across the industry and is considered the gold standard consensus engine for building Proof-of-Stake systems. - The SDK is open source and designed to make it easy to build blockchains out of composable [modules](../../x/). As the ecosystem of open source SDK modules grows, it will become increasingly easier to build complex decentralised platforms with it. - The SDK is inspired by capabilities-based security, and informed by years of wrestling with blockchain state-machines. This makes the Cosmos SDK a very secure environment to build blockchains. -- Most importantly, the Cosmos SDK has already been used to build many application-specific blockchains that are already in production. Among others, we can cite [Cosmos Hub](https://hub.cosmos.network), [IRIS Hub](https://irisnet.org), [Binance Chain](https://docs.binance.org/), [Terra](https://terra.money/) or [Lino](https://lino.network/). Many more are building on the Cosmos SDK. You can get a view of the ecosystem [here](https://cosmos.network/ecosystem). +- Most importantly, the Cosmos SDK has already been used to build many application-specific blockchains that are already in production. Among others, we can cite [Cosmos Hub](https://hub.cosmos.network), [IRIS Hub](https://irisnet.org), [Binance Chain](https://docs.binance.org/), [Terra](https://terra.money/) or [Lino](https://lino.network/). [Many more](https://cosmos.network/ecosystem) are building on the Cosmos SDK. ## Getting started with the Cosmos SDK diff --git a/docs/intro/sdk-app-architecture.md b/docs/intro/sdk-app-architecture.md index 5667e5c5d55c..4f4f0f3e9051 100644 --- a/docs/intro/sdk-app-architecture.md +++ b/docs/intro/sdk-app-architecture.md @@ -56,9 +56,9 @@ Blockchain node | | Consensus | | ``` -Tendermint is an application-agnostic engine that is responsible for handling the *networking* and *consensus* layers of a blockchain. In practice, this means that Tendermint is responsible for propagating and ordering transaction bytes. Tendermint Core relies on an eponymous Byzantine-Fault-Tolerant (BFT) algorithm to reach consensus on the order of transactions. For more on Tendermint, click [here](https://tendermint.com/docs/introduction/what-is-tendermint.html). +[Tendermint](https://tendermint.com/docs/introduction/what-is-tendermint.html) is an application-agnostic engine that is responsible for handling the *networking* and *consensus* layers of a blockchain. In practice, this means that Tendermint is responsible for propagating and ordering transaction bytes. Tendermint Core relies on an eponymous Byzantine-Fault-Tolerant (BFT) algorithm to reach consensus on the order of transactions. -The Tendermint consensus algorithm works with a set of special nodes called *Validators*. Validators are responsible for adding blocks of transactions to the blockchain. At any given block, there is a validator set V. A validator in V is chosen by the algorithm to be the proposer of the next block. This block is considered valid if more than two thirds of V signed a *[prevote](https://tendermint.com/docs/spec/consensus/consensus.html#prevote-step-height-h-round-r)* and a *[precommit](https://tendermint.com/docs/spec/consensus/consensus.html#precommit-step-height-h-round-r)* on it, and if all the transactions that it contains are valid. The validator set can be changed by rules written in the state-machine. For a deeper look at the algorithm, click [here](https://tendermint.com/docs/introduction/what-is-tendermint.html#consensus-overview). +The Tendermint [consensus algorithm](https://tendermint.com/docs/introduction/what-is-tendermint.html#consensus-overview) works with a set of special nodes called *Validators*. Validators are responsible for adding blocks of transactions to the blockchain. At any given block, there is a validator set V. A validator in V is chosen by the algorithm to be the proposer of the next block. This block is considered valid if more than two thirds of V signed a *[prevote](https://tendermint.com/docs/spec/consensus/consensus.html#prevote-step-height-h-round-r)* and a *[precommit](https://tendermint.com/docs/spec/consensus/consensus.html#precommit-step-height-h-round-r)* on it, and if all the transactions that it contains are valid. The validator set can be changed by rules written in the state-machine. ## ABCI @@ -90,7 +90,7 @@ Here are the most important messages of the ABCI: - `DeliverTx`: When a [valid block](https://tendermint.com/docs/spec/blockchain/blockchain.html#validation) is received by Tendermint Core, each transaction in the block is passed to the application via `DeliverTx` in order to be processed. It is during this stage that the state transitions occur. The `AnteHandler` executes again along with the actual [`handler`s](../building-modules/handler.md) for each message in the transaction. - `BeginBlock`/`EndBlock`: These messages are executed at the beginning and the end of each block, whether the block contains transaction or not. It is useful to trigger automatic execution of logic. Proceed with caution though, as computationally expensive loops could slow down your blockchain, or even freeze it if the loop is infinite. -For a more detailed view of the ABCI methods and types, click [here](https://tendermint.com/docs/spec/abci/abci.html#overview). +Find a more detailed view of the ABCI methods from the [Tendermint docs](https://tendermint.com/docs/spec/abci/abci.html#overview). Any application built on Tendermint needs to implement the ABCI interface in order to communicate with the underlying local Tendermint engine. Fortunately, you do not have to implement the ABCI interface. The Cosmos SDK provides a boilerplate implementation of it in the form of [baseapp](./sdk-design.md#baseapp). From c70539416de4a5236204c9ce3df9cbc8d6b45d88 Mon Sep 17 00:00:00 2001 From: gamarin Date: Mon, 9 Dec 2019 21:45:14 +0100 Subject: [PATCH 194/196] fix merge remants --- docs/architecture/README.md | 4 -- docs/building-modules/README.md | 78 --------------------------------- docs/intro/sdk-design.md | 8 ---- docs/package-lock.json | 11 ----- docs/package.json | 10 ----- docs/spec/README.md | 14 ------ 6 files changed, 125 deletions(-) diff --git a/docs/architecture/README.md b/docs/architecture/README.md index 712fd17cc715..f5b6a553305d 100644 --- a/docs/architecture/README.md +++ b/docs/architecture/README.md @@ -36,9 +36,5 @@ Please add a entry below in your Pull Request for an ADR. - [ADR 009: Evidence Module](./adr-009-evidence-module.md) - [ADR 010: Modular AnteHandler](./adr-010-modular-antehandler.md) - [ADR 011: Generalize Genesis Accounts](./adr-011-generalize-genesis-accounts.md) -<<<<<<< HEAD:docs/architecture/README.md -- [ADR 012: State Accessors](./adr-012-state-accessors.md) -======= - [ADR 012: State Accessors](./adr-012-state-accessors.md) - [ADR 017: Historical Header Module](./adr-017-historical-header-module.md) ->>>>>>> master:docs/architecture/README.MD diff --git a/docs/building-modules/README.md b/docs/building-modules/README.md index 0c084d536c10..732485c74477 100644 --- a/docs/building-modules/README.md +++ b/docs/building-modules/README.md @@ -1,4 +1,3 @@ -<<<<<<< HEAD --- order: false parent: @@ -21,80 +20,3 @@ This repository contains documentation on concepts developers need to know in or 10. [Module Interfaces](./module-interfaces.md) 11. [Standard Module Structure](./structure.md) -======= -# Modules - -## Auth - -The `x/auth` modules is used for accounts - -- [API docs](https://godoc.org/github.com/cosmos/cosmos-sdk/x/auth) -- [Specification](https://github.com/cosmos/cosmos-sdk/tree/master/docs/spec/auth) - -## Bank - -The `x/bank` module is for transferring coins between accounts. - -- [API docs](https://godoc.org/github.com/cosmos/cosmos-sdk/x/bank) -- [Specification](https://github.com/cosmos/cosmos-sdk/tree/master/docs/spec/bank) - -## Staking - -The `x/staking` module is for Cosmos Delegated-Proof-of-Stake. - -- [API docs](https://godoc.org/github.com/cosmos/cosmos-sdk/x/staking) -- [Specification](https://github.com/cosmos/cosmos-sdk/tree/master/docs/spec/staking) - -## Slashing - -The `x/slashing` module is for Cosmos Delegated-Proof-of-Stake. - -- [API docs](https://godoc.org/github.com/cosmos/cosmos-sdk/x/slashing) -- [Specification](https://github.com/cosmos/cosmos-sdk/tree/master/docs/spec/slashing) - -## Distribution - -The `x/distribution` module is for distributing fees and inflation across bonded -stakeholders. - -- [API docs](https://godoc.org/github.com/cosmos/cosmos-sdk/x/distribution) -- [Specification](https://github.com/cosmos/cosmos-sdk/tree/master/docs/spec/distribution) - -## Governance - -The `x/gov` module is for bonded stakeholders to make proposals and vote on them. - -- [API docs](https://godoc.org/github.com/cosmos/cosmos-sdk/x/gov) -- [Specification](https://github.com/cosmos/cosmos-sdk/tree/master/docs/spec/governance) - -To keep up with the current status of IBC, follow and contribute to [ICS](https://github.com/cosmos/ics) - -## Crisis - -The `x/crisis` module is for halting the blockchain under certain circumstances. - -- [API Docs](https://godoc.org/github.com/cosmos/cosmos-sdk/x/crisis) -- [Specification](https://github.com/cosmos/cosmos-sdk/blob/master/docs/spec/crisis) - -## Mint - -The `x/mint` module is for flexible inflation rates and effect a balance between market liquidity and staked supply. - -- [API Docs](https://godoc.org/github.com/cosmos/cosmos-sdk/x/mint) -- [Specification](https://github.com/cosmos/cosmos-sdk/blob/master/docs/spec/mint) - -## Params - -The `x/params` module provides a globally available parameter store. - -- [API Docs](https://godoc.org/github.com/cosmos/cosmos-sdk/x/params) -- [Specification](https://github.com/cosmos/cosmos-sdk/blob/master/docs/spec/params) - -## Evidence - -The `x/evidence` modules provides a mechanism for defining and submitting arbitrary -events of misbehavior and a means to execute custom business logic for such misbehavior. - -- [API Docs](https://godoc.org/github.com/cosmos/cosmos-sdk/x/evidence) -- [Specification](https://github.com/cosmos/cosmos-sdk/blob/master/docs/spec/evidence) ->>>>>>> master diff --git a/docs/intro/sdk-design.md b/docs/intro/sdk-design.md index a13fa3d497aa..0b4f9689f6ed 100644 --- a/docs/intro/sdk-design.md +++ b/docs/intro/sdk-design.md @@ -80,11 +80,7 @@ Here is a simplified view of how a transaction is processed by the application o v ``` -<<<<<<< HEAD Each module can be seen as a little state-machine. Developers need to define the subset of the state handled by the module, as well as custom message types that modify the state (*Note:* `messages` are extracted from `transactions` by `baseapp`). In general, each module declares its own `KVStore` in the `multistore` to persist the subset of the state it defines. Most developers will need to access other 3rd party modules when building their own modules. Given that the Cosmos-SDK is an open framework, some of the modules may be malicious, which means there is a need for security principles to reason about inter-module interactions. These principles are based on [object-capabilities](../core/ocap.md). In practice, this means that instead of having each module keep an access control list for other modules, each module implements special objects called `keepers` that can be passed to other modules to grant a pre-defined set of capabilities. -======= -Each module can be seen as a little state-machine. Developers need to define the subset of the state handled by the module, as well as custom message types that modify the state (*Note:* `messages` are extracted from `transactions` using `baseapp`). In general, each module declares its own `KVStore` in the multistore to persist the subset of the state it defines. Most developers will need to access other 3rd party modules when building their own modules. Given that the Cosmos-SDK is an open framework, some of the modules may be malicious, which means there is a need for security principles to reason about inter-module interactions. These principles are based on [object-capabilities](../core/ocap.md). In practice, this means that instead of having each module keep an access control list for other modules, each module implements special objects called `keepers` that can be passed to other modules to grant a pre-defined set of capabilities. ->>>>>>> master SDK modules are defined in the `x/` folder of the SDK. Some core modules include: @@ -98,7 +94,3 @@ In addition to the already existing modules in `x/`, that anyone can use in thei Learn more about the [anatomy of an SDK application](../basics/app-anatomy.md) {hide} -<<<<<<< HEAD -======= -### Next, learn more about the security model of the Cosmos SDK, [ocap](../core/ocap.md) ->>>>>>> master diff --git a/docs/package-lock.json b/docs/package-lock.json index ed0767deb598..1100a982c2a5 100644 --- a/docs/package-lock.json +++ b/docs/package-lock.json @@ -5370,16 +5370,9 @@ } }, "lodash": { -<<<<<<< HEAD "version": "4.17.15", "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.15.tgz", "integrity": "sha512-8xOcRHvCjnocdS5cpwXQXVzmmh5e5+saE2QGoeQmbKmRS6J3VQppPOIt0MnmE+4xlZoumy0GPG0D0MVIQbNA1A==" -======= - "version": "4.17.13", - "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.13.tgz", - "integrity": "sha512-vm3/XWXfWtRua0FkUyEHBZy8kCPjErNBT9fJx8Zvs+U6zjqPbTUOpkaoum3O5uiA8sm+yNMHXfYkTUHFoMxFNA==", - "dev": true ->>>>>>> master }, "lodash._reinterpolate": { "version": "3.0.0", @@ -5425,10 +5418,6 @@ "version": "4.5.0", "resolved": "https://registry.npmjs.org/lodash.template/-/lodash.template-4.5.0.tgz", "integrity": "sha512-84vYFxIkmidUiFxidA/KjjH9pAycqW+h980j7Fuz5qxRtO9pgB7MDFTdys1N7A5mcucRiDyEq4fusljItR1T/A==", -<<<<<<< HEAD -======= - "dev": true, ->>>>>>> master "requires": { "lodash._reinterpolate": "^3.0.0", "lodash.templatesettings": "^4.0.0" diff --git a/docs/package.json b/docs/package.json index 11992f679d7b..a8d32367076f 100644 --- a/docs/package.json +++ b/docs/package.json @@ -13,16 +13,6 @@ }, "author": "", "license": "ISC", -<<<<<<< HEAD -======= - "devDependencies": { - "@vuepress/plugin-google-analytics": "^1.2.0", - "lodash": "^4.17.13", - "markdown-it": "^8.4.2", - "markdown-it-meta": "0.0.1", - "vuepress": "^1.0.2" - }, ->>>>>>> master "dependencies": { "vuepress-theme-cosmos": "^1.0.93" } diff --git a/docs/spec/README.md b/docs/spec/README.md index ccf28043623c..2dd2321be23c 100644 --- a/docs/spec/README.md +++ b/docs/spec/README.md @@ -18,23 +18,9 @@ block. ## Modules specifications -<<<<<<< HEAD Go the [module directory](../../x/README.md) ## Tendermint -======= -- [Auth](../../x/auth/spec) - The structure and authentication of accounts and transactions. -- [Bank](../../x/bank/spec) - Sending tokens. -- [Governance](../../x/gov/spec) - Proposals and voting. -- [Staking](../../x/staking/spec) - Proof-of-stake bonding, delegation, etc. -- [Slashing](../../x/slashing/spec) - Validator punishment mechanisms. -- [Distribution](../../x/distribution/spec) - Fee distribution, and staking token provision distribution. -- [Crisis](.../../x/crisis/spec) - Halting the blockchain under certain circumstances. -- [Mint](../../x/mint/spec) - Staking token provision creation. -- [Params](../../x/params/spec) - Globally available parameter store. -- [Supply](../../x/supply/spec) - Total supply of the chain. -- [NFT](https://github.com/cosmos/modules/tree/master/incubator/nft/docs/spec) - Non-fungible tokens. ->>>>>>> master For details on the underlying blockchain and p2p protocols, see the [Tendermint specification](https://github.com/tendermint/tendermint/tree/master/docs/spec). From cfba8359e139ab2efe191b3dec192fc803eef9ff Mon Sep 17 00:00:00 2001 From: gamarin Date: Tue, 10 Dec 2019 13:47:23 +0100 Subject: [PATCH 195/196] changelog 1/2 --- CHANGELOG.md | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 10436fa612b2..5c25732789ed 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -194,6 +194,13 @@ caching through `CommitKVStoreCacheManager`. Any application wishing to utilize must set it in their app via a `BaseApp` option. The `BaseApp` docs have been drastically improved to detail this new feature and how state transitions occur. * (docs/spec) All module specs moved into their respective module dir in x/ (i.e. docs/spec/staking -->> x/staking/spec) +* (docs/) [\#5379](https://github.com/cosmos/cosmos-sdk/pull/5379) Major documentation refactor, including: + * (docs/intro/) Add and improve introduction material for newcomers. + * (docs/basics/) Add documentation about basic concepts of the cosmos sdk such as the anatomy of an SDK application, the transaction lifecycle or accounts. + * (docs/core/) Add documentation about core conepts of the cosmos sdk such as `baseapp`, `server`, `store`s, `context` and more. + * (docs/building-modules/) Add reference documentation on concepts relevant for module developers (`keeper`, `handler`, `messages`, `queries`,...). + * (docs/interfaces/) Add documentation on building interfaces for the Cosmos SDK. + ### Bug Fixes @@ -206,6 +213,8 @@ to detail this new feature and how state transitions occur. * (baseapp) [\#5350](https://github.com/cosmos/cosmos-sdk/issues/5350) Allow a node to restart successfully after a `halt-height` or `halt-time` has been triggered. + + ## [v0.37.4] - 2019-11-04 ### Improvements From d34481bd8509f8519f2db7c351b6bb7a4512c908 Mon Sep 17 00:00:00 2001 From: Denis Fadeev Date: Tue, 10 Dec 2019 18:01:15 +0500 Subject: [PATCH 196/196] Changelog: docs UI --- CHANGELOG.md | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 5c25732789ed..44fcf198b728 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -199,7 +199,8 @@ to detail this new feature and how state transitions occur. * (docs/basics/) Add documentation about basic concepts of the cosmos sdk such as the anatomy of an SDK application, the transaction lifecycle or accounts. * (docs/core/) Add documentation about core conepts of the cosmos sdk such as `baseapp`, `server`, `store`s, `context` and more. * (docs/building-modules/) Add reference documentation on concepts relevant for module developers (`keeper`, `handler`, `messages`, `queries`,...). - * (docs/interfaces/) Add documentation on building interfaces for the Cosmos SDK. + * (docs/interfaces/) Add documentation on building interfaces for the Cosmos SDK. + * Redesigned user interface that features new dynamically generated sidebar, build-time code embedding from GitHub, new homepage as well as many other improvements. ### Bug Fixes