Esempio n. 1
0
// putMeta puts a k-v into the meta bucket.
func putMeta(ns walletdb.ReadWriteBucket, key []byte, n int32) error {
	bucket := ns.NestedReadWriteBucket(metaBucketName)
	err := bucket.Put(key, uint32ToBytes(uint32(n)))
	if err != nil {
		str := fmt.Sprintf("failed to store meta key '%s'", key)
		return stakeStoreError(ErrDatabase, str, err)
	}
	return nil
}
Esempio n. 2
0
// updateStakePoolUserTickets updates a database entry for a pool user's tickets.
// The function pulls the current entry in the database, checks to see if the
// ticket is already there, updates it accordingly, or adds it to the list of
// tickets.
func updateStakePoolUserTickets(ns walletdb.ReadWriteBucket, scriptHash [20]byte,
	record *PoolTicket) error {

	// Fetch the current content of the key.
	// Possible buggy behaviour: If deserialization fails,
	// we won't detect it here. We assume we're throwing
	// ErrPoolUserTicketsNotFound.
	oldRecords, _ := fetchStakePoolUserTickets(ns, scriptHash)

	// Don't reinsert duplicate records we already have.
	if duplicateExistsInUserTickets(record, oldRecords) {
		return nil
	}

	// Does this modify an old record? If so, modify the record
	// itself and push. Otherwise, we need to insert a new
	// record.
	var records []*PoolTicket
	preExists, loc := recordExistsInUserTickets(record, oldRecords)
	if preExists {
		records = oldRecords
		records[loc] = record
	} else {
		// Either create a slice if currently nothing exists for this
		// key in the db, or append the entry to the slice.
		if oldRecords == nil {
			records = make([]*PoolTicket, 1)
			records[0] = record
		} else {
			records = append(oldRecords, record)
		}
	}

	bucket := ns.NestedReadWriteBucket(metaBucketName)
	key := make([]byte, stakePoolTicketsPrefixSize+scriptHashSize)
	copy(key[0:stakePoolTicketsPrefixSize], stakePoolTicketsPrefix)
	copy(key[stakePoolTicketsPrefixSize:stakePoolTicketsPrefixSize+scriptHashSize],
		scriptHash[:])

	// Write the serialized ticket data keyed by the script.
	serializedRecords := serializeUserTickets(records)

	err := bucket.Put(key, serializedRecords)
	if err != nil {
		str := fmt.Sprintf("failed to store pool user ticket records '%x'",
			scriptHash)
		return stakeStoreError(ErrDatabase, str, err)
	}
	return nil
}
Esempio n. 3
0
// updateSStxRecord updates a sstx record in the sstx records bucket.
func updateSStxRecord(ns walletdb.ReadWriteBucket, record *sstxRecord, voteBits stake.VoteBits) error {
	bucket := ns.NestedReadWriteBucket(sstxRecordsBucketName)

	// Write the serialized txrecord keyed by the tx hash.
	serializedSStxRecord, err := serializeSStxRecord(record, voteBits)
	if err != nil {
		str := fmt.Sprintf("failed to serialize sstxrecord '%s'", record.tx.Sha())
		return stakeStoreError(ErrDatabase, str, err)
	}
	err = bucket.Put(record.tx.Sha().Bytes(), serializedSStxRecord)
	if err != nil {
		str := fmt.Sprintf("failed to store sstxrecord '%s'", record.tx.Sha())
		return stakeStoreError(ErrDatabase, str, err)
	}
	return nil
}
Esempio n. 4
0
// updateSStxRecordVoteBits updates an individual ticket's intended voteBits
// which are used to override the default voteBits when voting.
func updateSStxRecordVoteBits(ns walletdb.ReadWriteBucket, hash *chainhash.Hash,
	voteBits stake.VoteBits) error {
	if len(voteBits.ExtendedBits) > stake.MaxSingleBytePushLength-2 {
		str := fmt.Sprintf("voteBitsExt too long (got %v bytes, want max %v)",
			len(voteBits.ExtendedBits), stake.MaxSingleBytePushLength-2)
		return stakeStoreError(ErrData, str, nil)
	}

	bucket := ns.NestedReadWriteBucket(sstxRecordsBucketName)

	key := hash.Bytes()
	val := bucket.Get(key)
	if val == nil {
		str := fmt.Sprintf("missing sstx record for hash '%s'", hash.String())
		return stakeStoreError(ErrSStxNotFound, str, nil)
	}
	valLen := len(val)
	valCopy := make([]byte, valLen, valLen)
	copy(valCopy, val)

	// Move the cursor to the voteBits position and rewrite it.
	curPos := 0
	curPos += int64Size
	curPos += int32Size

	// Write the intended votebits length (uint8).
	valCopy[curPos] = byte(int16Size + len(voteBits.ExtendedBits))
	curPos += int8Size

	// Write the first two bytes for the intended votebits.
	byteOrder.PutUint16(valCopy[curPos:curPos+int16Size], voteBits.Bits)
	curPos += int16Size

	// Copy the remaining data from voteBitsExt.
	copy(valCopy[curPos:], voteBits.ExtendedBits[:])

	err := bucket.Put(key, valCopy)
	if err != nil {
		str := fmt.Sprintf("failed to update sstxrecord votebits for '%s'", hash)
		return stakeStoreError(ErrDatabase, str, err)
	}
	return nil
}
Esempio n. 5
0
// removeStakePoolInvalUserTickets removes the ticket hash from the inval
// ticket bucket.
func removeStakePoolInvalUserTickets(ns walletdb.ReadWriteBucket, scriptHash [20]byte,
	record *chainhash.Hash) error {

	// Fetch the current content of the key.
	// Possible buggy behaviour: If deserialization fails,
	// we won't detect it here. We assume we're throwing
	// ErrPoolUserInvalTcktsNotFound.
	oldRecords, _ := fetchStakePoolUserInvalTickets(ns, scriptHash)

	// Don't need to remove records that don't exist.
	if !duplicateExistsInInvalTickets(record, oldRecords) {
		return nil
	}

	var newRecords []*chainhash.Hash
	for i := range oldRecords {
		if record.IsEqual(oldRecords[i]) {
			newRecords = append(oldRecords[:i:i], oldRecords[i+1:]...)
		}
	}

	if newRecords == nil {
		return nil
	}

	bucket := ns.NestedReadWriteBucket(metaBucketName)
	key := make([]byte, stakePoolInvalidPrefixSize+scriptHashSize)
	copy(key[0:stakePoolInvalidPrefixSize], stakePoolInvalidPrefix)
	copy(key[stakePoolInvalidPrefixSize:stakePoolInvalidPrefixSize+scriptHashSize],
		scriptHash[:])

	// Write the serialized invalid user ticket hashes.
	serializedRecords := serializeUserInvalTickets(newRecords)

	err := bucket.Put(key, serializedRecords)
	if err != nil {
		str := fmt.Sprintf("failed to store pool user invalid ticket "+
			"records '%x'", scriptHash)
		return stakeStoreError(ErrDatabase, str, err)
	}

	return nil
}
Esempio n. 6
0
// updateStakePoolInvalUserTickets updates a database entry for a pool user's
// invalid tickets. The function pulls the current entry in the database,
// checks to see if the ticket is already there. If it is it returns, otherwise
// it adds it to the list of tickets.
func updateStakePoolInvalUserTickets(ns walletdb.ReadWriteBucket, scriptHash [20]byte,
	record *chainhash.Hash) error {

	// Fetch the current content of the key.
	// Possible buggy behaviour: If deserialization fails,
	// we won't detect it here. We assume we're throwing
	// ErrPoolUserInvalTcktsNotFound.
	oldRecords, _ := fetchStakePoolUserInvalTickets(ns, scriptHash)

	// Don't reinsert duplicate records we already have.
	if duplicateExistsInInvalTickets(record, oldRecords) {
		return nil
	}

	// Either create a slice if currently nothing exists for this
	// key in the db, or append the entry to the slice.
	var records []*chainhash.Hash
	if oldRecords == nil {
		records = make([]*chainhash.Hash, 1)
		records[0] = record
	} else {
		records = append(oldRecords, record)
	}

	bucket := ns.NestedReadWriteBucket(metaBucketName)
	key := make([]byte, stakePoolInvalidPrefixSize+scriptHashSize)
	copy(key[0:stakePoolInvalidPrefixSize], stakePoolInvalidPrefix)
	copy(key[stakePoolInvalidPrefixSize:stakePoolInvalidPrefixSize+scriptHashSize],
		scriptHash[:])

	// Write the serialized invalid user ticket hashes.
	serializedRecords := serializeUserInvalTickets(records)

	err := bucket.Put(key, serializedRecords)
	if err != nil {
		str := fmt.Sprintf("failed to store pool user invalid ticket "+
			"records '%x'", scriptHash)
		return stakeStoreError(ErrDatabase, str, err)
	}
	return nil
}
Esempio n. 7
0
// updateSSRtxRecord updates an SSRtx record in the SSRtx records bucket.
func updateSSRtxRecord(ns walletdb.ReadWriteBucket, hash *chainhash.Hash,
	record *ssrtxRecord) error {

	// Fetch the current content of the key.
	// Possible buggy behaviour: If deserialization fails,
	// we won't detect it here. We assume we're throwing
	// ErrSSRtxsNotFound.
	oldRecords, _ := fetchSSRtxRecords(ns, hash)

	// Don't reinsert records we already have.
	if ssrtxRecordExistsInRecords(record, oldRecords) {
		return nil
	}

	bucket := ns.NestedReadWriteBucket(ssrtxRecordsBucketName)

	var records []*ssrtxRecord
	// Either create a slice if currently nothing exists for this
	// key in the db, or append the entry to the slice.
	if oldRecords == nil {
		records = make([]*ssrtxRecord, 1)
		records[0] = record
	} else {
		records = append(oldRecords, record)
	}

	// Write the serialized SSRtxs keyed by the sstx hash.
	serializedSSRtxsRecords := serializeSSRtxRecords(records)

	err := bucket.Put(hash.Bytes(), serializedSSRtxsRecords)
	if err != nil {
		str := fmt.Sprintf("failed to store ssrtx records '%s'", hash)
		return stakeStoreError(ErrDatabase, str, err)
	}
	return nil
}