-
Notifications
You must be signed in to change notification settings - Fork 1.3k
/
main.go
132 lines (107 loc) · 3.99 KB
/
main.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
package main
import (
"fmt"
"log"
"os"
"sort"
"github.com/urfave/cli/v2"
"github.com/filecoin-project/go-jsonrpc"
"github.com/filecoin-project/lotus/api/v1api"
lcli "github.com/filecoin-project/lotus/cli"
)
// FullAPI is a JSON-RPC client targeting a full node. It's initialized in a
// cli.BeforeFunc.
var FullAPI v1api.FullNode
// Closer is the closer for the JSON-RPC client, which must be called on
// cli.AfterFunc.
var Closer jsonrpc.ClientCloser
// DefaultLotusRepoPath is where the fallback path where to look for a Lotus
// client repo. It is expanded with mitchellh/go-homedir, so it'll work with all
// OSes despite the Unix twiddle notation.
const DefaultLotusRepoPath = "~/.lotus"
var repoFlag = cli.StringFlag{
Name: "repo",
EnvVars: []string{"LOTUS_PATH"},
Value: DefaultLotusRepoPath,
TakesFile: true,
}
func main() {
app := &cli.App{
Name: "tvx",
Description: `tvx is a tool for extracting and executing test vectors. It has four subcommands.
tvx extract extracts a test vector from a live network. It requires access to
a Filecoin client that exposes the standard JSON-RPC API endpoint. Only
message class test vectors are supported at this time.
tvx exec executes test vectors against Lotus. Either you can supply one in a
file, or many as an ndjson stdin stream.
tvx extract-many performs a batch extraction of many messages, supplied in a
CSV file. Refer to the help of that subcommand for more info.
tvx simulate takes a raw message and simulates it on top of the supplied
epoch, reporting the result on stderr and writing a test vector on stdout
or into the specified file.
SETTING THE JSON-RPC API ENDPOINT
You can set the JSON-RPC API endpoint through one of the following methods.
1. Directly set the API endpoint on the FULLNODE_API_INFO env variable.
The format is [token]:multiaddr, where token is optional for commands not
accessing privileged operations.
2. If you're running tvx against a local Lotus client, you can set the REPO
env variable to have the API endpoint and token extracted from the repo.
Alternatively, you can pass the --repo CLI flag.
3. Rely on the default fallback, which inspects ~/.lotus and extracts the
API endpoint string if the location is a Lotus repo.
tvx will apply these methods in the same order of precedence they're listed.
`,
Usage: "tvx is a tool for extracting and executing test vectors",
Commands: []*cli.Command{
extractCmd,
execCmd,
extractManyCmd,
simulateCmd,
},
}
sort.Sort(cli.CommandsByName(app.Commands))
for _, c := range app.Commands {
sort.Sort(cli.FlagsByName(c.Flags))
}
if err := app.Run(os.Args); err != nil {
log.Fatal(err)
}
}
func initialize(c *cli.Context) error {
// LOTUS_DISABLE_VM_BUF disables what's called "VM state tree buffering",
// which stashes write operations in a BufferedBlockstore
// (https://github.com/filecoin-project/lotus/blob/b7a4dbb07fd8332b4492313a617e3458f8003b2a/lib/bufbstore/buf_bstore.go#L21)
// such that they're not written until the VM is actually flushed.
//
// For some reason, the standard behaviour was not working for me (raulk),
// and disabling it (such that the state transformations are written immediately
// to the blockstore) worked.
_ = os.Setenv("LOTUS_DISABLE_VM_BUF", "iknowitsabadidea")
// Make the API client.
var err error
if FullAPI, Closer, err = lcli.GetFullNodeAPIV1(c); err != nil {
err = fmt.Errorf("failed to locate Lotus node; err: %w", err)
}
return err
}
func destroy(_ *cli.Context) error {
if Closer != nil {
Closer()
}
return nil
}
func ensureDir(path string) error {
switch fi, err := os.Stat(path); {
case os.IsNotExist(err):
if err := os.MkdirAll(path, 0755); err != nil {
return fmt.Errorf("failed to create directory %s: %w", path, err)
}
case err == nil:
if !fi.IsDir() {
return fmt.Errorf("path %s is not a directory: %w", path, err)
}
default:
return fmt.Errorf("failed to stat directory %s: %w", path, err)
}
return nil
}