2020package statediff
2121
2222import (
23- "errors"
24- "github.com/ethereum/go-ethereum/statediff/ipfs"
23+ "os"
24+ "encoding/csv"
25+ "time"
26+ "strconv"
27+ "strings"
2528)
2629
2730type Publisher interface {
2831 PublishStateDiff (sd * StateDiff ) (string , error )
2932}
3033
3134type publisher struct {
32- ipfs.DagPutter
33- Config
35+ Config Config
3436}
3537
36- func NewPublisher (config Config ) (* publisher , error ) {
37- adder , err := ipfs .NewAdder (config .Path )
38- if err != nil {
39- return nil , err
38+ var (
39+ Headers = []string {
40+ "blockNumber" , "blockHash" , "accountAction" ,
41+ "code" , "codeHash" ,
42+ "oldNonceValue" , "newNonceValue" ,
43+ "oldBalanceValue" , "newBalanceValue" ,
44+ "oldContractRoot" , "newContractRoot" ,
45+ "storageDiffPaths" ,
4046 }
4147
48+ timeStampFormat = "20060102150405.00000"
49+ deletedAccountAction = "deleted"
50+ createdAccountAction = "created"
51+ updatedAccountAction = "updated"
52+ )
53+
54+ func NewPublisher (config Config ) (* publisher , error ) {
4255 return & publisher {
43- DagPutter : ipfs .NewDagPutter (adder ),
4456 Config : config ,
4557 }, nil
4658}
4759
4860func (p * publisher ) PublishStateDiff (sd * StateDiff ) (string , error ) {
49- switch p .Mode {
50- case IPLD :
51- cidStr , err := p .DagPut (sd )
61+ switch p .Config .Mode {
62+ case CSV :
63+ return "" , p .publishStateDiffToCSV (* sd )
64+ default :
65+ return "" , p .publishStateDiffToCSV (* sd )
66+ }
67+ }
68+
69+ func (p * publisher ) publishStateDiffToCSV (sd StateDiff ) error {
70+ now := time .Now ()
71+ timeStamp := now .Format (timeStampFormat )
72+ filePath := p .Config .Path + timeStamp + ".csv"
73+ file , err := os .OpenFile (filePath , os .O_APPEND | os .O_CREATE | os .O_WRONLY , 0644 )
74+ if err != nil {
75+ return err
76+ }
77+ defer file .Close ()
78+
79+ writer := csv .NewWriter (file )
80+ defer writer .Flush ()
81+
82+ var data [][]string
83+ data = append (data , Headers )
84+ for _ , row := range accumulateCreatedAccountRows (sd ) {
85+ data = append (data , row )
86+ }
87+ for _ , row := range accumulateUpdatedAccountRows (sd ) {
88+ data = append (data , row )
89+ }
90+
91+ for _ , row := range accumulateDeletedAccountRows (sd ) {
92+ data = append (data , row )
93+ }
94+
95+ for _ , value := range data {
96+ err := writer .Write (value )
5297 if err != nil {
53- return "" , err
98+ return err
5499 }
100+ }
55101
56- return cidStr , err
57- case LDB :
58- case SQL :
59- default :
102+ return nil
103+ }
104+
105+ func accumulateUpdatedAccountRows (sd StateDiff ) [][]string {
106+ var updatedAccountRows [][]string
107+ for _ , accountDiff := range sd .UpdatedAccounts {
108+ formattedAccountData := formatAccountDiffIncremental (accountDiff , sd , updatedAccountAction )
109+
110+ updatedAccountRows = append (updatedAccountRows , formattedAccountData )
111+ }
112+
113+ return updatedAccountRows
114+ }
115+
116+ func accumulateDeletedAccountRows (sd StateDiff ) [][]string {
117+ var deletedAccountRows [][]string
118+ for _ , accountDiff := range sd .DeletedAccounts {
119+ formattedAccountData := formatAccountDiffEventual (accountDiff , sd , deletedAccountAction )
120+
121+ deletedAccountRows = append (deletedAccountRows , formattedAccountData )
122+ }
123+
124+ return deletedAccountRows
125+ }
126+
127+ func accumulateCreatedAccountRows (sd StateDiff ) [][]string {
128+ var createdAccountRows [][]string
129+ for _ , accountDiff := range sd .CreatedAccounts {
130+ formattedAccountData := formatAccountDiffEventual (accountDiff , sd , createdAccountAction )
131+
132+ createdAccountRows = append (createdAccountRows , formattedAccountData )
60133 }
61134
62- return "" , errors .New ("state diff publisher: unhandled publishing mode" )
63- }
135+ return createdAccountRows
136+ }
137+
138+ func formatAccountDiffEventual (accountDiff AccountDiffEventual , sd StateDiff , accountAction string ) []string {
139+ oldContractRoot := accountDiff .ContractRoot .OldValue
140+ newContractRoot := accountDiff .ContractRoot .NewValue
141+ var storageDiffPaths []string
142+ for k := range accountDiff .Storage {
143+ storageDiffPaths = append (storageDiffPaths , k )
144+ }
145+ formattedAccountData := []string {
146+ strconv .FormatInt (sd .BlockNumber , 10 ),
147+ sd .BlockHash .String (),
148+ accountAction ,
149+ string (accountDiff .Code ),
150+ accountDiff .CodeHash ,
151+ strconv .FormatUint (* accountDiff .Nonce .OldValue , 10 ),
152+ strconv .FormatUint (* accountDiff .Nonce .NewValue , 10 ),
153+ accountDiff .Balance .OldValue .String (),
154+ accountDiff .Balance .NewValue .String (),
155+ * oldContractRoot ,
156+ * newContractRoot ,
157+ strings .Join (storageDiffPaths , "," ),
158+ }
159+ return formattedAccountData
160+ }
161+
162+ func formatAccountDiffIncremental (accountDiff AccountDiffIncremental , sd StateDiff , accountAction string ) []string {
163+ oldContractRoot := accountDiff .ContractRoot .OldValue
164+ newContractRoot := accountDiff .ContractRoot .NewValue
165+ var storageDiffPaths []string
166+ for k := range accountDiff .Storage {
167+ storageDiffPaths = append (storageDiffPaths , k )
168+ }
169+ formattedAccountData := []string {
170+ strconv .FormatInt (sd .BlockNumber , 10 ),
171+ sd .BlockHash .String (),
172+ accountAction ,
173+ "" ,
174+ accountDiff .CodeHash ,
175+ strconv .FormatUint (* accountDiff .Nonce .OldValue , 10 ),
176+ strconv .FormatUint (* accountDiff .Nonce .NewValue , 10 ),
177+ accountDiff .Balance .OldValue .String (),
178+ accountDiff .Balance .NewValue .String (),
179+ * oldContractRoot ,
180+ * newContractRoot ,
181+ strings .Join (storageDiffPaths , "," ),
182+ }
183+ return formattedAccountData
184+ }
185+
0 commit comments