// 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 }
// 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 }
// 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 }
// 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 }
// 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 }
// 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 }
// 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 }