示例#1
0
func putChanCommitTxns(nodeChanBucket *bolt.Bucket, channel *OpenChannel) error {
	var bc bytes.Buffer
	if err := writeOutpoint(&bc, channel.ChanID); err != nil {
		return err
	}
	txnsKey := make([]byte, len(commitTxnsKey)+bc.Len())
	copy(txnsKey[:3], commitTxnsKey)
	copy(txnsKey[3:], bc.Bytes())

	var b bytes.Buffer

	if err := channel.OurCommitTx.Serialize(&b); err != nil {
		return err
	}

	if err := wire.WriteVarBytes(&b, 0, channel.OurCommitSig); err != nil {
		return err
	}

	// TODO(roasbeef): should move this into putChanFundingInfo
	scratch := make([]byte, 4)
	byteOrder.PutUint32(scratch, channel.LocalCsvDelay)
	if _, err := b.Write(scratch); err != nil {
		return err
	}
	byteOrder.PutUint32(scratch, channel.RemoteCsvDelay)
	if _, err := b.Write(scratch); err != nil {
		return err
	}

	return nodeChanBucket.Put(txnsKey, b.Bytes())
}
示例#2
0
func getGrantScopes(bucket *bolt.Bucket, grant string) map[string]bool {
	scopesByte := bucket.Get([]byte(grant))
	if scopesByte == nil {
		return nil
	}
	return database.StringToSet(string(scopesByte))
}
示例#3
0
// Params returns the currently stored configuration parameters for hook h
// from bucket b.
func (GithubValidator) Params(h Hook, b *bolt.Bucket) map[string]string {
	m := make(map[string]string)
	for _, k := range []string{"secret"} {
		m[k] = string(b.Get([]byte(fmt.Sprintf("%s-%s", h.ID, k))))
	}
	return m
}
示例#4
0
func addCityToIndex(
	bucket *bolt.Bucket, id string, name string, locale string, population uint32,
) error {
	var err error
	var cityName *ds.CityName

	if locale == "" {
		locale = "en"
	}

	cityNameKey := []byte(ds.PrepareCityNameKey(name))
	if conflict := bucket.Get(cityNameKey); conflict != nil {
		cityName, err = ds.CityNameFromString(string(cityNameKey), string(conflict))
		if strconv.Itoa(cityName.CityId) != id {
			cityNameKey = []byte(string(cityNameKey) + "|" + id)
		}
	}

	err = bucket.Put(
		cityNameKey, []byte(
			name+"\t"+id+"\t"+locale+"\t"+strconv.Itoa(int(population)),
		),
	)

	return err
}
示例#5
0
func fillBucket(b *bolt.Bucket, prefix []byte) error {
	n := 10 + rand.Intn(50)
	for i := 0; i < n; i++ {
		v := make([]byte, 10*(1+rand.Intn(4)))
		_, err := crypto.Read(v)
		if err != nil {
			return err
		}
		k := append(prefix, []byte(fmt.Sprintf("k%d", i))...)
		if err := b.Put(k, v); err != nil {
			return err
		}
	}
	// limit depth of subbuckets
	s := 2 + rand.Intn(4)
	if len(prefix) > (2*s + 1) {
		return nil
	}
	n = 1 + rand.Intn(3)
	for i := 0; i < n; i++ {
		k := append(prefix, []byte(fmt.Sprintf("b%d", i))...)
		sb, err := b.CreateBucket(k)
		if err != nil {
			return err
		}
		if err := fillBucket(sb, append(k, '.')); err != nil {
			return err
		}
	}
	return nil
}
示例#6
0
// Params returns the currently stored configuration parameters for hook h
// from bucket b.
func (ForwardRequestAction) Params(h Hook, b *bolt.Bucket) map[string]string {
	m := make(map[string]string)
	for _, k := range []string{"url"} {
		m[k] = string(b.Get([]byte(fmt.Sprintf("%s-%s", h.ID, k))))
	}
	return m
}
func PutTokenInfo(tokenInfo *TokenInfo) error {
	oldTokenInfo, err := GetTokenInfo(tokenInfo.Token, tokenInfo.Client)
	if err != nil {
		return err
	}
	if oldTokenInfo != nil {
		return errors.New("duplicate token")
	}
	err = db.Update(func(tx *bolt.Tx) error {
		var clientBucket *bolt.Bucket
		clientBucket = tx.Bucket([]byte(tokenInfo.Client))
		if clientBucket == nil {
			clientBucket, err = tx.CreateBucket([]byte(tokenInfo.Client))
			if err != nil {
				return err
			}
		}
		tokenBucket, err := clientBucket.CreateBucket([]byte(tokenInfo.Token))
		if err != nil {
			return err
		}
		tokenBucket.Put([]byte("token"), []byte(tokenInfo.Token))
		tokenBucket.Put([]byte("client"), []byte(tokenInfo.Client))
		tokenBucket.Put([]byte("user"), []byte(tokenInfo.User))
		tokenBucket.Put([]byte("scopes"), []byte(tokenInfo.Scopes))
		expireBinary, err := tokenInfo.ExpireTime.MarshalBinary()
		if err != nil {
			return err
		}
		tokenBucket.Put([]byte("expire-time"), expireBinary)
		return nil
	})
	return err
}
示例#8
0
func (store *BoltStore) Get(uri string, nested bool) (interface{}, error) {
	namespace, key := util.NamespaceKey(uri)
	bucketkeys := util.PathFolders(namespace)
	var bucket *bolt.Bucket = nil
	var result interface{}
	e := store.db.View(func(tx *bolt.Tx) error {
		for _, bucketkey := range bucketkeys {
			if bucket == nil {
				bucket = tx.Bucket([]byte(bucketkey))
				if bucket == nil {
					return errors.New(uri + " not exists")
				}
			} else {
				bucket = bucket.Bucket([]byte(bucketkey))
				if bucket == nil {
					return errors.New(uri + " not exists")
				}
			}
		}
		if bucket == nil {
			return errors.New(uri + " not exists")
		}

		val, err := store.get(bucket, key, nested)
		if err != nil {
			return err
		}
		result = val
		return nil
	})
	return result, e
}
示例#9
0
// Params returns the currently stored configuration parameters for hook h
// from bucket b.
func (EmailAction) Params(h Hook, b *bolt.Bucket) map[string]string {
	m := make(map[string]string)
	for _, k := range []string{"token", "domain", "address", "subject", "template"} {
		m[k] = string(b.Get([]byte(fmt.Sprintf("%s-%s", h.ID, k))))
	}
	return m
}
示例#10
0
func (store *BoltStore) MultiGet(uri string, suffix string, nested bool) ([]interface{}, error) {
	results := []interface{}{}
	bucketkeys := util.PathFolders(uri)
	var bucket *bolt.Bucket = nil
	e := store.db.View(func(tx *bolt.Tx) error {
		for _, bucketkey := range bucketkeys {
			if bucket == nil {
				bucket = tx.Bucket([]byte(bucketkey))
				if bucket == nil {
					return errors.New(uri + " not exists")
				}
			} else {
				bucket = bucket.Bucket([]byte(bucketkey))
				if bucket == nil {
					return errors.New(uri + " not exists")
				}
			}
		}
		if bucket == nil {
			return errors.New(uri + " not exists")
		}

		vals, err := store.multi_get(bucket, suffix, nested)
		if err != nil {
			return err
		}
		results = append(results, vals...)
		return nil
	})
	return results, e
}
示例#11
0
func (store *BoltStore) Size(uri string) (int64, error) {
	namespace, key := util.NamespaceKey(uri)
	bucketkeys := util.PathFolders(namespace)
	var bucket *bolt.Bucket = nil
	var result int64 = 0
	e := store.db.View(func(tx *bolt.Tx) error {
		for _, bucketkey := range bucketkeys {
			if bucket == nil {
				bucket = tx.Bucket([]byte(bucketkey))
				if bucket == nil {
					return errors.New(uri + " not exists")
				}
			} else {
				bucket = bucket.Bucket([]byte(bucketkey))
				if bucket == nil {
					return errors.New(uri + " not exists")
				}
			}
		}
		if bucket == nil {
			return errors.New(uri + " not exists")
		}

		result = store.size(bucket, key, nil)
		return nil
	})
	return result, e
}
示例#12
0
文件: db.go 项目: mbrodala/otto
func (this *DB) getData(bucket *bolt.Bucket) (map[string]int, ipQueue, error) {
	var addrQ ipQueue
	heapRaw := bucket.Get(boltAddrHeapKey)
	if heapRaw == nil {
		addrQ = ipQueue(make([]*ipEntry, 0, 1))
	} else {
		dec := gob.NewDecoder(bytes.NewReader(heapRaw))
		if err := dec.Decode(&addrQ); err != nil {
			return nil, nil, err
		}
	}

	var addrMap map[string]int
	mapRaw := bucket.Get(boltAddrMapKey)
	if mapRaw == nil {
		addrMap = make(map[string]int)
	} else {
		dec := gob.NewDecoder(bytes.NewReader(mapRaw))
		if err := dec.Decode(&addrMap); err != nil {
			return nil, nil, err
		}
	}

	return addrMap, addrQ, nil
}
示例#13
0
// Store a word,word -> word sequence
func storeWords(bucket *bolt.Bucket, word1, word2, word3 string) error {
	key := []byte(word1 + " " + word2)

	// Get value from bucket and decode it
	rawValue := bucket.Get(key)
	var value []string
	if rawValue == nil {
		value = make([]string, 0, 1)
	} else {
		if err := json.Unmarshal(rawValue, &value); err != nil {
			log.Printf("Cannot decode raw value for key '%v': %v; starting new empty key; old value is: %v", string(key), string(rawValue))
			value = make([]string, 0, 1)
		}
	}

	// Add new word to value
	value = append(value, word3)

	// Encode value and store it in bucket
	rawValue, err := json.Marshal(value)
	if err != nil {
		return err
	}

	if err := bucket.Put(key, rawValue); err != nil {
		return err
	}

	// All done
	return nil
}
示例#14
0
文件: tx.go 项目: jmptrader/unbolted
func (self *TX) dig(keys [][]byte, create bool) (buckets []*bolt.Bucket, err error) {
	var bucket *bolt.Bucket
	if create {
		if bucket, err = self.tx.CreateBucketIfNotExists(keys[0]); err != nil {
			return
		}
	} else {
		if bucket = self.tx.Bucket(keys[0]); bucket == nil {
			err = ErrNotFound
			return
		}
	}
	buckets = append(buckets, bucket)
	for keys = keys[1:]; len(keys) > 0; keys = keys[1:] {
		if create {
			if bucket, err = bucket.CreateBucketIfNotExists(keys[0]); err != nil {
				return
			}
		} else {
			if bucket = bucket.Bucket(keys[0]); bucket == nil {
				err = ErrNotFound
				return
			}
		}
		buckets = append(buckets, bucket)
	}
	return
}
示例#15
0
文件: program.go 项目: mnadel/boltq
func executeSelect(stmt *boltq.SelectStatement, db *bolt.DB) error {
	return db.View(func(tx *bolt.Tx) error {
		var bucket *bolt.Bucket

		for _, name := range stmt.BucketPath {
			log.Debugln("navigating to bucket", name)
			bucket = tx.Bucket([]byte(name))

			if bucket == nil {
				return fmt.Errorf("cannot find bucket %s", name)
			}
		}

		if containsAsterisk(stmt.Fields) {
			log.Debugln("interating keys")
			cursor := bucket.Cursor()

			for k, v := cursor.First(); k != nil; k, v = cursor.Next() {
				emitKeypair(k, v)
			}
		} else {
			for _, k := range stmt.Fields {
				keyBytes := []byte(k)
				v := bucket.Get(keyBytes)
				emitKeypair(keyBytes, v)
			}
		}

		return nil
	})
}
示例#16
0
// earliestChildTimestamp returns the earliest timestamp that a child node
// can have while still being valid. See section 'Timestamp Rules' in
// Consensus.md.
//
// To boost performance, earliestChildTimestamp is passed a bucket that it can
// use from inside of a boltdb transaction.
func earliestChildTimestamp(blockMap *bolt.Bucket, pb *processedBlock) types.Timestamp {
	// Get the previous MedianTimestampWindow timestamps.
	windowTimes := make(types.TimestampSlice, types.MedianTimestampWindow)
	windowTimes[0] = pb.Block.Timestamp
	parent := pb.Parent
	for i := uint64(1); i < types.MedianTimestampWindow; i++ {
		// If the genesis block is 'parent', use the genesis block timestamp
		// for all remaining times.
		if parent == (types.BlockID{}) {
			windowTimes[i] = windowTimes[i-1]
			continue
		}

		// Get the next parent's bytes. Because the ordering is specific, the
		// parent does not need to be decoded entirely to get the desired
		// information. This provides a performance boost. The id of the next
		// parent lies at the first 32 bytes, and the timestamp of the block
		// lies at bytes 40-48.
		parentBytes := blockMap.Get(parent[:])
		copy(parent[:], parentBytes[:32])
		windowTimes[i] = types.Timestamp(encoding.DecUint64(parentBytes[40:48]))
	}
	sort.Sort(windowTimes)

	// Return the median of the sorted timestamps.
	return windowTimes[len(windowTimes)/2]
}
示例#17
0
func findData(backetName string, option Option) error {
	var bucket *bolt.Bucket
	return db.View(func(tx *bolt.Tx) error {
		tx.ForEach(func(name []byte, b *bolt.Bucket) error {
			if backetName == string(name) {
				bucket = b
			}
			return nil
		})
		if bucket == nil {
			return errors.New("bucket not found")
		}
		c := bucket.Cursor()
		prefix := []byte(option.key)
		data := map[string]interface{}{}

	OUTER:
		for pk, v := c.Seek(prefix); bytes.HasPrefix(pk, prefix); pk, v = c.Next() {
			u := map[string]interface{}{}
			json.Unmarshal(v, &u)
			for fk, fv := range option.params {
				if u[fk] != fv {
					continue OUTER
				}
			}
			data[string(pk)] = u
		}

		showData(data)
		return nil
	})
}
示例#18
0
// targetAdjustmentBase returns the magnitude that the target should be
// adjusted by before a clamp is applied.
func (cs *ConsensusSet) targetAdjustmentBase(blockMap *bolt.Bucket, pb *processedBlock) *big.Rat {
	// Grab the block that was generated 'TargetWindow' blocks prior to the
	// parent. If there are not 'TargetWindow' blocks yet, stop at the genesis
	// block.
	var windowSize types.BlockHeight
	parent := pb.Block.ParentID
	current := pb.Block.ID()
	for windowSize = 0; windowSize < types.TargetWindow && parent != (types.BlockID{}); windowSize++ {
		current = parent
		copy(parent[:], blockMap.Get(parent[:])[:32])
	}
	timestamp := types.Timestamp(encoding.DecUint64(blockMap.Get(current[:])[40:48]))

	// The target of a child is determined by the amount of time that has
	// passed between the generation of its immediate parent and its
	// TargetWindow'th parent. The expected amount of seconds to have passed is
	// TargetWindow*BlockFrequency. The target is adjusted in proportion to how
	// time has passed vs. the expected amount of time to have passed.
	//
	// The target is converted to a big.Rat to provide infinite precision
	// during the calculation. The big.Rat is just the int representation of a
	// target.
	timePassed := pb.Block.Timestamp - timestamp
	expectedTimePassed := types.BlockFrequency * windowSize
	return big.NewRat(int64(timePassed), int64(expectedTimePassed))
}
示例#19
0
func RepoCreateOrder(order CheckoutCartPlayLoad) interface{} {
	var newOrder interface{}

	GlobalDB.Update(func(tx *bolt.Tx) error {
		orderBucket, err := tx.CreateBucketIfNotExists([]byte(OrderTable))
		if err != nil {
			HandleError(err)
			return err
		}
		var cusOrderBuck *bolt.Bucket
		if order.ChannelAccountId == nil {
			cusOrderBuck, err = orderBucket.CreateBucketIfNotExists([]byte("GUESTUSER"))
		} else {
			cusOrderBuck, err = orderBucket.CreateBucketIfNotExists([]byte(order.ChannelAccountId.(string)))
		}
		if err != nil {
			HandleError(err)
			return err
		}
		newId, _ := orderBucket.NextSequence()
		newOrder = GenerateOrder(order, newId)

		orderBytes, _ := json.Marshal(newOrder)
		cusOrderBuck.Put(TableId(newId).ToBytes(), orderBytes)

		return nil
	})

	return newOrder
}
示例#20
0
// Process verifies the signature and uniqueness of the random roken.
func (MailgunValidator) Process(h Hook, r Request, b *bolt.Bucket) error {
	// Check HMAC
	apikey := b.Get([]byte(fmt.Sprintf("%s-apikey", h.ID)))
	if apikey == nil {
		return errors.New("mailgun validator not initialized")
	}

	if r.Headers["Content-Type"] != "application/x-www-form-urlencoded" {
		return fmt.Errorf("unexpected Content-Type: %q", r.Headers["Content-Type"])
	}

	form, err := url.ParseQuery(string(r.Body))
	if err != nil {
		return fmt.Errorf("error parsing request body: %s", err)
	}

	timestamp := form.Get("timestamp")
	signature := []byte(form.Get("signature"))
	token := form.Get("token")

	mac := hmac.New(sha256.New, apikey)
	mac.Write([]byte(timestamp + token))
	expected := []byte(hex.EncodeToString(mac.Sum(nil)))
	if !hmac.Equal(signature, expected) {
		return errors.New("invalid signature")
	}

	// Check uniqueness
	tokens := b.Bucket([]byte("tokens"))
	if p := tokens.Get([]byte(token)); p != nil {
		return errors.New("duplicate request token received")
	}
	return tokens.Put([]byte(token), []byte{})
}
示例#21
0
文件: database.go 项目: Depado/govue
// Save saves an Entry in the database.
func (e *Entry) Save() error {
	if !database.Main.Opened {
		return fmt.Errorf("db must be opened before saving")
	}
	return database.Main.DB.Update(func(tx *bolt.Tx) error {
		var err error
		var b *bolt.Bucket
		var enc []byte
		var id uint64

		if b, err = tx.CreateBucketIfNotExists([]byte(Bucket)); err != nil {
			return fmt.Errorf("Error creating bucket : %s", err)
		}
		if enc, err = e.Encode(); err != nil {
			return fmt.Errorf("Could not encode : %s", err)
		}
		if e.ID == 0 {
			if id, err = b.NextSequence(); err != nil {
				return fmt.Errorf("Could not generate ID : %s", err)
			}
			e.ID = int(id)
		}
		return b.Put([]byte(strconv.Itoa(e.ID)), enc)
	})
}
func (rpcMethod *RPCMethod) listIDs(response *ResponseParameters) error {

	//open a read transaction
	rpcMethod.rpcServer.boltDB.View(func(tx *bolt.Tx) error {
		var cursor *bolt.Cursor
		cursor = tx.Cursor()

		var bucket *bolt.Bucket
		response.Result = make([]interface{}, 0, 10)

		//traverse through all keys
		for k, _ := cursor.First(); k != nil; k, _ = cursor.Next() {
			bucket = tx.Bucket(k)

			//traverse through all relation and value pairs
			bucket.ForEach(func(relation, value []byte) error {
				tuple := make([]string, 2)
				rpcMethod.rpcServer.logger.Println(string(k), string(relation), string(value))
				//make an array of 2 strings [key,relation]
				tuple[0] = string(k)
				tuple[1] = string(relation)
				response.Result = append(response.Result, tuple)
				return nil
			})
		}
		return nil
	})

	response.Error = nil
	return nil

}
示例#23
0
文件: main.go 项目: bcspragu/SDPServe
func instrumentsToDB(b *bolt.Bucket) error {
	d, err := ioutil.ReadFile("instruments")
	if err != nil {
		return err
	}

	lines := strings.Split(string(d), "\n")
	lines = lines[:len(lines)-1]
	instruments = make([]Instrument, len(lines))

	for i, line := range lines {
		var buf bytes.Buffer
		enc := gob.NewEncoder(&buf)
		s := strings.Split(line, ",")
		inst := Instrument{ID: i, Name: s[0], Tuned: s[1] == "1"}
		instruments[i] = inst
		err = enc.Encode(inst)
		if err != nil {
			return err
		}
		err = b.Put([]byte(s[0]), buf.Bytes())
		if err != nil {
			return err
		}
	}

	return nil
}
示例#24
0
func PersistOneBoltTx(bucket *bolt.Bucket, key string, obj proto.Marshaler) error {
	exBytes, err := obj.Marshal()
	if err != nil { // pragma: nocover -- no idea how to produce this error
		return fmt.Errorf("Could not marshal object")
	}
	return bucket.Put([]byte(key), exBytes)
}
示例#25
0
// Params returns the currently stored configuration parameters for hook h
// from bucket b.
func (ExecuteAction) Params(h Hook, b *bolt.Bucket) map[string]string {
	m := make(map[string]string)
	for _, k := range []string{"command"} {
		m[k] = string(b.Get([]byte(fmt.Sprintf("%s-%s", h.ID, k))))
	}
	return m
}
示例#26
0
// Allocate returns the next available inode number, and marks it
// used.
//
// Returns OutOfInodes if there are no free inodes.
func Allocate(bucket *bolt.Bucket) (uint64, error) {
	c := bucket.Cursor()
	var i uint64
	k, _ := c.Last()
	if k != nil {
		i = bytesToInode(k)
	}

	// reserve a few inodes for internal use
	if i < tokens.MaxReservedInode {
		i = tokens.MaxReservedInode
	}

	i++

	if i&tokens.InodeKindMask != tokens.InodeKindNormal {
		return 0, OutOfInodes
	}

	var buf [8]byte
	inodeToBytes(i, buf[:])
	err := bucket.Put(buf[:], nil)
	if err != nil {
		return 0, err
	}
	return i, nil
}
示例#27
0
文件: cursor.go 项目: raff/bolt
// NewCursor creates a C cursor from a Bucket.
func NewCursor(b *bolt.Bucket) *Cursor {
	info := b.Tx().DB().Info()
	root := b.Root()
	c := &Cursor{C: new(C.bolt_cursor)}
	C.bolt_cursor_init(c.C, unsafe.Pointer(&info.Data[0]), C.size_t(info.PageSize), C.pgid(root))
	return c
}
示例#28
0
文件: program.go 项目: mnadel/boltq
func executeUpdate(stmt *boltq.UpdateStatement, db *bolt.DB) error {
	return db.Update(func(tx *bolt.Tx) error {
		var bucket *bolt.Bucket
		var err error

		for _, name := range stmt.BucketPath {
			log.Debugln("navigating to bucket", name)
			bucket, err = tx.CreateBucketIfNotExists([]byte(name))

			if err != nil {
				return err
			}

			if bucket == nil {
				return fmt.Errorf("cannot find bucket %s", name)
			}
		}

		for k, v := range stmt.Fields {
			log.Debugf("putting %s -> %v", k, v)

			b, err := encode(v)
			if err != nil {
				return err
			}

			if err = bucket.Put([]byte(k), b); err != nil {
				return err
			}
		}

		return nil
	})
}
示例#29
0
文件: db_test.go 项目: heroku/sproxy
// mustContainKeys checks that a bucket contains a given set of keys.
func mustContainKeys(b *bolt.Bucket, m map[string]string) {
	found := make(map[string]string)
	b.ForEach(func(k, _ []byte) error {
		found[string(k)] = ""
		return nil
	})

	// Check for keys found in bucket that shouldn't be there.
	var keys []string
	for k, _ := range found {
		if _, ok := m[string(k)]; !ok {
			keys = append(keys, k)
		}
	}
	if len(keys) > 0 {
		sort.Strings(keys)
		panic(fmt.Sprintf("keys found(%d): %s", len(keys), strings.Join(keys, ",")))
	}

	// Check for keys not found in bucket that should be there.
	for k, _ := range m {
		if _, ok := found[string(k)]; !ok {
			keys = append(keys, k)
		}
	}
	if len(keys) > 0 {
		sort.Strings(keys)
		panic(fmt.Sprintf("keys not found(%d): %s", len(keys), strings.Join(keys, ",")))
	}
}
示例#30
0
func fetchChanCommitKeys(nodeChanBucket *bolt.Bucket, channel *OpenChannel) error {

	// Construct the key which stores the commitment keys: ckk || channelID.
	// TODO(roasbeef): factor into func
	var bc bytes.Buffer
	if err := writeOutpoint(&bc, channel.ChanID); err != nil {
		return err
	}
	commitKey := make([]byte, len(commitKeys)+bc.Len())
	copy(commitKey[:3], commitKeys)
	copy(commitKey[3:], bc.Bytes())

	var err error
	keyBytes := nodeChanBucket.Get(commitKey)

	channel.TheirCommitKey, err = btcec.ParsePubKey(keyBytes[:33], btcec.S256())
	if err != nil {
		return err
	}

	channel.OurCommitKey, err = btcec.ParsePubKey(keyBytes[33:], btcec.S256())
	if err != nil {
		return err
	}

	return nil
}