/
mapper.go
110 lines (90 loc) · 2.75 KB
/
mapper.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
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
package db
import (
types "github.com/FourthState/plasma-mvp-sidechain/types"
sdk "github.com/cosmos/cosmos-sdk/types"
"github.com/ethereum/go-ethereum/common"
amino "github.com/tendermint/go-amino"
)
// Maps Position struct to UTXO
// Uses go-amino encoding/decoding library
// Implements UTXOMapper
type utxoMapper struct {
// The contextKey used to access the store from the Context.
contextKey sdk.StoreKey
// The Amino codec for binary encoding/decoding
cdc *amino.Codec
}
func NewUTXOMapper(contextKey sdk.StoreKey, cdc *amino.Codec) types.UTXOMapper {
return utxoMapper{
contextKey: contextKey,
cdc: cdc,
}
}
// Returns the UTXO corresponding to the address + go amino encoded Position struct
// Returns nil if no UTXO exists at that position
func (um utxoMapper) GetUTXO(ctx sdk.Context, addr common.Address, position types.Position) types.UTXO {
store := ctx.KVStore(um.contextKey)
key := um.constructKey(addr, position)
bz := store.Get(key)
if bz == nil {
return nil
}
utxo := um.decodeUTXO(bz)
return utxo
}
// Returns all the UTXOs owned by an address.
// Returns empty slice if no UTXO exists for the address.
func (um utxoMapper) GetUTXOsForAddress(ctx sdk.Context, addr common.Address) []types.UTXO {
store := ctx.KVStore(um.contextKey)
iterator := sdk.KVStorePrefixIterator(store, addr.Bytes())
utxos := make([]types.UTXO, 0)
for ; iterator.Valid(); iterator.Next() {
utxo := um.decodeUTXO(iterator.Value())
utxos = append(utxos, utxo)
}
iterator.Close()
return utxos
}
// Adds the UTXO to the mapper
func (um utxoMapper) AddUTXO(ctx sdk.Context, utxo types.UTXO) {
position := utxo.GetPosition()
address := utxo.GetAddress()
store := ctx.KVStore(um.contextKey)
key := um.constructKey(address, position)
bz := um.encodeUTXO(utxo)
store.Set(key, bz)
}
// Deletes UTXO corresponding to address + position from mapping
func (um utxoMapper) DeleteUTXO(ctx sdk.Context, addr common.Address, position types.Position) {
store := ctx.KVStore(um.contextKey)
key := um.constructKey(addr, position)
store.Delete(key)
}
// (<address> + <encoded position>) forms the unique key that maps to an UTXO.
func (um utxoMapper) constructKey(address common.Address, position types.Position) []byte {
pos := um.encodePosition(position)
key := append(address.Bytes(), pos...)
return key
}
func (um utxoMapper) encodeUTXO(utxo types.UTXO) []byte {
bz, err := um.cdc.MarshalBinary(utxo)
if err != nil {
panic(err)
}
return bz
}
func (um utxoMapper) decodeUTXO(bz []byte) types.UTXO {
utxo := &types.BaseUTXO{}
err := um.cdc.UnmarshalBinary(bz, utxo)
if err != nil {
panic(err)
}
return utxo
}
func (um utxoMapper) encodePosition(pos types.Position) []byte {
bz, err := um.cdc.MarshalBinary(pos)
if err != nil {
panic(err)
}
return bz
}