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

Feat: Social Consensus #349

Merged
merged 4 commits into from
Jun 26, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions proto/canine_chain/storage/providers.proto
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,10 @@ message AttestationForm {
string cid = 2;
}

message ReportForm {
repeated Attestation attestations = 1;
string cid = 2;
}

message Collateral {
string address = 1;
Expand Down
28 changes: 28 additions & 0 deletions proto/canine_chain/storage/query.proto
Original file line number Diff line number Diff line change
Expand Up @@ -71,6 +71,18 @@ service Query {
option (google.api.http).get = "/jackal-dao/canine-chain/storage/attestations";
}

// Queries a Report by index.
rpc Reports(QueryReportRequest) returns (QueryReportResponse) {
option (google.api.http).get =
"/jackal-dao/canine-chain/storage/reports/{cid}";
}

// Queries a list of Attestation items.
rpc ReportsAll(QueryAllReportRequest)
returns (QueryAllReportResponse) {
option (google.api.http).get = "/jackal-dao/canine-chain/storage/reports";
}

// Queries a list of Freespace items.
rpc Freespace(QueryFreespaceRequest) returns (QueryFreespaceResponse) {
option (google.api.http).get =
Expand Down Expand Up @@ -233,6 +245,22 @@ message QueryAllAttestationsResponse {
cosmos.base.query.v1beta1.PageResponse pagination = 2;
}


message QueryReportRequest { string cid = 1; }

message QueryReportResponse {
ReportForm report = 1 [ (gogoproto.nullable) = false ];
}

message QueryAllReportRequest {
cosmos.base.query.v1beta1.PageRequest pagination = 1;
}

message QueryAllReportResponse {
repeated ReportForm reports = 1 [ (gogoproto.nullable) = false ];
cosmos.base.query.v1beta1.PageResponse pagination = 2;
}

message QueryFreespaceRequest { string address = 1; }

message QueryStoreCountRequest { string address = 1; }
Expand Down
21 changes: 21 additions & 0 deletions proto/canine_chain/storage/tx.proto
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,8 @@ service Msg {
rpc RemoveProviderClaimer(MsgRemoveClaimer) returns (MsgRemoveClaimerResponse);
rpc RequestAttestationForm(MsgRequestAttestationForm) returns (MsgRequestAttestationFormResponse);
rpc Attest(MsgAttest) returns (MsgAttestResponse);
rpc RequestReportForm(MsgRequestReportForm) returns (MsgRequestReportFormResponse);
rpc Report(MsgReport) returns (MsgReportResponse);


// this line is used by starport scaffolding # proto/tx/rpc
Expand Down Expand Up @@ -164,3 +166,22 @@ message MsgAttest {
}

message MsgAttestResponse {}

message MsgRequestReportForm {
string creator = 1;
string cid = 2;
}

message MsgRequestReportFormResponse {
repeated string providers = 1;
bool success = 2;
string error = 3;
string cid = 4;
}

message MsgReport {
string creator = 1;
string cid = 2;
}

message MsgReportResponse {}
6 changes: 6 additions & 0 deletions x/storage/handler.go
Original file line number Diff line number Diff line change
Expand Up @@ -65,6 +65,12 @@ func NewHandler(k keeper.Keeper) sdk.Handler {
case *types.MsgAttest:
res, err := msgServer.Attest(sdk.WrapSDKContext(ctx), msg)
return sdk.WrapServiceResult(ctx, res, err)
case *types.MsgRequestReportForm:
res, err := msgServer.RequestReportForm(sdk.WrapSDKContext(ctx), msg)
return sdk.WrapServiceResult(ctx, res, err)
case *types.MsgReport:
res, err := msgServer.Report(sdk.WrapSDKContext(ctx), msg)
return sdk.WrapServiceResult(ctx, res, err)
default:
errMsg := fmt.Sprintf("unrecognized %s message type: %T", types.ModuleName, msg)
return nil, sdkerrors.Wrap(sdkerrors.ErrUnknownRequest, errMsg)
Expand Down
21 changes: 21 additions & 0 deletions x/storage/keeper/contract_killing.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,8 @@ package keeper

import (
sdk "github.com/cosmos/cosmos-sdk/types"
sdkerror "github.com/cosmos/cosmos-sdk/types/errors"
"github.com/jackalLabs/canine-chain/v3/x/storage/types"
)

func (k Keeper) KillOldContracts(ctx sdk.Context) {
Expand All @@ -14,3 +16,22 @@ func (k Keeper) KillOldContracts(ctx sdk.Context) {
}
}
}

func (k Keeper) DropDeal(ctx sdk.Context, deal types.ActiveDeals) error {
intBlock, ok := sdk.NewIntFromString(deal.Endblock)
if !ok {
return sdkerror.Wrapf(sdkerror.ErrInvalidType, "int parse failed for endblock")
}
// Creating new stray file from the burned active deal
strayDeal := types.Strays{
Cid: deal.Cid,
Fid: deal.Fid,
Signee: deal.Signee,
Filesize: deal.Filesize,
Merkle: deal.Merkle,
End: intBlock.Int64(),
}
k.SetStrays(ctx, strayDeal)
k.RemoveActiveDeals(ctx, deal.Cid)
return nil
}
56 changes: 56 additions & 0 deletions x/storage/keeper/grpc_query_report.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
package keeper

import (
"context"

"github.com/cosmos/cosmos-sdk/store/prefix"
sdk "github.com/cosmos/cosmos-sdk/types"
"github.com/cosmos/cosmos-sdk/types/query"
"github.com/jackalLabs/canine-chain/v3/x/storage/types"
"google.golang.org/grpc/codes"
"google.golang.org/grpc/status"
)

func (k Keeper) ReportsAll(c context.Context, req *types.QueryAllReportRequest) (*types.QueryAllReportResponse, error) {
if req == nil {
return nil, status.Error(codes.InvalidArgument, "invalid request")
}

var reports []types.ReportForm
ctx := sdk.UnwrapSDKContext(c)

store := ctx.KVStore(k.storeKey)
reportStore := prefix.NewStore(store, types.KeyPrefix(types.ReportKeyPrefix))

pageRes, err := query.Paginate(reportStore, req.Pagination, func(key []byte, value []byte) error {
var providers types.ReportForm
if err := k.cdc.Unmarshal(value, &providers); err != nil {
return err
}

reports = append(reports, providers)
return nil
})
if err != nil {
return nil, status.Error(codes.Internal, err.Error())
}

return &types.QueryAllReportResponse{Reports: reports, Pagination: pageRes}, nil
}

func (k Keeper) Reports(c context.Context, req *types.QueryReportRequest) (*types.QueryReportResponse, error) {
if req == nil {
return nil, status.Error(codes.InvalidArgument, "invalid request")
}
ctx := sdk.UnwrapSDKContext(c)

val, found := k.GetReportForm(
ctx,
req.Cid,
)
if !found {
return nil, status.Error(codes.NotFound, "not found")
}

return &types.QueryReportResponse{Report: val}, nil
}
133 changes: 133 additions & 0 deletions x/storage/keeper/msg_server_report.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,133 @@
package keeper

import (
"context"

sdkerrors "github.com/cosmos/cosmos-sdk/types/errors"
"github.com/tendermint/tendermint/libs/rand"

sdk "github.com/cosmos/cosmos-sdk/types"
"github.com/jackalLabs/canine-chain/v3/x/storage/types"
)

func (k Keeper) Report(ctx sdk.Context, cid string, creator string) error {
form, found := k.GetReportForm(ctx, cid)
if !found {
return sdkerrors.Wrapf(types.ErrAttestInvalid, "cannot find this report")
}

done := false

var count int64

attestations := form.Attestations
for _, attestation := range attestations {
if attestation.Provider == creator {
attestation.Complete = true
done = true
}

if attestation.Complete {
count++
}
}

if !done {
return sdkerrors.Wrapf(types.ErrAttestInvalid, "you cannot attest to this deal")
}

if count < k.GetParams(ctx).AttestMinToPass {
form.Attestations = attestations
k.SetReportForm(ctx, form)
return nil
}

deal, found := k.GetActiveDeals(ctx, cid)

if !found {
return sdkerrors.Wrapf(types.ErrDealNotFound, "cannot find active deal from form")
}

k.RemoveReport(ctx, cid)

return k.DropDeal(ctx, deal)
}

func (k msgServer) Report(goCtx context.Context, msg *types.MsgReport) (*types.MsgReportResponse, error) {
ctx := sdk.UnwrapSDKContext(goCtx)

err := k.Keeper.Report(ctx, msg.Cid, msg.Creator)
if err != nil {
return nil, err
}

return &types.MsgReportResponse{}, nil
}

func (k Keeper) RequestReport(ctx sdk.Context, cid string) ([]string, error) {
_, found := k.GetActiveDeals(ctx, cid)
if !found {
return nil, sdkerrors.Wrapf(types.ErrDealNotFound, "cannot find active deal for report form")
}

_, found = k.GetReportForm(ctx, cid)
if found {
return nil, sdkerrors.Wrapf(types.ErrAttestAlreadyExists, "report form already exists")
}

providers := k.GetActiveProviders(ctx) // get a random list of active providers
params := k.GetParams(ctx)

if len(providers) < int(params.AttestFormSize) {
return nil, sdkerrors.Wrapf(types.ErrInvalidLengthQuery, "not enough providers online")
}

rand.Seed(ctx.BlockTime().UnixNano())

attestations := make([]*types.Attestation, params.AttestFormSize)

providerAddresses := make([]string, params.AttestFormSize)

for i := 0; i < int(params.AttestFormSize); i++ {
p := providers[i]

providerAddresses[i] = p.Address

attestations[i] = &types.Attestation{
Provider: p.Address,
Complete: false,
}
}

form := types.ReportForm{
Attestations: attestations,
Cid: cid,
}

k.SetReportForm(ctx, form)

return providerAddresses, nil
}

func (k msgServer) RequestReportForm(goCtx context.Context, msg *types.MsgRequestReportForm) (*types.MsgRequestReportFormResponse, error) {
ctx := sdk.UnwrapSDKContext(goCtx)
cid := msg.Cid

providerAddresses, err := k.RequestReport(ctx, cid)

success := true

errorString := ""

if err != nil {
success = false
errorString = err.Error()
}

return &types.MsgRequestReportFormResponse{
Providers: providerAddresses,
Success: success,
Error: errorString,
Cid: cid,
}, nil
}
Loading