Skip to content
Snippets Groups Projects
Commit 93d9ead9 authored by Hans Moog's avatar Hans Moog
Browse files

Feat: added spent/unspent filter flag

parent 86976822
No related branches found
No related tags found
No related merge requests found
package ledgerstate
const (
UNSPENT_SEPARATOR_BYTE = byte(0)
SPENT_SEPARATOR_BYTE = byte(1)
UNSPENT = SpentIndicator(0)
SPENT = SpentIndicator(1)
marshalTransferOutputBookingRealityIdStart = 0
marshalTransferOutputBookingRealityIdEnd = marshalTransferOutputBookingRealityIdStart + realityIdLength
......@@ -15,6 +15,8 @@ const (
marshalTransferOutputBookingTotalLength = marshalTransferOutputBookingTransferHashEnd
)
type SpentIndicator byte
var (
MAIN_REALITY_ID = NewRealityId("MAIN_REALITY")
)
......@@ -51,7 +51,7 @@ func (ledgerState *LedgerState) GetTransferOutput(transferOutputReference *Trans
}
func (ledgerState *LedgerState) ForEachTransferOutput(callback func(object *objectstorage.CachedObject) bool, filters ...interface{}) {
prefixes, searchBookings := ledgerState.generatePrefixes(filters)
prefixes, searchBookings := ledgerState.generateFilterPrefixes(filters)
if searchBookings {
for _, prefix := range prefixes {
if err := ledgerState.transferOutputBookings.ForEach(func(key []byte, cachedObject *objectstorage.CachedObject) bool {
......@@ -74,10 +74,46 @@ func (ledgerState *LedgerState) ForEachTransferOutput(callback func(object *obje
}
}
func (ledgerState *LedgerState) generatePrefixes(filters []interface{}) ([][]byte, bool) {
func (ledgerState *LedgerState) CreateReality(id RealityId) {
ledgerState.realities.Store(newReality(id, MAIN_REALITY_ID))
}
func (ledgerState *LedgerState) GetReality(id RealityId) *objectstorage.CachedObject {
if cachedObject, err := ledgerState.realities.Load(id[:]); err != nil {
panic(err)
} else {
if cachedObject.Exists() {
if reality := cachedObject.Get().(*Reality); reality != nil {
reality.ledgerState = ledgerState
}
}
return cachedObject
}
}
func (ledgerState *LedgerState) Prune() *LedgerState {
if err := ledgerState.transferOutputs.Prune(); err != nil {
panic(err)
}
if err := ledgerState.transferOutputBookings.Prune(); err != nil {
panic(err)
}
if err := ledgerState.realities.Prune(); err != nil {
panic(err)
}
return ledgerState
}
func (ledgerState *LedgerState) generateFilterPrefixes(filters []interface{}) ([][]byte, bool) {
filteredRealities := make([]RealityId, 0)
filteredAddresses := make([]AddressHash, 0)
filteredTransfers := make([]TransferHash, 0)
filterSpent := false
filterUnspent := false
for _, filter := range filters {
switch typeCastedValue := filter.(type) {
......@@ -87,6 +123,15 @@ func (ledgerState *LedgerState) generatePrefixes(filters []interface{}) ([][]byt
filteredAddresses = append(filteredAddresses, typeCastedValue)
case TransferHash:
filteredTransfers = append(filteredTransfers, typeCastedValue)
case SpentIndicator:
switch typeCastedValue {
case SPENT:
filterSpent = true
case UNSPENT:
filterUnspent = true
default:
panic("unknown SpentIndicator")
}
default:
panic("unknown filter type: " + reflect.ValueOf(filter).Kind().String())
}
......@@ -102,9 +147,20 @@ func (ledgerState *LedgerState) generatePrefixes(filters []interface{}) ([][]byt
addressPrefix := append([]byte{}, realityPrefix...)
addressPrefix = append(addressPrefix, addressHash[:]...)
// TODO: FILTER UNSPENT + TRANSFER HASH
if filterSpent != filterUnspent {
spentPrefix := append([]byte{}, addressPrefix...)
if filterSpent {
spentPrefix = append(spentPrefix, byte(SPENT))
} else {
spentPrefix = append(spentPrefix, byte(UNSPENT))
}
// TODO: FILTER TRANSFER HASH
prefixes = append(prefixes, spentPrefix)
} else {
prefixes = append(prefixes, addressPrefix)
}
}
} else {
prefixes = append(prefixes, realityPrefix)
}
......@@ -115,45 +171,21 @@ func (ledgerState *LedgerState) generatePrefixes(filters []interface{}) ([][]byt
for _, transferHash := range filteredTransfers {
transferPrefix := append([]byte{}, transferHash[:]...)
prefixes = append(prefixes, transferPrefix)
}
}
return prefixes, false
}
if len(filteredAddresses) >= 1 {
for _, addressHash := range filteredAddresses {
addressPrefix := append([]byte{}, transferPrefix...)
addressPrefix = append(addressPrefix, addressHash[:]...)
func (ledgerState *LedgerState) CreateReality(id RealityId) {
ledgerState.realities.Store(newReality(id, MAIN_REALITY_ID))
// TODO: FILTER UNSPENT + TRANSFER HASH
prefixes = append(prefixes, addressPrefix)
}
func (ledgerState *LedgerState) GetReality(id RealityId) *objectstorage.CachedObject {
if cachedObject, err := ledgerState.realities.Load(id[:]); err != nil {
panic(err)
} else {
if cachedObject.Exists() {
if reality := cachedObject.Get().(*Reality); reality != nil {
reality.ledgerState = ledgerState
}
}
return cachedObject
}
}
func (ledgerState *LedgerState) Prune() *LedgerState {
if err := ledgerState.transferOutputs.Prune(); err != nil {
panic(err)
prefixes = append(prefixes, transferPrefix)
}
if err := ledgerState.transferOutputBookings.Prune(); err != nil {
panic(err)
}
if err := ledgerState.realities.Prune(); err != nil {
panic(err)
}
return ledgerState
return prefixes, false
}
func transferOutputFactory(key []byte) objectstorage.StorableObject {
......
......@@ -48,7 +48,7 @@ func Test(t *testing.T) {
})
return true
}, pendingReality, addressHash3)
}, pendingReality, addressHash3, UNSPENT)
ledgerState.ForEachTransferOutput(func(object *objectstorage.CachedObject) bool {
object.Consume(func(object objectstorage.StorableObject) {
......@@ -56,6 +56,6 @@ func Test(t *testing.T) {
})
return true
}, transferHash2)
}, transferHash2, addressHash4)
})
}
......@@ -29,10 +29,18 @@ func newReality(id RealityId, parentRealities ...RealityId) *Reality {
}
func (reality *Reality) BookTransfer(transfer *Transfer) {
transferHash := transfer.GetHash()
transferOutputs := transfer.GetOutputs()
// process outputs
for addressHash, coloredBalances := range transfer.GetOutputs() {
createdTransferOutput := NewTransferOutput(reality.ledgerState, reality.id, transfer.GetHash(), addressHash, coloredBalances...)
createdBooking := newTransferOutputBooking(reality.id, addressHash, false, transfer.GetHash())
reality.bookTransferOutputs(transferHash, transferOutputs)
}
func (reality *Reality) bookTransferOutputs(transferHash TransferHash, transferOutputs map[AddressHash][]*ColoredBalance) {
for addressHash, coloredBalances := range transferOutputs {
createdTransferOutput := NewTransferOutput(reality.ledgerState, reality.id, transferHash, addressHash, coloredBalances...)
createdBooking := newTransferOutputBooking(reality.id, addressHash, false, transferHash)
reality.ledgerState.storeTransferOutput(createdTransferOutput).Release()
reality.ledgerState.storeTransferOutputBooking(createdBooking).Release()
......
......@@ -83,10 +83,10 @@ func (booking *TransferOutputBooking) UnmarshalBinary(data []byte) error {
return err
}
switch booking.storageKey[marshalTransferOutputBookingSpentStart] {
case UNSPENT_SEPARATOR_BYTE:
switch SpentIndicator(booking.storageKey[marshalTransferOutputBookingSpentStart]) {
case UNSPENT:
booking.spent = false
case SPENT_SEPARATOR_BYTE:
case SPENT:
booking.spent = true
default:
return errors.New("unmarshal failed: invalid spent separator in key")
......@@ -107,9 +107,9 @@ func (booking *TransferOutputBooking) buildId() {
copy(booking.storageKey[marshalTransferOutputBookingRealityIdStart:marshalTransferOutputBookingRealityIdEnd], booking.realityId[:realityIdLength])
copy(booking.storageKey[marshalTransferOutputBookingAddressHashStart:marshalTransferOutputBookingAddressHashEnd], booking.addressHash[:addressHashLength])
if booking.spent {
booking.storageKey[marshalTransferOutputBookingSpentStart] = SPENT_SEPARATOR_BYTE
booking.storageKey[marshalTransferOutputBookingSpentStart] = byte(SPENT)
} else {
booking.storageKey[marshalTransferOutputBookingSpentStart] = UNSPENT_SEPARATOR_BYTE
booking.storageKey[marshalTransferOutputBookingSpentStart] = byte(UNSPENT)
}
copy(booking.storageKey[marshalTransferOutputBookingTransferHashStart:marshalTransferOutputBookingTransferHashEnd], booking.transferHash[:transferHashLength])
}
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment