From c9b5450778afa40c97fe863d9ed89f9e8c8ff447 Mon Sep 17 00:00:00 2001 From: Jimmy Hu Date: Sat, 4 May 2019 22:18:40 +0800 Subject: zoo: refacter and save keys (#403) --- cmd/zoo/client/client.go | 190 ++++++++++++++++++++++++++++++++++++++++++ cmd/zoo/main.go | 12 +++ cmd/zoo/monkey/feeder.go | 23 +++--- cmd/zoo/monkey/gambler.go | 16 ++-- cmd/zoo/monkey/monkey.go | 205 ++++++++++------------------------------------ cmd/zoo/utils/shutdown.go | 114 ++++++++++++++++++++++++++ 6 files changed, 380 insertions(+), 180 deletions(-) create mode 100644 cmd/zoo/client/client.go create mode 100644 cmd/zoo/utils/shutdown.go (limited to 'cmd/zoo') 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 +// . + +// 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 +// . + +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) + } +} -- cgit