Skip to content

Commit 3e6caf2

Browse files
author
Tural Devrishev
committed
scripts: add script for gasConsumed comparison
Signed-off-by: Tural Devrishev <tural@nspcc.ru>
1 parent c41054f commit 3e6caf2

1 file changed

Lines changed: 143 additions & 0 deletions

File tree

Lines changed: 143 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,143 @@
1+
package main
2+
3+
import (
4+
"context"
5+
"errors"
6+
"fmt"
7+
"os"
8+
9+
"github.com/davecgh/go-spew/spew"
10+
"github.com/nspcc-dev/neo-go/pkg/rpcclient"
11+
"github.com/nspcc-dev/neo-go/pkg/util"
12+
"github.com/pmezard/go-difflib/difflib"
13+
"github.com/urfave/cli/v2"
14+
)
15+
16+
func initClient(addr string, name string) (*rpcclient.Client, uint32, error) {
17+
c, err := rpcclient.New(context.Background(), addr, rpcclient.Options{})
18+
if err != nil {
19+
return nil, 0, fmt.Errorf("RPC %s: %w", name, err)
20+
}
21+
if err = c.Init(); err != nil {
22+
return nil, 0, fmt.Errorf("RPC %s init: %w", name, err)
23+
}
24+
h, err := c.GetBlockCount()
25+
if err != nil {
26+
return nil, 0, fmt.Errorf("RPC %s block count: %w", name, err)
27+
}
28+
return c, h, nil
29+
}
30+
31+
func compareNetworkMagic(ca, cb *rpcclient.Client) error {
32+
va, err := ca.GetVersion()
33+
if err != nil {
34+
return fmt.Errorf("failed to get version from A: %w", err)
35+
}
36+
vb, err := cb.GetVersion()
37+
if err != nil {
38+
return fmt.Errorf("failed to get version from B: %w", err)
39+
}
40+
if va.Protocol.Network != vb.Protocol.Network {
41+
return fmt.Errorf("different network magic: A=%s (0x%X), B=%s (0x%X)", va.Protocol.Network, uint32(va.Protocol.Network), vb.Protocol.Network, uint32(vb.Protocol.Network))
42+
}
43+
return nil
44+
}
45+
46+
func dumpApplogDiff(tx util.Uint256, a string, b string, ca *rpcclient.Client, cb *rpcclient.Client) error {
47+
la, err := ca.GetApplicationLog(tx, nil)
48+
if err != nil {
49+
return fmt.Errorf("can't get applog for tx %s from A: %w", tx.StringLE(), err)
50+
}
51+
lb, err := cb.GetApplicationLog(tx, nil)
52+
if err != nil {
53+
return fmt.Errorf("can't get applog for tx %s from B: %w", tx.StringLE(), err)
54+
}
55+
da := spew.Sdump(la)
56+
db := spew.Sdump(lb)
57+
diff, _ := difflib.GetUnifiedDiffString(difflib.UnifiedDiff{
58+
A: difflib.SplitLines(da),
59+
B: difflib.SplitLines(db),
60+
FromFile: a,
61+
ToFile: b,
62+
Context: 3,
63+
})
64+
fmt.Println(diff)
65+
return nil
66+
}
67+
68+
func cliMain(c *cli.Context) error {
69+
a := c.Args().Get(0)
70+
b := c.Args().Get(1)
71+
if a == "" || b == "" {
72+
return errors.New("usage: compare-gasconsumed RPC_A RPC_B [START_BLOCK_INDEX] [END_BLOCK_INDEX]")
73+
}
74+
75+
ca, ha, err := initClient(a, "A")
76+
if err != nil {
77+
return err
78+
}
79+
cb, hb, err := initClient(b, "B")
80+
if err != nil {
81+
return err
82+
}
83+
84+
if err := compareNetworkMagic(ca, cb); err != nil {
85+
return err
86+
}
87+
88+
var start uint32
89+
_, err = fmt.Sscan(c.Args().Get(2), &start)
90+
if err != nil {
91+
return fmt.Errorf("invalid start block index: %w", err)
92+
}
93+
94+
var end uint32
95+
_, err = fmt.Sscan(c.Args().Get(3), &end)
96+
if err != nil {
97+
return fmt.Errorf("invalid end block index: %w", err)
98+
}
99+
100+
if end >= ha || end >= hb {
101+
return fmt.Errorf("end %d is beyond available blocks: A has %d, B has %d", end, ha, hb)
102+
}
103+
104+
for i := start; i <= end; i++ {
105+
blk, err := ca.GetBlockByIndex(i)
106+
if err != nil {
107+
return fmt.Errorf("can't get block %d from A: %w", i, err)
108+
}
109+
for _, tx := range blk.Transactions {
110+
la, err := ca.GetApplicationLog(tx.Hash(), nil)
111+
if err != nil {
112+
return fmt.Errorf("can't get applog for tx %s from A: %w", tx.Hash().StringLE(), err)
113+
}
114+
lb, err := cb.GetApplicationLog(tx.Hash(), nil)
115+
if err != nil {
116+
return fmt.Errorf("can't get applog for tx %s from B: %w", tx.Hash().StringLE(), err)
117+
}
118+
ga := la.Executions[0].GasConsumed
119+
gb := lb.Executions[0].GasConsumed
120+
if ga != gb {
121+
fmt.Printf("mismatch at block %d, tx %s: gasConsumed A=%d B=%d\n", i, tx.Hash().StringLE(), ga, gb)
122+
if err := dumpApplogDiff(tx.Hash(), a, b, ca, cb); err != nil {
123+
return err
124+
}
125+
return errors.New("gas mismatch found")
126+
}
127+
}
128+
}
129+
return nil
130+
}
131+
132+
func main() {
133+
ctl := cli.NewApp()
134+
ctl.Name = "compare-gasconsumed"
135+
ctl.Version = "1.0"
136+
ctl.Usage = "compare-gasconsumed RPC_A RPC_B [START_BLOCK_INDEX] [END_BLOCK_INDEX]"
137+
ctl.Action = cliMain
138+
if err := ctl.Run(os.Args); err != nil {
139+
fmt.Fprintln(os.Stderr, err)
140+
os.Exit(1)
141+
}
142+
fmt.Println("compare-gasconsumed: all checks passed")
143+
}

0 commit comments

Comments
 (0)