-
Notifications
You must be signed in to change notification settings - Fork 0
/
dag_io.go
183 lines (139 loc) · 6.17 KB
/
dag_io.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
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
// Package db defines the standard go-summercash transaction database.
package db
import (
"encoding/gob"
"errors"
"fmt"
"io/ioutil"
"math/big"
"os"
"path/filepath"
"strings"
"github.com/SummerCash/go-summercash/common"
"github.com/SummerCash/go-summercash/config"
"github.com/SummerCash/go-summercash/crypto"
"github.com/SummerCash/go-summercash/types"
)
// ErrNilDag is an error definition representing a root dag leaf of nil value.
var ErrNilDag = errors.New("dag has no root")
/* BEGIN EXPORTED METHODS */
// ImportBlockmesh attempts to reconstruct the dag from a given blockmesh.
func ImportBlockmesh(dbPath string, inflationRate float64, networkID uint) (*Dag, error) {
files, err := ioutil.ReadDir(filepath.FromSlash(dbPath)) // Walk keystore dir
if err != nil { // Check for errors
return &Dag{}, err // Return found error
}
alloc := make(map[string]*big.Float) // Init address list buffer
addresses := []common.Address{} // Init address list buffer
concatenatedAddresses := []byte{} // Init concat addr buffer
for _, file := range files { // Iterate through files
parsed, err := common.StringToAddress(strings.Split(strings.Split(file.Name(), "chain_")[1], ".json")[0]) // Parse file name
if err != nil { // Check for errors
return &Dag{}, err // Return found error
}
chain, err := types.ReadChainFromMemory(parsed) // Read chain from persistent memory
if err != nil { // Check for errors
return &Dag{}, err // Return found error
}
alloc[strings.Split(strings.Split(file.Name(), "chain_")[1], ".json")[0]] = chain.CalculateBalance() // Calculate balance
addresses = append(addresses, parsed) // Append parsed to address list
concatenatedAddresses = append(concatenatedAddresses, parsed[:]...) // Append parsed
}
config := &config.ChainConfig{
Alloc: alloc, // Set alloc
AllocAddresses: addresses, // Set alloc addresses
InflationRate: inflationRate, // Set inflation rate
NetworkID: networkID, // Set network ID
ChainID: common.NewHash(crypto.Sha3(concatenatedAddresses)), // Set chain ID
ChainVersion: config.Version, // Set version
} // Initialize chain config
err = config.WriteToMemory() // Write config to persistent memory
if err != nil { // Check for errors
return &Dag{}, err // Return found error
}
dag := NewDag() // Initialize dag
err = dag.MakeGenesis(config) // Make genesis
if err != nil { // Check for errors
return &Dag{}, err // Return found error
}
return dag, nil // Return initialized dag
}
// Flatten flattens the working dag. If the working
// dag is nil, an error is returned.
func (dag *Dag) Flatten() (*Flattened, error) {
if dag.Root == nil { // Check no root
return &Flattened{}, ErrNilDag // Return error
}
leaves := []*Leaf{dag.Root} // Init leaves list
children, err := dag.Root.GetChildren() // Get children
if err != nil { // Check for errors
return &Flattened{}, err // Return found error
}
leaves = append(leaves, children...) // Append children to leaves
transactions := []*types.Transaction{} // Initialize transactions
for _, leaf := range leaves { // Iterate through leaves
transactionCopy := *leaf.Transaction // Get raw value
err = transactionCopy.MakeEncodingSafe() // Make tx encoding safe
if err != nil { // Check for errors
return &Flattened{}, err // Return found error
}
transactions = append(transactions, &transactionCopy) // Append transaction
}
return &Flattened{
Transactions: transactions,
}, nil // Return flattened dag
}
// UnflattenDag attempts to unflatten the given flattened dag.
func UnflattenDag(flattened *Flattened) (*Dag, error) {
dag := NewDag() // Initialize dag ref
for _, transaction := range flattened.Transactions { // Iterate through transactions
err := transaction.RecoverSafeEncoding() // Recover tx
if err != nil { // Check for errors
return &Dag{}, err // Return found error
}
err = dag.AddTransaction(transaction) // Add tx to dag
if err != nil { // Check for errors
return &Dag{}, err // Return found error
}
}
return dag, nil // Return unflattened dag
}
// WriteToMemory writes the working dag to persistent memory.
func (dag *Dag) WriteToMemory(network string) error {
err := common.CreateDirIfDoesNotExist(common.DagDir) // Create dag dir
if err != nil { // Check for errors
return err // Return found error
}
file, err := os.Create(filepath.FromSlash(fmt.Sprintf("%s/dag_%s.gob", common.DagDir, network))) // Create dag file
defer file.Close() // Close file
if err != nil { // Check for errors
return err // Return found error
}
encoder := gob.NewEncoder(file) // Initialize encoder
flattened, err := dag.Flatten() // Flatten dag
if err != nil { // Check for errors
return err // Return found error
}
err = encoder.Encode(flattened) // Encode dag
if err != nil { // Check for errors
return err // Return found error
}
return nil // No error occurred, return nil
}
// ReadDagFromMemory attempts to reconstruct a dag from
// the local persisted dag db.
func ReadDagFromMemory(network string) (*Dag, error) {
file, err := os.Open(filepath.FromSlash(fmt.Sprintf("%s/dag_%s.gob", common.DagDir, network))) // Open file
defer file.Close() // Close file
if err != nil { // Check for errors
return &Dag{}, err // Return found error
}
decoder := gob.NewDecoder(file) // Initialize decoder
buffer := &Flattened{} // Init flattened dag buffer
err = decoder.Decode(buffer) // Decode file
if err != nil { // Check for errors
return &Dag{}, err // Return found error
}
return UnflattenDag(buffer) // Return decoded, unflattened dag
}
/* END EXPORTED METHODS */