aboutsummaryrefslogblamecommitdiffstats
path: root/build/testtool/testtool.go
blob: 3f880b3bd6c9cc64df5a6d42773b59ddc6fdac1e (plain) (tree)
1
2
3
4
5
6
7
8
9
10
11
12
13












                       

                                                                  

























                                                              






                                                                           

         
                                                                             
                       
























                                                                                     











                                                                           







                                                         






                                                                                  
                       














                                                             









                                                                           










                                                         

                                           
                                                                  

         
                                                                                     






                                                                                  
                       




                                                         
                                                                               





























                                                                                                   
                             















                                                                                                                     
package main

import (
    "bytes"
    "context"
    "log"
    "math/big"
    "os"
    "path/filepath"
    "strconv"
    "strings"
    "time"

    dexCore "github.com/dexon-foundation/dexon-consensus/core"

    "github.com/dexon-foundation/dexon"
    "github.com/dexon-foundation/dexon/accounts/abi"
    "github.com/dexon-foundation/dexon/cmd/zoo/monkey"
    "github.com/dexon-foundation/dexon/core/vm"
    "github.com/dexon-foundation/dexon/crypto"
    "github.com/dexon-foundation/dexon/ethclient"
    "github.com/dexon-foundation/dexon/internal/build"
)

func main() {
    if len(os.Args) < 2 {
        log.Fatal("need subcommand as first argument")
    }

    switch os.Args[1] {
    case "verifyGovCRS":
        doVerifyGovCRS(os.Args[2:])
    case "verifyGovMPK":
        doVerifyGovMPK(os.Args[2:])
    case "monkeyTest":
        doMonkeyTest(os.Args[2:])
    case "upload":
        doUpload(os.Args[2:])
    }
}

func getBlockNumber(client *ethclient.Client, round int) *big.Int {
    if round == 0 {
        return big.NewInt(0)
    }
    abiObject, err := abi.JSON(strings.NewReader(vm.GovernanceABIJSON))
    if err != nil {
        log.Fatalf("read abi fail: %v", err)
    }

    input, err := abiObject.Pack("roundHeight", big.NewInt(int64(round)))
    if err != nil {
        log.Fatalf("pack input fail: %v", err)
    }

    result, err := client.CallContract(context.Background(), ethereum.CallMsg{
        To:   &vm.GovernanceContractAddress,
        Data: input,
    }, nil)
    if err != nil {
        log.Fatalf("call contract fail: %v", err)
    }

    if bytes.Equal(make([]byte, 32), result) {
        log.Fatalf("round %d height not found", round)
    }

    roundHeight := new(big.Int)
    if err := abiObject.Unpack(&roundHeight, "roundHeight", result); err != nil {
        log.Fatalf("unpack output fail: %v", err)
    }
    return roundHeight
}

func doVerifyGovCRS(args []string) {
    if len(args) < 2 {
        log.Fatal("arg length is not enough")
    }

    abiObject, err := abi.JSON(strings.NewReader(vm.GovernanceABIJSON))
    if err != nil {
        log.Fatalf("read abi fail: %v", err)
    }

    round, err := strconv.Atoi(args[1])
    if err != nil {
        log.Fatalf("pasre round from arg 2 fail: %v", err)
    }

    client, err := ethclient.Dial(args[0])
    if err != nil {
        log.Fatalf("new ethclient fail: %v", err)
    }

    blockNumber := getBlockNumber(client, round)

    input, err := abiObject.Pack("crs")
    if err != nil {
        log.Fatalf("pack input fail: %v", err)
    }

    result, err := client.CallContract(context.Background(), ethereum.CallMsg{
        To:   &vm.GovernanceContractAddress,
        Data: input,
    }, blockNumber)
    if err != nil {
        log.Fatalf("call contract fail: %v", err)
    }

    if bytes.Equal(make([]byte, 32), result) {
        log.Fatalf("round %s crs not found", args[1])
    }

    log.Printf("get round %s crs %x", args[1], result)
}

func doVerifyGovMPK(args []string) {
    if len(args) < 3 {
        log.Fatal("arg length is not enough")
    }
    abiObject, err := abi.JSON(strings.NewReader(vm.GovernanceABIJSON))
    if err != nil {
        log.Fatalf("read abi fail: %v", err)
    }

    round, err := strconv.Atoi(args[1])
    if err != nil {
        log.Fatalf("pasre round from arg 2 fail: %v", err)
    }

    if uint64(round) < dexCore.DKGDelayRound {
        return
    }

    client, err := ethclient.Dial(args[0])
    if err != nil {
        log.Fatalf("new ethclient fail: %v", err)
    }

    blockNumber := getBlockNumber(client, round)

    index, err := strconv.Atoi(args[2])
    if err != nil {
        log.Fatalf("pasre index from arg 2 fail: %v", err)
    }

    input, err := abiObject.Pack("dkgMasterPublicKeys", big.NewInt(int64(index)))
    if err != nil {
        log.Fatalf("pack input fail: %v", err)
    }

    result, err := client.CallContract(context.Background(), ethereum.CallMsg{
        To:   &vm.GovernanceContractAddress,
        Data: input,
    }, blockNumber)
    if err != nil {
        log.Fatalf("call contract fail: %v", err)
    }

    if bytes.Equal(make([]byte, 0), result) {
        log.Fatalf("round %s index %s mpk not found", args[1], args[2])
    }

    log.Printf("get round %s index %s master public key %x", args[1], args[2], result)
}

func doUpload(args []string) {
    auth := build.GCPOption{
        CredentialPath: os.Getenv("GCP_CREDENTIAL_PATH"),
    }

    if err := build.GCPFileUpload(args[0], args[1], filepath.Base(args[0]), auth); err != nil {
        log.Fatalf("upload fail: %v", err)
    }
}

func doMonkeyTest(args []string) {
    if len(args) < 1 {
        log.Fatal("arg length is not enough")
    }

    client, err := ethclient.Dial(args[0])
    if err != nil {
        log.Fatalf("new ethclient fail: %v", err)
    }

    monkey.Init(&monkey.MonkeyConfig{
        Key:      "test/keystore/monkey.key",
        Endpoint: args[0],
        N:        30,
        Sleep:    3000,
        Timeout:  30,
    })
    m, nonce := monkey.Exec()

    time.Sleep(10 * time.Second)

    for _, key := range m.Keys() {
        currentNonce, err := client.NonceAt(context.Background(), crypto.PubkeyToAddress(key.PublicKey), nil)
        if err != nil {
            log.Fatalf("get address nonce fail: %v", err)
        }

        if currentNonce != nonce+1 {
            log.Fatalf("expect nonce %v but %v", nonce, currentNonce)
        }
    }
}