func LoadPackage(fileName string) (*definitions.Package, error) { log.Info("Loading eris-pm Package Definition File.") var pkg = definitions.BlankPackage() var epmJobs = viper.New() // setup file abs, err := filepath.Abs(fileName) if err != nil { return nil, fmt.Errorf("Sorry, the marmots were unable to find the absolute path to the eris-pm jobs file.") } path := filepath.Dir(abs) file := filepath.Base(abs) extName := filepath.Ext(file) bName := file[:len(file)-len(extName)] log.WithFields(log.Fields{ "path": path, "name": bName, }).Debug("Loading eris-pm file") epmJobs.AddConfigPath(path) epmJobs.SetConfigName(bName) // load file if err := epmJobs.ReadInConfig(); err != nil { return nil, fmt.Errorf("Sorry, the marmots were unable to load the eris-pm jobs file. Please check your path.\nERROR =>\t\t\t%v", err) } // marshall file if err := epmJobs.Unmarshal(pkg); err != nil { return nil, fmt.Errorf("Sorry, the marmots could not figure that eris-pm jobs file out.\nPlease check your epm.yaml is properly formatted.\n") } return pkg, nil }
func assembleTypesWizard(accountT *definitions.AccountType, tokenIze bool) error { var err error accountT.Number, err = common.GetIntResponse(AccountTypeIntro(accountT), accountT.Number, reader) log.WithField("=>", accountT.Number).Debug("What the marmots heard") if err != nil { return err } if tokenIze && accountT.Number > 0 { accountT.Tokens, err = common.GetIntResponse(AccountTypeTokens(accountT), accountT.Tokens, reader) log.WithField("=>", accountT.Tokens).Debug("What the marmots heard") if err != nil { return err } } if accountT.Perms["bond"] == 1 && accountT.Number > 0 { accountT.ToBond, err = common.GetIntResponse(AccountTypeToBond(accountT), accountT.ToBond, reader) log.WithField("=>", accountT.ToBond).Debug("What the marmots heard") if err != nil { return err } } else { log.Info("Setting accountType.ToBond to 0") log.WithField("=>", accountT.Name).Debug("No bond permissions") accountT.ToBond = 0 } return nil }
func MakeChain(do *definitions.Do) error { switch { case len(do.AccountTypes) != 0: log.Info("Making chain using account type paradigm.") return makeRaw(do, "accounttype") case do.ChainType != "": log.Info("Making chain using chain type paradigm.") return makeRaw(do, "chaintype") case do.CSV != "": log.Info("Making chain using csv type paradigm.") return makeRaw(do, "csv") default: log.Info("Making chain using wizard paradigm.") return makeWizard(do) } return nil }
func postProcess(do *definitions.Do) error { switch do.DefaultOutput { case "csv": log.Info("Writing [epm.csv] to current directory") for _, job := range do.Package.Jobs { if err := util.WriteJobResultCSV(job.JobName, job.JobResult); err != nil { return err } } case "json": log.Info("Writing [jobs_output.json] to current directory") results := make(map[string]string) for _, job := range do.Package.Jobs { results[job.JobName] = job.JobResult } return util.WriteJobResultJSON(results) } if do.SummaryTable { // TableWriter goes here. } return nil }
func DeployJob(deploy *definitions.Deploy, do *definitions.Do) (result string, err error) { // Preprocess variables deploy.Source, _ = util.PreProcess(deploy.Source, do) deploy.Contract, _ = util.PreProcess(deploy.Contract, do) deploy.Instance, _ = util.PreProcess(deploy.Instance, do) deploy.Libraries, _ = util.PreProcessLibs(deploy.Libraries, do) deploy.Amount, _ = util.PreProcess(deploy.Amount, do) deploy.Nonce, _ = util.PreProcess(deploy.Nonce, do) deploy.Fee, _ = util.PreProcess(deploy.Fee, do) deploy.Gas, _ = util.PreProcess(deploy.Gas, do) // trim the extension contractName := strings.TrimSuffix(deploy.Contract, filepath.Ext(deploy.Contract)) // Use defaults deploy.Source = useDefault(deploy.Source, do.Package.Account) deploy.Instance = useDefault(deploy.Instance, contractName) deploy.Amount = useDefault(deploy.Amount, do.DefaultAmount) deploy.Fee = useDefault(deploy.Fee, do.DefaultFee) deploy.Gas = useDefault(deploy.Gas, do.DefaultGas) // assemble contract var p string if _, err := os.Stat(deploy.Contract); err == nil { p = deploy.Contract } else { p = filepath.Join(do.ContractsPath, deploy.Contract) } log.WithField("=>", p).Info("Contract path") // use the proper compiler if do.Compiler != "" { log.WithField("=>", do.Compiler).Info("Setting compiler path") } // Don't use pubKey if account override var oldKey string if deploy.Source != do.Package.Account { oldKey = do.PublicKey do.PublicKey = "" } // compile if filepath.Ext(deploy.Contract) == ".bin" { log.Info("Binary file detected. Using binary deploy sequence.") // binary deploy sequence contractCode, err := ioutil.ReadFile(p) if err != nil { result := "could not read binary file" return result, err } tx, err := deployRaw(do, deploy, contractName, string(contractCode)) if err != nil { result := "could not deploy binary contract" return result, err } result, err := deployFinalize(do, tx, deploy.Wait) if err != nil { return "", fmt.Errorf("Error finalizing contract deploy %s: %v", p, err) } return result, err } else { // normal compilation/deploy sequence resp, err := compilers.BeginCompile(do.Compiler, p, false, deploy.Libraries) if err != nil { log.Errorln("Error compiling contracts: Compilers error:") return "", err } else if resp.Error != "" { log.Errorln("Error compiling contracts: Language error:") return "", fmt.Errorf("%v", resp.Error) } // loop through objects returned from compiler switch { case len(resp.Objects) == 1: log.WithField("path", p).Info("Deploying the only contract in file") r := resp.Objects[0] if r.Bytecode != "" { result, err = deployContract(deploy, do, r, p) if err != nil { return "", err } } case deploy.Instance == "all": log.WithField("path", p).Info("Deploying all contracts") var baseObj string for _, r := range resp.Objects { if r.Bytecode == "" { continue } result, err = deployContract(deploy, do, r, p) if err != nil { return "", err } if strings.ToLower(r.Objectname) == strings.ToLower(strings.TrimSuffix(filepath.Base(deploy.Contract), filepath.Ext(filepath.Base(deploy.Contract)))) { baseObj = result } } if baseObj != "" { result = baseObj } default: log.WithField("contract", deploy.Instance).Info("Deploying a single contract") for _, r := range resp.Objects { if r.Bytecode == "" { continue } if strings.ToLower(r.Objectname) == strings.ToLower(deploy.Instance) { result, err = deployContract(deploy, do, r, p) if err != nil { return "", err } } } } } // Don't use pubKey if account override if deploy.Source != do.Package.Account { do.PublicKey = oldKey } return result, nil }
func CallJob(call *definitions.Call, do *definitions.Do) (string, []*definitions.Variable, error) { var err error var callData string var callDataArray []string // Preprocess variables call.Source, _ = util.PreProcess(call.Source, do) call.Destination, _ = util.PreProcess(call.Destination, do) //todo: find a way to call the fallback function here call.Function, callDataArray, err = util.PreProcessInputData(call.Function, call.Data, do, false) if err != nil { return "", make([]*definitions.Variable, 0), err } call.Function, _ = util.PreProcess(call.Function, do) call.Amount, _ = util.PreProcess(call.Amount, do) call.Nonce, _ = util.PreProcess(call.Nonce, do) call.Fee, _ = util.PreProcess(call.Fee, do) call.Gas, _ = util.PreProcess(call.Gas, do) call.ABI, _ = util.PreProcess(call.ABI, do) // Use default call.Source = useDefault(call.Source, do.Package.Account) call.Amount = useDefault(call.Amount, do.DefaultAmount) call.Fee = useDefault(call.Fee, do.DefaultFee) call.Gas = useDefault(call.Gas, do.DefaultGas) // formulate call var packedBytes []byte if call.ABI == "" { packedBytes, err = util.ReadAbiFormulateCall(call.Destination, call.Function, callDataArray, do) callData = hex.EncodeToString(packedBytes) } else { packedBytes, err = util.ReadAbiFormulateCall(call.ABI, call.Function, callDataArray, do) callData = hex.EncodeToString(packedBytes) } if err != nil { if call.Function == "()" { log.Warn("Calling the fallback function") } else { var str, err = util.ABIErrorHandler(do, err, call, nil) return str, make([]*definitions.Variable, 0), err } } // Don't use pubKey if account override var oldKey string if call.Source != do.Package.Account { oldKey = do.PublicKey do.PublicKey = "" } log.WithFields(log.Fields{ "destination": call.Destination, "function": call.Function, "data": callData, }).Info("Calling") erisNodeClient := client.NewErisNodeClient(do.Chain) erisKeyClient := keys.NewErisKeyClient(do.Signer) tx, err := core.Call(erisNodeClient, erisKeyClient, do.PublicKey, call.Source, call.Destination, call.Amount, call.Nonce, call.Gas, call.Fee, callData) if err != nil { return "", make([]*definitions.Variable, 0), err } // Don't use pubKey if account override if call.Source != do.Package.Account { do.PublicKey = oldKey } // Sign, broadcast, display res, err := core.SignAndBroadcast(do.ChainID, erisNodeClient, erisKeyClient, tx, true, true, call.Wait) if err != nil { var str, err = util.MintChainErrorHandler(do, err) return str, make([]*definitions.Variable, 0), err } txResult := res.Return var result string log.Debug(txResult) // Formally process the return if txResult != nil { log.WithField("=>", result).Debug("Decoding Raw Result") if call.ABI == "" { call.Variables, err = util.ReadAndDecodeContractReturn(call.Destination, call.Function, txResult, do) } else { call.Variables, err = util.ReadAndDecodeContractReturn(call.ABI, call.Function, txResult, do) } if err != nil { return "", make([]*definitions.Variable, 0), err } log.WithField("=>", call.Variables).Debug("call variables:") result = util.GetReturnValue(call.Variables) if result != "" { log.WithField("=>", result).Warn("Return Value") } else { log.Debug("No return.") } } else { log.Debug("No return from contract.") } if call.Save == "tx" { log.Info("Saving tx hash instead of contract return") result = fmt.Sprintf("%X", res.Hash) } return result, call.Variables, nil }
PreRun: func(cmd *cobra.Command, args []string) { // loop through chains directories to make sure they exist for _, d := range []string{ChainsPath, AccountsTypePath, ChainTypePath} { if _, err := os.Stat(d); os.IsNotExist(err) { os.MkdirAll(d, 0755) } } // drop default tomls into eris' location IfExit(util.CheckDefaultTypes(AccountsTypePath, "account-types")) IfExit(util.CheckDefaultTypes(ChainTypePath, "chain-types")) keys.DaemonAddr = keysAddr // Welcomer.... log.Info("Hello! I'm the marmot who makes eris chains.") }, Run: MakeChain, PostRun: Archive, } // build the data subcommand func buildMakerCommand() { AddMakerFlags() } // Flags that are to be used by commands are handled by the Do struct // Define the persistent commands (globals) func AddMakerFlags() { MakerCmd.PersistentFlags().StringVarP(&keysAddr, "keys-server", "k", defaultKeys(), "keys server which should be used to generate keys; default respects $ERIS_KEYS_PATH") MakerCmd.PersistentFlags().StringSliceVarP(&do.AccountTypes, "account-types", "t", defaultActTypes(), "what number of account types should we use? find these in ~/.eris/chains/account_types; incompatible with and overrides chain-type; default respects $ERIS_CHAINMANAGER_ACCOUNTTYPES")
PersistentPreRun: func(cmd *cobra.Command, args []string) { // TODO: make this better.... need proper epm config // need to be able to have variable writers (eventually) log.SetLevel(log.WarnLevel) if do.Verbose { log.SetLevel(log.InfoLevel) } else if do.Debug { log.SetLevel(log.DebugLevel) } // clears epm.log file util.ClearJobResults() // Welcomer.... log.Info("Hello! I'm EPM.") // Fixes path issues and controls for mint-client / eris-keys assumptions // util.BundleHttpPathCorrect(do) util.PrintPathPackage(do) // Populates chainID from the chain (if its not passed) common.IfExit(util.GetChainID(do)) }, Run: RunPackage, PersistentPostRun: func(cmd *cobra.Command, args []string) { // Ensure that errors get written to screen and generally flush the log // log.Flush() },