2023-05-31 14:36:31 +08:00
|
|
|
// submit the evidence of malicious voting
|
|
|
|
package main
|
|
|
|
|
|
|
|
import (
|
|
|
|
"context"
|
|
|
|
"fmt"
|
|
|
|
"math/big"
|
|
|
|
"os"
|
|
|
|
"strings"
|
|
|
|
"time"
|
|
|
|
|
|
|
|
"github.com/ethereum/go-ethereum/accounts/abi/bind"
|
|
|
|
"github.com/ethereum/go-ethereum/common"
|
|
|
|
"github.com/ethereum/go-ethereum/core/systemcontracts"
|
|
|
|
"github.com/ethereum/go-ethereum/core/types"
|
|
|
|
"github.com/ethereum/go-ethereum/crypto"
|
|
|
|
"github.com/ethereum/go-ethereum/ethclient"
|
|
|
|
"github.com/ethereum/go-ethereum/internal/flags"
|
|
|
|
"github.com/ethereum/go-ethereum/log"
|
2023-08-23 17:46:08 +08:00
|
|
|
"github.com/urfave/cli/v2"
|
2023-05-31 14:36:31 +08:00
|
|
|
)
|
|
|
|
|
|
|
|
var (
|
|
|
|
app *cli.App
|
|
|
|
|
2023-08-23 17:46:08 +08:00
|
|
|
senderFlag = &cli.StringFlag{
|
2023-05-31 14:36:31 +08:00
|
|
|
Name: "sender",
|
|
|
|
Usage: "raw private key in hex format without 0x prefix; check permission on your own",
|
|
|
|
}
|
2023-08-23 17:46:08 +08:00
|
|
|
nodeFlag = &cli.StringFlag{
|
2023-05-31 14:36:31 +08:00
|
|
|
Name: "node",
|
|
|
|
Usage: "rpc endpoint, http,https,ws,wss,ipc are supported",
|
|
|
|
}
|
2023-08-23 17:46:08 +08:00
|
|
|
chainIdFlag = &cli.UintFlag{
|
2023-05-31 14:36:31 +08:00
|
|
|
Name: "chainId",
|
|
|
|
Usage: "chainId, can get by eth_chainId",
|
|
|
|
}
|
2023-08-23 17:46:08 +08:00
|
|
|
evidenceFlag = &cli.StringFlag{
|
2023-05-31 14:36:31 +08:00
|
|
|
Name: "evidence",
|
|
|
|
Usage: "params for submitFinalityViolationEvidence in json format; string",
|
|
|
|
}
|
|
|
|
)
|
|
|
|
|
|
|
|
func init() {
|
2023-08-23 17:46:08 +08:00
|
|
|
app = flags.NewApp("a tool for submitting the evidence of malicious voting")
|
|
|
|
app.Name = "maliciousvote-submit"
|
2023-05-31 14:36:31 +08:00
|
|
|
app.Flags = []cli.Flag{
|
|
|
|
senderFlag,
|
|
|
|
nodeFlag,
|
|
|
|
chainIdFlag,
|
|
|
|
evidenceFlag,
|
|
|
|
}
|
|
|
|
app.Action = submitMaliciousVotes
|
|
|
|
}
|
|
|
|
|
2023-08-23 17:46:08 +08:00
|
|
|
func submitMaliciousVotes(c *cli.Context) error {
|
2023-05-31 14:36:31 +08:00
|
|
|
// get sender
|
2023-08-23 17:46:08 +08:00
|
|
|
senderRawKey := c.String(senderFlag.Name)
|
2023-05-31 14:36:31 +08:00
|
|
|
if senderRawKey == "" {
|
|
|
|
log.Crit("no sender specified (--sender)")
|
|
|
|
}
|
|
|
|
sender, err := crypto.HexToECDSA(senderRawKey)
|
|
|
|
if err != nil {
|
|
|
|
log.Crit("get sender failed", "error", err)
|
|
|
|
} else {
|
|
|
|
log.Info("get sender success")
|
|
|
|
}
|
|
|
|
|
|
|
|
// connect to the given URL
|
2023-08-23 17:46:08 +08:00
|
|
|
nodeURL := c.String(nodeFlag.Name)
|
2023-05-31 14:36:31 +08:00
|
|
|
if nodeURL == "" {
|
|
|
|
log.Crit("no node specified (--node)")
|
|
|
|
}
|
|
|
|
client, err := ethclient.Dial(nodeURL)
|
|
|
|
if err != nil {
|
|
|
|
log.Crit("Error connecting to client", "nodeURL", nodeURL, "error", err)
|
|
|
|
} else {
|
|
|
|
// when nodeURL is type of http or https, err==nil not mean successfully connected
|
|
|
|
if !strings.HasPrefix(nodeURL, "http") {
|
|
|
|
log.Info("Successfully connected to client", "nodeURL", nodeURL)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
// get chainId
|
2023-08-23 17:46:08 +08:00
|
|
|
chainId := c.Uint(chainIdFlag.Name)
|
2023-05-31 14:36:31 +08:00
|
|
|
if chainId == 0 {
|
|
|
|
log.Crit("no chainId specified (--chainId)")
|
|
|
|
} else {
|
|
|
|
log.Info("get chainId success", "chainId", chainId)
|
|
|
|
}
|
|
|
|
|
|
|
|
// get evidence
|
2023-08-23 17:46:08 +08:00
|
|
|
evidenceJson := c.String(evidenceFlag.Name)
|
2023-05-31 14:36:31 +08:00
|
|
|
if evidenceJson == "" {
|
|
|
|
log.Crit("no evidence specified (--evidence)")
|
|
|
|
}
|
|
|
|
var evidence SlashIndicatorFinalityEvidence
|
|
|
|
if err = evidence.UnmarshalJSON([]byte(evidenceJson)); err != nil {
|
|
|
|
log.Crit("Error parsing evidence", "error", err)
|
|
|
|
} else {
|
|
|
|
log.Info("get evidence success")
|
|
|
|
}
|
|
|
|
|
|
|
|
ops, _ := bind.NewKeyedTransactorWithChainID(sender, big.NewInt(int64(chainId)))
|
|
|
|
//ops.GasLimit = 800000
|
|
|
|
slashIndicator, _ := NewSlashIndicator(common.HexToAddress(systemcontracts.SlashContract), client)
|
|
|
|
tx, err := slashIndicator.SubmitFinalityViolationEvidence(ops, evidence)
|
|
|
|
if err != nil {
|
|
|
|
log.Crit("submitMaliciousVotes:", "error", err)
|
|
|
|
}
|
|
|
|
var rc *types.Receipt
|
|
|
|
for i := 0; i < 180; i++ {
|
|
|
|
rc, err = client.TransactionReceipt(context.Background(), tx.Hash())
|
|
|
|
if err == nil && rc.Status != 0 {
|
|
|
|
log.Info("submitMaliciousVotes: submit evidence success", "receipt", rc)
|
|
|
|
break
|
|
|
|
}
|
|
|
|
if rc != nil && rc.Status == 0 {
|
|
|
|
log.Crit("submitMaliciousVotes: tx failed: ", "error", err, "receipt", rc)
|
|
|
|
}
|
|
|
|
time.Sleep(100 * time.Millisecond)
|
|
|
|
}
|
|
|
|
if rc == nil {
|
|
|
|
log.Crit("submitMaliciousVotes: submit evidence failed")
|
|
|
|
}
|
2023-08-23 17:46:08 +08:00
|
|
|
|
|
|
|
return nil
|
2023-05-31 14:36:31 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
func main() {
|
2024-02-02 15:43:33 +08:00
|
|
|
log.SetDefault(log.NewLogger(log.NewTerminalHandlerWithLevel(os.Stderr, log.LevelInfo, true)))
|
2023-05-31 14:36:31 +08:00
|
|
|
|
|
|
|
if err := app.Run(os.Args); err != nil {
|
|
|
|
fmt.Fprintln(os.Stderr, err)
|
|
|
|
os.Exit(1)
|
|
|
|
}
|
|
|
|
}
|