Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Attribute module simulation support #348

Merged
merged 11 commits into from
Jun 9, 2021
12 changes: 12 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,19 @@ Ref: https://keepachangelog.com/en/1.0.0/

## Unreleased

### API Breaking

* Redundant account parameter was removed from Attribute module SetAttribute API. [PR 348](https://github.com/provenance-io/provenance/pull/348)

### Bug Fixes

* Attribute module allows removal of orphan attributes, attributes against root names [PR 348](https://github.com/provenance-io/provenance/pull/348)

### Improvements

* Bump `wasmd` to v0.17.0 [#345](https://github.com/provenance-io/provenance/issues/345)
* Attribute module simulation support [#25](https://github.com/provenance-io/provenance/issues/25)


## [v1.4.1](https://github.com/provenance-io/provenance/releases/tag/v1.4.1) - 2021-06-02

Expand Down
4 changes: 2 additions & 2 deletions app/app.go
Original file line number Diff line number Diff line change
Expand Up @@ -481,7 +481,7 @@ func New(
metadata.NewAppModule(appCodec, app.MetadataKeeper, app.AccountKeeper),
marker.NewAppModule(appCodec, app.MarkerKeeper, app.AccountKeeper, app.BankKeeper),
name.NewAppModule(appCodec, app.NameKeeper, app.AccountKeeper, app.BankKeeper),
attribute.NewAppModule(app.AttributeKeeper),
attribute.NewAppModule(appCodec, app.AttributeKeeper, app.AccountKeeper, app.BankKeeper, app.NameKeeper),
wasm.NewAppModule(appCodec, &app.WasmKeeper, app.StakingKeeper),

upgrade.NewAppModule(app.UpgradeKeeper),
Expand Down Expand Up @@ -556,7 +556,7 @@ func New(
metadata.NewAppModule(appCodec, app.MetadataKeeper, app.AccountKeeper),
marker.NewAppModule(appCodec, app.MarkerKeeper, app.AccountKeeper, app.BankKeeper),
name.NewAppModule(appCodec, app.NameKeeper, app.AccountKeeper, app.BankKeeper),
attribute.NewAppModule(app.AttributeKeeper),
attribute.NewAppModule(appCodec, app.AttributeKeeper, app.AccountKeeper, app.BankKeeper, app.NameKeeper),
wasm.NewAppModule(appCodec, &app.WasmKeeper, app.StakingKeeper),

params.NewAppModule(app.ParamsKeeper),
Expand Down
5 changes: 4 additions & 1 deletion app/params/weights.go
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,10 @@ const (
DefaultWeightTextProposal int = 5
DefaultWeightParamChangeProposal int = 5

DefaultWeightMsgBindName int = 5
DefaultWeightMsgBindName int = 10
DefaultWeightMsgDeleteName int = 5
DefaultWeightCreateRootNameProposal int = 5

DefaultWeightMsgDeleteAttribute int = 5
DefaultWeightMsgAddAttribute int = 15
)
1 change: 0 additions & 1 deletion internal/antewrapper/tracing_meter.go
Original file line number Diff line number Diff line change
Expand Up @@ -64,7 +64,6 @@ func (g *tracingGasMeter) ConsumeGas(amount sdkgas.Gas, descriptor string) {
g.calls[descriptor] = cur + 1

telemetry.IncrCounterWithLabels([]string{"tx", "gas", "consumed"}, float32(amount), []metrics.Label{telemetry.NewLabel("purpose", descriptor)})
g.log.Debug(fmt.Sprintf("TracingGasMeter: [%s]: %d", descriptor, amount))

g.base.ConsumeGas(amount, descriptor)
}
Expand Down
13 changes: 10 additions & 3 deletions x/attribute/keeper/keeper.go
Original file line number Diff line number Diff line change
Expand Up @@ -112,7 +112,7 @@ func (k Keeper) IterateRecords(ctx sdk.Context, prefix []byte, handle Handler) e

// Stores an attribute under the given account. The attribute name must resolve to the given owner address.
func (k Keeper) SetAttribute(
ctx sdk.Context, acc sdk.AccAddress, attr types.Attribute, owner sdk.AccAddress,
ctx sdk.Context, attr types.Attribute, owner sdk.AccAddress,
) error {
defer telemetry.MeasureSince(time.Now(), types.ModuleName, "keeper_method", "set")

Expand Down Expand Up @@ -147,7 +147,11 @@ func (k Keeper) SetAttribute(
if err != nil {
return err
}
key := types.AccountAttributeKey(acc, attr)
addr, err := sdk.AccAddressFromBech32(attr.Address)
if err != nil {
return err
}
key := types.AccountAttributeKey(addr, attr)
store := ctx.KVStore(k.storeKey)
store.Set(key, bz)

Expand All @@ -168,7 +172,10 @@ func (k Keeper) DeleteAttribute(ctx sdk.Context, acc sdk.AccAddress, name string
}
// Verify name resolves to owner
if !k.nameKeeper.ResolvesTo(ctx, name, owner) {
return fmt.Errorf("\"%s\" does not resolve to address \"%s\"", name, owner.String())
if k.nameKeeper.NameExists(ctx, name) {
return fmt.Errorf("\"%s\" does not resolve to address \"%s\"", name, owner.String())
}
// else name does not exist (anymore) so we can't enforce permission check on delete here, proceed.
}
// Delete all keys that match the name prefix
store := ctx.KVStore(k.storeKey)
Expand Down
45 changes: 37 additions & 8 deletions x/attribute/keeper/keeper_legacy_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -13,9 +13,10 @@ import (
"github.com/cosmos/cosmos-sdk/crypto/keys/secp256k1"
cryptotypes "github.com/cosmos/cosmos-sdk/crypto/types"
sdk "github.com/cosmos/cosmos-sdk/types"
"github.com/stretchr/testify/suite"

"github.com/provenance-io/provenance/x/attribute/types"
nametypes "github.com/provenance-io/provenance/x/name/types"
"github.com/stretchr/testify/suite"
)

type KeeperLegacyTestSuite struct {
Expand All @@ -31,6 +32,10 @@ type KeeperLegacyTestSuite struct {
pubkey2 cryptotypes.PubKey
user2 string
user2Addr sdk.AccAddress

pubkey3 cryptotypes.PubKey
user3 string
user3Addr sdk.AccAddress
}

func TestKeeperLegacyTestSuite(t *testing.T) {
Expand All @@ -51,6 +56,10 @@ func (s *KeeperLegacyTestSuite) SetupTest() {
s.user2Addr = sdk.AccAddress(s.pubkey2.Address())
s.user2 = s.user2Addr.String()

s.pubkey3 = secp256k1.GenPrivKey().PubKey()
s.user3Addr = sdk.AccAddress(s.pubkey3.Address())
s.user3 = s.user3Addr.String()

var nameData nametypes.GenesisState
nameData.Bindings = append(nameData.Bindings, nametypes.NewNameRecord("attribute", s.user1Addr, false))
nameData.Bindings = append(nameData.Bindings, nametypes.NewNameRecord("old.attribute", s.user1Addr, false))
Expand All @@ -65,6 +74,7 @@ func (s *KeeperLegacyTestSuite) SetupTest() {
params.MaxValueLength = 10
app.AttributeKeeper.SetParams(ctx, params)
s.app.AccountKeeper.SetAccount(s.ctx, s.app.AccountKeeper.NewAccountWithAddress(s.ctx, s.user1Addr))
s.app.AccountKeeper.SetAccount(s.ctx, s.app.AccountKeeper.NewAccountWithAddress(s.ctx, s.user3Addr))

var attributeData types.GenesisState
attributeData.Attributes = append(attributeData.Attributes, types.Attribute{
Expand Down Expand Up @@ -130,19 +140,31 @@ func (s *KeeperLegacyTestSuite) TestSetAttribute() {
Address: s.user1,
AttributeType: types.AttributeType_String,
},
accAddr: s.user2Addr,
accAddr: s.user1Addr,
ownerAddr: s.user2Addr,
wantErr: true,
errorMsg: fmt.Sprintf("no account found for owner address \"%s\"", s.user2),
},
"should fail with owner does not match": {
attr: types.Attribute{
Name: "old.attribute",
Value: []byte("0123456789"),
Address: s.user1,
AttributeType: types.AttributeType_String,
},
accAddr: s.user1Addr,
ownerAddr: s.user3Addr,
wantErr: true,
errorMsg: fmt.Sprintf("\"old.attribute\" does not resolve to address \"%s\"", s.user3),
},
"should fail unable to normalize segment length too short": {
attr: types.Attribute{
Name: "example.cant.normalize.me",
Value: []byte("0123456789"),
Address: s.user1,
AttributeType: types.AttributeType_String,
},
accAddr: s.user2Addr,
accAddr: s.user1Addr,
ownerAddr: s.user2Addr,
wantErr: true,
errorMsg: "unable to normalize attribute name \"example.cant.normalize.me\": segment of name is too short",
Expand All @@ -164,7 +186,7 @@ func (s *KeeperLegacyTestSuite) TestSetAttribute() {
tc := tc

s.Run(n, func() {
err := s.app.AttributeKeeper.SetAttribute(s.ctx, tc.accAddr, tc.attr, tc.ownerAddr)
err := s.app.AttributeKeeper.SetAttribute(s.ctx, tc.attr, tc.ownerAddr)
if tc.wantErr {
s.Error(err)
s.Equal(tc.errorMsg, err.Error())
Expand All @@ -185,19 +207,26 @@ func (s *KeeperLegacyTestSuite) TestDeleteAttribute() {
wantErr bool
errorMsg string
}{
"should fail to delete, cant resolve name wrong owner": {
"should fail to delete, invalid owner account": {
name: "old.example.attribute",
accAddr: s.user1Addr,
ownerAddr: s.user2Addr,
wantErr: true,
errorMsg: fmt.Sprintf("no account found for owner address \"%s\"", s.user2Addr),
},
"should fail to delete, cant resolve unknown name": {
"should process request for non-existant name, fail with no records": {
name: "dne",
accAddr: s.user1Addr,
ownerAddr: s.user1Addr,
wantErr: true,
errorMsg: fmt.Sprintf("\"dne\" does not resolve to address \"%s\"", s.user1Addr),
errorMsg: "no keys deleted with name dne",
},
"should fail to delete attribute, wrong owner address": {
name: "old.attribute",
accAddr: s.user1Addr,
ownerAddr: s.user3Addr,
wantErr: true,
errorMsg: fmt.Sprintf("\"old.attribute\" does not resolve to address \"%s\"", s.user3Addr),
},
"should successfully delete attribute": {
name: "old.attribute",
Expand Down Expand Up @@ -291,7 +320,7 @@ func (s *KeeperLegacyTestSuite) TestIterateRecord() {
Address: s.user1,
AttributeType: types.AttributeType_String,
}
s.app.AttributeKeeper.SetAttribute(s.ctx, s.user1Addr, attr, s.user1Addr)
s.app.AttributeKeeper.SetAttribute(s.ctx, attr, s.user1Addr)

records := []types.Attribute{}
// Callback func that adds records to genesis state.
Expand Down
36 changes: 21 additions & 15 deletions x/attribute/keeper/keeper_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -12,9 +12,10 @@ import (
"github.com/cosmos/cosmos-sdk/crypto/keys/secp256k1"
cryptotypes "github.com/cosmos/cosmos-sdk/crypto/types"
sdk "github.com/cosmos/cosmos-sdk/types"
"github.com/stretchr/testify/suite"

"github.com/provenance-io/provenance/x/attribute/types"
nametypes "github.com/provenance-io/provenance/x/name/types"
"github.com/stretchr/testify/suite"
)

type KeeperTestSuite struct {
Expand Down Expand Up @@ -70,7 +71,6 @@ func (s *KeeperTestSuite) TestSetAttribute() {

cases := map[string]struct {
attr types.Attribute
accAddr sdk.AccAddress
ownerAddr sdk.AccAddress
wantErr bool
errorMsg string
Expand All @@ -82,7 +82,6 @@ func (s *KeeperTestSuite) TestSetAttribute() {
Address: s.user1,
AttributeType: types.AttributeType_String,
},
accAddr: s.user1Addr,
ownerAddr: s.user1Addr,
wantErr: false,
errorMsg: "",
Expand All @@ -94,7 +93,6 @@ func (s *KeeperTestSuite) TestSetAttribute() {
Address: s.user1,
AttributeType: types.AttributeType_String,
},
accAddr: s.user1Addr,
ownerAddr: s.user1Addr,
wantErr: true,
errorMsg: "invalid name: empty",
Expand All @@ -106,7 +104,6 @@ func (s *KeeperTestSuite) TestSetAttribute() {
Address: s.user1,
AttributeType: types.AttributeType_String,
},
accAddr: s.user1Addr,
ownerAddr: s.user1Addr,
wantErr: true,
errorMsg: "attribute value length of 11 exceeds max length 10",
Expand All @@ -118,7 +115,6 @@ func (s *KeeperTestSuite) TestSetAttribute() {
Address: s.user1,
AttributeType: types.AttributeType_String,
},
accAddr: s.user2Addr,
ownerAddr: s.user2Addr,
wantErr: true,
errorMsg: fmt.Sprintf("no account found for owner address \"%s\"", s.user2),
Expand All @@ -130,7 +126,6 @@ func (s *KeeperTestSuite) TestSetAttribute() {
Address: s.user1,
AttributeType: types.AttributeType_String,
},
accAddr: s.user2Addr,
ownerAddr: s.user2Addr,
wantErr: true,
errorMsg: "unable to normalize attribute name \"example.cant.normalize.me\": segment of name is too short",
Expand All @@ -142,7 +137,6 @@ func (s *KeeperTestSuite) TestSetAttribute() {
Address: s.user1,
AttributeType: types.AttributeType_String,
},
accAddr: s.user1Addr,
ownerAddr: s.user1Addr,
wantErr: true,
errorMsg: fmt.Sprintf("\"example.not.found\" does not resolve to address \"%s\"", s.user1),
Expand All @@ -152,7 +146,7 @@ func (s *KeeperTestSuite) TestSetAttribute() {
tc := tc

s.Run(n, func() {
err := s.app.AttributeKeeper.SetAttribute(s.ctx, tc.accAddr, tc.attr, tc.ownerAddr)
err := s.app.AttributeKeeper.SetAttribute(s.ctx, tc.attr, tc.ownerAddr)
if tc.wantErr {
s.Error(err)
s.Equal(tc.errorMsg, err.Error())
Expand All @@ -172,7 +166,12 @@ func (s *KeeperTestSuite) TestDeleteAttribute() {
Address: s.user1,
AttributeType: types.AttributeType_String,
}
s.app.AttributeKeeper.SetAttribute(s.ctx, s.user1Addr, attr, s.user1Addr)
s.NoError(s.app.AttributeKeeper.SetAttribute(s.ctx, attr, s.user1Addr), "should save successfully")

// Create a name, make an attribute under it, then remove the name leaving an orphan attribute.
s.NoError(s.app.NameKeeper.SetNameRecord(s.ctx, "deleted", s.user1Addr, false), "name record should save successfully")
s.NoError(s.app.AttributeKeeper.SetAttribute(s.ctx, types.NewAttribute("deleted", s.user1Addr, types.AttributeType_String, []byte("test")), s.user1Addr), "should save successfully")
s.NoError(s.app.NameKeeper.DeleteRecord(s.ctx, "deleted"), "name record should be removed successfully")

cases := map[string]struct {
name string
Expand All @@ -188,12 +187,19 @@ func (s *KeeperTestSuite) TestDeleteAttribute() {
wantErr: true,
errorMsg: fmt.Sprintf("no account found for owner address \"%s\"", s.user2Addr),
},
"should fail to delete, cant resolve unknown name": {
"no keys will be deleted with unknown name": {
name: "dne",
accAddr: s.user1Addr,
ownerAddr: s.user1Addr,
wantErr: true,
errorMsg: fmt.Sprintf("\"dne\" does not resolve to address \"%s\"", s.user1Addr),
errorMsg: "no keys deleted with name dne",
},
"attribute will be removed without error when name has been removed": {
name: "deleted",
accAddr: s.user1Addr,
ownerAddr: s.user1Addr,
wantErr: false,
errorMsg: "",
},
"should successfully delete attribute": {
name: "example.attribute",
Expand Down Expand Up @@ -231,7 +237,7 @@ func (s *KeeperTestSuite) TestGetAllAttributes() {
Address: s.user1,
AttributeType: types.AttributeType_String,
}
s.app.AttributeKeeper.SetAttribute(s.ctx, s.user1Addr, attr, s.user1Addr)
s.NoError(s.app.AttributeKeeper.SetAttribute(s.ctx, attr, s.user1Addr), "should save successfully")

attributes, err = s.app.AttributeKeeper.GetAllAttributes(s.ctx, s.user1Addr)
s.NoError(err)
Expand All @@ -248,7 +254,7 @@ func (s *KeeperTestSuite) TestGetAttributesByName() {
Address: s.user1,
AttributeType: types.AttributeType_String,
}
s.app.AttributeKeeper.SetAttribute(s.ctx, s.user1Addr, attr, s.user1Addr)
s.NoError(s.app.AttributeKeeper.SetAttribute(s.ctx, attr, s.user1Addr), "should save successfully")

_, err := s.app.AttributeKeeper.GetAttributes(s.ctx, s.user1Addr, "blah")
s.Error(err)
Expand Down Expand Up @@ -290,7 +296,7 @@ func (s *KeeperTestSuite) TestIterateRecord() {
Address: s.user1,
AttributeType: types.AttributeType_String,
}
s.app.AttributeKeeper.SetAttribute(s.ctx, s.user1Addr, attr, s.user1Addr)
s.NoError(s.app.AttributeKeeper.SetAttribute(s.ctx, attr, s.user1Addr), "should save successfully")

records := []types.Attribute{}
// Callback func that adds records to genesis state.
Expand Down
7 changes: 1 addition & 6 deletions x/attribute/keeper/msg_server.go
Original file line number Diff line number Diff line change
Expand Up @@ -32,17 +32,12 @@ func (k msgServer) AddAttribute(goCtx context.Context, msg *types.MsgAddAttribut
Value: msg.Value,
}

accountAddr, err := sdk.AccAddressFromBech32(msg.Account)
if err != nil {
return nil, err
}

ownerAddr, err := sdk.AccAddressFromBech32(msg.Owner)
if err != nil {
return nil, err
}

err = k.Keeper.SetAttribute(ctx, accountAddr, attrib, ownerAddr)
err = k.Keeper.SetAttribute(ctx, attrib, ownerAddr)
if err != nil {
return nil, err
}
Expand Down
Loading