Example #1
0
// applyFileContractMaintenance looks for all of the file contracts that have
// expired without an appropriate storage proof, and calls 'applyMissedProof'
// for the file contract.
func applyFileContractMaintenance(tx *bolt.Tx, pb *processedBlock) {
	// Get the bucket pointing to all of the expiring file contracts.
	fceBucketID := append(prefixFCEX, encoding.Marshal(pb.Height)...)
	fceBucket := tx.Bucket(fceBucketID)
	// Finish if there are no expiring file contracts.
	if fceBucket == nil {
		return
	}

	var dscods []modules.DelayedSiacoinOutputDiff
	var fcds []modules.FileContractDiff
	err := fceBucket.ForEach(func(keyBytes, valBytes []byte) error {
		var id types.FileContractID
		copy(id[:], keyBytes)
		amspDSCODS, fcd := applyMissedStorageProof(tx, pb, id)
		fcds = append(fcds, fcd)
		dscods = append(dscods, amspDSCODS...)
		return nil
	})
	if build.DEBUG && err != nil {
		panic(err)
	}
	for _, dscod := range dscods {
		pb.DelayedSiacoinOutputDiffs = append(pb.DelayedSiacoinOutputDiffs, dscod)
		commitDelayedSiacoinOutputDiff(tx, dscod, modules.DiffApply)
	}
	for _, fcd := range fcds {
		pb.FileContractDiffs = append(pb.FileContractDiffs, fcd)
		commitFileContractDiff(tx, fcd, modules.DiffApply)
	}
	err = tx.DeleteBucket(fceBucketID)
	if build.DEBUG && err != nil {
		panic(err)
	}
}
Example #2
0
func (n *node) drop(tx *bolt.Tx, bucketName string) error {
	bucket := n.GetBucket(tx)
	if bucket == nil {
		return tx.DeleteBucket([]byte(bucketName))
	}

	return bucket.DeleteBucket([]byte(bucketName))
}
Example #3
0
func delete(tx *bolt.Tx, hash, kw, kh []byte) error {
	bimg := tx.Bucket([]byte(images))
	bhits := tx.Bucket([]byte(hits))

	w := bimg.Get(hash)
	if w == nil {
		return e.New(ErrImageNotFound)
	}

	bw := tx.Bucket(append(hash, w...))
	if bw == nil {
		return e.New(ErrImageNotFound)
	}
	h := bw.Get(kw)
	if h == nil {
		return e.New(ErrImageNotFound)
	}

	bh := tx.Bucket([]byte(string(hash) + string(w) + string(h)))
	if bh == nil {
		return e.New(ErrImageNotFound)
	}
	err := bh.Delete(kh)
	if err != nil {
		return e.Forward(err)
	}

	if bh.Stats().KeyN <= 0 {
		err = tx.DeleteBucket([]byte(string(hash) + string(w) + string(h)))
		if err != nil {
			return e.Forward(err)
		}
		err = bw.Delete(kw)
		if err != nil {
			return e.Forward(err)
		}
		if bw.Stats().KeyN <= 0 {
			err = tx.DeleteBucket(append(hash, w...))
			if err != nil {
				return e.Forward(err)
			}
			err = bimg.Delete(hash)
			if err != nil {
				return e.Forward(err)
			}
		}
	}

	// BUG: FAULT ADDRS
	hitshash := append(hash, append(kw, kh...)...)
	err = bhits.Delete(hitshash)
	if err != nil {
		return e.Forward(err)
	}

	return nil
}
Example #4
0
func removeDSCOBucket(tx *bolt.Tx, bh types.BlockHeight) error {
	bhBytes := encoding.EncUint64(uint64(bh))
	bucketID := append(prefix_dsco, bhBytes...)
	err := tx.DeleteBucket(bucketID)
	if err != nil {
		return err
	}
	b := tx.Bucket(DSCOBuckets)
	if build.DEBUG && b.Get(bhBytes) == nil {
		panic(errNilItem)
	}
	return b.Delete(bhBytes)
}
Example #5
0
// deleteDSCOBucket deletes the bucket that held a set of delayed siacoin
// outputs.
func deleteDSCOBucket(tx *bolt.Tx, bh types.BlockHeight) {
	// Delete the bucket.
	bucketID := append(prefixDSCO, encoding.Marshal(bh)...)
	bucket := tx.Bucket(bucketID)
	if build.DEBUG && bucket == nil {
		panic(errNilBucket)
	}

	// TODO: Check that the bucket is empty. Using Stats() does not work at the
	// moment, as there is an error in the boltdb code.

	err := tx.DeleteBucket(bucketID)
	if build.DEBUG && err != nil {
		panic(err)
	}
}
Example #6
0
// refreshDB saves, deletes, and then restores all of the buckets in the
// database. This eliminates bugs during reorgs. The exact source of the bugs
// is unknown, but the problem is that after excessive use by Sia, calling
// Delete on a bucket will occasionally delete many more elements than the
// single element being targeted. It is strongly suspected that this is due to
// an error in the boltdb code, but the source remains unknown for the time
// being. Refreshing the database between blocks has solved the issue for the
// time being - it is currently unknown whether large blocks are able to
// trigger the error, but it is suspected that large blocks are safe.
func refreshDB(tx *bolt.Tx) {
	// Get a list of buckets.
	var bucketNames [][]byte
	err := tx.ForEach(func(bucketName []byte, _ *bolt.Bucket) error {
		bucketNames = append(bucketNames, bucketName)
		return nil
	})
	if err != nil {
		manageErr(tx, err)
	}

	for _, bucketName := range bucketNames {
		var keys [][]byte
		var values [][]byte
		err := tx.Bucket(bucketName).ForEach(func(k, v []byte) error {
			keys = append(keys, k)
			values = append(values, v)
			return nil
		})
		if err != nil {
			manageErr(tx, err)
		}

		err = tx.DeleteBucket(bucketName)
		if err != nil {
			manageErr(tx, err)
		}
		bucket, err := tx.CreateBucket(bucketName)
		if err != nil {
			manageErr(tx, err)
		}
		for i := range keys {
			err := bucket.Put(keys[i], values[i])
			if err != nil {
				manageErr(tx, err)
			}
		}
	}
}
Example #7
0
func Del(tx *bolt.Tx, bucket []byte, keys [][]byte) error {
	if len(keys) == 0 {
		return e.New("no keys")
	}
	bname := make([][]byte, len(keys))
	bs := make([]*bolt.Bucket, len(keys))
	b := tx.Bucket(bucket)
	bname[0] = bucket
	bs[0] = b
	for i := 0; i < len(keys); i++ {
		v := b.Get(keys[i])
		b = tx.Bucket(v)
		if i+1 < len(keys) {
			bname[i+1] = v
			bs[i+1] = b
		}
	}

	for level := len(bs) - 1; level >= 0; level-- {
		err := bs[level].Delete(keys[level])
		if err != nil {
			return e.Forward(err)
		}
		if bs[level].Stats().KeyN <= 1 {
			if level-1 < 0 {
				break
			}
			err = tx.DeleteBucket(bname[level])
			if err != nil {
				return e.Forward(err)
			}
			continue
		}
		break
	}
	return nil
}