Skip to content

Commit 9ec0a6f

Browse files
LexLuthrmagik6k
andauthored
feat: spark contract (#377)
* 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]>
1 parent bc00cce commit 9ec0a6f

File tree

19 files changed

+14581
-19
lines changed

19 files changed

+14581
-19
lines changed

cmd/sptool/main.go

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,7 @@ func main() {
2424
spcli.InfoCmd(SPTActorGetter),
2525
sectorsCmd,
2626
provingCmd,
27-
//multiSigCmd,
27+
toolboxCmd,
2828
}
2929

3030
app := &cli.App{
@@ -84,3 +84,11 @@ func SPTActorGetter(cctx *cli.Context) (address.Address, error) {
8484
}
8585
return addr, nil
8686
}
87+
88+
var toolboxCmd = &cli.Command{
89+
Name: "toolbox",
90+
Usage: "some tools to fix some problems",
91+
Subcommands: []*cli.Command{
92+
sparkCmd,
93+
},
94+
}

cmd/sptool/toolbox_ipni.go

Lines changed: 236 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,236 @@
1+
package main
2+
3+
import (
4+
"bytes"
5+
"fmt"
6+
"strings"
7+
8+
eabi "github.com/ethereum/go-ethereum/accounts/abi"
9+
"github.com/urfave/cli/v2"
10+
"golang.org/x/xerrors"
11+
12+
"github.com/filecoin-project/go-address"
13+
"github.com/filecoin-project/go-state-types/abi"
14+
fbig "github.com/filecoin-project/go-state-types/big"
15+
"github.com/filecoin-project/go-state-types/builtin"
16+
17+
"github.com/filecoin-project/curio/market/ipni/spark"
18+
19+
"github.com/filecoin-project/lotus/api"
20+
"github.com/filecoin-project/lotus/build/buildconstants"
21+
"github.com/filecoin-project/lotus/chain/actors"
22+
"github.com/filecoin-project/lotus/chain/types"
23+
"github.com/filecoin-project/lotus/chain/types/ethtypes"
24+
cliutil "github.com/filecoin-project/lotus/cli/util"
25+
)
26+
27+
var sparkCmd = &cli.Command{
28+
Name: "spark",
29+
Usage: "Manage Smart Contract PeerID used by Spark",
30+
Subcommands: []*cli.Command{
31+
deletePeer,
32+
},
33+
}
34+
35+
var deletePeer = &cli.Command{
36+
Name: "delete-peer",
37+
Usage: "Delete PeerID from Spark Smart Contract",
38+
ArgsUsage: "<Miner ID>",
39+
Flags: []cli.Flag{
40+
&cli.BoolFlag{
41+
Name: "really-do-it",
42+
Usage: "Send the message to the smart contract",
43+
},
44+
},
45+
Action: func(cctx *cli.Context) error {
46+
if cctx.Args().Len() != 1 {
47+
return cli.ShowCommandHelp(cctx, cctx.Command.Name)
48+
}
49+
50+
minerID := cctx.Args().Get(0)
51+
52+
full, closer, err := cliutil.GetFullNodeAPIV1(cctx)
53+
if err != nil {
54+
return xerrors.Errorf("connecting to full node: %w", err)
55+
}
56+
defer closer()
57+
58+
maddr, err := address.NewFromString(minerID)
59+
if err != nil {
60+
return xerrors.Errorf("parsing miner address: %w", err)
61+
}
62+
63+
actorId, err := address.IDFromAddress(maddr)
64+
if err != nil {
65+
return err
66+
}
67+
68+
ctx := cctx.Context
69+
70+
mInfo, err := full.StateMinerInfo(ctx, maddr, types.EmptyTSK)
71+
if err != nil {
72+
return err
73+
}
74+
75+
contractID, err := spark.GetContractAddress()
76+
if err != nil {
77+
return err
78+
}
79+
80+
to, err := ethtypes.ParseEthAddress(contractID)
81+
if err != nil {
82+
return xerrors.Errorf("failed to parse contract address: %w", err)
83+
}
84+
85+
toAddr, err := to.ToFilecoinAddress()
86+
if err != nil {
87+
return xerrors.Errorf("failed to convert Eth address to Filecoin address: %w", err)
88+
}
89+
90+
// Parse the contract ABI
91+
parsedABI, err := eabi.JSON(strings.NewReader(spark.GetPeerAbi))
92+
if err != nil {
93+
log.Fatalf("Failed to parse getPeer ABI: %v", err)
94+
}
95+
96+
// Encode the function call
97+
callData, err := parsedABI.Pack("getPeerData", int64(actorId))
98+
if err != nil {
99+
log.Fatalf("Failed to pack function call data: %v", err)
100+
}
101+
102+
getparam := abi.CborBytes(callData)
103+
getParams, err := actors.SerializeParams(&getparam)
104+
if err != nil {
105+
return fmt.Errorf("failed to serialize params: %w", err)
106+
}
107+
108+
rMsg := &types.Message{
109+
To: toAddr,
110+
From: mInfo.Worker,
111+
Value: types.NewInt(0),
112+
Method: builtin.MethodsEVM.InvokeContract,
113+
Params: getParams,
114+
GasLimit: buildconstants.BlockGasLimit,
115+
GasFeeCap: fbig.Zero(),
116+
GasPremium: fbig.Zero(),
117+
}
118+
119+
res, err := full.StateCall(ctx, rMsg, types.EmptyTSK)
120+
if err != nil {
121+
return fmt.Errorf("state call failed: %w", err)
122+
}
123+
124+
if res.MsgRct.ExitCode.IsError() {
125+
return fmt.Errorf("state call failed: %s", res.MsgRct.ExitCode.String())
126+
}
127+
128+
var evmReturn abi.CborBytes
129+
err = evmReturn.UnmarshalCBOR(bytes.NewReader(res.MsgRct.Return))
130+
if err != nil {
131+
return xerrors.Errorf("failed to unmarshal evm return: %w", err)
132+
}
133+
134+
if len(evmReturn) == 0 {
135+
if err != nil {
136+
return xerrors.Errorf("failed to get spark params for %s: %w", maddr.String(), err)
137+
}
138+
} else {
139+
// Define a struct that represents the tuple from the ABI
140+
type PeerData struct {
141+
PeerID string `abi:"peerID"`
142+
Signature []byte `abi:"signature"`
143+
}
144+
145+
// Define a wrapper struct that will be used for unpacking
146+
type WrappedPeerData struct {
147+
Result PeerData `abi:""`
148+
}
149+
150+
// Create an instance of the wrapper struct
151+
var result WrappedPeerData
152+
153+
err = parsedABI.UnpackIntoInterface(&result, "getPeerData", evmReturn)
154+
if err != nil {
155+
return xerrors.Errorf("Failed to unpack result: %w", err)
156+
}
157+
158+
pd := result.Result
159+
160+
// Check if peerID is empty, indicating no data found
161+
if pd.PeerID == "" && len(pd.Signature) == 0 {
162+
return xerrors.Errorf("no data found for minerID in MinerPeerIDMapping contract: %s", maddr.String())
163+
}
164+
}
165+
166+
// Parse the contract's ABI
167+
parsedABI, err = eabi.JSON(strings.NewReader(spark.DeletePeerAbi))
168+
if err != nil {
169+
return xerrors.Errorf("Failed to parse contract ABI: %w", err)
170+
}
171+
172+
//Encode the method call to the contract (using the pay method with UUID)
173+
data, err := parsedABI.Pack("deletePeerData", int64(actorId))
174+
if err != nil {
175+
return xerrors.Errorf("Failed to pack the `deletePeerData()` function call: %v", err)
176+
}
177+
178+
var params []byte
179+
180+
param := abi.CborBytes(data)
181+
params, err = actors.SerializeParams(&param)
182+
if err != nil {
183+
return fmt.Errorf("failed to serialize params: %w", err)
184+
}
185+
186+
msg := &types.Message{
187+
From: mInfo.Worker,
188+
To: toAddr,
189+
Value: abi.NewTokenAmount(0),
190+
Method: builtin.MethodsEVM.InvokeContract,
191+
Params: params,
192+
GasLimit: buildconstants.BlockGasLimit,
193+
GasFeeCap: fbig.Zero(),
194+
GasPremium: fbig.Zero(),
195+
}
196+
197+
maxFee, err := types.ParseFIL("5 FIL")
198+
if err != nil {
199+
return xerrors.Errorf("failed to parse max fee: %w", err)
200+
}
201+
202+
mspec := &api.MessageSendSpec{
203+
MaxFee: abi.TokenAmount(maxFee),
204+
}
205+
206+
msg, err = full.GasEstimateMessageGas(ctx, msg, mspec, types.EmptyTSK)
207+
if err != nil {
208+
return xerrors.Errorf("failed to estimate gas: %w", err)
209+
}
210+
211+
if !cctx.Bool("really-do-it") {
212+
fmt.Println("Not sending the message... Use '--really-do-it flag to send the message'")
213+
return nil
214+
}
215+
216+
sm, err := full.MpoolPushMessage(ctx, msg, mspec)
217+
if err != nil {
218+
return xerrors.Errorf("failed to push message to mempool: %w", err)
219+
}
220+
221+
fmt.Printf("Sent the delete request in message %s\n", sm.Cid().String())
222+
223+
wait, err := full.StateWaitMsg(ctx, sm.Cid(), 5, 2000, true)
224+
if err != nil {
225+
return xerrors.Errorf("failed to wait for message: %w", err)
226+
}
227+
228+
if wait.Receipt.ExitCode != 0 {
229+
return xerrors.Errorf("message execution failed (exit code %d)", wait.Receipt.ExitCode)
230+
}
231+
232+
fmt.Printf("PeerID binding deleted successfully with %s!\n", wait.Message.String())
233+
234+
return nil
235+
},
236+
}

documentation/en/curio-cli/sptool.md

Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@ COMMANDS:
1414
info Print miner actor info
1515
sectors interact with sector store
1616
proving View proving information
17+
toolbox some tools to fix some problems
1718
help, h Shows a list of commands or help for one command
1819
1920
GLOBAL OPTIONS:
@@ -489,3 +490,48 @@ USAGE:
489490
OPTIONS:
490491
--help, -h show help
491492
```
493+
494+
## sptool toolbox
495+
```
496+
NAME:
497+
sptool toolbox - some tools to fix some problems
498+
499+
USAGE:
500+
sptool toolbox command [command options]
501+
502+
COMMANDS:
503+
spark Manage Smart Contract PeerID used by Spark
504+
help, h Shows a list of commands or help for one command
505+
506+
OPTIONS:
507+
--help, -h show help
508+
```
509+
510+
### sptool toolbox spark
511+
```
512+
NAME:
513+
sptool toolbox spark - Manage Smart Contract PeerID used by Spark
514+
515+
USAGE:
516+
sptool toolbox spark command [command options]
517+
518+
COMMANDS:
519+
delete-peer Delete PeerID from Spark Smart Contract
520+
help, h Shows a list of commands or help for one command
521+
522+
OPTIONS:
523+
--help, -h show help
524+
```
525+
526+
#### sptool toolbox spark delete-peer
527+
```
528+
NAME:
529+
sptool toolbox spark delete-peer - Delete PeerID from Spark Smart Contract
530+
531+
USAGE:
532+
sptool toolbox spark delete-peer [command options] <Miner ID>
533+
534+
OPTIONS:
535+
--really-do-it Send the message to the smart contract (default: false)
536+
--help, -h show help
537+
```

go.mod

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@ require (
1818
github.com/dustin/go-humanize v1.0.1
1919
github.com/elastic/go-sysinfo v1.7.0
2020
github.com/etclabscore/go-openrpc-reflect v0.0.36
21+
github.com/ethereum/go-ethereum v1.14.12
2122
github.com/fatih/color v1.16.0
2223
github.com/filecoin-project/filecoin-ffi v1.31.0
2324
github.com/filecoin-project/go-address v1.2.0
@@ -177,7 +178,7 @@ require (
177178
github.com/go-logfmt/logfmt v0.6.0 // indirect
178179
github.com/go-logr/logr v1.4.2 // indirect
179180
github.com/go-logr/stdr v1.2.2 // indirect
180-
github.com/go-ole/go-ole v1.2.6 // indirect
181+
github.com/go-ole/go-ole v1.3.0 // indirect
181182
github.com/go-openapi/jsonpointer v0.19.3 // indirect
182183
github.com/go-openapi/jsonreference v0.19.4 // indirect
183184
github.com/go-openapi/spec v0.19.11 // indirect
@@ -188,7 +189,7 @@ require (
188189
github.com/golang/glog v1.2.4 // indirect
189190
github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da // indirect
190191
github.com/golang/protobuf v1.5.4 // indirect
191-
github.com/golang/snappy v0.0.4 // indirect
192+
github.com/golang/snappy v0.0.5-0.20220116011046-fa5810519dcb // indirect
192193
github.com/google/gopacket v1.1.19 // indirect
193194
github.com/google/pprof v0.0.0-20241017200806-017d972448fc // indirect
194195
github.com/hailocab/go-hostpool v0.0.0-20160125115350-e80d13ce29ed // indirect
@@ -198,6 +199,7 @@ require (
198199
github.com/hashicorp/go-retryablehttp v0.7.7 // indirect
199200
github.com/hashicorp/golang-lru v1.0.2 // indirect
200201
github.com/hashicorp/golang-lru/arc/v2 v2.0.7 // indirect
202+
github.com/holiman/uint256 v1.3.1 // indirect
201203
github.com/huin/goupnp v1.3.0 // indirect
202204
github.com/iancoleman/orderedmap v0.1.0 // indirect
203205
github.com/ipfs/bbloom v0.0.4 // indirect
@@ -311,8 +313,8 @@ require (
311313
github.com/shirou/gopsutil v3.21.4-0.20210419000835-c7a38de76ee5+incompatible // indirect
312314
github.com/spaolacci/murmur3 v1.1.0 // indirect
313315
github.com/syndtr/goleveldb v1.0.1-0.20210819022825-2ae1ddf74ef7 // indirect
314-
github.com/tklauser/go-sysconf v0.3.5 // indirect
315-
github.com/tklauser/numcpus v0.2.2 // indirect
316+
github.com/tklauser/go-sysconf v0.3.12 // indirect
317+
github.com/tklauser/numcpus v0.6.1 // indirect
316318
github.com/twmb/murmur3 v1.1.6 // indirect
317319
github.com/valyala/bytebufferpool v1.0.0 // indirect
318320
github.com/valyala/fasttemplate v1.0.1 // indirect

0 commit comments

Comments
 (0)