Skip to content

Commit

Permalink
feat(x/data): add basic validation for genesis state (#1395)
Browse files Browse the repository at this point in the history
* feat(x/data): add state validation

* fix lint

* add failing scenarios and validate genesis test

* update changelog

* update changelog

* add basic checks for validate genesis

* feat(x/ecocredit): query all credit holders

* Revert "feat(x/ecocredit): query all credit holders"

This reverts commit 1339dbe.

Co-authored-by: tyler <{ID}+{username}@users.noreply.github.com>
  • Loading branch information
ryanchristo and tyler authored Aug 25, 2022
1 parent 8855cba commit b58cb0f
Show file tree
Hide file tree
Showing 21 changed files with 756 additions and 5 deletions.
20 changes: 16 additions & 4 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,21 +7,28 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0

## [Unreleased]

### General

#### Changed

- [#1244](https://github.com/regen-network/regen-ledger/pull/1244) Update all modules to Cosmos SDK v0.46

### app

#### Added

- [#1340](https://github.com/regen-network/regen-ledger/pull/1340) Add Cosmos SDK group module to stable config
- [#1340](https://github.com/regen-network/regen-ledger/pull/1340) Add Cosmos SDK group module to app configuration

#### Changed

- [#1350](https://github.com/regen-network/regen-ledger/pull/1350) Move application entry point to root directory
- [#1357](https://github.com/regen-network/regen-ledger/pull/1350) Migrate from custom module manager to sdk module manager

#### Removed

- [#1258](https://github.com/regen-network/regen-ledger/pull/1258) Remove group module from experimental config
- [#1350](https://github.com/regen-network/regen-ledger/pull/1350) Remove experimental app configuration
- [#1357](https://github.com/regen-network/regen-ledger/pull/1357) Remove unused RegenApp functions for setting custom keepers.
- [#1357](https://github.com/regen-network/regen-ledger/pull/1357) Remove unused RegenApp functions for setting custom keepers

### types

Expand All @@ -31,7 +38,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0

#### Changed

- [#1357](https://github.com/regen-network/regen-ledger/pull/1357) Refactor fixture factory to use baseApp routing and cosmos sdk module manager
- [#1357](https://github.com/regen-network/regen-ledger/pull/1357) Refactor fixture factory to use baseApp routing and Cosmos SDK module manager
- [#1357](https://github.com/regen-network/regen-ledger/pull/1357) Rename FixtureFactory to Factory to prevent package stuttering


Expand All @@ -40,6 +47,11 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
#### Added

- [#1351](https://github.com/regen-network/regen-ledger/pull/1351) Add `signer` option to transaction messages
- [#1395](https://github.com/regen-network/regen-ledger/pull/1395) Add `DataId` state validation checks
- [#1395](https://github.com/regen-network/regen-ledger/pull/1395) Add `DataAnchor` state validation checks
- [#1395](https://github.com/regen-network/regen-ledger/pull/1395) Add `DataAttestor` state validation checks
- [#1395](https://github.com/regen-network/regen-ledger/pull/1395) Add `Resolver` state validation checks
- [#1395](https://github.com/regen-network/regen-ledger/pull/1395) Add `DataResolver` state validation checks

### x/ecocredit

Expand All @@ -56,7 +68,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
- [#1337](https://github.com/regen-network/regen-ledger/pull/1342) Add `AddAllowedDenom` msg-based gov proposal
- [#1337](https://github.com/regen-network/regen-ledger/pull/1337) Add `AddCreditType` msg-based gov proposal
- [#1346](https://github.com/regen-network/regen-ledger/pull/1346) Add `RemoveAllowedDenom` msg-based gov proposal
- [#1349](https://github.com/regen-network/regen-ledger/pull/1349) Add `UpdateBasketFees` imsg-based gov proposal
- [#1349](https://github.com/regen-network/regen-ledger/pull/1349) Add `UpdateBasketFees` msg-based gov proposal
- [#1351](https://github.com/regen-network/regen-ledger/pull/1351) Add `signer` option to transaction messages
- [#1362](https://github.com/regen-network/regen-ledger/pull/1362) Add `BatchBalance` state validation checks
- [#1362](https://github.com/regen-network/regen-ledger/pull/1362) Add `BatchContract` state validation checks
Expand Down
1 change: 1 addition & 0 deletions x/data/errors.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,4 +8,5 @@ var (
ErrInvalidIRI = sdkerrors.Register(DataCodespace, 2, "invalid IRI")
ErrInvalidMediaExtension = sdkerrors.Register(DataCodespace, 3, "invalid media extension")
ErrUnauthorizedResolverManager = sdkerrors.Register(DataCodespace, 4, "unauthorized resolver manager")
ErrParseFailure = sdkerrors.Register(DataCodespace, 5, "parse error")
)
30 changes: 30 additions & 0 deletions x/data/features/state_data_anchor.feature
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
Feature: DataAnchor

Scenario: a valid data anchor
Given the data anchor
"""
{
"id": "cmVnZW4=",
"timestamp": "2020-01-01T00:00:00Z"
}
"""
When the data anchor is validated
Then expect no error

Scenario: an error is returned if id is empty
Given the data anchor
"""
{}
"""
When the data anchor is validated
Then expect the error "id cannot be empty: parse error"

Scenario: an error is returned if timestamp is empty
Given the data anchor
"""
{
"id": "cmVnZW4="
}
"""
When the data anchor is validated
Then expect the error "timestamp cannot be empty: parse error"
42 changes: 42 additions & 0 deletions x/data/features/state_data_attestor.feature
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
Feature: DataAttestor

Scenario: a valid data attestor
Given the data attestor
"""
{
"id": "cmVnZW4=",
"attestor": "BTZfSbi0JKqguZ/tIAPUIhdAa7Y=",
"timestamp": "2020-01-01T00:00:00Z"
}
"""
When the data attestor is validated
Then expect no error

Scenario: an error is returned if id is empty
Given the data attestor
"""
{}
"""
When the data attestor is validated
Then expect the error "id cannot be empty: parse error"

Scenario: an error is returned if attestor is empty
Given the data attestor
"""
{
"id": "cmVnZW4="
}
"""
When the data attestor is validated
Then expect the error "attestor: empty address string is not allowed: parse error"

Scenario: an error is returned if timestamp is empty
Given the data attestor
"""
{
"id": "cmVnZW4=",
"attestor": "BTZfSbi0JKqguZ/tIAPUIhdAa7Y="
}
"""
When the data attestor is validated
Then expect the error "timestamp cannot be empty: parse error"
41 changes: 41 additions & 0 deletions x/data/features/state_data_id.feature
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
Feature: DataId

Scenario: a valid data id
Given the data id
"""
{
"id": "cmVnZW4=",
"iri": "regen:13toVgf5aZqSVSeJQv562xkkeoe3rr3bJWa29PHVKVf77VAkVMcDvVd.rdf"
}
"""
When the data id is validated
Then expect no error

Scenario: an error is returned if id is empty
Given the data id
"""
{}
"""
When the data id is validated
Then expect the error "id cannot be empty: parse error"

Scenario: an error is returned if iri is empty
Given the data id
"""
{
"id": "cmVnZW4="
}
"""
When the data id is validated
Then expect the error "failed to parse IRI: empty string is not allowed: invalid IRI: parse error"

Scenario: an error is returned if iri is not formatted
Given the data id
"""
{
"id": "cmVnZW4=",
"iri": "foo"
}
"""
When the data id is validated
Then expect the error "failed to parse IRI foo: regen: prefix required: invalid IRI: parse error"
30 changes: 30 additions & 0 deletions x/data/features/state_data_resolver.feature
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
Feature: DataResolver

Scenario: a valid data resolver
Given the data resolver
"""
{
"id": "cmVnZW4=",
"resolver_id": 1
}
"""
When the data resolver is validated
Then expect no error

Scenario: an error is returned if id is empty
Given the data resolver
"""
{}
"""
When the data resolver is validated
Then expect the error "id cannot be empty: parse error"

Scenario: an error is returned if resolver id is empty
Given the data resolver
"""
{
"id": "cmVnZW4="
}
"""
When the data resolver is validated
Then expect the error "resolver id cannot be empty: parse error"
53 changes: 53 additions & 0 deletions x/data/features/state_resolver.feature
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
Feature: Resolver

Scenario: a valid resolver
Given the resolver
"""
{
"id": 1,
"url": "https://regen.network",
"manager": "BTZfSbi0JKqguZ/tIAPUIhdAa7Y="
}
"""
When the resolver is validated
Then expect no error

Scenario: an error is returned if id is empty
Given the resolver
"""
{}
"""
When the resolver is validated
Then expect the error "id cannot be empty: parse error"

Scenario: an error is returned if url is empty
Given the resolver
"""
{
"id": 1
}
"""
When the resolver is validated
Then expect the error "url cannot be empty: parse error"

Scenario: an error is returned if url is not formatted
Given the resolver
"""
{
"id": 1,
"url": "foo"
}
"""
When the resolver is validated
Then expect the error "url: invalid url format: parse error"

Scenario: an error is returned if manager is empty
Given the resolver
"""
{
"id": 1,
"url": "https://regen.network"
}
"""
When the resolver is validated
Then expect the error "manager: empty address string is not allowed: parse error"
87 changes: 87 additions & 0 deletions x/data/genesis/genesis.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,87 @@
package genesis

import (
"encoding/json"

dbm "github.com/tendermint/tm-db"
"google.golang.org/protobuf/proto"

"github.com/cosmos/cosmos-sdk/orm/model/ormdb"
"github.com/cosmos/cosmos-sdk/orm/model/ormtable"
"github.com/cosmos/cosmos-sdk/orm/types/ormjson"

api "github.com/regen-network/regen-ledger/api/regen/data/v1"
"github.com/regen-network/regen-ledger/types/ormutil"
"github.com/regen-network/regen-ledger/x/data"
)

// ValidateGenesis performs basic validation of genesis state.
func ValidateGenesis(jsonData json.RawMessage) error {
db := dbm.NewMemDB()
backend := ormtable.NewBackend(ormtable.BackendOptions{
CommitmentStore: db,
IndexStore: db,
})

moduleDB, err := ormdb.NewModuleDB(&data.ModuleSchema, ormdb.ModuleDBOptions{
JSONValidator: validateMsg,
})
if err != nil {
return err
}

ormCtx := ormtable.WrapContextDefault(backend)

jsonSource, err := ormjson.NewRawMessageSource(jsonData)
if err != nil {
return err
}

err = moduleDB.ImportJSON(ormCtx, jsonSource)
if err != nil {
return err
}

if err := moduleDB.ValidateJSON(jsonSource); err != nil {
return err
}

return nil
}

func validateMsg(m proto.Message) error {
switch m.(type) {
case *api.DataID:
msg := &data.DataID{}
if err := ormutil.PulsarToGogoSlow(m, msg); err != nil {
return err
}
return msg.Validate()
case *api.DataAnchor:
msg := &data.DataAnchor{}
if err := ormutil.PulsarToGogoSlow(m, msg); err != nil {
return err
}
return msg.Validate()
case *api.DataAttestor:
msg := &data.DataAttestor{}
if err := ormutil.PulsarToGogoSlow(m, msg); err != nil {
return err
}
return msg.Validate()
case *api.Resolver:
msg := &data.Resolver{}
if err := ormutil.PulsarToGogoSlow(m, msg); err != nil {
return err
}
return msg.Validate()
case *api.DataResolver:
msg := &data.DataResolver{}
if err := ormutil.PulsarToGogoSlow(m, msg); err != nil {
return err
}
return msg.Validate()
}

return nil
}
Loading

0 comments on commit b58cb0f

Please sign in to comment.