diff --git a/scripts/bulk-upload.sh b/scripts/bulk-upload.sh new file mode 100755 index 000000000..cfc74582a --- /dev/null +++ b/scripts/bulk-upload.sh @@ -0,0 +1,5 @@ +while : +do + canined tx storage post-random --home=$HOME/canine-test --from charlie --gas-prices=0.02ujkl -y + sleep 60 +done \ No newline at end of file diff --git a/scripts/test-sequoia.sh b/scripts/test-sequoia.sh index c0bf7489d..cb72f91ab 100755 --- a/scripts/test-sequoia.sh +++ b/scripts/test-sequoia.sh @@ -38,8 +38,8 @@ canined collect-gentxs --home=$JKL_HOME sed -i.bak -e "s/stake/ujkl/" $JKL_HOME/config/genesis.json sed -i.bak -e "s/cosmos1arsaayyj5tash86mwqudmcs2fd5jt5zgp07gl8/jkl1arsaayyj5tash86mwqudmcs2fd5jt5zgc3sexc/" $JKL_HOME/config/genesis.json -sed -i.bak -e "s/\"proof_window\": \"50\"/\"proof_window\": \"40\"/" $JKL_HOME/config/genesis.json -sed -i.bak -e "s/\"chunk_size\": \"1024\"/\"chunk_size\": \"10240\"/" $JKL_HOME/config/genesis.json +sed -i.bak -e "s/\"proof_window\": \"50\"/\"proof_window\": \"900\"/" $JKL_HOME/config/genesis.json +sed -i.bak -e "s/\"chunk_size\": \"1024\"/\"chunk_size\": \"1024\"/" $JKL_HOME/config/genesis.json sed -i.bak -e "s/^minimum-gas-prices *=.*/minimum-gas-prices = \"0.0025ujkl\"/" $JKL_HOME/config/app.toml sed -i.bak -e 's/enable = false/enable=true/' $JKL_HOME/config/app.toml sed -i.bak -e 's/enabled-unsafe-cors = false/enabled-unsafe-cors = true/' $JKL_HOME/config/app.toml @@ -51,9 +51,8 @@ canined tx storage buy-storage $(canined keys show charlie -a --home=$JKL_HOME) sequoia init --home=$PROV_HOME -yq -i '.chunk_size=10240' $PROV_HOME/config.yaml -yq -i '.proof_interval=10' $PROV_HOME/config.yaml -yq -i '.queue_interval=5' $PROV_HOME/config.yaml +yq -i '.proof_interval=300' $PROV_HOME/config.yaml +yq -i '.queue_interval=7' $PROV_HOME/config.yaml yq -i '.chain_config.rpc_addr="http://localhost:26657"' $PROV_HOME/config.yaml yq -i '.chain_config.grpc_addr="localhost:9090"' $PROV_HOME/config.yaml yq -i '.domain="http://localhost:3334"' $PROV_HOME/config.yaml diff --git a/x/storage/client/cli/tx.go b/x/storage/client/cli/tx.go index 24cabebb5..b47b2214c 100644 --- a/x/storage/client/cli/tx.go +++ b/x/storage/client/cli/tx.go @@ -26,7 +26,7 @@ func GetTxCmd() *cobra.Command { cmd.AddCommand(CmdCancelContract()) cmd.AddCommand(CmdBuyStorage()) cmd.AddCommand(CmdUpgradeStorage()) - cmd.AddCommand(CmdPostFile()) + cmd.AddCommand(CmdPostFile(), CmdPostRandomFile()) return cmd } diff --git a/x/storage/client/cli/tx_post_file.go b/x/storage/client/cli/tx_post_file.go index 627e635e6..2772a4c6d 100644 --- a/x/storage/client/cli/tx_post_file.go +++ b/x/storage/client/cli/tx_post_file.go @@ -123,7 +123,7 @@ func GenerateOrBroadcastTx(clientCtx client.Context, flags *pflag.FlagSet, msgs } // broadcast to a Tendermint node - return clientCtx.BroadcastTx(txBytes) + return clientCtx.BroadcastTxCommit(txBytes) } func uploadFile(ip string, r io.Reader, merkle []byte, start int64, address string) error { @@ -191,115 +191,167 @@ func uploadFile(ip string, r io.Reader, merkle []byte, start int64, address stri return nil } -func CmdPostFile() *cobra.Command { - cmd := &cobra.Command{ - Use: "post [file-path]", - Short: "Post file to chain", - Args: cobra.ExactArgs(1), - RunE: func(cmd *cobra.Command, args []string) (err error) { - filePath := args[0] +func postFile(fileData []byte, cmd *cobra.Command) { + buf := bytes.NewBuffer(fileData) + treeBuffer := bytes.NewBuffer(buf.Bytes()) + clientCtx, err := client.GetClientTxContext(cmd) + if err != nil { + panic(err) + } + cl := types.NewQueryClient(clientCtx) - file, err := os.ReadFile(filePath) - if err != nil { - return err - } + params, err := cl.Params(context.Background(), &types.QueryParams{}) + if err != nil { + panic(err) + } - buf := bytes.NewBuffer(file) - treeBuffer := bytes.NewBuffer(buf.Bytes()) + root, _, _, size, err := utils.BuildTree(treeBuffer, params.Params.ChunkSize) + if err != nil { + panic(err) + } - root, _, _, size, err := utils.BuildTree(treeBuffer, 10240) - if err != nil { - return err - } - clientCtx, err := client.GetClientTxContext(cmd) - if err != nil { - return err - } + address := clientCtx.GetFromAddress().String() + + msg := types.NewMsgPostFile( + address, + root, + int64(size), + 40, + 0, + 3, + "Uploaded with canined", + ) + if err := msg.ValidateBasic(); err != nil { + panic(err) + } - address := clientCtx.GetFromAddress().String() - - msg := types.NewMsgPostFile( - address, - root, - int64(size), - 40, - 0, - 3, - "Uploaded with canined", - ) - if err := msg.ValidateBasic(); err != nil { - panic(err) - } + res, err := GenerateOrBroadcastTx(clientCtx, cmd.Flags(), msg) + if err != nil { + panic(err) + } - res, err := GenerateOrBroadcastTx(clientCtx, cmd.Flags(), msg) - if err != nil { - panic(err) - } + if res.Code != 0 { + panic("tx failed!") + } + + fmt.Println(res.RawLog) + + var postRes types.MsgPostFileResponse + data, err := hex.DecodeString(res.Data) + if err != nil { + panic(err) + } + + var txMsgData sdk.TxMsgData + err = clientCtx.Codec.Unmarshal(data, &txMsgData) + if err != nil { + panic(err) + } + + fmt.Println(txMsgData) + if len(txMsgData.Data) == 0 { + panic("no message data") + } + + err = postRes.Unmarshal(txMsgData.Data[0].Data) + if err != nil { + panic(err) + } + + ips := postRes.ProviderIps + fmt.Println(ips) - fmt.Println(res.RawLog) + fmt.Println(res.Code) + fmt.Println(res.RawLog) + fmt.Println(res.TxHash) - var postRes types.MsgPostFileResponse - data, err := hex.DecodeString(res.Data) + ipCount := len(ips) + randomCount := 3 - ipCount + for i := 0; i < ipCount; i++ { + ip := ips[i] + uploadBuffer := bytes.NewBuffer(buf.Bytes()) + err := uploadFile(ip, uploadBuffer, root, postRes.StartBlock, address) + if err != nil { + fmt.Println(err) + } + } + pageReq, err := client.ReadPageRequest(cmd.Flags()) + if err != nil { + panic(err) + } + provReq := types.QueryAllProviders{ + Pagination: pageReq, + } + + provRes, err := cl.AllProviders(context.Background(), &provReq) + if err != nil { + panic(err) + } + + providers := provRes.Providers + for i, provider := range providers { + if i > randomCount { + break + } + uploadBuffer := bytes.NewBuffer(buf.Bytes()) + err := uploadFile(provider.Ip, uploadBuffer, root, postRes.StartBlock, address) + if err != nil { + fmt.Println(err) + } + } +} + +func CmdPostRandomFile() *cobra.Command { + cmd := &cobra.Command{ + Use: "post-random [p-count]", + Short: "Post random file to chain", + Args: cobra.ExactArgs(1), + RunE: func(cmd *cobra.Command, args []string) (err error) { + countArg := args[0] + count, err := strconv.ParseInt(countArg, 10, 64) if err != nil { panic(err) } - var txMsgData sdk.TxMsgData - err = clientCtx.Codec.Unmarshal(data, &txMsgData) + url := fmt.Sprintf("https://baconipsum.com/api/?type=meat-and-filler¶s=%d&format=text", count) + hcli := http.DefaultClient + resp, err := hcli.Get(url) if err != nil { panic(err) } + defer resp.Body.Close() - fmt.Println(txMsgData) - - err = postRes.Unmarshal(txMsgData.Data[0].Data) + if resp.StatusCode != http.StatusOK { + return nil + } + bodyBytes, err := io.ReadAll(resp.Body) if err != nil { panic(err) } - ips := postRes.ProviderIps - fmt.Println(ips) - - fmt.Println(res.Code) - fmt.Println(res.RawLog) + postFile(bodyBytes, cmd) - fmt.Println(res.TxHash) + return nil + }, + } + flags.AddTxFlagsToCmd(cmd) + return cmd +} - ipCount := len(ips) - randomCount := 3 - ipCount - for i := 0; i < ipCount; i++ { - ip := ips[i] - uploadBuffer := bytes.NewBuffer(buf.Bytes()) - err := uploadFile(ip, uploadBuffer, root, postRes.StartBlock, address) - if err != nil { - fmt.Println(err) - } - } - pageReq, err := client.ReadPageRequest(cmd.Flags()) - if err != nil { - panic(err) - } - cl := types.NewQueryClient(clientCtx) - provReq := types.QueryAllProviders{ - Pagination: pageReq, - } +func CmdPostFile() *cobra.Command { + cmd := &cobra.Command{ + Use: "post [file-path]", + Short: "Post file to chain", + Args: cobra.ExactArgs(1), + RunE: func(cmd *cobra.Command, args []string) (err error) { + filePath := args[0] - provRes, err := cl.AllProviders(context.Background(), &provReq) + file, err := os.ReadFile(filePath) if err != nil { - panic(err) + return err } - providers := provRes.Providers - for i, provider := range providers { - if i > randomCount { - break - } - uploadBuffer := bytes.NewBuffer(buf.Bytes()) - err := uploadFile(provider.Ip, uploadBuffer, root, postRes.StartBlock, address) - if err != nil { - fmt.Println(err) - } - } + postFile(file, cmd) return nil }, diff --git a/x/storage/keeper/msg_server_post_file.go b/x/storage/keeper/msg_server_post_file.go index a98e48096..dc0e5fd78 100644 --- a/x/storage/keeper/msg_server_post_file.go +++ b/x/storage/keeper/msg_server_post_file.go @@ -13,9 +13,9 @@ func (k msgServer) PostFile(goCtx context.Context, msg *types.MsgPostFile) (*typ ctx := sdk.UnwrapSDKContext(goCtx) window := k.GetParams(ctx).ProofWindow - if msg.ProofInterval != window { - return nil, sdkerrors.Wrapf(sdkerrors.ErrUnauthorized, "cannot create a file with a window different than %d", window) - } + // if msg.ProofInterval != window { + // return nil, sdkerrors.Wrapf(sdkerrors.ErrUnauthorized, "cannot create a file with a window different than %d", window) + //} providers := k.GetActiveProviders(ctx, "") @@ -25,7 +25,7 @@ func (k msgServer) PostFile(goCtx context.Context, msg *types.MsgPostFile) (*typ Start: ctx.BlockHeight(), Expires: msg.Expires, FileSize: msg.FileSize, - ProofInterval: msg.ProofInterval, + ProofInterval: window, ProofType: msg.ProofType, Proofs: make([]string, 0), MaxProofs: msg.MaxProofs, diff --git a/x/storage/keeper/rewards.go b/x/storage/keeper/rewards.go index 1f6fd5dec..f4a867fcd 100644 --- a/x/storage/keeper/rewards.go +++ b/x/storage/keeper/rewards.go @@ -2,6 +2,8 @@ package keeper import ( "fmt" + "strconv" + "strings" sdkerrors "github.com/cosmos/cosmos-sdk/types/errors" @@ -9,13 +11,33 @@ import ( "github.com/jackalLabs/canine-chain/v3/x/storage/types" ) +func (k Keeper) burnContract(ctx sdk.Context, providerAddress string) { + prov, found := k.GetProviders(ctx, providerAddress) + if !found { + return + } + + burned, err := strconv.ParseInt(prov.BurnedContracts, 10, 64) + if err != nil { + ctx.Logger().Error("cannot parse providers burn count") + return + } + + prov.BurnedContracts = fmt.Sprintf("%d", burned+1) + k.SetProviders(ctx, prov) +} + func (k Keeper) manageProofs(ctx sdk.Context, sizeTracker *map[string]int64, file *types.UnifiedFile, proofKey string) { st := *sizeTracker + pks := strings.Split(proofKey, "/") + providerAddress := pks[0] + proof, found := k.GetProofWithBuiltKey(ctx, []byte(proofKey)) if !found { ctx.Logger().Info(fmt.Sprintf("cannot find proof: %s", proofKey)) file.RemoveProverWithKey(ctx, k, proofKey) + k.burnContract(ctx, providerAddress) } currentHeight := ctx.BlockHeight() @@ -25,6 +47,7 @@ func (k Keeper) manageProofs(ctx sdk.Context, sizeTracker *map[string]int64, fil if windowStart > proof.LastProven { // if the last time this file was proven was outside the proof window, burn their stake in the file ctx.Logger().Info(fmt.Sprintf("proof has not been proven within the last window: %d > %d", windowStart, proof.LastProven)) file.RemoveProverWithKey(ctx, k, proofKey) + k.burnContract(ctx, providerAddress) return } diff --git a/x/storage/types/file_deal.go b/x/storage/types/file_deal.go index 76278c528..ffd5dc298 100644 --- a/x/storage/types/file_deal.go +++ b/x/storage/types/file_deal.go @@ -126,8 +126,15 @@ func (f *UnifiedFile) ResetChunk(ctx sdk.Context, k ProofLoader, prover string, var newChunk int64 if pieces > 0 { // if there is more than one piece we pick a random to prove + var gs int64 + gasMeter := ctx.BlockGasMeter() + if gasMeter != nil { + gs = int64(gasMeter.GasConsumed()) + } + h := ctx.BlockHeight() + r := rand.NewRand() - r.Seed(ctx.BlockHeight() + int64(ctx.BlockGasMeter().GasConsumed())) + r.Seed(gs + h) newChunk = r.Int63n(pieces) }