nursery_store: reject duplicate registrations for an output

This commit is contained in:
Olaoluwa Osuntokun 2018-01-16 20:56:22 -08:00
parent fc8a6568c9
commit 5758a4e1af
No known key found for this signature in database
GPG Key ID: 964EA263DD637C21

@ -979,6 +979,19 @@ func (ns *nurseryStore) enterCrib(tx *bolt.Tx, baby *babyOutput) error {
return err return err
} }
// Since we are inserting this output into the crib bucket, we create a
// key that prefixes the baby output's outpoint with the crib prefix.
pfxOutputKey, err := prefixOutputKey(cribPrefix, baby.OutPoint())
if err != nil {
return err
}
// We'll first check that we don't already have an entry for this
// output. If we do, then we can exit early.
if rawBytes := chanBucket.Get(pfxOutputKey); rawBytes != nil {
return nil
}
// Next, retrieve or create the height-channel bucket located in the // Next, retrieve or create the height-channel bucket located in the
// height bucket corresponding to the baby output's CLTV expiry height. // height bucket corresponding to the baby output's CLTV expiry height.
hghtChanBucket, err := ns.createHeightChanBucket(tx, hghtChanBucket, err := ns.createHeightChanBucket(tx,
@ -987,15 +1000,8 @@ func (ns *nurseryStore) enterCrib(tx *bolt.Tx, baby *babyOutput) error {
return err return err
} }
// Since we are inserting this output into the crib bucket, we create a // Serialize the baby output so that it can be written to the
// key that prefixes the baby output's outpoint with the crib prefix. // underlying key-value store.
pfxOutputKey, err := prefixOutputKey(cribPrefix, baby.OutPoint())
if err != nil {
return err
}
// Serialize the baby output so that it can be written to the underlying
// key-value store.
var babyBuffer bytes.Buffer var babyBuffer bytes.Buffer
if err := baby.Encode(&babyBuffer); err != nil { if err := baby.Encode(&babyBuffer); err != nil {
return err return err
@ -1009,9 +1015,9 @@ func (ns *nurseryStore) enterCrib(tx *bolt.Tx, baby *babyOutput) error {
} }
// Finally, create a corresponding bucket in the height-channel bucket // Finally, create a corresponding bucket in the height-channel bucket
// for this crib output. The existence of this bucket indicates that the // for this crib output. The existence of this bucket indicates that
// serialized output can be retrieved from the channel bucket using the // the serialized output can be retrieved from the channel bucket using
// same prefix key. // the same prefix key.
return hghtChanBucket.Put(pfxOutputKey, []byte{}) return hghtChanBucket.Put(pfxOutputKey, []byte{})
} }
@ -1035,6 +1041,12 @@ func (ns *nurseryStore) enterPreschool(tx *bolt.Tx, kid *kidOutput) error {
return err return err
} }
// We'll first check if a entry for this key is already stored. If so,
// then we'll ignore this request, and return a nil error.
if rawBytes := chanBucket.Get(pfxOutputKey); rawBytes != nil {
return nil
}
// Serialize the kidOutput and insert it into the channel bucket. // Serialize the kidOutput and insert it into the channel bucket.
var kidBuffer bytes.Buffer var kidBuffer bytes.Buffer
if err := kid.Encode(&kidBuffer); err != nil { if err := kid.Encode(&kidBuffer); err != nil {