-
Notifications
You must be signed in to change notification settings - Fork 13
/
list.go
94 lines (75 loc) · 2.43 KB
/
list.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
// SPDX-License-Identifier: ISC
// Copyright (c) 2014-2019 Bitmark Inc.
// Use of this source code is governed by an ISC
// license that can be found in the LICENSE file.
package ownership
import (
"bytes"
"encoding/binary"
"github.com/bitmark-inc/bitmarkd/account"
"github.com/bitmark-inc/bitmarkd/merkle"
"github.com/bitmark-inc/bitmarkd/storage"
"github.com/bitmark-inc/bitmarkd/transactionrecord"
"github.com/bitmark-inc/logger"
)
// Ownership - type to represent an ownership record
type Ownership struct {
N uint64 `json:"n,string"`
TxId merkle.Digest `json:"txId"`
IssueTxId merkle.Digest `json:"issue"`
Item OwnedItem `json:"item"`
AssetId *transactionrecord.AssetIdentifier `json:"assetId,omitempty"`
BlockNumber *uint64 `json:"blockNumber,omitempty"`
}
// ListBitmarksFor - fetch a list of bitmarks for an owner
func ListBitmarksFor(owner *account.Account, start uint64, count int) ([]Ownership, error) {
startBytes := make([]byte, uint64ByteSize)
binary.BigEndian.PutUint64(startBytes, start)
ownerBytes := owner.Bytes()
prefix := append(ownerBytes, startBytes...)
cursor := storage.Pool.OwnerList.NewFetchCursor().Seek(prefix)
// owner ⧺ count → txId
items, err := cursor.Fetch(count)
if nil != err {
return nil, err
}
records := make([]Ownership, 0, len(items))
loop:
for _, item := range items {
n := len(item.Key)
split := n - uint64ByteSize
if split <= 0 {
logger.Panicf("split cannot be <= 0: %d", split)
}
itemOwner := item.Key[:n-uint64ByteSize]
if !bytes.Equal(ownerBytes, itemOwner) {
break loop
}
record := Ownership{
N: binary.BigEndian.Uint64(item.Key[split:]),
}
merkle.DigestFromBytes(&record.TxId, item.Value)
ownerData, err := GetOwnerData(nil, record.TxId)
if nil != err {
return nil, err
}
switch od := ownerData.(type) {
case *AssetOwnerData:
record.Item = OwnedAsset
record.IssueTxId = od.issueTxId
record.AssetId = &od.assetId
case *BlockOwnerData:
record.Item = OwnedBlock
record.IssueTxId = od.issueTxId
record.BlockNumber = &od.issueBlockNumber
case *ShareOwnerData:
record.Item = OwnedShare
record.IssueTxId = od.issueTxId
record.AssetId = &od.assetId
default:
logger.Panicf("unsupported item type: %d", item)
}
records = append(records, record)
}
return records, nil
}