Пример #1
0
func assembleTypesChainsTypesDefs(accountT []*definitions.AccountType, do *definitions.Do) error {
	clearDefaultNumbers(accountT)

	chainTypeAccounts, err := LoadChainTypes(do.ChainType)
	if err != nil {
		return err
	}

	log.WithFields(log.Fields{
		"chainType": do.ChainType,
	}).Debug("Chain Type Loaded")

	for act, num := range chainTypeAccounts.AccountTypes {
		for _, thisActT := range accountT {
			// we match against the accountType we get from the chain-type file
			// which will be upper case, however the current yaml unmarshal sequence
			// seems to lower case this for some odd reason.
			// TODO: see if burntsushi's toml renderer will handle this better in the future
			if thisActT.Name == strings.Title(act) {
				thisActT.Number = num
				log.WithFields(log.Fields{
					"name":   thisActT.Name,
					"number": thisActT.Number,
				}).Debug("Setting Account Type Number")
			}
		}
	}
	return nil
}
Пример #2
0
func assembleTypesFlags(accountT []*definitions.AccountType, do *definitions.Do) error {
	clearDefaultNumbers(accountT)

	for _, acctT := range do.AccountTypes {
		tmp := strings.Split(acctT, ":")
		act := tmp[0]

		var (
			err error

			// If the number of account types is missing,
			// assuming 1.
			num int = 1
		)
		if len(tmp) > 1 {
			num, err = strconv.Atoi(tmp[1])
			if err != nil {
				return err
			}
		}

		for _, thisActT := range accountT {
			if thisActT.Name == act {
				thisActT.Number = num
				log.WithFields(log.Fields{
					"name":   thisActT.Name,
					"number": thisActT.Number,
				}).Debug("Setting Account Type Number")
			}
		}
	}
	return nil
}
Пример #3
0
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
}
Пример #4
0
func BondJob(bond *definitions.Bond, do *definitions.Do) (string, error) {
	// Process Variables
	bond.Account, _ = util.PreProcess(bond.Account, do)
	bond.Amount, _ = util.PreProcess(bond.Amount, do)
	bond.PublicKey, _ = util.PreProcess(bond.PublicKey, do)

	// Use Defaults
	bond.Account = useDefault(bond.Account, do.Package.Account)
	do.PublicKey = useDefault(do.PublicKey, bond.PublicKey)

	// Formulate tx
	log.WithFields(log.Fields{
		"public key": do.PublicKey,
		"amount":     bond.Amount,
	}).Infof("Bond Transaction")

	erisNodeClient := client.NewErisNodeClient(do.Chain)
	erisKeyClient := keys.NewErisKeyClient(do.Signer)
	tx, err := core.Bond(erisNodeClient, erisKeyClient, do.PublicKey, bond.Account, bond.Amount, bond.Nonce)
	if err != nil {
		return util.MintChainErrorHandler(do, err)
	}

	// Sign, broadcast, display
	return txFinalize(do, tx, bond.Wait)
}
Пример #5
0
func assembleTypesCSV(accountT []*definitions.AccountType, do *definitions.Do) error {
	clearDefaultNumbers(accountT)

	csvfile, err := os.Open(do.CSV)
	if err != nil {
		return err
	}
	defer csvfile.Close()

	reader := csv.NewReader(csvfile)
	reader.TrimLeadingSpace = true

	rawCSVdata, err := reader.ReadAll()
	if err != nil {
		return err
	}
	log.WithField("rawCSVdata", rawCSVdata).Debug("Data read.")

	for _, record := range rawCSVdata {
		act, num, tokens, toBond, perms := record[0], record[1], record[2], record[3], record[4:]
		for _, thisActT := range accountT {
			if thisActT.Name == act {
				var err error
				thisActT.Number, err = strconv.Atoi(num)
				if err != nil {
					return err
				}
				thisActT.Tokens, err = strconv.Atoi(tokens)
				if err != nil {
					return err
				}
				thisActT.ToBond, err = strconv.Atoi(toBond)
				if err != nil {
					return err
				}
				permsPrime := make(map[string]int)
				for i := 0; i < len(perms); i++ {
					p, err := strconv.Atoi(perms[i+1])
					if err != nil {
						return err
					}
					permsPrime[perms[i]] = p
					i++
				}
				thisActT.Perms = permsPrime
				log.WithFields(log.Fields{
					"name":   thisActT.Name,
					"number": thisActT.Number,
					"tokens": thisActT.Tokens,
					"toBond": thisActT.ToBond,
					"perms":  thisActT.Perms,
				}).Debug("Setting Account Type Number")
			}
		}
	}
	return nil
}
Пример #6
0
// ensures that the files which are included in this repository (`defaultTyps`) are also
// present in the user's .eris/chains/account_types directory.
//
// does not ensure that the contents of the files are the same so will not affect user
// defined settings around these files.
//
// does not check if the user has more account_types files in their .eris/chains/account_types
// directory either so users can safely add additional account_types beyond the marmot
// established defaults.
func CheckDefaultTypes(erisPath, myPath string) error {
	// by default the dockerimage will move the default files to /default
	//   however if anyone installs by binary then these files will be located
	//   in the repo.
	defaultTypsPath := filepath.Join("/defaults", myPath, "*.toml")
	if _, err := os.Stat(filepath.Dir(defaultTypsPath)); os.IsNotExist(err) {
		log.WithField("path", defaultTypsPath).Warn("Default types path does not exist. Trying GOPATH.")
		defaultTypsPath = filepath.Join(ErisGo, version.NAME, myPath, "*.toml")
	}
	if _, err := os.Stat(filepath.Dir(defaultTypsPath)); os.IsNotExist(err) {
		log.WithField("path", defaultTypsPath).Info("Default types path does not exist. Exiting.")
		return fmt.Errorf("Could not locate default directory for %s", myPath)
	}

	// files in the default location which is /defaults in the docker image and $GOPATH/src/github.com/.../
	//   if binary install
	defaultTyps, err := filepath.Glob(defaultTypsPath)
	if err != nil {
		return err
	}

	// these are files which are in ~/.eris/chains/XXXXX and imported to the data container
	//   by cli
	haveTyps, err := AccountTypesNames(erisPath, true)
	if err != nil {
		return err
	}

	// fail fast if there are not files present in either imported or in default directory
	if len(defaultTyps) == 0 && len(haveTyps) == 0 {
		return fmt.Errorf("There are no default or custom types to use.")
	}

	for _, file := range defaultTyps {
		f := filepath.Base(file)
		itsThere := false

		// check if present
		for _, b := range haveTyps {
			if f == b {
				itsThere = true
			}
		}

		if !itsThere {
			log.WithFields(log.Fields{
				"file": file,
				"path": filepath.Join(erisPath, f),
			}).Debug("Copying default file")
			Copy(file, filepath.Join(erisPath, f))
		}
	}

	return nil
}
Пример #7
0
func deployRaw(do *definitions.Do, deploy *definitions.Deploy, contractName, contractCode string) (*txs.CallTx, error) {

	// Deploy contract
	log.WithFields(log.Fields{
		"name": contractName,
	}).Warn("Deploying Contract")

	log.WithFields(log.Fields{
		"source": deploy.Source,
		"code":   contractCode,
	}).Info()

	erisNodeClient := client.NewErisNodeClient(do.Chain)
	erisKeyClient := keys.NewErisKeyClient(do.Signer)
	tx, err := core.Call(erisNodeClient, erisKeyClient, do.PublicKey, deploy.Source, "", deploy.Amount, deploy.Nonce, deploy.Gas, deploy.Fee, contractCode)
	if err != nil {
		return &txs.CallTx{}, fmt.Errorf("Error deploying contract %s: %v", contractName, err)
	}

	return tx, err
}
Пример #8
0
func replaceBlockVariable(toReplace string, do *definitions.Do) (string, error) {
	log.WithFields(log.Fields{
		"chain": do.Chain,
		"var":   toReplace,
	}).Debug("Correcting $block variable")
	blockHeight, err := GetBlockHeight(do)
	block := strconv.Itoa(blockHeight)
	log.WithField("=>", block).Debug("Current height is")
	if err != nil {
		return "", err
	}

	if toReplace == "$block" {
		log.WithField("=>", block).Debug("Replacement (=)")
		return block, nil
	}

	catchEr := regexp.MustCompile("\\$block\\+(\\d*)")
	if catchEr.MatchString(toReplace) {
		height := catchEr.FindStringSubmatch(toReplace)[1]
		h1, err := strconv.Atoi(height)
		if err != nil {
			return "", err
		}
		h2, err := strconv.Atoi(block)
		if err != nil {
			return "", err
		}
		height = strconv.Itoa(h1 + h2)
		log.WithField("=>", height).Debug("Replacement (+)")
		return height, nil
	}

	catchEr = regexp.MustCompile("\\$block\\-(\\d*)")
	if catchEr.MatchString(toReplace) {
		height := catchEr.FindStringSubmatch(toReplace)[1]
		h1, err := strconv.Atoi(height)
		if err != nil {
			return "", err
		}
		h2, err := strconv.Atoi(block)
		if err != nil {
			return "", err
		}
		height = strconv.Itoa(h1 - h2)
		log.WithField("=>", height).Debug("Replacement (-)")
		return height, nil
	}

	log.WithField("=>", toReplace).Debug("Replacement (unknown)")
	return toReplace, nil
}
Пример #9
0
func ReadAbiFormulateCall(abiLocation string, funcName string, args []string, do *definitions.Do) ([]byte, error) {
	abiSpecBytes, err := readAbi(do.ABIPath, abiLocation)
	if err != nil {
		return []byte{}, err
	}
	log.WithField("=>", string(abiSpecBytes)).Debug("ABI Specification (Formulate)")
	log.WithFields(log.Fields{
		"function":  funcName,
		"arguments": fmt.Sprintf("%v", args),
	}).Debug("Packing Call via ABI")

	return ebi.Packer(abiSpecBytes, funcName, args...)
}
Пример #10
0
func ABIErrorHandler(do *definitions.Do, err error, call *definitions.Call, query *definitions.QueryContract) (string, error) {
	switch {
	case call != nil:
		log.WithFields(log.Fields{
			"data":   call.Data,
			"abi":    call.ABI,
			"dest":   call.Destination,
			"rawErr": err,
		}).Error("ABI Error")
	case query != nil:
		log.WithFields(log.Fields{
			"data":   query.Data,
			"abi":    query.ABI,
			"dest":   query.Destination,
			"rawErr": err,
		}).Error("ABI Error")
	}

	return "", fmt.Errorf(`
There has been an error in finding or in using your ABI. ABI's are "Application Binary
Interface" and they are what let us know how to talk to smart contracts.

These little json files can be read by a variety of things which need to talk to smart
contracts so they are quite necessary to be able to find and use properly.

The ABIs are saved after the deploy events. So if there was a glitch in the matrix,
we apologize in advance.

The marmot recovery checklist is...
  * ensure your chain is running and you have enough validators online
  * ensure that your contracts successfully deployed
  * if you used imports or have multiple contracts in one file check the instance
    variable in the deploy and the abi variable in the call/query-contract
  * make sure you're calling or querying the right function
  * make sure you're using the correct variables for job results
`)
}
Пример #11
0
func makeKey(keyType string, account *definitions.Account) error {
	log.WithFields(log.Fields{
		"path": keys.DaemonAddr,
		"type": keyType,
	}).Debug("Sending Call to eris-keys server")

	var err error
	log.WithField("endpoint", "gen").Debug()
	account.Address, err = keys.Call("gen", map[string]string{"auth": "", "type": keyType, "name": account.Name}) // note, for now we use not password to lock/unlock keys
	if _, ok := err.(keys.ErrConnectionRefused); ok {
		return fmt.Errorf("Could not connect to eris-keys server. Start it with `eris services start keys`. Error: %v", err)
	}
	if err != nil {
		return err
	}

	log.WithField("endpoint", "pub").Debug()
	account.PubKey, err = keys.Call("pub", map[string]string{"addr": account.Address, "name": account.Name})
	if _, ok := err.(keys.ErrConnectionRefused); ok {
		return fmt.Errorf("Could not connect to eris-keys server. Start it with `eris services start keys`. Error: %v", err)
	}
	if err != nil {
		return err
	}

	// log.WithField("endpoint", "to-mint").Debug()
	// mint, err := keys.Call("to-mint", map[string]string{"addr": account.Address, "name": account.Name})

	log.WithField("endpoint", "mint").Debug()
	mint, err := keys.Call("mint", map[string]string{"addr": account.Address, "name": account.Name})
	if _, ok := err.(keys.ErrConnectionRefused); ok {
		return fmt.Errorf("Could not connect to eris-keys server. Start it with `eris services start keys`. Error: %v", err)
	}
	if err != nil {
		return err
	}

	account.MintKey = &definitions.MintPrivValidator{}
	err = json.Unmarshal([]byte(mint), account.MintKey)
	if err != nil {
		log.Error(string(mint))
		log.Error(account.MintKey)
		return err
	}

	account.MintKey.Address = account.Address
	return nil
}
Пример #12
0
// Runs an individual nametx.
func registerNameTx(name *definitions.RegisterName, do *definitions.Do) (string, error) {
	// Process Variables
	name.Source, _ = util.PreProcess(name.Source, do)
	name.Name, _ = util.PreProcess(name.Name, do)
	name.Data, _ = util.PreProcess(name.Data, do)
	name.Amount, _ = util.PreProcess(name.Amount, do)
	name.Fee, _ = util.PreProcess(name.Fee, do)

	// Set Defaults
	name.Source = useDefault(name.Source, do.Package.Account)
	name.Fee = useDefault(name.Fee, do.DefaultFee)
	name.Amount = useDefault(name.Amount, do.DefaultAmount)

	// Don't use pubKey if account override
	var oldKey string
	if name.Source != do.Package.Account {
		oldKey = do.PublicKey
		do.PublicKey = ""
	}

	// Formulate tx
	log.WithFields(log.Fields{
		"name":   name.Name,
		"data":   name.Data,
		"amount": name.Amount,
	}).Info("NameReg Transaction")

	erisNodeClient := client.NewErisNodeClient(do.Chain)
	erisKeyClient := keys.NewErisKeyClient(do.Signer)
	tx, err := core.Name(erisNodeClient, erisKeyClient, do.PublicKey, name.Source, name.Amount, name.Nonce, name.Fee, name.Name, name.Data)
	if err != nil {
		return util.MintChainErrorHandler(do, err)
	}

	// Don't use pubKey if account override
	if name.Source != do.Package.Account {
		do.PublicKey = oldKey
	}

	// Sign, broadcast, display
	return txFinalize(do, tx, name.Wait)
}
Пример #13
0
func MintChainErrorHandler(do *definitions.Do, err error) (string, error) {
	log.WithFields(log.Fields{
		"defAddr":  do.Package.Account,
		"chainID":  do.ChainID,
		"chainURL": do.Chain,
		"rawErr":   err,
	}).Error("")

	return "", fmt.Errorf(`
There has been an error talking to your eris chain.

%v

Debugging this error is tricky, but don't worry the marmot recovery checklist is...
  * is the %s account right?
  * is the account you want to use in your keys service: eris keys ls ?
  * is the account you want to use in your genesis.json: eris chains cat %s genesis ?
  * is your chain making blocks: eris chains logs -f %s ?
  * do you have permissions to do what you're trying to do on the chain?
`, err, do.Package.Account, do.ChainID, do.ChainID)
}
Пример #14
0
func QueryNameJob(query *definitions.QueryName, do *definitions.Do) (string, error) {
	// Preprocess variables
	query.Name, _ = util.PreProcess(query.Name, do)
	query.Field, _ = util.PreProcess(query.Field, do)

	// Peform query
	log.WithFields(log.Fields{
		"name":  query.Name,
		"field": query.Field,
	}).Info("Querying")
	result, err := util.NamesInfo(query.Name, query.Field, do)
	if err != nil {
		return "", err
	}

	if result != "" {
		log.WithField("=>", result).Warn("Return Value")
	} else {
		log.Debug("No return.")
	}
	return result, nil
}
Пример #15
0
func SendJob(send *definitions.Send, do *definitions.Do) (string, error) {

	// Process Variables
	send.Source, _ = util.PreProcess(send.Source, do)
	send.Destination, _ = util.PreProcess(send.Destination, do)
	send.Amount, _ = util.PreProcess(send.Amount, do)

	// Use Default
	send.Source = useDefault(send.Source, do.Package.Account)

	// Don't use pubKey if account override
	var oldKey string
	if send.Source != do.Package.Account {
		oldKey = do.PublicKey
		do.PublicKey = ""
	}

	// Formulate tx
	log.WithFields(log.Fields{
		"source":      send.Source,
		"destination": send.Destination,
		"amount":      send.Amount,
	}).Info("Sending Transaction")

	erisNodeClient := client.NewErisNodeClient(do.Chain)
	erisKeyClient := keys.NewErisKeyClient(do.Signer)
	tx, err := core.Send(erisNodeClient, erisKeyClient, do.PublicKey, send.Source, send.Destination, send.Amount, send.Nonce)
	if err != nil {
		return util.MintChainErrorHandler(do, err)
	}

	// Don't use pubKey if account override
	if send.Source != do.Package.Account {
		do.PublicKey = oldKey
	}

	// Sign, broadcast, display
	return txFinalize(do, tx, send.Wait)
}
Пример #16
0
func MakeMintChain(name string, accounts []*definitions.Account, chainImageName string,
	useDataContainer bool, exportedPorts []string, containerEntrypoint string) error {
	genesis := definitions.BlankGenesis()
	genesis.ChainID = name
	for _, account := range accounts {
		log.WithFields(log.Fields{
			"name":    account.Name,
			"address": account.Address,
			"tokens":  account.Tokens,
			"perms":   account.MintPermissions.MintBase.MintPerms,
		}).Debug("Making a Mint Account")

		thisAct := MakeMintAccount(account)
		genesis.Accounts = append(genesis.Accounts, thisAct)

		if account.Validator {
			thisVal := MakeMintValidator(account)
			genesis.Validators = append(genesis.Validators, thisVal)
		}
	}
	for _, account := range accounts {
		if err := util.WritePrivVals(genesis.ChainID, account, len(accounts) == 1); err != nil {
			return err
		}
		if err := util.WriteGenesisFile(genesis.ChainID, genesis, account, len(accounts) == 1); err != nil {
			return err
		}
		// TODO: [ben] we can expose seeds to be written into the configuration file
		// here, but currently not used and we'll overwrite the configuration file
		// with flag or environment variable in eris-db container
		if err := util.WriteConfigurationFile(genesis.ChainID, account.Name, "",
			len(accounts) == 1, chainImageName, useDataContainer, exportedPorts,
			containerEntrypoint); err != nil {
			return err
		}
	}
	return nil
}
Пример #17
0
func RebondJob(rebond *definitions.Rebond, do *definitions.Do) (string, error) {
	// Process Variables
	var err error
	rebond.Account, err = util.PreProcess(rebond.Account, do)
	rebond.Height, err = util.PreProcess(rebond.Height, do)
	if err != nil {
		return "", err
	}

	// Use defaults
	rebond.Account = useDefault(rebond.Account, do.Package.Account)

	// Don't use pubKey if account override
	var oldKey string
	if rebond.Account != do.Package.Account {
		oldKey = do.PublicKey
		do.PublicKey = ""
	}

	// Formulate tx
	log.WithFields(log.Fields{
		"account": rebond.Account,
		"height":  rebond.Height,
	}).Info("Rebond Transaction")

	tx, err := core.Rebond(rebond.Account, rebond.Height)
	if err != nil {
		return util.MintChainErrorHandler(do, err)
	}

	// Don't use pubKey if account override
	if rebond.Account != do.Package.Account {
		do.PublicKey = oldKey
	}

	// Sign, broadcast, display
	return txFinalize(do, tx, rebond.Wait)
}
Пример #18
0
func KeysErrorHandler(do *definitions.Do, err error) (string, error) {
	log.WithFields(log.Fields{
		"defAddr": do.Package.Account,
	}).Error("")

	r := regexp.MustCompile(fmt.Sprintf("open /home/eris/.eris/keys/data/%s/%s: no such file or directory", do.Package.Account, do.Package.Account))
	if r.MatchString(fmt.Sprintf("%v", err)) {
		return "", fmt.Errorf(`
Unfortunately the marmots could not find the key you are trying to use in the keys service.

There are two ways to fix this.
  1. Import your keys from your host: eris keys import %s
  2. Import your keys from your chain:

eris chains exec %s "mintkey eris chains/%s/priv_validator.json" && \
eris services exec keys "chown eris:eris -R /home/eris"

Now, run  eris keys ls  to check that the keys are available. If they are not there
then change the account. Once you have verified that the keys for account

%s

are in the keys service, then rerun me.
`, do.Package.Account, do.ChainID, do.ChainID, do.Package.Account)
	}

	return "", fmt.Errorf(`
There has been an error talking to your eris keys service.

%v

Debugging this error is tricky, but don't worry the marmot recovery checklist is...
  * is your %s account right?
  * is the key for %s in your keys service: eris keys ls ?
`, err, do.Package.Account, do.Package.Account)
}
Пример #19
0
func Tarball(do *definitions.Do) error {

	paths, err := filepath.Glob(filepath.Join(ChainsPath, do.Name, "*"))
	if err != nil {
		return err
	}

	for _, path := range paths {
		fileP := fmt.Sprintf("%s.tar.gz", path)
		log.WithFields(log.Fields{
			// "path": path,
			"file": fileP,
		}).Debug("Making A Tarball")

		dir, err := os.Open(path)
		if err != nil {
			return err
		}
		defer dir.Close()

		files, err := dir.Readdir(0) // grab the files list
		if err != nil {
			return err
		}

		tarfile, err := os.Create(fileP)
		if err != nil {
			return err
		}
		defer tarfile.Close()

		var fileWriter io.WriteCloser = tarfile
		fileWriter = gzip.NewWriter(tarfile)
		defer fileWriter.Close()

		tarfileWriter := tar.NewWriter(fileWriter)
		defer tarfileWriter.Close()

		for _, fileInfo := range files {
			if fileInfo.IsDir() {
				continue
			}

			file, err := os.Open(dir.Name() + string(filepath.Separator) + fileInfo.Name())
			if err != nil {
				return err
			}
			defer file.Close()

			// log.WithField("file", fileInfo.Name()).Debug("Adding File Info to Tarball")
			header := new(tar.Header)
			header.Name = filepath.Base(file.Name())
			header.Size = fileInfo.Size()
			header.Mode = int64(fileInfo.Mode())
			header.ModTime = fileInfo.ModTime()

			if err := tarfileWriter.WriteHeader(header); err != nil {
				return err
			}

			_, err = io.Copy(tarfileWriter, file)
			if err != nil {
				return err
			}
		}

		log.WithField("dir", path).Debug("Removing Directory.")
		if err := os.RemoveAll(path); err != nil {
			return err
		}
	}
	return nil
}
Пример #20
0
func Zip(do *definitions.Do) error {

	paths, err := filepath.Glob(filepath.Join(ChainsPath, do.Name, "*"))
	if err != nil {
		return err
	}

	for _, path := range paths {
		fileP := fmt.Sprintf("%s.zip", path)
		log.WithFields(log.Fields{
			"path": path,
			"file": fileP,
		}).Debug("Making A ZipFile")

		dir, err := os.Open(path)
		if err != nil {
			return err
		}
		defer dir.Close()

		files, err := dir.Readdir(0) // grab the files list
		if err != nil {
			return err
		}

		newfile, err := os.Create(fileP)
		if err != nil {
			return err
		}
		defer newfile.Close()

		zipit := zip.NewWriter(newfile)
		defer zipit.Close()

		for _, fileInfo := range files {
			// log.WithField("file", fileInfo.Name()).Debug("Adding File Info to ZipFile")
			if fileInfo.IsDir() {
				continue
			}

			file, err := os.Open(dir.Name() + string(filepath.Separator) + fileInfo.Name())
			if err != nil {
				return err
			}
			defer file.Close()

			header, err := zip.FileInfoHeader(fileInfo)
			if err != nil {
				return err
			}
			header.Method = zip.Deflate

			writer, err := zipit.CreateHeader(header)
			if err != nil {
				return err
			}
			_, err = io.Copy(writer, file)
			if err != nil {
				return err
			}
		}

		log.WithField("dir", path).Debug("Removing Directory.")
		if err := os.RemoveAll(path); err != nil {
			return err
		}
	}
	return nil
}
Пример #21
0
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
}
Пример #22
0
func PreProcess(toProcess string, do *definitions.Do) (string, error) {
	// $block.... $account.... etc. should be caught. hell$$o should not
	// :$libAddr needs to be caught
	catchEr := regexp.MustCompile("(^|\\s|:)\\$([a-zA-Z0-9_.]+)")
	// If there's a match then run through the replacement process
	if catchEr.MatchString(toProcess) {
		log.WithField("match", toProcess).Debug("Replacement Match Found")

		// find what we need to catch.
		processedString := toProcess

		for _, jobMatch := range catchEr.FindAllStringSubmatch(toProcess, -1) {
			jobName := jobMatch[2]
			varName := "$" + jobName
			var innerVarName string
			var wantsInnerValues bool = false
			/*
				log.WithFields(log.Fields{
				 	"var": varName,
				 	"job": jobName,
				}).Debugf("Correcting match %d", i+1)
			*/
			// first parse the reserved words.
			if strings.Contains(jobName, "block") {
				block, err := replaceBlockVariable(toProcess, do)
				if err != nil {
					log.WithField("err", err).Error("Error replacing block variable.")
					return "", err
				}
				/*log.WithFields(log.Fields{
					"var": toProcess,
					"res": block,
				}).Debug("Fixing Variables =>")*/
				processedString = strings.Replace(processedString, toProcess, block, 1)
			}

			if strings.Contains(jobName, ".") { //for functions with multiple returns
				wantsInnerValues = true
				var splitStr = strings.Split(jobName, ".")
				jobName = splitStr[0]
				innerVarName = splitStr[1]
			}

			// second we loop through the jobNames to do a result replace
			for _, job := range do.Package.Jobs {
				if string(jobName) == job.JobName {
					if wantsInnerValues {
						for _, innerVal := range job.JobVars {
							if innerVal.Name == innerVarName { //find the value we want from the bunch
								processedString = strings.Replace(processedString, varName, innerVal.Value, 1)
								log.WithFields(log.Fields{
									"job":     string(jobName),
									"varName": innerVarName,
									"result":  innerVal.Value,
								}).Debug("Fixing Inner Vars =>")
							}
						}
					} else {
						log.WithFields(log.Fields{
							"var": string(jobName),
							"res": job.JobResult,
						}).Debug("Fixing Variables =>")
						processedString = strings.Replace(processedString, varName, job.JobResult, 1)
					}
				}
			}
		}
		return processedString, nil
	}

	// if no matches, return original
	return toProcess, nil
}
Пример #23
0
func AssertJob(assertion *definitions.Assert, do *definitions.Do) (string, error) {
	var result string
	// Preprocess variables
	assertion.Key, _ = util.PreProcess(assertion.Key, do)
	assertion.Relation, _ = util.PreProcess(assertion.Relation, do)
	assertion.Value, _ = util.PreProcess(assertion.Value, do)

	// Switch on relation
	log.WithFields(log.Fields{
		"key":      assertion.Key,
		"relation": assertion.Relation,
		"value":    assertion.Value,
	}).Info("Assertion =>")

	switch assertion.Relation {
	case "==", "eq":
		/*log.Debug("Compare", strings.Compare(assertion.Key, assertion.Value))
		log.Debug("UTF8?: ", utf8.ValidString(assertion.Key))
		log.Debug("UTF8?: ", utf8.ValidString(assertion.Value))
		log.Debug("UTF8?: ", utf8.RuneCountInString(assertion.Key))
		log.Debug("UTF8?: ", utf8.RuneCountInString(assertion.Value))*/
		if assertion.Key == assertion.Value {
			return assertPass("==", assertion.Key, assertion.Value)
		} else {
			return assertFail("==", assertion.Key, assertion.Value)
		}
	case "!=", "ne":
		if assertion.Key != assertion.Value {
			return assertPass("!=", assertion.Key, assertion.Value)
		} else {
			return assertFail("!=", assertion.Key, assertion.Value)
		}
	case ">", "gt":
		k, v, err := bulkConvert(assertion.Key, assertion.Value)
		if err != nil {
			return convFail()
		}
		if k > v {
			return assertPass(">", assertion.Key, assertion.Value)
		} else {
			return assertFail(">", assertion.Key, assertion.Value)
		}
	case ">=", "ge":
		k, v, err := bulkConvert(assertion.Key, assertion.Value)
		if err != nil {
			return convFail()
		}
		if k >= v {
			return assertPass(">=", assertion.Key, assertion.Value)
		} else {
			return assertFail(">=", assertion.Key, assertion.Value)
		}
	case "<", "lt":
		k, v, err := bulkConvert(assertion.Key, assertion.Value)
		if err != nil {
			return convFail()
		}
		if k < v {
			return assertPass("<", assertion.Key, assertion.Value)
		} else {
			return assertFail("<", assertion.Key, assertion.Value)
		}
	case "<=", "le":
		k, v, err := bulkConvert(assertion.Key, assertion.Value)
		if err != nil {
			return convFail()
		}
		if k <= v {
			return assertPass("<=", assertion.Key, assertion.Value)
		} else {
			return assertFail("<=", assertion.Key, assertion.Value)
		}
	}

	return result, nil
}