<commit_before>package asset

import (
	"github.com/btcsuite/btcutil/hdkeychain"
	"golang.org/x/net/context"

	"chain/api/appdb"
	"chain/errors"
	"chain/fedchain-sandbox/hdkey"
)

var (
	// ErrBadXPub is returned by CreateNode.
	// It may be wrapped using package chain/errors.
	ErrBadXPub = errors.New("bad xpub")

	// ErrTooFewKeys can be returned by CreateNode if not enough keys
	// have been provided or generated.
	ErrTooFewKeys = errors.New("too few keys for signatures required")
)

type nodeType int

// Node types used for CreateNode
const (
	ManagerNode nodeType = iota
	IssuerNode  nodeType = iota
)

// CreateNodeReq is a user filled struct
// passed into CreateManagerNode or CreateIssuerNode
type CreateNodeReq struct {
	Label        string
	Keys         []*XPubInit
	SigsRequired int `json:"signatures_required"`
}

// DeprecatedCreateNodeReq is a user filled struct
// passed into CreateManagerNode or CreateIssuerNode.
// It is deprecated in favor of CreateNodeReq.
type DeprecatedCreateNodeReq struct {
	Label       string
	XPubs       []string
	GenerateKey bool `json:"generate_key"`
}

// XPubInit is a representation of an xpub used when nodes are being created.
// It includes the key itself, as well as two flags:
// Generate specifies whether the key needs to be generated server-side, and
// Variable specifies whether this is a placeholder for an account-specific key.
// If Variable is true, Generate must be false and Key must be empty.
type XPubInit struct {
	Key      string
	Generate bool
	Variable bool
}

// CreateNode is used to create manager and issuer nodes
func CreateNode(ctx context.Context, node nodeType, projID string, req *CreateNodeReq) (interface{}, error) {
	if req.Label == "" {
		return nil, appdb.ErrBadLabel
	}

	var (
		keys       []*hdkey.XKey
		gennedKeys []*hdkey.XKey
	)

	variableKeyCount := 0
	for i, xpub := range req.Keys {
		if xpub.Generate {
			pub, priv, err := newKey()
			if err != nil {
				return nil, err
			}
			keys = append(keys, pub)
			gennedKeys = append(gennedKeys, priv)
		} else if xpub.Variable {
			variableKeyCount++
		} else {
			key, err := hdkey.NewXKey(xpub.Key)
			if err != nil {
				err = errors.Wrap(ErrBadXPub, err.Error())
				return nil, errors.WithDetailf(err, "xpub %d", i)
			}
			keys = append(keys, key)<commit_msg>bugfix: return better error when xpubs are missing<commit_after>package asset

import (
	"github.com/btcsuite/btcutil/hdkeychain"
	"golang.org/x/net/context"

	"chain/api/appdb"
	"chain/errors"
	"chain/fedchain-sandbox/hdkey"
)

var (
	// ErrBadXPub is returned by CreateNode.
	// It may be wrapped using package chain/errors.
	ErrBadXPub = errors.New("bad xpub")

	// ErrTooFewKeys can be returned by CreateNode if not enough keys
	// have been provided or generated.
	ErrTooFewKeys = errors.New("too few keys for signatures required")
)

type nodeType int

// Node types used for CreateNode
const (
	ManagerNode nodeType = iota
	IssuerNode  nodeType = iota
)

// CreateNodeReq is a user filled struct
// passed into CreateManagerNode or CreateIssuerNode
type CreateNodeReq struct {
	Label        string
	Keys         []*XPubInit
	SigsRequired int `json:"signatures_required"`
}

// DeprecatedCreateNodeReq is a user filled struct
// passed into CreateManagerNode or CreateIssuerNode.
// It is deprecated in favor of CreateNodeReq.
type DeprecatedCreateNodeReq struct {
	Label       string
	XPubs       []string
	GenerateKey bool `json:"generate_key"`
}

// XPubInit is a representation of an xpub used when nodes are being created.
// It includes the key itself, as well as two flags:
// Generate specifies whether the key needs to be generated server-side, and
// Variable specifies whether this is a placeholder for an account-specific key.
// If Variable is true, Generate must be false and Key must be empty.
type XPubInit struct {
	Key      string
	Generate bool
	Variable bool
}

// CreateNode is used to create manager and issuer nodes
func CreateNode(ctx context.Context, node nodeType, projID string, req *CreateNodeReq) (interface{}, error) {
	if req.Label == "" {
		return nil, appdb.ErrBadLabel
	}

	var (
		keys       []*hdkey.XKey
		gennedKeys []*hdkey.XKey
	)

	variableKeyCount := 0
	for i, xpub := range req.Keys {
		if xpub.Generate {
			pub, priv, err := newKey()
			if err != nil {
				return nil, err
			}
			keys = append(keys, pub)
			gennedKeys = append(gennedKeys, priv)
		} else if xpub.Variable {
			variableKeyCount++
		} else if xpub.Key != "" {
			key, err := hdkey.NewXKey(xpub.Key)
			if err != nil {
				err = errors.Wrap(ErrBadXPub, err.Error())
				return nil, errors.WithDetailf(err, "xpub %d", i)
			}
			keys = append(keys, key)
		} else {
			return nil, errors.WithDetail(ErrBadXPub, "xpub must have `generated`, `variable` or `key` set")
{'fraction_non_alphanumeric': 0.09390651085141903, 'fraction_numerical': 0.00041736227045075126, 'mean_word_length': 3.4836295603367633, 'pattern_counts': {'":': 0, '<': 3, '<?xml version=': 0, '>': 3, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '627629', 'n_tokens_mistral': 1615, 'n_tokens_neox': 1500, 'n_words': 530}