Skip to content

Commit

Permalink
feat: spark contract (#377)
Browse files Browse the repository at this point in the history
* spark contract

* add README, use correct key

* make contract immutable

* make gen

* fix log fatal

* fix ABI strings

* serealize params

* update contract getPeerData

* update getPeerData return

* update getPeerData return struct

* fix retrun unpacking

* update readme

* some spack contract fixes

* fix address conversion

* log not updatin

* pre-merge cleanup

* switch signer to IPNI peerID

* rename signedMessage to signature

* Use mainnet verified contract

---------

Co-authored-by: Łukasz Magiera <[email protected]>
  • Loading branch information
LexLuthr and magik6k authored Feb 17, 2025
1 parent bc00cce commit 9ec0a6f
Show file tree
Hide file tree
Showing 19 changed files with 14,581 additions and 19 deletions.
10 changes: 9 additions & 1 deletion cmd/sptool/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ func main() {
spcli.InfoCmd(SPTActorGetter),
sectorsCmd,
provingCmd,
//multiSigCmd,
toolboxCmd,
}

app := &cli.App{
Expand Down Expand Up @@ -84,3 +84,11 @@ func SPTActorGetter(cctx *cli.Context) (address.Address, error) {
}
return addr, nil
}

var toolboxCmd = &cli.Command{
Name: "toolbox",
Usage: "some tools to fix some problems",
Subcommands: []*cli.Command{
sparkCmd,
},
}
236 changes: 236 additions & 0 deletions cmd/sptool/toolbox_ipni.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,236 @@
package main

import (
"bytes"
"fmt"
"strings"

eabi "github.com/ethereum/go-ethereum/accounts/abi"
"github.com/urfave/cli/v2"
"golang.org/x/xerrors"

"github.com/filecoin-project/go-address"
"github.com/filecoin-project/go-state-types/abi"
fbig "github.com/filecoin-project/go-state-types/big"
"github.com/filecoin-project/go-state-types/builtin"

"github.com/filecoin-project/curio/market/ipni/spark"

"github.com/filecoin-project/lotus/api"
"github.com/filecoin-project/lotus/build/buildconstants"
"github.com/filecoin-project/lotus/chain/actors"
"github.com/filecoin-project/lotus/chain/types"
"github.com/filecoin-project/lotus/chain/types/ethtypes"
cliutil "github.com/filecoin-project/lotus/cli/util"
)

var sparkCmd = &cli.Command{
Name: "spark",
Usage: "Manage Smart Contract PeerID used by Spark",
Subcommands: []*cli.Command{
deletePeer,
},
}

var deletePeer = &cli.Command{
Name: "delete-peer",
Usage: "Delete PeerID from Spark Smart Contract",
ArgsUsage: "<Miner ID>",
Flags: []cli.Flag{
&cli.BoolFlag{
Name: "really-do-it",
Usage: "Send the message to the smart contract",
},
},
Action: func(cctx *cli.Context) error {
if cctx.Args().Len() != 1 {
return cli.ShowCommandHelp(cctx, cctx.Command.Name)
}

minerID := cctx.Args().Get(0)

full, closer, err := cliutil.GetFullNodeAPIV1(cctx)
if err != nil {
return xerrors.Errorf("connecting to full node: %w", err)
}
defer closer()

maddr, err := address.NewFromString(minerID)
if err != nil {
return xerrors.Errorf("parsing miner address: %w", err)
}

actorId, err := address.IDFromAddress(maddr)
if err != nil {
return err
}

ctx := cctx.Context

mInfo, err := full.StateMinerInfo(ctx, maddr, types.EmptyTSK)
if err != nil {
return err
}

contractID, err := spark.GetContractAddress()
if err != nil {
return err
}

to, err := ethtypes.ParseEthAddress(contractID)
if err != nil {
return xerrors.Errorf("failed to parse contract address: %w", err)
}

toAddr, err := to.ToFilecoinAddress()
if err != nil {
return xerrors.Errorf("failed to convert Eth address to Filecoin address: %w", err)
}

// Parse the contract ABI
parsedABI, err := eabi.JSON(strings.NewReader(spark.GetPeerAbi))
if err != nil {
log.Fatalf("Failed to parse getPeer ABI: %v", err)
}

// Encode the function call
callData, err := parsedABI.Pack("getPeerData", int64(actorId))
if err != nil {
log.Fatalf("Failed to pack function call data: %v", err)
}

getparam := abi.CborBytes(callData)
getParams, err := actors.SerializeParams(&getparam)
if err != nil {
return fmt.Errorf("failed to serialize params: %w", err)
}

rMsg := &types.Message{
To: toAddr,
From: mInfo.Worker,
Value: types.NewInt(0),
Method: builtin.MethodsEVM.InvokeContract,
Params: getParams,
GasLimit: buildconstants.BlockGasLimit,
GasFeeCap: fbig.Zero(),
GasPremium: fbig.Zero(),
}

res, err := full.StateCall(ctx, rMsg, types.EmptyTSK)
if err != nil {
return fmt.Errorf("state call failed: %w", err)
}

if res.MsgRct.ExitCode.IsError() {
return fmt.Errorf("state call failed: %s", res.MsgRct.ExitCode.String())
}

var evmReturn abi.CborBytes
err = evmReturn.UnmarshalCBOR(bytes.NewReader(res.MsgRct.Return))
if err != nil {
return xerrors.Errorf("failed to unmarshal evm return: %w", err)
}

if len(evmReturn) == 0 {
if err != nil {
return xerrors.Errorf("failed to get spark params for %s: %w", maddr.String(), err)
}
} else {
// Define a struct that represents the tuple from the ABI
type PeerData struct {
PeerID string `abi:"peerID"`
Signature []byte `abi:"signature"`
}

// Define a wrapper struct that will be used for unpacking
type WrappedPeerData struct {
Result PeerData `abi:""`
}

// Create an instance of the wrapper struct
var result WrappedPeerData

err = parsedABI.UnpackIntoInterface(&result, "getPeerData", evmReturn)
if err != nil {
return xerrors.Errorf("Failed to unpack result: %w", err)
}

pd := result.Result

// Check if peerID is empty, indicating no data found
if pd.PeerID == "" && len(pd.Signature) == 0 {
return xerrors.Errorf("no data found for minerID in MinerPeerIDMapping contract: %s", maddr.String())
}
}

// Parse the contract's ABI
parsedABI, err = eabi.JSON(strings.NewReader(spark.DeletePeerAbi))
if err != nil {
return xerrors.Errorf("Failed to parse contract ABI: %w", err)
}

//Encode the method call to the contract (using the pay method with UUID)
data, err := parsedABI.Pack("deletePeerData", int64(actorId))
if err != nil {
return xerrors.Errorf("Failed to pack the `deletePeerData()` function call: %v", err)
}

var params []byte

param := abi.CborBytes(data)
params, err = actors.SerializeParams(&param)
if err != nil {
return fmt.Errorf("failed to serialize params: %w", err)
}

msg := &types.Message{
From: mInfo.Worker,
To: toAddr,
Value: abi.NewTokenAmount(0),
Method: builtin.MethodsEVM.InvokeContract,
Params: params,
GasLimit: buildconstants.BlockGasLimit,
GasFeeCap: fbig.Zero(),
GasPremium: fbig.Zero(),
}

maxFee, err := types.ParseFIL("5 FIL")
if err != nil {
return xerrors.Errorf("failed to parse max fee: %w", err)
}

mspec := &api.MessageSendSpec{
MaxFee: abi.TokenAmount(maxFee),
}

msg, err = full.GasEstimateMessageGas(ctx, msg, mspec, types.EmptyTSK)
if err != nil {
return xerrors.Errorf("failed to estimate gas: %w", err)
}

if !cctx.Bool("really-do-it") {
fmt.Println("Not sending the message... Use '--really-do-it flag to send the message'")
return nil
}

sm, err := full.MpoolPushMessage(ctx, msg, mspec)
if err != nil {
return xerrors.Errorf("failed to push message to mempool: %w", err)
}

fmt.Printf("Sent the delete request in message %s\n", sm.Cid().String())

wait, err := full.StateWaitMsg(ctx, sm.Cid(), 5, 2000, true)
if err != nil {
return xerrors.Errorf("failed to wait for message: %w", err)
}

if wait.Receipt.ExitCode != 0 {
return xerrors.Errorf("message execution failed (exit code %d)", wait.Receipt.ExitCode)
}

fmt.Printf("PeerID binding deleted successfully with %s!\n", wait.Message.String())

return nil
},
}
46 changes: 46 additions & 0 deletions documentation/en/curio-cli/sptool.md
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ COMMANDS:
info Print miner actor info
sectors interact with sector store
proving View proving information
toolbox some tools to fix some problems
help, h Shows a list of commands or help for one command
GLOBAL OPTIONS:
Expand Down Expand Up @@ -489,3 +490,48 @@ USAGE:
OPTIONS:
--help, -h show help
```

## sptool toolbox
```
NAME:
sptool toolbox - some tools to fix some problems
USAGE:
sptool toolbox command [command options]
COMMANDS:
spark Manage Smart Contract PeerID used by Spark
help, h Shows a list of commands or help for one command
OPTIONS:
--help, -h show help
```

### sptool toolbox spark
```
NAME:
sptool toolbox spark - Manage Smart Contract PeerID used by Spark
USAGE:
sptool toolbox spark command [command options]
COMMANDS:
delete-peer Delete PeerID from Spark Smart Contract
help, h Shows a list of commands or help for one command
OPTIONS:
--help, -h show help
```

#### sptool toolbox spark delete-peer
```
NAME:
sptool toolbox spark delete-peer - Delete PeerID from Spark Smart Contract
USAGE:
sptool toolbox spark delete-peer [command options] <Miner ID>
OPTIONS:
--really-do-it Send the message to the smart contract (default: false)
--help, -h show help
```
10 changes: 6 additions & 4 deletions go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ require (
github.com/dustin/go-humanize v1.0.1
github.com/elastic/go-sysinfo v1.7.0
github.com/etclabscore/go-openrpc-reflect v0.0.36
github.com/ethereum/go-ethereum v1.14.12
github.com/fatih/color v1.16.0
github.com/filecoin-project/filecoin-ffi v1.31.0
github.com/filecoin-project/go-address v1.2.0
Expand Down Expand Up @@ -177,7 +178,7 @@ require (
github.com/go-logfmt/logfmt v0.6.0 // indirect
github.com/go-logr/logr v1.4.2 // indirect
github.com/go-logr/stdr v1.2.2 // indirect
github.com/go-ole/go-ole v1.2.6 // indirect
github.com/go-ole/go-ole v1.3.0 // indirect
github.com/go-openapi/jsonpointer v0.19.3 // indirect
github.com/go-openapi/jsonreference v0.19.4 // indirect
github.com/go-openapi/spec v0.19.11 // indirect
Expand All @@ -188,7 +189,7 @@ require (
github.com/golang/glog v1.2.4 // indirect
github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da // indirect
github.com/golang/protobuf v1.5.4 // indirect
github.com/golang/snappy v0.0.4 // indirect
github.com/golang/snappy v0.0.5-0.20220116011046-fa5810519dcb // indirect
github.com/google/gopacket v1.1.19 // indirect
github.com/google/pprof v0.0.0-20241017200806-017d972448fc // indirect
github.com/hailocab/go-hostpool v0.0.0-20160125115350-e80d13ce29ed // indirect
Expand All @@ -198,6 +199,7 @@ require (
github.com/hashicorp/go-retryablehttp v0.7.7 // indirect
github.com/hashicorp/golang-lru v1.0.2 // indirect
github.com/hashicorp/golang-lru/arc/v2 v2.0.7 // indirect
github.com/holiman/uint256 v1.3.1 // indirect
github.com/huin/goupnp v1.3.0 // indirect
github.com/iancoleman/orderedmap v0.1.0 // indirect
github.com/ipfs/bbloom v0.0.4 // indirect
Expand Down Expand Up @@ -311,8 +313,8 @@ require (
github.com/shirou/gopsutil v3.21.4-0.20210419000835-c7a38de76ee5+incompatible // indirect
github.com/spaolacci/murmur3 v1.1.0 // indirect
github.com/syndtr/goleveldb v1.0.1-0.20210819022825-2ae1ddf74ef7 // indirect
github.com/tklauser/go-sysconf v0.3.5 // indirect
github.com/tklauser/numcpus v0.2.2 // indirect
github.com/tklauser/go-sysconf v0.3.12 // indirect
github.com/tklauser/numcpus v0.6.1 // indirect
github.com/twmb/murmur3 v1.1.6 // indirect
github.com/valyala/bytebufferpool v1.0.0 // indirect
github.com/valyala/fasttemplate v1.0.1 // indirect
Expand Down
Loading

0 comments on commit 9ec0a6f

Please sign in to comment.