-
Notifications
You must be signed in to change notification settings - Fork 103
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #30 from regen-network/27-claim_module
#27 Create claim module
- Loading branch information
Showing
16 changed files
with
615 additions
and
60 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,30 @@ | ||
package util | ||
|
||
import ( | ||
"github.com/cosmos/cosmos-sdk/codec" | ||
"github.com/cosmos/cosmos-sdk/store" | ||
sdk "github.com/cosmos/cosmos-sdk/types" | ||
"github.com/stretchr/testify/suite" | ||
abci "github.com/tendermint/tendermint/abci/types" | ||
dbm "github.com/tendermint/tendermint/libs/db" | ||
"github.com/tendermint/tendermint/libs/log" | ||
) | ||
|
||
type TestHarness struct { | ||
suite.Suite | ||
Ctx sdk.Context | ||
Cms store.CommitMultiStore | ||
Cdc *codec.Codec | ||
Db *dbm.MemDB | ||
Addr1 sdk.AccAddress | ||
Addr2 sdk.AccAddress | ||
} | ||
|
||
func (s *TestHarness) Setup() { | ||
s.Db = dbm.NewMemDB() | ||
s.Cms = store.NewCommitMultiStore(s.Db) | ||
s.Cdc = codec.New() | ||
s.Ctx = sdk.NewContext(s.Cms, abci.Header{}, false, log.NewNopLogger()) | ||
s.Addr1 = sdk.AccAddress{0, 1, 2, 3, 4, 5, 6, 7, 8} | ||
s.Addr2 = sdk.AccAddress{1, 2, 3, 4, 5, 6, 7, 8, 9} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,126 @@ | ||
package claim_test | ||
|
||
import ( | ||
"bytes" | ||
sdk "github.com/cosmos/cosmos-sdk/types" | ||
"github.com/regen-network/regen-ledger/graph" | ||
"github.com/regen-network/regen-ledger/graph/binary" | ||
"github.com/regen-network/regen-ledger/graph/gen" | ||
"github.com/regen-network/regen-ledger/types" | ||
"github.com/regen-network/regen-ledger/x/claim" | ||
"github.com/regen-network/regen-ledger/x/data" | ||
schema_test "github.com/regen-network/regen-ledger/x/schema/test" | ||
"github.com/stretchr/testify/suite" | ||
"testing" | ||
) | ||
|
||
type Suite struct { | ||
schema_test.Harness | ||
dataKeeper data.Keeper | ||
Keeper claim.Keeper | ||
Handler sdk.Handler | ||
} | ||
|
||
func (s *Suite) SetupTest() { | ||
s.Setup() | ||
data.RegisterCodec(s.Cdc) | ||
claim.RegisterCodec(s.Cdc) | ||
dataKey := sdk.NewKVStoreKey("data") | ||
s.dataKeeper = data.NewKeeper(dataKey, s.Harness.Keeper, s.Cdc) | ||
claimKey := sdk.NewKVStoreKey("claim") | ||
s.Keeper = claim.NewKeeper(claimKey, s.dataKeeper, s.Cdc) | ||
s.Handler = claim.NewHandler(s.Keeper) | ||
s.Cms.MountStoreWithDB(dataKey, sdk.StoreTypeIAVL, s.Db) | ||
s.Cms.MountStoreWithDB(claimKey, sdk.StoreTypeIAVL, s.Db) | ||
_ = s.Cms.LoadLatestVersion() | ||
s.CreateSampleSchema() | ||
} | ||
|
||
func (s *Suite) randomData() types.DataAddress { | ||
x, ok := gen.Graph(s.Resolver).Sample() | ||
if !ok { | ||
panic("couldn't generate graph") | ||
} | ||
g := x.(graph.Graph) | ||
buf := new(bytes.Buffer) | ||
err := binary.SerializeGraph(s.Harness.Resolver, g, buf) | ||
s.Require().Nil(err) | ||
addr, err := s.dataKeeper.StoreGraph(s.Ctx, graph.Hash(g), buf.Bytes()) | ||
s.Require().Nil(err) | ||
return addr | ||
} | ||
|
||
func (s *Suite) TestCreateClaim() { | ||
s.T().Logf("sign a claim") | ||
c := s.randomData() | ||
ev0 := s.randomData() | ||
ev1 := s.randomData() | ||
msg := claim.MsgSignClaim{Content: c, Evidence: []types.DataAddress{ev0, ev1}, Signers: []sdk.AccAddress{s.Addr1}} | ||
res := s.Handler(s.Ctx, msg) | ||
s.Require().Equal(sdk.CodeOK, res.Code) | ||
s.Require().Equal(string(res.Tags[0].Value), c.String()) | ||
|
||
s.T().Logf("retrieve the signatures") | ||
sigs := s.Keeper.GetSigners(s.Ctx, c) | ||
s.Require().True(bytes.Equal(s.Addr1, sigs[0])) | ||
|
||
s.T().Logf("retrieve the evidence") | ||
ev := s.Keeper.GetEvidence(s.Ctx, c, s.Addr1) | ||
s.requireContainsData(ev, ev0) | ||
s.requireContainsData(ev, ev1) | ||
|
||
s.T().Logf("add more evidence and another signature") | ||
ev2 := s.randomData() | ||
err := s.Keeper.SignClaim(s.Ctx, c, []types.DataAddress{ev2}, []sdk.AccAddress{s.Addr1, s.Addr2}) | ||
s.Require().Nil(err) | ||
|
||
s.T().Logf("retrieve the signatures") | ||
sigs = s.Keeper.GetSigners(s.Ctx, c) | ||
s.requireContainsAddr(sigs, s.Addr1) | ||
s.requireContainsAddr(sigs, s.Addr2) | ||
|
||
s.T().Logf("retrieve the evidence") | ||
ev = s.Keeper.GetEvidence(s.Ctx, c, s.Addr1) | ||
s.requireContainsData(ev, ev0) | ||
s.requireContainsData(ev, ev1) | ||
s.requireContainsData(ev, ev2) | ||
|
||
ev = s.Keeper.GetEvidence(s.Ctx, c, s.Addr2) | ||
s.requireContainsData(ev, ev2) | ||
} | ||
|
||
func (s *Suite) TestCreateBadClaim() { | ||
msg := claim.MsgSignClaim{Signers: []sdk.AccAddress{s.Addr1}} | ||
err := msg.ValidateBasic() | ||
s.Require().NotNil(err) | ||
|
||
msg = claim.MsgSignClaim{Content: types.GetDataAddressOnChainGraph([]byte{}), Signers: []sdk.AccAddress{s.Addr1}} | ||
res := s.Handler(s.Ctx, msg) | ||
s.Require().Equal(sdk.CodeUnknownRequest, res.Code) | ||
|
||
msg = claim.MsgSignClaim{Content: types.DataAddress([]byte{10, 2, 3, 4}), Signers: []sdk.AccAddress{s.Addr1}} | ||
res = s.Handler(s.Ctx, msg) | ||
s.Require().Equal(sdk.CodeUnknownRequest, res.Code) | ||
} | ||
|
||
func (s *Suite) requireContainsAddr(xs []sdk.AccAddress, x sdk.AccAddress) { | ||
for _, y := range xs { | ||
if bytes.Equal(x, y) { | ||
return | ||
} | ||
} | ||
s.Require().FailNow("can't find address") | ||
} | ||
|
||
func (s *Suite) requireContainsData(xs []types.DataAddress, x types.DataAddress) { | ||
for _, y := range xs { | ||
if bytes.Equal(x, y) { | ||
return | ||
} | ||
} | ||
s.Require().FailNow("can't find the data") | ||
} | ||
|
||
func TestSuite(t *testing.T) { | ||
suite.Run(t, new(Suite)) | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,98 @@ | ||
package cli | ||
|
||
import ( | ||
"fmt" | ||
"github.com/cosmos/cosmos-sdk/client/context" | ||
"github.com/cosmos/cosmos-sdk/codec" | ||
sdk "github.com/cosmos/cosmos-sdk/types" | ||
"github.com/regen-network/regen-ledger/types" | ||
"github.com/regen-network/regen-ledger/x/claim" | ||
"github.com/spf13/cobra" | ||
"strings" | ||
) | ||
|
||
// GetSignaturesQueryCmd creates a query sub-command for the claim module using cmdName as the name of the sub-command. | ||
func GetSignaturesQueryCmd(storeName string, cdc *codec.Codec) *cobra.Command { | ||
return &cobra.Command{ | ||
Use: "signatures <content-address>", | ||
Short: "get signatures for claim", | ||
Args: cobra.ExactArgs(1), | ||
RunE: func(cmd *cobra.Command, args []string) error { | ||
cliCtx := context.NewCLIContext().WithCodec(cdc) | ||
content, err := types.DecodeBech32DataAddress(args[0]) | ||
if err != nil { | ||
return err | ||
} | ||
|
||
res, err := cliCtx.QueryStore(claim.KeySignatures(content), storeName) | ||
if err != nil { | ||
return err | ||
} | ||
|
||
if len(res) == 0 { | ||
return fmt.Errorf("no signatures for claim") | ||
} | ||
|
||
var sigs []sdk.AccAddress | ||
err = cdc.UnmarshalBinaryBare(res, &sigs) | ||
if err != nil { | ||
return err | ||
} | ||
|
||
var signatures strings.Builder | ||
for _, sig := range sigs { | ||
signatures.WriteString(sig.String()) | ||
signatures.WriteString(" ") | ||
} | ||
|
||
fmt.Println(signatures) | ||
return nil | ||
}, | ||
} | ||
} | ||
|
||
// GetEvidenceQueryCmd creates a query sub-command for the claim module using cmdName as the name of the sub-command. | ||
func GetEvidenceQueryCmd(storeName string, cdc *codec.Codec) *cobra.Command { | ||
return &cobra.Command{ | ||
Use: "evidence <evidence-address> <signer-address>", | ||
Short: "get evidence for claim", | ||
Args: cobra.ExactArgs(2), | ||
RunE: func(cmd *cobra.Command, args []string) error { | ||
cliCtx := context.NewCLIContext().WithCodec(cdc) | ||
content, err := types.DecodeBech32DataAddress(args[0]) | ||
if err != nil { | ||
return err | ||
} | ||
signer, err := sdk.AccAddressFromBech32(args[1]) | ||
if err != nil { | ||
return err | ||
} | ||
|
||
res, err := cliCtx.QueryStore(claim.KeySignatureEvidence(content, signer), storeName) | ||
if err != nil { | ||
return err | ||
} | ||
|
||
if len(res) == 0 { | ||
return fmt.Errorf("no evidence for claim") | ||
} | ||
|
||
var evidence []types.DataAddress | ||
err = cdc.UnmarshalBinaryBare(res, &evidence) | ||
if err != nil { | ||
return err | ||
} | ||
|
||
var evidenceString strings.Builder | ||
|
||
for _, data := range evidence { | ||
evidenceString.WriteString(data.String()) | ||
evidenceString.WriteString(" ") | ||
} | ||
|
||
fmt.Println(evidenceString) | ||
return nil | ||
}, | ||
} | ||
} | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,62 @@ | ||
package cli | ||
|
||
import ( | ||
"github.com/cosmos/cosmos-sdk/client/context" | ||
"github.com/cosmos/cosmos-sdk/client/utils" | ||
"github.com/cosmos/cosmos-sdk/codec" | ||
sdk "github.com/cosmos/cosmos-sdk/types" | ||
authtxb "github.com/cosmos/cosmos-sdk/x/auth/client/txbuilder" | ||
"github.com/regen-network/regen-ledger/types" | ||
"github.com/regen-network/regen-ledger/x/claim" | ||
"github.com/spf13/cobra" | ||
) | ||
|
||
// GetCmdSignClaim returns the tx claim sign command. | ||
func GetCmdSignClaim(cdc *codec.Codec) *cobra.Command { | ||
var evidence []string | ||
cmd := &cobra.Command{ | ||
Use: "sign <content-address> [--evidence <evidence-addresses>] --from <signer>", | ||
Short: "sign a claim on the blockchain", | ||
Args: cobra.ExactArgs(1), | ||
RunE: func(cmd *cobra.Command, args []string) error { | ||
cliCtx := context.NewCLIContext().WithCodec(cdc).WithAccountDecoder(cdc) | ||
|
||
txBldr := authtxb.NewTxBuilderFromCLI().WithTxEncoder(utils.GetTxEncoder(cdc)) | ||
|
||
if err := cliCtx.EnsureAccountExists(); err != nil { | ||
return err | ||
} | ||
|
||
account := cliCtx.GetFromAddress() | ||
|
||
contentAddr, err := types.DecodeBech32DataAddress(args[0]) | ||
if err != nil { | ||
return err | ||
} | ||
|
||
evidenceAddrs := make([]types.DataAddress, len(evidence)) | ||
for i, bech := range evidence { | ||
evidenceAddrs[i], err = types.DecodeBech32DataAddress(bech) | ||
if err != nil { | ||
return err | ||
} | ||
} | ||
|
||
msg := claim.MsgSignClaim{ | ||
Content: contentAddr, | ||
Signers: []sdk.AccAddress{account}, | ||
Evidence: evidenceAddrs, | ||
} | ||
err = msg.ValidateBasic() | ||
if err != nil { | ||
return err | ||
} | ||
|
||
cliCtx.PrintResponse = true | ||
|
||
return utils.CompleteAndBroadcastTxCLI(txBldr, cliCtx, []sdk.Msg{msg}) | ||
}, | ||
} | ||
cmd.Flags().StringSliceVar(&evidence, "evidence", nil, "A comma-separated list of data addresses representing claim evidence") | ||
return cmd | ||
} |
Oops, something went wrong.