forked from dfuse-io/dfuse-eosio
-
Notifications
You must be signed in to change notification settings - Fork 1
/
tablet_contract_state.go
102 lines (78 loc) · 2.75 KB
/
tablet_contract_state.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
package statedb
import (
"fmt"
pbcodec "github.com/dfuse-io/dfuse-eosio/pb/dfuse/eosio/codec/v1"
pbstatedb "github.com/dfuse-io/dfuse-eosio/pb/dfuse/eosio/statedb/v1"
"github.com/eoscanada/eos-go"
"github.com/golang/protobuf/proto"
"github.com/streamingfast/fluxdb"
)
const cstCollection = 0xB000
const cstPrefix = "cst"
func init() {
fluxdb.RegisterTabletFactory(cstCollection, cstPrefix, func(identifier []byte) (fluxdb.Tablet, error) {
if len(identifier) < 24 {
return nil, fluxdb.ErrInvalidKeyLengthAtLeast("contract state tablet identifier", 24, len(identifier))
}
return ContractStateTablet(identifier[0:24]), nil
})
}
func NewContractStateTablet(contract, table string, scope string) ContractStateTablet {
return ContractStateTablet(extendedNameToBytes(contract, table, scope))
}
type ContractStateTablet []byte
func (t ContractStateTablet) Collection() uint16 {
return cstCollection
}
func (t ContractStateTablet) Identifier() []byte {
return t
}
func (t ContractStateTablet) Row(height uint64, primaryKey []byte, data []byte) (fluxdb.TabletRow, error) {
if len(primaryKey) != 8 {
return nil, fluxdb.ErrInvalidKeyLength("contract state primary key", 8, len(primaryKey))
}
return &ContractStateRow{baseRow(t, height, primaryKey, data)}, nil
}
func (t ContractStateTablet) Explode() (contract, table, scope string) {
return bytesToName3(t)
}
func (t ContractStateTablet) String() string {
return cstPrefix + ":" + bytesToJoinedName3(t)
}
type ContractStateRow struct {
fluxdb.BaseTabletRow
}
func NewContractStateRow(blockNum uint64, op *pbcodec.DBOp) (row *ContractStateRow, err error) {
var value []byte
if op.Operation != pbcodec.DBOp_OPERATION_REMOVE {
pb := pbstatedb.ContractStateValue{
Payer: eos.MustStringToName(op.NewPayer),
Data: op.NewData,
}
if value, err = proto.Marshal(&pb); err != nil {
return nil, fmt.Errorf("marshal proto: %w", err)
}
}
tablet := NewContractStateTablet(op.Code, op.TableName, op.Scope)
return &ContractStateRow{baseRow(tablet, blockNum, standardNameToBytes(op.PrimaryKey), value)}, nil
}
func (r *ContractStateRow) Info() (payer string, rowData []byte, err error) {
pb := pbstatedb.ContractStateValue{}
if err := proto.Unmarshal(r.Value(), &pb); err != nil {
return "", nil, err
}
return eos.NameToString(pb.Payer), pb.Data, nil
}
func (r *ContractStateRow) ToProto() (proto.Message, error) {
pb := &pbstatedb.ContractStateValue{}
if err := proto.Unmarshal(r.Value(), pb); err != nil {
return nil, err
}
return pb, nil
}
func (r *ContractStateRow) String() string {
return r.Stringify(bytesToName(r.PrimaryKey()))
}
type ContractStatePrimaryKey []byte
func (k ContractStatePrimaryKey) Bytes() []byte { return k }
func (k ContractStatePrimaryKey) String() string { return bytesToName(k) }