From bbd7eb14df70377131968c130321e6f15de30b99 Mon Sep 17 00:00:00 2001 From: siovanus Date: Tue, 23 Jun 2020 18:38:19 +0800 Subject: [PATCH] init --- .gitignore | 12 +++ config.json | 8 ++ config/config.go | 88 +++++++++++++++++++++ core/core.go | 156 +++++++++++++++++++++++++++++++++++++ log4go.xml | 31 ++++++++ main.go | 62 +++++++++++++++ methods/methods.go | 26 +++++++ methods/triones/init.go | 32 ++++++++ methods/triones/methods.go | 99 +++++++++++++++++++++++ methods/triones/utils.go | 138 ++++++++++++++++++++++++++++++++ 10 files changed, 652 insertions(+) create mode 100644 .gitignore create mode 100644 config.json create mode 100644 config/config.go create mode 100644 core/core.go create mode 100644 log4go.xml create mode 100644 main.go create mode 100644 methods/methods.go create mode 100644 methods/triones/init.go create mode 100644 methods/triones/methods.go create mode 100644 methods/triones/utils.go diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..2d1bc20 --- /dev/null +++ b/.gitignore @@ -0,0 +1,12 @@ +.idea/* +idea/* +temp/* +build/ +*.patch +*.log +*.rej +vendor/* +*.iml +ontology-tool +wallet.dat +main \ No newline at end of file diff --git a/config.json b/config.json new file mode 100644 index 0000000..6c03c37 --- /dev/null +++ b/config.json @@ -0,0 +1,8 @@ +{ + "JsonRpcAddress":"http://localhost:20336", + "WalletPath": "wallet.dat", + "PeerPublicKey": "02d500543eaa4110b8d5f8df4fabe31a8caabaa58cb8512baa8af15a303606efe4", + "InitPos":100000, + "GasPrice":0, + "GasLimit":20000 +} diff --git a/config/config.go b/config/config.go new file mode 100644 index 0000000..d895cb0 --- /dev/null +++ b/config/config.go @@ -0,0 +1,88 @@ +/* + * Copyright (C) 2018 The ontology Authors + * This file is part of The ontology library. + * + * The ontology 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 ontology 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 ontology. If not, see . + */ + +//common use fot ontology-tool +package config + +import ( + "encoding/json" + "fmt" + log4 "github.com/alecthomas/log4go" + "io/ioutil" + "os" +) + +//Default config instance +var DefConfig = NewConfig() + +//Config object used by ontology-instance +type Config struct { + //JsonRpcAddress of ontology + JsonRpcAddress string + WalletPath string + PeerPublicKey string + InitPos uint32 + //Gas Price of transaction + GasPrice uint64 + //Gas Limit of invoke transaction + GasLimit uint64 +} + +//NewConfig retuen a Config instance +func NewConfig() *Config { + return &Config{} +} + +//Init Config with a config file +func (this *Config) Init(fileName string) error { + err := this.loadConfig(fileName) + if err != nil { + return fmt.Errorf("loadConfig error:%s", err) + } + return nil +} + +func (this *Config) loadConfig(fileName string) error { + data, err := this.readFile(fileName) + if err != nil { + return err + } + err = json.Unmarshal(data, this) + if err != nil { + return fmt.Errorf("json.Unmarshal TestConfig:%s error:%s", data, err) + } + return nil +} + +func (this *Config) readFile(fileName string) ([]byte, error) { + file, err := os.OpenFile(fileName, os.O_RDONLY, 0666) + if err != nil { + return nil, fmt.Errorf("OpenFile %s error %s", fileName, err) + } + defer func() { + err := file.Close() + if err != nil { + log4.Error("File %s close error %s", fileName, err) + } + }() + data, err := ioutil.ReadAll(file) + if err != nil { + return nil, fmt.Errorf("ioutil.ReadAll %s error %s", fileName, err) + } + return data, nil +} diff --git a/core/core.go b/core/core.go new file mode 100644 index 0000000..f90dd16 --- /dev/null +++ b/core/core.go @@ -0,0 +1,156 @@ +/* + * Copyright (C) 2018 The ontology Authors + * This file is part of The ontology library. + * + * The ontology 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 ontology 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 ontology. If not, see . + */ + +package core + +import ( + log4 "github.com/alecthomas/log4go" + sdk "github.com/ontio/ontology-go-sdk" + "github.com/ontio/triones-node-tool/config" +) + +var OntTool = NewOntologyTool() + +type Method func(sdk *sdk.OntologySdk) bool + +type OntologyTool struct { + //Map name to method + methodsMap map[string]Method + //Map method result + methodsRes map[string]bool +} + +func NewOntologyTool() *OntologyTool { + return &OntologyTool{ + methodsMap: make(map[string]Method, 0), + methodsRes: make(map[string]bool, 0), + } +} + +func (this *OntologyTool) RegMethod(name string, method Method) { + this.methodsMap[name] = method +} + +//Start run +func (this *OntologyTool) Start(methodsList []string) { + if len(methodsList) > 0 { + this.runMethodList(methodsList) + return + } + log4.Info("No method to run") + return +} + +func (this *OntologyTool) runMethodList(methodsList []string) { + this.onStart() + defer this.onFinish(methodsList) + ontSdk := sdk.NewOntologySdk() + ontSdk.NewRpcClient().SetAddress(config.DefConfig.JsonRpcAddress) + for i, method := range methodsList { + this.runMethod(i+1, ontSdk, method) + } +} + +func (this *OntologyTool) runMethod(index int, sdk *sdk.OntologySdk, methodName string) { + this.onBeforeMethodStart(index, methodName) + method := this.getMethodByName(methodName) + if method != nil { + ok := method(sdk) + this.onAfterMethodFinish(index, methodName, ok) + this.methodsRes[methodName] = ok + } +} + +func (this *OntologyTool) onStart() { + log4.Info("===============================================================") + log4.Info("-------Ontology Tool Start-------") + log4.Info("===============================================================") + log4.Info("") +} + +func (this *OntologyTool) onFinish(methodsList []string) { + failedList := make([]string, 0) + successList := make([]string, 0) + for methodName, ok := range this.methodsRes { + if ok { + successList = append(successList, methodName) + } else { + failedList = append(failedList, methodName) + } + } + + skipList := make([]string, 0) + for _, method := range methodsList { + _, ok := this.methodsRes[method] + if !ok { + skipList = append(skipList, method) + } + } + + succCount := len(successList) + failedCount := len(failedList) + + log4.Info("===============================================================") + log4.Info("Ontology Tool Finish Total:%v Success:%v Failed:%v Skip:%v", + len(methodsList), + succCount, + failedCount, + len(methodsList)-succCount-failedCount) + if succCount > 0 { + log4.Info("---------------------------------------------------------------") + log4.Info("Success list:") + for i, succ := range successList { + log4.Info("%d.\t%s", i+1, succ) + } + } + if failedCount > 0 { + log4.Info("---------------------------------------------------------------") + log4.Info("Fail list:") + for i, fail := range failedList { + log4.Info("%d.\t%s", i+1, fail) + } + } + if len(skipList) > 0 { + log4.Info("---------------------------------------------------------------") + log4.Info("Skip list:") + for i, skip := range skipList { + log4.Info("%d.\t%s", i+1, skip) + } + } + log4.Info("===============================================================") +} + +func (this *OntologyTool) onBeforeMethodStart(index int, methodName string) { + log4.Info("===============================================================") + log4.Info("%d. Start Method:%s", index, methodName) + log4.Info("---------------------------------------------------------------") +} + +func (this *OntologyTool) onAfterMethodFinish(index int, methodName string, res bool) { + if res { + log4.Info("Run Method:%s success.", methodName) + } else { + log4.Info("Run Method:%s failed.", methodName) + } + log4.Info("---------------------------------------------------------------") + log4.Info("") +} + +func (this *OntologyTool) getMethodByName(name string) Method { + return this.methodsMap[name] +} diff --git a/log4go.xml b/log4go.xml new file mode 100644 index 0000000..c5e9051 --- /dev/null +++ b/log4go.xml @@ -0,0 +1,31 @@ + + + stdout + console + + DEBUG + [%D %T] [%L] %M + + + file + file + DEBUG + ./log/test.log + + [%D %T] [%L] %M + false + 100M + 0K + true + + diff --git a/main.go b/main.go new file mode 100644 index 0000000..9ce3d76 --- /dev/null +++ b/main.go @@ -0,0 +1,62 @@ +/* + * Copyright (C) 2018 The ontology Authors + * This file is part of The ontology library. + * + * The ontology 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 ontology 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 ontology. If not, see . + */ +package main + +import ( + "flag" + "math/rand" + "strings" + "time" + + log4 "github.com/alecthomas/log4go" + "github.com/ontio/triones-node-tool/config" + "github.com/ontio/triones-node-tool/core" + _ "github.com/ontio/triones-node-tool/methods" +) + +var ( + Config string //config file + LogConfig string //Log config file + Methods string //Methods list in cmdline +) + +func init() { + flag.StringVar(&Config, "cfg", "./config.json", "Config of ontology-tool") + flag.StringVar(&LogConfig, "lfg", "./log4go.xml", "Log config of ontology-tool") + flag.StringVar(&Methods, "t", "", "methods to run. use ',' to split methods") + flag.Parse() +} + +func main() { + rand.Seed(time.Now().UnixNano()) + log4.LoadConfiguration(LogConfig) + defer time.Sleep(time.Second) + + err := config.DefConfig.Init(Config) + if err != nil { + log4.Error("DefConfig.Init error:%s", err) + return + } + + methods := make([]string, 0) + if Methods != "" { + methods = strings.Split(Methods, ",") + } + + core.OntTool.Start(methods) +} diff --git a/methods/methods.go b/methods/methods.go new file mode 100644 index 0000000..22fb34a --- /dev/null +++ b/methods/methods.go @@ -0,0 +1,26 @@ +/* + * Copyright (C) 2018 The ontology Authors + * This file is part of The ontology library. + * + * The ontology 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 ontology 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 ontology. If not, see . + */ +package methods + +import ( + "github.com/ontio/triones-node-tool/methods/triones" +) + +func init() { + triones.InitTriones() +} diff --git a/methods/triones/init.go b/methods/triones/init.go new file mode 100644 index 0000000..5deee14 --- /dev/null +++ b/methods/triones/init.go @@ -0,0 +1,32 @@ +/* + * Copyright (C) 2018 The ontology Authors + * This file is part of The ontology library. + * + * The ontology 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 ontology 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 ontology. If not, see . + */ + +package triones + +import ( + "github.com/ontio/triones-node-tool/core" +) + +func InitTriones() { + core.OntTool.RegMethod("RegisterTriones", RegisterTriones) + core.OntTool.RegMethod("QuitTriones", QuitTriones) + core.OntTool.RegMethod("WithdrawInitPos", WithdrawInitPos) + core.OntTool.RegMethod("WithdrawOng", WithdrawOng) + + core.OntTool.RegMethod("GetTrionesInfo", GetTrionesInfo) +} diff --git a/methods/triones/methods.go b/methods/triones/methods.go new file mode 100644 index 0000000..6f45ceb --- /dev/null +++ b/methods/triones/methods.go @@ -0,0 +1,99 @@ +/* + * Copyright (C) 2018 The ontology Authors + * This file is part of The ontology library. + * + * The ontology 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 ontology 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 ontology. If not, see . + */ + +package triones + +import ( + "fmt" + "github.com/ontio/celo-ontid/common" + sdk "github.com/ontio/ontology-go-sdk" + "github.com/ontio/triones-node-tool/config" +) + +func RegisterTriones(ontSdk *sdk.OntologySdk) bool { + user, ok := common.GetAccountByPassword(ontSdk, config.DefConfig.WalletPath) + if !ok { + return false + } + ok = registerCandidate(ontSdk, user, config.DefConfig.PeerPublicKey, config.DefConfig.InitPos) + if !ok { + return false + } + common.WaitForBlock(ontSdk) + return true +} + +func QuitTriones(ontSdk *sdk.OntologySdk) bool { + user, ok := common.GetAccountByPassword(ontSdk, config.DefConfig.WalletPath) + if !ok { + return false + } + ok = quitNode(ontSdk, user, config.DefConfig.PeerPublicKey) + if !ok { + return false + } + common.WaitForBlock(ontSdk) + return true +} + +func WithdrawInitPos(ontSdk *sdk.OntologySdk) bool { + user, ok := common.GetAccountByPassword(ontSdk, config.DefConfig.WalletPath) + if !ok { + return false + } + ok = withdraw(ontSdk, user, []string{config.DefConfig.PeerPublicKey}, []uint32{config.DefConfig.InitPos}) + if !ok { + return false + } + common.WaitForBlock(ontSdk) + return true +} + +func WithdrawOng(ontSdk *sdk.OntologySdk) bool { + user, ok := common.GetAccountByPassword(ontSdk, config.DefConfig.WalletPath) + if !ok { + return false + } + ok = withdrawFee(ontSdk, user) + if !ok { + return false + } + common.WaitForBlock(ontSdk) + return true +} + +func GetTrionesInfo(ontSdk *sdk.OntologySdk) bool { + peerPoolMap, err := getPeerPoolMap(ontSdk) + if err != nil { + fmt.Println("getPeerPoolMap failed ", err) + return false + } + + peerPoolItem, ok := peerPoolMap.PeerPoolMap[config.DefConfig.PeerPublicKey] + if !ok { + fmt.Println("Can't find peerPubkey in peerPoolMap") + return false + } + fmt.Println("peerPoolItem.Index is:", peerPoolItem.Index) + fmt.Println("peerPoolItem.PeerPubkey is:", peerPoolItem.PeerPubkey) + fmt.Println("peerPoolItem.Address is:", peerPoolItem.Address.ToBase58()) + fmt.Println("peerPoolItem.Status is:", peerPoolItem.Status) + fmt.Println("peerPoolItem.InitPos is:", peerPoolItem.InitPos) + fmt.Println("peerPoolItem.TotalPos is:", peerPoolItem.TotalPos) + return true +} diff --git a/methods/triones/utils.go b/methods/triones/utils.go new file mode 100644 index 0000000..7849b37 --- /dev/null +++ b/methods/triones/utils.go @@ -0,0 +1,138 @@ +package triones + +import ( + "bytes" + + log4 "github.com/alecthomas/log4go" + "github.com/ontio/ont-relayer/common" + sdk "github.com/ontio/ontology-go-sdk" + "github.com/ontio/ontology-tool/config" + ontcommon "github.com/ontio/ontology/common" + "github.com/ontio/ontology/errors" + "github.com/ontio/ontology/smartcontract/service/native/governance" + "github.com/ontio/ontology/smartcontract/service/native/utils" +) + +var OntIDVersion = byte(0) + +func registerCandidate(ontSdk *sdk.OntologySdk, user *sdk.Account, peerPubkey string, initPos uint32) bool { + params := &governance.RegisterCandidateParam{ + PeerPubkey: peerPubkey, + Address: user.Address, + InitPos: initPos, + } + method := "registerCandidate" + contractAddress := utils.GovernanceContractAddress + tx, err := ontSdk.Native.NewNativeInvokeTransaction(config.DefConfig.GasPrice, config.DefConfig.GasLimit, + OntIDVersion, contractAddress, method, []interface{}{params}) + if err != nil { + log4.Error("NewNativeInvokeTransaction error :", err) + return false + } + err = ontSdk.SignToTransaction(tx, user) + if err != nil { + log4.Error("SignToTransaction error :", err) + return false + } + txHash, err := ontSdk.SendTransaction(tx) + if err != nil { + log4.Error("SendTransaction error :", err) + return false + } + log4.Info("registerCandidate txHash is :", txHash.ToHexString()) + return true +} + +func quitNode(ontSdk *sdk.OntologySdk, user *sdk.Account, peerPubkey string) bool { + params := &governance.QuitNodeParam{ + PeerPubkey: peerPubkey, + Address: user.Address, + } + contractAddress := utils.GovernanceContractAddress + method := "quitNode" + txHash, err := ontSdk.Native.InvokeNativeContract(config.DefConfig.GasPrice, config.DefConfig.GasLimit, + user, user, OntIDVersion, contractAddress, method, []interface{}{params}) + if err != nil { + log4.Error("invokeNativeContract error :", err) + return false + } + log4.Info("quitNode txHash is :", txHash.ToHexString()) + return true +} + +func withdraw(ontSdk *sdk.OntologySdk, user *sdk.Account, peerPubkeyList []string, withdrawList []uint32) bool { + params := &governance.WithdrawParam{ + Address: user.Address, + PeerPubkeyList: peerPubkeyList, + WithdrawList: withdrawList, + } + contractAddress := utils.GovernanceContractAddress + method := "withdraw" + txHash, err := ontSdk.Native.InvokeNativeContract(config.DefConfig.GasPrice, config.DefConfig.GasLimit, + user, user, OntIDVersion, contractAddress, method, []interface{}{params}) + if err != nil { + log4.Error("invokeNativeContract error :", err) + return false + } + log4.Info("withdraw txHash is :", txHash.ToHexString()) + return true +} + +func withdrawFee(ontSdk *sdk.OntologySdk, user *sdk.Account) bool { + params := &governance.WithdrawFeeParam{ + Address: user.Address, + } + contractAddress := utils.GovernanceContractAddress + method := "withdrawFee" + txHash, err := ontSdk.Native.InvokeNativeContract(config.DefConfig.GasPrice, config.DefConfig.GasLimit, + user, user, OntIDVersion, contractAddress, method, []interface{}{params}) + if err != nil { + log4.Error("invokeNativeContract error :", err) + return false + } + log4.Info("withdrawFee txHash is :", txHash.ToHexString()) + return true +} + +func getGovernanceView(ontSdk *sdk.OntologySdk) (*governance.GovernanceView, error) { + contractAddress := utils.GovernanceContractAddress + governanceView := new(governance.GovernanceView) + key := []byte(governance.GOVERNANCE_VIEW) + value, err := ontSdk.GetStorage(contractAddress.ToHexString(), key) + if err != nil { + return nil, errors.NewDetailErr(err, errors.ErrNoCode, "getStorage error") + } + if err := governanceView.Deserialize(bytes.NewBuffer(value)); err != nil { + return nil, errors.NewDetailErr(err, errors.ErrNoCode, "deserialize, deserialize governanceView error!") + } + return governanceView, nil +} + +func getView(ontSdk *sdk.OntologySdk) (uint32, error) { + governanceView, err := getGovernanceView(ontSdk) + if err != nil { + return 0, errors.NewDetailErr(err, errors.ErrNoCode, "getGovernanceView error") + } + return governanceView.View, nil +} + +func getPeerPoolMap(ontSdk *sdk.OntologySdk) (*governance.PeerPoolMap, error) { + contractAddress := utils.GovernanceContractAddress + view, err := getView(ontSdk) + if err != nil { + return nil, errors.NewDetailErr(err, errors.ErrNoCode, "getView error") + } + peerPoolMap := &governance.PeerPoolMap{ + PeerPoolMap: make(map[string]*governance.PeerPoolItem), + } + viewBytes := governance.GetUint32Bytes(view) + key := common.ConcatKey([]byte(governance.PEER_POOL), viewBytes) + value, err := ontSdk.GetStorage(contractAddress.ToHexString(), key) + if err != nil { + return nil, errors.NewDetailErr(err, errors.ErrNoCode, "getStorage error") + } + if err := peerPoolMap.Deserialization(ontcommon.NewZeroCopySource(value)); err != nil { + return nil, errors.NewDetailErr(err, errors.ErrNoCode, "deserialize, deserialize peerPoolMap error!") + } + return peerPoolMap, nil +}