Added transaction command #10
4 changed files with 188 additions and 1 deletions
8
flags.go
8
flags.go
|
@ -22,6 +22,7 @@ const (
|
||||||
disableProgressBarFlagKey = "disable-progress-bar"
|
disableProgressBarFlagKey = "disable-progress-bar"
|
||||||
stutterThresholdFlagKey = "threshold"
|
stutterThresholdFlagKey = "threshold"
|
||||||
forceCacheRewriteKey = "force"
|
forceCacheRewriteKey = "force"
|
||||||
|
walletFlag = "walletKey"
|
||||||
)
|
)
|
||||||
|
|
||||||
var (
|
var (
|
||||||
|
@ -85,6 +86,13 @@ var (
|
||||||
Aliases: []string{"f"},
|
Aliases: []string{"f"},
|
||||||
Usage: "force blockchain cache rewrite",
|
Usage: "force blockchain cache rewrite",
|
||||||
}
|
}
|
||||||
|
|
||||||
|
keyParseFlag = &cli.StringFlag{
|
||||||
|
Name: walletFlag,
|
||||||
|
Aliases: []string{"k"},
|
||||||
|
Usage: "wallet parse notifications",
|
||||||
|
Required: true,
|
||||||
|
}
|
||||||
)
|
)
|
||||||
|
|
||||||
func parseNotifications(notifications []string, cli *rpcclient.Client) (map[string]*util.Uint160, error) {
|
func parseNotifications(notifications []string, cli *rpcclient.Client) (map[string]*util.Uint160, error) {
|
||||||
|
|
16
main.go
16
main.go
|
@ -11,10 +11,11 @@ import (
|
||||||
"sync"
|
"sync"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
"git.frostfs.info/TrueCloudLab/monza/internal/chain"
|
|
||||||
"github.com/nspcc-dev/neo-go/pkg/util"
|
"github.com/nspcc-dev/neo-go/pkg/util"
|
||||||
"github.com/schollz/progressbar/v3"
|
"github.com/schollz/progressbar/v3"
|
||||||
"github.com/urfave/cli/v2"
|
"github.com/urfave/cli/v2"
|
||||||
|
|
||||||
|
"git.frostfs.info/TrueCloudLab/monza/internal/chain"
|
||||||
)
|
)
|
||||||
|
|
||||||
func main() {
|
func main() {
|
||||||
|
@ -63,6 +64,19 @@ func main() {
|
||||||
cacheFlag,
|
cacheFlag,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
Name: "transactions",
|
||||||
|
Usage: "Parse all transactions operation for wallet",
|
||||||
|
UsageText: "monza transactions -r [endpoint] -k [key] -n \"Transfer:gas\"",
|
||||||
|
Action: parse_transactions,
|
||||||
|
Flags: []cli.Flag{
|
||||||
|
endpointFlag,
|
||||||
|
notificationFlag,
|
||||||
|
keyParseFlag,
|
||||||
|
cacheFlag,
|
||||||
|
workersFlag,
|
||||||
|
},
|
||||||
|
},
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
10
plot.gnu
Normal file
10
plot.gnu
Normal file
|
@ -0,0 +1,10 @@
|
||||||
|
set datafile separator ","
|
||||||
|
set xlabel "Блоки"
|
||||||
|
set ylabel "Баланс"
|
||||||
|
set title "График баланса"
|
||||||
|
set grid
|
||||||
|
|
||||||
|
set terminal pngcairo size 800,600 enhanced font 'Verdana,10'
|
||||||
|
set output "balance_plot.png"
|
||||||
|
|
||||||
|
plot "out.csv" using 1:2 with lines title "Баланс"
|
155
transactions.go
Normal file
155
transactions.go
Normal file
|
@ -0,0 +1,155 @@
|
||||||
|
package main
|
||||||
|
|
||||||
|
import (
|
||||||
|
"bytes"
|
||||||
|
"context"
|
||||||
|
"encoding/csv"
|
||||||
|
"fmt"
|
||||||
|
"math/big"
|
||||||
|
"os"
|
||||||
|
"os/signal"
|
||||||
|
"strconv"
|
||||||
|
|
||||||
|
"github.com/nspcc-dev/neo-go/pkg/encoding/address"
|
||||||
|
"github.com/nspcc-dev/neo-go/pkg/vm/stackitem"
|
||||||
|
"github.com/urfave/cli/v2"
|
||||||
|
|
||||||
|
"git.frostfs.info/TrueCloudLab/monza/internal/chain"
|
||||||
|
)
|
||||||
|
|
||||||
|
func parse_transactions(c *cli.Context) (err error) {
|
||||||
|
|
||||||
|
ctx, cancel := signal.NotifyContext(context.Background(), os.Interrupt)
|
||||||
|
|
||||||
|
defer cancel()
|
||||||
|
|
||||||
|
cacheDir := c.String(cacheFlagKey)
|
||||||
|
if len(cacheDir) == 0 {
|
||||||
|
cacheDir, err = defaultConfigDir()
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
blockchain, err := chain.Open(ctx, cacheDir, c.String(endpointFlagKey), c.Bool(forceCacheRewriteKey))
|
||||||
|
if err != nil {
|
||||||
|
return fmt.Errorf("cannot initialize remote blockchain client: %w", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
defer blockchain.Close()
|
||||||
|
|
||||||
|
addr, err := address.StringToUint160(c.String(walletFlag))
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
notifications, err := parseNotifications(c.StringSlice(notificationFlagKey), blockchain.Client)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
nep17Balance, err := blockchain.Client.GetNEP17Balances(addr)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
balance := nep17Balance.Balances[0]
|
||||||
|
amount := new(big.Int)
|
||||||
|
from := balance.LastUpdated
|
||||||
|
|
||||||
|
p := ¶ms{
|
||||||
|
blockchain: blockchain,
|
||||||
|
notifications: notifications,
|
||||||
|
from: 0,
|
||||||
|
to: balance.LastUpdated,
|
||||||
|
workers: int(c.Uint64(workersFlagKey)),
|
||||||
|
disableBar: c.Bool(disableProgressBarFlagKey),
|
||||||
|
}
|
||||||
|
|
||||||
|
err = cacheBlocks(ctx, p)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
file, err := os.Create("out.csv")
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
defer file.Close()
|
||||||
|
|
||||||
|
writer := csv.NewWriter(file)
|
||||||
|
defer writer.Flush()
|
||||||
|
|
||||||
|
err = writer.Write([]string{"block", "balanse"})
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
for i := uint32(1); i <= from; i++ {
|
||||||
|
|
||||||
|
b, err := p.blockchain.Block(i)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
notifications, err := p.blockchain.AllNotifications(b)
|
||||||
|
if err != nil {
|
||||||
|
return fmt.Errorf("cannot fetch notifications from block %d: %w", i, err)
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, ev := range notifications {
|
||||||
|
|
||||||
|
if ev.Name != "Transfer" {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
|
items, ok := ev.Item.Value().([]stackitem.Item)
|
||||||
|
if !ok {
|
||||||
|
PrintEvent(b, ev, nonCompatibleMsg)
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
|
if len(items) != 3 {
|
||||||
|
PrintEvent(b, ev, nonCompatibleMsg)
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
snd, err := items[0].TryBytes()
|
||||||
|
if err != nil {
|
||||||
|
snd = nil
|
||||||
|
}
|
||||||
|
|
||||||
|
rcv, err := items[1].TryBytes()
|
||||||
|
if err != nil {
|
||||||
|
rcv = nil
|
||||||
|
}
|
||||||
|
|
||||||
|
bigAmount, err := items[2].TryInteger()
|
||||||
|
if err != nil {
|
||||||
|
PrintEvent(b, ev, nonCompatibleMsg)
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
|
if bytes.Equal(addr.BytesBE(), rcv) {
|
||||||
|
err = writer.Write([]string{strconv.FormatUint(uint64(b.Index), 10), new(big.Int).Add(amount, bigAmount).String()})
|
||||||
|
amount = new(big.Int).Add(amount, bigAmount)
|
||||||
|
if err != nil {
|
||||||
|
fmt.Println("Error write data:", err)
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if bytes.Equal(addr.BytesBE(), snd) {
|
||||||
|
err = writer.Write([]string{strconv.FormatUint(uint64(b.Index), 10), new(big.Int).Sub(amount, bigAmount).String()})
|
||||||
|
amount = new(big.Int).Sub(amount, bigAmount)
|
||||||
|
if err != nil {
|
||||||
|
fmt.Println("Error write data:", err)
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
Loading…
Add table
Reference in a new issue