forked from hyperledger-archives/burrow
-
Notifications
You must be signed in to change notification settings - Fork 0
/
dump_server.go
117 lines (100 loc) · 2.77 KB
/
dump_server.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
111
112
113
114
115
116
117
package rpcdump
import (
"time"
"github.com/hyperledger/burrow/acm"
"github.com/hyperledger/burrow/bcm"
"github.com/hyperledger/burrow/binary"
"github.com/hyperledger/burrow/consensus/tendermint"
dump "github.com/hyperledger/burrow/dump"
"github.com/hyperledger/burrow/execution/exec"
"github.com/hyperledger/burrow/execution/names"
"github.com/hyperledger/burrow/execution/state"
"github.com/hyperledger/burrow/logging"
)
type dumpServer struct {
state *state.State
blockchain bcm.BlockchainInfo
nodeView *tendermint.NodeView
logger *logging.Logger
}
var _ DumpServer = &dumpServer{}
func NewDumpServer(state *state.State, blockchain bcm.BlockchainInfo, nodeView *tendermint.NodeView, logger *logging.Logger) *dumpServer {
return &dumpServer{
state: state,
blockchain: blockchain,
nodeView: nodeView,
logger: logger,
}
}
func (ds *dumpServer) GetDump(param *GetDumpParam, stream Dump_GetDumpServer) error {
height := param.Height
if height <= 0 {
height = ds.blockchain.LastBlockHeight()
}
st, err := ds.state.LoadHeight(height)
if err != nil {
return err
}
err = st.IterateAccounts(func(acc *acm.Account) error {
err = stream.Send(&dump.Dump{Height: height, Account: acc})
if err != nil {
return err
}
storage := dump.AccountStorage{
Address: acc.Address,
Storage: make([]*dump.Storage, 0),
}
err = st.IterateStorage(acc.Address, func(key, value binary.Word256) error {
storage.Storage = append(storage.Storage, &dump.Storage{Key: key, Value: value})
return nil
})
if err != nil {
return err
}
if len(storage.Storage) > 0 {
return stream.Send(&dump.Dump{
Height: height,
AccountStorage: &storage,
})
}
return nil
})
if err != nil {
return err
}
err = st.IterateNames(func(entry *names.Entry) error {
return stream.Send(&dump.Dump{Height: height, Name: entry})
})
if err != nil {
return err
}
var blockTime time.Time
var origin *exec.Origin
return ds.state.IterateStreamEvents(nil, &exec.StreamKey{Height: height},
func(ev *exec.StreamEvent) error {
switch {
case ev.BeginBlock != nil:
blockTime = ev.BeginBlock.Header.GetTime()
case ev.BeginTx != nil:
origin = ev.BeginTx.TxHeader.Origin
case ev.Event != nil && ev.Event.Log != nil:
evmevent := dump.EVMEvent{Event: ev.Event.Log}
if origin != nil {
// this event was already restored
evmevent.ChainID = origin.ChainID
evmevent.Time = origin.Time
} else {
// this event was generated on this chain
evmevent.ChainID = ds.blockchain.ChainID()
evmevent.Time = blockTime
}
err := stream.Send(&dump.Dump{Height: ev.Event.Header.Height, EVMEvent: &evmevent})
if err != nil {
return err
}
case ev.EndTx != nil:
origin = nil
}
return nil
})
}