Skip to content

Commit

Permalink
Merge branch 'miguel/bonds-module-review-changes' into stefania/updat…
Browse files Browse the repository at this point in the history
…e_to_cosmos_0_40
  • Loading branch information
stefaniatadama committed May 27, 2021
2 parents 0c9e649 + e3e02d2 commit e5accc0
Show file tree
Hide file tree
Showing 12 changed files with 764 additions and 49 deletions.
33 changes: 32 additions & 1 deletion docs/core/proto-docs.md
Expand Up @@ -256,6 +256,8 @@
- [MsgCreateProjectResponse](#project.MsgCreateProjectResponse)
- [MsgUpdateAgent](#project.MsgUpdateAgent)
- [MsgUpdateAgentResponse](#project.MsgUpdateAgentResponse)
- [MsgUpdateProjectDoc](#project.MsgUpdateProjectDoc)
- [MsgUpdateProjectDocResponse](#project.MsgUpdateProjectDocResponse)
- [MsgUpdateProjectStatus](#project.MsgUpdateProjectStatus)
- [MsgUpdateProjectStatusResponse](#project.MsgUpdateProjectStatusResponse)
- [MsgWithdrawFunds](#project.MsgWithdrawFunds)
Expand Down Expand Up @@ -3656,7 +3658,7 @@ GenesisState defines the did module's genesis state.
| sender_did | [string](#string) | | |
| project_did | [string](#string) | | |
| pub_key | [string](#string) | | |
| data | [bytes](#bytes) | | TODO (Stef) check about customtype |
| data | [bytes](#bytes) | | |



Expand Down Expand Up @@ -3701,6 +3703,34 @@ GenesisState defines the did module's genesis state.



<a name="project.MsgUpdateProjectDoc"></a>

### MsgUpdateProjectDoc



| Field | Type | Label | Description |
| ----- | ---- | ----- | ----------- |
| tx_hash | [string](#string) | | |
| sender_did | [string](#string) | | |
| project_did | [string](#string) | | |
| data | [bytes](#bytes) | | |






<a name="project.MsgUpdateProjectDocResponse"></a>

### MsgUpdateProjectDocResponse







<a name="project.MsgUpdateProjectStatus"></a>

### MsgUpdateProjectStatus
Expand Down Expand Up @@ -3776,6 +3806,7 @@ check all cases in NewHandler().
| CreateClaim | [MsgCreateClaim](#project.MsgCreateClaim) | [MsgCreateClaimResponse](#project.MsgCreateClaimResponse) | |
| CreateEvaluation | [MsgCreateEvaluation](#project.MsgCreateEvaluation) | [MsgCreateEvaluationResponse](#project.MsgCreateEvaluationResponse) | |
| WithdrawFunds | [MsgWithdrawFunds](#project.MsgWithdrawFunds) | [MsgWithdrawFundsResponse](#project.MsgWithdrawFundsResponse) | |
| UpdateProjectDoc | [MsgUpdateProjectDoc](#project.MsgUpdateProjectDoc) | [MsgUpdateProjectDocResponse](#project.MsgUpdateProjectDocResponse) | |



Expand Down
3 changes: 1 addition & 2 deletions go.mod
Expand Up @@ -16,13 +16,12 @@ require (
github.com/spf13/cast v1.3.1
github.com/spf13/cobra v1.1.1
github.com/spf13/pflag v1.0.5
github.com/spf13/viper v1.7.1
github.com/stretchr/testify v1.6.1
github.com/tendermint/go-amino v0.16.0
github.com/tendermint/tendermint v0.34.1 //latest
github.com/tendermint/tm-db v0.6.3
golang.org/x/crypto v0.0.0-20210513164829-c07d793c2f9a
google.golang.org/genproto v0.0.0-20210518161634-ec7691c0a37d
google.golang.org/genproto v0.0.0-20210524171403-669157292da3
google.golang.org/grpc v1.36.1
google.golang.org/protobuf v1.26.0
)
Expand Down
4 changes: 2 additions & 2 deletions go.sum
Expand Up @@ -795,8 +795,8 @@ google.golang.org/genproto v0.0.0-20200825200019-8632dd797987/go.mod h1:FWY/as6D
google.golang.org/genproto v0.0.0-20201111145450-ac7456db90a6/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no=
google.golang.org/genproto v0.0.0-20201119123407-9b1e624d6bc4/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no=
google.golang.org/genproto v0.0.0-20201214200347-8c77b98c765d/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no=
google.golang.org/genproto v0.0.0-20210518161634-ec7691c0a37d h1:bRz6UmsZEz/CzoTjUDp4ZcdguhSWi6CyU299wMQBpZU=
google.golang.org/genproto v0.0.0-20210518161634-ec7691c0a37d/go.mod h1:P3QM42oQyzQSnHPnZ/vqoCdDmzH28fzWByN9asMeM8A=
google.golang.org/genproto v0.0.0-20210524171403-669157292da3 h1:xFyh6GBb+NO1L0xqb978I3sBPQpk6FrKO0jJGRvdj/0=
google.golang.org/genproto v0.0.0-20210524171403-669157292da3/go.mod h1:P3QM42oQyzQSnHPnZ/vqoCdDmzH28fzWByN9asMeM8A=
google.golang.org/grpc v1.33.2 h1:EQyQC3sa8M+p6Ulc8yy9SWSS2GVwyRc83gAbG8lrl4o=
google.golang.org/grpc v1.33.2/go.mod h1:JMHMWHQWaTccqQQlmk3MJZS+GWXOdAesneDmEnv2fbc=
google.golang.org/protobuf v0.0.0-20200109180630-ec00e32a8dfd/go.mod h1:DFci5gLYBciE7Vtevhsrf46CRTquxDuWsQurQQe4oz8=
Expand Down
12 changes: 11 additions & 1 deletion proto/project/tx.proto
Expand Up @@ -16,6 +16,7 @@ service Msg {
rpc CreateClaim(MsgCreateClaim) returns (MsgCreateClaimResponse);
rpc CreateEvaluation(MsgCreateEvaluation) returns (MsgCreateEvaluationResponse);
rpc WithdrawFunds(MsgWithdrawFunds) returns (MsgWithdrawFundsResponse);
rpc UpdateProjectDoc(MsgUpdateProjectDoc) returns (MsgUpdateProjectDocResponse);
}

message MsgCreateProject {
Expand Down Expand Up @@ -90,4 +91,13 @@ message MsgWithdrawFunds {
WithdrawFundsDoc data = 2 [(gogoproto.nullable) = false, (gogoproto.moretags) = "yaml:\"data\""];
}

message MsgWithdrawFundsResponse {}
message MsgWithdrawFundsResponse {}

message MsgUpdateProjectDoc {
string tx_hash = 1 [(gogoproto.moretags) = "yaml:\"tx_hash\""];
string sender_did = 2 [(gogoproto.moretags) = "yaml:\"sender_did\""];
string project_did = 3 [(gogoproto.moretags) = "yaml:\"project_did\""];
bytes data = 4 [(gogoproto.moretags) = "yaml:\"data\""];
}

message MsgUpdateProjectDocResponse {}
25 changes: 25 additions & 0 deletions scripts/demo_project.sh
Expand Up @@ -143,6 +143,27 @@ ixod_tx project update-project-status "$SENDER_DID" CREATED "$PROJECT_DID_FULL"
echo "Updating project to PENDING..."
ixod_tx project update-project-status "$SENDER_DID" PENDING "$PROJECT_DID_FULL"

# Updating project doc succeeds as project is in status PENDING and tx sender DID
# is the same as project sender DID
PROJECT_INFO2='{
"nodeDid":"nodeDid",
"requiredClaims":"500",
"serviceEndpoint":"serviceEndpoint",
"createdOn":"2020-01-01T01:01:01.000Z",
"createdBy":"Creator",
"status":"",
"fees":{
"@context":"",
"items": [
{"@type":"OracleFee", "id":"payment:template:oracle-fee"},
{"@type":"FeeForService", "id":"payment:template:fee-for-service"}
]
},
"newField":"someNewField"
}'
echo "Updating project doc..."
ixod_tx project update-project-doc "$SENDER_DID" "$PROJECT_INFO2" "$PROJECT_DID_FULL"

# Fund project and progress status to FUNDED
FULL_PROJECT_ADDR=$(ixod q project get-project-accounts $PROJECT_DID | grep "$PROJECT_DID")
# Delete longest match of pattern ': ' from the beginning
Expand All @@ -158,6 +179,10 @@ SENDER_DID="$SHAUN_DID"
echo "Updating project to STARTED..."
ixod_tx project update-project-status "$SENDER_DID" STARTED "$PROJECT_DID_FULL"

# If we try updating the project-doc now, the tx fails as the project is in status STARTED
echo "Updating project doc fails since project is in status STARTED..."
ixod_tx project update-project-doc "$SENDER_DID" "$PROJECT_INFO" "$PROJECT_DID_FULL"

# Create claim and evaluation
echo "Creating a claim in project..."
SENDER_DID="$SHAUN_DID"
Expand Down
30 changes: 30 additions & 0 deletions x/project/client/cli/tx.go
Expand Up @@ -28,6 +28,7 @@ func NewTxCmd() *cobra.Command {
NewCmdCreateClaim(),
NewCmdCreateEvaluation(),
NewCmdWithdrawFunds(),
NewCmdUpdateProjectDoc(),
)

return projectTxCmd
Expand Down Expand Up @@ -295,3 +296,32 @@ func NewCmdWithdrawFunds() *cobra.Command {
flags.AddTxFlagsToCmd(cmd)
return cmd
}

func NewCmdUpdateProjectDoc() *cobra.Command {
cmd := &cobra.Command{
Use: "update-project-doc [sender-did] [project-data-json] [ixo-did]",
Short: "Update a project's data signed by the ixoDid of the project",
Args: cobra.ExactArgs(3),
RunE: func(cmd *cobra.Command, args []string) error {
senderDid := args[0]
projectDataStr := args[1]
ixoDid, err := didtypes.UnmarshalIxoDid(args[2])
if err != nil {
return err
}

clientCtx, err := client.GetClientTxContext(cmd)
if err != nil {
return err
}
clientCtx = clientCtx.WithFromAddress(ixoDid.Address())

msg := types.NewMsgUpdateProjectDoc(senderDid, json.RawMessage(projectDataStr), ixoDid.Did)

return ixotypes.GenerateOrBroadcastTxCLI(clientCtx, cmd.Flags(), ixoDid, msg)
},
}

flags.AddTxFlagsToCmd(cmd)
return cmd
}
31 changes: 31 additions & 0 deletions x/project/client/rest/tx.go
Expand Up @@ -23,6 +23,7 @@ func registerTxHandlers(clientCtx client.Context, r *mux.Router) {
r.HandleFunc("/project/create_claim", createClaimRequestHandler(clientCtx)).Methods("POST")
r.HandleFunc("/project/create_evaluation", createEvaluationRequestHandler(clientCtx)).Methods("POST")
r.HandleFunc("/project/withdraw_funds", withdrawFundsRequestHandler(clientCtx)).Methods("POST")
r.Handle("/project/update_project_doc", updateProjectDocRequestHandler(clientCtx)).Methods("PUT")
}

type createProjectReq struct {
Expand Down Expand Up @@ -234,3 +235,33 @@ func withdrawFundsRequestHandler(clientCtx client.Context) http.HandlerFunc {
tx.WriteGeneratedTxResponse(clientCtx, w, req.BaseReq, msg)
}
}

type updateProjectDocReq struct {
BaseReq rest.BaseReq `json:"base_req" yaml:"base_req"`
TxHash string `json:"txHash" yaml:"txHash"`
SenderDid did.Did `json:"senderDid" yaml:"senderDid"`
ProjectDid did.Did `json:"projectDid" yaml:"projectDid"`
Data json.RawMessage `json:"data" yaml:"data"`
}

func updateProjectDocRequestHandler(clientCtx client.Context) http.HandlerFunc {
return func(w http.ResponseWriter, r *http.Request) {
var req updateProjectDocReq
if !rest.ReadRESTReq(w, r, clientCtx.LegacyAmino, &req) {
return
}

req.BaseReq = req.BaseReq.Sanitize()
if !req.BaseReq.ValidateBasic(w) {
return
}

msg := types.NewMsgUpdateProjectDoc(req.SenderDid, req.Data, req.ProjectDid)
if err := msg.ValidateBasic(); err != nil {
rest.WriteErrorResponse(w, http.StatusBadRequest, err.Error())
return
}

tx.WriteGeneratedTxResponse(clientCtx, w, req.BaseReq, msg)
}
}
3 changes: 3 additions & 0 deletions x/project/handler.go
Expand Up @@ -37,6 +37,9 @@ func NewHandler(k keeper.Keeper, pk paymentskeeper.Keeper, bk bankkeeper.Keeper)
case *types.MsgWithdrawFunds:
res, err := msgServer.WithdrawFunds(sdk.WrapSDKContext(ctx), msg)
return sdk.WrapServiceResult(ctx, res, err)
case *types.MsgUpdateProjectDoc:
res, err := msgServer.UpdateProjectDoc(sdk.WrapSDKContext(ctx), msg)
return sdk.WrapServiceResult(ctx, res, err)
default:
return nil, sdkerrors.Wrapf(sdkerrors.ErrUnauthorized,
"unrecognized project Msg type: %v", msg.Type())
Expand Down
49 changes: 48 additions & 1 deletion x/project/keeper/msg_server.go
Expand Up @@ -90,7 +90,6 @@ func (s msgServer) CreateProject(goCtx context.Context, msg *types.MsgCreateProj
return &types.MsgCreateProjectResponse{}, nil
}

// TODO (Stef) Why isn't there a bank keeper inside the keeper?
func (s msgServer) UpdateProjectStatus(goCtx context.Context, msg *types.MsgUpdateProjectStatus) (*types.MsgUpdateProjectStatusResponse, error) {
ctx := sdk.UnwrapSDKContext(goCtx)
k := s.Keeper
Expand Down Expand Up @@ -496,6 +495,54 @@ func (s msgServer) WithdrawFunds(goCtx context.Context, msg *types.MsgWithdrawFu
return &types.MsgWithdrawFundsResponse{}, nil
}

func (s msgServer) UpdateProjectDoc(goCtx context.Context, msg *types.MsgUpdateProjectDoc) (*types.MsgUpdateProjectDocResponse, error) {
ctx := sdk.UnwrapSDKContext(goCtx)
k := s.Keeper

projectDoc, err := k.GetProjectDoc(ctx, msg.ProjectDid)
if err != nil {
return nil, sdkerrors.Wrap(did.ErrInvalidDid, "could not find project")
}

// Get and validate project fees map
err = k.ValidateProjectFeesMap(ctx, projectDoc.GetProjectFeesMap())
if err != nil {
return nil, err
}

// Editor of project doc has to be the same as project creator
if msg.SenderDid != projectDoc.SenderDid {
return nil, sdkerrors.Wrap(sdkerrors.ErrUnauthorized,
"only project creator can edit project doc")
}

// Project doc can be updated when in states Null, Created, Pending, or Funded
// and cannot be edited when in states Started, Stopped, and Paidout
status := types.ProjectStatusFromString(projectDoc.Status)
if status == types.StartedStatus || status == types.StoppedStatus || status == types.PaidoutStatus {
return nil, sdkerrors.Wrapf(sdkerrors.ErrUnknownRequest,
"project doc cannot be updated when project is in status %s", projectDoc.Status)
}

projectDoc.Data = msg.Data
k.SetProjectDoc(ctx, projectDoc)

ctx.EventManager().EmitEvents(sdk.Events{
sdk.NewEvent(
types.EventTypeUpdateProjectStatus,
sdk.NewAttribute(types.AttributeKeyTxHash, msg.TxHash),
sdk.NewAttribute(types.AttributeKeySenderDid, msg.SenderDid),
sdk.NewAttribute(types.AttributeKeyProjectDid, msg.ProjectDid),
),
sdk.NewEvent(
sdk.EventTypeMessage,
sdk.NewAttribute(sdk.AttributeKeyModule, types.AttributeValueCategory),
),
})

return &types.MsgUpdateProjectDocResponse{}, nil
}

func payoutAndRecon(ctx sdk.Context, k Keeper, bk bankkeeper.Keeper, projectDid did.Did,
fromAccountId types.InternalAccountID, recipientDid did.Did, amount sdk.Coin) error {

Expand Down
2 changes: 2 additions & 0 deletions x/project/types/codec.go
Expand Up @@ -16,6 +16,7 @@ func RegisterLegacyAminoCodec(cdc *codec.LegacyAmino) {
cdc.RegisterConcrete(MsgCreateClaim{}, "project/CreateClaim", nil)
cdc.RegisterConcrete(MsgCreateEvaluation{}, "project/CreateEvaluation", nil)
cdc.RegisterConcrete(MsgWithdrawFunds{}, "project/WithdrawFunds", nil)
cdc.RegisterConcrete(MsgUpdateProjectDoc{}, "project/UpdateProjectDoc", nil)

cdc.RegisterConcrete(ProjectDoc{}, "project/ProjectDoc", nil)
cdc.RegisterConcrete(AccountMap{}, "project/AccountMap", nil)
Expand All @@ -31,6 +32,7 @@ func RegisterInterfaces(registry types.InterfaceRegistry) {
&MsgCreateClaim{},
&MsgCreateEvaluation{},
&MsgWithdrawFunds{},
&MsgUpdateProjectDoc{},
)

msgservice.RegisterMsgServiceDesc(registry, &_Msg_serviceDesc)
Expand Down
48 changes: 48 additions & 0 deletions x/project/types/msgs.go
Expand Up @@ -18,6 +18,7 @@ const (
TypeMsgCreateClaim = "create-claim"
TypeMsgCreateEvaluation = "create-evaluation"
TypeMsgWithdrawFunds = "withdraw-funds"
TypeMsgUpdateProjectDoc = "update-project-doc"

MsgCreateProjectTotalFee = int64(1000000)
MsgCreateProjectTransactionFee = int64(10000)
Expand All @@ -32,6 +33,7 @@ var (
_ ixotypes.IxoMsg = &MsgCreateClaim{}
_ ixotypes.IxoMsg = &MsgCreateEvaluation{}
_ ixotypes.IxoMsg = &MsgWithdrawFunds{}
_ ixotypes.IxoMsg = &MsgUpdateProjectDoc{}
)

//type MsgCreateProject struct {
Expand Down Expand Up @@ -469,3 +471,49 @@ func (msg MsgWithdrawFunds) String() string {

return string(b)
}

func NewMsgUpdateProjectDoc(senderDid did.Did, projectData json.RawMessage, projectDid did.Did) *MsgUpdateProjectDoc {
return &MsgUpdateProjectDoc{
TxHash: "",
SenderDid: senderDid,
ProjectDid: projectDid,
Data: projectData,
}
}

func (msg MsgUpdateProjectDoc) Type() string { return TypeMsgUpdateProjectDoc }
func (msg MsgUpdateProjectDoc) Route() string { return RouterKey }

func (msg MsgUpdateProjectDoc) ValidateBasic() error {
// Check that not empty
if valid, err := CheckNotEmpty(msg.ProjectDid, "ProjectDid"); !valid {
return err
} else if valid, err := CheckNotEmpty(msg.SenderDid, "SenderDid"); !valid {
return err
}

// Check that data marshallable to map[string]json.RawMessage
var dataMap ProjectDataMap
err := json.Unmarshal(msg.Data, &dataMap)
if err != nil {
return sdkerrors.Wrap(sdkerrors.ErrJSONUnmarshal, "failed to unmarshal project data map")
}

// Check that DIDs valid
if !did.IsValidDid(msg.ProjectDid) {
return sdkerrors.Wrap(did.ErrInvalidDid, "project DID is invalid")
} else if !did.IsValidDid(msg.SenderDid) {
return sdkerrors.Wrap(did.ErrInvalidDid, "sender DID is invalid")
}

return nil
}

func (msg MsgUpdateProjectDoc) GetSignBytes() []byte {
return sdk.MustSortJSON(ModuleCdc.MustMarshalJSON(&msg))
}

func (msg MsgUpdateProjectDoc) GetSignerDid() did.Did { return msg.ProjectDid }
func (msg MsgUpdateProjectDoc) GetSigners() []sdk.AccAddress {
return []sdk.AccAddress{nil} // not used in signature verification in ixo AnteHandler
}

0 comments on commit e5accc0

Please sign in to comment.