From 9cdbe493fb4da541edbd821ba3774d00db7de24d Mon Sep 17 00:00:00 2001 From: Adrian Brink Date: Tue, 10 Jul 2018 13:48:43 +0200 Subject: [PATCH 01/39] Finalise LCD spec --- docs/spec/light/api.md | 391 ++++++++++++++++++ docs/spec/light/getting_started.md | 40 ++ docs/spec/light/load_balancer.md | 203 +++++++++ docs/spec/light/overview.md | 55 +++ docs/spec/light/pics/C2H.png | Bin 0 -> 17324 bytes docs/spec/light/pics/H2C.png | Bin 0 -> 20012 bytes docs/spec/light/pics/MA.png | Bin 0 -> 31774 bytes docs/spec/light/pics/absence1.png | Bin 0 -> 97697 bytes docs/spec/light/pics/absence2.png | Bin 0 -> 31717 bytes docs/spec/light/pics/absence3.png | Bin 0 -> 28517 bytes docs/spec/light/pics/architecture.png | Bin 0 -> 30539 bytes docs/spec/light/pics/changeProcess.png | Bin 0 -> 8919 bytes docs/spec/light/pics/commitValidation.png | Bin 0 -> 64713 bytes docs/spec/light/pics/create-account.png | Bin 0 -> 21826 bytes docs/spec/light/pics/deposit.png | Bin 0 -> 20738 bytes docs/spec/light/pics/existProof.png | Bin 0 -> 96053 bytes docs/spec/light/pics/high-level.png | Bin 0 -> 11595 bytes .../light/pics/light-client-architecture.png | Bin 0 -> 24816 bytes docs/spec/light/pics/loadbalanceDiagram.png | Bin 0 -> 34910 bytes docs/spec/light/pics/simpleMerkleTree.png | Bin 0 -> 24768 bytes docs/spec/light/pics/substoreProof.png | Bin 0 -> 62165 bytes docs/spec/light/pics/transfer-tokens.png | Bin 0 -> 26410 bytes docs/spec/light/pics/transfer.png | Bin 0 -> 18492 bytes docs/spec/light/pics/trustPropagate.png | Bin 0 -> 49750 bytes .../light/pics/updateValidatorToHeight.png | Bin 0 -> 18077 bytes docs/spec/light/pics/validatorSetChange.png | Bin 0 -> 36169 bytes docs/spec/light/pics/withdraw.png | Bin 0 -> 20935 bytes docs/spec/light/readme.md | 101 +++++ docs/spec/light/specification.md | 318 ++++++++++++++ docs/spec/light/todo.md | 16 + 30 files changed, 1124 insertions(+) create mode 100644 docs/spec/light/api.md create mode 100644 docs/spec/light/getting_started.md create mode 100644 docs/spec/light/load_balancer.md create mode 100644 docs/spec/light/overview.md create mode 100644 docs/spec/light/pics/C2H.png create mode 100644 docs/spec/light/pics/H2C.png create mode 100644 docs/spec/light/pics/MA.png create mode 100755 docs/spec/light/pics/absence1.png create mode 100755 docs/spec/light/pics/absence2.png create mode 100755 docs/spec/light/pics/absence3.png create mode 100644 docs/spec/light/pics/architecture.png create mode 100755 docs/spec/light/pics/changeProcess.png create mode 100755 docs/spec/light/pics/commitValidation.png create mode 100644 docs/spec/light/pics/create-account.png create mode 100644 docs/spec/light/pics/deposit.png create mode 100755 docs/spec/light/pics/existProof.png create mode 100644 docs/spec/light/pics/high-level.png create mode 100644 docs/spec/light/pics/light-client-architecture.png create mode 100644 docs/spec/light/pics/loadbalanceDiagram.png create mode 100755 docs/spec/light/pics/simpleMerkleTree.png create mode 100755 docs/spec/light/pics/substoreProof.png create mode 100644 docs/spec/light/pics/transfer-tokens.png create mode 100644 docs/spec/light/pics/transfer.png create mode 100755 docs/spec/light/pics/trustPropagate.png create mode 100755 docs/spec/light/pics/updateValidatorToHeight.png create mode 100755 docs/spec/light/pics/validatorSetChange.png create mode 100644 docs/spec/light/pics/withdraw.png create mode 100644 docs/spec/light/readme.md create mode 100644 docs/spec/light/specification.md create mode 100644 docs/spec/light/todo.md diff --git a/docs/spec/light/api.md b/docs/spec/light/api.md new file mode 100644 index 000000000..4dc2619a3 --- /dev/null +++ b/docs/spec/light/api.md @@ -0,0 +1,391 @@ +# Cosmos Hub (Gaia) LCD API + +This document describes the API that is exposed by the specific LCD implementation of the Cosmos +Hub (Gaia). Those APIs are exposed by a REST server and can easily be accessed over HTTP/WS(websocket) +connections. + +The complete API is comprised of the sub-APIs of different modules. The modules in the Cosmos Hub +(Gaia) API are: + +* ICS0 (TendermintAPI) +* ICS1 (KeyAPI) +* ICS20 (TokenAPI) +* ICS21 (StakingAPI) - not yet implemented +* ICS22 (GovernanceAPI) - not yet implemented + +Error messages my change and should be only used for display purposes. Error messages should not be +used for determining the error type. + +## ICS0 - TendermintAPI - not yet implemented + +Exposes the same functionality as the Tendermint RPC from a full node. It aims to have a very +similar API. + +### /broadcast_tx_sync - POST + +url: /broadcast_tx_sync + +Functionality: Submit a signed transaction and wait for it to be committed. + +Parameters: +| Parameter | Type | Default | Required | Description | +| ----------- | ------ | ------- | -------- | --------------- | +| transaction | string | null | true | signed tx bytes | + +Returns on success: + +```json +{ + "rest api": "2.0", + "code":200, + "error": "", + "result": { + "code": 0, + "hash": "0D33F2F03A5234F38706E43004489E061AC40A2E", + "data": "", + "log": "" + } +} +``` + +Returns on failure: + +```json +{ + "rest api": "2.0", + "code":500, + "error": "Could not submit the transaction synchronously.", + "result": {} +} +``` + +### /broadcast_tx_async - POST + +url: /broadcast_tx_async + +Functionality: Submit a signed transaction asynchronously. + +Parameters: +| Parameter | Type | Default | Required | Description | +| ----------- | ------ | ------- | -------- | --------------- | +| transaction | string | null | true | signed tx bytes | + +Returns on success: + +```json +{ + "rest api": "2.0", + "code":200, + "error": "", + "result": { + "code": 0, + "hash": "E39AAB7A537ABAA237831742DCE1117F187C3C52", + "data": "", + "log": "" + } +} +``` + +Returns on failure: + +```json +{ + "rest api": "2.0", + "code":500, + "error": "Could not submit the transaction asynchronously.", + "result": {} +} +``` + +## ICS1 - KeyAPI + +This API exposes all functionality needed for key creation, signing and management. + +### /keys - GET + +url: /keys + +Functionality: Gets a list of all the keys. + +Returns on success: + +```json +{ + "rest api": "2.0", + "code":200, + "error": "", + "result": { + "keys": [ + { + "name": "monkey", + "address": "cosmosaccaddr1fedh326uxqlxs8ph9ej7cf854gz7fd5zlym5pd", + "pub_key": "cosmosaccpub1zcjduc3q8s8ha96ry4xc5xvjp9tr9w9p0e5lk5y0rpjs5epsfxs4wmf72x3shvus0t" + }, + { + "name": "test", + "address": "cosmosaccaddr1thlqhjqw78zvcy0ua4ldj9gnazqzavyw4eske2", + "pub_key": "cosmosaccpub1zcjduc3qyx6hlf825jcnj39adpkaxjer95q7yvy25yhfj3dmqy2ctev0rxmse9cuak" + } + ], + "block_height": 5241 + } +} +``` + +Returns on failure: + +```json +{ + "rest api": "2.0", + "code":500, + "error":"Could not retrieve the keys.", + "result":{} +} +``` + +### /keys/recover - POST + +url: /keys/recover + +Functionality: Recover your key from seed and persist it encrypted with the password. + +Parameter: +| Parameter | Type | Default | Required | Description | +| --------- | ------ | ------- | -------- | ---------------- | +| name | string | null | true | name of key | +| password | string | null | true | password of key | +| seed | string | null | true | seed of key | + +Returns on success: + +```json +{ + "rest api": "2.0", + "code":200, + "error": "", + "result": { + "address":BD607C37147656A507A5A521AA9446EB72B2C907 + } +} +``` + +Returns on failure: + +```json +{ + "rest api": "2.0", + "code":500, + "error": "Could not recover the key.", + "result": {} +} +``` + +### /keys/create - POST + +url: /keys/create + +Functionality: Create a new key. + +Parameter: +| Parameter | Type | Default | Required | Description | +| --------- | ------ | ------- | -------- | ---------------- | +| name | string | null | true | name of key | +| password | string | null | true | password of key | + +Returns on success: + +```json +{ + "rest api": "2.0", + "code":200, + "error": "", + "result": { + "seed":crime carpet recycle erase simple prepare moral dentist fee cause pitch trigger when velvet animal abandon + } +} +``` + +Returns on failure: + +```json +{ + "rest api": "2.0", + "code":500, + "error": "Could not create new key.", + "result": {} +} +``` + +### /keys/{name} - GET + +url: /keys/{name} + +Functionality: Get the information for the specified key. + +Returns on success: + +```json +{ + "rest api": "2.0", + "code":200, + "error": "", + "result": { + "name": "test", + "address": "cosmosaccaddr1thlqhjqw78zvcy0ua4ldj9gnazqzavyw4eske2", + "pub_key": "cosmosaccpub1zcjduc3qyx6hlf825jcnj39adpkaxjer95q7yvy25yhfj3dmqy2ctev0rxmse9cuak" + } +} +``` + +Returns on failure: + +```json +{ + "rest api": "2.0", + "code":500, + "error": "Could not find information on the specified key.", + "result": {} +} +``` + +### /keys/{name} - PUT + +url: /keys/{name} + +Functionality: Change the encryption password for the specified key. + +Parameters: +| Parameter | Type | Default | Required | Description | +| --------------- | ------ | ------- | -------- | --------------- | +| old_password | string | null | true | old password | +| new_password | string | null | true | new password | + +Returns on success: + +```json +{ + "rest api": "2.0", + "code":200, + "error": "", + "result": {} +} +``` + +Returns on failure: + +```json +{ + "rest api": "2.0", + "code":500, + "error": "Could not update the specified key.", + "result": {} +} +``` + +### /keys/{name} - DELETE + +url: /keys/{name} + +Functionality: Delete the specified key. + +Parameters: +| Parameter | Type | Default | Required | Description | +| --------- | ------ | ------- | -------- | ---------------- | +| password | string | null | true | password of key | + +Returns on success: + +```json +{ + "rest api": "2.0", + "code":200, + "error": "", + "result": {} +} +``` + +Returns on failure: + +```json +{ + "rest api": "2.0", + "code":500, + "error": "Could not delete the specified key.", + "result": {} +} +``` + +## ICS20 - TokenAPI + +The TokenAPI exposes all functionality needed to query account balances and send transactions. + +### /bank/balance/{account} - GET + +url: /bank/balance/{account} + +Functionality: Query the specified account. + +Returns on success: + +```json +{ + "rest api": "2.0", + "code":200, + "error": "", + "result": { + "atom": 1000, + "photon": 500, + "ether": 20 + } +} +``` + +Returns on error: + +```json +{ + "rest api": "2.0", + "code":500, + "error": "Could not find any balance for the specified account.", + "result": {} +} +``` + +### /bank/create_transfer - POST + +url: /bank/create_transfer + +Functionality: Create a transfer in the bank module. + +Parameters: +| Parameter | Type | Default | Required | Description | +| ------------ | ------ | ------- | -------- | ------------------------- | +| sender | string | null | true | Address of sender | +| receiver | string | null | true | address of receiver | +| chain_id | string | null | true | chain id | +| amount | int | null | true | amount of the token | +| denomonation | string | null | true | denomonation of the token | + +Returns on success: + +```json +{ + "rest api": "2.0", + "code":200, + "error": "", + "result": { + "transaction": "TODO:" + } +} +``` + +Returns on failure: + +```json +{ + "rest api": "2.0", + "code":500, + "error": "Could not create the transaction.", + "result": {} +} +``` diff --git a/docs/spec/light/getting_started.md b/docs/spec/light/getting_started.md new file mode 100644 index 000000000..1856372c8 --- /dev/null +++ b/docs/spec/light/getting_started.md @@ -0,0 +1,40 @@ +# Getting Started + +To start a rest server, we need to specify the following parameters: +| Parameter | Type | Default | Required | Description | +| ----------- | --------- | ----------------------- | -------- | ---------------------------------------------------- | +| chain-id | string | null | true | chain id of the full node to connect | +| node | URL | "tcp://localhost:46657" | true | address of the full node to connect | +| laddr | URL | "tcp://localhost:1317" | true | address to run the rest server on | +| trust-node | bool | "false" | true | Whether this LCD is connected to a trusted full node | +| trust-store | DIRECTORY | "$HOME/.lcd" | false | directory for save checkpoints and validator sets | + +Sample command: + +```bash +gaiacli light-client --chain-id=test --laddr=tcp://localhost:1317 --node tcp://localhost:46657 --trust-node=false +``` + +## Gaia Light Use Cases + +LCD could be very helpful for related service providers. For a wallet service provider, LCD could +make transaction faster and more reliable in the following cases. + +### Create an account + +![deposit](https://github.com/irisnet/cosmos-sdk/raw/bianjie/lcd_spec/docs/spec/lcd/pics/create-account.png) + +First you need to get a new seed phrase :[get-seed](https://github.com/irisnet/cosmos-sdk/blob/bianjie/lcd_spec/docs/spec/lcd/api.md#keysseed---get) + +After having new seed, you could generate a new account with it : [keys](https://github.com/irisnet/cosmos-sdk/blob/bianjie/lcd_spec/docs/spec/lcd/api.md#keys---post) + +### Transfer a token + +![transfer](https://github.com/irisnet/cosmos-sdk/raw/bianjie/lcd_spec/docs/spec/lcd/pics/transfer-tokens.png) + +The first step is to build an asset transfer transaction. Here we can post all necessary parameters +to /create_transfer to get the unsigned transaction byte array. Refer to this link for detailed +operation: [build transaction](https://github.com/irisnet/cosmos-sdk/blob/bianjie/lcd_spec/docs/spec/lcd/api.md#create_transfer---post) + +Then sign the returned transaction byte array with users' private key. Finally broadcast the signed +transaction. Refer to this link for how to broadcast the signed transaction: [broadcast transaction](https://github.com/irisnet/cosmos-sdk/blob/bianjie/lcd_spec/docs/spec/lcd/api.md#create_transfer---post) diff --git a/docs/spec/light/load_balancer.md b/docs/spec/light/load_balancer.md new file mode 100644 index 000000000..b3ba212ed --- /dev/null +++ b/docs/spec/light/load_balancer.md @@ -0,0 +1,203 @@ +# Load Balancing Module + +The LCD will be an important bridge between service providers and cosmos blockchain network. Suppose +a service provider wants to monitor token information for millions of accounts. Then it has to keep +sending a large mount of requests to LCD to query token information. As a result, LCD will send huge +requests to full node to get token information and necessary proof which will cost full node much +computing and bandwidth resource. Too many requests to a single full node may result in some bad +situations: + +```text +1. The full node crash possibility increases. +2. The reply delay increases. +3. The system reliability will decrease. +4. As the full node may belong to other people or associates, they may deny too frequent access from a single client. +``` + +It is very urgent to solve this problems. Here we consider to import load balancing into LCD. By the +help of load balancing, LCD can distribute millions of requests to a set of full nodes. Thus the +load of each full node won't be too heavy and the unavailable full nodes will be wiped out of query +list. In addition, the system reliability will increase. + +## Design + +This module need combine with client to realize the real load balancing. It can embed the +[HTTP Client](https://github.com/tendermint/tendermint/rpc/lib/client/httpclient.go). In other +words,we realise the new httpclient based on `HTTP`. + +```go +type HTTPLoadBalancer struct { + rpcs map[string]*rpcclient.JSONRPCClient + *WSEvents +} +``` + +## The Diagram of LCD RPC WorkFlow with LoadBalance + +![The Diagram of LCD RPC WorkFlow](pics/loadbalanceDiagram.png) + +In the above sequence diagram, application calls the `Request()`, and LCD finally call the +`HTTP.Request()` through the SecureClient `Wrapper`. In every `HTTP.Request()`, `Getclient()` +selects the current working rpcclient by the load balancing algorithm,then run the +`JSONRPCClient.Call()` to request from the Full Node, finally `UpdateClient()` updates the weight of + the current rpcclient according to the status that is returned by the full node. The `GetAddr()` + and `UpdateAddrWeight()` are realized in the load balancing module. + +There are some abilities to do: + +* Add the Remote Address +* Delete the Remote Address +* Update the weights of the addresses + +## Load balancing Strategies + +We can design some strategies like nginx to combine the different load balancing algorithms to get +the final remote. We can also get the status of the remote server to add or delete the addresses and + update weights of the addresses. + +In a word,it can make the entire LCD work more effective in actual conditions. +We are working this module independently in this [Github Repository](https://github.com/MrXJC/GoLoadBalance). + +## Interface And Type + +### Balancer + +This interface `Balancer`is the core of the package. Every load balancing algorithm should realize +it,and it defined two interfaces. + +* `init` initialize the balancer, assigns the variables which `DoBalance` needs. +* `DoBalance` load balance the full node addresses according to the current situation. + +```go +package balance + +type Balancer interface { + init(NodeAddrs) + DoBalance(NodeAddrs) (*NodeAddr,int,error) +} +``` + +### NodeAddr + +* host: ip address +* port: the number of port +* weight: the weight of this full node address,default:1 + +This NodeAddr is the base struct of the address. + +```go +type NodeAddr struct{ + host string + port int + weight int +} + +func (p *NodeAddr) GetHost() string + +func (p *NodeAddr) GetPort() int + +func (p *NodeAddr) GetWeight() int + +func (p *NodeAddr) updateWeight(weight int) +``` + +The `weight` is the important factor that schedules which full node the LCD calls. The weight can be +changed by the information from the full node. So we have the function `updateWegiht`. + +### NodeAddrs + +>in `balance/types.go` + +`NodeAddrs` is the list of the full node address. This is the member variable in the +BalanceManager(`BalancerMgr`). + +```go +type NodeAddrs []*NodeAddr +``` + +## Load Balancing Algorithm + +### Random + +>in `balance/random.go` + +Random algorithm selects a remote address randomly to process the request. The probability of them +being selected is the same. + +### RandomWeight + +>in `balance/random.go` + +RandomWeight Algorithm also selects a remote address randomly to process the request. But the higher +the weight, the greater the probability. + +### RoundRobin + +>in `balance/roundrobin.go` + +RoundRobin Algorithm selects a remote address orderly. Every remote address have the same +probability to be selected. + +### RoundRobinWeight + +>in `balance/roundrobin.go` + +RoundRobinWeight Algorthm selects a remote address orderly. But every remote address have different +probability to be selected which are determined by their weight. + +### Hash + +//TODO + +## Load Balancing Manager + +### BalanceMgr + +>in `balance/manager.go` + +* addrs: the set of the remote full node addresses +* balancers: map the string of balancer name to the specific balancer +* change: record whether the machine reinitialize after the `addrs` changes + +`BalanceMgr` is the manager of many balancer. It is the access of load balancing. Its main function +is to maintain the `NodeAddrs` and to call the specific load balancing algorithm above. + +```go +type BalanceMgr struct{ + addrs NodeAddrs + balancers map[string]Balancer + change map[string]bool +} + +func (p *BalanceMgr) RegisterBalancer(name string,balancer Balancer) + +func (p *BalanceMgr) updateBalancer(name string) + +func (p *BalanceMgr) AddNodeAddr(addr *NodeAddr) + +func (p *BalanceMgr) DeleteNodeAddr(i int) + +func (p *BalanceMgr) UpdateWeightNodeAddr(i int,weight int) + +func (p *BalanceMgr) GetAddr(name string)(*NodeAddr,int,error) { + // if addrs change,update the balancer which we use. + if p.change[name]{ + p.updateBalancer(name) + } + + // get the balancer by name + balancer := p.balancers[name] + + // use the load balancing algorithm + addr,index,err := balancer.DoBalance(p.addrs) + + return addr,index,err +} +``` + +* `RegisterBalancer`: register the basic balancer implementing the `Balancer` interface and initialize them. +* `updateBalancer`: update the specific balancer after the `addrs` change. +* `AddNodeAddr`: add the remote address and set all the values of the `change` to true. +* `DeleteNodeAddr`: delete the remote address and set all the values of the `change` to true. +* `UpdateWeightNodeAddr`: update the weight of the remote address and set all the values of the `change` to true. +* `GetAddr`:select the address by the balancer the `name` decides. diff --git a/docs/spec/light/overview.md b/docs/spec/light/overview.md new file mode 100644 index 000000000..82cf542ea --- /dev/null +++ b/docs/spec/light/overview.md @@ -0,0 +1,55 @@ +# Overview + +## What is a Light Client? + + The LCD is split into two separate components. The first component is generic for any Tendermint based application. It handles the security and connectivity aspects of following the header chain and verify proofs from full nodes against locally trusted validator set. Furthermore it exposes exactly the same API as any Tendermint Core node. The second component is specific for the Cosmos Hub (Gaiad). It works as a query endpoint and exposes the application specific functionality, which can be arbitrary. All queries against the application state have to go through the query endpoint. The advantage of the query endpoint is that it can verify the proofs that the application returns. + +## High-Level Architecture + +An application developer that would like to build a third party integration can ship his application with the LCD for the Cosmos Hub (or any other zone) and only needs to initialise it. Afterwards his application can interact with the zone as if it was running against a full node. + +![high-level](https://github.com/irisnet/cosmos-sdk/raw/bianjie/lcd_spec/docs/spec/lcd/pics/high-level.png) + +An application developer that wants to build an third party application for the Cosmos Hub (or any other zone) should build it against it's canonical API. That API is a combination of multiple parts. All zones have to expose ICS0 (TendermintAPI). Beyond that any zone is free to choose any combination of module APIs, depending on which modules the state machine uses. The Cosmos Hub will initially support ICS0 (TendermintAPI), ICS1 (KeyAPI), ICS20 (TokenAPI), ICS21 (StakingAPI) and ICS22 (GovernanceAPI). + +All applications are expected to only run against the LCD. The LCD is the only piece of software that offers stability guarantees around the zone API. + +### Comparision + +A full node of ABCI is different from its light client in the following ways: + +|| Full Node | LCD | Description| +|-| ------------- | ----- | -------------- | +| Execute and verify transactions|Yes|No|Full node will execute and verify all transactions while LCD won't| +| Verify and save blocks|Yes|No|Full node will verify and save all blocks while LCD won't| +| Participate consensus| Yes|No|Only when the full node is a validtor, it will participate consensus. LCD nodes never participate consensus| +| Bandwidth cost|Huge|Little|Full node will receive all blocks. if the bandwidth is limited, it will fall behind the main network. What's more, if it happens to be a validator,it will slow down the consensus process. LCD requires little bandwidth. Only when serving local request, it will cost bandwidth| +| Computing resource|Huge|Little|Full node will execute all transactions and verify all blocks which require much computing resource| +| Storage resource|Huge|Little|Full node will save all blocks and ABCI states. LCD just saves validator sets and some checkpoints| +| Power consume|Huge|Little|Full nodes have to be deployed on machines which have high performance and will be running all the time. So power consume will be huge. LCD can be deployed on the same machines as users' applications, or on independent machines but with poor performance. Besides, LCD can be shutdown anytime when necessary. So LCD only consume very little power, even mobile devices can meet the power requirement| +| Provide APIs|All cosmos APIs|Modular APIs|Full node supports all cosmos APIs. LCD provides modular APIs according to users' configuration| +| Secuity level| High|High|Full node will verify all transactions and blocks by itself. LCD can't do this, but it can query any data from other full nodes and verify the data independently. So both full node and LCD don't need to trust any third nodes, they all can achieve high security| + +According to the above table, LCD can meet all users' functionality and security requirements, but only requires little resource on bandwidth, computing, storage and power. + +## How does LCD achieve high security? + +### Trusted validator set + +The base design philosophy of lcd follows the two rules: + +1. **Doesn't trust any blockchin nodes, including validator nodes and other full nodes** +2. **Only trusts the whole validator set** + +The original trusted validator set should be prepositioned into its trust store, usually this validator set comes from genesis file. During running time, if LCD detects different validator set, it will verify it and save new validated validator set to trust store. + +![validator-set-change](https://github.com/irisnet/cosmos-sdk/raw/bianjie/lcd_spec/docs/spec/lcd/pics/validatorSetChange.png) + + +### Trust propagation + +From the above section, we come to know how to get trusted validator set and how lcd keeps track of validator set evolution. Validator set is the foundation of trust, and the trust can propagate to other blockchain data, such as block and transaction. The propagate architecture is shown as follows: + +![change-process](https://github.com/irisnet/cosmos-sdk/raw/bianjie/lcd_spec/docs/spec/lcd/pics/trustPropagate.png) + +In general, by trusted validator set, LCD can verify each block commit which contains all pre-commit data and block header data. Then the block hash, data hash and appHash are trusted. Based on this and merkle proof, all transactions data and ABCI states can be verified too. Detailed implementation will be posted on technical specification. diff --git a/docs/spec/light/pics/C2H.png b/docs/spec/light/pics/C2H.png new file mode 100644 index 0000000000000000000000000000000000000000..49f7e07f320ebf40829556d168f45cc0f43daf6d GIT binary patch literal 17324 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 a{n&+RG4;Gs8|xYPCnYW~Rv}{W@qYoAmxHtb literal 0 HcmV?d00001 diff --git a/docs/spec/light/pics/H2C.png b/docs/spec/light/pics/H2C.png new file mode 100644 index 0000000000000000000000000000000000000000..027eafcde1f4f0779e6614acbd42e72a2628a78f GIT binary patch literal 20012 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 X`?u`l20X!A;9z7V6vfL#jXwN;zxS{Y literal 0 HcmV?d00001 diff --git a/docs/spec/light/pics/MA.png b/docs/spec/light/pics/MA.png new file mode 100644 index 0000000000000000000000000000000000000000..ae38239628554d6c2e8fac48b5eed77bceeaf5ec GIT binary patch literal 31774 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 literal 0 HcmV?d00001 diff --git a/docs/spec/light/pics/absence1.png b/docs/spec/light/pics/absence1.png new file mode 100755 index 0000000000000000000000000000000000000000..70b4c9e8d22753b506682086f11e442a7441cbb5 GIT binary patch literal 97697 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

3lE(0~5)&o^Fq;k9fm>rMfA^yRsE{JL7~ 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

aD}wU94-=NdKwuYnfXBd=y@ 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

MFm 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 literal 0 HcmV?d00001 diff --git a/docs/spec/light/pics/absence2.png b/docs/spec/light/pics/absence2.png new file mode 100755 index 0000000000000000000000000000000000000000..6ce5bcde31dece5528a36f18fcbea1c98461ca0a GIT binary patch literal 31717 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 Wa-vp4fIrE_QdW2>U-Zb>@BaWy%|5CC literal 0 HcmV?d00001 diff --git a/docs/spec/light/pics/changeProcess.png b/docs/spec/light/pics/changeProcess.png new file mode 100755 index 0000000000000000000000000000000000000000..1771c239b92f73d761ac77c06a5a11a435321f71 GIT binary patch literal 8919 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 literal 0 HcmV?d00001 diff --git a/docs/spec/light/pics/commitValidation.png b/docs/spec/light/pics/commitValidation.png new file mode 100755 index 0000000000000000000000000000000000000000..89985bcc12eab6f731d8d2332aa0b8822069d5f7 GIT binary patch literal 64713 zcmd?Rhm9(k0z3tsq?jBHbn3jdZtkNq09$3rG(o-646O(eJPRh39zz zpMg1NpS@S@wXSvT6RxT(i-!CP843ytOTKi>ia4S;g~>slD4?rNkO{&Qxh zGn0ULzu6rL_Cx_x6j+)o-$xV3Gu_jG2e85JZc1kO^;k=Ld=YF#+x5d|D3t$dLLHy; z3L{uZs6KkM%>o$d5SW}hDTfMX85|3*U?c7V_>y!-m9du+BL#s5`M}P&@t3$rf<`QB zZ@=*;q!a}hN49oLU|KMNP>~7UH8|Cr-AIe1$|NPWJrC<-VxA_b=FuY|>Xaxo`d6$A z@W0>UTd(NCcZ@{P4#mh+(V=654A0@diF?c|b-#dsMfeh*Bf~~P4W!I9IB#a54SDZ^WI4~OF^qk)9Bz)#R4_b0w%wwNxpdCX8zuQQmm>y-qI!pq z%+TY|8v1@be1tKe0}N!$&*N^2V#B#r_5FH?8(%U7mwYt*Y$PT*4pt%u5w1qT@zmzi z#Dg*Svi`Lh|f5_APpr)`vY085rGGZejch6=p7C zh~3Ze9dc1geD$UigVb#pP&j8o5ZPIbQil*iGu7NoyCFI> z=fPT#C@zr5$0-DKp@&VJ^q)k?Jl?hi=HHCSYlKir5asUAP`a9Xv?+D3L-gi`a(@4q z?l)r6H~3|KQC%;vCEYm^2hy=G#rPc& zU^~yLfbEEy_n#WUbSZT2+MC!(RFmaX|ouy%V-ldc`?|2kb|xWU*A23Iv!Qq;*zG&jdkme94x)?m3D_x|giq!xXgKdq!^W>i7H?Z67_VD>^ zAO@L)PlRA7Y9d(u2cG&vu14_6WK&8catn$@%r^Rc@%LYtrOIMf z<_KV_q}*+S;#ug>*v}HRo>WEvWGL($Gj`p8L zV2ICkfk=i#2AS|sayt$iw&f`YIM7Z}dg+F%WVR->1DZ9IG&oJwYqO!W%NaGnI_*jmU3m+Y> zT-evtnLJO&Ge$|H5UtsL;y^(ZfI(AQI}+samGlL54+OjgMmON}-3KJ@HMN-X_m;NHSc5hBTgKc6z$WeevTzR2zj2@{R>6X)uGFkDte?R33&m!9% zcSaqY8yDR7u_@Pk-MszzX!dT>%|+Y(UP6gT7@x~rMOI~L!ToZUG)zt|NF6!RW;N{F z@OiV{(p$nDvJkc$U&33_=QoK3k?du;nD8D;VQ6-JzfufkB*!f?xlZ|Uqq74(a1Bz2 zAe@~=nt189Ub%mM5>YLEKv5=~g#RTpo*HTj(FORnNas#!i zLK?HQg`sc15y5~^1Na+QW<)a0&3_CA}f%)d`?Qp`BoY5u0HSvi8 zPXAm=z(6dOMu^Y3q0cM3G-7!&6pa4v035>#YLeh06^E3*kRSK29&4U-D_)Kit=A1B z<1c>>#H!9r>g3oawJq)^Ci6*$O)O}GYHzYoHW$9UJ76uN?vH% zT1BIkQ;c%;%E{Nv=EaL0f=d;PgM>9Rgq>seWT>Kn_uTc7xF!c#b(XtwG$qvSjt#R- zj>UZuRrih+9w(HKUc#VgUz3qU?xVX6V49wcC;Gei^sH?}UY#C@FYY_kLB)7fqHplC zcn0o{6kk8z-zj8@@(~l~_`<{nIOm*MpmrbvUW3LHEGc`S2--<6EzoQiU-qkfB26<$-C1GVu}fQ*+x3D zLG;%m9(!mcHH8~74=KhnJ}l@yPn^%LlWnP&#YL&2pJ8UcYTn(YEuYJL;I4W;q#f2s zJ=^*9vXOLKWAok1`s_LXhcGE6GIJc4p--5eq$F%5WcA&m zx_TfEU7LrRJzLk`ELK*+Z(t-|6@1GM4YdurvsYxaN*9z4UhEyGkrP%Y=?~7{LTJ1QVg&<`%CcDvm?o-1QaiyP-N7L(O}NRv}%o|;_=+hs+Zapc6Re9XD4$+#}5 z6p7-^B0ZS1-u^}_b^@Izy}tk?B<>cHps#aS{9gb!C@ppF2#xOP23$)8CKvLBhUEI&pFLg%eSX|UenFQupv)JurCYGtMNx!*_WDuJ)KA2 z8g$WfH7t5R)D2Pa@%;F_^j7w}s1F8Em-s_W-so4f*0Chamv^S3PkE@bvL83^Kpv`$ zW+Hm=zDkvRA8Kuv#erO$m4we<`l3vgiz3} zy_Sc(VNgrE${k2?uZQK3Mwn4s512}=fZX)9fPo8Cti&87p#BD`>=6l4Om)A7R5WmO z>|!vu)oQaV!A(C2s0Acgtvm|*r9(B(iZjHUkg$_O6@dhBdWuHMt3hrRYGNQ3B1bWZ z9OG);OP^)^?oV;Gtj;%+1A!#5pK&&XnoeTV7v;J)V%TdgkIUqE7uNQ4`iNs#CGu9) zvw;AAT#^$QfgLhJRH=L3vqHB?gQ=4P8t+kMzr)rgyQ#CQT)(a=)X}|uXl+3S*5xR3P=ZT8%eepz@sM%x$)GX|DY_uhc4a-N$kM=bN ziB~yq1c--Jwxejf1QXjS=rAE=AY9G4`~I_}Ulo74po@0hC(&_yVtjHgxBA}B^|*^-&tqwG zJK#EeR-?MTrkqZ^&{|?opoH4#hQjT#U|v)G;j!H5_qt&C5Gahyu_SG@vYbv5Z)P z(^$BB0YYCb^~i+SS0SZyJrNuhqJ&FKU zBH<6rT(ySt)L|H;YDaXzu1cC1%q3&u{@z3karhT0x*D3>Y9nXV*uq9XBYfEVV42aY zIC8RVAZvwY?HvT_V)sBXL+in1;s|5*4;-cJt7A`YD-%#1*ZH1wZDSd6X%+YbyI{uT zLEVJ&W}vzY5`wl$3IP2FTXG z4xEU66@V#LW|nBAONKQPR!&7UgHhTj21It|VFY79BL@AQR9GgJg*VQwZj$_xhTg=(W6@wDzKO!kZk z?OGFf1J6Gng>Dv2wc9PR3f1?glz!Cxt@_)g{072Px-V*!j2Mu#S@2m5J4x6&uCU)% z>I4r&5_kb$`Z))%7 zKYQS=$#fnR>~I=C*I~tv5KO3sAEFtU2)}u&fy3&qn4Pf{)0?BE=HtfYvr*=1B!`Pd z)7ZS+TqwSEZ?4w1wpzy>h4IWc34r5&NF^8pK&pRQgQ6B&5J*Z&YQFp-SnIT>yy7_a znt_dNh}f>(zwNY>*u}*~qD0SmTDtl9{t%0toZLuodk2WQ|7|WL&>0hSRkm`u+uPd| zOiakSjn+K@@F+E=L+DbnvRl)#*V-rutwOHpFZ^jVu&z+ResOU z&j90Ib|106l%07rOGeKu5hgxKN$iQ`~AK3f&bjmT) z`AbLy8v-I^_ZOq>&Q1_(AgLDI2C3Q~`NJYgsUCfMn_=GrPY{;7*m+M+i4g`3I5cJr zB;r==yKgE%u@gqSKUKQb?ml5Stj_!Pt!%{vE8+jJ{OimA9a_mF;PhC#PwatBUcy6C zkoS~TQvL&;xe`h6rvj(=f^bQtLKt<{PW*_Wz}s=SfB?Y5a@ncvsBn?u7;1l!TJFyk z6t)sQl&4SUaZ$eERS1i3w54u!rYoc!H1ZZ_0uTc%g32Hky;sQY?ymX2;zL?UXv0i^`xQ3#78rA5*3PV<1hiR4S*E#>%YB2LbVA+m#>W{Ovng`UmB6ql$D@M0N<9Ss?x=dSjjqt zl07grEE=w&0>IGj-(1Ty9dZp4{O<14abA5HznkIGzDT};$cSzwe0sMqf=#|UF>Y{Gxz~&%26f4%a0392A z+DL7f<|yUU$ozy@;~tEdmdGjs7Zb5yP4#!8hS&N)>INh z9#J8w(*_2B|7}wD!g-7Nf#qAT%o7)y!at|{O15>F;EVvvJ8I;H$A(D2)p+_iY!`8) zuR=F^VSHB8S*C)q4lSZLd92YiOQ29kGr;ul*%6`whRg#Je)$sZ^xJ(W7+ge?+BZ|b zK8k&^VOA(hm#)MfEhNe)?x~5AqLC_>I;iH88exN;^8C$I+M*E)%j29h2b0x91!FVv zS@JNvpqyrZs$ysl0Spg#!3G~7;k#%?cgh}xTsFMsyh>RlYz6qnUq{1lqY3hZ0yG(q z7qogxaZ^m3_@|~#C8QK<&FfbswF=%Skkio4H08^C(_Pi0S z0x%z^|1*|7zy1`_>k{jO?#@1)b1h^c((I%l2ai{U^aB(Ul$Yfg-a2(_X5tNvC|*qI zLE7=bitJQ^A1cz?nXnXM6!+KVH{5^-Gi3+_*L%gN^+`CN&~B9u%#XM#j@rysZ-0B5 zIcFnKfB!0_Q`6-|$-p{bR=ZieM%MZ@f9B5gQa!FboZ#K3FFVJZlEXj+Vh`ChBG$x7Bcs+ayUwQ zL`9;pROxWyNqbu+(@$3_ogLPA73g|K2Q}5v7AYU297_XXoHGnyeUE+U?GaE^6s<6V zzUo}t>_sqcl3t)URn)iD4#Z<9B6vbV?xANho zl}{o})$SH?LjQMj{vg$?x*U)@lW20ciU20;%=%&9rbiOf3@4fq4{og-29n z!*{w&)rLB=0bk4T3CG_T(hr7}HU7yjt3=-H@0ea(rkOTW|Nhzwg7~ zOwkaMJmn(x%B^e0EPpRaw`2H6(zvrzgeTfYIRE=W&o6wn{wQ@n`9$18+OQ4PQW|Gr z`1fs+bJls-f4rE}r>52dX&MAsgOSJ7TD;%jB@rVBo|8a=2?Y3-w3J90i%Bk1KU#4? zl4%|Y5n>`MpjQ%iRmb(IlxP_4f8K6Fh} z^F-g`d%n&xBaArnt7U1XvzjQlsF7I;Y7UviU8FF@-2-my6(y{ z=55t&3}V`}DI9gGq73c6bZ3ZwdQmsA9NwVa-BeoCUZmN@33OskV{uB+?wCCH)^XHQ zJZlYv&zko(R&xi5_Uv1(++k-ggM{o48yM!K&^HexO_{J%B;ZG!JK#sqKTj`K z;bdc3CGt@T%ES5Gdok5iSI%p>$0%%T?0jGnlI^7xq{RooYAV_{a~*Fx8?h!Q;U0lr zQ37Rs%xvD!AYXP5vmvql4ymGA944q#GbAibZkUEO)w6ZlhP@k)Rn}UML=*Wqhaa2tOr(dM%YNdb(|BR2}K*#Oh3ro+jLb1cea@ zq5Vk;H2_?KhK?Dxa_yA&F?H~s`u7s&QvaDc&#Fy zwZv!@&&qs#5!yPx82u#3SI|BUMbO)yWTp-t8DUk?suAgP^X9khQ;>B%saG&Z z4xT+~^0NpyySWrt{>0XE`2#;JA3>tcUfLHib4?CT;#uZ+m?;NZRsy}gubW3;m13Qd zLT5o8;Z}XldCls~{m28ysETew7iM(jf!}z?<2g5Pf%5wdrMfm!9qW#V1}=!-;|tIG z&Sp~6J+k0_BzTjrb@oT+PVp7oc^z%A`dO-~r!8c8d=Cw5RTS$!Jt!zg47FCMV2drVCYVf50|0|z7r$DyL%WKL)&ZH^#tqU+J~w)9Gq!Ou7k*CY8&giT+8xvO`$6SQ z_X(cVcd237gO1+kKfD&(P1yu`GgXTSjLy>tOi%hH7`)@MS?{ryNOPNU6{P9xkmqCN zHD!@hkOv;7)-}G(k$+poxTrYW0>bAV;$I6!Y~uI8ueNdB*hQ>%jKpc4`p`riyVgwd zmB?airp`R?%YuN=_0I+Vr?Mnq;l??ghp-A3t6EDz5rgOsJe)#Y@`-wr3hyJ)+n!Z( zg8E0On+&4L3Tf{Sm*~Yd54uBQp94>=aO^L?G?}P>h0pP>!N>EY{XUyuY+Kq(5A-j< zE6nzjc*T8=?!qT}=R%I{4t@W{1pp6D_La_t^ijrBG#TMuaH}m|o=0leUJz%tS>f#x zFrF`!t8ApXB=Ot!$P*@2N$F~EnV`fD$a4)+s_(Wb&}{b>UD+_jtB_`nWJoZMFa;}d zE74>W{msGdC~VC!W#h?#aw<0mh~8H?i$-h8U^ATX1Uu5^egBtm9Q{k^iq1oM24ru^WQyL+?6q*T4Zw)XBDk)lpnBXwrtQ8mf=Y@ zd%k3sReRYgra*^UF=k6eDt8buo~se26k`R?f(xFSysDO+F6cG;b3%%M?p5M=RGI$a z`Hie@ycamfVayO;a^_tyxzD11L|NZdV|{_y9=bNRN_SbYodkON*~P*9owprqNOX?B zsm0{rIHPGiAx_AuXhcF1;ipG*H_^^T1L;gm{gG=z z7N7%yHGxptW6~~n{*9UZMWmoz0Ei1QnSd0iEq46fT8)}?j9s9Riykc)fl?C9Jb}oS z9+Qj=J*b5ufmu4-vuz%xoElXjm_*s@bY0`4`m;?`r->n&&57oQq)TOuHYrt%nNlZ0 zOFDmi)xoKF5{>fvH3!DlLA~gQDj^&PCQy{kN9`{QHh1kjc(-frST{ZwY}O^neMfJG z#0qM*9#llSDaZI(UWO(J6AC3l8(*#4EeA{(Rt}v=da^V>3h1@lW21k$$4;)MnH*8+ zAE7O`za;7a7dCZ9hz>c0HRFc1N%_3-=x0c6kwkPUR5#O7OMb`cBAx7@7lG)bc8;mk zy$4B6SK!+H{4sOyX#@)30nmHVOPkpQH}S$A_akitg@Tm`fm|&}6rn%n1dkpIJN4J- z`O5d@vrk?K&#t?;?JpNja)M7}D~>0%sygZC_XW3`TM^tWUI#L`rG3UuA>ynkl3v#a zLOu(mmOpgELTy_JqlpcU@#xFh-+3V2uKa<@#9I8whIlrPxe~zBgP4pchDNtDESJ1@clY|xR3^e?B?c3|~2gL8&gDN%h+LHfFSmcih zK?MF28i7(|zf-Jm#JBpEX3HP$gog@eIa=%fw4c!5KW_;zd~Vz-C&iPKn}xd9srd5Z zWH!-)+GOa7T-NFHXUK0c0mZMOoV+J;o!9gvUxS^Km*nHaEtSK?KL11Fe%RNCTb@Z3 z6~cicRalwPUZ#`l^l3cR7`pd`A$vsw)VoOS<}?bgh>2@Ij^S%pz8}xv!x$MEVNq>= z*cvb3@?WQgwEV-?aegbp+n!8qiA4+IY1`G`Bqys#i+c*06eJ=QYie|@PgJw1uIof= zE8v0SUYdVqFUg+XXYSeDv zX>IRaMv0AJL<%wN$~nB2hA}^Ybiq*Nm@-VDAAiY{OYuv}rH~>1Wi~^#3~pskdLeIB`OqafYWME=4alp?f#O){ItUP64|C70SpHVG%3A1j=dENd3CZF z#mppXwY6d4sOT|Yl6*1voQ>S13rZvuIb;({pVd-Po>8Uie>BV}H8Qme?#9A9gx=H+mqpUej?e zywAPqMjt-%R7zt<@bG9+b)>LX%?a+YWu>HqM!{zhv$bV?L4URm(2D^aqMbR15_ozB;RUCZY3woUqtfS#@=6a*ESz(%6`)uo&6F-)Uh}xD-mSVoIqw?KRa9I1@~< z#CJwpuuEh;LVp=K>zD8m)_h!c6}p_sDA{+U;-p37l_a>p>E&>;X8j7D1G|NYE_i`> z+Wz$Uj1a%vEZY?{HsVhTU82Sa-)KKu6T$SsCGme~ailfyK9|<>`LmNM=vLL1O4J1t zAeJfxQ^bUoAicz|GZG0LRDw&Z-E2_bU8Ve7wHIS~wDnjKS!C)g!LqMGLQk|$w?l3{ zwoN_zU&Ul5FglF+$z$X{2*}joxm2z)loq-o*yQGFGY!k+(=flmpJp0uwjV-GoiI;K zO4=-l6~Sg4AR;2l|1lDVMZM?+mK407o!fq6?7(@25BW9jG3bMB&!07wQIT&Be?6J! zNsk+-9*56X<;|He7j{*L-jJUhCXZpG4=W(h2Hk?p_$f_JS+mdBx?A?e09NrvlO^4k zJ6~8QX&zofg;d1b0nNHa)^wUt!}tC5{HNo=>{H(SUnPS_OS04=5^E}-@79+~S)vN~ zp4!VwalFv^@~VmyowL7n3MTp}N5l9sKV`y@xd>#PWvjA31%Yrdad5VLiFfe+1OW}E z93#X?oOS!X4~SxZLYQ<1s>^udV10{{IQbo(>igqEYVv-6g0CS$Uw@tb!nFmJ_|8Zxi1oKlMD1gQmrq+|! zYX6Iwx2~4(n)joF_58<;)(lozV=E&9;)2nd;|?u98okmi=%O5r2Hnv+1=U;Ee35|5 zpIQNaTW@2a-XnDc4}{xAO@RCPRy=-+V`84eb&xB3%$KZupUA2brWXFqw~q@)I+oN5 zf$xf(o0V|+^V!cjjLjrA1rD3FKdD?_;Ano@9{p-1yWb9PJ`191cfJf{SK>!$dV1oP zk|XhxLM~E(|1$~Wv#MXQf6(L49yErh%J{4`GQZ>8YtGSU($GVMkI*8)Sk-b>NvrMf zN0^=51^uMe6$Hlhla9hdmu|*E3mu)_43jceiz(s!%=-Z#i9mpS~@(@K>>4pyLT$C3QPBlS7gg}3o`LyV_^%MvS}hgmur03o-(4Mf@w z(5Q!c+640dd@RX<@D_>tfTRP>Eqfjo&gbAqwe^9Nd=dWqgnq|rcmlfsy)@hm`X@J& zVm#Wz^ zmn9O4{Bh6p0iUZbqi^LII5_U{pln*P^t57h`cYdTC=1pid5JzkA&!^wU#=uj9I_0w zz1(BhZlM^@BpYdcg2gQj=D)5FPBln`PwNj){`GVRE_Yefnuc*|A`=LNk54z|KhAV= zc)ar-4q=$csJeBQVYbR>3!)HSS)?q3(}?5tP~c3M4+GFjx)?;CM)$B606GU}%mM^i zz*630;QT&RU7q^+`u;5OXMF_coo2sHF92T`tCEuiFNiji?Am(Yt#oLgzsIwE9>US) z=Xf9>UsL|AbGy}}SUuqRn%#DkX8WT|fz^v!3Ae@8jn_%fk=m<8)QP)|`FVFIMOeC+ zjED+;;v3uLh?xG;=BHN0cyL8u7ugrWj8}aeE;IHeg$T}R1r8TqBiWf6i7*TuFvc~0 z^uM!+?rkN=8Q9eU{die+N#&A>SvYAYAdZ%9e%UO~wO$D$p6tNkVI(3HHKzFv?ya?0 zMxd||IqAAQ9sb(5l~hdLvlr?|G!zq9cn&3^{eXpSp%<1>)q$E2T12@ri`CJ^Pi!`% z+yVONV$1g7%jej$C{-5F^_YBkq@$Pp;#=@$4ii}ngakhE24YqxLggt)sw)7u6tfnw zi0AbQu6hSiDQG$$^%+1X`=!e%5}w;7D~pp&=bJWnLZ3qjZu`Nd#VMwat}s3ZiZk%~ zpFw2Wo}`V8LtEKxRfBVn{F*+uytZ9iHks~Yjx74@SgVK&TOn=PQY%p?4t>&2SmY<& zYm_WS52e|FsRc-&qMmS>zj z`QYHc>?mY{NVv)H6FaUy{Z%{~Wp)M>8jUbMZpp#?>_08foMYKwJzre)uAuk_Y%I>(J{SVZQ9Z?J#!kqZjNZwlAor z)hz^CEZG5N(bXHLw<4j2O7!daxE6ti`Z`ij0t^~($!am{ZIA+^-eg6(saPPgI)6IFXvBx$@E4U#maZdSl0=$r;|iIh-@(n-_eF&9uh2qUo?pTfmQ$*FgAP+R zFSx!*($*U7g|Zn9l%eszoWDyg*zY~qxivLSf(-{D%Wa71{WQ~a9+6JX%z-Hltq0B1 z?{lQ9EiF=3?J&@$s{4+}Y@g?YKQY1Uuew|IQVRJBy)y#3H(=t2+JE605$N{PBy~XOn@Zi+0V?3qk;vOIeLNCKrtrB=l zTv9q{Pt8j+j#Qro2EKVe<`~D7_TD?7ERoez`NuREdLuDOS7hsMiQ7-gk zKHKoy+0Go_wudC}vBK-eh0KcRBx#BDkev-bc__f+f6xkT$o)*x>PjuHp13ns!Awq~ znmxk?DSe|q0A3LyIC&rmgF7i!I;@HRqH4n&!JIMu(-e1qDDhgnbU6G#Zdi)R(U;&r zBDN8itThh45nS&S%S{K8K}Vhr7vRjF)fxEsi73i@N9=;fQ42 z==uUb1Yev{6=Q;=7edm>nCaeThn%%WH$OBMQwm!_vkF~X4!0fDlvhB@P6(n-t7kcXFmo=RdjN(JyCscNf$NNf~;)lsopup!*kMUQ7dfEUQ75^;piz7>!6?Z zBYs}*re9Ak=okw_dWU);qtYF&_@jHg-M-!XHi13*4W1TTRxCel?&}Bq*p)}22-XgC zf^1GAk`h3?1>+F1kc?-~{v0g=G zc)|P-{49dqcW^d-Ty8|_D^S(CO`}chww0q&C6Q*0Z2P!ex_CQ!dAFwLM{L(d7_n>P zzP(Gpe!#}J@#uk*m#D4wxRc?2Z@6wcz3OHXP=*{Ue8FyoOU>TEfXD7yP-Vt8TDgDs zV8gc+#6c8CmKQ*+X7ao8O3?uOB6+F+em^|FUg)EyG}F$C|1T9EUUwo02gTb7`#)A= z0eFbCitq=WR_QaAfugCdf+I3)rV~xGvb^)lm5lY3kTLXvPS}QP9cLF}%7pS<`7tT= z{8#EJ@MuXc_A;~-)I89e*xgnKGB(oGRO(#0@?lsUbjqQ4`o}tRJXXfMq2feXk@e%6 z{pHl+4Zp1EU=OUUrhnS_DdEMAXL9$;GH-s*@ElT+lCct^VI|ffF3Xz_rDSHtOMd^_ zGn2{eV{ru7z9BRNGd>yg)|;Eg*!gKLAY{;%#=Ho8cE4~otk`x|{L#(iB#c{*#9Y(b zn|ML=iBb9CaJBhp+o4N$FUV>-4(jM)I`}k9|3OIWA81dcb%_{$rT70N+eP=Y9KJr~TaP#=jFW<}ek?rKNZBZQn(CYk#n*cnG_}$PC;@|ZO;LJC(uiR4Hyip4h5efuQ-%z8l#{X=%0uh> z*Li?vACWo7zlnGDMa%58`)TJ|(~!wtHnweQb*=C1lC=|E+H7HK#A^t&j`~<+?B;ckPHCT`e88<+2JA+ zpvAUi0fr$Kg$hhk|H6%dN1~=W(|7nKMhEaHy=a!gHuKZ-XrL6xBl!10#ONb|7EeKu zMl3+yP?Jsp%a=q{33=Po9{r)=fcE{XB>evn?8ouMbj6i6sv6 z>8LKv`GXbQhV+y4LN-5y6K0i*>qyiOwNhc=GV3d<`DXmuWj(5#i_kPePROh3)}&17 zmk$a6%fpDen&(E{wM+qg$$mapi+`4cgiTQ$G_9l`?^V+z!OS%E>qr^5aLCkK{FNj3 z6HELlbO=pm$&}uQtTtwL__jfrQYjXY{`wS8OaSskE!{bk4H*^Y-~D#}U*vq%3%63V z%80i>I$7IQ_5m)_3Oir=C(89@o~B+}O6$c9pcBHc>eERdB5ecV(}NhI#uV}N{rB%j zbT30|_B{@v0R}SQ*T6YcNQp#8alf-jitc=%MAa55C1Kj8jO$38w1qD4HoV}Qdp4tq zjPy1tKJhCCyymhG?ur$>p-3~dYTGv}aCTU4L>!fjC?G_HpkEs~0P^7;A_Rj&$PJB+ zE|37<0Fah6ro+D9yT(sTa*#tfCvut?{H(zT30IFac+CpSjIB@_f4-D$r)T5BCS_LH z-kq3Fg=|9y#6WyMHSu3yRNBx2sp>_Hm`DQTG1_-0*nfb$bm>*Y@I_vL1xH8ea2Gx8 z?}HF^|790ClKiUfBptPB9&yrh(?-l97^hDjB4J7!w-5nNfQ-J`e4Dic7+dlq*vm)8Z4UqgEkF{aaz!{;M!P!aUK5IWT(G;ayj* z=9lOK$8UeH?^uERUC@f4HSBUMlK^+qU}vHqd9Amtr_;G!^9LXyDMFMQ1M?5cN$d6l zP0dFS9GoC4eHzZO{^eg5Vy=|Kj$B8FE^BN~g`H1Lfs$e$cj(7>8Tgk=A8x1oU-$aS zBK<~_S!n`edEcEEyPN&_!hc7^B`!Qva-e6ix^rnT5-;Ur;D*@cmWi=D)&~ z8RrZMXe*QT3`Pc0W0eqXHNLoHSV==q?N} zGIIaDPm&>jtu6gO*49l8+~f{NjnNC4+2jx4OHnQ)wouR&aOOARc?x_BFvo!SEB}(_ z0R{obU~`8}*`diHumkm(kj?PlK&tUCkS2lLAqZQn(YAOhl;Pps5)p8f1;XYIyZ4KBMF4I*rBQ>*_GA8w!M92M1Vj#R%` z2xfrgp3Q3p`4C~H#~mD0jJ>l`M#O|$J_sxd363fuj2x~oJ8#f zh+|K{b%mn!cO6Q(F8~>R#@9TXt*__fe{lia0|vtB87>Hwx@7^AxI+?BA?Ad97@Yer zKP7`ah?)>$#tQ=fA2vLHXe{8M`0t~mpdKSJ1qI|xW%`rWL)P}|pStcREqnH(jKyNb zvw7v^DB2}TQG!|?I zP|3CH%+Yx5)}o3OQ@|w!F#%FkL{oZy#{uN+0`ckyp~*2g1TnuV2S^(P(u>iqF@mn@ zxX}^1p3{)X6nZ$So3i9?J|86BwCAq@80boAoWTPlQ2dwFU2nU0U@}?hGnEN4Sv_+U zAKA1Gk4Z`0H=ZBPChn`xw-1Wh4^vGkKqw|Xv5abeFT}9nCyp0-8LRhyM}=7L@2<9-`eO2bU$ubu-`9A0UwlC%UD|w`M1YVmqDKcLYri`yZGev3$n$RawuzRNsn=FO;z^#8!~z?=4c_e8vDz9vIB9 zPPruO2EpIjj@)cB*8MsH4&hiH&lCVHj_6|nN*$nc#8JzR_F<$}b+oU;75hV`JKAfE zakzHbZri4<47<*r3BL6xFxZ4r6&D#EpUof&kNG_X7gs_D-C7^{9JTH-I&fZTV;THv zlX2v2^bpXDf?&x+u^&sO<{8sJ) zCI#=#20efg!H)7^fr)(g%feDc0 z7vHUgO+1ug6{#ET{${~7r=yY(w|(5WA%u%b@@`VU$gFoEu6;5Rc74Z91-#J#hYpWI zm_x>WO6U)e^8#-zz{eq!fVqk`U#QaW^^)*?8Z&&Rdd@ac23~4$uh?zWXabzI^KRKKI;8#1`BWE&qgqCY7}g>w_Si7Umkv0B4+G>eKi!uM>r1W z>?xe>ySaY1ouJ~dN7}TNnl>xF0_uW<@Tt&=WNd6Y9?0u0xMVDVLvlT9U!TQLYj3|2 z6n$$!$?-9yn;9WcBB!i+7IGQr1Jm@Q$j z^e&{8kz~B|;r?PDx2-=FI(`Bi$-MbO1W-1?%^;63^${XeoI6Pv&BJdx%i$P}iO3v( z-$J1&>q(OkIxs>G-s5A3exVdoy8_rFp~TD5_|p1{eEHP4VQM2&KTWaKZlsswQ{!?X zqRebvC)TLC?bQoYrgo%YW+?IFYJ>sCkmtlEc-&ra$ z0<$pw(Jxej8yM?h>Hrp}K37%h)`cTcruRgpQ4pvpsDMVRTm=)40&g@S1Q_FTMM`jG zcv@Dq)#@l2tKq#-a7qkHIO3m4rhdO3gS%;rW^9$yZH8FFY$(_WC#4*(Vx@QI>E9bZJO;`p6eZHYpn6`3NF8cq`^bOpR zwoSJ)aWcWgPA0bPiEZ1qZ5tiinAo;$+qQlBdB1gjK=!8)Y;C>>p}sR@gXOw~ctIh|$( zg!K*dIYUf|VdU>L@rji({DdTcVpgDqL?1waB0u;v9D|PzZU3bS}A_9@aqBOS^xj%nZ$M|q6`q9^^YTTB{qsFB17OpYS$nxwg++u$U z`d!(UVUdL=Xd6e*xSR=5_Z0Ryp(K!pEB*Bd+P0y{?g6qr8`u8`!MH0#nNZ!$BLy7? z3rQ48@RsWS`3ahg{>B8dP*5hZ9=_bYM#bnDgPGBq#3g%)Bgi z*vau>KxY=9g2qsGY)2YHjwlXltECxcJ7sD2qjf(%32B_a=BF|Lw-&X#72kUvPEjLG z%gF#VP;-j#q6LJ5WwG!72?YJ{7L!X^4s5IxV3w1!%puRiLt{9gxRpbsZo8^o$2Exg zTs#n;%^x-s(Xr?t7tYGSBIAsO7Xb?nTLtmS@BpCx=QNVup2cUHIr6fHj*LP5Ga{a< zYR+JC=#%|^WfmhVg;8&s8pw^+2+T1B0sW%~9E$UIQd(%%)_2Iev6RN6xl5d^1@lsu zu9vgvcoP@IoSW{O(~cuz!u(Zu*-p6B!y| z=0x=!q(Pna9(ap6&`uAjH+QD(aq&2T^Tn|kcE<*2WM5XsI+}97Uvf(N$hlG5$1-LN z>4`LvLr44P;`Sl4VF=PaqWE;^;#Gqsr=riFB#Cvw^urEe=hV*a8aMSBT-JsoMtFBkXS6E|-$B(g+}uQl{``_T?@ z^07VIC7n<_0c5#d(SJFDnEvQF%=SIKOVly~Co?xHoszlLRboI+Bnct*kak{UZgZ8G zN(5GXA{;Urdp0B`#IiYkK}SqPFG~Oj1Jyg#lQU9L+*X?1UcXVcRR@ot+Cq`7%>8EKi^{-{;!b`3SYDll`Lsr zS=|~VO`UMr)z3Z0rgRY*3}pnT=;H;G?`A_nLY(1LbO0Gm+)k7Hy_YYlCd^Z!^UUT1i?*@lU(F z>pOI$SLct4I@euSW!9%65?+ZXn}R%E1{9=+P*f{#XWX z+XJvi#;U-zbp6CrPcYss{;e{BT#u_EdKales!35`c&&#q-h{_9hajK=lt z`}T-OVj8|}hBptFX&F^Y?bg2jnaH)j#&b~Y38r$Bz+i?WeQyRftBP=!5_=dMhPGT0 z)Cv#=W1+=NN%P})Ds)%}5aH$gpYRFZ5BP3@XUNX_A?6DeS2AGbm|I(^`H+|A!;G>Z z;Y=`eTtdh~03p%J41`nP`Xjd_87P2o&LU7Sp!!>xut?zp$ZZE+SByZ_8Wchbd<&+U z?{fe3_cyRPx+%LM1;z!nOow}yfQJ=2YXl;8wG|;V}kBX6$O;~B3SUx|lmi)C- zP=HX_wkaQ2&b3ov$uF)D2#vJ_C`FAC#3MmtMxx|=WCF7%^iy0~;vg_@$8lT;Hp;&h zN#_@K6=8FYW82jfD-TFUP0c@eNaPC#HvI1DJZ+{pX$z$kUNUR1*_Y!PJ6jW`@RF#- z%P2w2MnR(Zz~Th9ydg2p(YVeu+G|QW#2-@RNBV^;z`Xqw zcw*&ZDKM$s2oxq*7nohc&$IjCaPtXPT0o+2#7KrkT6ricJ|H6B5OPfI??S^~-~xew zXVBp2pBMx_39ya)fsnRjn_GW%m1R<)krgkvp@#@04qrWwhnfclvUmYhr|?zin9l-nNUNM+n zJSG|iKknlW&z~221{G^Hx1m^g;5Ld*4AnOX&S-Z_^Dk8F#2#@_G#{9zDKLDDpkmbR zr1|;NMIx1r;^ZXkfC^DyUx8RCuF5WsQaH*$B52`+L?IH13xu2q?UK1E6vBnv6h=Ig zuw?Cd{j-ZN111eZ7Jrf_b!um6)2>vQsNv|#QJ@O0ou&G)OWf4v1L~-;sNngH=*gU}$jwc0_U9--JW?e_-Cs)}>cZK`J@ucB zTHjufFC!2t^4`ImV0G26se`yxbxu?WLxSl;VPR`Qh|vdA~f3vjjOA%qY6ccXy) z<1SwcCmBZCs{u*{zO+R>1$2>%Z!mEDJ9yW0%Wr%-6<)I+kNat4KTehtVOh%#X(6J^ za-c>R47~lX)X8C)3ltD{IU9l8G*HU~GA`Q$FU#QM#hnAwB>uTZB%Cd-$;d5hN$3^{ z=;arBv=Gv#|e&Nl5l>F z8OYr{GQAql;_nR}-cf>Sic-3te zT)7X{Z0+r+B2}Fj`B5aV_pk0-V|U^&mwSbi<}M&hKr7m@>Xobbh>Slk>~EpO&(WO* zXyAK#hz;1L%LWE7ayMV$mQHT}DGILr_&HZic?Z9dm)y`~P#^Q{Bqy!JAsYh;Z3-w_ z0VZwPfAo8OeOmSlR(36<5pwK9RXq+X6*X$s5hco}mxsH&bG-6Rc;G1SopLiPuZ&{< zMyi>Ngi4*}tXK|#*w?c)(?!YF8=;xn7t5SXD|G#f88wH;1#)Y}ddQw^>aP_0j8ZKm zq^E)1CQUP8zfx35wlAECGoHy*W=KJa6e6J%=SZi!ZsrW^_wbhcUs3r+{TK1=2N^7J zF@cj#*Z3{)!Z3rpQf6TfS*W}q9qQ6tF~GmMNGGsDS1^S?aa;AP#Oto#j%0ox5y5zN z$2hTg^^V6=Y_2BRuVe2#xbMHP|G_M#s;e6s8a^h*+y$w`%=&4R3D}y1OPNHc$;Yac z^!Lq4{1fw>F_|%!FJo34Goq`=^oN#_vbzhq%0;)u_(^gH!crTqo*6Df%0Y!7i|%>) zOQWMu$VdEE!ign+Ow#DS8CxE5DNpkKZ6$tsP#3|0X**msowa9k>kR>2K=flZ&}z#i z&BOMwSfvIM&G)?ny{2H;Z}r}~!jw68{+xlS`DGmP2B2my9G5TZra-$bcDNVKOcBqz zFs*IDh_Q1RU|k!CLiEb!W4u>E2W7^V@N?38h2EQxZ(wDnNRw&9ikkk!d8Oq=uG|Dp z%gSkBSo`22TzA#?1kC4gORt9u_vUS0!<{{nSDJm+5=Oku8MLvHt4PA*6Mj*Ihr?XF z(5UPdnld}GW#Df`{Y=%&PtY;s@ zbKiU|R9mzLIOH<5$!QbVn{dc%L)0E_wYR{t3P{D*OJg3{(QO&M;Lc;Dib7ox?Z7kJ?Tr^3h&mPmw;!+&HxyhtQiIBx4x6dE`_{3 z4}oGpLIciE5}AY&;)X&l8JFoHMS~ej`G3r6YO5PmrYu-+W=axHCMpV#VZWD<^dSmn zVJ$7Ot&9joci=N&p@_OY5c)(OdKMKV_a4paoLmwq(1SWBKyK-k%au!6I45X!*18ra zGV62Lj!=8U!G(Rl_g_pf$R}j9HID3Z%Q4^Y-ozp6&+rGuK2crWNu{^w=l=)N+=DKVY&!vgY zy=PD)_VA?i_XdvUiKqJMGe;nqh*??PbH>g$m@+qYc5REU}GPS?4$b zJ4QWj1|1m;#ty!jNv8u^vO_$Dus%96!gi!Fc?x+*$2R6NeXrI+F*<^hKgnn)^`pNK z_QwlrYTSxT?;KaUtSEo^E;71bh*^XtwzytfG+HR_eKDu%>l=Ui3it}=F~FJZ`7Bw^ zocuL0eIMu(BV}jk9W~@3)eXu5PdqrHy5<-6u=&}A=bAe(jZ5}!dP2c~HPY%GpLFgb zpD%)~gG_5I>6pk7ZnfQ#&V2lj8QyN^pbS*2BP~M4TE=db)9GZ*pV5aF#Yl(rjF;WM zHqp`S6G4mOCVxG{`nHKB4#_e8a^2NoR|F!atJh7vu+~(P*&B^ES5a9up(@kxI^KIO zQnkAFPoWkrr<1vCZhbarM%QlrU^#n^we)?6bD3Hv!=|T8eqnv~IeP5f{g>bXDVm=7 zDSuMiquFK$FUcnEhd|{Uixy^X+K(YL))0 zoR4`~Gybh$lwI*wq@1bO78IC7ENB^v#9NY)byQEyTRY#eh6nWHg7N8t58GMx7vR%WOKraaULl2x*7+jYaAEkdvc)E0+%X}bRVTxf08RCV6RM`Hr~-${H>FCsXc^mw zd=+&BM&#-m+jZWm2+zf>WX8penSZq{WH{IEP7jnEqAnH3C)U^=Pd-_C2%b?MEVU(1 zbysTKmFup3nkhs6f}ZTyDPbb!B7f~z)?6=zf)%n)lI)**#rY-xvi0_l@|4b(;{6g| zYWXDhN2o4W8>6G;;w$dph$r$RSBJx=I2-^SX-NR4W14s9lik(Si$B3)(XF7QnuFCb zR+mOckgkoTxl%W864heC`+D`hdG^rmC!gcPhcgNcb_dA#T!*sanG#HV2g_ZerParg zDYc-N{6^P6qY`HI^Qm-!#7{MzpKfgb-F(?I`yDTEL=F-Tcgi1VIkck_rUz(ZSFc#c zALNR2xT0LU(QZq0=tSw0-DPri10LNMc`L5_cQ(kbdgMZFi1~x0TunDM!ykrIagHB9A_Y zw70saq^0OI)2U`mW;J<9tQs$8ktmSpo~oleb~tFFfwNQ@42O-u;f+=;$o874Wh7&* zK8QTbsG<3$%*t5E)5rq;Xr!RV!}=~Au|@7x_uvFF;RDjqd*z^)R`K0z1>UNa@oa>` zu)7n!khFpC_V&&1=I!rq{J~Yc&n_A~yS?7Y`3#IjQ_fZYJSB2fG+kB4{Arxxp8B82 zq_8Ct&_wO3G<)^VB@~J!q&BP;wAwu5t-A9k3@)UG+vYusf_!)TyXEX2ZhFzlRNXlF zxkie`QW!yoSKunXk1XR)TKVD`%Vuhol#l7mz0qLFKCNMnm{rVW%0ID{kwSf1|F*(k z-`iIwx2$MvLJJ={x@{7gRB}pQ*Qh^~;s^2aMMvvO89oaC8jAVy+lXvux8uNN!>60L zo8$1=!T7R<{LN5GC1U~&jAC6F+E1aEk;MimWP*%{le&F1R<;Q16x4-MMa*B;5M

  • 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 Z@m8}L+OwX38hOqB^8hcDG6x=q+2-TTL<{v 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 E1eUxUYybcN literal 0 HcmV?d00001 diff --git a/docs/spec/light/pics/deposit.png b/docs/spec/light/pics/deposit.png new file mode 100644 index 0000000000000000000000000000000000000000..1fb3acdc5aa28416ea79ee8b6e155f6a7c497c41 GIT binary patch literal 20738 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 literal 0 HcmV?d00001 diff --git a/docs/spec/light/pics/existProof.png b/docs/spec/light/pics/existProof.png new file mode 100755 index 0000000000000000000000000000000000000000..ee5de0851bf1d1a0ea503fb03b8c745547c58b87 GIT binary patch literal 96053 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 literal 0 HcmV?d00001 diff --git a/docs/spec/light/pics/high-level.png b/docs/spec/light/pics/high-level.png new file mode 100644 index 0000000000000000000000000000000000000000..73a14e0d73db9a276150b0c2affaf332b7ab0331 GIT binary patch literal 11595 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 R1w=ltjM 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%0DO|0SYW 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 literal 0 HcmV?d00001 diff --git a/docs/spec/light/pics/substoreProof.png b/docs/spec/light/pics/substoreProof.png new file mode 100755 index 0000000000000000000000000000000000000000..90dadaef37afe2c1992342fc0bfb548e14743b28 GIT binary patch literal 62165 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

    v$AEl$= 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 literal 0 HcmV?d00001 diff --git a/docs/spec/light/pics/transfer-tokens.png b/docs/spec/light/pics/transfer-tokens.png new file mode 100644 index 0000000000000000000000000000000000000000..c6635a30c8b57d2f1765a3ba6e3334489a7775e3 GIT binary patch literal 26410 zcmd43WmJ{n*X~OTN`sQpEmFb)B&9>Tl}_oDPC<}Xy1P3iq(M5QQ@TSMY0kaC|GVFP z_CDjB5BtLz1IG|pJnPAO{^oUEa|O!FilaRyd<+8vgC;2M}?&(sk?U>FRb5yr6$<=cM@MONgRwb9>7` zOFLPI?oYCmI8Dt(e9XmmZyfg@oh`^2%sZd@rH-#%Msup&Z=XR*S4-9zU4tl@1US1?5Pje)H%Z$?ix4m?wW&r&fr&e1<_%soJL7-Z;|HySLy6cN`KI9N;==oh}!$-n<$mXX5< zo5DX*__rAt;XwZXY!iZ@OJ})A_W0i>b?Js5{o8npKMZO%8nKAa!{%X7sW1Qi4|xjH zJH5)sm+s+>z&9eK_iqWlCxT;%g4kdp{@Z1is7?5P@2V>d<3ECgp7C$^> z+R7ok`n#WdwAPz=H3iOq4GB2w8`bfd9G<)7U3oT3ZN|^1z80yM3!UvumdZ6>{oe1d zwOi|rpOu|DH{FoS`DQU!%i4H6$m6iq`;Fs)0=@A9m9YYq7g7=uY1bFWN}8HU{Z9wu zSlcBin&tRTqq>7aL$mEoO;2_!hong6o9}L~Ot;7KnYOGKnq<7LW*73Te%C7(sk8RR zGLuHXd>`X^ceOA&QT%?O%3}3>jg{q}=BqzH6bJ2x_)JK6T$ZU$cP7KZYndxeEO|i9Abs%T5Eipocj3BwUATmmS61UQp>*=7h=YcgqM> zBFpft+ml=Y$?I>F;>tgRp7P}kcWOQ7cb{S$Rr46|gAm=?tnJG2Uu20V$0aw}%IC_Z zLZr8*$}{6*!jHv?+_-b_KICHvT>pBTn0&deni$us3y)wY0Yj4AL_x;o+j4QdAxXp) zf8};_I{A~xaKPp2@^oi;`uaHaF6-mY#Bic@ld02(wnLpuD$^2m~Ev&9EKD-{0bX5R}BBj_}q%_yj&lJ>Rf2-Wm@X&0$i z(p2Abh(#PR5&H+s=RA&Yj~cI!`l?({%?NoMi^euO0&z|@1n#E$%`Kb@OR-W%bxOMC z>g+{P-4;t5&l1Yk>h#gUCCKFWxa|IZH5p38`9-ajgwItuLoA#`W{CGVB!1Uwn`jfl z8r_P7yc#8lj`p&`S1=6ueB}b4B<9bK6o#)cy>(aE^W_0X^|BV~!GlG!u{=Ez&IY`g z?9e0^O^k8|zFoR`EVl&W2n?D;5?r?s9nXvG5iylzh{aUe$+qe=q^U}eeKZ`OwT-Jt zHu-h-(P|H+?eo_TEaAugBtg+DyGv&6jJ8eNI}|N_VFH?ks>KXO8v}`ITY82{*ptHt z-{VKa1#anVRl_SRXTKY3#piPv)-=^k)2KF z`SowBN?Pa5U*tW5_Kg_)=V|mo8_wX2oBt`*`Y|yFfvA>fnp%wbhW=Sy^X1OBE}Q94 zCLtnQd<0wMdJ2yn;fLWfVkBjv;Exw|eHiXVMIy!l$6UXJfq`XaJ;=3t)W?ii<{uY_ zzf*!5$)r`U>`z*UiXO|XL$fE-8xZi$rF(q#Ad9^JQj?m z;P-BBPENu!FP}enE)ieN7c{&4s$gBR#xYb-v`AOyHj_#HeTh^k!?TCJm2E`>M#e1QK?Yh%-&L#H1){OP`Ycv3yTAf-`jEu5$gmvO>Y6P)sv6hX^R5U#0h zY6`u-Vj#f1X-OTApHNBL7#Xa?b=#SEIiB_g-X4*r)PW;qZ`3}@E-AIKzagIfqUZ&q zOLY+kexc#TB(m=#42aQ=JwxAj&yF^Uf`($(HH05d`>L+UucSR=@L2x@22#3?}n!cevgR-Cc)ENy~5qSCqJ}nb2{Uh0Ii&2cvqDs5D2&hneI;AKnbq zCPA_Qghho*H*p^aJxT8k(q_#w>W};LTJv%Chs&Z2nt3dZhn+<1#{Kxi7j2)Pocyd{ z{v&ngb-hB$?lh=rHr#-Cn1SaR7MaSuIyrhMM4FO$LVKV|JCu3UM!K^1=GvdcGH-L% zx;gvq@7-;xfIeJ;{|0;=dV^vdpSJdJpM6HP*?5LRrr7YhOk#diNuic5!8I@4qZH=# zbVKwyjRnE#K)N7i%md#RK8p`G5&=~II0!Qu?6#OuW#-7k4{ou&(@$b?M;F`seAbt>9+GEy;uybK*-8_3w2RDj zny@tF;t(#2i}}PBFrU1)$aJ-6Ne8#aUrpGI&z~f%zM+L^R>|pd2}vy?bCt_o7QXV= zhM$xpLwVS3I1~hn&G9XZrpxUY`9h;KGWmx25wfM|C*g2#o0ST`y7Tl)a1J(j+kO>V zAvrdOmg)a|>NXLHL~Za#q{Tf~GTe--t2-i?_6!}Xm8H5Jt_aZ(RMKEFK{nuBi2 z@L!9qzFO?==Su;Bvz#}Y^)BuJ453_C@3@!X((kbXAR=pON}b!{x1-!f(?Xe^@Jx+Y z^Oc_c9r(+!CJ#3Tm4c}5QkBAIjR5$J-P0gve}3;Ay|qeP6+%ZAA@m8xWA3dxYF{U9 zP_>-K>)Tv$yYLI5Fukacoo=g zl$Sn$Do6d%h~83r-d>o@)Y;RPvtCX%-x-nUG`ezdn2z`Xrqv~RGKQ4u;FxaE6&A&5 zt$k_sQ?1IN3;nWB=T-24pI(35mbmKZ>KX-rH{dW2X{hFG z7Tp4*J~D5=(LWH8EEjh(GwXgju9h!3N~4@9hUR*?m1}ykIUHq7P;yGM&?xYfSv%?W zdP5*_t?V0pWqVw5?(s| zj*klSjd}D-)=PAqt;wH8JxWdPE*u7(sMR)0LfOn_+nO`n*#SGspsiAF_Pn9;cxP4+ z6dbHXm{o7P;@>@tq_j6vEo~a^bB891Mg)1Aot2gM1dqv(zWoL!mylD1YbXHs4((Qr z#dOBwrwmkA;N(U+5bOQ^Zf-66K0^eh+VjSB{sjL-Ch{b^`S!F_%B`8<*f>Y}HP6ML z8%ehiDYvlgv%OggVImKeQf0+Je+wES>f?{r1@+N2VMJTG18N8T#k!GD8 z8*!gyMkv`KFU^qN?RBBJQ>CDCGy!NY|FQUQEzCq@*LfJqM61u#+vKdI5^7Z!T z#q~GqliYc^vz-3^x9@&97UObT&+~4N7sgt=Z=P~v)T(Dkd;VJal5PQ|vPP>+w@7DA z!$^+^AtMmR&CmTelXC4ZEtSMciUYW2LI1A=QYnQ;>|yT5>oN>qo4rFsZOFou3wqPctbGZOII~v0 zh%39$B{q>EWIjJXf2{GnljN#&Q?9tZa^i5@9?Tw*Llel`R7Q>v?#(K9 zQR;OQ>W&P-Q25cOlvKwXsvh?qr+qm&fzztZo2}f`ppE{E-|)=4OScwiy!#meDL;RF z-}%phv~W%}JX-`!PLJZLNs5dANts#9N+;|Y)x~|CsTFVPJln4r zICS;~v>E=A8@&0J?>(~H_+>e52KQf@@b`yodcr!4&^2o%9B`J=gp4hLo0#l56w_!pNg z!F!z{1eD>n1cmSJK*!%B^LL7~GXZljh5NGoV0EXh=SkxeYeOL3&CHi@b0RQ3wY&bZXLGb*%tiyM4oTo7^UY?WHdx`B=+Q3 zHR!6Za)`h1LT~C&n^Wq{3whhSxa~j}NN@ zN@<}A5hDx-&c#$&jI|TVQg|Wpb3pg*k7;;Q$|UE63N*GZFc&N34kZCIJVd5!FsBFJJPm{xjoK=-kE=}86F zqQb4vr+BWtKfgY-e>fLS4fR)bRDGW8JaF)r_i?@WR#8sC_Xh+WmId%M;|8;hanH88 zP%M6iLGi${8OZ>AtNy}_kvg30i~);P!`o*gSy;w0#Mv_&x6zga__* zgmZyMX}NqWMYblS`T;qOPq_Vg_9t&86p?KXN?j6afg~&U^K=gc6C9SA2(RIkK`ZGG z7;vp*m_3sr-UPk6>lz=B+ zd3HZE1DHz)#Cmj;r{ojJ`|tHs_)gNx%+TrJ;if4tw~r^W{Mp`%e8c~Tns5@}Tzj*S zKPbjzM*w5Rv=cML9<~b$ZBPW`{^`G%E(iz2Myu8IW(W^^AqaOs2ak;NPXne17Zkzo z4GBSg9UJouQjBAD>4z2vLkIUA)*BfMY;T%k5m|U^hadsq-$>KVm4~YP{(R%Abc`Ii zC)I%(ses5uvSEK5D^w#43J=c(GR#%-kSWT3j3vv=Z&Su}W@N6uaxD-j91T z(d&cpFVJet#u@a7eEEvrRhwZEVf}@|lG#KN0g&dxtmYf&hXpKdeG(w!cj6iqRO2OD ziO-m|8M~%&UaFN4qml9_ZBG_pLD~ljC#*~&BorvD zlxt;=xNH^$Q`Zg_LeL1=zw}1YQ>LmGzk~88wN9p3=q6C@*lm|ZT+OeYxz~%CQck|1 zHha1R{iO-6WYnzv3Y1M*TU*<);`f|OU0t5nhvGoXtqzKDAns~SeEY+-zVahh*mG#t z(ftzcvJLm_&E#*@E}$sn0kV}&fPaLZC-nJoen*GM$CXaBYS7oHfPSDFh=$cBLnOCK z(jRXwKW3waj^JrawiAphDn&O<6{6tK#9dVBDgAKVV>=Ed=2q<0<(@&#D}GD&(X@*=--{AfG50owQ+)Onk50f)`6YD`Gx9>VD-Hl?mBp`2MIm&SrX-;;UD zsQydT5wzyGUDI0|g(<4vnc6&d&$os7D=0xrP3DIn2KW+GK)grhAXuI7_P3Pyb~DxgWNd}%UWVWfZ16-q?A1vGP` zmx>x_*;-n2r?yxbPID`JhK;8a@1@)pbC4l1YkjeJ1|Ll5_6#oza-)ki%1DWtF29me zd_@2|E&|>0*ZP|(HKFUPI$Qt}Rr2IpscqMKqm4d{aK+`QbpvTOs*2NuID=9=tXrN2 zBb+c5!1_qw3T;0-@2;s|951UUbHWmLyWeA!2o9Yl_o%2Skr}RgU|PwSF7HEe!Nsi$3F^ahE{niM>~Z~sveqbxAg|0HIdN?2@Iz!h6jE>AW@wq zlR7-{)A_lRaJ(Xhxfm|pVZz`6CZ_`H2d6diPRa|>WB0}NfkZ9Coh4z0;tjaa13;+} zB=b>qt#?<=ca#uq-bWe$vPatU#n@PrT=8S4%GRmW@g}LLX@(=Hr9X`3$aEkj!4t{o zkW+Jic4mq=T@k0M;uOER`b!H@{nJ{)1X_!ux~Z;$(&VB#`;7<^Hb?ptYh|vEj*hP+ z%j;NA?6b>B)}y)Z_Y=9&-2-$_9mjFV(1i*?Kgm&t)uL|u|hTG*UkrN z&Xx@l0n918pHH`DCvhVMygUg@@ftVl_(zV->>5mlQaX@6_6p=c)yt}#T&;>JlUtMH z0ry)g^;6rSNLzm2+H1vZDM@Zuy6C|qZsAF5O((hSie}?ILJh`te?L6>r!U_r^D_l{ z{zfs>+BM|6SdCncmji_VOyp3X;%tmtIbZSf2{E@E=81*IJU!xPSi98G2OqZ0*4R{+(k`l$;SfEnKz&A$U z75bCSpGEt+E!fUkI}DyV4@xP^E-WeLL>y*O#7;w9k4W=wyc4+Xb2@%_X`Jd!yBx1` zL~cHWC+U`hpu-SA)HX*CNAGf$E%>Q~>Q9*lO zcwjx1MM{Zj8Zj9*3kWf&%?%`vH-=)xy-=xt1)yS|Bf@TAfeJ~4C0sga?)V`o5do;- zBD@VdmgP!TF=*4^7WgI(%G%KkF2@LhF5@s7(9GaOVT4P4C{Vb`X?0N>-#umZ*Sjdk zL0x#?qf3O4Buq9YTpGp_HJ8NPe9Z>6@CHpaJ`h3>&ZlKPf0DvMabgZs68zpD`NT&e zc(8H+7sN6bTvsc~XzTORpya|$?akerge`JgMh!zr@LdM}r(lZ$v=Z~VJPyl1HS(2h z`7M!wf!K&5Plk*T@=(coy@&nN^2ipgs4_D~@~FUNFTwg!>(sbTNRRA@01Jt@u7GVg z9>*F$q<+(a1*-n*jQF%H0fckJGnR zW>`&Y2LFHxx^Up^I!_CFzvp}WGabXl`s4u=*7sNV+M_)mbnWwTzpf0gy! zEpZ=4RMIXT8xV>av>Uj95jnayTT>bN)bve@HIUgnGlhgOYlYK5Rb;nc@8@|0S6l6V zVYfY!Ee%6G6I}0nnBf5@U;t0uHMC4MU8GUDSv{$p>2cXfEk~j`SkaDddPBSTCFLWh z)AcQ-VDAUA#X<~FA|rZZUP^-%KNt8uf?u7FaMAV;&JS0{n!UWjH>ccI9d@@)fN9G1 z>eYY)RB0a06i>YRL$tLqLeIew4T>YP0beV~kaqDoq1J3G!0AVG38ka)!M?DL1U6{4WOpjldNz4Q{X7hVFPClM>>} zNQ1`?vo^6Sk^vrA(0Wk8Hxa*SnY>8ciT?GRb=TJ)^X#=y>jBMTF~;6hxv;HfsdnQSC{SZF z9OlYPZJ)DW^l~d7kciHf=(^-5>v|KqL^`40wgxouNchcdvprV`35tP#Xi# zh;kGa6~}* zIjJV8?6sYQ`YgSP=t$BYl@!a)siUB%t868r|KI6lgp<^`{L=W1$KgJ+;exD_lLwP# zt!{6N*g4LD<1Lc3y|{XsyzpaHgS4bMN^nLF5tT8f=^HVBGByAebUWT8#g^4uEQ?t< ze*;e?l13(ERca`ae(z;LeA#v0W{r@tveMvMJHkcfA9>gRnx0j19l~ij zBjS$J()t^w@6C-7ZI{H#eyK|H?xt>ZYDAI{FJ8~-a+ln^>(0w~qO*=MStl!{LjDQ1 zvgafS^-lY;!Ovb&r0k>D*lfIg!a2Zr`Qh(OMSu)uH$UtT{;UAREdWf<(jTD{lQmV2 zANwh1OFbR2kE*EM=v{lk4j@)aPOj!K^rOMH7K$&i9jBMicd~b>6Y~~*UQ-9B8^uG zchl~@T&ZtBa)I_Ni93u`Ko8#irt@RZ;CxC7CpBM|w4+@}MZ?Xzwc6anY+pB51FwM@ z4ru?O@7oic8T9NW11aVFWg^b+V!N{Egm6&*nNN#sBlQQ8<3_35jOH}P1U_>wtd9*< zi@jQd^Jly-o8*$Gf_sm~lH@kx3byt5vm2#<9vebs2k`jU?dg*Yc0X}Ed90%0oEd-~ zeRk5%EyaI(xl@{WR7~WWT~skRYCBi6;8{q>{voaEo4hM^;j-v!V)gw7m*d{=hd+bu z2|2A8?ZaG8OGf5%MYdFm|ARK8qv0ueKwd7uq7;+3{z@)vI2=K;9OYqc7h-pRggYj= zzO3S=(S3Vqq|M*BwPOkcjG`eCZJ+Rv2wGo@_jEOE{V56mM%uh2EJ(zqao!ocbx!;^ z*9PN7C6+Kg04>9YB86y6#8DaG?OhMA1gd8zZ zknAcYT1XXNXY`a)Yig*<1)!VUXI?G&}ykZvT_GcWBmaY*Lw9Xfh?QRG~CU z1C6lcHxU>Qx`=l;9|J|;uC?{8#n_Kwdy4GcQi|}W@vruB&G*^> zKR<*^uoTW=Ts1a3?Q1_i`>K7qJ#Gq$pN50QY)1x*@ zqz$-yH7LUTfc4a|^W@Xv29mg6F*+pPY+2OXtp#ne8Fpj#CUP>%r0{B-85kI}3yJek zGif(`5DUOjQ_3f{;%dw6aMQM*>g^75LKL?l)y2pGh5+#WYzp4jFqP+W15qNMRfh)& zjZnm>H|m=lu(LJ~mfEqMuFq|^7n++TjX|8DgG47^F+0zEvSh5m#Xf=Gj=TEp)(SAg zGG^zv?R%1UKxgxXPu5tzQ1vD7(_&UDN0qSEn}n?3tKc5GyYC29PT8tO>fc10kJkDM z30@iJfpw0~Lq-L3%2DhMrHw4rK%>t_i!M;e^nV@eD693uQ3mM$lBT{!IV zdaVR85!{`F)CbGK%t1%H#^#W;=#}gU^!WEvSFlsFqpOdj{crV!PE9w7uH%@EE*;Gn)Tt(;UH<78x$BX5Cf@wN(0rQy)T z!5FF6we8{ZlV??=&n7rg+7|0JQX&i3Qb9xZwW&27P;MWqoGbtNqAxZcla7Yl+u9Gt z!<17ve_}Gq3CKZrku>`i@i8vh-kMQ<3pl;`g12z%wj|mdLT^*>>piX@)&Ix<+;UHa zyM?`g%gPxM-%Kl;gt=ls@{7nKq^LFW`d%Sn!U*^;g=BLqUrGNhD#6?%Kz`=C##gau zyhM`d7e{NEAUXJLGEEOYA#bOmsg&`K(J|(CoDU70$2B@Wi+UFj_wiLei)37#NWNyjR*}4M8yP8;&i*{ zUZ$?!PXElJtN^{hW59RQM%p71LnL%=1`{@yC#E|kU6v_C#cHJ_*}1uiqg&@)bSW$k6A@-dd{ zuDesLu`2=S&of45W*rs1(;XDe-%NVr=u+ly_`xyZ!NH4r<4rUG^QS^6nz?_s+%|Em zPTUnlFD#zCt8@%St*h`^{7D6lJv!Vir^(|An}|!Bsy$`A~%&NhdAnRFca>fqlY`>n-!YpV;xBcYN3eye+t zBEDJ&(Uvhit>Asy@!}1S=8fQalKGY+mG0A~1c*MGk`*KE9? z2Q%00-44H7l>5@1;W{m@&g+yJ{s~ow=SSC=1Zdyjy5+IAtS?-edw;_ zd-zu@s+$!dt-g;&K^Ey{N+X9>tu@cG^>=6Ycg)_8onn45hoIE{C2#7kP}AqV`+WPf zGZYVD+_~gifG82Cl|@WvXJlgzh`ysj-ZL%l)M~v;r zESS(Jwq^R2Nj}h_*{*woy-!w9*+yE16e;{tyic#uK0};&sc^>>jJuIrB>Yi5)bZxB zOmPSt_kN|rAGRO!?$%2*GkR~ZV+lg*><1c5WCU0qN`h^k3BfT8Hc(aV0=y}Cd*#FB zHqc!q&}d-)2s^f_HE3yf0Oe|x#0T)!FP{AdoRN`QUPf(`!&`-{7P;>bAe zFMgkX5uCzAu12%z&`&8deMz_c0S+k4F&oY2*@O2B{eMDDS|XU<R%G%kHV+3%Aq@7K?|_mbV}a$V4GULVEuRD8#^X>f#{4eaKHC(*Tu3 zcSKC%0WrcT7r*@E4ai3B;InB$e)dh|hyQ60_&teUCtO zGGK=yQqy}RYr$h2NXp=Z0sIG$P9&`(J#+H{PD+&0?`x*rNxyr6gx9}{)QWS5Z z>!#gyiG&bhA#ruKkH=x}YhE@>Kj$JWfN6v60|n9Zm314-Um#QQ3v}A;LXFd@gE=65 z@r6m)A2l67_6XohBLN5m!st+?w7mQ?*w}%~mLs|i2@uQ}Hn{!bXN%iO-qzWzeKu7@>O?Yp*Qrwo{{|ke>a*&pkQ~)ZLDrnDDCrfqItQ${b zy2t$6RXzVDX>e%X%5z%HVe(azLwy)U;0&vPL_J`&W0CbZRs)e7h@Hl^KHslKHz#n# znRm#mK|-pB$6|`*XT8;2t-^M#)$iAmHAa2U=!5_6$8-TDys?)TOh7OwWcZC}myFp1 ztG+FGXUJy-nq;08yJ)aqY=Iqq!OA+knu%6CA~vZihh=!dHq&E=3}p~>D3#+0m)0YO zKw+ep#_i*-M|oEU^P}U_xM2wBviYwMgoUfF zT_c)Zj*aPsiA*KinKz6}qxlrhj!2vrVMoN|mgk*U&@MrKeT(AN51w{yLNO2&kyxPm z_1$uI6HG|tp4e}lRFYgWDrO-k^SUVZ8r1;}XGH--W=h%OsolQ&=iY+sQZSxQS=vom zS(79t5=aUrDMw#8Y>j+AK|>EE;d>Y6GI9(;wNYFT3cD z*b!~*X9S$q^I32gPvW{ zaCz zrhAt6vrK|4$Xqk>gkJSKPjH!wT=pCP8h&QbiJLYUJ$BC8AlXU}AgLH=0uBm+oe_L% zu;jhM@b@k7tf(P24HEu*<9`>tQcpC~+$tEapn68rf!swGZhf>%u;WctFlZ6Pjs+6s z8r}Zptgado7#qfeWL)fLCJn#2pFSbS1W~}`(Qxiq3nSu`MV&q+(%`c$bmk#(WV=A} zZ4^G!uWJCX`An?N5-PmCl=V->AmOFEh=Z-+cKhqWZhc=Ckdc5qE+seg z>j1G58gIO)*!et;!`@itkA#XZ$lKLruf`kRZEx9-FtTmr(%bj{CkC;5f22w2HZswI z8uGNB(coaQ_2g{UI@rWoX2X0|iS#J?(II%sm)_jpRP(33UyBUJEEcCI*;5)TJ3kj_ zxcmn~3R?bW2=Sm}f0w2V7RMhCeLG3^)1n{WsyaX0UG2tKj^)S@5qPeN3SQbG9XeiU zNZp@E7}yPLo3R!0B{QnJi$r!yiuMv9WRZC~rvzx>ZN(xUB+=ZPF5ceuC|t&yr#q$1 zjs#ZK6c_>NYK8n$=mK!*B=sl)6u*$~%^M&x@Jd1auHSJR$c{9+5KzE@!6_E~4&+#F zE9)&AVo+LnQT%2I?EJ)gWV-fI))0B|m^8abBGUciM9Kffbid%kg=zGU)_*j2ISbRt z3w@9tVBlJz!39&);x=`p!uKND++w6b4GHODWSAHK42yR^U_-K_k-k6Fbh||F6;x_? zJ%fvBlhmc*;JH7~zdj^c1jE>)=B%!rq%Q@~B=2-66R`fJFziCTDODSf&Z}yoi?0XO zAPLB1y5cP*7}IOQ#GuG-qWE22fAmX7^?3CL{z0huK)pDXKKa3tWsK;79BQFp)JK&4 zkUQrJ0g{JNUTV6ndZLgP257W+1zX86ZIJH^K1&q3sdOI7gRV!!20e z>8Qlg5)U-7f&7AZjuEW53DVc=m@AGostL@;|X82fb75e~T)@ ztsHX~f&$>q>Zbh4iCr*OZXnJYrc-<#6ckG*3$-6VOqJ;=*V^b^u8`hIfRVej_*W+W zqADg{uMnQ3`3E2FO)(50P_Zs5?Ia(rt>L>;HvYIm4Ww6lWhoxCW4j&mLYVf>y zy*EiR2%T4xNr0q-;Os9jwk4A(9-dRB6M!5}Dj*BIY0lvXYB9j5`ftKXd4Tf&YONSI zkwWeS0f1)%zgrR55rJ#?K8@lr8X(>R{2o#xV`D-Ere+{v=k!Lu=*!h@{nSBfkh

    #o{idOFKylBK+@`f{8eZo&cDlLP}sJA;;rBK!3{6J3$ z&zg<9^*>zW6`}ROHG!)uPTMK}gKM;^&7PKb^`K4_rv67+L0IZ5!9YxR#s#P2D?A*z zfY&J^$FA?Xd0{5RQHn_7bh7zY#d50bjnRC+gJd%ZjTm)H0C<@hRfe+5Om{)eysPwb z)snneJqWc*dCpI2r_9uUECe$jDj>OH1_s@rt_>8Gq=?vnq|X%X&Z4p9#i{@T6*%z* zogrB9Gu?HYOHHHyP$sq=G;UuTW++vQcEDeX1^}m8vK|;D5*iKGxuuY~wp9>62GGbc zp07lkjaJ+Jzf)K~VEw-;EM)Ekd!&9D@(AD=^M*cS)ir{!CA+_ajuE#&$(OB_){zcGgUF(g{jh|D*Hr6^eauk)+%VD+a`@_Yyb?ET${;qe5L>Mw|d11ff0M z>AcUCY@5*9gT6Ru#{zA^<8N}k`&I?Zz1wN?#=*d65#&4Uz@hPybA8v>GhnIX zLC4wWZvh^ZB&ajK^Cevktp}o6?;z>V1N8`KoZ^76h-3ym*N+*{yvIg%Ip zjL-u_e`r1z+Xamfk`@?A(^FPbKM=OT+#1=`P-_|?+xONPKRQ4Nyo`z9f8v=`0Z_q< z`Vom*2qkom z5mx0I{64K6u#W|+MLc#v#LSVcL&af8+@NK z=`_7{<(kVZui6oA9l=k55lFVXfNG8<-5B+9;>xAxI7t^ zt2AufZ@T($S+%7v;X-Evrt*}4$@>M(TT3@Qg84eN|JrX^x=U%cYbGMaHC(3 z-AB+)C>ABZ)mG`_By4!h#l#WTGS;?*AdL9AHue zd+RYySBgNB89qO#7r}Gel!(u&j{r@eIK7u!4c3RdKF26^2&>TWr?awE<{LpSLqlG> z*ufVjkdpW|u|-kMpW<)goF&-IDyf|i&X1e_GTc@4wU0cJlz6{_m@BQ|4bW=zsLCZ? zIGqbIAd5VK6?cvr9>LEu8AMj+lfv&wDi^T=@6H3VC18N57?~V|SIE%<&AdVG^Gm%- zsb1T2vsG-6L}}=azQaa^h2jR7A;cod{wVPhGul6-o2sRh?ZlXBIDn#ZK%sE+A#!3L zg^KdxS>}pgx8%!V?ucF$R$S8q-_+|M8;_K<>unCk`C)svpdy zyzC}9GqPXIzsSum2$mGo;(^8dVhr$Rcw zN3?|#*hyiyaLFRjObTw0UNTt3M?rki9!=$+wWGau74$cO6#+|C3xv25&G$I0=D46y zMho+}#5K1UQwvS{YpXJX3VSP7Ft$& zaO&1OusGV?wBbi`Gv9qFiuql_$SyW9$LYwV^o z8UEJ{EtX|24($Q(hZ1WyAecZqefmn{^ zVI_0fegb-~gmow>GlNTEEUm}fj&9BV&UJMk(O0fw7&v5+mp&lkO6Nh5uifZ+KZsOq zK9L8mccJx!XJ$w(h#KWbMd4Ok&O);9(nY`&e*q9@^8mHcS`cztS#hlJPSK1+Pp7^Po}Po=Do@w>SH=ics;V_^k)43WwR4Jebdg zUZ;FOfAp5#1CECA;2LoL{mof)_~&%4);4pp9vE2S4wIbEC?fvW&4Wsy;`n;{u-u^K zv-(Gl-i;M-`3`1C#9qs}+RcMpo8tKqBmh(ui=j$;h-Z2i--(!y;tFz@)agc1vu1#-#BD5!O5~i_*y+1&!3!mK$^xfS5N zH|#bTN|IMA)mE7a{>lZ>wy>!VD462fu49gMcV!YcEqz;_p7i=-!N`1Qa6c$CvRX|J z)2i!WB&b88(xQoO0i;<({ZBKtun%{_IOc1=5S&&O2J69qc`C~wqnl~Jl?{jI~(c5eM%sy^yA^WE;TSYib_2+yc7J9+SKkq&kNkDoB;=QCK_NpdO+qV%0(G!egyG1U8*)I?3Pf&IAG*orU>Qk?G$VbIHlBXCd|7}?|F*Yo!zvV#^BS`Vwn`xKWmz1L%Ja2S4rnv!n*a`5bd&z&e;=7#3&L#(J7q@yW zC|%r7X4#Ppa`FS6Hw&jrZtCo*Irpu_hGSy=j;cH15e}&2nO)}fC*8#vx`*-+>jaxk7NH-^uoRD!$%q)6-Q+s3_dO)1CVe8 zNlZ5Q%mT^wV`q1TYNQm5l@@(LUn?Ho zuD-QWVPuRd{`ho4ZLZ^dZeS1cQLUv!J87aI+)aCa<1P|y(q@AJvxHEH8ME66 z&Q<;EyyulAz37lz4@%)iVMSEI2J03Wh+XEcz-yz0xH))So@M_>NgA_#as2Es6UhRm zbfH%EpXvmF4av6Y&~*u(`SDTwjYCj>2u{3f$v_5MVmtyNC6cC2wxq7lXusK&3~-vsY}61MPRUbvmOejiz!WQ0 zSHT$b6dbs42#ad91uN`FdO3`5^o>F)>yJR9prFbp(z&r$87y+|w)8aPYlg!K{wr+5 z%SV_zn z*kUah`DEbZH7B;asP6nRIa;E*L!3@V>X&2S)Cq!r#^Gpv`rXRL%>$|EaBY!+IqM<6~Ufi=_) zp4i{bGB!&ZC1LZjC+99(c}5Qz$7UC$UXf$?ijJ~-K4-~&5_{UtFQR7Pp1UST>Nw++iod^D;h>Bc3h}#9Kb%f(ipTGw5mP7hd6LjqEv&DbfgMw zH9j!%eaMlF`jRd9M4H*!EMNLQr6IzWe|WWj^LNSCf4`ebfoDuwaQAAtO1&j5NgzLt z34stkyvspS7#scWoaEY((9(a)VAImL(SwLS?CeQGh_aRe6p9mnLeLVlt56#9PLwSf ztqM8Xz|)8RrfF?4U$L%d#weyp?BcxR4{cm$IEi~ zZCly@!_j*n>?RT(WeBHnNP;`vZc5)93Tvt}uwsBBPY6Rl#|7sN(WRdQ10kQ0+?7AV z6KU=7Jr&)Pcg-5dJViF0+9SO&iwzb7-#F!uW4EC`-gXi(5=;fH;1bCTcfq{IQf*-eQ<;6E@2@#IAN$8(So z31aA4{}`_jGf?RZ3~dgf7|6hDLzq0NP!|bIC2ecVPSSX#=Co8(IC8g`ol}CkS^fXL-Xt1P7Vc!S<4e#a%KfRwX%hso6a6gxm!9 zuoe9rUNi=d8qP2op6Tauu^vpw~4V_i(zQ20f##eU>c^W2f- z5r?!lcF=AA1W-Ch^}5y}`9XHKTpo7mm&P%8N64gbG;U58+6^R7Q{-8l?*rw&JMUX; zw|#0JD=ylupXwqQ^lzXe;tEiyn?JX=GN>4Zk%g^YgxqK!`3uotg0%p_-ZO1Cv!#vM zYNQ>mA(14=P9>2XLN`|^1#<}s2Diy}kirPj8>W8wvQJ{xw}JG2c`8RXL)6Pk zaS0D(&E*S;DH)qOuSVx!rH`K|I6ZO2TICSOAj?dMHzS#(|)x@;@Z z9hYVIRi7uU+U1`3lPN9eR0v+^+Gm`AS#329TUgTNhEBUH3*QSc!JquIMS7Dh4Z?YIcbN|M)yjLkB!0lWT9QDlPMnk$!RH9u)zCNAi+v>MA zM06Ng^^!u0`31}`c3<ub&xtbcL8fN1>xo za%er(=1nX<>23^5_a(4kJ;)W*i&{CSv%y1OY)HSOdu(tZsEHB3OXShX0xG^WN}nVV8PUT;Lnv)St-;KzE?JZa71nVJx+x?4}MEbo@|i!Y;yE>0c(R zIVZJe zA@6@Ex*O^xAd-f18oFckT)Rk0$vb$N=pO6ly&akh@tK~|dF)o#h=w9)t-f%8*mv&T zs+v*1IlkZ*7mt}8B6=dlg5Gn;%>FRH68zEP+e`a%FOw;%JsiNeVV&tMHfZb1x65c_ zYre2(aPz0}FxBJ;Z_~9r2AxAt`#Zw+&L2{u54_BPO{4iU5u3^F1FZVyDCr zRGt-&9asr6O=;O7XZ0dLf8dFQIrE5%kCR_7RM0>qHV|^EJJ9RjJeMryJ#=Iq#|nuE zKTir~HLxN$etq&h%y{~dIF9d5Gt23#Z+skK!j$u(U>0s)I2nBOy?$W?66kTcru&x* z6ZxkL!zk$-wYL1zvQ~G;j6v)mAYQ4#Qc(GU!wU(T+muIc6-_l%7Oaj%mc3XlnkysI zS2^5yaYWnb5?u9HC>iIiDQ}Ig{i@u!C%8QX)jI|}lPmAnfkD+$R({a~@<40Mo11wL zqZ50xOubvTby?T{w_D*US)?8%Dd~-}zTd54=R%#B(p6}*d42u%?bjo>kl2mvTV=GK zX>u~D^*YjH0u_<5ts+!sna|#ba)w$pmwYT5i=XMe4#zZZi>{=opT*n#s(%>R`hLOq zR7fMY-pSvLiM1HH!(CbqEyXxse82r?2qdU0e`E(mu>^aq5^YMMh8EiEThYvW_`QO= zK6pH=)DFq?V2Fka!J@7(PzuNwhgjC(hiA=x{QQg?_V0G zLGCr{%Lp`Qn>$jhcyPRg#MhU7|BQ}?rsff(S#yW?;8cAL1uU9*-QgP?b8{((|I!R0 zHN-33&FQ`)PguAz0dJfmJh~nT5+xl^@hywrNXUaI`^Hv!d&O1Aj*qdbV zzs4?2eRc#!lsz2`zd4)2q8BC%~=#4|hRt+|GzBf(*hE_AyB^57-^>6Vl)XH6Ec!-@n%p@(yIX z$8eH{gV+w0(P^QrzYC%c4OX7R_N!lvs`+;>11>`nh*GEgCHRCR!gxOmwArLRo*R^| zv4aAd+Z|wMK&1CtQ~vWDWHanOQ+JiQHk~{XNthnm^D|~u%ee*ME>Hp?)!P5y^yYZ1 zi~hCB1>KvWDcW~HjBU#@Rf%O{%J6|i8{4`2{g)v&pc^e{?$_21hgAottQtpT#uwiH z3H-)Y&ERF2j`Em~p%2B}zZ?-UQs(QW?E81Nf^#~Ek3h_Jt+!o_Ku#8HMgr0mxj`oV zsgdiod`cDaL0-4gng}kuKWHR#+|HkoNSZo9DyV#pNps?a77#0c9Wbz zk;mm*G0|xHox=}1rB%I62=K2~07sNjEPeOXrg`ASi~yMKv6=u!NR{xT82A-xJe%jZ zc%e^#`0N;0HcKg?2vMI`vwB~gAq|Q_2H69QJ@r=`xHs(gZKH{I$qNEfls7D#%G~76 zH6j_)k%;v?m#=bpwvgiB&Y!&$3oVMloQv)tx~}QsdcC8VDxXw5 z`L1w3!4CW81CWMd zUk%yapUwdJ*yj6(r@Y=Hzd3vbut9N!jXOp79)yWhiX`UoP3;!%!J~xh%K=_Y*k{6) z{ZVYDGU0R?r8Y@F@xLCYshZ5jH_4mjU&y_tR%o_j!$kbRPoS;N&ZhNq)O!cDDT^?g z%eV>mi-%{9t_i!6q@$v`I5*qrWHZt&d?of=3oBO2%=qgx?+*73iELQi=}9~l%A?)t zcFwi71!-C7xyi89aENFt3M%H>N4htK%iyRsr(9qVz9MLAX;p4%bs(;ZBuqqkQMF{i z=<-0&)3CCEMN-*}()&k4b~o`s1lu_LKy~0R}}VRB`hq3Eh4B zPm!#&{dCU_-a}Bwu#^rvufp^{@`!o2o-P;;>JsGLg2>LZP~JrWyumeI3kv_-&0JFho&>L3 z;+G+)5~2=Sy9ppm1ivjNFjjeGh(PKk9<=A?nxmWzLT){z;ql~J#4MaSDA*8Hf#T*1 zT>+=|F3k89RTBo=TVWVSIKQ?*Z^Y>~oZVw1`Xo6xtnR?uy1^z$5>#|A) z>y;mz9L&Pb^gh~~Gt9)81>oNObY##b+b*`hE#7#4&q6sh#@`<7=TXnFWnaGWZ|Cs? z@MAz|m(4b7cwO#A@r^BwDIN}#XeFWr^heJiX50V2_PJ#w3Nqdl8}=(k%>3a?oMRcT zvw!SAp)W#pR%s$opY{$8>^tScJYK$!;V4=`z`QrcRLwU?Z>}v>2AiFPW?25=f>865 zB_yPmPPu_m)C#6L(sYck<<7X0JJmi?Fsc!UG#Lv&D6lcs|8n_mitgvEip8Z-Q1IS> zc+m_GGTgxSun@D~Nz39;7#QN-q>kdjz$B4@9H*(z>b}LxsYa`aCF8B4fA@+cs_(KU z%717f$n5zZ!xTvToSNb1>M#XB=rjk1oF2^hDs;2^MGNQW6N4Sr?sPS&IZO>%=RW8b zC~eKRvs?lTKNUV*Wi-TORrEev%R%?Z71)*4XZj0oO%7=zW{y%Zm^o0?!P-6W(IPT& zm~{H1o`X%#Ufs&#o9Z~rh(zAar3@GCo^|bT5kbAyZluAh$5^Y!Mk~*9fSRsnA{F-O znvX?B0nQa-YbM7FPpZf8I6Vd!HwDTOUeslAtD{!uP4U;a?ro7pZN|&*+u2e&Rn>GC8m&RguBi=&^FeYiXyq5EoU1{JT61STJ z(B&E4vUv05g(tX6NQ1J;r>khbAI6|01rObLc+>**e4HP1cyZi7A`AE`Y5 z3eW=lENA|tMaVmlTaM8%E2xXlyW@Eq$Ne1>B$u4CM8HODg(V^BD`?6ZpyQbIu2uFM z1J8XIpz&6PRkc@zGf#<)H%~X6ChKLPR7G{MjZE9dmwC*l^b}CL(X0?dnc0;E-O%Jm zBhaa>>9#>^!h>y1RLXfgsYzG#<2-Lsvz4gz$TRYC`rv|%{9T&Gy<$3_N*RL6y(_g& zMB*c*iy;pPmh>XYA1$zpp=I?mD`f+aO7}~Fpy2%5xb_5{J*1JhTGePX*WMpv^Zh(_ zvX!GXfvPpEizRzrO;t5%_WKu=69x-uo2O1%l5Y-CxWt{e8T(2}fgT{-N78o+*O`V4 zag1qHj@eZ>n%R5lPvag0DYlFRn%({#AQT4;l^yqN! z>yb>NR<1$8!S5_04X77PqMDHI`#MJEJjRTRrhiy(dM<0Ii;Fd;uMwkrCO7uLqQmy;UzW>WeQ)e!V5Z2CR^oTvD5U0>UC2> z|0nzu=D#}n8LBtkX~-tyvHcB4kV*!NPl>#f<7vm1!^~ryu1&@>3c~W=zxEA;*3cri zt39HT0`I*sD{(QAq0V)a_}T|yaw7e;f*z|~d~4j>ubb9fJtpEPzc!vLzfo^IQ(e%| z`Iv2Dd~$T7rOAL>|NT3K)DWgbwt6g_(yKE}F8ceod?^a95jmkTij`k!^Lx}`+%X<R!T z1!wwov%0LVj}~L&_g#KAcy+J4&e2EyI5+$aqlFi#)upr)@=2+sU;Ej1wb=809HZOx z%)M_yIuWC{ELzO-%{CG>uB9G!qmm+Ut0Hctw22)5{KzA#&Sf9(5%U8qu7>gi@J~rj L?NYjo;nRNsuCn5^ literal 0 HcmV?d00001 diff --git a/docs/spec/light/pics/transfer.png b/docs/spec/light/pics/transfer.png new file mode 100644 index 0000000000000000000000000000000000000000..7642e996cf323d1483ce8b1b3aa1efb85b1c1ce6 GIT binary patch literal 18492 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 literal 0 HcmV?d00001 diff --git a/docs/spec/light/pics/trustPropagate.png b/docs/spec/light/pics/trustPropagate.png new file mode 100755 index 0000000000000000000000000000000000000000..a743cfc72147ad521c2fc5be292c90de47faf6fd GIT binary patch literal 49750 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 literal 0 HcmV?d00001 diff --git a/docs/spec/light/pics/updateValidatorToHeight.png b/docs/spec/light/pics/updateValidatorToHeight.png new file mode 100755 index 0000000000000000000000000000000000000000..b2c9349b6b455ffd0854bccf92819937f98a25c7 GIT binary patch literal 18077 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 literal 0 HcmV?d00001 diff --git a/docs/spec/light/pics/validatorSetChange.png b/docs/spec/light/pics/validatorSetChange.png new file mode 100755 index 0000000000000000000000000000000000000000..16dbf39be7ea37ec240b429623df535e10c766ac GIT binary patch literal 36169 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 literal 0 HcmV?d00001 diff --git a/docs/spec/light/pics/withdraw.png b/docs/spec/light/pics/withdraw.png new file mode 100644 index 0000000000000000000000000000000000000000..2249b5e34839c9387e4188e14d39855993a75ff4 GIT binary patch literal 20935 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 ZbfkgttAP#bllBJi_<08$sPYO+`xnx4A^QLT literal 0 HcmV?d00001 diff --git a/docs/spec/light/readme.md b/docs/spec/light/readme.md new file mode 100644 index 000000000..d15901b47 --- /dev/null +++ b/docs/spec/light/readme.md @@ -0,0 +1,101 @@ +# Cosmos-Sdk Light Client + +## Introduction + +A light client allows clients, such as mobile phones, to receive proofs of the state of the +blockchain from any full node. Light clients do not have to trust any full node, since they are able +to verify any proof they receive and hence full nodes cannot lie about the state of the network. + +A light client can provide the same security as a full node with the minimal requirements on +bandwidth, computing and storage resource. Besides, it can also provide modular functionality +according to users' configuration. These fantastic features allow developers to build fully secure, +efficient and usable mobile apps, websites or any other applications without deploying or +maintaining any full blockchain nodes. + +LCD will be used in the Cosmos Hub, the first Hub in the Cosmos network. + +## Contents + +1. [**Overview**](#Overview) +2. [**Get Started**](https://github.com/irisnet/cosmos-sdk/blob/bianjie/lcd_spec/docs/spec/lcd/getting_started.md) +3. [**API**](https://github.com/irisnet/cosmos-sdk/blob/bianjie/lcd_spec/docs/spec/lcd/api.md) +4. [**Specifications**](https://github.com/irisnet/cosmos-sdk/blob/bianjie/lcd_spec/docs/spec/lcd/specification.md) +5. [**Future Improvements**](https://github.com/irisnet/cosmos-sdk/blob/bianjie/lcd_spec/docs/spec/lcd/Future%20Improvements.md) + +## Overview + +### What is a Light Client + +The LCD is split into two separate components. The first component is generic for any Tendermint +based application. It handles the security and connectivity aspects of following the header chain +and verify proofs from full nodes against locally trusted validator set. Furthermore it exposes +exactly the same API as any Tendermint Core node. The second component is specific for the Cosmos +Hub (Gaiad). It works as a query endpoint and exposes the application specific functionality, which +can be arbitrary. All queries against the application state have to go through the query endpoint. +The advantage of the query endpoint is that it can verify the proofs that the application returns. + +### High-Level Architecture + +An application developer that would like to build a third party integration can ship his application +with the LCD for the Cosmos Hub (or any other zone) and only needs to initialise it. Afterwards his +application can interact with the zone as if it was running against a full node. + +![high-level](https://github.com/irisnet/cosmos-sdk/raw/bianjie/lcd_spec/docs/spec/lcd/pics/high-level.png) + +An application developer that wants to build an third party application for the Cosmos Hub (or any +other zone) should build it against it's canonical API. That API is a combination of multiple parts. +All zones have to expose ICS0 (TendermintAPI). Beyond that any zone is free to choose any +combination of module APIs, depending on which modules the state machine uses. The Cosmos Hub will +initially support ICS0 (TendermintAPI), ICS1 (KeyAPI), ICS20 (TokenAPI), ICS21 (StakingAPI) and +ICS22 (GovernanceAPI). + +All applications are expected to only run against the LCD. The LCD is the only piece of software +that offers stability guarantees around the zone API. + +### Comparision + +A full node of ABCI is different from its light client in the following ways: + +|| Full Node | LCD | Description| +|-| ------------- | ----- | -------------- | +| Execute and verify transactions|Yes|No|Full node will execute and verify all transactions while LCD won't| +| Verify and save blocks|Yes|No|Full node will verify and save all blocks while LCD won't| +| Participate consensus| Yes|No|Only when the full node is a validator, it will participate consensus. LCD nodes never participate consensus| +| Bandwidth cost|Huge|Little|Full node will receive all blocks. if the bandwidth is limited, it will fall behind the main network. What's more, if it happens to be a validator,it will slow down the consensus process. LCD requires little bandwidth. Only when serving local request, it will cost bandwidth| +| Computing resource|Huge|Little|Full node will execute all transactions and verify all blocks which require much computing resource| +| Storage resource|Huge|Little|Full node will save all blocks and ABCI states. LCD just saves validator sets and some checkpoints| +| Power consume|Huge|Little|Full nodes have to be deployed on machines which have high performance and will be running all the time. So power consume will be huge. LCD can be deployed on the same machines as users' applications, or on independent machines but with poor performance. Besides, LCD can be shutdown anytime when necessary. So LCD only consume very little power, even mobile devices can meet the power requirement| +| Provide APIs|All cosmos APIs|Modular APIs|Full node supports all cosmos APIs. LCD provides modular APIs according to users' configuration| +| Security level| High|High|Full node will verify all transactions and blocks by itself. LCD can't do this, but it can query any data from other full nodes and verify the data independently. So both full node and LCD don't need to trust any third nodes, they all can achieve high security| + +According to the above table, LCD can meet all users' functionality and security requirements, but +only requires little resource on bandwidth, computing, storage and power. + +## How does LCD achieve high security? + +### Trusted validator set + +The base design philosophy of lcd follows the two rules: + +1. **Doesn't trust any blockchain nodes, including validator nodes and other full nodes** +2. **Only trusts the whole validator set** + +The original trusted validator set should be prepositioned into its trust store, usually this +validator set comes from genesis file. During running time, if LCD detects different validator set, +it will verify it and save new validated validator set to trust store. + +![validator-set-change](https://github.com/irisnet/cosmos-sdk/raw/bianjie/lcd_spec/docs/spec/lcd/pics/validatorSetChange.png) + +### Trust propagation + +From the above section, we come to know how to get trusted validator set and how lcd keeps track of +validator set evolution. Validator set is the foundation of trust, and the trust can propagate to +other blockchain data, such as block and transaction. The propagate architecture is shown as +follows: + +![change-process](https://github.com/irisnet/cosmos-sdk/raw/bianjie/lcd_spec/docs/spec/lcd/pics/trustPropagate.png) + +In general, by trusted validator set, LCD can verify each block commit which contains all pre-commit +data and block header data. Then the block hash, data hash and appHash are trusted. Based on this +and merkle proof, all transactions data and ABCI states can be verified too. Detailed implementation +will be posted on technical specification. diff --git a/docs/spec/light/specification.md b/docs/spec/light/specification.md new file mode 100644 index 000000000..48c87d047 --- /dev/null +++ b/docs/spec/light/specification.md @@ -0,0 +1,318 @@ +# Specifications + +This specification describes how to implement the LCD. LCD supports modular APIs. Currently, only +ICS0 (TendermintAPI), ICS1 (Key API) and ICS20 (Token API) are supported. Later, if necessary, more +APIs can be included. + +## Build and Verify Proof of ABCI States + +As we all know, storage of cosmos-sdk based application contains multi-substores. Each substore is +implemented by a IAVL store. These substores are organized by simple Merkle tree. To build the tree, +we need to extract name, height and store root hash from these substores to build a set of simple +Merkle leaf nodes, then calculate hash from leaf nodes to root. The root hash of the simple Merkle +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), +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: + +* IAVL proof +* Substore to AppHash proof + +### IAVL Proof + +The proof has two types: existance proof and absence proof. If the query key exists in the IAVL +store, then it returns key-value and its existance proof. On the other hand, if the key doesn't +exist, then it only returns absence proof which can demostrate the key definitely doesn't exist. + +### IAVL Existance Proof + +```go +type CommitID struct { + Version int64 + Hash []byte +} + +type storeCore struct { + CommitID CommitID +} + +type MultiStoreCommitID struct { + Name string + Core storeCore +} + +type proofInnerNode struct { + Height int8 + Size int64 + Version int64 + Left []byte + Right []byte +} + +type KeyExistsProof struct { + MultiStoreCommitInfo []MultiStoreCommitID //All substore commitIDs + StoreName string //Current substore name + Height int64 //The commit height of current substore + RootHash cmn.HexBytes //The root hash of this IAVL tree + Version int64 //The version of the key-value in this IAVL tree + InnerNodes []proofInnerNode //The path from to root node to key-value leaf node +} +``` + +The data structure of exist proof is shown as above. The process to build and verify existance proof +is shown as follows: + +![Exist Proof](pics/existProof.png) + +Steps to build proof: + +* Access the IAVL tree from the root node. +* Record the visited nodes in InnerNodes, +* Once the target leaf node is found, assign leaf node version to proof version +* Assign the current IAVL tree height to proof height +* Assign the current IAVL tree rootHash to proof rootHash +* Assign the current substore name to proof StoreName +* Read multistore commitInfo from db by height and assign it to proof StoreCommitInfo + +Steps to verify proof: + +* Build leaf node with key, value and proof version. +* Calculate leaf node hash +* Assign the hash to the first innerNode's rightHash, then calculate first innerNode hash +* Propagate the hash calculation process. If prior innerNode is the left child of next innerNode, then assign the prior innerNode hash to the left hash of next innerNode. Otherwise, assign the prior innerNode hash to the right hash of next innerNode. +* The hash of last innerNode should be equal to the rootHash of this proof. Otherwise, the proof is invalid. + +### IAVL Absence Proof + +As we all know, all IAVL leaf nodes are sorted by the key of each leaf nodes. So we can calculate +the postition of the target key in the whole key set of this IAVL tree. As shown below, we can find +out the left key and the right key. If we can demonstrate that both left key and right key +definitely exist, and they are adjacent nodes. Thus the target key definitely doesn't exist. + +![Absence Proof1](pics/absence1.png) + +If the target key is larger than the right most leaf node or less than the left most key, then the +target key definitely doesn't exist. + +![Absence Proof2](pics/absence2.png)![Absence Proof3](pics/absence3.png) + +```go +type proofLeafNode struct { + KeyBytes cmn.HexBytes + ValueBytes cmn.HexBytes + Version int64 +} + +type pathWithNode struct { + InnerNodes []proofInnerNode + Node proofLeafNode +} + +type KeyAbsentProof struct { + MultiStoreCommitInfo []MultiStoreCommitID + StoreName string + Height int64 + RootHash cmn.HexBytes + Left *pathWithNode // Proof the left key exist + Right *pathWithNode //Proof the right key exist +} +``` + +The above is the data structure of absence proof. Steps to build proof: + +* Access the IAVL tree from the root node. +* Get the deserved index(Marked as INDEX) of the key in whole key set. +* If the returned index equals to 0, the right index should be 0 and left node doesn't exist +* If the returned index equals to the size of the whole key set, the left node index should be INDEX-1 and the right node doesn't exist. +* Otherwise, the right node index should be INDEX and the left node index should be INDEX-1 +* Assign the current IAVL tree height to proof height +* Assign the current IAVL tree rootHash to proof rootHash +* Assign the current substore name to proof StoreName +* Read multistore commitInfo from db by height and assign it to proof StoreCommitInfo + +Steps to verify proof: + +* If only right node exist, verify its exist proof and verify if it is the left most node +* If only left node exist, verify its exist proof and verify if it is the right most node. +* If both right node and left node exist, verify if they are adjacent. + +### Substores to AppHash Proof + +After verify the IAVL proof, then we can start to verify substore proof against AppHash. Firstly, +iterate MultiStoreCommitInfo and find the substore commitID by proof StoreName. Verify if yhe Hash +in commitID equals to proof RootHash. If not, the proof is invalid. Then sort the substore +commitInfo array by the hash of substore name. Finally, build the simple Merkle tree with all +substore commitInfo array and verify if the Merkle root hash equal to appHash. + +![substore proof](pics/substoreProof.png) + +```go +func SimpleHashFromTwoHashes(left []byte, right []byte) []byte { + var hasher = ripemd160.New() + + err := encodeByteSlice(hasher, left) + if err != nil { + panic(err) + } + + err = encodeByteSlice(hasher, right) + if err != nil { + panic(err) + } + + return hasher.Sum(nil) +} + +func SimpleHashFromHashes(hashes [][]byte) []byte { + // Recursive impl. + switch len(hashes) { + case 0: + return nil + case 1: + return hashes[0] + default: + left := SimpleHashFromHashes(hashes[:(len(hashes)+1)/2]) + right := SimpleHashFromHashes(hashes[(len(hashes)+1)/2:]) + return SimpleHashFromTwoHashes(left, right) + } +} +``` + +## Verify block header against validator set + +Above sections refer appHash frequently. But where does the trusted appHash come from? Actually, +appHash exist in block header, so next we need to verify blocks header at specific height against +LCD trusted validator set. The validation flow is shown as follows: + +![commit verification](pics/commitValidation.png) + +When the trusted validator set doesn't match the block header, we need to try to update our +validator set to the height of this block. LCD have a rule that each validator set change should not +affact more than 1/3 voting power. Compare with the trusted validator set, if the voting power of +target validator set changes more than 1/3. We have to verify if there are hidden validator set +change before the target validator set. Only when all validator set changes obey this rule, can our +validator set update be accomplished. + +For instance: + +![Update validator set to height](pics/updateValidatorToHeight.png) + +* Update to 10000, tooMuchChangeErr +* Update to 5050, tooMuchChangeErr +* Update to 2575, Success +* Update to 5050, Success +* Update to 10000,tooMuchChangeErr +* Update to 7525, Success +* Update to 10000, Success + +## Load Balancing + +To improve LCD reliability and TPS, we recommend to connect LCD to more than one fullnode. But the +complexity will increase a lot. So load balancing module will be imported as the adapter. Please +refer to this link for detailed description: [load balancing](https://github.com/irisnet/cosmos-sdk/blob/bianjie/lcd_spec/docs/spec/lcd/loadbalance.md) + +## ICS1 (KeyAPI) + +### [/keys - GET](api.md#keys---get) + +Load the key store: + +```go +db, err := dbm.NewGoLevelDB(KeyDBName, filepath.Join(rootDir, "keys")) +if err != nil { + return nil, err +} + +keybase = client.GetKeyBase(db) +``` + +Iterate through the key store. + +```go +var res []Info +iter := kb.db.Iterator(nil, nil) +defer iter.Close() + +for ; iter.Valid(); iter.Next() { + // key := iter.Key() + info, err := readInfo(iter.Value()) + if err != nil { + return nil, err + } + res = append(res, info) +} + +return res, nil +``` + +Encode the addresses and public keys in bech32. + +```go +bechAccount, err := sdk.Bech32ifyAcc(sdk.Address(info.PubKey.Address().Bytes())) +if err != nil { + return KeyOutput{}, err +} + +bechPubKey, err := sdk.Bech32ifyAccPub(info.PubKey) +if err != nil { + return KeyOutput{}, err +} + +return KeyOutput{ + Name: info.Name, + Address: bechAccount, + PubKey: bechPubKey, +}, nil +``` + +### [/keys/recover - POST](api.md#keys/recover---get) + +1. Load the key store. +2. Parameter checking. Name, password and seed should not be empty. +3. Check for keys with the same name. +4. Build the key from the name, password and seed. +5. Persist the key to key store. + +### [/keys/create - GET](api.md#keys/create---get)** + +1. Load the key store. +2. Create a new key in the key store. +3. Save the key to disk. +4. Return the seed. + +### [/keys/{name} - GET](api.md#keysname---get) + +1. Load the key store. +2. Iterate the whole key store to find the key by name. +3. Encode address and public key in bech32. + +### [/keys/{name} - PUT](api.md#keysname---put) + +1. Load the key store. +2. Iterate the whole key store to find the key by name. +3. Verify if that the old-password matches the current key password. +4. Re-persist the key with the new password. + +### [/keys/{name} - DELETE](api.md#keysname---delete) + +1. Load the key store. +2. Iterate the whole key store to find the key by name. +3. Verify that the specified password matches the current key password. +4. Delete the key from the key store. + +## ICS20 (TokenAPI) + +### [/bank/balance/{account}](api.md#balanceaccount---get) + +1. Decode the address from bech32 to hex. +2. Send a query request to a full node. Ask for proof if required by Gaia Light. +3. Verify the proof against the root of trust. + +### [/bank/create_transfer](api.md#create_transfer---post) + +1. Check the parameters. +2. Build the transaction with the specified parameters. +3. Serialise the transaction and return the JSON encoded sign bytes. diff --git a/docs/spec/light/todo.md b/docs/spec/light/todo.md new file mode 100644 index 000000000..ce1f8508a --- /dev/null +++ b/docs/spec/light/todo.md @@ -0,0 +1,16 @@ +# TODO + +This document is a place to gather all points for future development. + +## API + +* finalise ICS0 - TendermintAPI + * make sure that the explorer and voyager can use it +* add ICS21 - StakingAPI +* add ICS22 - GovernanceAPI +* split Gaia Light into reusable components that other zones can leverage + * it should be possible to register extra standards on the light client + * the setup should be similar to how the app is currently started +* implement Gaia light and the general light client in Rust + * export the API as a C interface + * write thin wrappers around the C interface in JS, Swift and Kotlin/Java From 6a119f69349c202d8ffefe0ae2f1d1bf47392882 Mon Sep 17 00:00:00 2001 From: Christopher Goes Date: Tue, 10 Jul 2018 20:46:28 +0200 Subject: [PATCH 02/39] Work-in-progress staking invariants --- x/mock/app.go | 3 +- x/mock/random_simulate_blocks.go | 43 +++++++++++++- x/mock/types.go | 9 +++ x/stake/simulation_test.go | 99 ++++++++++++++++++++++++++++++++ 4 files changed, 151 insertions(+), 3 deletions(-) create mode 100644 x/stake/simulation_test.go diff --git a/x/mock/app.go b/x/mock/app.go index dd8edb102..45df31dfd 100644 --- a/x/mock/app.go +++ b/x/mock/app.go @@ -202,8 +202,7 @@ func RandomSetGenesis(r *rand.Rand, app *App, addrs []sdk.Address, denoms []stri (&baseAcc).SetCoins(coins) accts[i] = &baseAcc } - - SetGenesis(app, accts) + app.GenesisAccounts = accts } // GetAllAccounts returns all accounts in the accountMapper. diff --git a/x/mock/random_simulate_blocks.go b/x/mock/random_simulate_blocks.go index a37913065..8d167f45e 100644 --- a/x/mock/random_simulate_blocks.go +++ b/x/mock/random_simulate_blocks.go @@ -31,11 +31,13 @@ func (app *App) RandomizedTestingFromSeed( keys, addrs := GeneratePrivKeyAddressPairs(numKeys) r := rand.New(rand.NewSource(seed)) + RandomSetGenesis(r, app, addrs, []string{"foocoin"}) + app.InitChain(abci.RequestInitChain{}) for i := 0; i < len(setups); i++ { setups[i](r, keys) } + app.Commit() - RandomSetGenesis(r, app, addrs, []string{"foocoin"}) header := abci.Header{Height: 0} for i := 0; i < numBlocks; i++ { @@ -62,6 +64,45 @@ func (app *App) RandomizedTestingFromSeed( } } +func (app *App) SimpleRandomizedTestingFromSeed( + t *testing.T, seed int64, ops []TestAndRunMsg, setups []RandSetup, + invariants []Invariant, numKeys int, numBlocks int, blockSize int, +) { + log := fmt.Sprintf("Starting SimpleSingleModuleTest with randomness created with seed %d", int(seed)) + keys, addrs := GeneratePrivKeyAddressPairs(numKeys) + r := rand.New(rand.NewSource(seed)) + + RandomSetGenesis(r, app, addrs, []string{"foocoin"}) + app.InitChain(abci.RequestInitChain{}) + for i := 0; i < len(setups); i++ { + setups[i](r, keys) + } + app.Commit() + + header := abci.Header{Height: 0} + + for i := 0; i < numBlocks; i++ { + app.BeginBlock(abci.RequestBeginBlock{}) + + app.assertAllInvariants(t, invariants, log) + + ctx := app.NewContext(false, header) + + // TODO: Add modes to simulate "no load", "medium load", and + // "high load" blocks. + for j := 0; j < blockSize; j++ { + logUpdate, err := ops[r.Intn(len(ops))](t, r, ctx, keys, log) + log += "\n" + logUpdate + + require.Nil(t, err, log) + app.assertAllInvariants(t, invariants, log) + } + + app.EndBlock(abci.RequestEndBlock{}) + header.Height++ + } +} + func (app *App) assertAllInvariants(t *testing.T, tests []Invariant, log string) { for i := 0; i < len(tests); i++ { tests[i](t, app, log) diff --git a/x/mock/types.go b/x/mock/types.go index 50957e1c4..8a1c3d3e8 100644 --- a/x/mock/types.go +++ b/x/mock/types.go @@ -17,6 +17,15 @@ type ( privKeys []crypto.PrivKey, log string, ) (action string, err sdk.Error) + // TestAndRunMsg produces a fuzzed message, calls the appropriate handler + // (bypassing all ante handler checks), and ensures that the state + // transition was as expected. It returns a descriptive message "action" + // about what this fuzzed msg actually did for ease of debugging. + TestAndRunMsg func( + t *testing.T, r *rand.Rand, ctx sdk.Context, + privKey []crypto.PrivKey, log string, + ) (action string, err sdk.Error) + // RandSetup performs the random setup the mock module needs. RandSetup func(r *rand.Rand, privKeys []crypto.PrivKey) diff --git a/x/stake/simulation_test.go b/x/stake/simulation_test.go new file mode 100644 index 000000000..8a59d9aa0 --- /dev/null +++ b/x/stake/simulation_test.go @@ -0,0 +1,99 @@ +package stake + +import ( + // "errors" + "fmt" + "math/rand" + "testing" + + "github.com/stretchr/testify/require" + + sdk "github.com/cosmos/cosmos-sdk/types" + "github.com/cosmos/cosmos-sdk/x/auth" + "github.com/cosmos/cosmos-sdk/x/bank" + "github.com/cosmos/cosmos-sdk/x/mock" + abci "github.com/tendermint/tendermint/abci/types" + "github.com/tendermint/tendermint/crypto" +) + +// ModuleInvariants runs all invariants of the stake module. +// Currently: total supply, positive power +func ModuleInvariants(ck bank.Keeper, k Keeper) mock.Invariant { + return func(t *testing.T, app *mock.App, log string) { + TotalSupplyInvariant(ck, k)(t, app, log) + PositivePowerInvariant(k)(t, app, log) + } +} + +// TotalSupplyInvariant checks that the total supply reflects all held loose tokens, bonded tokens, and unbonding delegations +func TotalSupplyInvariant(ck bank.Keeper, k Keeper) mock.Invariant { + return func(t *testing.T, app *mock.App, log string) { + ctx := app.NewContext(false, abci.Header{}) + pool := k.GetPool(ctx) + + // Loose tokens should equal coin supply + loose := sdk.ZeroInt() + app.AccountMapper.IterateAccounts(ctx, func(acc auth.Account) bool { + loose = loose.Add(acc.GetCoins().AmountOf("steak")) + return false + }) + require.True(t, sdk.NewInt(pool.LooseTokens).Equal(loose), "expected loose tokens to equal total steak held by accounts") + + // Bonded tokens should equal sum of tokens with bonded validators + + // Unbonded tokens should equal sum of tokens with unbonded validators + } +} + +// PositivePowerInvariant checks that all stored validators have > 0 power +func PositivePowerInvariant(k Keeper) mock.Invariant { + return func(t *testing.T, app *mock.App, log string) { + ctx := app.NewContext(false, abci.Header{}) + k.IterateValidatorsBonded(ctx, func(_ int64, validator sdk.Validator) bool { + require.True(t, validator.GetPower().GT(sdk.ZeroRat()), "validator with non-positive power stored") + return false + }) + } +} + +// SimulateMsgDelegate +func SimulateMsgDelegate(k Keeper) mock.TestAndRunMsg { + return func(t *testing.T, r *rand.Rand, ctx sdk.Context, keys []crypto.PrivKey, log string) (action string, err sdk.Error) { + msg := fmt.Sprintf("TestMsgDelegate with %s", "ok") + return msg, nil + } +} + +// SimulationSetup +func SimulationSetup(mapp *mock.App, k Keeper) mock.RandSetup { + return func(r *rand.Rand, privKeys []crypto.PrivKey) { + ctx := mapp.NewContext(false, abci.Header{}) + InitGenesis(ctx, k, DefaultGenesisState()) + } +} + +// Test random messages +func TestStakeWithRandomMessages(t *testing.T) { + mapp := mock.NewApp() + + bank.RegisterWire(mapp.Cdc) + coinKeeper := bank.NewKeeper(mapp.AccountMapper) + stakeKey := sdk.NewKVStoreKey("stake") + stakeKeeper := NewKeeper(mapp.Cdc, stakeKey, coinKeeper, DefaultCodespace) + mapp.Router().AddRoute("stake", NewHandler(stakeKeeper)) + + err := mapp.CompleteSetup([]*sdk.KVStoreKey{stakeKey}) + if err != nil { + panic(err) + } + + mapp.SimpleRandomizedTestingFromSeed( + t, 20, []mock.TestAndRunMsg{ + SimulateMsgDelegate(stakeKeeper), + }, []mock.RandSetup{ + SimulationSetup(mapp, stakeKeeper), + }, []mock.Invariant{ + ModuleInvariants(coinKeeper, stakeKeeper), + }, 10, 100, 500, + ) +} From 940cfa98af3cc5adac7cebe2644398f0f2d1206f Mon Sep 17 00:00:00 2001 From: Christopher Goes Date: Wed, 11 Jul 2018 02:36:50 +0200 Subject: [PATCH 03/39] Invariants & random Msgs in progress --- types/coin.go | 6 +- x/mock/random_simulate_blocks.go | 26 +++++++ x/stake/simulation_test.go | 123 +++++++++++++++++++++++++++++-- 3 files changed, 148 insertions(+), 7 deletions(-) diff --git a/types/coin.go b/types/coin.go index eba645932..862614ca0 100644 --- a/types/coin.go +++ b/types/coin.go @@ -15,9 +15,13 @@ type Coin struct { } func NewCoin(denom string, amount int64) Coin { + return NewIntCoin(denom, NewInt(amount)) +} + +func NewIntCoin(denom string, amount Int) Coin { return Coin{ Denom: denom, - Amount: NewInt(amount), + Amount: amount, } } diff --git a/x/mock/random_simulate_blocks.go b/x/mock/random_simulate_blocks.go index 4883cb180..452b8f6bf 100644 --- a/x/mock/random_simulate_blocks.go +++ b/x/mock/random_simulate_blocks.go @@ -135,3 +135,29 @@ func RandFromBigInterval(r *rand.Rand, intervals []BigInterval) sdk.Int { return result } + +// shamelessly copied from https://stackoverflow.com/questions/22892120/how-to-generate-a-random-string-of-a-fixed-length-in-golang#31832326 + +const letterBytes = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ" +const ( + letterIdxBits = 6 // 6 bits to represent a letter index + letterIdxMask = 1<= 0; { + if remain == 0 { + cache, remain = r.Int63(), letterIdxMax + } + if idx := int(cache & letterIdxMask); idx < len(letterBytes) { + b[i] = letterBytes[idx] + i-- + } + cache >>= letterIdxBits + remain-- + } + return string(b) +} diff --git a/x/stake/simulation_test.go b/x/stake/simulation_test.go index 8a59d9aa0..f9aac426c 100644 --- a/x/stake/simulation_test.go +++ b/x/stake/simulation_test.go @@ -20,13 +20,14 @@ import ( // Currently: total supply, positive power func ModuleInvariants(ck bank.Keeper, k Keeper) mock.Invariant { return func(t *testing.T, app *mock.App, log string) { - TotalSupplyInvariant(ck, k)(t, app, log) + SupplyInvariants(ck, k)(t, app, log) PositivePowerInvariant(k)(t, app, log) + ValidatorSetInvariant(k)(t, app, log) } } -// TotalSupplyInvariant checks that the total supply reflects all held loose tokens, bonded tokens, and unbonding delegations -func TotalSupplyInvariant(ck bank.Keeper, k Keeper) mock.Invariant { +// SupplyInvariants checks that the total supply reflects all held loose tokens, bonded tokens, and unbonding delegations +func SupplyInvariants(ck bank.Keeper, k Keeper) mock.Invariant { return func(t *testing.T, app *mock.App, log string) { ctx := app.NewContext(false, abci.Header{}) pool := k.GetPool(ctx) @@ -40,8 +41,26 @@ func TotalSupplyInvariant(ck bank.Keeper, k Keeper) mock.Invariant { require.True(t, sdk.NewInt(pool.LooseTokens).Equal(loose), "expected loose tokens to equal total steak held by accounts") // Bonded tokens should equal sum of tokens with bonded validators - // Unbonded tokens should equal sum of tokens with unbonded validators + bonded := sdk.ZeroRat() + unbonded := sdk.ZeroRat() + k.IterateValidators(ctx, func(_ int64, validator sdk.Validator) bool { + switch validator.GetStatus() { + case sdk.Bonded: + bonded = bonded.Add(validator.GetPower()) + case sdk.Unbonding: + // TODO + case sdk.Unbonded: + unbonded = unbonded.Add(validator.GetPower()) + } + return false + }) + require.True(t, sdk.NewRat(pool.BondedTokens).Equal(bonded), "expected bonded tokens to equal total steak held by bonded validators") + require.True(t, sdk.NewRat(pool.UnbondedTokens).Equal(unbonded), "expected unbonded tokens to equal total steak held by unbonded validators") + + // TODO Unbonding tokens + + // TODO Inflation check on total supply } } @@ -56,6 +75,59 @@ func PositivePowerInvariant(k Keeper) mock.Invariant { } } +// ValidatorSetInvariant checks equivalence of Tendermint validator set and SDK validator set +func ValidatorSetInvariant(k Keeper) mock.Invariant { + return func(t *testing.T, app *mock.App, log string) { + // TODO + } +} + +// SimulateMsgCreateValidator +func SimulateMsgCreateValidator(m auth.AccountMapper, k Keeper) mock.TestAndRunMsg { + return func(t *testing.T, r *rand.Rand, ctx sdk.Context, keys []crypto.PrivKey, log string) (action string, err sdk.Error) { + denom := k.GetParams(ctx).BondDenom + description := Description{ + Moniker: mock.RandStringOfLength(r, 10), + } + key := keys[r.Intn(len(keys))] + pubkey := key.PubKey() + address := sdk.AccAddress(pubkey.Address()) + amount := m.GetAccount(ctx, address).GetCoins().AmountOf(denom) + if amount.GT(sdk.ZeroInt()) { + amount = sdk.NewInt(int64(r.Intn(int(amount.Int64())))) + } + msg := MsgCreateValidator{ + Description: description, + ValidatorAddr: address, + PubKey: pubkey, + SelfDelegation: sdk.NewIntCoin(denom, amount), + } + action = fmt.Sprintf("TestMsgCreateValidator: %s", msg.GetSignBytes()) + return action, nil + } +} + +// SimulateMsgEditValidator +func SimulateMsgEditValidator(k Keeper) mock.TestAndRunMsg { + return func(t *testing.T, r *rand.Rand, ctx sdk.Context, keys []crypto.PrivKey, log string) (action string, err sdk.Error) { + description := Description{ + Moniker: mock.RandStringOfLength(r, 10), + Identity: mock.RandStringOfLength(r, 10), + Website: mock.RandStringOfLength(r, 10), + Details: mock.RandStringOfLength(r, 10), + } + key := keys[r.Intn(len(keys))] + pubkey := key.PubKey() + address := sdk.AccAddress(pubkey.Address()) + msg := MsgEditValidator{ + Description: description, + ValidatorAddr: address, + } + action = fmt.Sprintf("TestMsgEditValidator: %s", msg.GetSignBytes()) + return action, nil + } +} + // SimulateMsgDelegate func SimulateMsgDelegate(k Keeper) mock.TestAndRunMsg { return func(t *testing.T, r *rand.Rand, ctx sdk.Context, keys []crypto.PrivKey, log string) (action string, err sdk.Error) { @@ -64,6 +136,38 @@ func SimulateMsgDelegate(k Keeper) mock.TestAndRunMsg { } } +// SimulateMsgBeginUnbonding +func SimulateMsgBeginUnbonding(k Keeper) mock.TestAndRunMsg { + return func(t *testing.T, r *rand.Rand, ctx sdk.Context, keys []crypto.PrivKey, log string) (action string, err sdk.Error) { + msg := fmt.Sprintf("TestMsgBeginUnbonding with %s", "ok") + return msg, nil + } +} + +// SimulateMsgCompleteUnbonding +func SimulateMsgCompleteUnbonding(k Keeper) mock.TestAndRunMsg { + return func(t *testing.T, r *rand.Rand, ctx sdk.Context, keys []crypto.PrivKey, log string) (action string, err sdk.Error) { + msg := fmt.Sprintf("TestMsgCompleteUnbonding with %s", "ok") + return msg, nil + } +} + +// SimulateMsgBeginRedelegate +func SimulateMsgBeginRedelegate(k Keeper) mock.TestAndRunMsg { + return func(t *testing.T, r *rand.Rand, ctx sdk.Context, keys []crypto.PrivKey, log string) (action string, err sdk.Error) { + msg := fmt.Sprintf("TestMsgBeginRedelegate with %s", "ok") + return msg, nil + } +} + +// SimulateMsgCompleteRedelegate +func SimulateMsgCompleteRedelegate(k Keeper) mock.TestAndRunMsg { + return func(t *testing.T, r *rand.Rand, ctx sdk.Context, keys []crypto.PrivKey, log string) (action string, err sdk.Error) { + msg := fmt.Sprintf("TestMsgCompleteRedelegate with %s", "ok") + return msg, nil + } +} + // SimulationSetup func SimulationSetup(mapp *mock.App, k Keeper) mock.RandSetup { return func(r *rand.Rand, privKeys []crypto.PrivKey) { @@ -72,12 +176,13 @@ func SimulationSetup(mapp *mock.App, k Keeper) mock.RandSetup { } } -// Test random messages +// TestStakeWithRandomMessages func TestStakeWithRandomMessages(t *testing.T) { mapp := mock.NewApp() bank.RegisterWire(mapp.Cdc) - coinKeeper := bank.NewKeeper(mapp.AccountMapper) + mapper := mapp.AccountMapper + coinKeeper := bank.NewKeeper(mapper) stakeKey := sdk.NewKVStoreKey("stake") stakeKeeper := NewKeeper(mapp.Cdc, stakeKey, coinKeeper, DefaultCodespace) mapp.Router().AddRoute("stake", NewHandler(stakeKeeper)) @@ -89,7 +194,13 @@ func TestStakeWithRandomMessages(t *testing.T) { mapp.SimpleRandomizedTestingFromSeed( t, 20, []mock.TestAndRunMsg{ + SimulateMsgCreateValidator(mapper, stakeKeeper), + SimulateMsgEditValidator(stakeKeeper), SimulateMsgDelegate(stakeKeeper), + SimulateMsgBeginUnbonding(stakeKeeper), + SimulateMsgCompleteUnbonding(stakeKeeper), + SimulateMsgBeginRedelegate(stakeKeeper), + SimulateMsgCompleteRedelegate(stakeKeeper), }, []mock.RandSetup{ SimulationSetup(mapp, stakeKeeper), }, []mock.Invariant{ From a3d8b38d47c5d01f90030d4b1f9a6ce70a2746fc Mon Sep 17 00:00:00 2001 From: Christopher Goes Date: Wed, 11 Jul 2018 04:36:12 +0200 Subject: [PATCH 04/39] Add several simulated Msgs --- x/stake/simulation_test.go | 110 ++++++++++++++++++++++++++++++++----- 1 file changed, 97 insertions(+), 13 deletions(-) diff --git a/x/stake/simulation_test.go b/x/stake/simulation_test.go index f9aac426c..7dacf02b2 100644 --- a/x/stake/simulation_test.go +++ b/x/stake/simulation_test.go @@ -16,6 +16,10 @@ import ( "github.com/tendermint/tendermint/crypto" ) +var ( + stats = make(map[string]int) +) + // ModuleInvariants runs all invariants of the stake module. // Currently: total supply, positive power func ModuleInvariants(ck bank.Keeper, k Keeper) mock.Invariant { @@ -38,7 +42,9 @@ func SupplyInvariants(ck bank.Keeper, k Keeper) mock.Invariant { loose = loose.Add(acc.GetCoins().AmountOf("steak")) return false }) - require.True(t, sdk.NewInt(pool.LooseTokens).Equal(loose), "expected loose tokens to equal total steak held by accounts") + require.True(t, sdk.NewInt(pool.LooseTokens).Equal(loose), "expected loose tokens to equal total steak held by accounts - pool.LooseTokens: %v, sum of account tokens: %v\nlog: %s", + pool.LooseTokens, loose, log) + stats["stake/invariant/looseTokens"] += 1 // Bonded tokens should equal sum of tokens with bonded validators // Unbonded tokens should equal sum of tokens with unbonded validators @@ -55,8 +61,10 @@ func SupplyInvariants(ck bank.Keeper, k Keeper) mock.Invariant { } return false }) - require.True(t, sdk.NewRat(pool.BondedTokens).Equal(bonded), "expected bonded tokens to equal total steak held by bonded validators") - require.True(t, sdk.NewRat(pool.UnbondedTokens).Equal(unbonded), "expected unbonded tokens to equal total steak held by unbonded validators") + require.True(t, sdk.NewRat(pool.BondedTokens).Equal(bonded), "expected bonded tokens to equal total steak held by bonded validators\nlog: %s", log) + stats["stake/invariant/bondedTokens"] += 1 + require.True(t, sdk.NewRat(pool.UnbondedTokens).Equal(unbonded), "expected unbonded tokens to equal total steak held by unbonded validators\n log: %s", log) + stats["stake/invariant/unbondedTokens"] += 1 // TODO Unbonding tokens @@ -72,6 +80,7 @@ func PositivePowerInvariant(k Keeper) mock.Invariant { require.True(t, validator.GetPower().GT(sdk.ZeroRat()), "validator with non-positive power stored") return false }) + stats["stake/invariant/positivePower"] += 1 } } @@ -96,12 +105,19 @@ func SimulateMsgCreateValidator(m auth.AccountMapper, k Keeper) mock.TestAndRunM if amount.GT(sdk.ZeroInt()) { amount = sdk.NewInt(int64(r.Intn(int(amount.Int64())))) } + if amount.Equal(sdk.ZeroInt()) { + return "nop", nil + } msg := MsgCreateValidator{ Description: description, ValidatorAddr: address, PubKey: pubkey, SelfDelegation: sdk.NewIntCoin(denom, amount), } + require.Nil(t, msg.ValidateBasic(), "expected msg to pass ValidateBasic: %s", msg.GetSignBytes()) + result := handleMsgCreateValidator(ctx, msg, k) + stats[fmt.Sprintf("stake/createvalidator/%v", result.IsOK())] += 1 + // require.True(t, result.IsOK(), "expected OK result but instead got %v", result) action = fmt.Sprintf("TestMsgCreateValidator: %s", msg.GetSignBytes()) return action, nil } @@ -123,21 +139,44 @@ func SimulateMsgEditValidator(k Keeper) mock.TestAndRunMsg { Description: description, ValidatorAddr: address, } + require.Nil(t, msg.ValidateBasic(), "expected msg to pass ValidateBasic: %s", msg.GetSignBytes()) + result := handleMsgEditValidator(ctx, msg, k) + stats[fmt.Sprintf("stake/editvalidator/%v", result.IsOK())] += 1 action = fmt.Sprintf("TestMsgEditValidator: %s", msg.GetSignBytes()) return action, nil } } // SimulateMsgDelegate -func SimulateMsgDelegate(k Keeper) mock.TestAndRunMsg { +func SimulateMsgDelegate(m auth.AccountMapper, k Keeper) mock.TestAndRunMsg { return func(t *testing.T, r *rand.Rand, ctx sdk.Context, keys []crypto.PrivKey, log string) (action string, err sdk.Error) { - msg := fmt.Sprintf("TestMsgDelegate with %s", "ok") - return msg, nil + denom := k.GetParams(ctx).BondDenom + validatorKey := keys[r.Intn(len(keys))] + validatorAddress := sdk.AccAddress(validatorKey.PubKey().Address()) + delegatorKey := keys[r.Intn(len(keys))] + delegatorAddress := sdk.AccAddress(delegatorKey.PubKey().Address()) + amount := m.GetAccount(ctx, delegatorAddress).GetCoins().AmountOf(denom) + if amount.GT(sdk.ZeroInt()) { + amount = sdk.NewInt(int64(r.Intn(int(amount.Int64())))) + } + if amount.Equal(sdk.ZeroInt()) { + return "nop", nil + } + msg := MsgDelegate{ + DelegatorAddr: delegatorAddress, + ValidatorAddr: validatorAddress, + Bond: sdk.NewIntCoin(denom, amount), + } + require.Nil(t, msg.ValidateBasic(), "expected msg to pass ValidateBasic: %s", msg.GetSignBytes()) + result := handleMsgDelegate(ctx, msg, k) + stats[fmt.Sprintf("stake/delegate/%v", result.IsOK())] += 1 + action = fmt.Sprintf("TestMsgDelegate: %s", msg.GetSignBytes()) + return action, nil } } // SimulateMsgBeginUnbonding -func SimulateMsgBeginUnbonding(k Keeper) mock.TestAndRunMsg { +func SimulateMsgBeginUnbonding(m auth.AccountMapper, k Keeper) mock.TestAndRunMsg { return func(t *testing.T, r *rand.Rand, ctx sdk.Context, keys []crypto.PrivKey, log string) (action string, err sdk.Error) { msg := fmt.Sprintf("TestMsgBeginUnbonding with %s", "ok") return msg, nil @@ -153,10 +192,34 @@ func SimulateMsgCompleteUnbonding(k Keeper) mock.TestAndRunMsg { } // SimulateMsgBeginRedelegate -func SimulateMsgBeginRedelegate(k Keeper) mock.TestAndRunMsg { +func SimulateMsgBeginRedelegate(m auth.AccountMapper, k Keeper) mock.TestAndRunMsg { return func(t *testing.T, r *rand.Rand, ctx sdk.Context, keys []crypto.PrivKey, log string) (action string, err sdk.Error) { - msg := fmt.Sprintf("TestMsgBeginRedelegate with %s", "ok") - return msg, nil + denom := k.GetParams(ctx).BondDenom + sourceValidatorKey := keys[r.Intn(len(keys))] + sourceValidatorAddress := sdk.AccAddress(sourceValidatorKey.PubKey().Address()) + destValidatorKey := keys[r.Intn(len(keys))] + destValidatorAddress := sdk.AccAddress(destValidatorKey.PubKey().Address()) + delegatorKey := keys[r.Intn(len(keys))] + delegatorAddress := sdk.AccAddress(delegatorKey.PubKey().Address()) + // TODO + amount := m.GetAccount(ctx, delegatorAddress).GetCoins().AmountOf(denom) + if amount.GT(sdk.ZeroInt()) { + amount = sdk.NewInt(int64(r.Intn(int(amount.Int64())))) + } + if amount.Equal(sdk.ZeroInt()) { + return "nop", nil + } + msg := MsgBeginRedelegate{ + DelegatorAddr: delegatorAddress, + ValidatorSrcAddr: sourceValidatorAddress, + ValidatorDstAddr: destValidatorAddress, + SharesAmount: sdk.NewRatFromInt(amount), + } + require.Nil(t, msg.ValidateBasic(), "expected msg to pass ValidateBasic: %s", msg.GetSignBytes()) + result := handleMsgBeginRedelegate(ctx, msg, k) + stats[fmt.Sprintf("stake/beginredelegate/%v", result.IsOK())] += 1 + action = fmt.Sprintf("TestMsgBeginRedelegate: %s", msg.GetSignBytes()) + return action, nil } } @@ -173,6 +236,19 @@ func SimulationSetup(mapp *mock.App, k Keeper) mock.RandSetup { return func(r *rand.Rand, privKeys []crypto.PrivKey) { ctx := mapp.NewContext(false, abci.Header{}) InitGenesis(ctx, k, DefaultGenesisState()) + params := k.GetParams(ctx) + denom := params.BondDenom + loose := sdk.ZeroInt() + mapp.AccountMapper.IterateAccounts(ctx, func(acc auth.Account) bool { + balance := sdk.NewInt(int64(r.Intn(1000000))) + acc.SetCoins(acc.GetCoins().Plus(sdk.Coins{sdk.NewIntCoin(denom, balance)})) + mapp.AccountMapper.SetAccount(ctx, acc) + loose = loose.Add(balance) + return false + }) + pool := k.GetPool(ctx) + pool.LooseTokens += loose.Int64() + k.SetPool(ctx, pool) } } @@ -186,6 +262,12 @@ func TestStakeWithRandomMessages(t *testing.T) { stakeKey := sdk.NewKVStoreKey("stake") stakeKeeper := NewKeeper(mapp.Cdc, stakeKey, coinKeeper, DefaultCodespace) mapp.Router().AddRoute("stake", NewHandler(stakeKeeper)) + mapp.SetEndBlocker(func(ctx sdk.Context, req abci.RequestEndBlock) abci.ResponseEndBlock { + validatorUpdates := EndBlocker(ctx, stakeKeeper) + return abci.ResponseEndBlock{ + ValidatorUpdates: validatorUpdates, + } + }) err := mapp.CompleteSetup([]*sdk.KVStoreKey{stakeKey}) if err != nil { @@ -196,10 +278,10 @@ func TestStakeWithRandomMessages(t *testing.T) { t, 20, []mock.TestAndRunMsg{ SimulateMsgCreateValidator(mapper, stakeKeeper), SimulateMsgEditValidator(stakeKeeper), - SimulateMsgDelegate(stakeKeeper), - SimulateMsgBeginUnbonding(stakeKeeper), + SimulateMsgDelegate(mapper, stakeKeeper), + SimulateMsgBeginUnbonding(mapper, stakeKeeper), SimulateMsgCompleteUnbonding(stakeKeeper), - SimulateMsgBeginRedelegate(stakeKeeper), + SimulateMsgBeginRedelegate(mapper, stakeKeeper), SimulateMsgCompleteRedelegate(stakeKeeper), }, []mock.RandSetup{ SimulationSetup(mapp, stakeKeeper), @@ -207,4 +289,6 @@ func TestStakeWithRandomMessages(t *testing.T) { ModuleInvariants(coinKeeper, stakeKeeper), }, 10, 100, 500, ) + + fmt.Printf("Stats: %v\n", stats) } From 27f157a3e213daa55da59b5ae932d595b853fbcc Mon Sep 17 00:00:00 2001 From: Christopher Goes Date: Wed, 11 Jul 2018 04:55:57 +0200 Subject: [PATCH 05/39] CacheContext() --- x/stake/simulation_test.go | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/x/stake/simulation_test.go b/x/stake/simulation_test.go index 7dacf02b2..f9abc6064 100644 --- a/x/stake/simulation_test.go +++ b/x/stake/simulation_test.go @@ -115,7 +115,11 @@ func SimulateMsgCreateValidator(m auth.AccountMapper, k Keeper) mock.TestAndRunM SelfDelegation: sdk.NewIntCoin(denom, amount), } require.Nil(t, msg.ValidateBasic(), "expected msg to pass ValidateBasic: %s", msg.GetSignBytes()) + ctx, write := ctx.CacheContext() result := handleMsgCreateValidator(ctx, msg, k) + if result.IsOK() { + write() + } stats[fmt.Sprintf("stake/createvalidator/%v", result.IsOK())] += 1 // require.True(t, result.IsOK(), "expected OK result but instead got %v", result) action = fmt.Sprintf("TestMsgCreateValidator: %s", msg.GetSignBytes()) @@ -140,7 +144,11 @@ func SimulateMsgEditValidator(k Keeper) mock.TestAndRunMsg { ValidatorAddr: address, } require.Nil(t, msg.ValidateBasic(), "expected msg to pass ValidateBasic: %s", msg.GetSignBytes()) + ctx, write := ctx.CacheContext() result := handleMsgEditValidator(ctx, msg, k) + if result.IsOK() { + write() + } stats[fmt.Sprintf("stake/editvalidator/%v", result.IsOK())] += 1 action = fmt.Sprintf("TestMsgEditValidator: %s", msg.GetSignBytes()) return action, nil @@ -168,7 +176,11 @@ func SimulateMsgDelegate(m auth.AccountMapper, k Keeper) mock.TestAndRunMsg { Bond: sdk.NewIntCoin(denom, amount), } require.Nil(t, msg.ValidateBasic(), "expected msg to pass ValidateBasic: %s", msg.GetSignBytes()) + ctx, write := ctx.CacheContext() result := handleMsgDelegate(ctx, msg, k) + if result.IsOK() { + write() + } stats[fmt.Sprintf("stake/delegate/%v", result.IsOK())] += 1 action = fmt.Sprintf("TestMsgDelegate: %s", msg.GetSignBytes()) return action, nil @@ -216,7 +228,11 @@ func SimulateMsgBeginRedelegate(m auth.AccountMapper, k Keeper) mock.TestAndRunM SharesAmount: sdk.NewRatFromInt(amount), } require.Nil(t, msg.ValidateBasic(), "expected msg to pass ValidateBasic: %s", msg.GetSignBytes()) + ctx, write := ctx.CacheContext() result := handleMsgBeginRedelegate(ctx, msg, k) + if result.IsOK() { + write() + } stats[fmt.Sprintf("stake/beginredelegate/%v", result.IsOK())] += 1 action = fmt.Sprintf("TestMsgBeginRedelegate: %s", msg.GetSignBytes()) return action, nil From 42c271254325ae47b9319792838e22b75e1f1f99 Mon Sep 17 00:00:00 2001 From: Adrian Brink Date: Wed, 11 Jul 2018 13:50:09 +0200 Subject: [PATCH 06/39] Address comments * Move from specs to docs folder * Attempt to fix markdown links * Address general comments from the PR * Remove overview.md due to duplication with readme.md --- docs/{spec => }/light/api.md | 219 +++++++++++------- docs/{spec => }/light/getting_started.md | 12 +- docs/{spec => }/light/load_balancer.md | 2 +- docs/{spec => }/light/pics/C2H.png | Bin docs/{spec => }/light/pics/H2C.png | Bin docs/{spec => }/light/pics/MA.png | Bin docs/{spec => }/light/pics/absence1.png | Bin docs/{spec => }/light/pics/absence2.png | Bin docs/{spec => }/light/pics/absence3.png | Bin docs/{spec => }/light/pics/architecture.png | Bin docs/{spec => }/light/pics/changeProcess.png | Bin .../light/pics/commitValidation.png | Bin docs/{spec => }/light/pics/create-account.png | Bin docs/{spec => }/light/pics/deposit.png | Bin docs/{spec => }/light/pics/existProof.png | Bin docs/{spec => }/light/pics/high-level.png | Bin .../light/pics/light-client-architecture.png | Bin .../light/pics/loadbalanceDiagram.png | Bin .../light/pics/simpleMerkleTree.png | Bin docs/{spec => }/light/pics/substoreProof.png | Bin .../{spec => }/light/pics/transfer-tokens.png | Bin docs/{spec => }/light/pics/transfer.png | Bin docs/{spec => }/light/pics/trustPropagate.png | Bin .../light/pics/updateValidatorToHeight.png | Bin .../light/pics/validatorSetChange.png | Bin docs/{spec => }/light/pics/withdraw.png | Bin docs/{spec => }/light/readme.md | 21 +- docs/{spec => }/light/specification.md | 0 docs/{spec => }/light/todo.md | 0 docs/spec/light/overview.md | 55 ----- 30 files changed, 153 insertions(+), 156 deletions(-) rename docs/{spec => }/light/api.md (59%) rename docs/{spec => }/light/getting_started.md (69%) rename docs/{spec => }/light/load_balancer.md (99%) rename docs/{spec => }/light/pics/C2H.png (100%) rename docs/{spec => }/light/pics/H2C.png (100%) rename docs/{spec => }/light/pics/MA.png (100%) rename docs/{spec => }/light/pics/absence1.png (100%) rename docs/{spec => }/light/pics/absence2.png (100%) rename docs/{spec => }/light/pics/absence3.png (100%) rename docs/{spec => }/light/pics/architecture.png (100%) rename docs/{spec => }/light/pics/changeProcess.png (100%) rename docs/{spec => }/light/pics/commitValidation.png (100%) rename docs/{spec => }/light/pics/create-account.png (100%) rename docs/{spec => }/light/pics/deposit.png (100%) rename docs/{spec => }/light/pics/existProof.png (100%) rename docs/{spec => }/light/pics/high-level.png (100%) rename docs/{spec => }/light/pics/light-client-architecture.png (100%) rename docs/{spec => }/light/pics/loadbalanceDiagram.png (100%) rename docs/{spec => }/light/pics/simpleMerkleTree.png (100%) rename docs/{spec => }/light/pics/substoreProof.png (100%) rename docs/{spec => }/light/pics/transfer-tokens.png (100%) rename docs/{spec => }/light/pics/transfer.png (100%) rename docs/{spec => }/light/pics/trustPropagate.png (100%) rename docs/{spec => }/light/pics/updateValidatorToHeight.png (100%) rename docs/{spec => }/light/pics/validatorSetChange.png (100%) rename docs/{spec => }/light/pics/withdraw.png (100%) rename docs/{spec => }/light/readme.md (81%) rename docs/{spec => }/light/specification.md (100%) rename docs/{spec => }/light/todo.md (100%) delete mode 100644 docs/spec/light/overview.md diff --git a/docs/spec/light/api.md b/docs/light/api.md similarity index 59% rename from docs/spec/light/api.md rename to docs/light/api.md index 4dc2619a3..26fbe77c2 100644 --- a/docs/spec/light/api.md +++ b/docs/light/api.md @@ -25,9 +25,10 @@ similar API. url: /broadcast_tx_sync -Functionality: Submit a signed transaction and wait for it to be committed. +Functionality: Submit a signed transaction synchronously. This returns a response from CheckTx. Parameters: + | Parameter | Type | Default | Required | Description | | ----------- | ------ | ------- | -------- | --------------- | | transaction | string | null | true | signed tx bytes | @@ -36,14 +37,14 @@ Returns on success: ```json { - "rest api": "2.0", + "rest api":"2.0", "code":200, - "error": "", - "result": { - "code": 0, - "hash": "0D33F2F03A5234F38706E43004489E061AC40A2E", - "data": "", - "log": "" + "error":"", + "result":{ + "code":0, + "hash":"0D33F2F03A5234F38706E43004489E061AC40A2E", + "data":"", + "log":"" } } ``` @@ -52,10 +53,10 @@ Returns on failure: ```json { - "rest api": "2.0", + "rest api":"2.0", "code":500, - "error": "Could not submit the transaction synchronously.", - "result": {} + "error":"Could not submit the transaction synchronously.", + "result":{} } ``` @@ -63,9 +64,10 @@ Returns on failure: url: /broadcast_tx_async -Functionality: Submit a signed transaction asynchronously. +Functionality: Submit a signed transaction asynchronously. This does not return a response from CheckTx. Parameters: + | Parameter | Type | Default | Required | Description | | ----------- | ------ | ------- | -------- | --------------- | | transaction | string | null | true | signed tx bytes | @@ -74,14 +76,14 @@ Returns on success: ```json { - "rest api": "2.0", + "rest api":"2.0", "code":200, - "error": "", + "error":"", "result": { - "code": 0, - "hash": "E39AAB7A537ABAA237831742DCE1117F187C3C52", - "data": "", - "log": "" + "code":0, + "hash":"E39AAB7A537ABAA237831742DCE1117F187C3C52", + "data":"", + "log":"" } } ``` @@ -90,10 +92,56 @@ Returns on failure: ```json { - "rest api": "2.0", + "rest api":"2.0", "code":500, - "error": "Could not submit the transaction asynchronously.", - "result": {} + "error":"Could not submit the transaction asynchronously.", + "result":{} +} +``` + +### /broadcast_tx_commit - POST + +url: /broadcast_tx_commit + +Functionality: Submit a signed transaction and waits for it to be committed in a block. + +Parameters: + +| Parameter | Type | Default | Required | Description | +| ----------- | ------ | ------- | -------- | --------------- | +| transaction | string | null | true | signed tx bytes | + +Returns on success: + +```json +{ + "rest api":"2.0", + "code":200, + "error":"", + "result":{ + "height":26682, + "hash":"75CA0F856A4DA078FC4911580360E70CEFB2EBEE", + "deliver_tx":{ + "log":"", + "data":"", + "code":0 + }, + "check_tx":{ + "log":"", + "data":"", + "code":0 + } +} +``` + +Returns on failure: + +```json +{ + "rest api":"2.0", + "code":500, + "error":"Could not commit the transaction.", + "result":{} } ``` @@ -111,23 +159,23 @@ Returns on success: ```json { - "rest api": "2.0", + "rest api":"2.0", "code":200, - "error": "", - "result": { - "keys": [ + "error":"", + "result":{ + "keys":[ { - "name": "monkey", - "address": "cosmosaccaddr1fedh326uxqlxs8ph9ej7cf854gz7fd5zlym5pd", - "pub_key": "cosmosaccpub1zcjduc3q8s8ha96ry4xc5xvjp9tr9w9p0e5lk5y0rpjs5epsfxs4wmf72x3shvus0t" + "name":"monkey", + "address":"cosmosaccaddr1fedh326uxqlxs8ph9ej7cf854gz7fd5zlym5pd", + "pub_key":"cosmosaccpub1zcjduc3q8s8ha96ry4xc5xvjp9tr9w9p0e5lk5y0rpjs5epsfxs4wmf72x3shvus0t" }, { - "name": "test", - "address": "cosmosaccaddr1thlqhjqw78zvcy0ua4ldj9gnazqzavyw4eske2", - "pub_key": "cosmosaccpub1zcjduc3qyx6hlf825jcnj39adpkaxjer95q7yvy25yhfj3dmqy2ctev0rxmse9cuak" + "name":"test", + "address":"cosmosaccaddr1thlqhjqw78zvcy0ua4ldj9gnazqzavyw4eske2", + "pub_key":"cosmosaccpub1zcjduc3qyx6hlf825jcnj39adpkaxjer95q7yvy25yhfj3dmqy2ctev0rxmse9cuak" } ], - "block_height": 5241 + "block_height":5241 } } ``` @@ -136,7 +184,7 @@ Returns on failure: ```json { - "rest api": "2.0", + "rest api":"2.0", "code":500, "error":"Could not retrieve the keys.", "result":{} @@ -150,6 +198,7 @@ url: /keys/recover Functionality: Recover your key from seed and persist it encrypted with the password. Parameter: + | Parameter | Type | Default | Required | Description | | --------- | ------ | ------- | -------- | ---------------- | | name | string | null | true | name of key | @@ -160,11 +209,11 @@ Returns on success: ```json { - "rest api": "2.0", + "rest api":"2.0", "code":200, - "error": "", - "result": { - "address":BD607C37147656A507A5A521AA9446EB72B2C907 + "error":"", + "result":{ + "address":"BD607C37147656A507A5A521AA9446EB72B2C907" } } ``` @@ -173,10 +222,10 @@ Returns on failure: ```json { - "rest api": "2.0", + "rest api":"2.0", "code":500, - "error": "Could not recover the key.", - "result": {} + "error":"Could not recover the key.", + "result":{} } ``` @@ -187,6 +236,7 @@ url: /keys/create Functionality: Create a new key. Parameter: + | Parameter | Type | Default | Required | Description | | --------- | ------ | ------- | -------- | ---------------- | | name | string | null | true | name of key | @@ -196,11 +246,11 @@ Returns on success: ```json { - "rest api": "2.0", + "rest api":"2.0", "code":200, - "error": "", - "result": { - "seed":crime carpet recycle erase simple prepare moral dentist fee cause pitch trigger when velvet animal abandon + "error":"", + "result":{ + "seed":"crime carpet recycle erase simple prepare moral dentist fee cause pitch trigger when velvet animal abandon" } } ``` @@ -209,10 +259,10 @@ Returns on failure: ```json { - "rest api": "2.0", + "rest api":"2.0", "code":500, - "error": "Could not create new key.", - "result": {} + "error":"Could not create new key.", + "result":{} } ``` @@ -226,13 +276,13 @@ Returns on success: ```json { - "rest api": "2.0", + "rest api":"2.0", "code":200, - "error": "", - "result": { - "name": "test", - "address": "cosmosaccaddr1thlqhjqw78zvcy0ua4ldj9gnazqzavyw4eske2", - "pub_key": "cosmosaccpub1zcjduc3qyx6hlf825jcnj39adpkaxjer95q7yvy25yhfj3dmqy2ctev0rxmse9cuak" + "error":"", + "result":{ + "name":"test", + "address":"cosmosaccaddr1thlqhjqw78zvcy0ua4ldj9gnazqzavyw4eske2", + "pub_key":"cosmosaccpub1zcjduc3qyx6hlf825jcnj39adpkaxjer95q7yvy25yhfj3dmqy2ctev0rxmse9cuak" } } ``` @@ -241,10 +291,10 @@ Returns on failure: ```json { - "rest api": "2.0", + "rest api":"2.0", "code":500, - "error": "Could not find information on the specified key.", - "result": {} + "error":"Could not find information on the specified key.", + "result":{} } ``` @@ -255,6 +305,7 @@ url: /keys/{name} Functionality: Change the encryption password for the specified key. Parameters: + | Parameter | Type | Default | Required | Description | | --------------- | ------ | ------- | -------- | --------------- | | old_password | string | null | true | old password | @@ -264,10 +315,10 @@ Returns on success: ```json { - "rest api": "2.0", + "rest api":"2.0", "code":200, - "error": "", - "result": {} + "error":"", + "result":{} } ``` @@ -275,10 +326,10 @@ Returns on failure: ```json { - "rest api": "2.0", + "rest api":"2.0", "code":500, - "error": "Could not update the specified key.", - "result": {} + "error":"Could not update the specified key.", + "result":{} } ``` @@ -289,6 +340,7 @@ url: /keys/{name} Functionality: Delete the specified key. Parameters: + | Parameter | Type | Default | Required | Description | | --------- | ------ | ------- | -------- | ---------------- | | password | string | null | true | password of key | @@ -297,10 +349,10 @@ Returns on success: ```json { - "rest api": "2.0", + "rest api":"2.0", "code":200, - "error": "", - "result": {} + "error":"", + "result":{} } ``` @@ -308,10 +360,10 @@ Returns on failure: ```json { - "rest api": "2.0", + "rest api":"2.0", "code":500, - "error": "Could not delete the specified key.", - "result": {} + "error":"Could not delete the specified key.", + "result":{} } ``` @@ -329,13 +381,13 @@ Returns on success: ```json { - "rest api": "2.0", + "rest api":"2.0", "code":200, - "error": "", + "error":"", "result": { - "atom": 1000, - "photon": 500, - "ether": 20 + "atom":1000, + "photon":500, + "ether":20 } } ``` @@ -344,10 +396,10 @@ Returns on error: ```json { - "rest api": "2.0", + "rest api":"2.0", "code":500, - "error": "Could not find any balance for the specified account.", - "result": {} + "error":"Could not find any balance for the specified account.", + "result":{} } ``` @@ -358,6 +410,7 @@ url: /bank/create_transfer Functionality: Create a transfer in the bank module. Parameters: + | Parameter | Type | Default | Required | Description | | ------------ | ------ | ------- | -------- | ------------------------- | | sender | string | null | true | Address of sender | @@ -370,11 +423,11 @@ Returns on success: ```json { - "rest api": "2.0", + "rest api":"2.0", "code":200, - "error": "", - "result": { - "transaction": "TODO:" + "error":"", + "result":{ + "transaction":"TODO:" } } ``` @@ -383,9 +436,9 @@ Returns on failure: ```json { - "rest api": "2.0", + "rest api":"2.0", "code":500, - "error": "Could not create the transaction.", - "result": {} + "error":"Could not create the transaction.", + "result":{} } ``` diff --git a/docs/spec/light/getting_started.md b/docs/light/getting_started.md similarity index 69% rename from docs/spec/light/getting_started.md rename to docs/light/getting_started.md index 1856372c8..5f11956c0 100644 --- a/docs/spec/light/getting_started.md +++ b/docs/light/getting_started.md @@ -22,19 +22,19 @@ make transaction faster and more reliable in the following cases. ### Create an account -![deposit](https://github.com/irisnet/cosmos-sdk/raw/bianjie/lcd_spec/docs/spec/lcd/pics/create-account.png) +![deposit](pics/create-account.png) -First you need to get a new seed phrase :[get-seed](https://github.com/irisnet/cosmos-sdk/blob/bianjie/lcd_spec/docs/spec/lcd/api.md#keysseed---get) +First you need to get a new seed phrase :[get-seed](api.md#keysseed---get) -After having new seed, you could generate a new account with it : [keys](https://github.com/irisnet/cosmos-sdk/blob/bianjie/lcd_spec/docs/spec/lcd/api.md#keys---post) +After having new seed, you could generate a new account with it : [keys](api.md#keys---post) ### Transfer a token -![transfer](https://github.com/irisnet/cosmos-sdk/raw/bianjie/lcd_spec/docs/spec/lcd/pics/transfer-tokens.png) +![transfer](pics/transfer-tokens.png) The first step is to build an asset transfer transaction. Here we can post all necessary parameters to /create_transfer to get the unsigned transaction byte array. Refer to this link for detailed -operation: [build transaction](https://github.com/irisnet/cosmos-sdk/blob/bianjie/lcd_spec/docs/spec/lcd/api.md#create_transfer---post) +operation: [build transaction](api.md#create_transfer---post) Then sign the returned transaction byte array with users' private key. Finally broadcast the signed -transaction. Refer to this link for how to broadcast the signed transaction: [broadcast transaction](https://github.com/irisnet/cosmos-sdk/blob/bianjie/lcd_spec/docs/spec/lcd/api.md#create_transfer---post) +transaction. Refer to this link for how to broadcast the signed transaction: [broadcast transaction](api.md#create_transfer---post) diff --git a/docs/spec/light/load_balancer.md b/docs/light/load_balancer.md similarity index 99% rename from docs/spec/light/load_balancer.md rename to docs/light/load_balancer.md index b3ba212ed..0cc280827 100644 --- a/docs/spec/light/load_balancer.md +++ b/docs/light/load_balancer.md @@ -1,4 +1,4 @@ -# Load Balancing Module +# Load Balancing Module - WIP The LCD will be an important bridge between service providers and cosmos blockchain network. Suppose a service provider wants to monitor token information for millions of accounts. Then it has to keep diff --git a/docs/spec/light/pics/C2H.png b/docs/light/pics/C2H.png similarity index 100% rename from docs/spec/light/pics/C2H.png rename to docs/light/pics/C2H.png diff --git a/docs/spec/light/pics/H2C.png b/docs/light/pics/H2C.png similarity index 100% rename from docs/spec/light/pics/H2C.png rename to docs/light/pics/H2C.png diff --git a/docs/spec/light/pics/MA.png b/docs/light/pics/MA.png similarity index 100% rename from docs/spec/light/pics/MA.png rename to docs/light/pics/MA.png diff --git a/docs/spec/light/pics/absence1.png b/docs/light/pics/absence1.png similarity index 100% rename from docs/spec/light/pics/absence1.png rename to docs/light/pics/absence1.png diff --git a/docs/spec/light/pics/absence2.png b/docs/light/pics/absence2.png similarity index 100% rename from docs/spec/light/pics/absence2.png rename to docs/light/pics/absence2.png diff --git a/docs/spec/light/pics/absence3.png b/docs/light/pics/absence3.png similarity index 100% rename from docs/spec/light/pics/absence3.png rename to docs/light/pics/absence3.png diff --git a/docs/spec/light/pics/architecture.png b/docs/light/pics/architecture.png similarity index 100% rename from docs/spec/light/pics/architecture.png rename to docs/light/pics/architecture.png diff --git a/docs/spec/light/pics/changeProcess.png b/docs/light/pics/changeProcess.png similarity index 100% rename from docs/spec/light/pics/changeProcess.png rename to docs/light/pics/changeProcess.png diff --git a/docs/spec/light/pics/commitValidation.png b/docs/light/pics/commitValidation.png similarity index 100% rename from docs/spec/light/pics/commitValidation.png rename to docs/light/pics/commitValidation.png diff --git a/docs/spec/light/pics/create-account.png b/docs/light/pics/create-account.png similarity index 100% rename from docs/spec/light/pics/create-account.png rename to docs/light/pics/create-account.png diff --git a/docs/spec/light/pics/deposit.png b/docs/light/pics/deposit.png similarity index 100% rename from docs/spec/light/pics/deposit.png rename to docs/light/pics/deposit.png diff --git a/docs/spec/light/pics/existProof.png b/docs/light/pics/existProof.png similarity index 100% rename from docs/spec/light/pics/existProof.png rename to docs/light/pics/existProof.png diff --git a/docs/spec/light/pics/high-level.png b/docs/light/pics/high-level.png similarity index 100% rename from docs/spec/light/pics/high-level.png rename to docs/light/pics/high-level.png diff --git a/docs/spec/light/pics/light-client-architecture.png b/docs/light/pics/light-client-architecture.png similarity index 100% rename from docs/spec/light/pics/light-client-architecture.png rename to docs/light/pics/light-client-architecture.png diff --git a/docs/spec/light/pics/loadbalanceDiagram.png b/docs/light/pics/loadbalanceDiagram.png similarity index 100% rename from docs/spec/light/pics/loadbalanceDiagram.png rename to docs/light/pics/loadbalanceDiagram.png diff --git a/docs/spec/light/pics/simpleMerkleTree.png b/docs/light/pics/simpleMerkleTree.png similarity index 100% rename from docs/spec/light/pics/simpleMerkleTree.png rename to docs/light/pics/simpleMerkleTree.png diff --git a/docs/spec/light/pics/substoreProof.png b/docs/light/pics/substoreProof.png similarity index 100% rename from docs/spec/light/pics/substoreProof.png rename to docs/light/pics/substoreProof.png diff --git a/docs/spec/light/pics/transfer-tokens.png b/docs/light/pics/transfer-tokens.png similarity index 100% rename from docs/spec/light/pics/transfer-tokens.png rename to docs/light/pics/transfer-tokens.png diff --git a/docs/spec/light/pics/transfer.png b/docs/light/pics/transfer.png similarity index 100% rename from docs/spec/light/pics/transfer.png rename to docs/light/pics/transfer.png diff --git a/docs/spec/light/pics/trustPropagate.png b/docs/light/pics/trustPropagate.png similarity index 100% rename from docs/spec/light/pics/trustPropagate.png rename to docs/light/pics/trustPropagate.png diff --git a/docs/spec/light/pics/updateValidatorToHeight.png b/docs/light/pics/updateValidatorToHeight.png similarity index 100% rename from docs/spec/light/pics/updateValidatorToHeight.png rename to docs/light/pics/updateValidatorToHeight.png diff --git a/docs/spec/light/pics/validatorSetChange.png b/docs/light/pics/validatorSetChange.png similarity index 100% rename from docs/spec/light/pics/validatorSetChange.png rename to docs/light/pics/validatorSetChange.png diff --git a/docs/spec/light/pics/withdraw.png b/docs/light/pics/withdraw.png similarity index 100% rename from docs/spec/light/pics/withdraw.png rename to docs/light/pics/withdraw.png diff --git a/docs/spec/light/readme.md b/docs/light/readme.md similarity index 81% rename from docs/spec/light/readme.md rename to docs/light/readme.md index d15901b47..53e3b59bd 100644 --- a/docs/spec/light/readme.md +++ b/docs/light/readme.md @@ -16,11 +16,10 @@ LCD will be used in the Cosmos Hub, the first Hub in the Cosmos network. ## Contents -1. [**Overview**](#Overview) -2. [**Get Started**](https://github.com/irisnet/cosmos-sdk/blob/bianjie/lcd_spec/docs/spec/lcd/getting_started.md) -3. [**API**](https://github.com/irisnet/cosmos-sdk/blob/bianjie/lcd_spec/docs/spec/lcd/api.md) -4. [**Specifications**](https://github.com/irisnet/cosmos-sdk/blob/bianjie/lcd_spec/docs/spec/lcd/specification.md) -5. [**Future Improvements**](https://github.com/irisnet/cosmos-sdk/blob/bianjie/lcd_spec/docs/spec/lcd/Future%20Improvements.md) +1. [**Overview**](##Overview) +2. [**Get Started**](getting_started.md) +3. [**API**](api.md) +4. [**Specifications**](hspecification.md) ## Overview @@ -40,7 +39,7 @@ An application developer that would like to build a third party integration can with the LCD for the Cosmos Hub (or any other zone) and only needs to initialise it. Afterwards his application can interact with the zone as if it was running against a full node. -![high-level](https://github.com/irisnet/cosmos-sdk/raw/bianjie/lcd_spec/docs/spec/lcd/pics/high-level.png) +![high-level](pics/high-level.png) An application developer that wants to build an third party application for the Cosmos Hub (or any other zone) should build it against it's canonical API. That API is a combination of multiple parts. @@ -60,15 +59,15 @@ A full node of ABCI is different from its light client in the following ways: |-| ------------- | ----- | -------------- | | Execute and verify transactions|Yes|No|Full node will execute and verify all transactions while LCD won't| | Verify and save blocks|Yes|No|Full node will verify and save all blocks while LCD won't| -| Participate consensus| Yes|No|Only when the full node is a validator, it will participate consensus. LCD nodes never participate consensus| +| Participate consensus| Yes|No|Only when the full node is a validtor, it will participate consensus. LCD nodes never participate consensus| | Bandwidth cost|Huge|Little|Full node will receive all blocks. if the bandwidth is limited, it will fall behind the main network. What's more, if it happens to be a validator,it will slow down the consensus process. LCD requires little bandwidth. Only when serving local request, it will cost bandwidth| | Computing resource|Huge|Little|Full node will execute all transactions and verify all blocks which require much computing resource| | Storage resource|Huge|Little|Full node will save all blocks and ABCI states. LCD just saves validator sets and some checkpoints| | Power consume|Huge|Little|Full nodes have to be deployed on machines which have high performance and will be running all the time. So power consume will be huge. LCD can be deployed on the same machines as users' applications, or on independent machines but with poor performance. Besides, LCD can be shutdown anytime when necessary. So LCD only consume very little power, even mobile devices can meet the power requirement| | Provide APIs|All cosmos APIs|Modular APIs|Full node supports all cosmos APIs. LCD provides modular APIs according to users' configuration| -| Security level| High|High|Full node will verify all transactions and blocks by itself. LCD can't do this, but it can query any data from other full nodes and verify the data independently. So both full node and LCD don't need to trust any third nodes, they all can achieve high security| +| Secuity level| High|High|Full node will verify all transactions and blocks by itself. LCD can't do this, but it can query any data from other full nodes and verify the data independently. So both full node and LCD don't need to trust any third nodes, they all can achieve high security| -According to the above table, LCD can meet all users' functionality and security requirements, but +According to the above table, LCD can meet all users' functionality and security requirements, but only requires little resource on bandwidth, computing, storage and power. ## How does LCD achieve high security? @@ -84,7 +83,7 @@ The original trusted validator set should be prepositioned into its trust store, validator set comes from genesis file. During running time, if LCD detects different validator set, it will verify it and save new validated validator set to trust store. -![validator-set-change](https://github.com/irisnet/cosmos-sdk/raw/bianjie/lcd_spec/docs/spec/lcd/pics/validatorSetChange.png) +![validator-set-change](pics/validatorSetChange.png) ### Trust propagation @@ -93,7 +92,7 @@ validator set evolution. Validator set is the foundation of trust, and the trust other blockchain data, such as block and transaction. The propagate architecture is shown as follows: -![change-process](https://github.com/irisnet/cosmos-sdk/raw/bianjie/lcd_spec/docs/spec/lcd/pics/trustPropagate.png) +![change-process](pics/trustPropagate.png) In general, by trusted validator set, LCD can verify each block commit which contains all pre-commit data and block header data. Then the block hash, data hash and appHash are trusted. Based on this diff --git a/docs/spec/light/specification.md b/docs/light/specification.md similarity index 100% rename from docs/spec/light/specification.md rename to docs/light/specification.md diff --git a/docs/spec/light/todo.md b/docs/light/todo.md similarity index 100% rename from docs/spec/light/todo.md rename to docs/light/todo.md diff --git a/docs/spec/light/overview.md b/docs/spec/light/overview.md deleted file mode 100644 index 82cf542ea..000000000 --- a/docs/spec/light/overview.md +++ /dev/null @@ -1,55 +0,0 @@ -# Overview - -## What is a Light Client? - - The LCD is split into two separate components. The first component is generic for any Tendermint based application. It handles the security and connectivity aspects of following the header chain and verify proofs from full nodes against locally trusted validator set. Furthermore it exposes exactly the same API as any Tendermint Core node. The second component is specific for the Cosmos Hub (Gaiad). It works as a query endpoint and exposes the application specific functionality, which can be arbitrary. All queries against the application state have to go through the query endpoint. The advantage of the query endpoint is that it can verify the proofs that the application returns. - -## High-Level Architecture - -An application developer that would like to build a third party integration can ship his application with the LCD for the Cosmos Hub (or any other zone) and only needs to initialise it. Afterwards his application can interact with the zone as if it was running against a full node. - -![high-level](https://github.com/irisnet/cosmos-sdk/raw/bianjie/lcd_spec/docs/spec/lcd/pics/high-level.png) - -An application developer that wants to build an third party application for the Cosmos Hub (or any other zone) should build it against it's canonical API. That API is a combination of multiple parts. All zones have to expose ICS0 (TendermintAPI). Beyond that any zone is free to choose any combination of module APIs, depending on which modules the state machine uses. The Cosmos Hub will initially support ICS0 (TendermintAPI), ICS1 (KeyAPI), ICS20 (TokenAPI), ICS21 (StakingAPI) and ICS22 (GovernanceAPI). - -All applications are expected to only run against the LCD. The LCD is the only piece of software that offers stability guarantees around the zone API. - -### Comparision - -A full node of ABCI is different from its light client in the following ways: - -|| Full Node | LCD | Description| -|-| ------------- | ----- | -------------- | -| Execute and verify transactions|Yes|No|Full node will execute and verify all transactions while LCD won't| -| Verify and save blocks|Yes|No|Full node will verify and save all blocks while LCD won't| -| Participate consensus| Yes|No|Only when the full node is a validtor, it will participate consensus. LCD nodes never participate consensus| -| Bandwidth cost|Huge|Little|Full node will receive all blocks. if the bandwidth is limited, it will fall behind the main network. What's more, if it happens to be a validator,it will slow down the consensus process. LCD requires little bandwidth. Only when serving local request, it will cost bandwidth| -| Computing resource|Huge|Little|Full node will execute all transactions and verify all blocks which require much computing resource| -| Storage resource|Huge|Little|Full node will save all blocks and ABCI states. LCD just saves validator sets and some checkpoints| -| Power consume|Huge|Little|Full nodes have to be deployed on machines which have high performance and will be running all the time. So power consume will be huge. LCD can be deployed on the same machines as users' applications, or on independent machines but with poor performance. Besides, LCD can be shutdown anytime when necessary. So LCD only consume very little power, even mobile devices can meet the power requirement| -| Provide APIs|All cosmos APIs|Modular APIs|Full node supports all cosmos APIs. LCD provides modular APIs according to users' configuration| -| Secuity level| High|High|Full node will verify all transactions and blocks by itself. LCD can't do this, but it can query any data from other full nodes and verify the data independently. So both full node and LCD don't need to trust any third nodes, they all can achieve high security| - -According to the above table, LCD can meet all users' functionality and security requirements, but only requires little resource on bandwidth, computing, storage and power. - -## How does LCD achieve high security? - -### Trusted validator set - -The base design philosophy of lcd follows the two rules: - -1. **Doesn't trust any blockchin nodes, including validator nodes and other full nodes** -2. **Only trusts the whole validator set** - -The original trusted validator set should be prepositioned into its trust store, usually this validator set comes from genesis file. During running time, if LCD detects different validator set, it will verify it and save new validated validator set to trust store. - -![validator-set-change](https://github.com/irisnet/cosmos-sdk/raw/bianjie/lcd_spec/docs/spec/lcd/pics/validatorSetChange.png) - - -### Trust propagation - -From the above section, we come to know how to get trusted validator set and how lcd keeps track of validator set evolution. Validator set is the foundation of trust, and the trust can propagate to other blockchain data, such as block and transaction. The propagate architecture is shown as follows: - -![change-process](https://github.com/irisnet/cosmos-sdk/raw/bianjie/lcd_spec/docs/spec/lcd/pics/trustPropagate.png) - -In general, by trusted validator set, LCD can verify each block commit which contains all pre-commit data and block header data. Then the block hash, data hash and appHash are trusted. Based on this and merkle proof, all transactions data and ABCI states can be verified too. Detailed implementation will be posted on technical specification. From 0572a2743e2de71b03bafc3df58a96ed0c953fdf Mon Sep 17 00:00:00 2001 From: Christopher Goes Date: Wed, 11 Jul 2018 19:17:09 +0200 Subject: [PATCH 07/39] Changes from merge --- x/stake/simulation_test.go | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/x/stake/simulation_test.go b/x/stake/simulation_test.go index f9abc6064..b7fe42e38 100644 --- a/x/stake/simulation_test.go +++ b/x/stake/simulation_test.go @@ -109,10 +109,11 @@ func SimulateMsgCreateValidator(m auth.AccountMapper, k Keeper) mock.TestAndRunM return "nop", nil } msg := MsgCreateValidator{ - Description: description, - ValidatorAddr: address, - PubKey: pubkey, - SelfDelegation: sdk.NewIntCoin(denom, amount), + Description: description, + ValidatorAddr: address, + DelegatorAddr: address, + PubKey: pubkey, + Delegation: sdk.NewIntCoin(denom, amount), } require.Nil(t, msg.ValidateBasic(), "expected msg to pass ValidateBasic: %s", msg.GetSignBytes()) ctx, write := ctx.CacheContext() @@ -173,7 +174,7 @@ func SimulateMsgDelegate(m auth.AccountMapper, k Keeper) mock.TestAndRunMsg { msg := MsgDelegate{ DelegatorAddr: delegatorAddress, ValidatorAddr: validatorAddress, - Bond: sdk.NewIntCoin(denom, amount), + Delegation: sdk.NewIntCoin(denom, amount), } require.Nil(t, msg.ValidateBasic(), "expected msg to pass ValidateBasic: %s", msg.GetSignBytes()) ctx, write := ctx.CacheContext() From 53138fb36f5854466c85a19f587fa9b54361b179 Mon Sep 17 00:00:00 2001 From: Christopher Goes Date: Wed, 11 Jul 2018 19:43:25 +0200 Subject: [PATCH 08/39] 'make test_sim', simulation folder --- Makefile | 8 ++- x/stake/{ => simulation}/simulation_test.go | 59 +++++++++++---------- 2 files changed, 36 insertions(+), 31 deletions(-) rename x/stake/{ => simulation}/simulation_test.go (85%) diff --git a/Makefile b/Makefile index 4d761ede1..ce753afef 100644 --- a/Makefile +++ b/Makefile @@ -1,5 +1,6 @@ PACKAGES=$(shell go list ./... | grep -v '/vendor/') -PACKAGES_NOCLITEST=$(shell go list ./... | grep -v '/vendor/' | grep -v github.com/cosmos/cosmos-sdk/cmd/gaia/cli_test) +PACKAGES_NOCLITEST=$(shell go list ./... | grep -v '/vendor/' | grep -v '/simulation' | grep -v github.com/cosmos/cosmos-sdk/cmd/gaia/cli_test) +PACKAGES_SIMTEST=$(shell go list ./... | grep -v '/vendor/' | grep '/simulation') COMMIT_HASH := $(shell git rev-parse --short HEAD) BUILD_FLAGS = -tags netgo -ldflags "-X github.com/cosmos/cosmos-sdk/version.GitCommit=${COMMIT_HASH}" @@ -98,6 +99,9 @@ test_unit: test_race: @go test -race $(PACKAGES_NOCLITEST) +test_sim: + @go test $(PACKAGES_SIMTEST) -v + test_cover: @bash tests/test_cover.sh @@ -181,4 +185,4 @@ remotenet-status: # To avoid unintended conflicts with file names, always add to .PHONY # unless there is a reason not to. # https://www.gnu.org/software/make/manual/html_node/Phony-Targets.html -.PHONY: build build_examples install install_examples install_debug dist check_tools get_tools get_vendor_deps draw_deps test test_cli test_unit test_cover test_lint benchmark devdoc_init devdoc devdoc_save devdoc_update build-linux build-docker-gaiadnode localnet-start localnet-stop remotenet-start remotenet-stop remotenet-status format +.PHONY: build build_examples install install_examples install_debug dist check_tools get_tools get_vendor_deps draw_deps test test_cli test_unit test_cover test_sim test_lint benchmark devdoc_init devdoc devdoc_save devdoc_update build-linux build-docker-gaiadnode localnet-start localnet-stop remotenet-start remotenet-stop remotenet-status format diff --git a/x/stake/simulation_test.go b/x/stake/simulation/simulation_test.go similarity index 85% rename from x/stake/simulation_test.go rename to x/stake/simulation/simulation_test.go index b7fe42e38..fd951b2b7 100644 --- a/x/stake/simulation_test.go +++ b/x/stake/simulation/simulation_test.go @@ -1,7 +1,6 @@ -package stake +package simulation import ( - // "errors" "fmt" "math/rand" "testing" @@ -12,6 +11,7 @@ import ( "github.com/cosmos/cosmos-sdk/x/auth" "github.com/cosmos/cosmos-sdk/x/bank" "github.com/cosmos/cosmos-sdk/x/mock" + "github.com/cosmos/cosmos-sdk/x/stake" abci "github.com/tendermint/tendermint/abci/types" "github.com/tendermint/tendermint/crypto" ) @@ -22,7 +22,7 @@ var ( // ModuleInvariants runs all invariants of the stake module. // Currently: total supply, positive power -func ModuleInvariants(ck bank.Keeper, k Keeper) mock.Invariant { +func ModuleInvariants(ck bank.Keeper, k stake.Keeper) mock.Invariant { return func(t *testing.T, app *mock.App, log string) { SupplyInvariants(ck, k)(t, app, log) PositivePowerInvariant(k)(t, app, log) @@ -31,7 +31,7 @@ func ModuleInvariants(ck bank.Keeper, k Keeper) mock.Invariant { } // SupplyInvariants checks that the total supply reflects all held loose tokens, bonded tokens, and unbonding delegations -func SupplyInvariants(ck bank.Keeper, k Keeper) mock.Invariant { +func SupplyInvariants(ck bank.Keeper, k stake.Keeper) mock.Invariant { return func(t *testing.T, app *mock.App, log string) { ctx := app.NewContext(false, abci.Header{}) pool := k.GetPool(ctx) @@ -73,7 +73,7 @@ func SupplyInvariants(ck bank.Keeper, k Keeper) mock.Invariant { } // PositivePowerInvariant checks that all stored validators have > 0 power -func PositivePowerInvariant(k Keeper) mock.Invariant { +func PositivePowerInvariant(k stake.Keeper) mock.Invariant { return func(t *testing.T, app *mock.App, log string) { ctx := app.NewContext(false, abci.Header{}) k.IterateValidatorsBonded(ctx, func(_ int64, validator sdk.Validator) bool { @@ -85,17 +85,17 @@ func PositivePowerInvariant(k Keeper) mock.Invariant { } // ValidatorSetInvariant checks equivalence of Tendermint validator set and SDK validator set -func ValidatorSetInvariant(k Keeper) mock.Invariant { +func ValidatorSetInvariant(k stake.Keeper) mock.Invariant { return func(t *testing.T, app *mock.App, log string) { // TODO } } // SimulateMsgCreateValidator -func SimulateMsgCreateValidator(m auth.AccountMapper, k Keeper) mock.TestAndRunMsg { +func SimulateMsgCreateValidator(m auth.AccountMapper, k stake.Keeper) mock.TestAndRunMsg { return func(t *testing.T, r *rand.Rand, ctx sdk.Context, keys []crypto.PrivKey, log string) (action string, err sdk.Error) { denom := k.GetParams(ctx).BondDenom - description := Description{ + description := stake.Description{ Moniker: mock.RandStringOfLength(r, 10), } key := keys[r.Intn(len(keys))] @@ -108,7 +108,7 @@ func SimulateMsgCreateValidator(m auth.AccountMapper, k Keeper) mock.TestAndRunM if amount.Equal(sdk.ZeroInt()) { return "nop", nil } - msg := MsgCreateValidator{ + msg := stake.MsgCreateValidator{ Description: description, ValidatorAddr: address, DelegatorAddr: address, @@ -117,7 +117,7 @@ func SimulateMsgCreateValidator(m auth.AccountMapper, k Keeper) mock.TestAndRunM } require.Nil(t, msg.ValidateBasic(), "expected msg to pass ValidateBasic: %s", msg.GetSignBytes()) ctx, write := ctx.CacheContext() - result := handleMsgCreateValidator(ctx, msg, k) + result := stake.NewHandler(k)(ctx, msg) if result.IsOK() { write() } @@ -129,9 +129,9 @@ func SimulateMsgCreateValidator(m auth.AccountMapper, k Keeper) mock.TestAndRunM } // SimulateMsgEditValidator -func SimulateMsgEditValidator(k Keeper) mock.TestAndRunMsg { +func SimulateMsgEditValidator(k stake.Keeper) mock.TestAndRunMsg { return func(t *testing.T, r *rand.Rand, ctx sdk.Context, keys []crypto.PrivKey, log string) (action string, err sdk.Error) { - description := Description{ + description := stake.Description{ Moniker: mock.RandStringOfLength(r, 10), Identity: mock.RandStringOfLength(r, 10), Website: mock.RandStringOfLength(r, 10), @@ -140,13 +140,13 @@ func SimulateMsgEditValidator(k Keeper) mock.TestAndRunMsg { key := keys[r.Intn(len(keys))] pubkey := key.PubKey() address := sdk.AccAddress(pubkey.Address()) - msg := MsgEditValidator{ + msg := stake.MsgEditValidator{ Description: description, ValidatorAddr: address, } require.Nil(t, msg.ValidateBasic(), "expected msg to pass ValidateBasic: %s", msg.GetSignBytes()) ctx, write := ctx.CacheContext() - result := handleMsgEditValidator(ctx, msg, k) + result := stake.NewHandler(k)(ctx, msg) if result.IsOK() { write() } @@ -157,7 +157,7 @@ func SimulateMsgEditValidator(k Keeper) mock.TestAndRunMsg { } // SimulateMsgDelegate -func SimulateMsgDelegate(m auth.AccountMapper, k Keeper) mock.TestAndRunMsg { +func SimulateMsgDelegate(m auth.AccountMapper, k stake.Keeper) mock.TestAndRunMsg { return func(t *testing.T, r *rand.Rand, ctx sdk.Context, keys []crypto.PrivKey, log string) (action string, err sdk.Error) { denom := k.GetParams(ctx).BondDenom validatorKey := keys[r.Intn(len(keys))] @@ -171,14 +171,14 @@ func SimulateMsgDelegate(m auth.AccountMapper, k Keeper) mock.TestAndRunMsg { if amount.Equal(sdk.ZeroInt()) { return "nop", nil } - msg := MsgDelegate{ + msg := stake.MsgDelegate{ DelegatorAddr: delegatorAddress, ValidatorAddr: validatorAddress, Delegation: sdk.NewIntCoin(denom, amount), } require.Nil(t, msg.ValidateBasic(), "expected msg to pass ValidateBasic: %s", msg.GetSignBytes()) ctx, write := ctx.CacheContext() - result := handleMsgDelegate(ctx, msg, k) + result := stake.NewHandler(k)(ctx, msg) if result.IsOK() { write() } @@ -189,7 +189,7 @@ func SimulateMsgDelegate(m auth.AccountMapper, k Keeper) mock.TestAndRunMsg { } // SimulateMsgBeginUnbonding -func SimulateMsgBeginUnbonding(m auth.AccountMapper, k Keeper) mock.TestAndRunMsg { +func SimulateMsgBeginUnbonding(m auth.AccountMapper, k stake.Keeper) mock.TestAndRunMsg { return func(t *testing.T, r *rand.Rand, ctx sdk.Context, keys []crypto.PrivKey, log string) (action string, err sdk.Error) { msg := fmt.Sprintf("TestMsgBeginUnbonding with %s", "ok") return msg, nil @@ -197,7 +197,7 @@ func SimulateMsgBeginUnbonding(m auth.AccountMapper, k Keeper) mock.TestAndRunMs } // SimulateMsgCompleteUnbonding -func SimulateMsgCompleteUnbonding(k Keeper) mock.TestAndRunMsg { +func SimulateMsgCompleteUnbonding(k stake.Keeper) mock.TestAndRunMsg { return func(t *testing.T, r *rand.Rand, ctx sdk.Context, keys []crypto.PrivKey, log string) (action string, err sdk.Error) { msg := fmt.Sprintf("TestMsgCompleteUnbonding with %s", "ok") return msg, nil @@ -205,7 +205,7 @@ func SimulateMsgCompleteUnbonding(k Keeper) mock.TestAndRunMsg { } // SimulateMsgBeginRedelegate -func SimulateMsgBeginRedelegate(m auth.AccountMapper, k Keeper) mock.TestAndRunMsg { +func SimulateMsgBeginRedelegate(m auth.AccountMapper, k stake.Keeper) mock.TestAndRunMsg { return func(t *testing.T, r *rand.Rand, ctx sdk.Context, keys []crypto.PrivKey, log string) (action string, err sdk.Error) { denom := k.GetParams(ctx).BondDenom sourceValidatorKey := keys[r.Intn(len(keys))] @@ -222,7 +222,7 @@ func SimulateMsgBeginRedelegate(m auth.AccountMapper, k Keeper) mock.TestAndRunM if amount.Equal(sdk.ZeroInt()) { return "nop", nil } - msg := MsgBeginRedelegate{ + msg := stake.MsgBeginRedelegate{ DelegatorAddr: delegatorAddress, ValidatorSrcAddr: sourceValidatorAddress, ValidatorDstAddr: destValidatorAddress, @@ -230,7 +230,7 @@ func SimulateMsgBeginRedelegate(m auth.AccountMapper, k Keeper) mock.TestAndRunM } require.Nil(t, msg.ValidateBasic(), "expected msg to pass ValidateBasic: %s", msg.GetSignBytes()) ctx, write := ctx.CacheContext() - result := handleMsgBeginRedelegate(ctx, msg, k) + result := stake.NewHandler(k)(ctx, msg) if result.IsOK() { write() } @@ -241,7 +241,7 @@ func SimulateMsgBeginRedelegate(m auth.AccountMapper, k Keeper) mock.TestAndRunM } // SimulateMsgCompleteRedelegate -func SimulateMsgCompleteRedelegate(k Keeper) mock.TestAndRunMsg { +func SimulateMsgCompleteRedelegate(k stake.Keeper) mock.TestAndRunMsg { return func(t *testing.T, r *rand.Rand, ctx sdk.Context, keys []crypto.PrivKey, log string) (action string, err sdk.Error) { msg := fmt.Sprintf("TestMsgCompleteRedelegate with %s", "ok") return msg, nil @@ -249,10 +249,10 @@ func SimulateMsgCompleteRedelegate(k Keeper) mock.TestAndRunMsg { } // SimulationSetup -func SimulationSetup(mapp *mock.App, k Keeper) mock.RandSetup { +func SimulationSetup(mapp *mock.App, k stake.Keeper) mock.RandSetup { return func(r *rand.Rand, privKeys []crypto.PrivKey) { ctx := mapp.NewContext(false, abci.Header{}) - InitGenesis(ctx, k, DefaultGenesisState()) + stake.InitGenesis(ctx, k, stake.DefaultGenesisState()) params := k.GetParams(ctx) denom := params.BondDenom loose := sdk.ZeroInt() @@ -277,10 +277,10 @@ func TestStakeWithRandomMessages(t *testing.T) { mapper := mapp.AccountMapper coinKeeper := bank.NewKeeper(mapper) stakeKey := sdk.NewKVStoreKey("stake") - stakeKeeper := NewKeeper(mapp.Cdc, stakeKey, coinKeeper, DefaultCodespace) - mapp.Router().AddRoute("stake", NewHandler(stakeKeeper)) + stakeKeeper := stake.NewKeeper(mapp.Cdc, stakeKey, coinKeeper, stake.DefaultCodespace) + mapp.Router().AddRoute("stake", stake.NewHandler(stakeKeeper)) mapp.SetEndBlocker(func(ctx sdk.Context, req abci.RequestEndBlock) abci.ResponseEndBlock { - validatorUpdates := EndBlocker(ctx, stakeKeeper) + validatorUpdates := stake.EndBlocker(ctx, stakeKeeper) return abci.ResponseEndBlock{ ValidatorUpdates: validatorUpdates, } @@ -298,7 +298,8 @@ func TestStakeWithRandomMessages(t *testing.T) { SimulateMsgDelegate(mapper, stakeKeeper), SimulateMsgBeginUnbonding(mapper, stakeKeeper), SimulateMsgCompleteUnbonding(stakeKeeper), - SimulateMsgBeginRedelegate(mapper, stakeKeeper), + // XXX TODO Bug found! + // SimulateMsgBeginRedelegate(mapper, stakeKeeper), SimulateMsgCompleteRedelegate(stakeKeeper), }, []mock.RandSetup{ SimulationSetup(mapp, stakeKeeper), From 88364c838eaf14f171df403dcd2c6c37e4431ef1 Mon Sep 17 00:00:00 2001 From: Christopher Goes Date: Wed, 11 Jul 2018 19:51:04 +0200 Subject: [PATCH 09/39] TestMsgBeginUnbonding --- x/stake/simulation/simulation_test.go | 28 +++++++++++++++++++++++++-- 1 file changed, 26 insertions(+), 2 deletions(-) diff --git a/x/stake/simulation/simulation_test.go b/x/stake/simulation/simulation_test.go index fd951b2b7..626108236 100644 --- a/x/stake/simulation/simulation_test.go +++ b/x/stake/simulation/simulation_test.go @@ -191,8 +191,32 @@ func SimulateMsgDelegate(m auth.AccountMapper, k stake.Keeper) mock.TestAndRunMs // SimulateMsgBeginUnbonding func SimulateMsgBeginUnbonding(m auth.AccountMapper, k stake.Keeper) mock.TestAndRunMsg { return func(t *testing.T, r *rand.Rand, ctx sdk.Context, keys []crypto.PrivKey, log string) (action string, err sdk.Error) { - msg := fmt.Sprintf("TestMsgBeginUnbonding with %s", "ok") - return msg, nil + denom := k.GetParams(ctx).BondDenom + validatorKey := keys[r.Intn(len(keys))] + validatorAddress := sdk.AccAddress(validatorKey.PubKey().Address()) + delegatorKey := keys[r.Intn(len(keys))] + delegatorAddress := sdk.AccAddress(delegatorKey.PubKey().Address()) + amount := m.GetAccount(ctx, delegatorAddress).GetCoins().AmountOf(denom) + if amount.GT(sdk.ZeroInt()) { + amount = sdk.NewInt(int64(r.Intn(int(amount.Int64())))) + } + if amount.Equal(sdk.ZeroInt()) { + return "nop", nil + } + msg := stake.MsgBeginUnbonding{ + DelegatorAddr: delegatorAddress, + ValidatorAddr: validatorAddress, + SharesAmount: sdk.NewRatFromInt(amount), + } + require.Nil(t, msg.ValidateBasic(), "expected msg to pass ValidateBasic: %s", msg.GetSignBytes()) + ctx, write := ctx.CacheContext() + result := stake.NewHandler(k)(ctx, msg) + if result.IsOK() { + write() + } + stats[fmt.Sprintf("stake/beginunbonding/%v", result.IsOK())] += 1 + action = fmt.Sprintf("TestMsgBeginUnbonding: %s", msg.GetSignBytes()) + return action, nil } } From 4623923fb877def1d7995841b92895a0aca30cbc Mon Sep 17 00:00:00 2001 From: Christopher Goes Date: Wed, 11 Jul 2018 22:44:21 +0200 Subject: [PATCH 10/39] Add 'test_sim' to CircleCI --- .circleci/config.yml | 19 ++++++++++++ x/stake/simulation/simulation_test.go | 44 ++++++++++++++++++++++++--- 2 files changed, 58 insertions(+), 5 deletions(-) diff --git a/.circleci/config.yml b/.circleci/config.yml index 155945ae6..b12fd8a3a 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -85,6 +85,22 @@ jobs: export PATH="$GOBIN:$PATH" make test_cli + test_sim: + <<: *defaults + parallelism: 1 + steps: + - attach_workspace: + at: /tmp/workspace + - restore_cache: + key: v1-pkg-cache + - restore_cache: + key: v1-tree-{{ .Environment.CIRCLE_SHA1 }} + - run: + name: Test simulation + command: | + export PATH="$GOBIN:$PATH" + make test_sim + test_cover: <<: *defaults parallelism: 2 @@ -145,6 +161,9 @@ workflows: - test_cli: requires: - setup_dependencies + - test_sim: + requires: + - setup_dependencies - test_cover: requires: - setup_dependencies diff --git a/x/stake/simulation/simulation_test.go b/x/stake/simulation/simulation_test.go index 626108236..621e2c5b2 100644 --- a/x/stake/simulation/simulation_test.go +++ b/x/stake/simulation/simulation_test.go @@ -223,8 +223,23 @@ func SimulateMsgBeginUnbonding(m auth.AccountMapper, k stake.Keeper) mock.TestAn // SimulateMsgCompleteUnbonding func SimulateMsgCompleteUnbonding(k stake.Keeper) mock.TestAndRunMsg { return func(t *testing.T, r *rand.Rand, ctx sdk.Context, keys []crypto.PrivKey, log string) (action string, err sdk.Error) { - msg := fmt.Sprintf("TestMsgCompleteUnbonding with %s", "ok") - return msg, nil + validatorKey := keys[r.Intn(len(keys))] + validatorAddress := sdk.AccAddress(validatorKey.PubKey().Address()) + delegatorKey := keys[r.Intn(len(keys))] + delegatorAddress := sdk.AccAddress(delegatorKey.PubKey().Address()) + msg := stake.MsgCompleteUnbonding{ + DelegatorAddr: delegatorAddress, + ValidatorAddr: validatorAddress, + } + require.Nil(t, msg.ValidateBasic(), "expected msg to pass ValidateBasic: %s", msg.GetSignBytes()) + ctx, write := ctx.CacheContext() + result := stake.NewHandler(k)(ctx, msg) + if result.IsOK() { + write() + } + stats[fmt.Sprintf("stake/completeunbonding/%v", result.IsOK())] += 1 + action = fmt.Sprintf("TestMsgCompleteUnbonding with %s", msg.GetSignBytes()) + return action, nil } } @@ -267,8 +282,26 @@ func SimulateMsgBeginRedelegate(m auth.AccountMapper, k stake.Keeper) mock.TestA // SimulateMsgCompleteRedelegate func SimulateMsgCompleteRedelegate(k stake.Keeper) mock.TestAndRunMsg { return func(t *testing.T, r *rand.Rand, ctx sdk.Context, keys []crypto.PrivKey, log string) (action string, err sdk.Error) { - msg := fmt.Sprintf("TestMsgCompleteRedelegate with %s", "ok") - return msg, nil + validatorSrcKey := keys[r.Intn(len(keys))] + validatorSrcAddress := sdk.AccAddress(validatorSrcKey.PubKey().Address()) + validatorDstKey := keys[r.Intn(len(keys))] + validatorDstAddress := sdk.AccAddress(validatorDstKey.PubKey().Address()) + delegatorKey := keys[r.Intn(len(keys))] + delegatorAddress := sdk.AccAddress(delegatorKey.PubKey().Address()) + msg := stake.MsgCompleteRedelegate{ + DelegatorAddr: delegatorAddress, + ValidatorSrcAddr: validatorSrcAddress, + ValidatorDstAddr: validatorDstAddress, + } + require.Nil(t, msg.ValidateBasic(), "expected msg to pass ValidateBasic: %s", msg.GetSignBytes()) + ctx, write := ctx.CacheContext() + result := stake.NewHandler(k)(ctx, msg) + if result.IsOK() { + write() + } + stats[fmt.Sprintf("stake/completeredelegate/%v", result.IsOK())] += 1 + action = fmt.Sprintf("TestMsgCompleteRedelegate with %s", msg.GetSignBytes()) + return action, nil } } @@ -320,7 +353,8 @@ func TestStakeWithRandomMessages(t *testing.T) { SimulateMsgCreateValidator(mapper, stakeKeeper), SimulateMsgEditValidator(stakeKeeper), SimulateMsgDelegate(mapper, stakeKeeper), - SimulateMsgBeginUnbonding(mapper, stakeKeeper), + // XXX TODO + // SimulateMsgBeginUnbonding(mapper, stakeKeeper), SimulateMsgCompleteUnbonding(stakeKeeper), // XXX TODO Bug found! // SimulateMsgBeginRedelegate(mapper, stakeKeeper), From f9f326cefb18cb0fa9689121a8bc6890616ffe18 Mon Sep 17 00:00:00 2001 From: Christopher Goes Date: Thu, 12 Jul 2018 00:14:37 +0200 Subject: [PATCH 11/39] Move files --- cmd/gaia/simulation/sim_test.go | 11 +++++++++++ .../simulation/{simulation_test.go => sim_test.go} | 0 2 files changed, 11 insertions(+) create mode 100644 cmd/gaia/simulation/sim_test.go rename x/stake/simulation/{simulation_test.go => sim_test.go} (100%) diff --git a/cmd/gaia/simulation/sim_test.go b/cmd/gaia/simulation/sim_test.go new file mode 100644 index 000000000..77940fba7 --- /dev/null +++ b/cmd/gaia/simulation/sim_test.go @@ -0,0 +1,11 @@ +package simulation + +import ( + "testing" + + "github.com/stretchr/testify/require" +) + +func TestFullGaiaSimulation(t *testing.T) { + require.True(t, true, "should not happen") +} diff --git a/x/stake/simulation/simulation_test.go b/x/stake/simulation/sim_test.go similarity index 100% rename from x/stake/simulation/simulation_test.go rename to x/stake/simulation/sim_test.go From 601251d9b8e2307b5dd22e9c00689d8bb545326b Mon Sep 17 00:00:00 2001 From: Christopher Goes Date: Thu, 12 Jul 2018 21:31:24 +0200 Subject: [PATCH 12/39] Update Gopkg.lock & Makefile --- Gopkg.lock | 181 ++++++++++++++++++++++++++++++++++++++++++++++++----- Makefile | 2 +- 2 files changed, 165 insertions(+), 18 deletions(-) diff --git a/Gopkg.lock b/Gopkg.lock index a73a2009a..eaf4d82dd 100644 --- a/Gopkg.lock +++ b/Gopkg.lock @@ -3,59 +3,78 @@ [[projects]] branch = "master" + digest = "1:09a7f74eb6bb3c0f14d8926610c87f569c5cff68e978d30e9a3540aeb626fdf0" name = "github.com/bartekn/go-bip39" packages = ["."] + pruneopts = "UT" revision = "a05967ea095d81c8fe4833776774cfaff8e5036c" [[projects]] branch = "master" + digest = "1:d6afaeed1502aa28e80a4ed0981d570ad91b2579193404256ce672ed0a609e0d" name = "github.com/beorn7/perks" packages = ["quantile"] + pruneopts = "UT" revision = "3a771d992973f24aa725d07868b467d1ddfceafb" [[projects]] + digest = "1:1343a2963481a305ca4d051e84bc2abd16b601ee22ed324f8d605de1adb291b0" name = "github.com/bgentry/speakeasy" packages = ["."] + pruneopts = "UT" revision = "4aabc24848ce5fd31929f7d1e4ea74d3709c14cd" version = "v0.1.0" [[projects]] branch = "master" + digest = "1:70f6b224a59b2fa453debffa85c77f71063d8754b90c8c4fbad5794e2c382b0f" name = "github.com/brejski/hid" packages = ["."] + pruneopts = "UT" revision = "06112dcfcc50a7e0e4fd06e17f9791e788fdaafc" [[projects]] branch = "master" + digest = "1:6aabc1566d6351115d561d038da82a4c19b46c3b6e17f4a0a2fa60260663dc79" name = "github.com/btcsuite/btcd" packages = ["btcec"] + pruneopts = "UT" revision = "fdfc19097e7ac6b57035062056f5b7b4638b8898" [[projects]] branch = "master" + digest = "1:386de157f7d19259a7f9c81f26ce011223ce0f090353c1152ffdf730d7d10ac2" name = "github.com/btcsuite/btcutil" packages = ["bech32"] + pruneopts = "UT" revision = "ab6388e0c60ae4834a1f57511e20c17b5f78be4b" [[projects]] + digest = "1:a2c1d0e43bd3baaa071d1b9ed72c27d78169b2b269f71c105ac4ba34b1be4a39" name = "github.com/davecgh/go-spew" packages = ["spew"] + pruneopts = "UT" revision = "346938d642f2ec3594ed81d874461961cd0faa76" version = "v1.1.0" [[projects]] branch = "master" + digest = "1:c7644c73a3d23741fdba8a99b1464e021a224b7e205be497271a8003a15ca41b" name = "github.com/ebuchman/fail-test" packages = ["."] + pruneopts = "UT" revision = "95f809107225be108efcf10a3509e4ea6ceef3c4" [[projects]] + digest = "1:abeb38ade3f32a92943e5be54f55ed6d6e3b6602761d74b4aab4c9dd45c18abd" name = "github.com/fsnotify/fsnotify" packages = ["."] + pruneopts = "UT" revision = "c2828203cd70a50dcccfb2761f8b1f8ceef9a8e9" version = "v1.4.7" [[projects]] + digest = "1:fa30c0652956e159cdb97dcb2ef8b8db63ed668c02a5c3a40961c8f0641252fe" name = "github.com/go-kit/kit" packages = [ "log", @@ -64,24 +83,30 @@ "metrics", "metrics/discard", "metrics/internal/lv", - "metrics/prometheus" + "metrics/prometheus", ] + pruneopts = "UT" revision = "4dc7be5d2d12881735283bcab7352178e190fc71" version = "v0.6.0" [[projects]] + digest = "1:31a18dae27a29aa074515e43a443abfd2ba6deb6d69309d8d7ce789c45f34659" name = "github.com/go-logfmt/logfmt" packages = ["."] + pruneopts = "UT" revision = "390ab7935ee28ec6b286364bba9b4dd6410cb3d5" version = "v0.3.0" [[projects]] + digest = "1:c4a2528ccbcabf90f9f3c464a5fc9e302d592861bbfd0b7135a7de8a943d0406" name = "github.com/go-stack/stack" packages = ["."] + pruneopts = "UT" revision = "259ab82a6cad3992b4e21ff5cac294ccb06474bc" version = "v1.7.0" [[projects]] + digest = "1:af1306bff89268721ea2550d504413c9487ebfca11e2ff8f39ae79b99a720ff5" name = "github.com/gogo/protobuf" packages = [ "gogoproto", @@ -89,49 +114,61 @@ "proto", "protoc-gen-gogo/descriptor", "sortkeys", - "types" + "types", ] + pruneopts = "UT" revision = "1adfc126b41513cc696b209667c8656ea7aac67c" version = "v1.0.0" [[projects]] + digest = "1:cb22af0ed7c72d495d8be1106233ee553898950f15fd3f5404406d44c2e86888" name = "github.com/golang/protobuf" packages = [ "proto", "ptypes", "ptypes/any", "ptypes/duration", - "ptypes/timestamp" + "ptypes/timestamp", ] + pruneopts = "UT" revision = "b4deda0973fb4c70b50d226b1af49f3da59f5265" version = "v1.1.0" [[projects]] branch = "master" + digest = "1:4a0c6bb4805508a6287675fac876be2ac1182539ca8a32468d8128882e9d5009" name = "github.com/golang/snappy" packages = ["."] + pruneopts = "UT" revision = "2e65f85255dbc3072edf28d6b5b8efc472979f5a" [[projects]] + digest = "1:c79fb010be38a59d657c48c6ba1d003a8aa651fa56b579d959d74573b7dff8e1" name = "github.com/gorilla/context" packages = ["."] + pruneopts = "UT" revision = "08b5f424b9271eedf6f9f0ce86cb9396ed337a42" version = "v1.1.1" [[projects]] + digest = "1:e73f5b0152105f18bc131fba127d9949305c8693f8a762588a82a48f61756f5f" name = "github.com/gorilla/mux" packages = ["."] + pruneopts = "UT" revision = "e3702bed27f0d39777b0b37b664b6280e8ef8fbf" version = "v1.6.2" [[projects]] + digest = "1:43dd08a10854b2056e615d1b1d22ac94559d822e1f8b6fcc92c1a1057e85188e" name = "github.com/gorilla/websocket" packages = ["."] + pruneopts = "UT" revision = "ea4d1f681babbce9545c9c5f3d5194a789c89f5b" version = "v1.2.0" [[projects]] branch = "master" + digest = "1:8951fe6e358876736d8fa1f3992624fdbb2dec6bc49401c1381d1ef8abbb544f" name = "github.com/hashicorp/hcl" packages = [ ".", @@ -142,162 +179,208 @@ "hcl/token", "json/parser", "json/scanner", - "json/token" + "json/token", ] + pruneopts = "UT" revision = "ef8a98b0bbce4a65b5aa4c368430a80ddc533168" [[projects]] + digest = "1:870d441fe217b8e689d7949fef6e43efbc787e50f200cb1e70dbca9204a1d6be" name = "github.com/inconshreveable/mousetrap" packages = ["."] + pruneopts = "UT" revision = "76626ae9c91c4f2a10f34cad8ce83ea42c93bb75" version = "v1.0" [[projects]] branch = "master" + digest = "1:39b27d1381a30421f9813967a5866fba35dc1d4df43a6eefe3b7a5444cb07214" name = "github.com/jmhodges/levigo" packages = ["."] + pruneopts = "UT" revision = "c42d9e0ca023e2198120196f842701bb4c55d7b9" [[projects]] branch = "master" + digest = "1:a64e323dc06b73892e5bb5d040ced475c4645d456038333883f58934abbf6f72" name = "github.com/kr/logfmt" packages = ["."] + pruneopts = "UT" revision = "b84e30acd515aadc4b783ad4ff83aff3299bdfe0" [[projects]] + digest = "1:c568d7727aa262c32bdf8a3f7db83614f7af0ed661474b24588de635c20024c7" name = "github.com/magiconair/properties" packages = ["."] + pruneopts = "UT" revision = "c2353362d570a7bfa228149c62842019201cfb71" version = "v1.8.0" [[projects]] + digest = "1:d4d17353dbd05cb52a2a52b7fe1771883b682806f68db442b436294926bbfafb" name = "github.com/mattn/go-isatty" packages = ["."] + pruneopts = "UT" revision = "0360b2af4f38e8d38c7fce2a9f4e702702d73a39" version = "v0.0.3" [[projects]] + digest = "1:ff5ebae34cfbf047d505ee150de27e60570e8c394b3b8fdbb720ff6ac71985fc" name = "github.com/matttproud/golang_protobuf_extensions" packages = ["pbutil"] + pruneopts = "UT" revision = "c12348ce28de40eed0136aa2b644d0ee0650e56c" version = "v1.0.1" [[projects]] branch = "master" + digest = "1:e730597b38a4d56e2361e0b6236cb800e52c73cace2ff91396f4ff35792ddfa7" name = "github.com/mitchellh/mapstructure" packages = ["."] + pruneopts = "UT" revision = "bb74f1db0675b241733089d5a1faa5dd8b0ef57b" [[projects]] + digest = "1:95741de3af260a92cc5c7f3f3061e85273f5a81b5db20d4bd68da74bd521675e" name = "github.com/pelletier/go-toml" packages = ["."] + pruneopts = "UT" revision = "c01d1270ff3e442a8a57cddc1c92dc1138598194" version = "v1.2.0" [[projects]] + digest = "1:40e195917a951a8bf867cd05de2a46aaf1806c50cf92eebf4c16f78cd196f747" name = "github.com/pkg/errors" packages = ["."] + pruneopts = "UT" revision = "645ef00459ed84a119197bfb8d8205042c6df63d" version = "v0.8.0" [[projects]] + digest = "1:0028cb19b2e4c3112225cd871870f2d9cf49b9b4276531f03438a88e94be86fe" name = "github.com/pmezard/go-difflib" packages = ["difflib"] + pruneopts = "UT" revision = "792786c7400a136282c1664665ae0a8db921c6c2" version = "v1.0.0" [[projects]] branch = "master" + digest = "1:98225904b7abff96c052b669b25788f18225a36673fba022fb93514bb9a2a64e" name = "github.com/prometheus/client_golang" packages = [ "prometheus", - "prometheus/promhttp" + "prometheus/promhttp", ] + pruneopts = "UT" revision = "ae27198cdd90bf12cd134ad79d1366a6cf49f632" [[projects]] branch = "master" + digest = "1:53a76eb11bdc815fcf0c757a9648fda0ab6887da13f07587181ff2223b67956c" name = "github.com/prometheus/client_model" packages = ["go"] + pruneopts = "UT" revision = "99fa1f4be8e564e8a6b613da7fa6f46c9edafc6c" [[projects]] branch = "master" + digest = "1:4d291d51042ed9de40eef61a3c1b56e969d6e0f8aa5fd3da5e958ec66bee68e4" name = "github.com/prometheus/common" packages = [ "expfmt", "internal/bitbucket.org/ww/goautoneg", - "model" + "model", ] + pruneopts = "UT" revision = "7600349dcfe1abd18d72d3a1770870d9800a7801" [[projects]] branch = "master" + digest = "1:55d7449d6987dabf272b4e81b2f9c449f05b17415c939b68d1e82f57e3374b7f" name = "github.com/prometheus/procfs" packages = [ ".", "internal/util", "nfs", - "xfs" + "xfs", ] + pruneopts = "UT" revision = "ae68e2d4c00fed4943b5f6698d504a5fe083da8a" [[projects]] branch = "master" + digest = "1:c4556a44e350b50a490544d9b06e9fba9c286c21d6c0e47f54f3a9214597298c" name = "github.com/rcrowley/go-metrics" packages = ["."] + pruneopts = "UT" revision = "e2704e165165ec55d062f5919b4b29494e9fa790" [[projects]] + digest = "1:37ace7f35375adec11634126944bdc45a673415e2fcc07382d03b75ec76ea94c" name = "github.com/spf13/afero" packages = [ ".", - "mem" + "mem", ] + pruneopts = "UT" revision = "787d034dfe70e44075ccc060d346146ef53270ad" version = "v1.1.1" [[projects]] + digest = "1:516e71bed754268937f57d4ecb190e01958452336fa73dbac880894164e91c1f" name = "github.com/spf13/cast" packages = ["."] + pruneopts = "UT" revision = "8965335b8c7107321228e3e3702cab9832751bac" version = "v1.2.0" [[projects]] + digest = "1:627ab2f549a6a55c44f46fa24a4307f4d0da81bfc7934ed0473bf38b24051d26" name = "github.com/spf13/cobra" packages = ["."] + pruneopts = "UT" revision = "7b2c5ac9fc04fc5efafb60700713d4fa609b777b" version = "v0.0.1" [[projects]] branch = "master" + digest = "1:080e5f630945ad754f4b920e60b4d3095ba0237ebf88dc462eb28002932e3805" name = "github.com/spf13/jwalterweatherman" packages = ["."] + pruneopts = "UT" revision = "7c0cea34c8ece3fbeb2b27ab9b59511d360fb394" [[projects]] + digest = "1:9424f440bba8f7508b69414634aef3b2b3a877e522d8a4624692412805407bb7" name = "github.com/spf13/pflag" packages = ["."] + pruneopts = "UT" revision = "583c0c0531f06d5278b7d917446061adc344b5cd" version = "v1.0.1" [[projects]] + digest = "1:f8e1a678a2571e265f4bf91a3e5e32aa6b1474a55cb0ea849750cc177b664d96" name = "github.com/spf13/viper" packages = ["."] + pruneopts = "UT" revision = "25b30aa063fc18e48662b86996252eabdcf2f0c7" version = "v1.0.0" [[projects]] + digest = "1:73697231b93fb74a73ebd8384b68b9a60c57ea6b13c56d2425414566a72c8e6d" name = "github.com/stretchr/testify" packages = [ "assert", - "require" + "require", ] + pruneopts = "UT" revision = "12b6f73e6084dad08a7c6e575284b177ecafbc71" version = "v1.2.1" [[projects]] branch = "master" + digest = "1:922191411ad8f61bcd8018ac127589bb489712c1d1a0ab2497aca4b16de417d2" name = "github.com/syndtr/goleveldb" packages = [ "leveldb", @@ -311,33 +394,41 @@ "leveldb/opt", "leveldb/storage", "leveldb/table", - "leveldb/util" + "leveldb/util", ] + pruneopts = "UT" revision = "c4c61651e9e37fa117f53c5a906d3b63090d8445" [[projects]] branch = "master" + digest = "1:203b409c21115233a576f99e8f13d8e07ad82b25500491f7e1cca12588fb3232" name = "github.com/tendermint/ed25519" packages = [ ".", "edwards25519", - "extra25519" + "extra25519", ] + pruneopts = "UT" revision = "d8387025d2b9d158cf4efb07e7ebf814bcce2057" [[projects]] + digest = "1:e9113641c839c21d8eaeb2c907c7276af1eddeed988df8322168c56b7e06e0e1" name = "github.com/tendermint/go-amino" packages = ["."] + pruneopts = "UT" revision = "2106ca61d91029c931fd54968c2bb02dc96b1412" version = "0.10.1" [[projects]] + digest = "1:d4a15d404afbf591e8be16fcda7f5ac87948d5c7531f9d909fd84cc730ab16e2" name = "github.com/tendermint/iavl" packages = ["."] + pruneopts = "UT" revision = "35f66e53d9b01e83b30de68b931f54b2477a94c9" version = "v0.9.2" [[projects]] + digest = "1:2511fa7bc2725251a1a48a923c8f01cd41de29b00a21224092d448a9e4627c21" name = "github.com/tendermint/tendermint" packages = [ "abci/client", @@ -392,18 +483,22 @@ "state/txindex/kv", "state/txindex/null", "types", - "version" + "version", ] + pruneopts = "UT" revision = "5ff65274b84ea905787a48512cc3124385bddf2f" version = "v0.22.2" [[projects]] + digest = "1:9d2f5bccd058537986ef2862b8c6daff855f293d924ae8ebc18974143ae9191e" name = "github.com/zondax/ledger-goclient" packages = ["."] + pruneopts = "UT" revision = "065cbf938a16f20335c40cfe180f9cd4955c6a5a" [[projects]] branch = "master" + digest = "1:e8206c1653e050116ec8c9a823a86413fc9f9ee3c2f3ae977c96d6a1747f7325" name = "golang.org/x/crypto" packages = [ "blowfish", @@ -416,12 +511,14 @@ "pbkdf2", "poly1305", "ripemd160", - "salsa20/salsa" + "salsa20/salsa", ] + pruneopts = "UT" revision = "a49355c7e3f8fe157a85be2f77e6e269a0f89602" [[projects]] branch = "master" + digest = "1:04dda8391c3e2397daf254ac68003f30141c069b228d06baec8324a5f81dc1e9" name = "golang.org/x/net" packages = [ "context", @@ -431,17 +528,21 @@ "idna", "internal/timeseries", "netutil", - "trace" + "trace", ] + pruneopts = "UT" revision = "292b43bbf7cb8d35ddf40f8d5100ef3837cced3f" [[projects]] branch = "master" + digest = "1:d773e525476aefa22ea944a5425a9bfb99819b2e67eeb9b1966454fd57522bbf" name = "golang.org/x/sys" packages = ["unix"] + pruneopts = "UT" revision = "1b2967e3c290b7c545b3db0deeda16e9be4f98a2" [[projects]] + digest = "1:7509ba4347d1f8de6ae9be8818b0cd1abc3deeffe28aeaf4be6d4b6b5178d9ca" name = "golang.org/x/text" packages = [ "collate", @@ -457,18 +558,22 @@ "unicode/bidi", "unicode/cldr", "unicode/norm", - "unicode/rangetable" + "unicode/rangetable", ] + pruneopts = "UT" revision = "f21a4dfb5e38f5895301dc265a8def02365cc3d0" version = "v0.3.0" [[projects]] branch = "master" + digest = "1:601e63e7d4577f907118bec825902505291918859d223bce015539e79f1160e3" name = "google.golang.org/genproto" packages = ["googleapis/rpc/status"] + pruneopts = "UT" revision = "e92b116572682a5b432ddd840aeaba2a559eeff1" [[projects]] + digest = "1:4d7b5d9746840266938cdb21a40f8eba7137d9153c4ed404d6bb2a450d06f690" name = "google.golang.org/grpc" packages = [ ".", @@ -493,20 +598,62 @@ "stats", "status", "tap", - "transport" + "transport", ] + pruneopts = "UT" revision = "d11072e7ca9811b1100b80ca0269ac831f06d024" version = "v1.11.3" [[projects]] + digest = "1:342378ac4dcb378a5448dd723f0784ae519383532f5e70ade24132c4c8693202" name = "gopkg.in/yaml.v2" packages = ["."] + pruneopts = "UT" revision = "5420a8b6744d3b0345ab293f6fcba19c978f1183" version = "v2.2.1" [solve-meta] analyzer-name = "dep" analyzer-version = 1 - inputs-digest = "37c54ed9bde68bad33be02f5e09b17a42397fb2fc9a10fa582e66b3852a99370" + input-imports = [ + "github.com/bartekn/go-bip39", + "github.com/bgentry/speakeasy", + "github.com/btcsuite/btcd/btcec", + "github.com/golang/protobuf/proto", + "github.com/gorilla/mux", + "github.com/mattn/go-isatty", + "github.com/pkg/errors", + "github.com/spf13/cobra", + "github.com/spf13/pflag", + "github.com/spf13/viper", + "github.com/stretchr/testify/assert", + "github.com/stretchr/testify/require", + "github.com/tendermint/go-amino", + "github.com/tendermint/iavl", + "github.com/tendermint/tendermint/abci/server", + "github.com/tendermint/tendermint/abci/types", + "github.com/tendermint/tendermint/cmd/tendermint/commands", + "github.com/tendermint/tendermint/config", + "github.com/tendermint/tendermint/crypto", + "github.com/tendermint/tendermint/crypto/merkle", + "github.com/tendermint/tendermint/libs/bech32", + "github.com/tendermint/tendermint/libs/cli", + "github.com/tendermint/tendermint/libs/cli/flags", + "github.com/tendermint/tendermint/libs/common", + "github.com/tendermint/tendermint/libs/db", + "github.com/tendermint/tendermint/libs/log", + "github.com/tendermint/tendermint/node", + "github.com/tendermint/tendermint/p2p", + "github.com/tendermint/tendermint/privval", + "github.com/tendermint/tendermint/proxy", + "github.com/tendermint/tendermint/rpc/client", + "github.com/tendermint/tendermint/rpc/core/types", + "github.com/tendermint/tendermint/rpc/lib/client", + "github.com/tendermint/tendermint/rpc/lib/server", + "github.com/tendermint/tendermint/types", + "github.com/zondax/ledger-goclient", + "golang.org/x/crypto/blowfish", + "golang.org/x/crypto/ripemd160", + ] solver-name = "gps-cdcl" solver-version = 1 diff --git a/Makefile b/Makefile index ce753afef..900219d37 100644 --- a/Makefile +++ b/Makefile @@ -4,7 +4,7 @@ PACKAGES_SIMTEST=$(shell go list ./... | grep -v '/vendor/' | grep '/simulation' COMMIT_HASH := $(shell git rev-parse --short HEAD) BUILD_FLAGS = -tags netgo -ldflags "-X github.com/cosmos/cosmos-sdk/version.GitCommit=${COMMIT_HASH}" -all: get_tools get_vendor_deps install install_examples test_lint test +all: get_tools get_vendor_deps install install_examples test_lint test test_sim ######################################## ### CI From bb217b91a428cd63853e43bd5372a39a10c28a1d Mon Sep 17 00:00:00 2001 From: Christopher Goes Date: Thu, 12 Jul 2018 22:01:43 +0200 Subject: [PATCH 13/39] Actual Gaia app --- cmd/gaia/simulation/sim_test.go | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/cmd/gaia/simulation/sim_test.go b/cmd/gaia/simulation/sim_test.go index 77940fba7..077ed9d67 100644 --- a/cmd/gaia/simulation/sim_test.go +++ b/cmd/gaia/simulation/sim_test.go @@ -4,8 +4,18 @@ import ( "testing" "github.com/stretchr/testify/require" + + dbm "github.com/tendermint/tendermint/libs/db" + "github.com/tendermint/tendermint/libs/log" + + gaia "github.com/cosmos/cosmos-sdk/cmd/gaia/app" + // stakesim "github.com/cosmos/cosmos-sdk/x/stake/simulation" ) func TestFullGaiaSimulation(t *testing.T) { - require.True(t, true, "should not happen") + // Setup Gaia application + logger := log.NewNopLogger() + db := dbm.NewMemDB() + app := gaia.NewGaiaApp(logger, db) + require.Equal(t, "GaiaApp", app.Name()) } From c272db06b82859f07efa963b723b90fa054865c5 Mon Sep 17 00:00:00 2001 From: Christopher Goes Date: Fri, 13 Jul 2018 01:54:07 +0200 Subject: [PATCH 14/39] Delegation bug fixed! --- x/stake/simulation/sim_test.go | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/x/stake/simulation/sim_test.go b/x/stake/simulation/sim_test.go index 621e2c5b2..5252158d8 100644 --- a/x/stake/simulation/sim_test.go +++ b/x/stake/simulation/sim_test.go @@ -356,8 +356,7 @@ func TestStakeWithRandomMessages(t *testing.T) { // XXX TODO // SimulateMsgBeginUnbonding(mapper, stakeKeeper), SimulateMsgCompleteUnbonding(stakeKeeper), - // XXX TODO Bug found! - // SimulateMsgBeginRedelegate(mapper, stakeKeeper), + SimulateMsgBeginRedelegate(mapper, stakeKeeper), SimulateMsgCompleteRedelegate(stakeKeeper), }, []mock.RandSetup{ SimulationSetup(mapp, stakeKeeper), From a4e7216b36eeb9fe5e79e582f4f27eed15085ac0 Mon Sep 17 00:00:00 2001 From: Christopher Goes Date: Tue, 17 Jul 2018 02:29:46 +0200 Subject: [PATCH 15/39] Fix gocyclo check --- tools/Makefile | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/tools/Makefile b/tools/Makefile index d58f52d1b..426600e0c 100644 --- a/tools/Makefile +++ b/tools/Makefile @@ -120,10 +120,10 @@ else @echo "Installing unparam" go get -v $(UNPARAM) endif -ifdef GOYCLO_CHECK - @echo "goyclo is already installed. Run 'make update_tools' to update." +ifdef GOCYCLO_CHECK + @echo "gocyclo is already installed. Run 'make update_tools' to update." else - @echo "Installing goyclo" + @echo "Installing gocyclo" go get -v $(GOCYCLO) endif From 9ad3d62e491869433e569802d78aad6586cec85f Mon Sep 17 00:00:00 2001 From: Christopher Goes Date: Tue, 17 Jul 2018 02:41:36 +0200 Subject: [PATCH 16/39] Updates from merge --- cmd/gaia/simulation/sim_test.go | 2 +- x/stake/simulation/sim_test.go | 16 +++------------- 2 files changed, 4 insertions(+), 14 deletions(-) diff --git a/cmd/gaia/simulation/sim_test.go b/cmd/gaia/simulation/sim_test.go index 077ed9d67..d00e56bab 100644 --- a/cmd/gaia/simulation/sim_test.go +++ b/cmd/gaia/simulation/sim_test.go @@ -16,6 +16,6 @@ func TestFullGaiaSimulation(t *testing.T) { // Setup Gaia application logger := log.NewNopLogger() db := dbm.NewMemDB() - app := gaia.NewGaiaApp(logger, db) + app := gaia.NewGaiaApp(logger, db, nil) require.Equal(t, "GaiaApp", app.Name()) } diff --git a/x/stake/simulation/sim_test.go b/x/stake/simulation/sim_test.go index 5252158d8..0280bab70 100644 --- a/x/stake/simulation/sim_test.go +++ b/x/stake/simulation/sim_test.go @@ -42,31 +42,21 @@ func SupplyInvariants(ck bank.Keeper, k stake.Keeper) mock.Invariant { loose = loose.Add(acc.GetCoins().AmountOf("steak")) return false }) - require.True(t, sdk.NewInt(pool.LooseTokens).Equal(loose), "expected loose tokens to equal total steak held by accounts - pool.LooseTokens: %v, sum of account tokens: %v\nlog: %s", + require.True(t, pool.LooseTokens.RoundInt64() == loose.Int64(), "expected loose tokens to equal total steak held by accounts - pool.LooseTokens: %v, sum of account tokens: %v\nlog: %s", pool.LooseTokens, loose, log) stats["stake/invariant/looseTokens"] += 1 // Bonded tokens should equal sum of tokens with bonded validators - // Unbonded tokens should equal sum of tokens with unbonded validators bonded := sdk.ZeroRat() - unbonded := sdk.ZeroRat() k.IterateValidators(ctx, func(_ int64, validator sdk.Validator) bool { switch validator.GetStatus() { case sdk.Bonded: bonded = bonded.Add(validator.GetPower()) - case sdk.Unbonding: - // TODO - case sdk.Unbonded: - unbonded = unbonded.Add(validator.GetPower()) } return false }) - require.True(t, sdk.NewRat(pool.BondedTokens).Equal(bonded), "expected bonded tokens to equal total steak held by bonded validators\nlog: %s", log) + require.True(t, pool.BondedTokens.Equal(bonded), "expected bonded tokens to equal total steak held by bonded validators\nlog: %s", log) stats["stake/invariant/bondedTokens"] += 1 - require.True(t, sdk.NewRat(pool.UnbondedTokens).Equal(unbonded), "expected unbonded tokens to equal total steak held by unbonded validators\n log: %s", log) - stats["stake/invariant/unbondedTokens"] += 1 - - // TODO Unbonding tokens // TODO Inflation check on total supply } @@ -321,7 +311,7 @@ func SimulationSetup(mapp *mock.App, k stake.Keeper) mock.RandSetup { return false }) pool := k.GetPool(ctx) - pool.LooseTokens += loose.Int64() + pool.LooseTokens = pool.LooseTokens.Add(sdk.NewRat(loose.Int64(), 1)) k.SetPool(ctx, pool) } } From a49f9d6314d103deb359abcdc36911e5392075a9 Mon Sep 17 00:00:00 2001 From: Christopher Goes Date: Tue, 17 Jul 2018 03:15:50 +0200 Subject: [PATCH 17/39] Restructure --- cmd/gaia/simulation/sim_test.go | 20 +++++- x/mock/random_simulate_blocks.go | 116 ++++--------------------------- x/mock/types.go | 16 ++--- x/mock/util.go | 60 ++++++++++++++++ 4 files changed, 95 insertions(+), 117 deletions(-) create mode 100644 x/mock/util.go diff --git a/cmd/gaia/simulation/sim_test.go b/cmd/gaia/simulation/sim_test.go index d00e56bab..3cbbd68c8 100644 --- a/cmd/gaia/simulation/sim_test.go +++ b/cmd/gaia/simulation/sim_test.go @@ -9,7 +9,13 @@ import ( "github.com/tendermint/tendermint/libs/log" gaia "github.com/cosmos/cosmos-sdk/cmd/gaia/app" - // stakesim "github.com/cosmos/cosmos-sdk/x/stake/simulation" + "github.com/cosmos/cosmos-sdk/x/mock" +) + +const ( + NumKeys = 10 + NumBlocks = 1000 + BlockSize = 1000 ) func TestFullGaiaSimulation(t *testing.T) { @@ -18,4 +24,16 @@ func TestFullGaiaSimulation(t *testing.T) { db := dbm.NewMemDB() app := gaia.NewGaiaApp(logger, db, nil) require.Equal(t, "GaiaApp", app.Name()) + + // Run randomized simulation + mock.RandomizedTesting( + t, app.BaseApp, + []mock.TestAndRunTx{}, + []mock.RandSetup{}, + []mock.Invariant{}, + NumKeys, + NumBlocks, + BlockSize, + ) + } diff --git a/x/mock/random_simulate_blocks.go b/x/mock/random_simulate_blocks.go index 452b8f6bf..5021d2785 100644 --- a/x/mock/random_simulate_blocks.go +++ b/x/mock/random_simulate_blocks.go @@ -2,36 +2,36 @@ package mock import ( "fmt" - "math/big" "math/rand" "testing" "time" - sdk "github.com/cosmos/cosmos-sdk/types" + "github.com/cosmos/cosmos-sdk/baseapp" "github.com/stretchr/testify/require" abci "github.com/tendermint/tendermint/abci/types" ) // RandomizedTesting tests application by sending random messages. -func (app *App) RandomizedTesting( - t *testing.T, ops []TestAndRunTx, setups []RandSetup, +func RandomizedTesting( + t *testing.T, app *baseapp.BaseApp, ops []TestAndRunTx, setups []RandSetup, invariants []Invariant, numKeys int, numBlocks int, blockSize int, ) { time := time.Now().UnixNano() - app.RandomizedTestingFromSeed(t, time, ops, setups, invariants, numKeys, numBlocks, blockSize) + RandomizedTestingFromSeed(t, app, time, ops, setups, invariants, numKeys, numBlocks, blockSize) } // RandomizedTestingFromSeed tests an application by running the provided // operations, testing the provided invariants, but using the provided seed. -func (app *App) RandomizedTestingFromSeed( - t *testing.T, seed int64, ops []TestAndRunTx, setups []RandSetup, +func RandomizedTestingFromSeed( + t *testing.T, app *baseapp.BaseApp, seed int64, ops []TestAndRunTx, setups []RandSetup, invariants []Invariant, numKeys int, numBlocks int, blockSize int, ) { log := fmt.Sprintf("Starting SingleModuleTest with randomness created with seed %d", int(seed)) - keys, addrs := GeneratePrivKeyAddressPairs(numKeys) + keys, _ := GeneratePrivKeyAddressPairs(numKeys) r := rand.New(rand.NewSource(seed)) - RandomSetGenesis(r, app, addrs, []string{"foocoin"}) + // XXX TODO + // RandomSetGenesis(r, app, addrs, []string{"foocoin"}) app.InitChain(abci.RequestInitChain{}) for i := 0; i < len(setups); i++ { setups[i](r, keys) @@ -45,7 +45,7 @@ func (app *App) RandomizedTestingFromSeed( // Make sure invariants hold at beginning of block and when nothing was // done. - app.assertAllInvariants(t, invariants, log) + AssertAllInvariants(t, app, invariants, log) ctx := app.NewContext(false, header) @@ -56,7 +56,7 @@ func (app *App) RandomizedTestingFromSeed( log += "\n" + logUpdate require.Nil(t, err, log) - app.assertAllInvariants(t, invariants, log) + AssertAllInvariants(t, app, invariants, log) } app.EndBlock(abci.RequestEndBlock{}) @@ -64,100 +64,8 @@ func (app *App) RandomizedTestingFromSeed( } } -// SimpleRandomizedTestingFromSeed -func (app *App) SimpleRandomizedTestingFromSeed( - t *testing.T, seed int64, ops []TestAndRunMsg, setups []RandSetup, - invariants []Invariant, numKeys int, numBlocks int, blockSize int, -) { - log := fmt.Sprintf("Starting SimpleSingleModuleTest with randomness created with seed %d", int(seed)) - keys, addrs := GeneratePrivKeyAddressPairs(numKeys) - r := rand.New(rand.NewSource(seed)) - - RandomSetGenesis(r, app, addrs, []string{"foocoin"}) - app.InitChain(abci.RequestInitChain{}) - for i := 0; i < len(setups); i++ { - setups[i](r, keys) - } - app.Commit() - - header := abci.Header{Height: 0} - - for i := 0; i < numBlocks; i++ { - app.BeginBlock(abci.RequestBeginBlock{}) - - app.assertAllInvariants(t, invariants, log) - - ctx := app.NewContext(false, header) - - // TODO: Add modes to simulate "no load", "medium load", and - // "high load" blocks. - for j := 0; j < blockSize; j++ { - logUpdate, err := ops[r.Intn(len(ops))](t, r, ctx, keys, log) - log += "\n" + logUpdate - - require.Nil(t, err, log) - app.assertAllInvariants(t, invariants, log) - } - - app.EndBlock(abci.RequestEndBlock{}) - header.Height++ - } -} - -func (app *App) assertAllInvariants(t *testing.T, tests []Invariant, log string) { +func AssertAllInvariants(t *testing.T, app *baseapp.BaseApp, tests []Invariant, log string) { for i := 0; i < len(tests); i++ { tests[i](t, app, log) } } - -// BigInterval is a representation of the interval [lo, hi), where -// lo and hi are both of type sdk.Int -type BigInterval struct { - lo sdk.Int - hi sdk.Int -} - -// RandFromBigInterval chooses an interval uniformly from the provided list of -// BigIntervals, and then chooses an element from an interval uniformly at random. -func RandFromBigInterval(r *rand.Rand, intervals []BigInterval) sdk.Int { - if len(intervals) == 0 { - return sdk.ZeroInt() - } - - interval := intervals[r.Intn(len(intervals))] - - lo := interval.lo - hi := interval.hi - - diff := hi.Sub(lo) - result := sdk.NewIntFromBigInt(new(big.Int).Rand(r, diff.BigInt())) - result = result.Add(lo) - - return result -} - -// shamelessly copied from https://stackoverflow.com/questions/22892120/how-to-generate-a-random-string-of-a-fixed-length-in-golang#31832326 - -const letterBytes = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ" -const ( - letterIdxBits = 6 // 6 bits to represent a letter index - letterIdxMask = 1<= 0; { - if remain == 0 { - cache, remain = r.Int63(), letterIdxMax - } - if idx := int(cache & letterIdxMask); idx < len(letterBytes) { - b[i] = letterBytes[idx] - i-- - } - cache >>= letterIdxBits - remain-- - } - return string(b) -} diff --git a/x/mock/types.go b/x/mock/types.go index 8a1c3d3e8..3a68e2422 100644 --- a/x/mock/types.go +++ b/x/mock/types.go @@ -4,6 +4,7 @@ import ( "math/rand" "testing" + "github.com/cosmos/cosmos-sdk/baseapp" sdk "github.com/cosmos/cosmos-sdk/types" "github.com/tendermint/tendermint/crypto" ) @@ -13,33 +14,24 @@ type ( // transition was as expected. It returns a descriptive message "action" // about what this fuzzed tx actually did, for ease of debugging. TestAndRunTx func( - t *testing.T, r *rand.Rand, app *App, ctx sdk.Context, + t *testing.T, r *rand.Rand, app *baseapp.BaseApp, ctx sdk.Context, privKeys []crypto.PrivKey, log string, ) (action string, err sdk.Error) - // TestAndRunMsg produces a fuzzed message, calls the appropriate handler - // (bypassing all ante handler checks), and ensures that the state - // transition was as expected. It returns a descriptive message "action" - // about what this fuzzed msg actually did for ease of debugging. - TestAndRunMsg func( - t *testing.T, r *rand.Rand, ctx sdk.Context, - privKey []crypto.PrivKey, log string, - ) (action string, err sdk.Error) - // RandSetup performs the random setup the mock module needs. RandSetup func(r *rand.Rand, privKeys []crypto.PrivKey) // An Invariant is a function which tests a particular invariant. // If the invariant has been broken, the function should halt the // test and output the log. - Invariant func(t *testing.T, app *App, log string) + Invariant func(t *testing.T, app *baseapp.BaseApp, log string) ) // PeriodicInvariant returns an Invariant function closure that asserts // a given invariant if the mock application's last block modulo the given // period is congruent to the given offset. func PeriodicInvariant(invariant Invariant, period int, offset int) Invariant { - return func(t *testing.T, app *App, log string) { + return func(t *testing.T, app *baseapp.BaseApp, log string) { if int(app.LastBlockHeight())%period == offset { invariant(t, app, log) } diff --git a/x/mock/util.go b/x/mock/util.go new file mode 100644 index 000000000..7b86cc69e --- /dev/null +++ b/x/mock/util.go @@ -0,0 +1,60 @@ +package mock + +import ( + "math/big" + "math/rand" + + sdk "github.com/cosmos/cosmos-sdk/types" +) + +// BigInterval is a representation of the interval [lo, hi), where +// lo and hi are both of type sdk.Int +type BigInterval struct { + lo sdk.Int + hi sdk.Int +} + +// RandFromBigInterval chooses an interval uniformly from the provided list of +// BigIntervals, and then chooses an element from an interval uniformly at random. +func RandFromBigInterval(r *rand.Rand, intervals []BigInterval) sdk.Int { + if len(intervals) == 0 { + return sdk.ZeroInt() + } + + interval := intervals[r.Intn(len(intervals))] + + lo := interval.lo + hi := interval.hi + + diff := hi.Sub(lo) + result := sdk.NewIntFromBigInt(new(big.Int).Rand(r, diff.BigInt())) + result = result.Add(lo) + + return result +} + +// shamelessly copied from https://stackoverflow.com/questions/22892120/how-to-generate-a-random-string-of-a-fixed-length-in-golang#31832326 + +const letterBytes = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ" +const ( + letterIdxBits = 6 // 6 bits to represent a letter index + letterIdxMask = 1<= 0; { + if remain == 0 { + cache, remain = r.Int63(), letterIdxMax + } + if idx := int(cache & letterIdxMask); idx < len(letterBytes) { + b[i] = letterBytes[idx] + i-- + } + cache >>= letterIdxBits + remain-- + } + return string(b) +} From cbcd0f08284a709e5298df3333437fb47b3d1a2e Mon Sep 17 00:00:00 2001 From: Christopher Goes Date: Tue, 17 Jul 2018 03:25:15 +0200 Subject: [PATCH 18/39] Restructure contd. --- cmd/gaia/simulation/sim_test.go | 10 +++--- .../random_simulate_blocks.go | 5 +-- x/mock/{ => simulation}/types.go | 2 +- x/mock/{ => simulation}/util.go | 31 +------------------ x/mock/test_utils.go | 28 +++++++++++++++++ 5 files changed, 38 insertions(+), 38 deletions(-) rename x/mock/{ => simulation}/random_simulate_blocks.go (94%) rename x/mock/{ => simulation}/types.go (98%) rename x/mock/{ => simulation}/util.go (56%) diff --git a/cmd/gaia/simulation/sim_test.go b/cmd/gaia/simulation/sim_test.go index 3cbbd68c8..b1382deb0 100644 --- a/cmd/gaia/simulation/sim_test.go +++ b/cmd/gaia/simulation/sim_test.go @@ -9,7 +9,7 @@ import ( "github.com/tendermint/tendermint/libs/log" gaia "github.com/cosmos/cosmos-sdk/cmd/gaia/app" - "github.com/cosmos/cosmos-sdk/x/mock" + "github.com/cosmos/cosmos-sdk/x/mock/simulation" ) const ( @@ -26,11 +26,11 @@ func TestFullGaiaSimulation(t *testing.T) { require.Equal(t, "GaiaApp", app.Name()) // Run randomized simulation - mock.RandomizedTesting( + simulation.RandomizedTesting( t, app.BaseApp, - []mock.TestAndRunTx{}, - []mock.RandSetup{}, - []mock.Invariant{}, + []simulation.TestAndRunTx{}, + []simulation.RandSetup{}, + []simulation.Invariant{}, NumKeys, NumBlocks, BlockSize, diff --git a/x/mock/random_simulate_blocks.go b/x/mock/simulation/random_simulate_blocks.go similarity index 94% rename from x/mock/random_simulate_blocks.go rename to x/mock/simulation/random_simulate_blocks.go index 5021d2785..d66373258 100644 --- a/x/mock/random_simulate_blocks.go +++ b/x/mock/simulation/random_simulate_blocks.go @@ -1,4 +1,4 @@ -package mock +package simulation import ( "fmt" @@ -7,6 +7,7 @@ import ( "time" "github.com/cosmos/cosmos-sdk/baseapp" + "github.com/cosmos/cosmos-sdk/x/mock" "github.com/stretchr/testify/require" abci "github.com/tendermint/tendermint/abci/types" ) @@ -27,7 +28,7 @@ func RandomizedTestingFromSeed( invariants []Invariant, numKeys int, numBlocks int, blockSize int, ) { log := fmt.Sprintf("Starting SingleModuleTest with randomness created with seed %d", int(seed)) - keys, _ := GeneratePrivKeyAddressPairs(numKeys) + keys, _ := mock.GeneratePrivKeyAddressPairs(numKeys) r := rand.New(rand.NewSource(seed)) // XXX TODO diff --git a/x/mock/types.go b/x/mock/simulation/types.go similarity index 98% rename from x/mock/types.go rename to x/mock/simulation/types.go index 3a68e2422..41736ce2c 100644 --- a/x/mock/types.go +++ b/x/mock/simulation/types.go @@ -1,4 +1,4 @@ -package mock +package simulation import ( "math/rand" diff --git a/x/mock/util.go b/x/mock/simulation/util.go similarity index 56% rename from x/mock/util.go rename to x/mock/simulation/util.go index 7b86cc69e..97307dc3e 100644 --- a/x/mock/util.go +++ b/x/mock/simulation/util.go @@ -1,38 +1,9 @@ -package mock +package simulation import ( - "math/big" "math/rand" - - sdk "github.com/cosmos/cosmos-sdk/types" ) -// BigInterval is a representation of the interval [lo, hi), where -// lo and hi are both of type sdk.Int -type BigInterval struct { - lo sdk.Int - hi sdk.Int -} - -// RandFromBigInterval chooses an interval uniformly from the provided list of -// BigIntervals, and then chooses an element from an interval uniformly at random. -func RandFromBigInterval(r *rand.Rand, intervals []BigInterval) sdk.Int { - if len(intervals) == 0 { - return sdk.ZeroInt() - } - - interval := intervals[r.Intn(len(intervals))] - - lo := interval.lo - hi := interval.hi - - diff := hi.Sub(lo) - result := sdk.NewIntFromBigInt(new(big.Int).Rand(r, diff.BigInt())) - result = result.Add(lo) - - return result -} - // shamelessly copied from https://stackoverflow.com/questions/22892120/how-to-generate-a-random-string-of-a-fixed-length-in-golang#31832326 const letterBytes = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ" diff --git a/x/mock/test_utils.go b/x/mock/test_utils.go index f9e1e8f5e..fa7d9875f 100644 --- a/x/mock/test_utils.go +++ b/x/mock/test_utils.go @@ -1,6 +1,8 @@ package mock import ( + "math/big" + "math/rand" "testing" "github.com/cosmos/cosmos-sdk/baseapp" @@ -10,6 +12,32 @@ import ( "github.com/tendermint/tendermint/crypto" ) +// BigInterval is a representation of the interval [lo, hi), where +// lo and hi are both of type sdk.Int +type BigInterval struct { + lo sdk.Int + hi sdk.Int +} + +// RandFromBigInterval chooses an interval uniformly from the provided list of +// BigIntervals, and then chooses an element from an interval uniformly at random. +func RandFromBigInterval(r *rand.Rand, intervals []BigInterval) sdk.Int { + if len(intervals) == 0 { + return sdk.ZeroInt() + } + + interval := intervals[r.Intn(len(intervals))] + + lo := interval.lo + hi := interval.hi + + diff := hi.Sub(lo) + result := sdk.NewIntFromBigInt(new(big.Int).Rand(r, diff.BigInt())) + result = result.Add(lo) + + return result +} + // CheckBalance checks the balance of an account. func CheckBalance(t *testing.T, app *App, addr sdk.AccAddress, exp sdk.Coins) { ctxCheck := app.BaseApp.NewContext(true, abci.Header{}) From cbc9d7d1da92ff671fdddd54ba8361ee91871e67 Mon Sep 17 00:00:00 2001 From: Christopher Goes Date: Tue, 17 Jul 2018 20:33:53 +0200 Subject: [PATCH 19/39] Genesis state --- cmd/gaia/simulation/sim_test.go | 18 ++++++++++++++++-- x/mock/simulation/random_simulate_blocks.go | 17 +++++++++-------- 2 files changed, 25 insertions(+), 10 deletions(-) diff --git a/cmd/gaia/simulation/sim_test.go b/cmd/gaia/simulation/sim_test.go index b1382deb0..2d36e0fa2 100644 --- a/cmd/gaia/simulation/sim_test.go +++ b/cmd/gaia/simulation/sim_test.go @@ -10,6 +10,7 @@ import ( gaia "github.com/cosmos/cosmos-sdk/cmd/gaia/app" "github.com/cosmos/cosmos-sdk/x/mock/simulation" + stake "github.com/cosmos/cosmos-sdk/x/stake" ) const ( @@ -19,15 +20,28 @@ const ( ) func TestFullGaiaSimulation(t *testing.T) { + // Setup Gaia application logger := log.NewNopLogger() db := dbm.NewMemDB() app := gaia.NewGaiaApp(logger, db, nil) require.Equal(t, "GaiaApp", app.Name()) + // Default genesis state + genesis := gaia.GenesisState{ + Accounts: []gaia.GenesisAccount{}, + StakeData: stake.DefaultGenesisState(), + } + + // Marshal genesis + appState, err := gaia.MakeCodec().MarshalJSON(genesis) + if err != nil { + panic(err) + } + // Run randomized simulation - simulation.RandomizedTesting( - t, app.BaseApp, + simulation.Simulate( + t, app.BaseApp, appState, []simulation.TestAndRunTx{}, []simulation.RandSetup{}, []simulation.Invariant{}, diff --git a/x/mock/simulation/random_simulate_blocks.go b/x/mock/simulation/random_simulate_blocks.go index d66373258..fdb1c9d42 100644 --- a/x/mock/simulation/random_simulate_blocks.go +++ b/x/mock/simulation/random_simulate_blocks.go @@ -1,6 +1,7 @@ package simulation import ( + "encoding/json" "fmt" "math/rand" "testing" @@ -12,19 +13,19 @@ import ( abci "github.com/tendermint/tendermint/abci/types" ) -// RandomizedTesting tests application by sending random messages. -func RandomizedTesting( - t *testing.T, app *baseapp.BaseApp, ops []TestAndRunTx, setups []RandSetup, +// Simulate tests application by sending random messages. +func Simulate( + t *testing.T, app *baseapp.BaseApp, appState json.RawMessage, ops []TestAndRunTx, setups []RandSetup, invariants []Invariant, numKeys int, numBlocks int, blockSize int, ) { time := time.Now().UnixNano() - RandomizedTestingFromSeed(t, app, time, ops, setups, invariants, numKeys, numBlocks, blockSize) + SimulateFromSeed(t, app, appState, time, ops, setups, invariants, numKeys, numBlocks, blockSize) } -// RandomizedTestingFromSeed tests an application by running the provided +// SimulateFromSeed tests an application by running the provided // operations, testing the provided invariants, but using the provided seed. -func RandomizedTestingFromSeed( - t *testing.T, app *baseapp.BaseApp, seed int64, ops []TestAndRunTx, setups []RandSetup, +func SimulateFromSeed( + t *testing.T, app *baseapp.BaseApp, appState json.RawMessage, seed int64, ops []TestAndRunTx, setups []RandSetup, invariants []Invariant, numKeys int, numBlocks int, blockSize int, ) { log := fmt.Sprintf("Starting SingleModuleTest with randomness created with seed %d", int(seed)) @@ -33,7 +34,7 @@ func RandomizedTestingFromSeed( // XXX TODO // RandomSetGenesis(r, app, addrs, []string{"foocoin"}) - app.InitChain(abci.RequestInitChain{}) + app.InitChain(abci.RequestInitChain{AppStateBytes: appState}) for i := 0; i < len(setups); i++ { setups[i](r, keys) } From af206bd0ed9450675a50fd0a21dc5fa0d697f638 Mon Sep 17 00:00:00 2001 From: Christopher Goes Date: Tue, 17 Jul 2018 20:50:30 +0200 Subject: [PATCH 20/39] Update stake simulation --- x/stake/simulation/invariants.go | 76 ++++++++++++++++++++ x/stake/simulation/sim_test.go | 115 ++++++++----------------------- 2 files changed, 105 insertions(+), 86 deletions(-) create mode 100644 x/stake/simulation/invariants.go diff --git a/x/stake/simulation/invariants.go b/x/stake/simulation/invariants.go new file mode 100644 index 000000000..08567bb4e --- /dev/null +++ b/x/stake/simulation/invariants.go @@ -0,0 +1,76 @@ +package simulation + +import ( + "testing" + + "github.com/stretchr/testify/require" + + "github.com/cosmos/cosmos-sdk/baseapp" + sdk "github.com/cosmos/cosmos-sdk/types" + "github.com/cosmos/cosmos-sdk/x/auth" + "github.com/cosmos/cosmos-sdk/x/bank" + "github.com/cosmos/cosmos-sdk/x/mock/simulation" + "github.com/cosmos/cosmos-sdk/x/stake" + abci "github.com/tendermint/tendermint/abci/types" +) + +// AllInvariants runs all invariants of the stake module. +// Currently: total supply, positive power +func AllInvariants(ck bank.Keeper, k stake.Keeper, am auth.AccountMapper) simulation.Invariant { + return func(t *testing.T, app *baseapp.BaseApp, log string) { + SupplyInvariants(ck, k, am)(t, app, log) + PositivePowerInvariant(k)(t, app, log) + ValidatorSetInvariant(k)(t, app, log) + } +} + +// SupplyInvariants checks that the total supply reflects all held loose tokens, bonded tokens, and unbonding delegations +func SupplyInvariants(ck bank.Keeper, k stake.Keeper, am auth.AccountMapper) simulation.Invariant { + return func(t *testing.T, app *baseapp.BaseApp, log string) { + ctx := app.NewContext(false, abci.Header{}) + pool := k.GetPool(ctx) + + // Loose tokens should equal coin supply + loose := sdk.ZeroInt() + am.IterateAccounts(ctx, func(acc auth.Account) bool { + loose = loose.Add(acc.GetCoins().AmountOf("steak")) + return false + }) + require.True(t, pool.LooseTokens.RoundInt64() == loose.Int64(), "expected loose tokens to equal total steak held by accounts - pool.LooseTokens: %v, sum of account tokens: %v\nlog: %s", + pool.LooseTokens, loose, log) + // stats["stake/invariant/looseTokens"] += 1 + + // Bonded tokens should equal sum of tokens with bonded validators + bonded := sdk.ZeroRat() + k.IterateValidators(ctx, func(_ int64, validator sdk.Validator) bool { + switch validator.GetStatus() { + case sdk.Bonded: + bonded = bonded.Add(validator.GetPower()) + } + return false + }) + require.True(t, pool.BondedTokens.Equal(bonded), "expected bonded tokens to equal total steak held by bonded validators\nlog: %s", log) + // stats["stake/invariant/bondedTokens"] += 1 + + // TODO Inflation check on total supply + } +} + +// PositivePowerInvariant checks that all stored validators have > 0 power +func PositivePowerInvariant(k stake.Keeper) simulation.Invariant { + return func(t *testing.T, app *baseapp.BaseApp, log string) { + ctx := app.NewContext(false, abci.Header{}) + k.IterateValidatorsBonded(ctx, func(_ int64, validator sdk.Validator) bool { + require.True(t, validator.GetPower().GT(sdk.ZeroRat()), "validator with non-positive power stored") + return false + }) + // stats["stake/invariant/positivePower"] += 1 + } +} + +// ValidatorSetInvariant checks equivalence of Tendermint validator set and SDK validator set +func ValidatorSetInvariant(k stake.Keeper) simulation.Invariant { + return func(t *testing.T, app *baseapp.BaseApp, log string) { + // TODO + } +} diff --git a/x/stake/simulation/sim_test.go b/x/stake/simulation/sim_test.go index 0280bab70..8e5a48a21 100644 --- a/x/stake/simulation/sim_test.go +++ b/x/stake/simulation/sim_test.go @@ -1,16 +1,19 @@ package simulation import ( + "encoding/json" "fmt" "math/rand" "testing" "github.com/stretchr/testify/require" + "github.com/cosmos/cosmos-sdk/baseapp" sdk "github.com/cosmos/cosmos-sdk/types" "github.com/cosmos/cosmos-sdk/x/auth" "github.com/cosmos/cosmos-sdk/x/bank" "github.com/cosmos/cosmos-sdk/x/mock" + "github.com/cosmos/cosmos-sdk/x/mock/simulation" "github.com/cosmos/cosmos-sdk/x/stake" abci "github.com/tendermint/tendermint/abci/types" "github.com/tendermint/tendermint/crypto" @@ -20,73 +23,12 @@ var ( stats = make(map[string]int) ) -// ModuleInvariants runs all invariants of the stake module. -// Currently: total supply, positive power -func ModuleInvariants(ck bank.Keeper, k stake.Keeper) mock.Invariant { - return func(t *testing.T, app *mock.App, log string) { - SupplyInvariants(ck, k)(t, app, log) - PositivePowerInvariant(k)(t, app, log) - ValidatorSetInvariant(k)(t, app, log) - } -} - -// SupplyInvariants checks that the total supply reflects all held loose tokens, bonded tokens, and unbonding delegations -func SupplyInvariants(ck bank.Keeper, k stake.Keeper) mock.Invariant { - return func(t *testing.T, app *mock.App, log string) { - ctx := app.NewContext(false, abci.Header{}) - pool := k.GetPool(ctx) - - // Loose tokens should equal coin supply - loose := sdk.ZeroInt() - app.AccountMapper.IterateAccounts(ctx, func(acc auth.Account) bool { - loose = loose.Add(acc.GetCoins().AmountOf("steak")) - return false - }) - require.True(t, pool.LooseTokens.RoundInt64() == loose.Int64(), "expected loose tokens to equal total steak held by accounts - pool.LooseTokens: %v, sum of account tokens: %v\nlog: %s", - pool.LooseTokens, loose, log) - stats["stake/invariant/looseTokens"] += 1 - - // Bonded tokens should equal sum of tokens with bonded validators - bonded := sdk.ZeroRat() - k.IterateValidators(ctx, func(_ int64, validator sdk.Validator) bool { - switch validator.GetStatus() { - case sdk.Bonded: - bonded = bonded.Add(validator.GetPower()) - } - return false - }) - require.True(t, pool.BondedTokens.Equal(bonded), "expected bonded tokens to equal total steak held by bonded validators\nlog: %s", log) - stats["stake/invariant/bondedTokens"] += 1 - - // TODO Inflation check on total supply - } -} - -// PositivePowerInvariant checks that all stored validators have > 0 power -func PositivePowerInvariant(k stake.Keeper) mock.Invariant { - return func(t *testing.T, app *mock.App, log string) { - ctx := app.NewContext(false, abci.Header{}) - k.IterateValidatorsBonded(ctx, func(_ int64, validator sdk.Validator) bool { - require.True(t, validator.GetPower().GT(sdk.ZeroRat()), "validator with non-positive power stored") - return false - }) - stats["stake/invariant/positivePower"] += 1 - } -} - -// ValidatorSetInvariant checks equivalence of Tendermint validator set and SDK validator set -func ValidatorSetInvariant(k stake.Keeper) mock.Invariant { - return func(t *testing.T, app *mock.App, log string) { - // TODO - } -} - // SimulateMsgCreateValidator -func SimulateMsgCreateValidator(m auth.AccountMapper, k stake.Keeper) mock.TestAndRunMsg { - return func(t *testing.T, r *rand.Rand, ctx sdk.Context, keys []crypto.PrivKey, log string) (action string, err sdk.Error) { +func SimulateMsgCreateValidator(m auth.AccountMapper, k stake.Keeper) simulation.TestAndRunTx { + return func(t *testing.T, r *rand.Rand, app *baseapp.BaseApp, ctx sdk.Context, keys []crypto.PrivKey, log string) (action string, err sdk.Error) { denom := k.GetParams(ctx).BondDenom description := stake.Description{ - Moniker: mock.RandStringOfLength(r, 10), + Moniker: simulation.RandStringOfLength(r, 10), } key := keys[r.Intn(len(keys))] pubkey := key.PubKey() @@ -119,13 +61,13 @@ func SimulateMsgCreateValidator(m auth.AccountMapper, k stake.Keeper) mock.TestA } // SimulateMsgEditValidator -func SimulateMsgEditValidator(k stake.Keeper) mock.TestAndRunMsg { - return func(t *testing.T, r *rand.Rand, ctx sdk.Context, keys []crypto.PrivKey, log string) (action string, err sdk.Error) { +func SimulateMsgEditValidator(k stake.Keeper) simulation.TestAndRunTx { + return func(t *testing.T, r *rand.Rand, app *baseapp.BaseApp, ctx sdk.Context, keys []crypto.PrivKey, log string) (action string, err sdk.Error) { description := stake.Description{ - Moniker: mock.RandStringOfLength(r, 10), - Identity: mock.RandStringOfLength(r, 10), - Website: mock.RandStringOfLength(r, 10), - Details: mock.RandStringOfLength(r, 10), + Moniker: simulation.RandStringOfLength(r, 10), + Identity: simulation.RandStringOfLength(r, 10), + Website: simulation.RandStringOfLength(r, 10), + Details: simulation.RandStringOfLength(r, 10), } key := keys[r.Intn(len(keys))] pubkey := key.PubKey() @@ -147,8 +89,8 @@ func SimulateMsgEditValidator(k stake.Keeper) mock.TestAndRunMsg { } // SimulateMsgDelegate -func SimulateMsgDelegate(m auth.AccountMapper, k stake.Keeper) mock.TestAndRunMsg { - return func(t *testing.T, r *rand.Rand, ctx sdk.Context, keys []crypto.PrivKey, log string) (action string, err sdk.Error) { +func SimulateMsgDelegate(m auth.AccountMapper, k stake.Keeper) simulation.TestAndRunTx { + return func(t *testing.T, r *rand.Rand, app *baseapp.BaseApp, ctx sdk.Context, keys []crypto.PrivKey, log string) (action string, err sdk.Error) { denom := k.GetParams(ctx).BondDenom validatorKey := keys[r.Intn(len(keys))] validatorAddress := sdk.AccAddress(validatorKey.PubKey().Address()) @@ -179,8 +121,8 @@ func SimulateMsgDelegate(m auth.AccountMapper, k stake.Keeper) mock.TestAndRunMs } // SimulateMsgBeginUnbonding -func SimulateMsgBeginUnbonding(m auth.AccountMapper, k stake.Keeper) mock.TestAndRunMsg { - return func(t *testing.T, r *rand.Rand, ctx sdk.Context, keys []crypto.PrivKey, log string) (action string, err sdk.Error) { +func SimulateMsgBeginUnbonding(m auth.AccountMapper, k stake.Keeper) simulation.TestAndRunTx { + return func(t *testing.T, r *rand.Rand, app *baseapp.BaseApp, ctx sdk.Context, keys []crypto.PrivKey, log string) (action string, err sdk.Error) { denom := k.GetParams(ctx).BondDenom validatorKey := keys[r.Intn(len(keys))] validatorAddress := sdk.AccAddress(validatorKey.PubKey().Address()) @@ -211,8 +153,8 @@ func SimulateMsgBeginUnbonding(m auth.AccountMapper, k stake.Keeper) mock.TestAn } // SimulateMsgCompleteUnbonding -func SimulateMsgCompleteUnbonding(k stake.Keeper) mock.TestAndRunMsg { - return func(t *testing.T, r *rand.Rand, ctx sdk.Context, keys []crypto.PrivKey, log string) (action string, err sdk.Error) { +func SimulateMsgCompleteUnbonding(k stake.Keeper) simulation.TestAndRunTx { + return func(t *testing.T, r *rand.Rand, app *baseapp.BaseApp, ctx sdk.Context, keys []crypto.PrivKey, log string) (action string, err sdk.Error) { validatorKey := keys[r.Intn(len(keys))] validatorAddress := sdk.AccAddress(validatorKey.PubKey().Address()) delegatorKey := keys[r.Intn(len(keys))] @@ -234,8 +176,8 @@ func SimulateMsgCompleteUnbonding(k stake.Keeper) mock.TestAndRunMsg { } // SimulateMsgBeginRedelegate -func SimulateMsgBeginRedelegate(m auth.AccountMapper, k stake.Keeper) mock.TestAndRunMsg { - return func(t *testing.T, r *rand.Rand, ctx sdk.Context, keys []crypto.PrivKey, log string) (action string, err sdk.Error) { +func SimulateMsgBeginRedelegate(m auth.AccountMapper, k stake.Keeper) simulation.TestAndRunTx { + return func(t *testing.T, r *rand.Rand, app *baseapp.BaseApp, ctx sdk.Context, keys []crypto.PrivKey, log string) (action string, err sdk.Error) { denom := k.GetParams(ctx).BondDenom sourceValidatorKey := keys[r.Intn(len(keys))] sourceValidatorAddress := sdk.AccAddress(sourceValidatorKey.PubKey().Address()) @@ -270,8 +212,8 @@ func SimulateMsgBeginRedelegate(m auth.AccountMapper, k stake.Keeper) mock.TestA } // SimulateMsgCompleteRedelegate -func SimulateMsgCompleteRedelegate(k stake.Keeper) mock.TestAndRunMsg { - return func(t *testing.T, r *rand.Rand, ctx sdk.Context, keys []crypto.PrivKey, log string) (action string, err sdk.Error) { +func SimulateMsgCompleteRedelegate(k stake.Keeper) simulation.TestAndRunTx { + return func(t *testing.T, r *rand.Rand, app *baseapp.BaseApp, ctx sdk.Context, keys []crypto.PrivKey, log string) (action string, err sdk.Error) { validatorSrcKey := keys[r.Intn(len(keys))] validatorSrcAddress := sdk.AccAddress(validatorSrcKey.PubKey().Address()) validatorDstKey := keys[r.Intn(len(keys))] @@ -296,7 +238,7 @@ func SimulateMsgCompleteRedelegate(k stake.Keeper) mock.TestAndRunMsg { } // SimulationSetup -func SimulationSetup(mapp *mock.App, k stake.Keeper) mock.RandSetup { +func SimulationSetup(mapp *mock.App, k stake.Keeper) simulation.RandSetup { return func(r *rand.Rand, privKeys []crypto.PrivKey) { ctx := mapp.NewContext(false, abci.Header{}) stake.InitGenesis(ctx, k, stake.DefaultGenesisState()) @@ -338,8 +280,9 @@ func TestStakeWithRandomMessages(t *testing.T) { panic(err) } - mapp.SimpleRandomizedTestingFromSeed( - t, 20, []mock.TestAndRunMsg{ + simulation.Simulate( + t, mapp.BaseApp, json.RawMessage("{}"), + []simulation.TestAndRunTx{ SimulateMsgCreateValidator(mapper, stakeKeeper), SimulateMsgEditValidator(stakeKeeper), SimulateMsgDelegate(mapper, stakeKeeper), @@ -348,10 +291,10 @@ func TestStakeWithRandomMessages(t *testing.T) { SimulateMsgCompleteUnbonding(stakeKeeper), SimulateMsgBeginRedelegate(mapper, stakeKeeper), SimulateMsgCompleteRedelegate(stakeKeeper), - }, []mock.RandSetup{ + }, []simulation.RandSetup{ SimulationSetup(mapp, stakeKeeper), - }, []mock.Invariant{ - ModuleInvariants(coinKeeper, stakeKeeper), + }, []simulation.Invariant{ + AllInvariants(coinKeeper, stakeKeeper, mapp.AccountMapper), }, 10, 100, 500, ) From eda7eb48cd0a68afa7adb605eec8d1ac23815be8 Mon Sep 17 00:00:00 2001 From: Christopher Goes Date: Tue, 17 Jul 2018 23:06:30 +0200 Subject: [PATCH 21/39] Gaia simulation needs internal field access --- Makefile | 6 +++--- cmd/gaia/{simulation => app}/sim_test.go | 17 +++++++++++------ 2 files changed, 14 insertions(+), 9 deletions(-) rename cmd/gaia/{simulation => app}/sim_test.go (74%) diff --git a/Makefile b/Makefile index 6f5b55e55..5d2cb8493 100644 --- a/Makefile +++ b/Makefile @@ -1,6 +1,6 @@ PACKAGES=$(shell go list ./... | grep -v '/vendor/') -PACKAGES_NOCLITEST=$(shell go list ./... | grep -v '/vendor/' | grep -v '/simulation' | grep -v github.com/cosmos/cosmos-sdk/cmd/gaia/cli_test) -PACKAGES_SIMTEST=$(shell go list ./... | grep -v '/vendor/' | grep '/simulation') +PACKAGES_NOCLITEST=$(shell go list ./... | grep -v '/vendor/' | grep -v github.com/cosmos/cosmos-sdk/cmd/gaia/cli_test) +PACKAGES_SIMTEST=$(shell go list ./... | grep -v '/vendor/') COMMIT_HASH := $(shell git rev-parse --short HEAD) BUILD_TAGS = netgo ledger BUILD_FLAGS = -tags "${BUILD_TAGS}" -ldflags "-X github.com/cosmos/cosmos-sdk/version.GitCommit=${COMMIT_HASH}" @@ -114,7 +114,7 @@ test_race: @go test -race $(PACKAGES_NOCLITEST) test_sim: - @go test $(PACKAGES_SIMTEST) -v + @ENABLE_GAIA_SIMULATION=1 go test ./cmd/gaia/app -run TestFullGaiaSimulation -v test_cover: @bash tests/test_cover.sh diff --git a/cmd/gaia/simulation/sim_test.go b/cmd/gaia/app/sim_test.go similarity index 74% rename from cmd/gaia/simulation/sim_test.go rename to cmd/gaia/app/sim_test.go index 2d36e0fa2..a42a34bc6 100644 --- a/cmd/gaia/simulation/sim_test.go +++ b/cmd/gaia/app/sim_test.go @@ -1,6 +1,7 @@ -package simulation +package app import ( + "os" "testing" "github.com/stretchr/testify/require" @@ -8,7 +9,6 @@ import ( dbm "github.com/tendermint/tendermint/libs/db" "github.com/tendermint/tendermint/libs/log" - gaia "github.com/cosmos/cosmos-sdk/cmd/gaia/app" "github.com/cosmos/cosmos-sdk/x/mock/simulation" stake "github.com/cosmos/cosmos-sdk/x/stake" ) @@ -17,24 +17,29 @@ const ( NumKeys = 10 NumBlocks = 1000 BlockSize = 1000 + + simulationEnv = "ENABLE_GAIA_SIMULATION" ) func TestFullGaiaSimulation(t *testing.T) { + if os.Getenv(simulationEnv) == "" { + t.Skip("Skipping Gaia simulation") + } // Setup Gaia application logger := log.NewNopLogger() db := dbm.NewMemDB() - app := gaia.NewGaiaApp(logger, db, nil) + app := NewGaiaApp(logger, db, nil) require.Equal(t, "GaiaApp", app.Name()) // Default genesis state - genesis := gaia.GenesisState{ - Accounts: []gaia.GenesisAccount{}, + genesis := GenesisState{ + Accounts: []GenesisAccount{}, StakeData: stake.DefaultGenesisState(), } // Marshal genesis - appState, err := gaia.MakeCodec().MarshalJSON(genesis) + appState, err := MakeCodec().MarshalJSON(genesis) if err != nil { panic(err) } From 253b82f92a0c4957ac08d63bb347eff5ae02826b Mon Sep 17 00:00:00 2001 From: Christopher Goes Date: Wed, 18 Jul 2018 00:04:10 +0200 Subject: [PATCH 22/39] Makefile changes --- Makefile | 5 +- cmd/gaia/app/sim_test.go | 53 +++-- x/mock/simulation/random_simulate_blocks.go | 16 +- x/stake/simulation/msgs.go | 246 +++++++++++++++++++ x/stake/simulation/sim_test.go | 248 -------------------- 5 files changed, 295 insertions(+), 273 deletions(-) create mode 100644 x/stake/simulation/msgs.go diff --git a/Makefile b/Makefile index 5d2cb8493..645973472 100644 --- a/Makefile +++ b/Makefile @@ -1,6 +1,6 @@ PACKAGES=$(shell go list ./... | grep -v '/vendor/') -PACKAGES_NOCLITEST=$(shell go list ./... | grep -v '/vendor/' | grep -v github.com/cosmos/cosmos-sdk/cmd/gaia/cli_test) -PACKAGES_SIMTEST=$(shell go list ./... | grep -v '/vendor/') +PACKAGES_NOCLITEST=$(shell go list ./... | grep -v '/vendor/' | grep -v '/simulation' | grep -v github.com/cosmos/cosmos-sdk/cmd/gaia/cli_test) +PACKAGES_SIMTEST=$(shell go list ./... | grep -v '/vendor/' | grep '/simulation') COMMIT_HASH := $(shell git rev-parse --short HEAD) BUILD_TAGS = netgo ledger BUILD_FLAGS = -tags "${BUILD_TAGS}" -ldflags "-X github.com/cosmos/cosmos-sdk/version.GitCommit=${COMMIT_HASH}" @@ -115,6 +115,7 @@ test_race: test_sim: @ENABLE_GAIA_SIMULATION=1 go test ./cmd/gaia/app -run TestFullGaiaSimulation -v + @go test $(PACKAGES_SIMTEST) test_cover: @bash tests/test_cover.sh diff --git a/cmd/gaia/app/sim_test.go b/cmd/gaia/app/sim_test.go index a42a34bc6..2fd2a55b6 100644 --- a/cmd/gaia/app/sim_test.go +++ b/cmd/gaia/app/sim_test.go @@ -1,6 +1,8 @@ package app import ( + "encoding/json" + "math/rand" "os" "testing" @@ -9,8 +11,10 @@ import ( dbm "github.com/tendermint/tendermint/libs/db" "github.com/tendermint/tendermint/libs/log" + sdk "github.com/cosmos/cosmos-sdk/types" "github.com/cosmos/cosmos-sdk/x/mock/simulation" stake "github.com/cosmos/cosmos-sdk/x/stake" + stakesim "github.com/cosmos/cosmos-sdk/x/stake/simulation" ) const ( @@ -21,6 +25,33 @@ const ( simulationEnv = "ENABLE_GAIA_SIMULATION" ) +func appStateFn(r *rand.Rand, accs []sdk.AccAddress) json.RawMessage { + var genesisAccounts []GenesisAccount + + // Randomly generate some genesis accounts + for _, addr := range accs { + coins := sdk.Coins{sdk.Coin{"steak", sdk.NewInt(100)}} + genesisAccounts = append(genesisAccounts, GenesisAccount{ + Address: addr, + Coins: coins, + }) + } + + // Default genesis state + genesis := GenesisState{ + Accounts: genesisAccounts, + StakeData: stake.DefaultGenesisState(), + } + + // Marshal genesis + appState, err := MakeCodec().MarshalJSON(genesis) + if err != nil { + panic(err) + } + + return appState +} + func TestFullGaiaSimulation(t *testing.T) { if os.Getenv(simulationEnv) == "" { t.Skip("Skipping Gaia simulation") @@ -32,24 +63,16 @@ func TestFullGaiaSimulation(t *testing.T) { app := NewGaiaApp(logger, db, nil) require.Equal(t, "GaiaApp", app.Name()) - // Default genesis state - genesis := GenesisState{ - Accounts: []GenesisAccount{}, - StakeData: stake.DefaultGenesisState(), - } - - // Marshal genesis - appState, err := MakeCodec().MarshalJSON(genesis) - if err != nil { - panic(err) - } - // Run randomized simulation simulation.Simulate( - t, app.BaseApp, appState, - []simulation.TestAndRunTx{}, + t, app.BaseApp, appStateFn, + []simulation.TestAndRunTx{ + stakesim.SimulateMsgCreateValidator(app.accountMapper, app.stakeKeeper), + }, []simulation.RandSetup{}, - []simulation.Invariant{}, + []simulation.Invariant{ + stakesim.AllInvariants(app.coinKeeper, app.stakeKeeper, app.accountMapper), + }, NumKeys, NumBlocks, BlockSize, diff --git a/x/mock/simulation/random_simulate_blocks.go b/x/mock/simulation/random_simulate_blocks.go index fdb1c9d42..eca9757c5 100644 --- a/x/mock/simulation/random_simulate_blocks.go +++ b/x/mock/simulation/random_simulate_blocks.go @@ -8,6 +8,7 @@ import ( "time" "github.com/cosmos/cosmos-sdk/baseapp" + sdk "github.com/cosmos/cosmos-sdk/types" "github.com/cosmos/cosmos-sdk/x/mock" "github.com/stretchr/testify/require" abci "github.com/tendermint/tendermint/abci/types" @@ -15,26 +16,24 @@ import ( // Simulate tests application by sending random messages. func Simulate( - t *testing.T, app *baseapp.BaseApp, appState json.RawMessage, ops []TestAndRunTx, setups []RandSetup, + t *testing.T, app *baseapp.BaseApp, appStateFn func(r *rand.Rand, accs []sdk.AccAddress) json.RawMessage, ops []TestAndRunTx, setups []RandSetup, invariants []Invariant, numKeys int, numBlocks int, blockSize int, ) { time := time.Now().UnixNano() - SimulateFromSeed(t, app, appState, time, ops, setups, invariants, numKeys, numBlocks, blockSize) + SimulateFromSeed(t, app, appStateFn, time, ops, setups, invariants, numKeys, numBlocks, blockSize) } // SimulateFromSeed tests an application by running the provided // operations, testing the provided invariants, but using the provided seed. func SimulateFromSeed( - t *testing.T, app *baseapp.BaseApp, appState json.RawMessage, seed int64, ops []TestAndRunTx, setups []RandSetup, + t *testing.T, app *baseapp.BaseApp, appStateFn func(r *rand.Rand, accs []sdk.AccAddress) json.RawMessage, seed int64, ops []TestAndRunTx, setups []RandSetup, invariants []Invariant, numKeys int, numBlocks int, blockSize int, ) { - log := fmt.Sprintf("Starting SingleModuleTest with randomness created with seed %d", int(seed)) - keys, _ := mock.GeneratePrivKeyAddressPairs(numKeys) + log := fmt.Sprintf("Starting SimulateFromSeed with randomness created with seed %d", int(seed)) + keys, addrs := mock.GeneratePrivKeyAddressPairs(numKeys) r := rand.New(rand.NewSource(seed)) - // XXX TODO - // RandomSetGenesis(r, app, addrs, []string{"foocoin"}) - app.InitChain(abci.RequestInitChain{AppStateBytes: appState}) + app.InitChain(abci.RequestInitChain{AppStateBytes: appStateFn(r, addrs)}) for i := 0; i < len(setups); i++ { setups[i](r, keys) } @@ -66,6 +65,7 @@ func SimulateFromSeed( } } +// AssertAllInvariants asserts a list of provided invariants against application state func AssertAllInvariants(t *testing.T, app *baseapp.BaseApp, tests []Invariant, log string) { for i := 0; i < len(tests); i++ { tests[i](t, app, log) diff --git a/x/stake/simulation/msgs.go b/x/stake/simulation/msgs.go new file mode 100644 index 000000000..2c7bf80f4 --- /dev/null +++ b/x/stake/simulation/msgs.go @@ -0,0 +1,246 @@ +package simulation + +import ( + "fmt" + "math/rand" + "testing" + + "github.com/stretchr/testify/require" + + "github.com/cosmos/cosmos-sdk/baseapp" + sdk "github.com/cosmos/cosmos-sdk/types" + "github.com/cosmos/cosmos-sdk/x/auth" + "github.com/cosmos/cosmos-sdk/x/mock" + "github.com/cosmos/cosmos-sdk/x/mock/simulation" + "github.com/cosmos/cosmos-sdk/x/stake" + abci "github.com/tendermint/tendermint/abci/types" + "github.com/tendermint/tendermint/crypto" +) + +// SimulateMsgCreateValidator +func SimulateMsgCreateValidator(m auth.AccountMapper, k stake.Keeper) simulation.TestAndRunTx { + return func(t *testing.T, r *rand.Rand, app *baseapp.BaseApp, ctx sdk.Context, keys []crypto.PrivKey, log string) (action string, err sdk.Error) { + denom := k.GetParams(ctx).BondDenom + description := stake.Description{ + Moniker: simulation.RandStringOfLength(r, 10), + } + key := keys[r.Intn(len(keys))] + pubkey := key.PubKey() + address := sdk.AccAddress(pubkey.Address()) + amount := m.GetAccount(ctx, address).GetCoins().AmountOf(denom) + if amount.GT(sdk.ZeroInt()) { + amount = sdk.NewInt(int64(r.Intn(int(amount.Int64())))) + } + if amount.Equal(sdk.ZeroInt()) { + return "nop", nil + } + msg := stake.MsgCreateValidator{ + Description: description, + ValidatorAddr: address, + DelegatorAddr: address, + PubKey: pubkey, + Delegation: sdk.NewIntCoin(denom, amount), + } + require.Nil(t, msg.ValidateBasic(), "expected msg to pass ValidateBasic: %s", msg.GetSignBytes()) + ctx, write := ctx.CacheContext() + result := stake.NewHandler(k)(ctx, msg) + if result.IsOK() { + write() + } + // require.True(t, result.IsOK(), "expected OK result but instead got %v", result) + action = fmt.Sprintf("TestMsgCreateValidator: %s", msg.GetSignBytes()) + return action, nil + } +} + +// SimulateMsgEditValidator +func SimulateMsgEditValidator(k stake.Keeper) simulation.TestAndRunTx { + return func(t *testing.T, r *rand.Rand, app *baseapp.BaseApp, ctx sdk.Context, keys []crypto.PrivKey, log string) (action string, err sdk.Error) { + description := stake.Description{ + Moniker: simulation.RandStringOfLength(r, 10), + Identity: simulation.RandStringOfLength(r, 10), + Website: simulation.RandStringOfLength(r, 10), + Details: simulation.RandStringOfLength(r, 10), + } + key := keys[r.Intn(len(keys))] + pubkey := key.PubKey() + address := sdk.AccAddress(pubkey.Address()) + msg := stake.MsgEditValidator{ + Description: description, + ValidatorAddr: address, + } + require.Nil(t, msg.ValidateBasic(), "expected msg to pass ValidateBasic: %s", msg.GetSignBytes()) + ctx, write := ctx.CacheContext() + result := stake.NewHandler(k)(ctx, msg) + if result.IsOK() { + write() + } + action = fmt.Sprintf("TestMsgEditValidator: %s", msg.GetSignBytes()) + return action, nil + } +} + +// SimulateMsgDelegate +func SimulateMsgDelegate(m auth.AccountMapper, k stake.Keeper) simulation.TestAndRunTx { + return func(t *testing.T, r *rand.Rand, app *baseapp.BaseApp, ctx sdk.Context, keys []crypto.PrivKey, log string) (action string, err sdk.Error) { + denom := k.GetParams(ctx).BondDenom + validatorKey := keys[r.Intn(len(keys))] + validatorAddress := sdk.AccAddress(validatorKey.PubKey().Address()) + delegatorKey := keys[r.Intn(len(keys))] + delegatorAddress := sdk.AccAddress(delegatorKey.PubKey().Address()) + amount := m.GetAccount(ctx, delegatorAddress).GetCoins().AmountOf(denom) + if amount.GT(sdk.ZeroInt()) { + amount = sdk.NewInt(int64(r.Intn(int(amount.Int64())))) + } + if amount.Equal(sdk.ZeroInt()) { + return "nop", nil + } + msg := stake.MsgDelegate{ + DelegatorAddr: delegatorAddress, + ValidatorAddr: validatorAddress, + Delegation: sdk.NewIntCoin(denom, amount), + } + require.Nil(t, msg.ValidateBasic(), "expected msg to pass ValidateBasic: %s", msg.GetSignBytes()) + ctx, write := ctx.CacheContext() + result := stake.NewHandler(k)(ctx, msg) + if result.IsOK() { + write() + } + action = fmt.Sprintf("TestMsgDelegate: %s", msg.GetSignBytes()) + return action, nil + } +} + +// SimulateMsgBeginUnbonding +func SimulateMsgBeginUnbonding(m auth.AccountMapper, k stake.Keeper) simulation.TestAndRunTx { + return func(t *testing.T, r *rand.Rand, app *baseapp.BaseApp, ctx sdk.Context, keys []crypto.PrivKey, log string) (action string, err sdk.Error) { + denom := k.GetParams(ctx).BondDenom + validatorKey := keys[r.Intn(len(keys))] + validatorAddress := sdk.AccAddress(validatorKey.PubKey().Address()) + delegatorKey := keys[r.Intn(len(keys))] + delegatorAddress := sdk.AccAddress(delegatorKey.PubKey().Address()) + amount := m.GetAccount(ctx, delegatorAddress).GetCoins().AmountOf(denom) + if amount.GT(sdk.ZeroInt()) { + amount = sdk.NewInt(int64(r.Intn(int(amount.Int64())))) + } + if amount.Equal(sdk.ZeroInt()) { + return "nop", nil + } + msg := stake.MsgBeginUnbonding{ + DelegatorAddr: delegatorAddress, + ValidatorAddr: validatorAddress, + SharesAmount: sdk.NewRatFromInt(amount), + } + require.Nil(t, msg.ValidateBasic(), "expected msg to pass ValidateBasic: %s", msg.GetSignBytes()) + ctx, write := ctx.CacheContext() + result := stake.NewHandler(k)(ctx, msg) + if result.IsOK() { + write() + } + action = fmt.Sprintf("TestMsgBeginUnbonding: %s", msg.GetSignBytes()) + return action, nil + } +} + +// SimulateMsgCompleteUnbonding +func SimulateMsgCompleteUnbonding(k stake.Keeper) simulation.TestAndRunTx { + return func(t *testing.T, r *rand.Rand, app *baseapp.BaseApp, ctx sdk.Context, keys []crypto.PrivKey, log string) (action string, err sdk.Error) { + validatorKey := keys[r.Intn(len(keys))] + validatorAddress := sdk.AccAddress(validatorKey.PubKey().Address()) + delegatorKey := keys[r.Intn(len(keys))] + delegatorAddress := sdk.AccAddress(delegatorKey.PubKey().Address()) + msg := stake.MsgCompleteUnbonding{ + DelegatorAddr: delegatorAddress, + ValidatorAddr: validatorAddress, + } + require.Nil(t, msg.ValidateBasic(), "expected msg to pass ValidateBasic: %s", msg.GetSignBytes()) + ctx, write := ctx.CacheContext() + result := stake.NewHandler(k)(ctx, msg) + if result.IsOK() { + write() + } + action = fmt.Sprintf("TestMsgCompleteUnbonding with %s", msg.GetSignBytes()) + return action, nil + } +} + +// SimulateMsgBeginRedelegate +func SimulateMsgBeginRedelegate(m auth.AccountMapper, k stake.Keeper) simulation.TestAndRunTx { + return func(t *testing.T, r *rand.Rand, app *baseapp.BaseApp, ctx sdk.Context, keys []crypto.PrivKey, log string) (action string, err sdk.Error) { + denom := k.GetParams(ctx).BondDenom + sourceValidatorKey := keys[r.Intn(len(keys))] + sourceValidatorAddress := sdk.AccAddress(sourceValidatorKey.PubKey().Address()) + destValidatorKey := keys[r.Intn(len(keys))] + destValidatorAddress := sdk.AccAddress(destValidatorKey.PubKey().Address()) + delegatorKey := keys[r.Intn(len(keys))] + delegatorAddress := sdk.AccAddress(delegatorKey.PubKey().Address()) + // TODO + amount := m.GetAccount(ctx, delegatorAddress).GetCoins().AmountOf(denom) + if amount.GT(sdk.ZeroInt()) { + amount = sdk.NewInt(int64(r.Intn(int(amount.Int64())))) + } + if amount.Equal(sdk.ZeroInt()) { + return "nop", nil + } + msg := stake.MsgBeginRedelegate{ + DelegatorAddr: delegatorAddress, + ValidatorSrcAddr: sourceValidatorAddress, + ValidatorDstAddr: destValidatorAddress, + SharesAmount: sdk.NewRatFromInt(amount), + } + require.Nil(t, msg.ValidateBasic(), "expected msg to pass ValidateBasic: %s", msg.GetSignBytes()) + ctx, write := ctx.CacheContext() + result := stake.NewHandler(k)(ctx, msg) + if result.IsOK() { + write() + } + action = fmt.Sprintf("TestMsgBeginRedelegate: %s", msg.GetSignBytes()) + return action, nil + } +} + +// SimulateMsgCompleteRedelegate +func SimulateMsgCompleteRedelegate(k stake.Keeper) simulation.TestAndRunTx { + return func(t *testing.T, r *rand.Rand, app *baseapp.BaseApp, ctx sdk.Context, keys []crypto.PrivKey, log string) (action string, err sdk.Error) { + validatorSrcKey := keys[r.Intn(len(keys))] + validatorSrcAddress := sdk.AccAddress(validatorSrcKey.PubKey().Address()) + validatorDstKey := keys[r.Intn(len(keys))] + validatorDstAddress := sdk.AccAddress(validatorDstKey.PubKey().Address()) + delegatorKey := keys[r.Intn(len(keys))] + delegatorAddress := sdk.AccAddress(delegatorKey.PubKey().Address()) + msg := stake.MsgCompleteRedelegate{ + DelegatorAddr: delegatorAddress, + ValidatorSrcAddr: validatorSrcAddress, + ValidatorDstAddr: validatorDstAddress, + } + require.Nil(t, msg.ValidateBasic(), "expected msg to pass ValidateBasic: %s", msg.GetSignBytes()) + ctx, write := ctx.CacheContext() + result := stake.NewHandler(k)(ctx, msg) + if result.IsOK() { + write() + } + action = fmt.Sprintf("TestMsgCompleteRedelegate with %s", msg.GetSignBytes()) + return action, nil + } +} + +// SimulationSetup +func SimulationSetup(mapp *mock.App, k stake.Keeper) simulation.RandSetup { + return func(r *rand.Rand, privKeys []crypto.PrivKey) { + ctx := mapp.NewContext(false, abci.Header{}) + stake.InitGenesis(ctx, k, stake.DefaultGenesisState()) + params := k.GetParams(ctx) + denom := params.BondDenom + loose := sdk.ZeroInt() + mapp.AccountMapper.IterateAccounts(ctx, func(acc auth.Account) bool { + balance := sdk.NewInt(int64(r.Intn(1000000))) + acc.SetCoins(acc.GetCoins().Plus(sdk.Coins{sdk.NewIntCoin(denom, balance)})) + mapp.AccountMapper.SetAccount(ctx, acc) + loose = loose.Add(balance) + return false + }) + pool := k.GetPool(ctx) + pool.LooseTokens = pool.LooseTokens.Add(sdk.NewRat(loose.Int64(), 1)) + k.SetPool(ctx, pool) + } +} diff --git a/x/stake/simulation/sim_test.go b/x/stake/simulation/sim_test.go index 8e5a48a21..c26f6c82c 100644 --- a/x/stake/simulation/sim_test.go +++ b/x/stake/simulation/sim_test.go @@ -2,262 +2,16 @@ package simulation import ( "encoding/json" - "fmt" - "math/rand" "testing" - "github.com/stretchr/testify/require" - - "github.com/cosmos/cosmos-sdk/baseapp" sdk "github.com/cosmos/cosmos-sdk/types" - "github.com/cosmos/cosmos-sdk/x/auth" "github.com/cosmos/cosmos-sdk/x/bank" "github.com/cosmos/cosmos-sdk/x/mock" "github.com/cosmos/cosmos-sdk/x/mock/simulation" "github.com/cosmos/cosmos-sdk/x/stake" abci "github.com/tendermint/tendermint/abci/types" - "github.com/tendermint/tendermint/crypto" ) -var ( - stats = make(map[string]int) -) - -// SimulateMsgCreateValidator -func SimulateMsgCreateValidator(m auth.AccountMapper, k stake.Keeper) simulation.TestAndRunTx { - return func(t *testing.T, r *rand.Rand, app *baseapp.BaseApp, ctx sdk.Context, keys []crypto.PrivKey, log string) (action string, err sdk.Error) { - denom := k.GetParams(ctx).BondDenom - description := stake.Description{ - Moniker: simulation.RandStringOfLength(r, 10), - } - key := keys[r.Intn(len(keys))] - pubkey := key.PubKey() - address := sdk.AccAddress(pubkey.Address()) - amount := m.GetAccount(ctx, address).GetCoins().AmountOf(denom) - if amount.GT(sdk.ZeroInt()) { - amount = sdk.NewInt(int64(r.Intn(int(amount.Int64())))) - } - if amount.Equal(sdk.ZeroInt()) { - return "nop", nil - } - msg := stake.MsgCreateValidator{ - Description: description, - ValidatorAddr: address, - DelegatorAddr: address, - PubKey: pubkey, - Delegation: sdk.NewIntCoin(denom, amount), - } - require.Nil(t, msg.ValidateBasic(), "expected msg to pass ValidateBasic: %s", msg.GetSignBytes()) - ctx, write := ctx.CacheContext() - result := stake.NewHandler(k)(ctx, msg) - if result.IsOK() { - write() - } - stats[fmt.Sprintf("stake/createvalidator/%v", result.IsOK())] += 1 - // require.True(t, result.IsOK(), "expected OK result but instead got %v", result) - action = fmt.Sprintf("TestMsgCreateValidator: %s", msg.GetSignBytes()) - return action, nil - } -} - -// SimulateMsgEditValidator -func SimulateMsgEditValidator(k stake.Keeper) simulation.TestAndRunTx { - return func(t *testing.T, r *rand.Rand, app *baseapp.BaseApp, ctx sdk.Context, keys []crypto.PrivKey, log string) (action string, err sdk.Error) { - description := stake.Description{ - Moniker: simulation.RandStringOfLength(r, 10), - Identity: simulation.RandStringOfLength(r, 10), - Website: simulation.RandStringOfLength(r, 10), - Details: simulation.RandStringOfLength(r, 10), - } - key := keys[r.Intn(len(keys))] - pubkey := key.PubKey() - address := sdk.AccAddress(pubkey.Address()) - msg := stake.MsgEditValidator{ - Description: description, - ValidatorAddr: address, - } - require.Nil(t, msg.ValidateBasic(), "expected msg to pass ValidateBasic: %s", msg.GetSignBytes()) - ctx, write := ctx.CacheContext() - result := stake.NewHandler(k)(ctx, msg) - if result.IsOK() { - write() - } - stats[fmt.Sprintf("stake/editvalidator/%v", result.IsOK())] += 1 - action = fmt.Sprintf("TestMsgEditValidator: %s", msg.GetSignBytes()) - return action, nil - } -} - -// SimulateMsgDelegate -func SimulateMsgDelegate(m auth.AccountMapper, k stake.Keeper) simulation.TestAndRunTx { - return func(t *testing.T, r *rand.Rand, app *baseapp.BaseApp, ctx sdk.Context, keys []crypto.PrivKey, log string) (action string, err sdk.Error) { - denom := k.GetParams(ctx).BondDenom - validatorKey := keys[r.Intn(len(keys))] - validatorAddress := sdk.AccAddress(validatorKey.PubKey().Address()) - delegatorKey := keys[r.Intn(len(keys))] - delegatorAddress := sdk.AccAddress(delegatorKey.PubKey().Address()) - amount := m.GetAccount(ctx, delegatorAddress).GetCoins().AmountOf(denom) - if amount.GT(sdk.ZeroInt()) { - amount = sdk.NewInt(int64(r.Intn(int(amount.Int64())))) - } - if amount.Equal(sdk.ZeroInt()) { - return "nop", nil - } - msg := stake.MsgDelegate{ - DelegatorAddr: delegatorAddress, - ValidatorAddr: validatorAddress, - Delegation: sdk.NewIntCoin(denom, amount), - } - require.Nil(t, msg.ValidateBasic(), "expected msg to pass ValidateBasic: %s", msg.GetSignBytes()) - ctx, write := ctx.CacheContext() - result := stake.NewHandler(k)(ctx, msg) - if result.IsOK() { - write() - } - stats[fmt.Sprintf("stake/delegate/%v", result.IsOK())] += 1 - action = fmt.Sprintf("TestMsgDelegate: %s", msg.GetSignBytes()) - return action, nil - } -} - -// SimulateMsgBeginUnbonding -func SimulateMsgBeginUnbonding(m auth.AccountMapper, k stake.Keeper) simulation.TestAndRunTx { - return func(t *testing.T, r *rand.Rand, app *baseapp.BaseApp, ctx sdk.Context, keys []crypto.PrivKey, log string) (action string, err sdk.Error) { - denom := k.GetParams(ctx).BondDenom - validatorKey := keys[r.Intn(len(keys))] - validatorAddress := sdk.AccAddress(validatorKey.PubKey().Address()) - delegatorKey := keys[r.Intn(len(keys))] - delegatorAddress := sdk.AccAddress(delegatorKey.PubKey().Address()) - amount := m.GetAccount(ctx, delegatorAddress).GetCoins().AmountOf(denom) - if amount.GT(sdk.ZeroInt()) { - amount = sdk.NewInt(int64(r.Intn(int(amount.Int64())))) - } - if amount.Equal(sdk.ZeroInt()) { - return "nop", nil - } - msg := stake.MsgBeginUnbonding{ - DelegatorAddr: delegatorAddress, - ValidatorAddr: validatorAddress, - SharesAmount: sdk.NewRatFromInt(amount), - } - require.Nil(t, msg.ValidateBasic(), "expected msg to pass ValidateBasic: %s", msg.GetSignBytes()) - ctx, write := ctx.CacheContext() - result := stake.NewHandler(k)(ctx, msg) - if result.IsOK() { - write() - } - stats[fmt.Sprintf("stake/beginunbonding/%v", result.IsOK())] += 1 - action = fmt.Sprintf("TestMsgBeginUnbonding: %s", msg.GetSignBytes()) - return action, nil - } -} - -// SimulateMsgCompleteUnbonding -func SimulateMsgCompleteUnbonding(k stake.Keeper) simulation.TestAndRunTx { - return func(t *testing.T, r *rand.Rand, app *baseapp.BaseApp, ctx sdk.Context, keys []crypto.PrivKey, log string) (action string, err sdk.Error) { - validatorKey := keys[r.Intn(len(keys))] - validatorAddress := sdk.AccAddress(validatorKey.PubKey().Address()) - delegatorKey := keys[r.Intn(len(keys))] - delegatorAddress := sdk.AccAddress(delegatorKey.PubKey().Address()) - msg := stake.MsgCompleteUnbonding{ - DelegatorAddr: delegatorAddress, - ValidatorAddr: validatorAddress, - } - require.Nil(t, msg.ValidateBasic(), "expected msg to pass ValidateBasic: %s", msg.GetSignBytes()) - ctx, write := ctx.CacheContext() - result := stake.NewHandler(k)(ctx, msg) - if result.IsOK() { - write() - } - stats[fmt.Sprintf("stake/completeunbonding/%v", result.IsOK())] += 1 - action = fmt.Sprintf("TestMsgCompleteUnbonding with %s", msg.GetSignBytes()) - return action, nil - } -} - -// SimulateMsgBeginRedelegate -func SimulateMsgBeginRedelegate(m auth.AccountMapper, k stake.Keeper) simulation.TestAndRunTx { - return func(t *testing.T, r *rand.Rand, app *baseapp.BaseApp, ctx sdk.Context, keys []crypto.PrivKey, log string) (action string, err sdk.Error) { - denom := k.GetParams(ctx).BondDenom - sourceValidatorKey := keys[r.Intn(len(keys))] - sourceValidatorAddress := sdk.AccAddress(sourceValidatorKey.PubKey().Address()) - destValidatorKey := keys[r.Intn(len(keys))] - destValidatorAddress := sdk.AccAddress(destValidatorKey.PubKey().Address()) - delegatorKey := keys[r.Intn(len(keys))] - delegatorAddress := sdk.AccAddress(delegatorKey.PubKey().Address()) - // TODO - amount := m.GetAccount(ctx, delegatorAddress).GetCoins().AmountOf(denom) - if amount.GT(sdk.ZeroInt()) { - amount = sdk.NewInt(int64(r.Intn(int(amount.Int64())))) - } - if amount.Equal(sdk.ZeroInt()) { - return "nop", nil - } - msg := stake.MsgBeginRedelegate{ - DelegatorAddr: delegatorAddress, - ValidatorSrcAddr: sourceValidatorAddress, - ValidatorDstAddr: destValidatorAddress, - SharesAmount: sdk.NewRatFromInt(amount), - } - require.Nil(t, msg.ValidateBasic(), "expected msg to pass ValidateBasic: %s", msg.GetSignBytes()) - ctx, write := ctx.CacheContext() - result := stake.NewHandler(k)(ctx, msg) - if result.IsOK() { - write() - } - stats[fmt.Sprintf("stake/beginredelegate/%v", result.IsOK())] += 1 - action = fmt.Sprintf("TestMsgBeginRedelegate: %s", msg.GetSignBytes()) - return action, nil - } -} - -// SimulateMsgCompleteRedelegate -func SimulateMsgCompleteRedelegate(k stake.Keeper) simulation.TestAndRunTx { - return func(t *testing.T, r *rand.Rand, app *baseapp.BaseApp, ctx sdk.Context, keys []crypto.PrivKey, log string) (action string, err sdk.Error) { - validatorSrcKey := keys[r.Intn(len(keys))] - validatorSrcAddress := sdk.AccAddress(validatorSrcKey.PubKey().Address()) - validatorDstKey := keys[r.Intn(len(keys))] - validatorDstAddress := sdk.AccAddress(validatorDstKey.PubKey().Address()) - delegatorKey := keys[r.Intn(len(keys))] - delegatorAddress := sdk.AccAddress(delegatorKey.PubKey().Address()) - msg := stake.MsgCompleteRedelegate{ - DelegatorAddr: delegatorAddress, - ValidatorSrcAddr: validatorSrcAddress, - ValidatorDstAddr: validatorDstAddress, - } - require.Nil(t, msg.ValidateBasic(), "expected msg to pass ValidateBasic: %s", msg.GetSignBytes()) - ctx, write := ctx.CacheContext() - result := stake.NewHandler(k)(ctx, msg) - if result.IsOK() { - write() - } - stats[fmt.Sprintf("stake/completeredelegate/%v", result.IsOK())] += 1 - action = fmt.Sprintf("TestMsgCompleteRedelegate with %s", msg.GetSignBytes()) - return action, nil - } -} - -// SimulationSetup -func SimulationSetup(mapp *mock.App, k stake.Keeper) simulation.RandSetup { - return func(r *rand.Rand, privKeys []crypto.PrivKey) { - ctx := mapp.NewContext(false, abci.Header{}) - stake.InitGenesis(ctx, k, stake.DefaultGenesisState()) - params := k.GetParams(ctx) - denom := params.BondDenom - loose := sdk.ZeroInt() - mapp.AccountMapper.IterateAccounts(ctx, func(acc auth.Account) bool { - balance := sdk.NewInt(int64(r.Intn(1000000))) - acc.SetCoins(acc.GetCoins().Plus(sdk.Coins{sdk.NewIntCoin(denom, balance)})) - mapp.AccountMapper.SetAccount(ctx, acc) - loose = loose.Add(balance) - return false - }) - pool := k.GetPool(ctx) - pool.LooseTokens = pool.LooseTokens.Add(sdk.NewRat(loose.Int64(), 1)) - k.SetPool(ctx, pool) - } -} - // TestStakeWithRandomMessages func TestStakeWithRandomMessages(t *testing.T) { mapp := mock.NewApp() @@ -297,6 +51,4 @@ func TestStakeWithRandomMessages(t *testing.T) { AllInvariants(coinKeeper, stakeKeeper, mapp.AccountMapper), }, 10, 100, 500, ) - - fmt.Printf("Stats: %v\n", stats) } From 5918ab18fdbc2fbb20b317e6fc03c588d8849b6d Mon Sep 17 00:00:00 2001 From: Christopher Goes Date: Wed, 18 Jul 2018 01:01:36 +0200 Subject: [PATCH 23/39] Restructure (probably) complete --- cmd/gaia/app/sim_test.go | 8 +++++--- x/stake/simulation/sim_test.go | 8 +++++++- 2 files changed, 12 insertions(+), 4 deletions(-) diff --git a/cmd/gaia/app/sim_test.go b/cmd/gaia/app/sim_test.go index 2fd2a55b6..86c0de594 100644 --- a/cmd/gaia/app/sim_test.go +++ b/cmd/gaia/app/sim_test.go @@ -19,8 +19,8 @@ import ( const ( NumKeys = 10 - NumBlocks = 1000 - BlockSize = 1000 + NumBlocks = 100 + BlockSize = 500 simulationEnv = "ENABLE_GAIA_SIMULATION" ) @@ -38,9 +38,11 @@ func appStateFn(r *rand.Rand, accs []sdk.AccAddress) json.RawMessage { } // Default genesis state + stakeGenesis := stake.DefaultGenesisState() + stakeGenesis.Pool.LooseTokens = sdk.NewRat(1000) genesis := GenesisState{ Accounts: genesisAccounts, - StakeData: stake.DefaultGenesisState(), + StakeData: stakeGenesis, } // Marshal genesis diff --git a/x/stake/simulation/sim_test.go b/x/stake/simulation/sim_test.go index c26f6c82c..a009dafe1 100644 --- a/x/stake/simulation/sim_test.go +++ b/x/stake/simulation/sim_test.go @@ -2,6 +2,7 @@ package simulation import ( "encoding/json" + "math/rand" "testing" sdk "github.com/cosmos/cosmos-sdk/types" @@ -34,8 +35,13 @@ func TestStakeWithRandomMessages(t *testing.T) { panic(err) } + appStateFn := func(r *rand.Rand, accs []sdk.AccAddress) json.RawMessage { + mock.RandomSetGenesis(r, mapp, accs, []string{"stake"}) + return json.RawMessage("{}") + } + simulation.Simulate( - t, mapp.BaseApp, json.RawMessage("{}"), + t, mapp.BaseApp, appStateFn, []simulation.TestAndRunTx{ SimulateMsgCreateValidator(mapper, stakeKeeper), SimulateMsgEditValidator(stakeKeeper), From c61b1aa591da31a1d2943444edd70637c5ac5c74 Mon Sep 17 00:00:00 2001 From: Christopher Goes Date: Wed, 18 Jul 2018 01:27:51 +0200 Subject: [PATCH 24/39] Event stats --- Makefile | 4 +++- x/mock/simulation/random_simulate_blocks.go | 10 +++++++++- x/mock/simulation/types.go | 2 +- x/mock/simulation/util.go | 6 ++++++ x/stake/simulation/msgs.go | 21 ++++++++++++++------- 5 files changed, 33 insertions(+), 10 deletions(-) diff --git a/Makefile b/Makefile index 645973472..830aed42e 100644 --- a/Makefile +++ b/Makefile @@ -114,8 +114,10 @@ test_race: @go test -race $(PACKAGES_NOCLITEST) test_sim: + @echo "Running individual module simulations..." + @go test $(PACKAGES_SIMTEST) -v + @echo "Running full Gaia simulation..." @ENABLE_GAIA_SIMULATION=1 go test ./cmd/gaia/app -run TestFullGaiaSimulation -v - @go test $(PACKAGES_SIMTEST) test_cover: @bash tests/test_cover.sh diff --git a/x/mock/simulation/random_simulate_blocks.go b/x/mock/simulation/random_simulate_blocks.go index eca9757c5..e952ce07f 100644 --- a/x/mock/simulation/random_simulate_blocks.go +++ b/x/mock/simulation/random_simulate_blocks.go @@ -33,6 +33,12 @@ func SimulateFromSeed( keys, addrs := mock.GeneratePrivKeyAddressPairs(numKeys) r := rand.New(rand.NewSource(seed)) + // Setup event stats + events := make(map[string]uint) + event := func(what string) { + events[what] += 1 + } + app.InitChain(abci.RequestInitChain{AppStateBytes: appStateFn(r, addrs)}) for i := 0; i < len(setups); i++ { setups[i](r, keys) @@ -53,7 +59,7 @@ func SimulateFromSeed( // TODO: Add modes to simulate "no load", "medium load", and // "high load" blocks. for j := 0; j < blockSize; j++ { - logUpdate, err := ops[r.Intn(len(ops))](t, r, app, ctx, keys, log) + logUpdate, err := ops[r.Intn(len(ops))](t, r, app, ctx, keys, log, event) log += "\n" + logUpdate require.Nil(t, err, log) @@ -63,6 +69,8 @@ func SimulateFromSeed( app.EndBlock(abci.RequestEndBlock{}) header.Height++ } + + DisplayEvents(events) } // AssertAllInvariants asserts a list of provided invariants against application state diff --git a/x/mock/simulation/types.go b/x/mock/simulation/types.go index 41736ce2c..6e1d9f198 100644 --- a/x/mock/simulation/types.go +++ b/x/mock/simulation/types.go @@ -15,7 +15,7 @@ type ( // about what this fuzzed tx actually did, for ease of debugging. TestAndRunTx func( t *testing.T, r *rand.Rand, app *baseapp.BaseApp, ctx sdk.Context, - privKeys []crypto.PrivKey, log string, + privKeys []crypto.PrivKey, log string, event func(string), ) (action string, err sdk.Error) // RandSetup performs the random setup the mock module needs. diff --git a/x/mock/simulation/util.go b/x/mock/simulation/util.go index 97307dc3e..c6f8ed54b 100644 --- a/x/mock/simulation/util.go +++ b/x/mock/simulation/util.go @@ -1,6 +1,7 @@ package simulation import ( + "fmt" "math/rand" ) @@ -29,3 +30,8 @@ func RandStringOfLength(r *rand.Rand, n int) string { } return string(b) } + +func DisplayEvents(events map[string]uint) { + // TODO + fmt.Printf("Events: %v\n", events) +} diff --git a/x/stake/simulation/msgs.go b/x/stake/simulation/msgs.go index 2c7bf80f4..c3060190f 100644 --- a/x/stake/simulation/msgs.go +++ b/x/stake/simulation/msgs.go @@ -19,7 +19,7 @@ import ( // SimulateMsgCreateValidator func SimulateMsgCreateValidator(m auth.AccountMapper, k stake.Keeper) simulation.TestAndRunTx { - return func(t *testing.T, r *rand.Rand, app *baseapp.BaseApp, ctx sdk.Context, keys []crypto.PrivKey, log string) (action string, err sdk.Error) { + return func(t *testing.T, r *rand.Rand, app *baseapp.BaseApp, ctx sdk.Context, keys []crypto.PrivKey, log string, event func(string)) (action string, err sdk.Error) { denom := k.GetParams(ctx).BondDenom description := stake.Description{ Moniker: simulation.RandStringOfLength(r, 10), @@ -47,6 +47,7 @@ func SimulateMsgCreateValidator(m auth.AccountMapper, k stake.Keeper) simulation if result.IsOK() { write() } + event(fmt.Sprintf("stake/MsgCreateValidator/%v", result.IsOK())) // require.True(t, result.IsOK(), "expected OK result but instead got %v", result) action = fmt.Sprintf("TestMsgCreateValidator: %s", msg.GetSignBytes()) return action, nil @@ -55,7 +56,7 @@ func SimulateMsgCreateValidator(m auth.AccountMapper, k stake.Keeper) simulation // SimulateMsgEditValidator func SimulateMsgEditValidator(k stake.Keeper) simulation.TestAndRunTx { - return func(t *testing.T, r *rand.Rand, app *baseapp.BaseApp, ctx sdk.Context, keys []crypto.PrivKey, log string) (action string, err sdk.Error) { + return func(t *testing.T, r *rand.Rand, app *baseapp.BaseApp, ctx sdk.Context, keys []crypto.PrivKey, log string, event func(string)) (action string, err sdk.Error) { description := stake.Description{ Moniker: simulation.RandStringOfLength(r, 10), Identity: simulation.RandStringOfLength(r, 10), @@ -75,6 +76,7 @@ func SimulateMsgEditValidator(k stake.Keeper) simulation.TestAndRunTx { if result.IsOK() { write() } + event(fmt.Sprintf("stake/MsgEditValidator/%v", result.IsOK())) action = fmt.Sprintf("TestMsgEditValidator: %s", msg.GetSignBytes()) return action, nil } @@ -82,7 +84,7 @@ func SimulateMsgEditValidator(k stake.Keeper) simulation.TestAndRunTx { // SimulateMsgDelegate func SimulateMsgDelegate(m auth.AccountMapper, k stake.Keeper) simulation.TestAndRunTx { - return func(t *testing.T, r *rand.Rand, app *baseapp.BaseApp, ctx sdk.Context, keys []crypto.PrivKey, log string) (action string, err sdk.Error) { + return func(t *testing.T, r *rand.Rand, app *baseapp.BaseApp, ctx sdk.Context, keys []crypto.PrivKey, log string, event func(string)) (action string, err sdk.Error) { denom := k.GetParams(ctx).BondDenom validatorKey := keys[r.Intn(len(keys))] validatorAddress := sdk.AccAddress(validatorKey.PubKey().Address()) @@ -106,6 +108,7 @@ func SimulateMsgDelegate(m auth.AccountMapper, k stake.Keeper) simulation.TestAn if result.IsOK() { write() } + event(fmt.Sprintf("stake/MsgDelegate/%v", result.IsOK())) action = fmt.Sprintf("TestMsgDelegate: %s", msg.GetSignBytes()) return action, nil } @@ -113,7 +116,7 @@ func SimulateMsgDelegate(m auth.AccountMapper, k stake.Keeper) simulation.TestAn // SimulateMsgBeginUnbonding func SimulateMsgBeginUnbonding(m auth.AccountMapper, k stake.Keeper) simulation.TestAndRunTx { - return func(t *testing.T, r *rand.Rand, app *baseapp.BaseApp, ctx sdk.Context, keys []crypto.PrivKey, log string) (action string, err sdk.Error) { + return func(t *testing.T, r *rand.Rand, app *baseapp.BaseApp, ctx sdk.Context, keys []crypto.PrivKey, log string, event func(string)) (action string, err sdk.Error) { denom := k.GetParams(ctx).BondDenom validatorKey := keys[r.Intn(len(keys))] validatorAddress := sdk.AccAddress(validatorKey.PubKey().Address()) @@ -137,6 +140,7 @@ func SimulateMsgBeginUnbonding(m auth.AccountMapper, k stake.Keeper) simulation. if result.IsOK() { write() } + event(fmt.Sprintf("stake/MsgBeginUnbonding/%v", result.IsOK())) action = fmt.Sprintf("TestMsgBeginUnbonding: %s", msg.GetSignBytes()) return action, nil } @@ -144,7 +148,7 @@ func SimulateMsgBeginUnbonding(m auth.AccountMapper, k stake.Keeper) simulation. // SimulateMsgCompleteUnbonding func SimulateMsgCompleteUnbonding(k stake.Keeper) simulation.TestAndRunTx { - return func(t *testing.T, r *rand.Rand, app *baseapp.BaseApp, ctx sdk.Context, keys []crypto.PrivKey, log string) (action string, err sdk.Error) { + return func(t *testing.T, r *rand.Rand, app *baseapp.BaseApp, ctx sdk.Context, keys []crypto.PrivKey, log string, event func(string)) (action string, err sdk.Error) { validatorKey := keys[r.Intn(len(keys))] validatorAddress := sdk.AccAddress(validatorKey.PubKey().Address()) delegatorKey := keys[r.Intn(len(keys))] @@ -159,6 +163,7 @@ func SimulateMsgCompleteUnbonding(k stake.Keeper) simulation.TestAndRunTx { if result.IsOK() { write() } + event(fmt.Sprintf("stake/MsgCompleteUnbonding/%v", result.IsOK())) action = fmt.Sprintf("TestMsgCompleteUnbonding with %s", msg.GetSignBytes()) return action, nil } @@ -166,7 +171,7 @@ func SimulateMsgCompleteUnbonding(k stake.Keeper) simulation.TestAndRunTx { // SimulateMsgBeginRedelegate func SimulateMsgBeginRedelegate(m auth.AccountMapper, k stake.Keeper) simulation.TestAndRunTx { - return func(t *testing.T, r *rand.Rand, app *baseapp.BaseApp, ctx sdk.Context, keys []crypto.PrivKey, log string) (action string, err sdk.Error) { + return func(t *testing.T, r *rand.Rand, app *baseapp.BaseApp, ctx sdk.Context, keys []crypto.PrivKey, log string, event func(string)) (action string, err sdk.Error) { denom := k.GetParams(ctx).BondDenom sourceValidatorKey := keys[r.Intn(len(keys))] sourceValidatorAddress := sdk.AccAddress(sourceValidatorKey.PubKey().Address()) @@ -194,6 +199,7 @@ func SimulateMsgBeginRedelegate(m auth.AccountMapper, k stake.Keeper) simulation if result.IsOK() { write() } + event(fmt.Sprintf("stake/MsgBeginRedelegate/%v", result.IsOK())) action = fmt.Sprintf("TestMsgBeginRedelegate: %s", msg.GetSignBytes()) return action, nil } @@ -201,7 +207,7 @@ func SimulateMsgBeginRedelegate(m auth.AccountMapper, k stake.Keeper) simulation // SimulateMsgCompleteRedelegate func SimulateMsgCompleteRedelegate(k stake.Keeper) simulation.TestAndRunTx { - return func(t *testing.T, r *rand.Rand, app *baseapp.BaseApp, ctx sdk.Context, keys []crypto.PrivKey, log string) (action string, err sdk.Error) { + return func(t *testing.T, r *rand.Rand, app *baseapp.BaseApp, ctx sdk.Context, keys []crypto.PrivKey, log string, event func(string)) (action string, err sdk.Error) { validatorSrcKey := keys[r.Intn(len(keys))] validatorSrcAddress := sdk.AccAddress(validatorSrcKey.PubKey().Address()) validatorDstKey := keys[r.Intn(len(keys))] @@ -219,6 +225,7 @@ func SimulateMsgCompleteRedelegate(k stake.Keeper) simulation.TestAndRunTx { if result.IsOK() { write() } + event(fmt.Sprintf("stake/MsgCompleteRedelegate/%v", result.IsOK())) action = fmt.Sprintf("TestMsgCompleteRedelegate with %s", msg.GetSignBytes()) return action, nil } From 6c61577b0b40d034d35bdff02e1effce3c5fc38d Mon Sep 17 00:00:00 2001 From: Christopher Goes Date: Wed, 18 Jul 2018 07:37:38 +0200 Subject: [PATCH 25/39] Misc, environment variables --- Makefile | 8 ++++---- cmd/gaia/app/sim_test.go | 29 ++++++++++++++++++++++++----- x/mock/simulation/util.go | 1 + x/stake/keeper/delegation.go | 16 ++++++++++++++++ x/stake/simulation/invariants.go | 8 +++++++- x/stake/simulation/sim_test.go | 5 ++--- 6 files changed, 54 insertions(+), 13 deletions(-) diff --git a/Makefile b/Makefile index 830aed42e..02fb21715 100644 --- a/Makefile +++ b/Makefile @@ -6,7 +6,7 @@ BUILD_TAGS = netgo ledger BUILD_FLAGS = -tags "${BUILD_TAGS}" -ldflags "-X github.com/cosmos/cosmos-sdk/version.GitCommit=${COMMIT_HASH}" GCC := $(shell command -v gcc 2> /dev/null) LEDGER_ENABLED ?= true -all: get_tools get_vendor_deps install install_examples test_lint test test_sim +all: get_tools get_vendor_deps install install_examples test_lint test ######################################## ### CI @@ -114,10 +114,10 @@ test_race: @go test -race $(PACKAGES_NOCLITEST) test_sim: - @echo "Running individual module simulations..." + @echo "Running individual module simulations." @go test $(PACKAGES_SIMTEST) -v - @echo "Running full Gaia simulation..." - @ENABLE_GAIA_SIMULATION=1 go test ./cmd/gaia/app -run TestFullGaiaSimulation -v + @echo "Running full Gaia simulation. This may take several minutes. Set the environment variable 'GAIA_SIMULATION_SEED' to run with a constant seed." + @GAIA_SIMULATION_ENABLED=1 go test ./cmd/gaia/app -run TestFullGaiaSimulation -v test_cover: @bash tests/test_cover.sh diff --git a/cmd/gaia/app/sim_test.go b/cmd/gaia/app/sim_test.go index 86c0de594..a7b20586c 100644 --- a/cmd/gaia/app/sim_test.go +++ b/cmd/gaia/app/sim_test.go @@ -20,9 +20,13 @@ import ( const ( NumKeys = 10 NumBlocks = 100 - BlockSize = 500 + BlockSize = 100 - simulationEnv = "ENABLE_GAIA_SIMULATION" + simulationEnvEnable = "GAIA_SIMULATION_ENABLED" + simulationEnvSeed = "GAIA_SIMULATION_SEED" + simulationEnvKeys = "GAIA_SIMULATION_KEYS" + simulationEnvBlocks = "GAIA_SIMULATION_BLOCKS" + simulationEnvBlockSize = "GAIA_SIMULATION_BLOCK_SIZE" ) func appStateFn(r *rand.Rand, accs []sdk.AccAddress) json.RawMessage { @@ -55,7 +59,7 @@ func appStateFn(r *rand.Rand, accs []sdk.AccAddress) json.RawMessage { } func TestFullGaiaSimulation(t *testing.T) { - if os.Getenv(simulationEnv) == "" { + if os.Getenv(simulationEnvEnable) == "" { t.Skip("Skipping Gaia simulation") } @@ -65,11 +69,26 @@ func TestFullGaiaSimulation(t *testing.T) { app := NewGaiaApp(logger, db, nil) require.Equal(t, "GaiaApp", app.Name()) + var seed int64 + envSeed := os.Getenv(simulationEnvSeed) + if envSeed != "" { + seed, err = strconv.ParseInt(envSeed, 10, 64) + require.Nil(t, err) + } else { + seed = time.Now().UnixNano() + } + // Run randomized simulation - simulation.Simulate( - t, app.BaseApp, appStateFn, + simulation.SimulateFromSeed( + t, app.BaseApp, appStateFn, seed, []simulation.TestAndRunTx{ stakesim.SimulateMsgCreateValidator(app.accountMapper, app.stakeKeeper), + stakesim.SimulateMsgEditValidator(app.accountMapper, app.stakeKeeper), + stakesim.SimulateMsgDelegate(app.accountMapper, app.stakeKeeper), + stakesim.SimulateMsgBeginUnbonding(app.accountMapper, app.stakeKeeper), + stakesim.SimulateMsgCompleteUnbonding(app.stakeKeeper), + stakesim.SimulateMsgBeginRedelegate(app.accountMapper, app.stakeKeeper), + stakesim.SimulateMsgCompleteRedelegate(app.stakeKeeper), }, []simulation.RandSetup{}, []simulation.Invariant{ diff --git a/x/mock/simulation/util.go b/x/mock/simulation/util.go index c6f8ed54b..35dcc1925 100644 --- a/x/mock/simulation/util.go +++ b/x/mock/simulation/util.go @@ -6,6 +6,7 @@ import ( ) // shamelessly copied from https://stackoverflow.com/questions/22892120/how-to-generate-a-random-string-of-a-fixed-length-in-golang#31832326 +// TODO we should probably move this to tendermint/libs/common/random.go const letterBytes = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ" const ( diff --git a/x/stake/keeper/delegation.go b/x/stake/keeper/delegation.go index e7168109a..4c7dab739 100644 --- a/x/stake/keeper/delegation.go +++ b/x/stake/keeper/delegation.go @@ -110,6 +110,22 @@ func (k Keeper) GetUnbondingDelegationsFromValidator(ctx sdk.Context, valAddr sd return ubds } +// iterate through all of the unbonding delegations +func (k Keeper) IterateUnbondingDelegations(ctx sdk.Context, fn func(index int64, ubd types.UnbondingDelegation) (stop bool)) { + store := ctx.KVStore(k.storeKey) + iterator := sdk.KVStorePrefixIterator(store, UnbondingDelegationKey) + i := int64(0) + for ; iterator.Valid(); iterator.Next() { + ubd := types.MustUnmarshalUBD(k.cdc, iterator.Key(), iterator.Value()) + stop := fn(i, ubd) + if stop { + break + } + i++ + } + iterator.Close() +} + // set the unbonding delegation and associated index func (k Keeper) SetUnbondingDelegation(ctx sdk.Context, ubd types.UnbondingDelegation) { store := ctx.KVStore(k.storeKey) diff --git a/x/stake/simulation/invariants.go b/x/stake/simulation/invariants.go index 08567bb4e..e5f042a6e 100644 --- a/x/stake/simulation/invariants.go +++ b/x/stake/simulation/invariants.go @@ -1,6 +1,7 @@ package simulation import ( + "fmt" "testing" "github.com/stretchr/testify/require" @@ -30,12 +31,17 @@ func SupplyInvariants(ck bank.Keeper, k stake.Keeper, am auth.AccountMapper) sim ctx := app.NewContext(false, abci.Header{}) pool := k.GetPool(ctx) - // Loose tokens should equal coin supply + // Loose tokens should equal coin supply plus unbonding delegations loose := sdk.ZeroInt() am.IterateAccounts(ctx, func(acc auth.Account) bool { loose = loose.Add(acc.GetCoins().AmountOf("steak")) return false }) + k.IterateUnbondingDelegations(ctx, func(_ int64, ubd stake.UnbondingDelegation) bool { + fmt.Printf("found ubd with balance: %v\n", ubd.Balance) + loose = loose.Add(ubd.Balance.Amount) + return false + }) require.True(t, pool.LooseTokens.RoundInt64() == loose.Int64(), "expected loose tokens to equal total steak held by accounts - pool.LooseTokens: %v, sum of account tokens: %v\nlog: %s", pool.LooseTokens, loose, log) // stats["stake/invariant/looseTokens"] += 1 diff --git a/x/stake/simulation/sim_test.go b/x/stake/simulation/sim_test.go index a009dafe1..a2afeb665 100644 --- a/x/stake/simulation/sim_test.go +++ b/x/stake/simulation/sim_test.go @@ -46,8 +46,7 @@ func TestStakeWithRandomMessages(t *testing.T) { SimulateMsgCreateValidator(mapper, stakeKeeper), SimulateMsgEditValidator(stakeKeeper), SimulateMsgDelegate(mapper, stakeKeeper), - // XXX TODO - // SimulateMsgBeginUnbonding(mapper, stakeKeeper), + SimulateMsgBeginUnbonding(mapper, stakeKeeper), SimulateMsgCompleteUnbonding(stakeKeeper), SimulateMsgBeginRedelegate(mapper, stakeKeeper), SimulateMsgCompleteRedelegate(stakeKeeper), @@ -55,6 +54,6 @@ func TestStakeWithRandomMessages(t *testing.T) { SimulationSetup(mapp, stakeKeeper), }, []simulation.Invariant{ AllInvariants(coinKeeper, stakeKeeper, mapp.AccountMapper), - }, 10, 100, 500, + }, 10, 100, 100, ) } From 966f26dfb23c532481972fa59ffd9cd395e24120 Mon Sep 17 00:00:00 2001 From: Christopher Goes Date: Wed, 18 Jul 2018 07:44:40 +0200 Subject: [PATCH 26/39] Remove print, quickfix --- cmd/gaia/app/sim_test.go | 5 ++++- x/stake/keeper/delegation.go | 6 ++++++ x/stake/simulation/invariants.go | 2 -- x/stake/types/errors.go | 4 ++++ 4 files changed, 14 insertions(+), 3 deletions(-) diff --git a/cmd/gaia/app/sim_test.go b/cmd/gaia/app/sim_test.go index a7b20586c..246d03a0f 100644 --- a/cmd/gaia/app/sim_test.go +++ b/cmd/gaia/app/sim_test.go @@ -4,7 +4,9 @@ import ( "encoding/json" "math/rand" "os" + "strconv" "testing" + "time" "github.com/stretchr/testify/require" @@ -70,6 +72,7 @@ func TestFullGaiaSimulation(t *testing.T) { require.Equal(t, "GaiaApp", app.Name()) var seed int64 + var err error envSeed := os.Getenv(simulationEnvSeed) if envSeed != "" { seed, err = strconv.ParseInt(envSeed, 10, 64) @@ -83,7 +86,7 @@ func TestFullGaiaSimulation(t *testing.T) { t, app.BaseApp, appStateFn, seed, []simulation.TestAndRunTx{ stakesim.SimulateMsgCreateValidator(app.accountMapper, app.stakeKeeper), - stakesim.SimulateMsgEditValidator(app.accountMapper, app.stakeKeeper), + stakesim.SimulateMsgEditValidator(app.stakeKeeper), stakesim.SimulateMsgDelegate(app.accountMapper, app.stakeKeeper), stakesim.SimulateMsgBeginUnbonding(app.accountMapper, app.stakeKeeper), stakesim.SimulateMsgCompleteUnbonding(app.stakeKeeper), diff --git a/x/stake/keeper/delegation.go b/x/stake/keeper/delegation.go index 4c7dab739..23b58108f 100644 --- a/x/stake/keeper/delegation.go +++ b/x/stake/keeper/delegation.go @@ -314,6 +314,12 @@ func (k Keeper) unbond(ctx sdk.Context, delegatorAddr, validatorAddr sdk.AccAddr // complete unbonding an unbonding record func (k Keeper) BeginUnbonding(ctx sdk.Context, delegatorAddr, validatorAddr sdk.AccAddress, sharesAmount sdk.Rat) sdk.Error { + // TODO quick fix, instead we should use an index, see https://github.com/cosmos/cosmos-sdk/issues/1402 + _, found := k.GetUnbondingDelegation(ctx, delegatorAddr, validatorAddr) + if found { + return types.ErrExistingUnbondingDelegation(k.Codespace()) + } + returnAmount, err := k.unbond(ctx, delegatorAddr, validatorAddr, sharesAmount) if err != nil { return err diff --git a/x/stake/simulation/invariants.go b/x/stake/simulation/invariants.go index e5f042a6e..776c8d1e7 100644 --- a/x/stake/simulation/invariants.go +++ b/x/stake/simulation/invariants.go @@ -1,7 +1,6 @@ package simulation import ( - "fmt" "testing" "github.com/stretchr/testify/require" @@ -38,7 +37,6 @@ func SupplyInvariants(ck bank.Keeper, k stake.Keeper, am auth.AccountMapper) sim return false }) k.IterateUnbondingDelegations(ctx, func(_ int64, ubd stake.UnbondingDelegation) bool { - fmt.Printf("found ubd with balance: %v\n", ubd.Balance) loose = loose.Add(ubd.Balance.Amount) return false }) diff --git a/x/stake/types/errors.go b/x/stake/types/errors.go index 237340b89..2ef747bae 100644 --- a/x/stake/types/errors.go +++ b/x/stake/types/errors.go @@ -120,6 +120,10 @@ func ErrNoUnbondingDelegation(codespace sdk.CodespaceType) sdk.Error { return sdk.NewError(codespace, CodeInvalidDelegation, "no unbonding delegation found") } +func ErrExistingUnbondingDelegation(codespace sdk.CodespaceType) sdk.Error { + return sdk.NewError(codespace, CodeInvalidDelegation, "existing unbonding delegation found") +} + func ErrNoRedelegation(codespace sdk.CodespaceType) sdk.Error { return sdk.NewError(codespace, CodeInvalidDelegation, "no redelegation found") } From ad410c1e2ebdc571da323c95c8b4ce90dacc0793 Mon Sep 17 00:00:00 2001 From: Christopher Goes Date: Wed, 18 Jul 2018 07:50:04 +0200 Subject: [PATCH 27/39] Linter fixes --- x/mock/simulation/random_simulate_blocks.go | 2 +- x/mock/simulation/util.go | 2 ++ x/stake/simulation/msgs.go | 4 ++-- x/stake/simulation/sim_test.go | 2 +- 4 files changed, 6 insertions(+), 4 deletions(-) diff --git a/x/mock/simulation/random_simulate_blocks.go b/x/mock/simulation/random_simulate_blocks.go index e952ce07f..5f507b89c 100644 --- a/x/mock/simulation/random_simulate_blocks.go +++ b/x/mock/simulation/random_simulate_blocks.go @@ -36,7 +36,7 @@ func SimulateFromSeed( // Setup event stats events := make(map[string]uint) event := func(what string) { - events[what] += 1 + events[what]++ } app.InitChain(abci.RequestInitChain{AppStateBytes: appStateFn(r, addrs)}) diff --git a/x/mock/simulation/util.go b/x/mock/simulation/util.go index 35dcc1925..8fdf5021e 100644 --- a/x/mock/simulation/util.go +++ b/x/mock/simulation/util.go @@ -15,6 +15,7 @@ const ( letterIdxMax = 63 / letterIdxBits // # of letter indices fitting in 63 bits ) +// Generate a random string of a particular length func RandStringOfLength(r *rand.Rand, n int) string { b := make([]byte, n) // A src.Int63() generates 63 random bits, enough for letterIdxMax characters! @@ -32,6 +33,7 @@ func RandStringOfLength(r *rand.Rand, n int) string { return string(b) } +// Pretty-print events as a table func DisplayEvents(events map[string]uint) { // TODO fmt.Printf("Events: %v\n", events) diff --git a/x/stake/simulation/msgs.go b/x/stake/simulation/msgs.go index c3060190f..f46881e30 100644 --- a/x/stake/simulation/msgs.go +++ b/x/stake/simulation/msgs.go @@ -231,8 +231,8 @@ func SimulateMsgCompleteRedelegate(k stake.Keeper) simulation.TestAndRunTx { } } -// SimulationSetup -func SimulationSetup(mapp *mock.App, k stake.Keeper) simulation.RandSetup { +// Setup +func Setup(mapp *mock.App, k stake.Keeper) simulation.RandSetup { return func(r *rand.Rand, privKeys []crypto.PrivKey) { ctx := mapp.NewContext(false, abci.Header{}) stake.InitGenesis(ctx, k, stake.DefaultGenesisState()) diff --git a/x/stake/simulation/sim_test.go b/x/stake/simulation/sim_test.go index a2afeb665..391ca1996 100644 --- a/x/stake/simulation/sim_test.go +++ b/x/stake/simulation/sim_test.go @@ -51,7 +51,7 @@ func TestStakeWithRandomMessages(t *testing.T) { SimulateMsgBeginRedelegate(mapper, stakeKeeper), SimulateMsgCompleteRedelegate(stakeKeeper), }, []simulation.RandSetup{ - SimulationSetup(mapp, stakeKeeper), + Setup(mapp, stakeKeeper), }, []simulation.Invariant{ AllInvariants(coinKeeper, stakeKeeper, mapp.AccountMapper), }, 10, 100, 100, From 8bd54f0701ea515d6faa4b307c0dbaa0f8f099f7 Mon Sep 17 00:00:00 2001 From: Christopher Goes Date: Wed, 18 Jul 2018 09:05:48 +0200 Subject: [PATCH 28/39] Refactor bank tests --- cmd/gaia/app/sim_test.go | 3 + x/bank/app_test.go | 15 ---- x/bank/simulation/invariants.go | 50 +++++++++++ x/bank/simulation/msgs.go | 117 +++++++++++++++++++++++++ x/bank/simulation/sim_test.go | 44 ++++++++++ x/bank/test_helpers.go | 150 -------------------------------- 6 files changed, 214 insertions(+), 165 deletions(-) create mode 100644 x/bank/simulation/invariants.go create mode 100644 x/bank/simulation/msgs.go create mode 100644 x/bank/simulation/sim_test.go delete mode 100644 x/bank/test_helpers.go diff --git a/cmd/gaia/app/sim_test.go b/cmd/gaia/app/sim_test.go index 246d03a0f..745824f00 100644 --- a/cmd/gaia/app/sim_test.go +++ b/cmd/gaia/app/sim_test.go @@ -14,6 +14,7 @@ import ( "github.com/tendermint/tendermint/libs/log" sdk "github.com/cosmos/cosmos-sdk/types" + banksim "github.com/cosmos/cosmos-sdk/x/bank/simulation" "github.com/cosmos/cosmos-sdk/x/mock/simulation" stake "github.com/cosmos/cosmos-sdk/x/stake" stakesim "github.com/cosmos/cosmos-sdk/x/stake/simulation" @@ -85,6 +86,7 @@ func TestFullGaiaSimulation(t *testing.T) { simulation.SimulateFromSeed( t, app.BaseApp, appStateFn, seed, []simulation.TestAndRunTx{ + banksim.TestAndRunSingleInputMsgSend(app.accountMapper), stakesim.SimulateMsgCreateValidator(app.accountMapper, app.stakeKeeper), stakesim.SimulateMsgEditValidator(app.stakeKeeper), stakesim.SimulateMsgDelegate(app.accountMapper, app.stakeKeeper), @@ -95,6 +97,7 @@ func TestFullGaiaSimulation(t *testing.T) { }, []simulation.RandSetup{}, []simulation.Invariant{ + banksim.NonnegativeBalanceInvariant(app.accountMapper), stakesim.AllInvariants(app.coinKeeper, app.stakeKeeper, app.accountMapper), }, NumKeys, diff --git a/x/bank/app_test.go b/x/bank/app_test.go index 74a421bd7..8c82cd475 100644 --- a/x/bank/app_test.go +++ b/x/bank/app_test.go @@ -83,21 +83,6 @@ func getMockApp(t *testing.T) *mock.App { return mapp } -func TestBankWithRandomMessages(t *testing.T) { - mapp := getMockApp(t) - setup := func(r *rand.Rand, keys []crypto.PrivKey) { - return - } - - mapp.RandomizedTesting( - t, - []mock.TestAndRunTx{TestAndRunSingleInputMsgSend}, - []mock.RandSetup{setup}, - []mock.Invariant{ModuleInvariants}, - 100, 30, 30, - ) -} - func TestMsgSendWithAccounts(t *testing.T) { mapp := getMockApp(t) diff --git a/x/bank/simulation/invariants.go b/x/bank/simulation/invariants.go new file mode 100644 index 000000000..847288e1f --- /dev/null +++ b/x/bank/simulation/invariants.go @@ -0,0 +1,50 @@ +package simulation + +import ( + "fmt" + "testing" + + "github.com/stretchr/testify/require" + + "github.com/cosmos/cosmos-sdk/baseapp" + sdk "github.com/cosmos/cosmos-sdk/types" + "github.com/cosmos/cosmos-sdk/x/auth" + "github.com/cosmos/cosmos-sdk/x/mock" + "github.com/cosmos/cosmos-sdk/x/mock/simulation" + abci "github.com/tendermint/tendermint/abci/types" +) + +// NonnegativeBalanceInvariant checks that all accounts in the application have non-negative balances +func NonnegativeBalanceInvariant(mapper auth.AccountMapper) simulation.Invariant { + return func(t *testing.T, app *baseapp.BaseApp, log string) { + ctx := app.NewContext(false, abci.Header{}) + accts := mock.GetAllAccounts(mapper, ctx) + for _, acc := range accts { + coins := acc.GetCoins() + require.True(t, coins.IsNotNegative(), + fmt.Sprintf("%s has a negative denomination of %s\n%s", + acc.GetAddress().String(), + coins.String(), + log), + ) + } + } +} + +// TotalCoinsInvariant checks that the sum of the coins across all accounts +// is what is expected +func TotalCoinsInvariant(mapper auth.AccountMapper, totalSupplyFn func() sdk.Coins) simulation.Invariant { + return func(t *testing.T, app *baseapp.BaseApp, log string) { + ctx := app.NewContext(false, abci.Header{}) + totalCoins := sdk.Coins{} + + chkAccount := func(acc auth.Account) bool { + coins := acc.GetCoins() + totalCoins = totalCoins.Plus(coins) + return false + } + + mapper.IterateAccounts(ctx, chkAccount) + require.Equal(t, totalSupplyFn(), totalCoins, log) + } +} diff --git a/x/bank/simulation/msgs.go b/x/bank/simulation/msgs.go new file mode 100644 index 000000000..553d000db --- /dev/null +++ b/x/bank/simulation/msgs.go @@ -0,0 +1,117 @@ +package simulation + +import ( + "errors" + "fmt" + "math/big" + "math/rand" + "testing" + + "github.com/stretchr/testify/require" + + "github.com/cosmos/cosmos-sdk/baseapp" + sdk "github.com/cosmos/cosmos-sdk/types" + "github.com/cosmos/cosmos-sdk/x/auth" + "github.com/cosmos/cosmos-sdk/x/bank" + "github.com/cosmos/cosmos-sdk/x/mock" + "github.com/cosmos/cosmos-sdk/x/mock/simulation" + "github.com/tendermint/tendermint/crypto" +) + +// TestAndRunSingleInputMsgSend tests and runs a single msg send, with one input and one output, where both +// accounts already exist. +func TestAndRunSingleInputMsgSend(mapper auth.AccountMapper) simulation.TestAndRunTx { + return func(t *testing.T, r *rand.Rand, app *baseapp.BaseApp, ctx sdk.Context, keys []crypto.PrivKey, log string, event func(string)) (action string, err sdk.Error) { + fromKey := keys[r.Intn(len(keys))] + fromAddr := sdk.AccAddress(fromKey.PubKey().Address()) + toKey := keys[r.Intn(len(keys))] + // Disallow sending money to yourself + for { + if !fromKey.Equals(toKey) { + break + } + toKey = keys[r.Intn(len(keys))] + } + toAddr := sdk.AccAddress(toKey.PubKey().Address()) + initFromCoins := mapper.GetAccount(ctx, fromAddr).GetCoins() + + denomIndex := r.Intn(len(initFromCoins)) + amt, goErr := randPositiveInt(r, initFromCoins[denomIndex].Amount) + if goErr != nil { + return "skipping bank send due to account having no coins of denomination " + initFromCoins[denomIndex].Denom, nil + } + + action = fmt.Sprintf("%s is sending %s %s to %s", + fromAddr.String(), + amt.String(), + initFromCoins[denomIndex].Denom, + toAddr.String(), + ) + log = fmt.Sprintf("%s\n%s", log, action) + + coins := sdk.Coins{{initFromCoins[denomIndex].Denom, amt}} + var msg = bank.MsgSend{ + Inputs: []bank.Input{bank.NewInput(fromAddr, coins)}, + Outputs: []bank.Output{bank.NewOutput(toAddr, coins)}, + } + sendAndVerifyMsgSend(t, app, mapper, msg, ctx, log, []crypto.PrivKey{fromKey}) + event("bank/sendAndVerifyMsgSend/ok") + + return action, nil + } +} + +// Sends and verifies the transition of a msg send. This fails if there are repeated inputs or outputs +func sendAndVerifyMsgSend(t *testing.T, app *baseapp.BaseApp, mapper auth.AccountMapper, msg bank.MsgSend, ctx sdk.Context, log string, privkeys []crypto.PrivKey) { + initialInputAddrCoins := make([]sdk.Coins, len(msg.Inputs)) + initialOutputAddrCoins := make([]sdk.Coins, len(msg.Outputs)) + AccountNumbers := make([]int64, len(msg.Inputs)) + SequenceNumbers := make([]int64, len(msg.Inputs)) + + for i := 0; i < len(msg.Inputs); i++ { + acc := mapper.GetAccount(ctx, msg.Inputs[i].Address) + AccountNumbers[i] = acc.GetAccountNumber() + SequenceNumbers[i] = acc.GetSequence() + initialInputAddrCoins[i] = acc.GetCoins() + } + for i := 0; i < len(msg.Outputs); i++ { + acc := mapper.GetAccount(ctx, msg.Outputs[i].Address) + initialOutputAddrCoins[i] = acc.GetCoins() + } + tx := mock.GenTx([]sdk.Msg{msg}, + AccountNumbers, + SequenceNumbers, + privkeys...) + res := app.Deliver(tx) + if !res.IsOK() { + // TODO: Do this in a more 'canonical' way + fmt.Println(res) + fmt.Println(log) + t.FailNow() + } + + for i := 0; i < len(msg.Inputs); i++ { + terminalInputCoins := mapper.GetAccount(ctx, msg.Inputs[i].Address).GetCoins() + require.Equal(t, + initialInputAddrCoins[i].Minus(msg.Inputs[i].Coins), + terminalInputCoins, + fmt.Sprintf("Input #%d had an incorrect amount of coins\n%s", i, log), + ) + } + for i := 0; i < len(msg.Outputs); i++ { + terminalOutputCoins := mapper.GetAccount(ctx, msg.Outputs[i].Address).GetCoins() + require.Equal(t, + initialOutputAddrCoins[i].Plus(msg.Outputs[i].Coins), + terminalOutputCoins, + fmt.Sprintf("Output #%d had an incorrect amount of coins\n%s", i, log), + ) + } +} + +func randPositiveInt(r *rand.Rand, max sdk.Int) (sdk.Int, error) { + if !max.GT(sdk.OneInt()) { + return sdk.Int{}, errors.New("max too small") + } + max = max.Sub(sdk.OneInt()) + return sdk.NewIntFromBigInt(new(big.Int).Rand(r, max.BigInt())).Add(sdk.OneInt()), nil +} diff --git a/x/bank/simulation/sim_test.go b/x/bank/simulation/sim_test.go new file mode 100644 index 000000000..5d76dd058 --- /dev/null +++ b/x/bank/simulation/sim_test.go @@ -0,0 +1,44 @@ +package simulation + +import ( + "encoding/json" + "math/rand" + "testing" + + sdk "github.com/cosmos/cosmos-sdk/types" + "github.com/cosmos/cosmos-sdk/x/bank" + "github.com/cosmos/cosmos-sdk/x/mock" + "github.com/cosmos/cosmos-sdk/x/mock/simulation" +) + +func TestBankWithRandomMessages(t *testing.T) { + mapp := mock.NewApp() + + bank.RegisterWire(mapp.Cdc) + mapper := mapp.AccountMapper + coinKeeper := bank.NewKeeper(mapper) + mapp.Router().AddRoute("bank", bank.NewHandler(coinKeeper)) + + err := mapp.CompleteSetup([]*sdk.KVStoreKey{}) + if err != nil { + panic(err) + } + + appStateFn := func(r *rand.Rand, accs []sdk.AccAddress) json.RawMessage { + mock.RandomSetGenesis(r, mapp, accs, []string{"stake"}) + return json.RawMessage("{}") + } + + simulation.Simulate( + t, mapp.BaseApp, appStateFn, + []simulation.TestAndRunTx{ + TestAndRunSingleInputMsgSend(mapper), + }, + []simulation.RandSetup{}, + []simulation.Invariant{ + NonnegativeBalanceInvariant(mapper), + TotalCoinsInvariant(mapper, func() sdk.Coins { return mapp.TotalCoinsSupply }), + }, + 100, 30, 30, + ) +} diff --git a/x/bank/test_helpers.go b/x/bank/test_helpers.go deleted file mode 100644 index 1dad0ba26..000000000 --- a/x/bank/test_helpers.go +++ /dev/null @@ -1,150 +0,0 @@ -package bank - -import ( - "errors" - "fmt" - "math/big" - "math/rand" - "testing" - - sdk "github.com/cosmos/cosmos-sdk/types" - "github.com/cosmos/cosmos-sdk/x/auth" - "github.com/cosmos/cosmos-sdk/x/mock" - "github.com/stretchr/testify/assert" - "github.com/stretchr/testify/require" - abci "github.com/tendermint/tendermint/abci/types" - "github.com/tendermint/tendermint/crypto" -) - -// ModuleInvariants runs all invariants of the bank module. -// Currently runs non-negative balance invariant and TotalCoinsInvariant -func ModuleInvariants(t *testing.T, app *mock.App, log string) { - NonnegativeBalanceInvariant(t, app, log) - TotalCoinsInvariant(t, app, log) -} - -// NonnegativeBalanceInvariant checks that all accounts in the application have non-negative balances -func NonnegativeBalanceInvariant(t *testing.T, app *mock.App, log string) { - ctx := app.NewContext(false, abci.Header{}) - accts := mock.GetAllAccounts(app.AccountMapper, ctx) - for _, acc := range accts { - coins := acc.GetCoins() - assert.True(t, coins.IsNotNegative(), - fmt.Sprintf("%s has a negative denomination of %s\n%s", - acc.GetAddress().String(), - coins.String(), - log), - ) - } -} - -// TotalCoinsInvariant checks that the sum of the coins across all accounts -// is what is expected -func TotalCoinsInvariant(t *testing.T, app *mock.App, log string) { - ctx := app.BaseApp.NewContext(false, abci.Header{}) - totalCoins := sdk.Coins{} - - chkAccount := func(acc auth.Account) bool { - coins := acc.GetCoins() - totalCoins = totalCoins.Plus(coins) - return false - } - - app.AccountMapper.IterateAccounts(ctx, chkAccount) - require.Equal(t, app.TotalCoinsSupply, totalCoins, log) -} - -// TestAndRunSingleInputMsgSend tests and runs a single msg send, with one input and one output, where both -// accounts already exist. -func TestAndRunSingleInputMsgSend(t *testing.T, r *rand.Rand, app *mock.App, ctx sdk.Context, keys []crypto.PrivKey, log string) (action string, err sdk.Error) { - fromKey := keys[r.Intn(len(keys))] - fromAddr := sdk.AccAddress(fromKey.PubKey().Address()) - toKey := keys[r.Intn(len(keys))] - // Disallow sending money to yourself - for { - if !fromKey.Equals(toKey) { - break - } - toKey = keys[r.Intn(len(keys))] - } - toAddr := sdk.AccAddress(toKey.PubKey().Address()) - initFromCoins := app.AccountMapper.GetAccount(ctx, fromAddr).GetCoins() - - denomIndex := r.Intn(len(initFromCoins)) - amt, goErr := randPositiveInt(r, initFromCoins[denomIndex].Amount) - if goErr != nil { - return "skipping bank send due to account having no coins of denomination " + initFromCoins[denomIndex].Denom, nil - } - - action = fmt.Sprintf("%s is sending %s %s to %s", - fromAddr.String(), - amt.String(), - initFromCoins[denomIndex].Denom, - toAddr.String(), - ) - log = fmt.Sprintf("%s\n%s", log, action) - - coins := sdk.Coins{{initFromCoins[denomIndex].Denom, amt}} - var msg = MsgSend{ - Inputs: []Input{NewInput(fromAddr, coins)}, - Outputs: []Output{NewOutput(toAddr, coins)}, - } - sendAndVerifyMsgSend(t, app, msg, ctx, log, []crypto.PrivKey{fromKey}) - - return action, nil -} - -// Sends and verifies the transition of a msg send. This fails if there are repeated inputs or outputs -func sendAndVerifyMsgSend(t *testing.T, app *mock.App, msg MsgSend, ctx sdk.Context, log string, privkeys []crypto.PrivKey) { - initialInputAddrCoins := make([]sdk.Coins, len(msg.Inputs)) - initialOutputAddrCoins := make([]sdk.Coins, len(msg.Outputs)) - AccountNumbers := make([]int64, len(msg.Inputs)) - SequenceNumbers := make([]int64, len(msg.Inputs)) - - for i := 0; i < len(msg.Inputs); i++ { - acc := app.AccountMapper.GetAccount(ctx, msg.Inputs[i].Address) - AccountNumbers[i] = acc.GetAccountNumber() - SequenceNumbers[i] = acc.GetSequence() - initialInputAddrCoins[i] = acc.GetCoins() - } - for i := 0; i < len(msg.Outputs); i++ { - acc := app.AccountMapper.GetAccount(ctx, msg.Outputs[i].Address) - initialOutputAddrCoins[i] = acc.GetCoins() - } - tx := mock.GenTx([]sdk.Msg{msg}, - AccountNumbers, - SequenceNumbers, - privkeys...) - res := app.Deliver(tx) - if !res.IsOK() { - // TODO: Do this in a more 'canonical' way - fmt.Println(res) - fmt.Println(log) - t.FailNow() - } - - for i := 0; i < len(msg.Inputs); i++ { - terminalInputCoins := app.AccountMapper.GetAccount(ctx, msg.Inputs[i].Address).GetCoins() - require.Equal(t, - initialInputAddrCoins[i].Minus(msg.Inputs[i].Coins), - terminalInputCoins, - fmt.Sprintf("Input #%d had an incorrect amount of coins\n%s", i, log), - ) - } - for i := 0; i < len(msg.Outputs); i++ { - terminalOutputCoins := app.AccountMapper.GetAccount(ctx, msg.Outputs[i].Address).GetCoins() - require.Equal(t, - initialOutputAddrCoins[i].Plus(msg.Outputs[i].Coins), - terminalOutputCoins, - fmt.Sprintf("Output #%d had an incorrect amount of coins\n%s", i, log), - ) - } -} - -func randPositiveInt(r *rand.Rand, max sdk.Int) (sdk.Int, error) { - if !max.GT(sdk.OneInt()) { - return sdk.Int{}, errors.New("max too small") - } - max = max.Sub(sdk.OneInt()) - return sdk.NewIntFromBigInt(new(big.Int).Rand(r, max.BigInt())).Add(sdk.OneInt()), nil -} From 05ceff521283705be9d95b29849f0e32e7719014 Mon Sep 17 00:00:00 2001 From: Christopher Goes Date: Wed, 18 Jul 2018 09:37:14 +0200 Subject: [PATCH 29/39] Deterministic 'make test_sim' on CircleCI; bank test fix --- .circleci/config.yml | 1 + x/bank/app_test.go | 2 -- x/stake/simulation/invariants.go | 5 +---- x/stake/simulation/msgs.go | 12 ++++++------ 4 files changed, 8 insertions(+), 12 deletions(-) diff --git a/.circleci/config.yml b/.circleci/config.yml index bba1031fd..ff9395c52 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -99,6 +99,7 @@ jobs: name: Test simulation command: | export PATH="$GOBIN:$PATH" + export GAIA_SIMULATION_SEED=1531897442166404087 make test_sim test_cover: diff --git a/x/bank/app_test.go b/x/bank/app_test.go index 8c82cd475..2deb5de38 100644 --- a/x/bank/app_test.go +++ b/x/bank/app_test.go @@ -5,8 +5,6 @@ import ( "github.com/stretchr/testify/require" - "math/rand" - sdk "github.com/cosmos/cosmos-sdk/types" "github.com/cosmos/cosmos-sdk/x/auth" "github.com/cosmos/cosmos-sdk/x/mock" diff --git a/x/stake/simulation/invariants.go b/x/stake/simulation/invariants.go index 776c8d1e7..92dd317d0 100644 --- a/x/stake/simulation/invariants.go +++ b/x/stake/simulation/invariants.go @@ -41,8 +41,7 @@ func SupplyInvariants(ck bank.Keeper, k stake.Keeper, am auth.AccountMapper) sim return false }) require.True(t, pool.LooseTokens.RoundInt64() == loose.Int64(), "expected loose tokens to equal total steak held by accounts - pool.LooseTokens: %v, sum of account tokens: %v\nlog: %s", - pool.LooseTokens, loose, log) - // stats["stake/invariant/looseTokens"] += 1 + pool.LooseTokens.RoundInt64(), loose.Int64(), log) // Bonded tokens should equal sum of tokens with bonded validators bonded := sdk.ZeroRat() @@ -54,7 +53,6 @@ func SupplyInvariants(ck bank.Keeper, k stake.Keeper, am auth.AccountMapper) sim return false }) require.True(t, pool.BondedTokens.Equal(bonded), "expected bonded tokens to equal total steak held by bonded validators\nlog: %s", log) - // stats["stake/invariant/bondedTokens"] += 1 // TODO Inflation check on total supply } @@ -68,7 +66,6 @@ func PositivePowerInvariant(k stake.Keeper) simulation.Invariant { require.True(t, validator.GetPower().GT(sdk.ZeroRat()), "validator with non-positive power stored") return false }) - // stats["stake/invariant/positivePower"] += 1 } } diff --git a/x/stake/simulation/msgs.go b/x/stake/simulation/msgs.go index f46881e30..597046107 100644 --- a/x/stake/simulation/msgs.go +++ b/x/stake/simulation/msgs.go @@ -49,7 +49,7 @@ func SimulateMsgCreateValidator(m auth.AccountMapper, k stake.Keeper) simulation } event(fmt.Sprintf("stake/MsgCreateValidator/%v", result.IsOK())) // require.True(t, result.IsOK(), "expected OK result but instead got %v", result) - action = fmt.Sprintf("TestMsgCreateValidator: %s", msg.GetSignBytes()) + action = fmt.Sprintf("TestMsgCreateValidator: ok %v, msg %s", result.IsOK(), msg.GetSignBytes()) return action, nil } } @@ -77,7 +77,7 @@ func SimulateMsgEditValidator(k stake.Keeper) simulation.TestAndRunTx { write() } event(fmt.Sprintf("stake/MsgEditValidator/%v", result.IsOK())) - action = fmt.Sprintf("TestMsgEditValidator: %s", msg.GetSignBytes()) + action = fmt.Sprintf("TestMsgEditValidator: ok %v, msg %s", result.IsOK(), msg.GetSignBytes()) return action, nil } } @@ -109,7 +109,7 @@ func SimulateMsgDelegate(m auth.AccountMapper, k stake.Keeper) simulation.TestAn write() } event(fmt.Sprintf("stake/MsgDelegate/%v", result.IsOK())) - action = fmt.Sprintf("TestMsgDelegate: %s", msg.GetSignBytes()) + action = fmt.Sprintf("TestMsgDelegate: ok %v, msg %s", result.IsOK(), msg.GetSignBytes()) return action, nil } } @@ -141,7 +141,7 @@ func SimulateMsgBeginUnbonding(m auth.AccountMapper, k stake.Keeper) simulation. write() } event(fmt.Sprintf("stake/MsgBeginUnbonding/%v", result.IsOK())) - action = fmt.Sprintf("TestMsgBeginUnbonding: %s", msg.GetSignBytes()) + action = fmt.Sprintf("TestMsgBeginUnbonding: ok %v, msg %s", result.IsOK(), msg.GetSignBytes()) return action, nil } } @@ -164,7 +164,7 @@ func SimulateMsgCompleteUnbonding(k stake.Keeper) simulation.TestAndRunTx { write() } event(fmt.Sprintf("stake/MsgCompleteUnbonding/%v", result.IsOK())) - action = fmt.Sprintf("TestMsgCompleteUnbonding with %s", msg.GetSignBytes()) + action = fmt.Sprintf("TestMsgCompleteUnbonding: ok %v, msg %s", result.IsOK(), msg.GetSignBytes()) return action, nil } } @@ -226,7 +226,7 @@ func SimulateMsgCompleteRedelegate(k stake.Keeper) simulation.TestAndRunTx { write() } event(fmt.Sprintf("stake/MsgCompleteRedelegate/%v", result.IsOK())) - action = fmt.Sprintf("TestMsgCompleteRedelegate with %s", msg.GetSignBytes()) + action = fmt.Sprintf("TestMsgCompleteRedelegate: ok %v, msg %s", result.IsOK(), msg.GetSignBytes()) return action, nil } } From cea2be6107abbf9b277e44d16a91c654c3b3ddc8 Mon Sep 17 00:00:00 2001 From: Christopher Goes Date: Wed, 18 Jul 2018 09:42:18 +0200 Subject: [PATCH 30/39] Fix loose tokens invariant --- types/stake.go | 1 + x/stake/simulation/invariants.go | 16 ++++++++++------ x/stake/types/validator.go | 1 + 3 files changed, 12 insertions(+), 6 deletions(-) diff --git a/types/stake.go b/types/stake.go index eb3f66082..e48577c0b 100644 --- a/types/stake.go +++ b/types/stake.go @@ -43,6 +43,7 @@ type Validator interface { GetOwner() AccAddress // owner AccAddress to receive/return validators coins GetPubKey() crypto.PubKey // validation pubkey GetPower() Rat // validation power + GetTokens() Rat // validation tokens GetDelegatorShares() Rat // Total out standing delegator shares GetBondHeight() int64 // height in which the validator became active } diff --git a/x/stake/simulation/invariants.go b/x/stake/simulation/invariants.go index 92dd317d0..e4869693c 100644 --- a/x/stake/simulation/invariants.go +++ b/x/stake/simulation/invariants.go @@ -30,8 +30,8 @@ func SupplyInvariants(ck bank.Keeper, k stake.Keeper, am auth.AccountMapper) sim ctx := app.NewContext(false, abci.Header{}) pool := k.GetPool(ctx) - // Loose tokens should equal coin supply plus unbonding delegations loose := sdk.ZeroInt() + bonded := sdk.ZeroRat() am.IterateAccounts(ctx, func(acc auth.Account) bool { loose = loose.Add(acc.GetCoins().AmountOf("steak")) return false @@ -40,18 +40,22 @@ func SupplyInvariants(ck bank.Keeper, k stake.Keeper, am auth.AccountMapper) sim loose = loose.Add(ubd.Balance.Amount) return false }) - require.True(t, pool.LooseTokens.RoundInt64() == loose.Int64(), "expected loose tokens to equal total steak held by accounts - pool.LooseTokens: %v, sum of account tokens: %v\nlog: %s", - pool.LooseTokens.RoundInt64(), loose.Int64(), log) - - // Bonded tokens should equal sum of tokens with bonded validators - bonded := sdk.ZeroRat() k.IterateValidators(ctx, func(_ int64, validator sdk.Validator) bool { switch validator.GetStatus() { case sdk.Bonded: bonded = bonded.Add(validator.GetPower()) + case sdk.Unbonding: + case sdk.Unbonded: + loose = loose.Add(validator.GetTokens().RoundInt()) } return false }) + + // Loose tokens should equal coin supply plus unbonding delegations plus tokens on unbonded validators + require.True(t, pool.LooseTokens.RoundInt64() == loose.Int64(), "expected loose tokens to equal total steak held by accounts - pool.LooseTokens: %v, sum of account tokens: %v\nlog: %s", + pool.LooseTokens.RoundInt64(), loose.Int64(), log) + + // Bonded tokens should equal sum of tokens with bonded validators require.True(t, pool.BondedTokens.Equal(bonded), "expected bonded tokens to equal total steak held by bonded validators\nlog: %s", log) // TODO Inflation check on total supply diff --git a/x/stake/types/validator.go b/x/stake/types/validator.go index ed109830f..ee1cb5a44 100644 --- a/x/stake/types/validator.go +++ b/x/stake/types/validator.go @@ -406,6 +406,7 @@ func (v Validator) GetStatus() sdk.BondStatus { return v.Status } func (v Validator) GetOwner() sdk.AccAddress { return v.Owner } func (v Validator) GetPubKey() crypto.PubKey { return v.PubKey } func (v Validator) GetPower() sdk.Rat { return v.BondedTokens() } +func (v Validator) GetTokens() sdk.Rat { return v.Tokens } func (v Validator) GetDelegatorShares() sdk.Rat { return v.DelegatorShares } func (v Validator) GetBondHeight() int64 { return v.BondHeight } From dc14eef639a0bfc61b113dba6d36a2b1aecc3892 Mon Sep 17 00:00:00 2001 From: Christopher Goes Date: Wed, 18 Jul 2018 09:47:55 +0200 Subject: [PATCH 31/39] Clarify 'nop', linter fix --- examples/democoin/mock/validator.go | 5 +++++ x/stake/simulation/msgs.go | 8 ++++---- 2 files changed, 9 insertions(+), 4 deletions(-) diff --git a/examples/democoin/mock/validator.go b/examples/democoin/mock/validator.go index 84d41d488..c3d01b170 100644 --- a/examples/democoin/mock/validator.go +++ b/examples/democoin/mock/validator.go @@ -28,6 +28,11 @@ func (v Validator) GetPubKey() crypto.PubKey { return nil } +// Implements sdk.Validator +func (v Validator) GetTokens() sdk.Rat { + return sdk.ZeroRat() +} + // Implements sdk.Validator func (v Validator) GetPower() sdk.Rat { return v.Power diff --git a/x/stake/simulation/msgs.go b/x/stake/simulation/msgs.go index 597046107..41bda5dd6 100644 --- a/x/stake/simulation/msgs.go +++ b/x/stake/simulation/msgs.go @@ -32,7 +32,7 @@ func SimulateMsgCreateValidator(m auth.AccountMapper, k stake.Keeper) simulation amount = sdk.NewInt(int64(r.Intn(int(amount.Int64())))) } if amount.Equal(sdk.ZeroInt()) { - return "nop", nil + return "no-operation", nil } msg := stake.MsgCreateValidator{ Description: description, @@ -95,7 +95,7 @@ func SimulateMsgDelegate(m auth.AccountMapper, k stake.Keeper) simulation.TestAn amount = sdk.NewInt(int64(r.Intn(int(amount.Int64())))) } if amount.Equal(sdk.ZeroInt()) { - return "nop", nil + return "no-operation", nil } msg := stake.MsgDelegate{ DelegatorAddr: delegatorAddress, @@ -127,7 +127,7 @@ func SimulateMsgBeginUnbonding(m auth.AccountMapper, k stake.Keeper) simulation. amount = sdk.NewInt(int64(r.Intn(int(amount.Int64())))) } if amount.Equal(sdk.ZeroInt()) { - return "nop", nil + return "no-operation", nil } msg := stake.MsgBeginUnbonding{ DelegatorAddr: delegatorAddress, @@ -185,7 +185,7 @@ func SimulateMsgBeginRedelegate(m auth.AccountMapper, k stake.Keeper) simulation amount = sdk.NewInt(int64(r.Intn(int(amount.Int64())))) } if amount.Equal(sdk.ZeroInt()) { - return "nop", nil + return "no-operation", nil } msg := stake.MsgBeginRedelegate{ DelegatorAddr: delegatorAddress, From dcbd13c392245538ec0602e75963657e6883ef7c Mon Sep 17 00:00:00 2001 From: Christopher Goes Date: Wed, 18 Jul 2018 09:54:41 +0200 Subject: [PATCH 32/39] Environment variables --- Makefile | 6 +++++- cmd/gaia/app/sim_test.go | 33 +++++++++++++++++++++++++++------ 2 files changed, 32 insertions(+), 7 deletions(-) diff --git a/Makefile b/Makefile index 02fb21715..b3b5851d6 100644 --- a/Makefile +++ b/Makefile @@ -116,7 +116,11 @@ test_race: test_sim: @echo "Running individual module simulations." @go test $(PACKAGES_SIMTEST) -v - @echo "Running full Gaia simulation. This may take several minutes. Set the environment variable 'GAIA_SIMULATION_SEED' to run with a constant seed." + @echo "Running full Gaia simulation. This may take several minutes." + @echo "Set the environment variable 'GAIA_SIMULATION_SEED' to run with a constant seed." + @echo "Set the environment variable 'GAIA_SIMULATION_KEYS' to run with the specified number of keys." + @echo "Set the environment variable 'GAIA_SIMULATION_BLOCKS' to run with the specified number of blocks." + @echo "Set the environment variable 'GAIA_SIMULATION_BLOCK_SIZE' to run with the specified block size (operations per block)." @GAIA_SIMULATION_ENABLED=1 go test ./cmd/gaia/app -run TestFullGaiaSimulation -v test_cover: diff --git a/cmd/gaia/app/sim_test.go b/cmd/gaia/app/sim_test.go index 745824f00..89b1b54aa 100644 --- a/cmd/gaia/app/sim_test.go +++ b/cmd/gaia/app/sim_test.go @@ -21,9 +21,9 @@ import ( ) const ( - NumKeys = 10 - NumBlocks = 100 - BlockSize = 100 + defaultNumKeys = 10 + defaultNumBlocks = 100 + defaultBlockSize = 100 simulationEnvEnable = "GAIA_SIMULATION_ENABLED" simulationEnvSeed = "GAIA_SIMULATION_SEED" @@ -82,6 +82,27 @@ func TestFullGaiaSimulation(t *testing.T) { seed = time.Now().UnixNano() } + keys := defaultNumKeys + envKeys := os.Getenv(simulationEnvKeys) + if envKeys != "" { + keys, err = strconv.Atoi(envKeys) + require.Nil(t, err) + } + + blocks := defaultNumBlocks + envBlocks := os.Getenv(simulationEnvBlocks) + if envBlocks != "" { + blocks, err = strconv.Atoi(envBlocks) + require.Nil(t, err) + } + + blockSize := defaultBlockSize + envBlockSize := os.Getenv(simulationEnvBlockSize) + if envBlockSize != "" { + blockSize, err = strconv.Atoi(envBlockSize) + require.Nil(t, err) + } + // Run randomized simulation simulation.SimulateFromSeed( t, app.BaseApp, appStateFn, seed, @@ -100,9 +121,9 @@ func TestFullGaiaSimulation(t *testing.T) { banksim.NonnegativeBalanceInvariant(app.accountMapper), stakesim.AllInvariants(app.coinKeeper, app.stakeKeeper, app.accountMapper), }, - NumKeys, - NumBlocks, - BlockSize, + keys, + blocks, + blockSize, ) } From 2c0cd73fc59fd66119239f6a44507383ae9a6d41 Mon Sep 17 00:00:00 2001 From: Christopher Goes Date: Wed, 18 Jul 2018 09:58:17 +0200 Subject: [PATCH 33/39] Remove old randomized pool testing, redundant --- x/stake/types/test_utils.go | 173 -------------------------------- x/stake/types/validator_test.go | 62 ------------ 2 files changed, 235 deletions(-) diff --git a/x/stake/types/test_utils.go b/x/stake/types/test_utils.go index 104eae3d3..1ab72119e 100644 --- a/x/stake/types/test_utils.go +++ b/x/stake/types/test_utils.go @@ -1,12 +1,7 @@ package types import ( - "fmt" - "math/rand" - "testing" - sdk "github.com/cosmos/cosmos-sdk/types" - "github.com/stretchr/testify/require" "github.com/tendermint/tendermint/crypto" ) @@ -21,171 +16,3 @@ var ( emptyAddr sdk.AccAddress emptyPubkey crypto.PubKey ) - -// Operation reflects any operation that transforms staking state. It takes in -// a RNG instance, pool, validator and returns an updated pool, updated -// validator, delta tokens, and descriptive message. -type Operation func(r *rand.Rand, pool Pool, c Validator) (Pool, Validator, sdk.Rat, string) - -// OpBondOrUnbond implements an operation that bonds or unbonds a validator -// depending on current status. -// nolint: unparam -// TODO split up into multiple operations -func OpBondOrUnbond(r *rand.Rand, pool Pool, validator Validator) (Pool, Validator, sdk.Rat, string) { - var ( - msg string - newStatus sdk.BondStatus - ) - - if validator.Status == sdk.Bonded { - msg = fmt.Sprintf("sdk.Unbonded previously bonded validator %#v", validator) - newStatus = sdk.Unbonded - - } else if validator.Status == sdk.Unbonded { - msg = fmt.Sprintf("sdk.Bonded previously bonded validator %#v", validator) - newStatus = sdk.Bonded - } - - validator, pool = validator.UpdateStatus(pool, newStatus) - return pool, validator, sdk.ZeroRat(), msg -} - -// OpAddTokens implements an operation that adds a random number of tokens to a -// validator. -func OpAddTokens(r *rand.Rand, pool Pool, validator Validator) (Pool, Validator, sdk.Rat, string) { - msg := fmt.Sprintf("validator %#v", validator) - - tokens := int64(r.Int31n(1000)) - validator, pool, _ = validator.AddTokensFromDel(pool, tokens) - msg = fmt.Sprintf("Added %d tokens to %s", tokens, msg) - - // Tokens are removed so for accounting must be negative - return pool, validator, sdk.NewRat(-1 * tokens), msg -} - -// OpRemoveShares implements an operation that removes a random number of -// delegatorshares from a validator. -func OpRemoveShares(r *rand.Rand, pool Pool, validator Validator) (Pool, Validator, sdk.Rat, string) { - var shares sdk.Rat - for { - shares = sdk.NewRat(int64(r.Int31n(1000))) - if shares.LT(validator.DelegatorShares) { - break - } - } - - msg := fmt.Sprintf("Removed %v shares from validator %#v", shares, validator) - - validator, pool, tokens := validator.RemoveDelShares(pool, shares) - return pool, validator, tokens, msg -} - -// RandomOperation returns a random staking operation. -func RandomOperation(r *rand.Rand) Operation { - operations := []Operation{ - OpBondOrUnbond, - OpAddTokens, - OpRemoveShares, - } - r.Shuffle(len(operations), func(i, j int) { - operations[i], operations[j] = operations[j], operations[i] - }) - - return operations[0] -} - -// AssertInvariants ensures invariants that should always be true are true. -// nolint: unparam -func AssertInvariants(t *testing.T, msg string, - pOrig Pool, cOrig []Validator, pMod Pool, vMods []Validator) { - - // total tokens conserved - require.True(t, - pOrig.LooseTokens.Add(pOrig.BondedTokens).Equal( - pMod.LooseTokens.Add(pMod.BondedTokens)), - "Tokens not conserved - msg: %v\n, pOrig.BondedTokens: %v, pOrig.LooseTokens: %v, pMod.BondedTokens: %v, pMod.LooseTokens: %v", - msg, - pOrig.BondedTokens, pOrig.LooseTokens, - pMod.BondedTokens, pMod.LooseTokens) - - // Nonnegative bonded tokens - require.False(t, pMod.BondedTokens.LT(sdk.ZeroRat()), - "Negative bonded shares - msg: %v\npOrig: %v\npMod: %v\n", - msg, pOrig, pMod) - - // Nonnegative loose tokens - require.False(t, pMod.LooseTokens.LT(sdk.ZeroRat()), - "Negative unbonded shares - msg: %v\npOrig: %v\npMod: %v\n", - msg, pOrig, pMod) - - for _, vMod := range vMods { - // Nonnegative ex rate - require.False(t, vMod.DelegatorShareExRate().LT(sdk.ZeroRat()), - "Applying operation \"%s\" resulted in negative validator.DelegatorShareExRate(): %v (validator.Owner: %s)", - msg, - vMod.DelegatorShareExRate(), - vMod.Owner, - ) - - // Nonnegative poolShares - require.False(t, vMod.BondedTokens().LT(sdk.ZeroRat()), - "Applying operation \"%s\" resulted in negative validator.BondedTokens(): %#v", - msg, - vMod, - ) - - // Nonnegative delShares - require.False(t, vMod.DelegatorShares.LT(sdk.ZeroRat()), - "Applying operation \"%s\" resulted in negative validator.DelegatorShares: %#v", - msg, - vMod, - ) - } -} - -// TODO: refactor this random setup - -// randomValidator generates a random validator. -// nolint: unparam -func randomValidator(r *rand.Rand, i int) Validator { - - tokens := sdk.NewRat(int64(r.Int31n(10000))) - delShares := sdk.NewRat(int64(r.Int31n(10000))) - - // TODO add more options here - status := sdk.Bonded - if r.Float64() > float64(0.5) { - status = sdk.Unbonded - } - - validator := NewValidator(addr1, pk1, Description{}) - validator.Status = status - validator.Tokens = tokens - validator.DelegatorShares = delShares - - return validator -} - -// RandomSetup generates a random staking state. -func RandomSetup(r *rand.Rand, numValidators int) (Pool, []Validator) { - pool := InitialPool() - pool.LooseTokens = sdk.NewRat(100000) - - validators := make([]Validator, numValidators) - for i := 0; i < numValidators; i++ { - validator := randomValidator(r, i) - - switch validator.Status { - case sdk.Bonded: - pool.BondedTokens = pool.BondedTokens.Add(validator.Tokens) - case sdk.Unbonded, sdk.Unbonding: - pool.LooseTokens = pool.LooseTokens.Add(validator.Tokens) - default: - panic("improper use of RandomSetup") - } - - validators[i] = validator - } - - return pool, validators -} diff --git a/x/stake/types/validator_test.go b/x/stake/types/validator_test.go index 8d97cbce7..5e0252015 100644 --- a/x/stake/types/validator_test.go +++ b/x/stake/types/validator_test.go @@ -2,7 +2,6 @@ package types import ( "fmt" - "math/rand" "testing" sdk "github.com/cosmos/cosmos-sdk/types" @@ -234,67 +233,6 @@ func TestPossibleOverflow(t *testing.T) { msg, newValidator.DelegatorShareExRate()) } -// run random operations in a random order on a random single-validator state, assert invariants hold -func TestSingleValidatorIntegrationInvariants(t *testing.T) { - r := rand.New(rand.NewSource(41)) - - for i := 0; i < 10; i++ { - poolOrig, validatorsOrig := RandomSetup(r, 1) - require.Equal(t, 1, len(validatorsOrig)) - - // sanity check - AssertInvariants(t, "no operation", - poolOrig, validatorsOrig, - poolOrig, validatorsOrig) - - for j := 0; j < 5; j++ { - poolMod, validatorMod, _, msg := RandomOperation(r)(r, poolOrig, validatorsOrig[0]) - - validatorsMod := make([]Validator, len(validatorsOrig)) - copy(validatorsMod[:], validatorsOrig[:]) - require.Equal(t, 1, len(validatorsOrig), "j %v", j) - require.Equal(t, 1, len(validatorsMod), "j %v", j) - validatorsMod[0] = validatorMod - - AssertInvariants(t, msg, - poolOrig, validatorsOrig, - poolMod, validatorsMod) - - poolOrig = poolMod - validatorsOrig = validatorsMod - } - } -} - -// run random operations in a random order on a random multi-validator state, assert invariants hold -func TestMultiValidatorIntegrationInvariants(t *testing.T) { - r := rand.New(rand.NewSource(42)) - - for i := 0; i < 10; i++ { - poolOrig, validatorsOrig := RandomSetup(r, 100) - - AssertInvariants(t, "no operation", - poolOrig, validatorsOrig, - poolOrig, validatorsOrig) - - for j := 0; j < 5; j++ { - index := int(r.Int31n(int32(len(validatorsOrig)))) - poolMod, validatorMod, _, msg := RandomOperation(r)(r, poolOrig, validatorsOrig[index]) - validatorsMod := make([]Validator, len(validatorsOrig)) - copy(validatorsMod[:], validatorsOrig[:]) - validatorsMod[index] = validatorMod - - AssertInvariants(t, msg, - poolOrig, validatorsOrig, - poolMod, validatorsMod) - - poolOrig = poolMod - validatorsOrig = validatorsMod - - } - } -} - func TestHumanReadableString(t *testing.T) { validator := NewValidator(addr1, pk1, Description{}) From 16d4e0773d16aad388b0191ca3597f62102a83f8 Mon Sep 17 00:00:00 2001 From: Christopher Goes Date: Wed, 18 Jul 2018 10:04:53 +0200 Subject: [PATCH 34/39] Update changelog --- CHANGELOG.md | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index ef203bbd0..63a539f9b 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -6,6 +6,10 @@ BREAKING CHANGES FEATURES * [lcd] Can now query governance proposals by ProposalStatus +* [x/mock/simulation] Randomized simulation framework + * Modules specify invariants and operations, preferably in an x/[module]/simulation package + * Modules can test random combinations of their own operations + * Applications can integrate operations and invariants from modules together for an integrated simulation IMPROVEMENTS * [baseapp] Allow any alphanumeric character in route From aa525418e152c55cb63a8e8af6d3ada484739af3 Mon Sep 17 00:00:00 2001 From: Joon Date: Wed, 18 Jul 2018 23:39:40 -0700 Subject: [PATCH 35/39] Merge PR #1373: Initialization of POS chain --- PENDING.md | 1 + baseapp/baseapp.go | 2 +- client/lcd/lcd_test.go | 21 +++++-------- cmd/gaia/app/app.go | 6 ++-- cmd/gaia/cmd/gaiadebug/hack.go | 6 ++-- server/init.go | 17 +++++----- x/gov/test_common.go | 6 ++-- x/slashing/app_test.go | 7 +++-- x/slashing/test_common.go | 2 +- x/stake/app_test.go | 6 ++-- x/stake/genesis.go | 19 +++++++++--- x/stake/genesis_test.go | 57 ++++++++++++++++++++++++++++++++-- x/stake/keeper/test_common.go | 4 +-- 13 files changed, 109 insertions(+), 45 deletions(-) diff --git a/PENDING.md b/PENDING.md index f297e6a4a..16ca3adc9 100644 --- a/PENDING.md +++ b/PENDING.md @@ -6,6 +6,7 @@ BREAKING CHANGES FEATURES * [lcd] Can now query governance proposals by ProposalStatus +* [baseapp] Initialize validator set on ResponseInitChain * Added support for cosmos-sdk-cli tool under cosmos-sdk/cmd * This allows SDK users to init a new project repository with a single command. diff --git a/baseapp/baseapp.go b/baseapp/baseapp.go index da75591a2..ca5e8fd97 100644 --- a/baseapp/baseapp.go +++ b/baseapp/baseapp.go @@ -290,7 +290,7 @@ func (app *BaseApp) InitChain(req abci.RequestInitChain) (res abci.ResponseInitC if app.initChainer == nil { return } - app.initChainer(app.deliverState.ctx, req) // no error + res = app.initChainer(app.deliverState.ctx, req) // NOTE: we don't commit, but BeginBlock for block 1 // starts from this deliverState diff --git a/client/lcd/lcd_test.go b/client/lcd/lcd_test.go index f5b2d263e..2de92575a 100644 --- a/client/lcd/lcd_test.go +++ b/client/lcd/lcd_test.go @@ -358,25 +358,20 @@ func TestTxs(t *testing.T) { } func TestValidatorsQuery(t *testing.T) { - cleanup, pks, port := InitializeTestLCD(t, 2, []sdk.AccAddress{}) + cleanup, pks, port := InitializeTestLCD(t, 1, []sdk.AccAddress{}) defer cleanup() - require.Equal(t, 2, len(pks)) + require.Equal(t, 1, len(pks)) validators := getValidators(t, port) - require.Equal(t, len(validators), 2) + require.Equal(t, len(validators), 1) // make sure all the validators were found (order unknown because sorted by owner addr) - foundVal1, foundVal2 := false, false - pk1Bech := sdk.MustBech32ifyValPub(pks[0]) - pk2Bech := sdk.MustBech32ifyValPub(pks[1]) - if validators[0].PubKey == pk1Bech || validators[1].PubKey == pk1Bech { - foundVal1 = true + foundVal := false + pkBech := sdk.MustBech32ifyValPub(pks[0]) + if validators[0].PubKey == pkBech { + foundVal = true } - if validators[0].PubKey == pk2Bech || validators[1].PubKey == pk2Bech { - foundVal2 = true - } - require.True(t, foundVal1, "pk1Bech %v, owner1 %v, owner2 %v", pk1Bech, validators[0].Owner, validators[1].Owner) - require.True(t, foundVal2, "pk2Bech %v, owner1 %v, owner2 %v", pk2Bech, validators[0].Owner, validators[1].Owner) + require.True(t, foundVal, "pkBech %v, owner %v", pkBech, validators[0].Owner) } func TestBonding(t *testing.T) { diff --git a/cmd/gaia/app/app.go b/cmd/gaia/app/app.go index 7b0f85e30..ab8a27e6c 100644 --- a/cmd/gaia/app/app.go +++ b/cmd/gaia/app/app.go @@ -173,7 +173,7 @@ func (app *GaiaApp) initChainer(ctx sdk.Context, req abci.RequestInitChain) abci } // load the initial stake information - err = stake.InitGenesis(ctx, app.stakeKeeper, genesisState.StakeData) + validators, err := stake.InitGenesis(ctx, app.stakeKeeper, genesisState.StakeData) if err != nil { panic(err) // TODO https://github.com/cosmos/cosmos-sdk/issues/468 // return sdk.ErrGenesisParse("").TraceCause(err, "") @@ -181,7 +181,9 @@ func (app *GaiaApp) initChainer(ctx sdk.Context, req abci.RequestInitChain) abci gov.InitGenesis(ctx, app.govKeeper, gov.DefaultGenesisState()) - return abci.ResponseInitChain{} + return abci.ResponseInitChain{ + Validators: validators, + } } // export the state of gaia for a genesis file diff --git a/cmd/gaia/cmd/gaiadebug/hack.go b/cmd/gaia/cmd/gaiadebug/hack.go index 11d2dfa73..aa3bc939e 100644 --- a/cmd/gaia/cmd/gaiadebug/hack.go +++ b/cmd/gaia/cmd/gaiadebug/hack.go @@ -249,10 +249,12 @@ func (app *GaiaApp) initChainer(ctx sdk.Context, req abci.RequestInitChain) abci } // load the initial stake information - err = stake.InitGenesis(ctx, app.stakeKeeper, genesisState.StakeData) + validators, err := stake.InitGenesis(ctx, app.stakeKeeper, genesisState.StakeData) if err != nil { panic(err) // TODO https://github.com/cosmos/cosmos-sdk/issues/468 // return sdk.ErrGenesisParse("").TraceCause(err, "") } - return abci.ResponseInitChain{} + return abci.ResponseInitChain{ + Validators: validators, + } } diff --git a/server/init.go b/server/init.go index 39f3d0b7f..a644c0c1a 100644 --- a/server/init.go +++ b/server/init.go @@ -48,10 +48,9 @@ var ( // genesis piece structure for creating combined genesis type GenesisTx struct { - NodeID string `json:"node_id"` - IP string `json:"ip"` - Validator tmtypes.GenesisValidator `json:"validator"` - AppGenTx json.RawMessage `json:"app_gen_tx"` + NodeID string `json:"node_id"` + IP string `json:"ip"` + AppGenTx json.RawMessage `json:"app_gen_tx"` } // Storage for init command input parameters @@ -121,16 +120,15 @@ func gentxWithConfig(cdc *wire.Codec, appInit AppInit, config *cfg.Config, genTx nodeID := string(nodeKey.ID()) pubKey := readOrCreatePrivValidator(config) - appGenTx, cliPrint, validator, err := appInit.AppGenTx(cdc, pubKey, genTxConfig) + appGenTx, cliPrint, _, err := appInit.AppGenTx(cdc, pubKey, genTxConfig) if err != nil { return } tx := GenesisTx{ - NodeID: nodeID, - IP: genTxConfig.IP, - Validator: validator, - AppGenTx: appGenTx, + NodeID: nodeID, + IP: genTxConfig.IP, + AppGenTx: appGenTx, } bz, err := wire.MarshalJSONIndent(cdc, tx) if err != nil { @@ -312,7 +310,6 @@ func processGenTxs(genTxsDir string, cdc *wire.Codec) ( genTx := genTxs[nodeID] // combine some stuff - validators = append(validators, genTx.Validator) appGenTxs = append(appGenTxs, genTx.AppGenTx) // Add a persistent peer diff --git a/x/gov/test_common.go b/x/gov/test_common.go index 5567e4697..7ea85fc72 100644 --- a/x/gov/test_common.go +++ b/x/gov/test_common.go @@ -61,12 +61,14 @@ func getInitChainer(mapp *mock.App, keeper Keeper, stakeKeeper stake.Keeper) sdk stakeGenesis := stake.DefaultGenesisState() stakeGenesis.Pool.LooseTokens = sdk.NewRat(100000) - err := stake.InitGenesis(ctx, stakeKeeper, stakeGenesis) + validators, err := stake.InitGenesis(ctx, stakeKeeper, stakeGenesis) if err != nil { panic(err) } InitGenesis(ctx, keeper, DefaultGenesisState()) - return abci.ResponseInitChain{} + return abci.ResponseInitChain{ + Validators: validators, + } } } diff --git a/x/slashing/app_test.go b/x/slashing/app_test.go index f5f8c98f8..8151c69da 100644 --- a/x/slashing/app_test.go +++ b/x/slashing/app_test.go @@ -59,11 +59,14 @@ func getInitChainer(mapp *mock.App, keeper stake.Keeper) sdk.InitChainer { mapp.InitChainer(ctx, req) stakeGenesis := stake.DefaultGenesisState() stakeGenesis.Pool.LooseTokens = sdk.NewRat(100000) - err := stake.InitGenesis(ctx, keeper, stakeGenesis) + validators, err := stake.InitGenesis(ctx, keeper, stakeGenesis) if err != nil { panic(err) } - return abci.ResponseInitChain{} + + return abci.ResponseInitChain{ + Validators: validators, + } } } diff --git a/x/slashing/test_common.go b/x/slashing/test_common.go index 190932995..142093c76 100644 --- a/x/slashing/test_common.go +++ b/x/slashing/test_common.go @@ -70,7 +70,7 @@ func createTestInput(t *testing.T) (sdk.Context, bank.Keeper, stake.Keeper, para genesis.Pool.LooseTokens = sdk.NewRat(initCoins.MulRaw(int64(len(addrs))).Int64()) - err = stake.InitGenesis(ctx, sk, genesis) + _, err = stake.InitGenesis(ctx, sk, genesis) require.Nil(t, err) for _, addr := range addrs { diff --git a/x/stake/app_test.go b/x/stake/app_test.go index 606369cd6..b1490edef 100644 --- a/x/stake/app_test.go +++ b/x/stake/app_test.go @@ -65,12 +65,14 @@ func getInitChainer(mapp *mock.App, keeper Keeper) sdk.InitChainer { stakeGenesis := DefaultGenesisState() stakeGenesis.Pool.LooseTokens = sdk.NewRat(100000) - err := InitGenesis(ctx, keeper, stakeGenesis) + validators, err := InitGenesis(ctx, keeper, stakeGenesis) if err != nil { panic(err) } - return abci.ResponseInitChain{} + return abci.ResponseInitChain{ + Validators: validators, + } } } diff --git a/x/stake/genesis.go b/x/stake/genesis.go index b4ed80e51..ad3ac0af5 100644 --- a/x/stake/genesis.go +++ b/x/stake/genesis.go @@ -1,10 +1,12 @@ package stake import ( + abci "github.com/tendermint/tendermint/abci/types" + tmtypes "github.com/tendermint/tendermint/types" + sdk "github.com/cosmos/cosmos-sdk/types" "github.com/cosmos/cosmos-sdk/x/stake/types" "github.com/pkg/errors" - tmtypes "github.com/tendermint/tendermint/types" ) // InitGenesis sets the pool and parameters for the provided keeper and @@ -12,7 +14,8 @@ import ( // validator in the keeper along with manually setting the indexes. In // addition, it also sets any delegations found in data. Finally, it updates // the bonded validators. -func InitGenesis(ctx sdk.Context, keeper Keeper, data types.GenesisState) error { +// Returns final validator set after applying all declaration and delegations +func InitGenesis(ctx sdk.Context, keeper Keeper, data types.GenesisState) (res []abci.Validator, err error) { keeper.SetPool(ctx, data.Pool) keeper.SetNewParams(ctx, data.Params) keeper.InitIntraTxCounter(ctx) @@ -21,10 +24,10 @@ func InitGenesis(ctx sdk.Context, keeper Keeper, data types.GenesisState) error keeper.SetValidator(ctx, validator) if validator.Tokens.IsZero() { - return errors.Errorf("genesis validator cannot have zero pool shares, validator: %v", validator) + return res, errors.Errorf("genesis validator cannot have zero pool shares, validator: %v", validator) } if validator.DelegatorShares.IsZero() { - return errors.Errorf("genesis validator cannot have zero delegator shares, validator: %v", validator) + return res, errors.Errorf("genesis validator cannot have zero delegator shares, validator: %v", validator) } // Manually set indexes for the first time @@ -43,7 +46,13 @@ func InitGenesis(ctx sdk.Context, keeper Keeper, data types.GenesisState) error } keeper.UpdateBondedValidatorsFull(ctx) - return nil + + vals := keeper.GetValidatorsBonded(ctx) + res = make([]abci.Validator, len(vals)) + for i, val := range vals { + res[i] = sdk.ABCIValidator(val) + } + return } // WriteGenesis returns a GenesisState for a given context and keeper. The diff --git a/x/stake/genesis_test.go b/x/stake/genesis_test.go index e27c7fed2..ec061ea3c 100644 --- a/x/stake/genesis_test.go +++ b/x/stake/genesis_test.go @@ -1,10 +1,13 @@ package stake import ( + "fmt" "testing" "github.com/stretchr/testify/require" + abci "github.com/tendermint/tendermint/abci/types" + sdk "github.com/cosmos/cosmos-sdk/types" keep "github.com/cosmos/cosmos-sdk/x/stake/keeper" "github.com/cosmos/cosmos-sdk/x/stake/types" @@ -14,7 +17,7 @@ func TestInitGenesis(t *testing.T) { ctx, _, keeper := keep.CreateTestInput(t, false, 1000) pool := keeper.GetPool(ctx) - pool.LooseTokens = sdk.NewRat(2) + pool.BondedTokens = sdk.NewRat(2) params := keeper.GetParams(ctx) var delegations []Delegation @@ -24,17 +27,19 @@ func TestInitGenesis(t *testing.T) { NewValidator(keep.Addrs[1], keep.PKs[1], Description{Moniker: "bloop"}), } genesisState := types.NewGenesisState(pool, params, validators, delegations) - err := InitGenesis(ctx, keeper, genesisState) + _, err := InitGenesis(ctx, keeper, genesisState) require.Error(t, err) // initialize the validators + validators[0].Status = sdk.Bonded validators[0].Tokens = sdk.OneRat() validators[0].DelegatorShares = sdk.OneRat() + validators[1].Status = sdk.Bonded validators[1].Tokens = sdk.OneRat() validators[1].DelegatorShares = sdk.OneRat() genesisState = types.NewGenesisState(pool, params, validators, delegations) - err = InitGenesis(ctx, keeper, genesisState) + vals, err := InitGenesis(ctx, keeper, genesisState) require.NoError(t, err) // now make sure the validators are bonded @@ -45,4 +50,50 @@ func TestInitGenesis(t *testing.T) { resVal, found = keeper.GetValidator(ctx, keep.Addrs[1]) require.True(t, found) require.Equal(t, sdk.Bonded, resVal.Status) + + abcivals := make([]abci.Validator, len(vals)) + for i, val := range validators { + abcivals[i] = sdk.ABCIValidator(val) + } + + require.Equal(t, abcivals, vals) +} + +func TestInitGenesisLargeValidatorSet(t *testing.T) { + size := 200 + require.True(t, size > 100) + + ctx, _, keeper := keep.CreateTestInput(t, false, 1000) + + // Assigning 2 to the first 100 vals, 1 to the rest + pool := keeper.GetPool(ctx) + pool.BondedTokens = sdk.NewRat(int64(200 + (size - 100))) + + params := keeper.GetParams(ctx) + delegations := []Delegation{} + validators := make([]Validator, size) + + for i := range validators { + validators[i] = NewValidator(keep.Addrs[i], keep.PKs[i], Description{Moniker: fmt.Sprintf("#%d", i)}) + + validators[i].Status = sdk.Bonded + if i < 100 { + validators[i].Tokens = sdk.NewRat(2) + validators[i].DelegatorShares = sdk.NewRat(2) + } else { + validators[i].Tokens = sdk.OneRat() + validators[i].DelegatorShares = sdk.OneRat() + } + } + + genesisState := types.NewGenesisState(pool, params, validators, delegations) + vals, err := InitGenesis(ctx, keeper, genesisState) + require.NoError(t, err) + + abcivals := make([]abci.Validator, 100) + for i, val := range validators[:100] { + abcivals[i] = sdk.ABCIValidator(val) + } + + require.Equal(t, abcivals, vals) } diff --git a/x/stake/keeper/test_common.go b/x/stake/keeper/test_common.go index db7e382d5..19cf4d27c 100644 --- a/x/stake/keeper/test_common.go +++ b/x/stake/keeper/test_common.go @@ -23,8 +23,8 @@ import ( // dummy addresses used for testing var ( - Addrs = createTestAddrs(100) - PKs = createTestPubKeys(100) + Addrs = createTestAddrs(500) + PKs = createTestPubKeys(500) emptyAddr sdk.AccAddress emptyPubkey crypto.PubKey From 1e5a7993ed6cb73c4b903f9c010d711b47f76611 Mon Sep 17 00:00:00 2001 From: Christopher Goes Date: Thu, 19 Jul 2018 08:40:46 +0200 Subject: [PATCH 36/39] Environment variables => flags --- Makefile | 10 +++---- cmd/gaia/app/sim_test.go | 65 +++++++++++----------------------------- 2 files changed, 23 insertions(+), 52 deletions(-) diff --git a/Makefile b/Makefile index 9cba9cb61..6459f08e8 100644 --- a/Makefile +++ b/Makefile @@ -132,11 +132,11 @@ test_sim: @echo "Running individual module simulations." @go test $(PACKAGES_SIMTEST) -v @echo "Running full Gaia simulation. This may take several minutes." - @echo "Set the environment variable 'GAIA_SIMULATION_SEED' to run with a constant seed." - @echo "Set the environment variable 'GAIA_SIMULATION_KEYS' to run with the specified number of keys." - @echo "Set the environment variable 'GAIA_SIMULATION_BLOCKS' to run with the specified number of blocks." - @echo "Set the environment variable 'GAIA_SIMULATION_BLOCK_SIZE' to run with the specified block size (operations per block)." - @GAIA_SIMULATION_ENABLED=1 go test ./cmd/gaia/app -run TestFullGaiaSimulation -v + @echo "Pass the flag 'SimulationSeed' to run with a constant seed." + @echo "Pass the flag 'SimulationNumKeys' to run with the specified number of keys." + @echo "Pass the flag 'SimulationNumBlocks' to run with the specified number of blocks." + @echo "Pass the flag 'SimulationBlockSize' to run with the specified block size (operations per block)." + @go test ./cmd/gaia/app -run TestFullGaiaSimulation -SimulationEnabled=true -SimulationBlockSize=200 -v test_cover: @bash tests/test_cover.sh diff --git a/cmd/gaia/app/sim_test.go b/cmd/gaia/app/sim_test.go index 89b1b54aa..f0bea1e17 100644 --- a/cmd/gaia/app/sim_test.go +++ b/cmd/gaia/app/sim_test.go @@ -2,11 +2,9 @@ package app import ( "encoding/json" + "flag" "math/rand" - "os" - "strconv" "testing" - "time" "github.com/stretchr/testify/require" @@ -20,18 +18,22 @@ import ( stakesim "github.com/cosmos/cosmos-sdk/x/stake/simulation" ) -const ( - defaultNumKeys = 10 - defaultNumBlocks = 100 - defaultBlockSize = 100 - - simulationEnvEnable = "GAIA_SIMULATION_ENABLED" - simulationEnvSeed = "GAIA_SIMULATION_SEED" - simulationEnvKeys = "GAIA_SIMULATION_KEYS" - simulationEnvBlocks = "GAIA_SIMULATION_BLOCKS" - simulationEnvBlockSize = "GAIA_SIMULATION_BLOCK_SIZE" +var ( + seed int64 + numKeys int + numBlocks int + blockSize int + enabled bool ) +func init() { + flag.Int64Var(&seed, "SimulationSeed", 42, "Simulation random seed") + flag.IntVar(&numKeys, "SimulationNumKeys", 10, "Number of keys (accounts)") + flag.IntVar(&numBlocks, "SimulationNumBlocks", 100, "Number of blocks") + flag.IntVar(&blockSize, "SimulationBlockSize", 100, "Operations per block") + flag.BoolVar(&enabled, "SimulationEnabled", false, "Enable the simulation") +} + func appStateFn(r *rand.Rand, accs []sdk.AccAddress) json.RawMessage { var genesisAccounts []GenesisAccount @@ -62,7 +64,7 @@ func appStateFn(r *rand.Rand, accs []sdk.AccAddress) json.RawMessage { } func TestFullGaiaSimulation(t *testing.T) { - if os.Getenv(simulationEnvEnable) == "" { + if !enabled { t.Skip("Skipping Gaia simulation") } @@ -72,37 +74,6 @@ func TestFullGaiaSimulation(t *testing.T) { app := NewGaiaApp(logger, db, nil) require.Equal(t, "GaiaApp", app.Name()) - var seed int64 - var err error - envSeed := os.Getenv(simulationEnvSeed) - if envSeed != "" { - seed, err = strconv.ParseInt(envSeed, 10, 64) - require.Nil(t, err) - } else { - seed = time.Now().UnixNano() - } - - keys := defaultNumKeys - envKeys := os.Getenv(simulationEnvKeys) - if envKeys != "" { - keys, err = strconv.Atoi(envKeys) - require.Nil(t, err) - } - - blocks := defaultNumBlocks - envBlocks := os.Getenv(simulationEnvBlocks) - if envBlocks != "" { - blocks, err = strconv.Atoi(envBlocks) - require.Nil(t, err) - } - - blockSize := defaultBlockSize - envBlockSize := os.Getenv(simulationEnvBlockSize) - if envBlockSize != "" { - blockSize, err = strconv.Atoi(envBlockSize) - require.Nil(t, err) - } - // Run randomized simulation simulation.SimulateFromSeed( t, app.BaseApp, appStateFn, seed, @@ -121,8 +92,8 @@ func TestFullGaiaSimulation(t *testing.T) { banksim.NonnegativeBalanceInvariant(app.accountMapper), stakesim.AllInvariants(app.coinKeeper, app.stakeKeeper, app.accountMapper), }, - keys, - blocks, + numKeys, + numBlocks, blockSize, ) From ee29e10068e6bdf19c9b6e7cf9001794574a7954 Mon Sep 17 00:00:00 2001 From: Christopher Goes Date: Thu, 19 Jul 2018 08:47:54 +0200 Subject: [PATCH 37/39] RandomKey, RandomAmount --- x/bank/simulation/msgs.go | 6 +++--- x/mock/simulation/util.go | 16 ++++++++++++++++ x/stake/simulation/msgs.go | 38 +++++++++++++++++++------------------- 3 files changed, 38 insertions(+), 22 deletions(-) diff --git a/x/bank/simulation/msgs.go b/x/bank/simulation/msgs.go index 553d000db..3a7248875 100644 --- a/x/bank/simulation/msgs.go +++ b/x/bank/simulation/msgs.go @@ -22,15 +22,15 @@ import ( // accounts already exist. func TestAndRunSingleInputMsgSend(mapper auth.AccountMapper) simulation.TestAndRunTx { return func(t *testing.T, r *rand.Rand, app *baseapp.BaseApp, ctx sdk.Context, keys []crypto.PrivKey, log string, event func(string)) (action string, err sdk.Error) { - fromKey := keys[r.Intn(len(keys))] + fromKey := simulation.RandomKey(r, keys) fromAddr := sdk.AccAddress(fromKey.PubKey().Address()) - toKey := keys[r.Intn(len(keys))] + toKey := simulation.RandomKey(r, keys) // Disallow sending money to yourself for { if !fromKey.Equals(toKey) { break } - toKey = keys[r.Intn(len(keys))] + toKey = simulation.RandomKey(r, keys) } toAddr := sdk.AccAddress(toKey.PubKey().Address()) initFromCoins := mapper.GetAccount(ctx, fromAddr).GetCoins() diff --git a/x/mock/simulation/util.go b/x/mock/simulation/util.go index 8fdf5021e..14227a1ae 100644 --- a/x/mock/simulation/util.go +++ b/x/mock/simulation/util.go @@ -3,6 +3,10 @@ package simulation import ( "fmt" "math/rand" + + crypto "github.com/tendermint/tendermint/crypto" + + sdk "github.com/cosmos/cosmos-sdk/types" ) // shamelessly copied from https://stackoverflow.com/questions/22892120/how-to-generate-a-random-string-of-a-fixed-length-in-golang#31832326 @@ -38,3 +42,15 @@ func DisplayEvents(events map[string]uint) { // TODO fmt.Printf("Events: %v\n", events) } + +// Pick a random key from an array +func RandomKey(r *rand.Rand, keys []crypto.PrivKey) crypto.PrivKey { + return keys[r.Intn( + len(keys), + )] +} + +// Generate a random amount +func RandomAmount(r *rand.Rand, max sdk.Int) sdk.Int { + return sdk.NewInt(int64(r.Intn(int(max.Int64())))) +} diff --git a/x/stake/simulation/msgs.go b/x/stake/simulation/msgs.go index 41bda5dd6..87324eed7 100644 --- a/x/stake/simulation/msgs.go +++ b/x/stake/simulation/msgs.go @@ -24,12 +24,12 @@ func SimulateMsgCreateValidator(m auth.AccountMapper, k stake.Keeper) simulation description := stake.Description{ Moniker: simulation.RandStringOfLength(r, 10), } - key := keys[r.Intn(len(keys))] + key := simulation.RandomKey(r, keys) pubkey := key.PubKey() address := sdk.AccAddress(pubkey.Address()) amount := m.GetAccount(ctx, address).GetCoins().AmountOf(denom) if amount.GT(sdk.ZeroInt()) { - amount = sdk.NewInt(int64(r.Intn(int(amount.Int64())))) + amount = simulation.RandomAmount(r, amount) } if amount.Equal(sdk.ZeroInt()) { return "no-operation", nil @@ -63,7 +63,7 @@ func SimulateMsgEditValidator(k stake.Keeper) simulation.TestAndRunTx { Website: simulation.RandStringOfLength(r, 10), Details: simulation.RandStringOfLength(r, 10), } - key := keys[r.Intn(len(keys))] + key := simulation.RandomKey(r, keys) pubkey := key.PubKey() address := sdk.AccAddress(pubkey.Address()) msg := stake.MsgEditValidator{ @@ -86,13 +86,13 @@ func SimulateMsgEditValidator(k stake.Keeper) simulation.TestAndRunTx { func SimulateMsgDelegate(m auth.AccountMapper, k stake.Keeper) simulation.TestAndRunTx { return func(t *testing.T, r *rand.Rand, app *baseapp.BaseApp, ctx sdk.Context, keys []crypto.PrivKey, log string, event func(string)) (action string, err sdk.Error) { denom := k.GetParams(ctx).BondDenom - validatorKey := keys[r.Intn(len(keys))] + validatorKey := simulation.RandomKey(r, keys) validatorAddress := sdk.AccAddress(validatorKey.PubKey().Address()) - delegatorKey := keys[r.Intn(len(keys))] + delegatorKey := simulation.RandomKey(r, keys) delegatorAddress := sdk.AccAddress(delegatorKey.PubKey().Address()) amount := m.GetAccount(ctx, delegatorAddress).GetCoins().AmountOf(denom) if amount.GT(sdk.ZeroInt()) { - amount = sdk.NewInt(int64(r.Intn(int(amount.Int64())))) + amount = simulation.RandomAmount(r, amount) } if amount.Equal(sdk.ZeroInt()) { return "no-operation", nil @@ -118,13 +118,13 @@ func SimulateMsgDelegate(m auth.AccountMapper, k stake.Keeper) simulation.TestAn func SimulateMsgBeginUnbonding(m auth.AccountMapper, k stake.Keeper) simulation.TestAndRunTx { return func(t *testing.T, r *rand.Rand, app *baseapp.BaseApp, ctx sdk.Context, keys []crypto.PrivKey, log string, event func(string)) (action string, err sdk.Error) { denom := k.GetParams(ctx).BondDenom - validatorKey := keys[r.Intn(len(keys))] + validatorKey := simulation.RandomKey(r, keys) validatorAddress := sdk.AccAddress(validatorKey.PubKey().Address()) - delegatorKey := keys[r.Intn(len(keys))] + delegatorKey := simulation.RandomKey(r, keys) delegatorAddress := sdk.AccAddress(delegatorKey.PubKey().Address()) amount := m.GetAccount(ctx, delegatorAddress).GetCoins().AmountOf(denom) if amount.GT(sdk.ZeroInt()) { - amount = sdk.NewInt(int64(r.Intn(int(amount.Int64())))) + amount = simulation.RandomAmount(r, amount) } if amount.Equal(sdk.ZeroInt()) { return "no-operation", nil @@ -149,9 +149,9 @@ func SimulateMsgBeginUnbonding(m auth.AccountMapper, k stake.Keeper) simulation. // SimulateMsgCompleteUnbonding func SimulateMsgCompleteUnbonding(k stake.Keeper) simulation.TestAndRunTx { return func(t *testing.T, r *rand.Rand, app *baseapp.BaseApp, ctx sdk.Context, keys []crypto.PrivKey, log string, event func(string)) (action string, err sdk.Error) { - validatorKey := keys[r.Intn(len(keys))] + validatorKey := simulation.RandomKey(r, keys) validatorAddress := sdk.AccAddress(validatorKey.PubKey().Address()) - delegatorKey := keys[r.Intn(len(keys))] + delegatorKey := simulation.RandomKey(r, keys) delegatorAddress := sdk.AccAddress(delegatorKey.PubKey().Address()) msg := stake.MsgCompleteUnbonding{ DelegatorAddr: delegatorAddress, @@ -173,16 +173,16 @@ func SimulateMsgCompleteUnbonding(k stake.Keeper) simulation.TestAndRunTx { func SimulateMsgBeginRedelegate(m auth.AccountMapper, k stake.Keeper) simulation.TestAndRunTx { return func(t *testing.T, r *rand.Rand, app *baseapp.BaseApp, ctx sdk.Context, keys []crypto.PrivKey, log string, event func(string)) (action string, err sdk.Error) { denom := k.GetParams(ctx).BondDenom - sourceValidatorKey := keys[r.Intn(len(keys))] + sourceValidatorKey := simulation.RandomKey(r, keys) sourceValidatorAddress := sdk.AccAddress(sourceValidatorKey.PubKey().Address()) - destValidatorKey := keys[r.Intn(len(keys))] + destValidatorKey := simulation.RandomKey(r, keys) destValidatorAddress := sdk.AccAddress(destValidatorKey.PubKey().Address()) - delegatorKey := keys[r.Intn(len(keys))] + delegatorKey := simulation.RandomKey(r, keys) delegatorAddress := sdk.AccAddress(delegatorKey.PubKey().Address()) // TODO amount := m.GetAccount(ctx, delegatorAddress).GetCoins().AmountOf(denom) if amount.GT(sdk.ZeroInt()) { - amount = sdk.NewInt(int64(r.Intn(int(amount.Int64())))) + amount = simulation.RandomAmount(r, amount) } if amount.Equal(sdk.ZeroInt()) { return "no-operation", nil @@ -208,11 +208,11 @@ func SimulateMsgBeginRedelegate(m auth.AccountMapper, k stake.Keeper) simulation // SimulateMsgCompleteRedelegate func SimulateMsgCompleteRedelegate(k stake.Keeper) simulation.TestAndRunTx { return func(t *testing.T, r *rand.Rand, app *baseapp.BaseApp, ctx sdk.Context, keys []crypto.PrivKey, log string, event func(string)) (action string, err sdk.Error) { - validatorSrcKey := keys[r.Intn(len(keys))] + validatorSrcKey := simulation.RandomKey(r, keys) validatorSrcAddress := sdk.AccAddress(validatorSrcKey.PubKey().Address()) - validatorDstKey := keys[r.Intn(len(keys))] + validatorDstKey := simulation.RandomKey(r, keys) validatorDstAddress := sdk.AccAddress(validatorDstKey.PubKey().Address()) - delegatorKey := keys[r.Intn(len(keys))] + delegatorKey := simulation.RandomKey(r, keys) delegatorAddress := sdk.AccAddress(delegatorKey.PubKey().Address()) msg := stake.MsgCompleteRedelegate{ DelegatorAddr: delegatorAddress, @@ -240,7 +240,7 @@ func Setup(mapp *mock.App, k stake.Keeper) simulation.RandSetup { denom := params.BondDenom loose := sdk.ZeroInt() mapp.AccountMapper.IterateAccounts(ctx, func(acc auth.Account) bool { - balance := sdk.NewInt(int64(r.Intn(1000000))) + balance := simulation.RandomAmount(r, sdk.NewInt(1000000)) acc.SetCoins(acc.GetCoins().Plus(sdk.Coins{sdk.NewIntCoin(denom, balance)})) mapp.AccountMapper.SetAccount(ctx, acc) loose = loose.Add(balance) From d2f70ec8af58581563f86bab5301f4d344d1c195 Mon Sep 17 00:00:00 2001 From: Rigel Date: Thu, 19 Jul 2018 02:53:12 -0400 Subject: [PATCH 38/39] Merge PR #1748: CLI use --from consistently --- PENDING.md | 12 +++++++++++ cmd/gaia/cli_test/cli_test.go | 28 ++++++++++++++++++------ docs/sdk/clients.md | 14 ++++++------ docs/sdk/gaiacli.md | 14 ++++++------ x/gov/client/cli/tx.go | 32 ++++++++++++---------------- x/slashing/client/cli/tx.go | 4 ++-- x/stake/client/cli/tx.go | 40 ++++++++++++----------------------- 7 files changed, 77 insertions(+), 67 deletions(-) diff --git a/PENDING.md b/PENDING.md index 16ca3adc9..2160dd80c 100644 --- a/PENDING.md +++ b/PENDING.md @@ -3,6 +3,18 @@ BREAKING CHANGES * [baseapp] Msgs are no longer run on CheckTx, removed `ctx.IsCheckTx()` * [x/stake] Fixed the period check for the inflation calculation +* \#1606 The following CLI commands have been switched to use `--from` + * `gaiacli stake create-validator --address-validator` + * `gaiacli stake edit-validator --address-validator` + * `gaiacli stake delegate --address-delegator` + * `gaiacli stake unbond begin --address-delegator` + * `gaiacli stake unbond complete --address-delegator` + * `gaiacli stake redelegate begin --address-delegator` + * `gaiacli stake redelegate complete --address-delegator` + * `gaiacli stake unrevoke [validator-address]` + * `gaiacli gov submit-proposal --proposer` + * `gaiacli gov deposit --depositer` + * `gaiacli gov vote --voter` FEATURES * [lcd] Can now query governance proposals by ProposalStatus diff --git a/cmd/gaia/cli_test/cli_test.go b/cmd/gaia/cli_test/cli_test.go index 650021d31..beac34097 100644 --- a/cmd/gaia/cli_test/cli_test.go +++ b/cmd/gaia/cli_test/cli_test.go @@ -118,7 +118,6 @@ func TestGaiaCLICreateValidator(t *testing.T) { // create validator cvStr := fmt.Sprintf("gaiacli stake create-validator %v", flags) cvStr += fmt.Sprintf(" --from=%s", "bar") - cvStr += fmt.Sprintf(" --address-validator=%s", barAddr) cvStr += fmt.Sprintf(" --pubkey=%s", barCeshPubKey) cvStr += fmt.Sprintf(" --amount=%v", "2steak") cvStr += fmt.Sprintf(" --moniker=%v", "bar-vally") @@ -137,7 +136,6 @@ func TestGaiaCLICreateValidator(t *testing.T) { unbondStr := fmt.Sprintf("gaiacli stake unbond begin %v", flags) unbondStr += fmt.Sprintf(" --from=%s", "bar") unbondStr += fmt.Sprintf(" --address-validator=%s", barAddr) - unbondStr += fmt.Sprintf(" --address-delegator=%s", barAddr) unbondStr += fmt.Sprintf(" --shares-amount=%v", "1") success := executeWrite(t, unbondStr, pass) @@ -176,7 +174,15 @@ func TestGaiaCLISubmitProposal(t *testing.T) { fooAcc := executeGetAccount(t, fmt.Sprintf("gaiacli account %s %v", fooAddr, flags)) require.Equal(t, int64(50), fooAcc.GetCoins().AmountOf("steak").Int64()) - executeWrite(t, fmt.Sprintf("gaiacli gov submit-proposal %v --proposer=%s --deposit=5steak --type=Text --title=Test --description=test --from=foo", flags, fooAddr), pass) + // unbond a single share + spStr := fmt.Sprintf("gaiacli gov submit-proposal %v", flags) + spStr += fmt.Sprintf(" --from=%s", "foo") + spStr += fmt.Sprintf(" --deposit=%s", "5steak") + spStr += fmt.Sprintf(" --type=%s", "Text") + spStr += fmt.Sprintf(" --title=%s", "Test") + spStr += fmt.Sprintf(" --description=%s", "test") + + executeWrite(t, spStr, pass) tests.WaitForNextNBlocksTM(2, port) fooAcc = executeGetAccount(t, fmt.Sprintf("gaiacli account %s %v", fooAddr, flags)) @@ -186,7 +192,12 @@ func TestGaiaCLISubmitProposal(t *testing.T) { require.Equal(t, int64(1), proposal1.GetProposalID()) require.Equal(t, gov.StatusDepositPeriod, proposal1.GetStatus()) - executeWrite(t, fmt.Sprintf("gaiacli gov deposit %v --depositer=%s --deposit=10steak --proposalID=1 --from=foo", flags, fooAddr), pass) + depositStr := fmt.Sprintf("gaiacli gov deposit %v", flags) + depositStr += fmt.Sprintf(" --from=%s", "foo") + depositStr += fmt.Sprintf(" --deposit=%s", "10steak") + depositStr += fmt.Sprintf(" --proposalID=%s", "1") + + executeWrite(t, depositStr, pass) tests.WaitForNextNBlocksTM(2, port) fooAcc = executeGetAccount(t, fmt.Sprintf("gaiacli account %s %v", fooAddr, flags)) @@ -195,10 +206,15 @@ func TestGaiaCLISubmitProposal(t *testing.T) { require.Equal(t, int64(1), proposal1.GetProposalID()) require.Equal(t, gov.StatusVotingPeriod, proposal1.GetStatus()) - executeWrite(t, fmt.Sprintf("gaiacli gov vote %v --proposalID=1 --voter=%s --option=Yes --from=foo", flags, fooAddr), pass) + voteStr := fmt.Sprintf("gaiacli gov vote %v", flags) + voteStr += fmt.Sprintf(" --from=%s", "foo") + voteStr += fmt.Sprintf(" --proposalID=%s", "1") + voteStr += fmt.Sprintf(" --option=%s", "Yes") + + executeWrite(t, voteStr, pass) tests.WaitForNextNBlocksTM(2, port) - vote := executeGetVote(t, fmt.Sprintf("gaiacli gov query-vote --proposalID=1 --voter=%s --output=json %v", fooAddr, flags)) + vote := executeGetVote(t, fmt.Sprintf("gaiacli gov query-vote --proposalID=1 --voter=%s --output=json %v", fooAddr, flags)) require.Equal(t, int64(1), vote.ProposalID) require.Equal(t, gov.OptionYes, vote.Option) } diff --git a/docs/sdk/clients.md b/docs/sdk/clients.md index 9fa015908..0767745e5 100644 --- a/docs/sdk/clients.md +++ b/docs/sdk/clients.md @@ -119,9 +119,8 @@ On the testnet, we delegate `steak` instead of `atom`. Here's how you can bond t ```bash gaiacli stake delegate \ --amount=10steak \ - --address-delegator= \ --address-validator=$(gaiad tendermint show_validator) \ - --name= \ + --from= \ --chain-id=gaia-6002 ``` @@ -136,15 +135,16 @@ While tokens are bonded, they are pooled with all the other bonded tokens in the If for any reason the validator misbehaves, or you want to unbond a certain amount of tokens, use this following command. You can unbond a specific amount of`shares`\(eg:`12.1`\) or all of them \(`MAX`\). ```bash -gaiacli stake unbond \ - --address-delegator= \ +gaiacli stake unbond begin \ --address-validator=$(gaiad tendermint show_validator) \ - --shares=MAX \ - --name= \ + --shares-percent=1 \ + --from= \ --chain-id=gaia-6002 ``` -You can check your balance and your stake delegation to see that the unbonding went through successfully. +Later you must use the `gaiacli stake unbond complete` command to finish +unbonding at which point you can can check your balance and your stake +delegation to see that the unbonding went through successfully. ```bash gaiacli account diff --git a/docs/sdk/gaiacli.md b/docs/sdk/gaiacli.md index f42bfd145..cd4271e42 100644 --- a/docs/sdk/gaiacli.md +++ b/docs/sdk/gaiacli.md @@ -108,9 +108,8 @@ On the testnet, we delegate `steak` instead of `atom`. Here's how you can bond t ```bash gaiacli stake delegate \ --amount=10steak \ - --address-delegator= \ --address-validator=$(gaiad tendermint show_validator) \ - --name= \ + --from= \ --chain-id=gaia-6002 ``` @@ -125,15 +124,16 @@ While tokens are bonded, they are pooled with all the other bonded tokens in the If for any reason the validator misbehaves, or you want to unbond a certain amount of tokens, use this following command. You can unbond a specific amount of`shares`\(eg:`12.1`\) or all of them \(`MAX`\). ```bash -gaiacli stake unbond \ - --address-delegator= \ +gaiacli stake unbond begin \ --address-validator=$(gaiad tendermint show_validator) \ - --shares=MAX \ - --name= \ + --shares-percent=1 \ + --from= \ --chain-id=gaia-6002 ``` -You can check your balance and your stake delegation to see that the unbonding went through successfully. +Later you must use the `gaiacli stake unbond complete` command to finish +unbonding at which point you can can check your balance and your stake +delegation to see that the unbonding went through successfully. ```bash gaiacli account diff --git a/x/gov/client/cli/tx.go b/x/gov/client/cli/tx.go index 88c4b7d17..c1bb62bc7 100644 --- a/x/gov/client/cli/tx.go +++ b/x/gov/client/cli/tx.go @@ -20,8 +20,6 @@ const ( flagDescription = "description" flagProposalType = "type" flagDeposit = "deposit" - flagProposer = "proposer" - flagDepositer = "depositer" flagVoter = "voter" flagOption = "option" ) @@ -32,13 +30,15 @@ func GetCmdSubmitProposal(cdc *wire.Codec) *cobra.Command { Use: "submit-proposal", Short: "Submit a proposal along with an initial deposit", RunE: func(cmd *cobra.Command, args []string) error { + ctx := context.NewCoreContextFromViper().WithDecoder(authcmd.GetAccountDecoder(cdc)) + title := viper.GetString(flagTitle) description := viper.GetString(flagDescription) strProposalType := viper.GetString(flagProposalType) initialDeposit := viper.GetString(flagDeposit) // get the from address from the name flag - from, err := sdk.AccAddressFromBech32(viper.GetString(flagProposer)) + fromAddr, err := ctx.GetFromAddress() if err != nil { return err } @@ -54,7 +54,7 @@ func GetCmdSubmitProposal(cdc *wire.Codec) *cobra.Command { } // create the message - msg := gov.NewMsgSubmitProposal(title, description, proposalType, from, amount) + msg := gov.NewMsgSubmitProposal(title, description, proposalType, fromAddr, amount) err = msg.ValidateBasic() if err != nil { @@ -62,10 +62,8 @@ func GetCmdSubmitProposal(cdc *wire.Codec) *cobra.Command { } // build and sign the transaction, then broadcast to Tendermint - ctx := context.NewCoreContextFromViper().WithDecoder(authcmd.GetAccountDecoder(cdc)) // proposalID must be returned, and it is a part of response ctx.PrintResponse = true - err = ctx.EnsureSignBuildBroadcast(ctx.FromAddressName, []sdk.Msg{msg}, cdc) if err != nil { return err @@ -78,7 +76,6 @@ func GetCmdSubmitProposal(cdc *wire.Codec) *cobra.Command { cmd.Flags().String(flagDescription, "", "description of proposal") cmd.Flags().String(flagProposalType, "", "proposalType of proposal") cmd.Flags().String(flagDeposit, "", "deposit of proposal") - cmd.Flags().String(flagProposer, "", "proposer of proposal") return cmd } @@ -89,8 +86,10 @@ func GetCmdDeposit(cdc *wire.Codec) *cobra.Command { Use: "deposit", Short: "deposit tokens for activing proposal", RunE: func(cmd *cobra.Command, args []string) error { + ctx := context.NewCoreContextFromViper().WithDecoder(authcmd.GetAccountDecoder(cdc)) + // get the from address from the name flag - depositer, err := sdk.AccAddressFromBech32(viper.GetString(flagDepositer)) + depositerAddr, err := ctx.GetFromAddress() if err != nil { return err } @@ -103,7 +102,7 @@ func GetCmdDeposit(cdc *wire.Codec) *cobra.Command { } // create the message - msg := gov.NewMsgDeposit(depositer, proposalID, amount) + msg := gov.NewMsgDeposit(depositerAddr, proposalID, amount) err = msg.ValidateBasic() if err != nil { @@ -111,8 +110,6 @@ func GetCmdDeposit(cdc *wire.Codec) *cobra.Command { } // build and sign the transaction, then broadcast to Tendermint - ctx := context.NewCoreContextFromViper().WithDecoder(authcmd.GetAccountDecoder(cdc)) - err = ctx.EnsureSignBuildBroadcast(ctx.FromAddressName, []sdk.Msg{msg}, cdc) if err != nil { return err @@ -122,7 +119,6 @@ func GetCmdDeposit(cdc *wire.Codec) *cobra.Command { } cmd.Flags().String(flagProposalID, "", "proposalID of proposal depositing on") - cmd.Flags().String(flagDepositer, "", "depositer of deposit") cmd.Flags().String(flagDeposit, "", "amount of deposit") return cmd @@ -134,9 +130,9 @@ func GetCmdVote(cdc *wire.Codec) *cobra.Command { Use: "vote", Short: "vote for an active proposal, options: Yes/No/NoWithVeto/Abstain", RunE: func(cmd *cobra.Command, args []string) error { + ctx := context.NewCoreContextFromViper().WithDecoder(authcmd.GetAccountDecoder(cdc)) - bechVoter := viper.GetString(flagVoter) - voter, err := sdk.AccAddressFromBech32(bechVoter) + voterAddr, err := ctx.GetFromAddress() if err != nil { return err } @@ -151,18 +147,17 @@ func GetCmdVote(cdc *wire.Codec) *cobra.Command { } // create the message - msg := gov.NewMsgVote(voter, proposalID, byteVoteOption) + msg := gov.NewMsgVote(voterAddr, proposalID, byteVoteOption) err = msg.ValidateBasic() if err != nil { return err } - fmt.Printf("Vote[Voter:%s,ProposalID:%d,Option:%s]", bechVoter, msg.ProposalID, msg.Option.String()) + fmt.Printf("Vote[Voter:%s,ProposalID:%d,Option:%s]", + voterAddr.String(), msg.ProposalID, msg.Option.String()) // build and sign the transaction, then broadcast to Tendermint - ctx := context.NewCoreContextFromViper().WithDecoder(authcmd.GetAccountDecoder(cdc)) - err = ctx.EnsureSignBuildBroadcast(ctx.FromAddressName, []sdk.Msg{msg}, cdc) if err != nil { return err @@ -172,7 +167,6 @@ func GetCmdVote(cdc *wire.Codec) *cobra.Command { } cmd.Flags().String(flagProposalID, "", "proposalID of proposal voting on") - cmd.Flags().String(flagVoter, "", "bech32 voter address") cmd.Flags().String(flagOption, "", "vote option {Yes, No, NoWithVeto, Abstain}") return cmd diff --git a/x/slashing/client/cli/tx.go b/x/slashing/client/cli/tx.go index 15458ad1a..ab8911c11 100644 --- a/x/slashing/client/cli/tx.go +++ b/x/slashing/client/cli/tx.go @@ -14,12 +14,12 @@ import ( func GetCmdUnrevoke(cdc *wire.Codec) *cobra.Command { cmd := &cobra.Command{ Use: "unrevoke", - Args: cobra.ExactArgs(1), + Args: cobra.ExactArgs(0), Short: "unrevoke validator previously revoked for downtime", RunE: func(cmd *cobra.Command, args []string) error { ctx := context.NewCoreContextFromViper().WithDecoder(authcmd.GetAccountDecoder(cdc)) - validatorAddr, err := sdk.AccAddressFromBech32(args[0]) + validatorAddr, err := ctx.GetFromAddress() if err != nil { return err } diff --git a/x/stake/client/cli/tx.go b/x/stake/client/cli/tx.go index 72317c82c..e391bad8c 100644 --- a/x/stake/client/cli/tx.go +++ b/x/stake/client/cli/tx.go @@ -28,7 +28,7 @@ func GetCmdCreateValidator(cdc *wire.Codec) *cobra.Command { if err != nil { return err } - validatorAddr, err := sdk.AccAddressFromBech32(viper.GetString(FlagAddressValidator)) + validatorAddr, err := ctx.GetFromAddress() if err != nil { return err } @@ -74,7 +74,6 @@ func GetCmdCreateValidator(cdc *wire.Codec) *cobra.Command { cmd.Flags().AddFlagSet(fsPk) cmd.Flags().AddFlagSet(fsAmount) cmd.Flags().AddFlagSet(fsDescription) - cmd.Flags().AddFlagSet(fsValidator) cmd.Flags().AddFlagSet(fsDelegator) return cmd } @@ -85,8 +84,9 @@ func GetCmdEditValidator(cdc *wire.Codec) *cobra.Command { Use: "edit-validator", Short: "edit and existing validator account", RunE: func(cmd *cobra.Command, args []string) error { + ctx := context.NewCoreContextFromViper().WithDecoder(authcmd.GetAccountDecoder(cdc)) - validatorAddr, err := sdk.AccAddressFromBech32(viper.GetString(FlagAddressValidator)) + validatorAddr, err := ctx.GetFromAddress() if err != nil { return err } @@ -99,8 +99,6 @@ func GetCmdEditValidator(cdc *wire.Codec) *cobra.Command { msg := stake.NewMsgEditValidator(validatorAddr, description) // build and sign the transaction, then broadcast to Tendermint - ctx := context.NewCoreContextFromViper().WithDecoder(authcmd.GetAccountDecoder(cdc)) - err = ctx.EnsureSignBuildBroadcast(ctx.FromAddressName, []sdk.Msg{msg}, cdc) if err != nil { return err @@ -111,7 +109,6 @@ func GetCmdEditValidator(cdc *wire.Codec) *cobra.Command { } cmd.Flags().AddFlagSet(fsDescription) - cmd.Flags().AddFlagSet(fsValidator) return cmd } @@ -121,12 +118,14 @@ func GetCmdDelegate(cdc *wire.Codec) *cobra.Command { Use: "delegate", Short: "delegate liquid tokens to an validator", RunE: func(cmd *cobra.Command, args []string) error { + ctx := context.NewCoreContextFromViper().WithDecoder(authcmd.GetAccountDecoder(cdc)) + amount, err := sdk.ParseCoin(viper.GetString(FlagAmount)) if err != nil { return err } - delegatorAddr, err := sdk.AccAddressFromBech32(viper.GetString(FlagAddressDelegator)) + delegatorAddr, err := ctx.GetFromAddress() if err != nil { return err } @@ -138,8 +137,6 @@ func GetCmdDelegate(cdc *wire.Codec) *cobra.Command { msg := stake.NewMsgDelegate(delegatorAddr, validatorAddr, amount) // build and sign the transaction, then broadcast to Tendermint - ctx := context.NewCoreContextFromViper().WithDecoder(authcmd.GetAccountDecoder(cdc)) - err = ctx.EnsureSignBuildBroadcast(ctx.FromAddressName, []sdk.Msg{msg}, cdc) if err != nil { return err @@ -150,7 +147,6 @@ func GetCmdDelegate(cdc *wire.Codec) *cobra.Command { } cmd.Flags().AddFlagSet(fsAmount) - cmd.Flags().AddFlagSet(fsDelegator) cmd.Flags().AddFlagSet(fsValidator) return cmd } @@ -175,9 +171,10 @@ func GetCmdBeginRedelegate(storeName string, cdc *wire.Codec) *cobra.Command { Use: "begin", Short: "begin redelegation", RunE: func(cmd *cobra.Command, args []string) error { + ctx := context.NewCoreContextFromViper().WithDecoder(authcmd.GetAccountDecoder(cdc)) var err error - delegatorAddr, err := sdk.AccAddressFromBech32(viper.GetString(FlagAddressDelegator)) + delegatorAddr, err := ctx.GetFromAddress() if err != nil { return err } @@ -202,8 +199,6 @@ func GetCmdBeginRedelegate(storeName string, cdc *wire.Codec) *cobra.Command { msg := stake.NewMsgBeginRedelegate(delegatorAddr, validatorSrcAddr, validatorDstAddr, sharesAmount) // build and sign the transaction, then broadcast to Tendermint - ctx := context.NewCoreContextFromViper().WithDecoder(authcmd.GetAccountDecoder(cdc)) - err = ctx.EnsureSignBuildBroadcast(ctx.FromAddressName, []sdk.Msg{msg}, cdc) if err != nil { return err @@ -214,7 +209,6 @@ func GetCmdBeginRedelegate(storeName string, cdc *wire.Codec) *cobra.Command { } cmd.Flags().AddFlagSet(fsShares) - cmd.Flags().AddFlagSet(fsDelegator) cmd.Flags().AddFlagSet(fsRedelegation) return cmd } @@ -266,8 +260,9 @@ func GetCmdCompleteRedelegate(cdc *wire.Codec) *cobra.Command { Use: "complete", Short: "complete redelegation", RunE: func(cmd *cobra.Command, args []string) error { + ctx := context.NewCoreContextFromViper().WithDecoder(authcmd.GetAccountDecoder(cdc)) - delegatorAddr, err := sdk.AccAddressFromBech32(viper.GetString(FlagAddressDelegator)) + delegatorAddr, err := ctx.GetFromAddress() if err != nil { return err } @@ -283,8 +278,6 @@ func GetCmdCompleteRedelegate(cdc *wire.Codec) *cobra.Command { msg := stake.NewMsgCompleteRedelegate(delegatorAddr, validatorSrcAddr, validatorDstAddr) // build and sign the transaction, then broadcast to Tendermint - ctx := context.NewCoreContextFromViper().WithDecoder(authcmd.GetAccountDecoder(cdc)) - err = ctx.EnsureSignBuildBroadcast(ctx.FromAddressName, []sdk.Msg{msg}, cdc) if err != nil { return err @@ -293,7 +286,6 @@ func GetCmdCompleteRedelegate(cdc *wire.Codec) *cobra.Command { return nil }, } - cmd.Flags().AddFlagSet(fsDelegator) cmd.Flags().AddFlagSet(fsRedelegation) return cmd } @@ -318,8 +310,9 @@ func GetCmdBeginUnbonding(storeName string, cdc *wire.Codec) *cobra.Command { Use: "begin", Short: "begin unbonding", RunE: func(cmd *cobra.Command, args []string) error { + ctx := context.NewCoreContextFromViper().WithDecoder(authcmd.GetAccountDecoder(cdc)) - delegatorAddr, err := sdk.AccAddressFromBech32(viper.GetString(FlagAddressDelegator)) + delegatorAddr, err := ctx.GetFromAddress() if err != nil { return err } @@ -340,8 +333,6 @@ func GetCmdBeginUnbonding(storeName string, cdc *wire.Codec) *cobra.Command { msg := stake.NewMsgBeginUnbonding(delegatorAddr, validatorAddr, sharesAmount) // build and sign the transaction, then broadcast to Tendermint - ctx := context.NewCoreContextFromViper().WithDecoder(authcmd.GetAccountDecoder(cdc)) - err = ctx.EnsureSignBuildBroadcast(ctx.FromAddressName, []sdk.Msg{msg}, cdc) if err != nil { return err @@ -352,7 +343,6 @@ func GetCmdBeginUnbonding(storeName string, cdc *wire.Codec) *cobra.Command { } cmd.Flags().AddFlagSet(fsShares) - cmd.Flags().AddFlagSet(fsDelegator) cmd.Flags().AddFlagSet(fsValidator) return cmd } @@ -363,8 +353,9 @@ func GetCmdCompleteUnbonding(cdc *wire.Codec) *cobra.Command { Use: "complete", Short: "complete unbonding", RunE: func(cmd *cobra.Command, args []string) error { + ctx := context.NewCoreContextFromViper().WithDecoder(authcmd.GetAccountDecoder(cdc)) - delegatorAddr, err := sdk.AccAddressFromBech32(viper.GetString(FlagAddressDelegator)) + delegatorAddr, err := ctx.GetFromAddress() if err != nil { return err } @@ -376,8 +367,6 @@ func GetCmdCompleteUnbonding(cdc *wire.Codec) *cobra.Command { msg := stake.NewMsgCompleteUnbonding(delegatorAddr, validatorAddr) // build and sign the transaction, then broadcast to Tendermint - ctx := context.NewCoreContextFromViper().WithDecoder(authcmd.GetAccountDecoder(cdc)) - err = ctx.EnsureSignBuildBroadcast(ctx.FromAddressName, []sdk.Msg{msg}, cdc) if err != nil { return err @@ -386,7 +375,6 @@ func GetCmdCompleteUnbonding(cdc *wire.Codec) *cobra.Command { return nil }, } - cmd.Flags().AddFlagSet(fsDelegator) cmd.Flags().AddFlagSet(fsValidator) return cmd } From 0471598c69a9a79b9205ebe962c5fe816348d41b Mon Sep 17 00:00:00 2001 From: xujiacheng Date: Thu, 19 Jul 2018 19:56:23 +0800 Subject: [PATCH 39/39] fix the bug about turning VoteOption byte to String --- x/gov/proposals.go | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/x/gov/proposals.go b/x/gov/proposals.go index bb6b0aed4..4a07342cb 100644 --- a/x/gov/proposals.go +++ b/x/gov/proposals.go @@ -167,11 +167,11 @@ func (pt *ProposalKind) UnmarshalJSON(data []byte) error { // Turns VoteOption byte to String func (pt ProposalKind) String() string { switch pt { - case 0x00: - return "Text" case 0x01: - return "ParameterChange" + return "Text" case 0x02: + return "ParameterChange" + case 0x03: return "SoftwareUpgrade" default: return ""