aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJimmy Hu <jimmy.hu@dexon.org>2019-05-04 22:18:40 +0800
committerWei-Ning Huang <w@byzantine-lab.io>2019-09-17 16:57:29 +0800
commitc9b5450778afa40c97fe863d9ed89f9e8c8ff447 (patch)
treef5508284971d80319747fea324f2dd10e497153a
parent2d3b0088eb051aa157046c396024a51cac5d87fc (diff)
downloadgo-tangerine-c9b5450778afa40c97fe863d9ed89f9e8c8ff447.tar
go-tangerine-c9b5450778afa40c97fe863d9ed89f9e8c8ff447.tar.gz
go-tangerine-c9b5450778afa40c97fe863d9ed89f9e8c8ff447.tar.bz2
go-tangerine-c9b5450778afa40c97fe863d9ed89f9e8c8ff447.tar.lz
go-tangerine-c9b5450778afa40c97fe863d9ed89f9e8c8ff447.tar.xz
go-tangerine-c9b5450778afa40c97fe863d9ed89f9e8c8ff447.tar.zst
go-tangerine-c9b5450778afa40c97fe863d9ed89f9e8c8ff447.zip
zoo: refacter and save keys (#403)
-rw-r--r--cmd/zoo/client/client.go190
-rw-r--r--cmd/zoo/main.go12
-rw-r--r--cmd/zoo/monkey/feeder.go23
-rw-r--r--cmd/zoo/monkey/gambler.go16
-rw-r--r--cmd/zoo/monkey/monkey.go205
-rw-r--r--cmd/zoo/utils/shutdown.go114
6 files changed, 380 insertions, 180 deletions
diff --git a/cmd/zoo/client/client.go b/cmd/zoo/client/client.go
new file mode 100644
index 000000000..9b65e778b
--- /dev/null
+++ b/cmd/zoo/client/client.go
@@ -0,0 +1,190 @@
+// Copyright 2019 The dexon-consensus Authors
+// This file is part of the dexon-consensus library.
+//
+// The dexon-consensus library is free software: you can redistribute it
+// and/or modify it under the terms of the GNU Lesser General Public License as
+// published by the Free Software Foundation, either version 3 of the License,
+// or (at your option) any later version.
+//
+// The dexon-consensus library is distributed in the hope that it will be
+// useful, but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser
+// General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public License
+// along with the dexon-consensus library. If not, see
+// <http://www.gnu.org/licenses/>.
+
+// A simple monkey that sends random transactions into the network.
+
+package client
+
+import (
+ "context"
+ "crypto/ecdsa"
+ "fmt"
+ "math"
+ "math/big"
+ "time"
+
+ dexon "github.com/dexon-foundation/dexon"
+ "github.com/dexon-foundation/dexon/common"
+ "github.com/dexon-foundation/dexon/core/types"
+ "github.com/dexon-foundation/dexon/crypto"
+ "github.com/dexon-foundation/dexon/ethclient"
+)
+
+type Client struct {
+ ethclient.Client
+
+ source *ecdsa.PrivateKey
+ networkID *big.Int
+}
+
+func New(ep string) (*Client, error) {
+ client, err := ethclient.Dial(ep)
+ if err != nil {
+ return nil, err
+ }
+
+ networkID, err := client.NetworkID(context.Background())
+ if err != nil {
+ return nil, err
+ }
+
+ return &Client{
+ Client: *client,
+ networkID: networkID,
+ }, nil
+}
+
+type TransferContext struct {
+ Key *ecdsa.PrivateKey
+ ToAddress common.Address
+ Amount *big.Int
+ Data []byte
+ Nonce uint64
+ Gas uint64
+}
+
+func (c *Client) PrepareTx(ctx *TransferContext) *types.Transaction {
+ if ctx.Nonce == math.MaxUint64 {
+ var err error
+ address := crypto.PubkeyToAddress(ctx.Key.PublicKey)
+ ctx.Nonce, err = c.PendingNonceAt(context.Background(), address)
+ if err != nil {
+ panic(err)
+ }
+ }
+
+ if ctx.Gas == uint64(0) {
+ var err error
+ ctx.Gas, err = c.EstimateGas(context.Background(), dexon.CallMsg{
+ Data: ctx.Data,
+ })
+ if err != nil {
+ panic(err)
+ }
+ }
+
+ gasPrice, err := c.SuggestGasPrice(context.Background())
+ if err != nil {
+ panic(err)
+ }
+
+ tx := types.NewTransaction(
+ ctx.Nonce,
+ ctx.ToAddress,
+ ctx.Amount,
+ ctx.Gas,
+ gasPrice,
+ ctx.Data)
+
+ signer := types.NewEIP155Signer(c.networkID)
+ tx, err = types.SignTx(tx, signer, ctx.Key)
+ if err != nil {
+ panic(err)
+ }
+
+ return tx
+}
+
+func (c *Client) Transfer(ctx *TransferContext) {
+ tx := c.PrepareTx(ctx)
+
+ err := c.SendTransaction(context.Background(), tx)
+ if err != nil {
+ panic(err)
+ }
+}
+
+func (c *Client) BatchTransfer(ctxs []*TransferContext) {
+ txs := make([]*types.Transaction, len(ctxs))
+ for i, ctx := range ctxs {
+ txs[i] = c.PrepareTx(ctx)
+ }
+
+ err := c.SendTransactions(context.Background(), txs)
+ if err != nil {
+ panic(err)
+ }
+}
+
+func (c *Client) Deploy(
+ key *ecdsa.PrivateKey, code string, ctors []string, amount *big.Int, nonce uint64) common.Address {
+
+ address := crypto.PubkeyToAddress(key.PublicKey)
+ if nonce == math.MaxUint64 {
+ var err error
+ nonce, err = c.PendingNonceAt(context.Background(), address)
+ if err != nil {
+ panic(err)
+ }
+ }
+
+ var input string
+ for _, ctor := range ctors {
+ input += fmt.Sprintf("%064s", ctor)
+ }
+ data := common.Hex2Bytes(code + input)
+
+ gas, err := c.EstimateGas(context.Background(), dexon.CallMsg{
+ From: address,
+ Data: data,
+ })
+ if err != nil {
+ panic(err)
+ }
+
+ tx := types.NewContractCreation(
+ nonce,
+ amount,
+ gas,
+ big.NewInt(1e9),
+ data)
+
+ signer := types.NewEIP155Signer(c.networkID)
+ tx, err = types.SignTx(tx, signer, key)
+ if err != nil {
+ panic(err)
+ }
+
+ fmt.Println("Sending TX", "fullhash", tx.Hash().String())
+
+ err = c.SendTransaction(context.Background(), tx)
+ if err != nil {
+ panic(err)
+ }
+
+ for {
+ time.Sleep(500 * time.Millisecond)
+ recp, err := c.TransactionReceipt(context.Background(), tx.Hash())
+ if err != nil {
+ if err == dexon.NotFound {
+ continue
+ }
+ panic(err)
+ }
+ return recp.ContractAddress
+ }
+}
diff --git a/cmd/zoo/main.go b/cmd/zoo/main.go
index 195d5737c..cd33d4cee 100644
--- a/cmd/zoo/main.go
+++ b/cmd/zoo/main.go
@@ -4,6 +4,7 @@ import (
"flag"
"github.com/dexon-foundation/dexon/cmd/zoo/monkey"
+ "github.com/dexon-foundation/dexon/cmd/zoo/utils"
)
var key = flag.String("key", "", "private key path")
@@ -14,10 +15,21 @@ var batch = flag.Bool("batch", false, "monkeys will send transaction in batch")
var sleep = flag.Int("sleep", 500, "time in millisecond that monkeys sleep between each transaction")
var feeder = flag.Bool("feeder", false, "make this monkey a feeder")
var timeout = flag.Int("timeout", 0, "execution time limit after start")
+var shutdown = flag.String("shutdown", "", "shutdown the previously opened zoo")
func main() {
flag.Parse()
+ if *shutdown != "" {
+ utils.Shutdown(&utils.ShutdownConfig{
+ Key: *key,
+ Endpoint: *endpoint,
+ File: *shutdown,
+ Batch: *batch,
+ })
+ return
+ }
+
monkey.Init(&monkey.MonkeyConfig{
Key: *key,
Endpoint: *endpoint,
diff --git a/cmd/zoo/monkey/feeder.go b/cmd/zoo/monkey/feeder.go
index 7a3db3a3a..99df83b98 100644
--- a/cmd/zoo/monkey/feeder.go
+++ b/cmd/zoo/monkey/feeder.go
@@ -27,6 +27,7 @@ import (
"time"
"github.com/dexon-foundation/dexon/accounts/abi"
+ "github.com/dexon-foundation/dexon/cmd/zoo/client"
"github.com/dexon-foundation/dexon/common"
"github.com/dexon-foundation/dexon/crypto"
)
@@ -44,12 +45,12 @@ func init() {
func (m *Monkey) DistributeBanana(contract common.Address) {
fmt.Println("Distributing Banana to random accounts ...")
address := crypto.PubkeyToAddress(m.source.PublicKey)
- nonce, err := m.client.PendingNonceAt(context.Background(), address)
+ nonce, err := m.PendingNonceAt(context.Background(), address)
if err != nil {
panic(err)
}
- ctxs := make([]*transferContext, len(m.keys))
+ ctxs := make([]*client.TransferContext, len(m.keys))
amount := new(big.Int)
amount.SetString("10000000000000000", 10)
for i, key := range m.keys {
@@ -58,22 +59,22 @@ func (m *Monkey) DistributeBanana(contract common.Address) {
if err != nil {
panic(err)
}
- ctxs[i] = &transferContext{
+ ctxs[i] = &client.TransferContext{
Key: m.source,
ToAddress: contract,
Data: input,
Nonce: nonce,
Gas: 100000,
}
- nonce += 1
+ nonce++
}
- m.batchTransfer(ctxs)
+ m.BatchTransfer(ctxs)
time.Sleep(20 * time.Second)
}
func (m *Monkey) Feed() uint64 {
fmt.Println("Deploying contract ...")
- contract := m.deploy(m.source, bananaContract, nil, new(big.Int), math.MaxUint64)
+ contract := m.Deploy(m.source, bananaContract, nil, new(big.Int), math.MaxUint64)
fmt.Println(" Contract deployed: ", contract.String())
m.DistributeBanana(contract)
@@ -83,7 +84,7 @@ func (m *Monkey) Feed() uint64 {
loop:
for {
fmt.Println("nonce", nonce)
- ctxs := make([]*transferContext, len(m.keys))
+ ctxs := make([]*client.TransferContext, len(m.keys))
for i, key := range m.keys {
to := crypto.PubkeyToAddress(m.keys[rand.Int()%len(m.keys)].PublicKey)
input, err := bananaABI.Pack("transfer", to, big.NewInt(rand.Int63n(100)+1))
@@ -91,7 +92,7 @@ loop:
panic(err)
}
- ctx := &transferContext{
+ ctx := &client.TransferContext{
Key: key,
ToAddress: contract,
Data: input,
@@ -101,11 +102,11 @@ loop:
if config.Batch {
ctxs[i] = ctx
} else {
- m.transfer(ctx)
+ m.Transfer(ctx)
}
}
if config.Batch {
- m.batchTransfer(ctxs)
+ m.BatchTransfer(ctxs)
}
if m.timer != nil {
@@ -116,7 +117,7 @@ loop:
}
}
- nonce += 1
+ nonce++
time.Sleep(time.Duration(config.Sleep) * time.Millisecond)
}
diff --git a/cmd/zoo/monkey/gambler.go b/cmd/zoo/monkey/gambler.go
index 33f749343..9c9098c42 100644
--- a/cmd/zoo/monkey/gambler.go
+++ b/cmd/zoo/monkey/gambler.go
@@ -25,6 +25,7 @@ import (
"time"
"github.com/dexon-foundation/dexon/accounts/abi"
+ "github.com/dexon-foundation/dexon/cmd/zoo/client"
)
var betContract = string("0x60806040523480156200001157600080fd5b5060405160208062000ee083398101806040528101908080519060200190929190505050336000806101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055506000809054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16600073ffffffffffffffffffffffffffffffffffffffff167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e060405160405180910390a36200010b8162000112640100000000026401000000009004565b50620003f5565b60006200011e62000364565b6000620001396200029f640100000000026401000000009004565b15156200014557600080fd5b606484101515620001e4576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260248152602001807f4578706563746174696f6e2073686f756c64206265206c657373207468616e2081526020017f3130302e0000000000000000000000000000000000000000000000000000000081525060400191505060405180910390fd5b836001819055506200021061271085620002f664010000000002620008c4179091906401000000009004565b925060008260006064811015156200022457fe5b602002018181525050600190505b606481101562000285576200025f8184620003386401000000000262000902179091906401000000009004565b82826064811015156200026e57fe5b602002018181525050808060010191505062000232565b8160029060646200029892919062000388565b5050505050565b60008060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614905090565b60008060008414156200030d576000915062000331565b82840290508284828115156200031f57fe5b041415156200032d57600080fd5b8091505b5092915050565b6000806000831115156200034b57600080fd5b82848115156200035757fe5b0490508091505092915050565b610c8060405190810160405280606490602082028038833980820191505090505090565b8260648101928215620003ba579160200282015b82811115620003b95782518255916020019190600101906200039c565b5b509050620003c99190620003cd565b5090565b620003f291905b80821115620003ee576000816000905550600101620003d4565b5090565b90565b610adb80620004056000396000f3006080604052600436106100a4576000357c0100000000000000000000000000000000000000000000000000000000900463ffffffff1680630c60e0c3146100a9578063379607f5146100d6578063715018a6146101035780637365870b1461011a5780638da5cb5b1461013a5780638f32d59b14610191578063e1152343146101c0578063ed88c68e14610201578063f2fde38b1461020b578063fc1c39dc1461024e575b600080fd5b3480156100b557600080fd5b506100d460048036038101908080359060200190929190505050610279565b005b3480156100e257600080fd5b50610101600480360381019080803590602001909291905050506103cb565b005b34801561010f57600080fd5b506101186104be565b005b61013860048036038101908080359060200190929190505050610590565b005b34801561014657600080fd5b5061014f610803565b604051808273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390f35b34801561019d57600080fd5b506101a661082c565b604051808215151515815260200191505060405180910390f35b3480156101cc57600080fd5b506101eb60048036038101908080359060200190929190505050610883565b6040518082815260200191505060405180910390f35b61020961089d565b005b34801561021757600080fd5b5061024c600480360381019080803573ffffffffffffffffffffffffffffffffffffffff16906020019092919050505061089f565b005b34801561025a57600080fd5b506102636108be565b6040518082815260200191505060405180910390f35b6000610283610a26565b600061028d61082c565b151561029857600080fd5b606484101515610336576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260248152602001807f4578706563746174696f6e2073686f756c64206265206c657373207468616e2081526020017f3130302e0000000000000000000000000000000000000000000000000000000081525060400191505060405180910390fd5b83600181905550610352612710856108c490919063ffffffff16565b9250600082600060648110151561036557fe5b602002018181525050600190505b60648110156103b35761038f818461090290919063ffffffff16565b828260648110151561039d57fe5b6020020181815250508080600101915050610373565b8160029060646103c4929190610a4a565b5050505050565b6103d361082c565b15156103de57600080fd5b3073ffffffffffffffffffffffffffffffffffffffff1631811115151561046d576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252601c8152602001807f4e6f20656e6f756768206f6620746f6b656e20746f20636c61696d2e0000000081525060200191505060405180910390fd5b610475610803565b73ffffffffffffffffffffffffffffffffffffffff166108fc829081150290604051600060405180830381858888f193505050501580156104ba573d6000803e3d6000fd5b5050565b6104c661082c565b15156104d157600080fd5b600073ffffffffffffffffffffffffffffffffffffffff166000809054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e060405160405180910390a360008060006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550565b60008060018311151561060b576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260188152602001807f5461726765742073686f756c64206265206269676765722e000000000000000081525060200191505060405180910390fd5b6001548311151515610685576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260198152602001807f5461726765742073686f756c6420626520736d616c6c65722e0000000000000081525060200191505060405180910390fd5b612710341115156106fe576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260158152602001807f4d696e696d756d206265742069732031303030302e000000000000000000000081525060200191505060405180910390fd5b600160642f81151561070c57fe5b0601915060009050828210156107a05761075661271061074860026001870360648110151561073757fe5b0154346108c490919063ffffffff16565b61090290919063ffffffff16565b90503373ffffffffffffffffffffffffffffffffffffffff166108fc829081150290604051600060405180830381858888f1935050505015801561079e573d6000803e3d6000fd5b505b3373ffffffffffffffffffffffffffffffffffffffff167f97371a3349bea11f577edf6e64350a3dfb9de665d1154c7e6d08eb0805aa043084348460405180848152602001838152602001828152602001935050505060405180910390a2505050565b60008060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905090565b60008060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614905090565b60028160648110151561089257fe5b016000915090505481565b565b6108a761082c565b15156108b257600080fd5b6108bb8161092c565b50565b60015481565b60008060008414156108d957600091506108fb565b82840290508284828115156108ea57fe5b041415156108f757600080fd5b8091505b5092915050565b60008060008311151561091457600080fd5b828481151561091f57fe5b0490508091505092915050565b600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff161415151561096857600080fd5b8073ffffffffffffffffffffffffffffffffffffffff166000809054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e060405160405180910390a3806000806101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555050565b610c8060405190810160405280606490602082028038833980820191505090505090565b8260648101928215610a79579160200282015b82811115610a78578251825591602001919060010190610a5d565b5b509050610a869190610a8a565b5090565b610aac91905b80821115610aa8576000816000905550600101610a90565b5090565b905600a165627a7a7230582087d19571ab3ae7207fb8f6182b6b891f2414f00e1904790341a82c957044b5330029")
@@ -47,19 +48,18 @@ func init() {
func (m *Monkey) Gamble() uint64 {
fmt.Println("Deploying contract ...")
- contract := m.deploy(m.source, betContract, betConstructor, new(big.Int), math.MaxUint64)
+ contract := m.Deploy(m.source, betContract, betConstructor, new(big.Int), math.MaxUint64)
fmt.Println(" Contract deployed: ", contract.String())
fmt.Println("Donating ...")
input, err := betABI.Pack("donate")
if err != nil {
panic(err)
}
- m.transfer(&transferContext{
+ m.Transfer(&client.TransferContext{
Key: m.source,
ToAddress: contract,
Amount: new(big.Int).Set(oneDEX),
Data: input,
- Gas: 0,
Nonce: math.MaxUint64,
})
@@ -74,9 +74,9 @@ func (m *Monkey) Gamble() uint64 {
loop:
for {
fmt.Println("nonce", nonce)
- ctxs := make([]*transferContext, len(m.keys))
+ ctxs := make([]*client.TransferContext, len(m.keys))
for i, key := range m.keys {
- ctx := &transferContext{
+ ctx := &client.TransferContext{
Key: key,
ToAddress: contract,
Amount: big.NewInt(100000),
@@ -87,11 +87,11 @@ loop:
if config.Batch {
ctxs[i] = ctx
} else {
- m.transfer(ctx)
+ m.Transfer(ctx)
}
}
if config.Batch {
- m.batchTransfer(ctxs)
+ m.BatchTransfer(ctxs)
}
if m.timer != nil {
@@ -102,7 +102,7 @@ loop:
}
}
- nonce += 1
+ nonce++
time.Sleep(time.Duration(config.Sleep) * time.Millisecond)
}
diff --git a/cmd/zoo/monkey/monkey.go b/cmd/zoo/monkey/monkey.go
index a511c42fa..c228f1814 100644
--- a/cmd/zoo/monkey/monkey.go
+++ b/cmd/zoo/monkey/monkey.go
@@ -22,17 +22,15 @@ package monkey
import (
"context"
"crypto/ecdsa"
+ "encoding/hex"
"fmt"
- "math"
"math/big"
"math/rand"
+ "os"
"time"
- dexon "github.com/dexon-foundation/dexon"
- "github.com/dexon-foundation/dexon/common"
- "github.com/dexon-foundation/dexon/core/types"
+ "github.com/dexon-foundation/dexon/cmd/zoo/client"
"github.com/dexon-foundation/dexon/crypto"
- "github.com/dexon-foundation/dexon/ethclient"
)
var config *MonkeyConfig
@@ -53,19 +51,37 @@ func Init(cfg *MonkeyConfig) {
}
type Monkey struct {
- client *ethclient.Client
- source *ecdsa.PrivateKey
- keys []*ecdsa.PrivateKey
- networkID *big.Int
- timer <-chan time.Time
+ client.Client
+
+ source *ecdsa.PrivateKey
+ keys []*ecdsa.PrivateKey
+ timer <-chan time.Time
}
func New(ep string, source *ecdsa.PrivateKey, num int, timeout time.Duration) *Monkey {
- client, err := ethclient.Dial(ep)
+ client, err := client.New(ep)
if err != nil {
panic(err)
}
+ file := func() *os.File {
+ for i := 0; i < 100; i++ {
+ name := fmt.Sprintf("zoo-%d.keys", i)
+ file, err := os.OpenFile(name,
+ os.O_CREATE|os.O_WRONLY|os.O_EXCL, 0600)
+ if err != nil {
+ continue
+ }
+ fmt.Printf("Save keys to file %s\n", name)
+ return file
+ }
+ return nil
+ }()
+ if file == nil {
+ panic(fmt.Errorf("Failed to create file for zoo keys"))
+ }
+ defer file.Close()
+
var keys []*ecdsa.PrivateKey
for i := 0; i < num; i++ {
@@ -73,19 +89,17 @@ func New(ep string, source *ecdsa.PrivateKey, num int, timeout time.Duration) *M
if err != nil {
panic(err)
}
+ _, err = file.Write([]byte(hex.EncodeToString(crypto.FromECDSA(key)) + "\n"))
+ if err != nil {
+ panic(err)
+ }
keys = append(keys, key)
}
- networkID, err := client.NetworkID(context.Background())
- if err != nil {
- panic(err)
- }
-
monkey := &Monkey{
- client: client,
- source: source,
- keys: keys,
- networkID: networkID,
+ Client: *client,
+ source: source,
+ keys: keys,
}
if timeout > 0 {
@@ -95,160 +109,29 @@ func New(ep string, source *ecdsa.PrivateKey, num int, timeout time.Duration) *M
return monkey
}
-type transferContext struct {
- Key *ecdsa.PrivateKey
- ToAddress common.Address
- Amount *big.Int
- Data []byte
- Nonce uint64
- Gas uint64
-}
-
-func (m *Monkey) prepareTx(ctx *transferContext) *types.Transaction {
- if ctx.Nonce == math.MaxUint64 {
- var err error
- address := crypto.PubkeyToAddress(ctx.Key.PublicKey)
- ctx.Nonce, err = m.client.PendingNonceAt(context.Background(), address)
- if err != nil {
- panic(err)
- }
- }
-
- if ctx.Gas == uint64(0) {
- var err error
- ctx.Gas, err = m.client.EstimateGas(context.Background(), dexon.CallMsg{
- Data: ctx.Data,
- })
- if err != nil {
- panic(err)
- }
- }
-
- gasPrice, err := m.client.SuggestGasPrice(context.Background())
- if err != nil {
- panic(err)
- }
-
- tx := types.NewTransaction(
- ctx.Nonce,
- ctx.ToAddress,
- ctx.Amount,
- ctx.Gas,
- gasPrice,
- ctx.Data)
-
- signer := types.NewEIP155Signer(m.networkID)
- tx, err = types.SignTx(tx, signer, ctx.Key)
- if err != nil {
- panic(err)
- }
-
- return tx
-}
-
-func (m *Monkey) transfer(ctx *transferContext) {
- tx := m.prepareTx(ctx)
-
- err := m.client.SendTransaction(context.Background(), tx)
- if err != nil {
- panic(err)
- }
-}
-
-func (m *Monkey) batchTransfer(ctxs []*transferContext) {
- txs := make([]*types.Transaction, len(ctxs))
- for i, ctx := range ctxs {
- txs[i] = m.prepareTx(ctx)
- }
-
- err := m.client.SendTransactions(context.Background(), txs)
- if err != nil {
- panic(err)
- }
-}
-
-func (m *Monkey) deploy(
- key *ecdsa.PrivateKey, code string, ctors []string, amount *big.Int, nonce uint64) common.Address {
-
- address := crypto.PubkeyToAddress(key.PublicKey)
- if nonce == math.MaxUint64 {
- var err error
- nonce, err = m.client.PendingNonceAt(context.Background(), address)
- if err != nil {
- panic(err)
- }
- }
-
- var input string
- for _, ctor := range ctors {
- input += fmt.Sprintf("%064s", ctor)
- }
- data := common.Hex2Bytes(code + input)
-
- gas, err := m.client.EstimateGas(context.Background(), dexon.CallMsg{
- From: address,
- Data: data,
- })
- if err != nil {
- panic(err)
- }
-
- tx := types.NewContractCreation(
- nonce,
- amount,
- gas,
- big.NewInt(1e9),
- data)
-
- signer := types.NewEIP155Signer(m.networkID)
- tx, err = types.SignTx(tx, signer, key)
- if err != nil {
- panic(err)
- }
-
- fmt.Println("Sending TX", "fullhash", tx.Hash().String())
-
- err = m.client.SendTransaction(context.Background(), tx)
- if err != nil {
- panic(err)
- }
-
- for {
- time.Sleep(500 * time.Millisecond)
- recp, err := m.client.TransactionReceipt(context.Background(), tx.Hash())
- if err != nil {
- if err == dexon.NotFound {
- continue
- }
- panic(err)
- }
- return recp.ContractAddress
- }
-}
-
func (m *Monkey) Distribute() {
fmt.Println("Distributing DEX to random accounts ...")
address := crypto.PubkeyToAddress(m.source.PublicKey)
- nonce, err := m.client.PendingNonceAt(context.Background(), address)
+ nonce, err := m.PendingNonceAt(context.Background(), address)
if err != nil {
panic(err)
}
- ctxs := make([]*transferContext, len(m.keys))
+ ctxs := make([]*client.TransferContext, len(m.keys))
for i, key := range m.keys {
address := crypto.PubkeyToAddress(key.PublicKey)
amount := new(big.Int)
amount.SetString("1000000000000000000", 10)
- ctxs[i] = &transferContext{
+ ctxs[i] = &client.TransferContext{
Key: m.source,
ToAddress: address,
Amount: amount,
Nonce: nonce,
Gas: 21000,
}
- nonce += 1
+ nonce++
}
- m.batchTransfer(ctxs)
+ m.BatchTransfer(ctxs)
time.Sleep(20 * time.Second)
}
@@ -257,12 +140,12 @@ func (m *Monkey) Crazy() uint64 {
nonce := uint64(0)
loop:
for {
- ctxs := make([]*transferContext, len(m.keys))
+ ctxs := make([]*client.TransferContext, len(m.keys))
for i, key := range m.keys {
to := crypto.PubkeyToAddress(m.keys[rand.Int()%len(m.keys)].PublicKey)
amount := new(big.Int)
amount.SetString(fmt.Sprintf("%d0000000000000", rand.Intn(10)+1), 10)
- ctx := &transferContext{
+ ctx := &client.TransferContext{
Key: key,
ToAddress: to,
Amount: amount,
@@ -272,11 +155,11 @@ loop:
if config.Batch {
ctxs[i] = ctx
} else {
- m.transfer(ctx)
+ m.Transfer(ctx)
}
}
if config.Batch {
- m.batchTransfer(ctxs)
+ m.BatchTransfer(ctxs)
}
fmt.Printf("Sent %d transactions, nonce = %d\n", len(m.keys), nonce)
@@ -288,7 +171,7 @@ loop:
}
}
- nonce += 1
+ nonce++
time.Sleep(time.Duration(config.Sleep) * time.Millisecond)
}
diff --git a/cmd/zoo/utils/shutdown.go b/cmd/zoo/utils/shutdown.go
new file mode 100644
index 000000000..288f664f6
--- /dev/null
+++ b/cmd/zoo/utils/shutdown.go
@@ -0,0 +1,114 @@
+// Copyright 2019 The dexon-consensus Authors
+// This file is part of the dexon-consensus library.
+//
+// The dexon-consensus library is free software: you can redistribute it
+// and/or modify it under the terms of the GNU Lesser General Public License as
+// published by the Free Software Foundation, either version 3 of the License,
+// or (at your option) any later version.
+//
+// The dexon-consensus library is distributed in the hope that it will be
+// useful, but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser
+// General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public License
+// along with the dexon-consensus library. If not, see
+// <http://www.gnu.org/licenses/>.
+
+package utils
+
+import (
+ "bufio"
+ "context"
+ "encoding/hex"
+ "fmt"
+ "io"
+ "math"
+ "math/big"
+ "os"
+
+ "github.com/dexon-foundation/dexon"
+ "github.com/dexon-foundation/dexon/cmd/zoo/client"
+ "github.com/dexon-foundation/dexon/crypto"
+)
+
+type ShutdownConfig struct {
+ Key string
+ Endpoint string
+ File string
+ Batch bool
+}
+
+func Shutdown(config *ShutdownConfig) {
+ privKey, err := crypto.LoadECDSA(config.Key)
+ if err != nil {
+ panic(err)
+ }
+ addr := crypto.PubkeyToAddress(privKey.PublicKey)
+
+ cl, err := client.New(config.Endpoint)
+ if err != nil {
+ panic(err)
+ }
+
+ file, err := os.Open(config.File)
+ if err != nil {
+ panic(err)
+ }
+ defer file.Close()
+
+ ctxs := make([]*client.TransferContext, 0)
+ reader := bufio.NewReader(file)
+ for {
+ buf, err := reader.ReadString('\n')
+ if err == io.EOF {
+ break
+ }
+ if err != nil {
+ panic(err)
+ }
+ buf = buf[:len(buf)-1]
+ key, err := hex.DecodeString(buf)
+ if err != nil {
+ panic(err)
+ }
+ prvKey, err := crypto.ToECDSA(key)
+ if err != nil {
+ panic(err)
+ }
+ balance, err := cl.BalanceAt(context.Background(),
+ crypto.PubkeyToAddress(prvKey.PublicKey), nil)
+ if err != nil {
+ panic(err)
+ }
+
+ gasLimit, err := cl.EstimateGas(context.Background(), dexon.CallMsg{})
+ if err != nil {
+ panic(err)
+ }
+ gasPrice, err := cl.SuggestGasPrice(context.Background())
+ if err != nil {
+ panic(err)
+ }
+ gas := new(big.Int).Mul(gasPrice, big.NewInt(int64(gasLimit)))
+ if gas.Cmp(balance) >= 0 {
+ fmt.Println("Skipping account: not enough of DXN", crypto.PubkeyToAddress(prvKey.PublicKey))
+ continue
+ }
+
+ ctx := &client.TransferContext{
+ Key: prvKey,
+ ToAddress: addr,
+ Amount: new(big.Int).Sub(balance, gas),
+ Nonce: math.MaxUint64,
+ }
+ if !config.Batch {
+ cl.Transfer(ctx)
+ } else {
+ ctxs = append(ctxs, ctx)
+ }
+ }
+ if config.Batch {
+ cl.BatchTransfer(ctxs)
+ }
+}