-
Notifications
You must be signed in to change notification settings - Fork 0
/
config.go
195 lines (175 loc) · 7.91 KB
/
config.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
184
185
186
187
188
189
190
191
192
193
194
195
package blockchain
import (
"encoding/json"
"errors"
"fmt"
"net/http"
"strings"
"time"
"github.com/kelseyhightower/envconfig"
"github.com/rs/zerolog/log"
)
var (
// SimulatedEVMNetwork ensures that the test will use a default simulated geth instance
SimulatedEVMNetwork = EVMNetwork{
Name: "Simulated Geth",
ClientImplementation: EthereumClientImplementation,
Simulated: true,
ChainID: 1337,
URLs: []string{"ws://geth:8546"},
HTTPURLs: []string{"http://geth:8544"},
PrivateKeys: []string{
"ac0974bec39a17e36ba4a6b4d238ff944bacb478cbed5efcae784d7bf4f2ff80",
"59c6995e998f97a5a0044966f0945389dc9e86dae88c7a8412f4603b6b78690d",
"5de4111afa1a4b94908f83103eb1f1706367c2e68ca870fc3fb9a804cdab365a",
"8d351f5fc88484c65c15d44c7d3aa8779d12383373fb42d802e4576a50f765e5",
"44fd8327d465031c71b20d7a5ba60bb01d33df8256fba406467bcb04e6f7262c",
"809871f5c72d01a953f44f65d8b7bd0f3e39aee084d8cd0bc17ba3c386391814",
"f29f5fda630ac9c0e39a8b05ec5b4b750a2e6ef098e612b177c6641bb5a675e1",
"99b256477c424bb0102caab28c1792a210af906b901244fa67e2b704fac5a2bb",
"bb74c3a9439ca83d09bcb4d3e5e65d8bc4977fc5b94be4db73772b22c3ff3d1a",
"58845406a51d98fb2026887281b4e91b8843bbec5f16b89de06d5b9a62b231e8",
},
PluginTransactionLimit: 500000,
Timeout: StrDuration{2 * time.Minute},
MinimumConfirmations: 1,
GasEstimationBuffer: 10000,
}
)
// EVMNetwork configures all the data the test needs to connect and operate on an EVM compatible network
type EVMNetwork struct {
// Human-readable name of the network:
Name string `toml:"evm_name" json:"evm_name"`
// Chain ID for the blockchain
ChainID int64 `toml:"evm_chain_id" json:"evm_chain_id"`
// List of websocket URLs you want to connect to
URLs []string `toml:"evm_urls" json:"evm_urls"`
// List of websocket URLs you want to connect to
HTTPURLs []string `toml:"evm_http_urls" json:"evm_http_urls"`
// True if the network is simulated like a geth instance in dev mode. False if the network is a real test or mainnet
Simulated bool `toml:"evm_simulated" json:"evm_simulated"`
// Type of chain client node. Values: "none" | "geth" | "besu"
SimulationType string `toml:"evm_simulation_type" json:"evm_simulation_type"`
// List of private keys to fund the tests
PrivateKeys []string `toml:"evm_keys" json:"evm_keys"`
// Default gas limit to assume that Plugin nodes will use. Used to try to estimate the funds that Plugin
// nodes require to run the tests.
PluginTransactionLimit uint64 `toml:"evm_plugin_transaction_limit" json:"evm_plugin_transaction_limit"`
// How long to wait for on-chain operations before timing out an on-chain operation
Timeout StrDuration `toml:"evm_transaction_timeout" json:"evm_transaction_timeout"`
// How many block confirmations to wait to confirm on-chain events
MinimumConfirmations int `toml:"evm_minimum_confirmations" json:"evm_minimum_confirmations"`
// How much WEI to add to gas estimations for sending transactions
GasEstimationBuffer uint64 `toml:"evm_gas_estimation_buffer" json:"evm_gas_estimation_buffer"`
// ClientImplementation is the blockchain client to use when interacting with the test chain
ClientImplementation ClientImplementation `toml:"client_implementation" json:"client_implementation"`
// SupportsEIP1559 indicates if the client should try to use EIP1559 style gas and transactions
SupportsEIP1559 bool `toml:"evm_supports_eip1559" json:"evm_supports_eip1559"`
// Default gaslimit to use when sending transactions. If set this will override the transactionOptions gaslimit in case the
// transactionOptions gaslimit is lesser than the defaultGasLimit.
DefaultGasLimit uint64 `toml:"evm_default_gas_limit" json:"evm_default_gas_limit"`
// Few chains use finality tags to mark blocks as finalized. This is used to determine if the chain uses finality tags.
FinalityTag bool `toml:"evm_finality_tag" json:"evm_finality_tag"`
// If the chain does not use finality tags, this is used to determine how many blocks to wait for before considering a block finalized.
FinalityDepth uint64 `toml:"evm_finality_depth" json:"evm_finality_depth"`
// TimeToReachFinality is the time it takes for a block to be considered final. This is used to determine how long to wait for a block to be considered final.
TimeToReachFinality StrDuration `toml:"evm_time_to_reach_finality" json:"evm_time_to_reach_finality"`
// Only used internally, do not set
URL string `ignored:"true"`
// Only used internally, do not set
Headers http.Header `toml:"evm_headers" json:"evm_headers"`
}
// LoadNetworkFromEnvironment loads an EVM network from default environment variables. Helpful in soak tests
func LoadNetworkFromEnvironment() EVMNetwork {
var network EVMNetwork
if err := envconfig.Process("", &network); err != nil {
log.Fatal().Err(err).Msg("Error loading network settings from environment variables")
}
log.Debug().Str("Name", network.Name).Int64("Chain ID", network.ChainID).Msg("Loaded Network")
return network
}
// ToMap marshalls the network's values to a generic map, useful for setting env vars on instances like the remote runner
// Map Structure
// "envconfig_key": stringValue
func (e *EVMNetwork) ToMap() map[string]interface{} {
return map[string]interface{}{
"evm_name": e.Name,
"evm_chain_id": fmt.Sprint(e.ChainID),
"evm_urls": strings.Join(e.URLs, ","),
"evm_http_urls": strings.Join(e.HTTPURLs, ","),
"evm_simulated": fmt.Sprint(e.Simulated),
"evm_simulation_type": e.SimulationType,
"evm_keys": strings.Join(e.PrivateKeys, ","),
"evm_plugin_transaction_limit": fmt.Sprint(e.PluginTransactionLimit),
"evm_transaction_timeout": fmt.Sprint(e.Timeout),
"evm_minimum_confirmations": fmt.Sprint(e.MinimumConfirmations),
"evm_gas_estimation_buffer": fmt.Sprint(e.GasEstimationBuffer),
"client_implementation": fmt.Sprint(e.ClientImplementation),
}
}
var (
evmNetworkTOML = `[[EVM]]
ChainID = '%d'
MinContractPayment = '0'
%s`
evmNodeTOML = `[[EVM.Nodes]]
Name = '%s'
WSURL = '%s'
HTTPURL = '%s'`
)
// MustPluginTOML marshals EVM network values into a TOML setting snippet. Will fail if error is encountered
// Can provide more detailed config for the network if non-default behaviors are desired.
func (e *EVMNetwork) MustPluginTOML(networkDetails string) string {
if len(e.HTTPURLs) != len(e.URLs) || len(e.HTTPURLs) == 0 || len(e.URLs) == 0 {
log.Fatal().
Int("WS Count", len(e.URLs)).
Int("HTTP Count", len(e.HTTPURLs)).
Interface("WS URLs", e.URLs).
Interface("HTTP URLs", e.HTTPURLs).
Msg("Amount of HTTP and WS URLs should match, and not be empty")
return ""
}
netString := fmt.Sprintf(evmNetworkTOML, e.ChainID, networkDetails)
for index := range e.URLs {
netString = fmt.Sprintf("%s\n\n%s", netString,
fmt.Sprintf(evmNodeTOML, fmt.Sprintf("node-%d", index), e.URLs[index], e.HTTPURLs[index]))
}
return netString
}
// StrDuration is JSON/TOML friendly duration that can be parsed from "1h2m0s" Go format
type StrDuration struct {
time.Duration
}
func (d *StrDuration) MarshalJSON() ([]byte, error) {
return json.Marshal(d.String())
}
func (d *StrDuration) UnmarshalJSON(b []byte) error {
var v interface{}
if err := json.Unmarshal(b, &v); err != nil {
return err
}
switch value := v.(type) {
case string:
var err error
d.Duration, err = time.ParseDuration(value)
if err != nil {
return err
}
return nil
default:
return errors.New("invalid duration")
}
}
// MarshalText implements the text.Marshaler interface (used by toml)
func (d StrDuration) MarshalText() ([]byte, error) {
return []byte(d.Duration.String()), nil
}
// UnmarshalText implements the text.Unmarshaler interface (used by toml)
func (d *StrDuration) UnmarshalText(b []byte) error {
var err error
d.Duration, err = time.ParseDuration(string(b))
if err != nil {
return err
}
return nil
}