neo3/neo_config/
config.rs

1use lazy_static::lazy_static;
2use primitive_types::H160;
3use serde::{Deserialize, Serialize};
4use std::{
5	collections::HashMap,
6	hash::{Hash, Hasher},
7	sync::{Arc, Mutex},
8};
9use tokio::runtime::Handle;
10
11#[derive(Clone, Debug, PartialEq, Eq, Hash, Deserialize, Serialize)]
12pub enum NeoNetwork {
13	MainNet = 0x334f454e,
14	TestNet = 0x74746e41,
15	PrivateNet = 0x4e454e,
16}
17
18impl NeoNetwork {
19	pub fn to_magic(&self) -> u32 {
20		match self {
21			NeoNetwork::MainNet => 0x334f454e,
22			NeoNetwork::TestNet => 0x74746e41,
23			NeoNetwork::PrivateNet => 0x4e454e,
24		}
25	}
26
27	pub fn from_magic(magic: u32) -> Option<NeoNetwork> {
28		match magic {
29			0x334f454e => Some(NeoNetwork::MainNet),
30			0x74746e41 => Some(NeoNetwork::TestNet),
31			0x4e454e => Some(NeoNetwork::PrivateNet),
32			_ => None,
33		}
34	}
35}
36
37pub const DEFAULT_BLOCK_TIME: u64 = 15_000;
38pub const DEFAULT_ADDRESS_VERSION: u8 = 0x35;
39pub const MAX_VALID_UNTIL_BLOCK_INCREMENT_BASE: u64 = 86_400_000;
40
41#[derive(Clone, Debug, Deserialize)]
42pub struct NeoConfig {
43	pub network: Option<u32>,
44	pub address_version: u8,
45	pub milliseconds_per_block: u32,
46	pub max_transactions_per_block: u32,
47	pub memory_pool_max_transactions: u32,
48	pub max_traceable_blocks: u32,
49	pub hardforks: HashMap<String, u32>,
50	pub initial_gas_distribution: u64,
51	pub validators_count: u32,
52	pub standby_committee: Vec<String>,
53	pub seed_list: Vec<String>,
54	pub nns_resolver: H160,
55	#[serde(skip)]
56	pub allows_transmission_on_fault: bool,
57}
58
59lazy_static! {
60	pub static ref NEOCONFIG: Mutex<NeoConfig> = Mutex::new(NeoConfig::default());
61}
62
63impl Hash for NeoConfig {
64	fn hash<H: Hasher>(&self, state: &mut H) {
65		self.network.hash(state);
66		self.milliseconds_per_block.hash(state);
67		self.max_transactions_per_block.hash(state);
68		self.memory_pool_max_transactions.hash(state);
69		self.max_traceable_blocks.hash(state);
70		self.initial_gas_distribution.hash(state);
71		self.validators_count.hash(state);
72		self.nns_resolver.hash(state);
73	}
74}
75
76impl Default for NeoConfig {
77	fn default() -> Self {
78		let mut hardforks = HashMap::new();
79		hardforks.insert("HF_Aspidochelone".to_string(), 1730000);
80		hardforks.insert("HF_Basilisk".to_string(), 4120000);
81		hardforks.insert("HF_Cockatrice".to_string(), 5450000);
82		hardforks.insert("HF_Domovoi".to_string(), 5570000);
83
84		NeoConfig {
85			network: Some(860833102), // TestNet
86			address_version: 53,
87			milliseconds_per_block: 15000,
88			max_transactions_per_block: 512,
89			memory_pool_max_transactions: 50000,
90			max_traceable_blocks: 2102400,
91			hardforks,
92			initial_gas_distribution: 5200000000000000,
93			validators_count: 7,
94			standby_committee: vec![
95				"03b209fd4f53a7170ea4444e0cb0a6bb6a53c2bd016926989cf85f9b0fba17a70c".to_string(),
96				"02df48f60e8f3e01c48ff40b9b7f1310d7a8b2a193188befe1c2e3df740e895093".to_string(),
97				"03b8d9d5771d8f513aa0869b9cc8d50986403b78c6da36890638c3d46a5adce04a".to_string(),
98				"02ca0e27697b9c248f6f16e085fd0061e26f44da85b58ee835c110caa5ec3ba554".to_string(),
99				"024c7b7fb6c310fccf1ba33b082519d82964ea93868d676662d4a59ad548df0e7d".to_string(),
100				"02aaec38470f6aad0042c6e877cfd8087d2676b0f516fddd362801b9bd3936399e".to_string(),
101				"02486fd15702c4490a26703112a5cc1d0923fd697a33406bd5a1c00e0013b09a70".to_string(),
102				"023a36c72844610b4d34d1968662424011bf783ca9d984efa19a20babf5582f3fe".to_string(),
103				"03708b860c1de5d87f5b151a12c2a99feebd2e8b315ee8e7cf8aa19692a9e18379".to_string(),
104				"03c6aa6e12638b36e88adc1ccdceac4db9929575c3e03576c617c49cce7114a050".to_string(),
105				"03204223f8c86b8cd5c89ef12e4f0dbb314172e9241e30c9ef2293790793537cf0".to_string(),
106				"02a62c915cf19c7f19a50ec217e79fac2439bbaad658493de0c7d8ffa92ab0aa62".to_string(),
107				"03409f31f0d66bdc2f70a9730b66fe186658f84a8018204db01c106edc36553cd0".to_string(),
108				"0288342b141c30dc8ffcde0204929bb46aed5756b41ef4a56778d15ada8f0c6654".to_string(),
109				"020f2887f41474cfeb11fd262e982051c1541418137c02a0f4961af911045de639".to_string(),
110				"0222038884bbd1d8ff109ed3bdef3542e768eef76c1247aea8bc8171f532928c30".to_string(),
111				"03d281b42002647f0113f36c7b8efb30db66078dfaaa9ab3ff76d043a98d512fde".to_string(),
112				"02504acbc1f4b3bdad1d86d6e1a08603771db135a73e61c9d565ae06a1938cd2ad".to_string(),
113				"0226933336f1b75baa42d42b71d9091508b638046d19abd67f4e119bf64a7cfb4d".to_string(),
114				"03cdcea66032b82f5c30450e381e5295cae85c5e6943af716cc6b646352a6067dc".to_string(),
115				"02cd5a5547119e24feaa7c2a0f37b8c9366216bab7054de0065c9be42084003c8a".to_string(),
116			],
117			seed_list: vec![
118				"seed1.neo.org:10333".to_string(),
119				"seed2.neo.org:10333".to_string(),
120				"seed3.neo.org:10333".to_string(),
121				"seed4.neo.org:10333".to_string(),
122				"seed5.neo.org:10333".to_string(),
123			],
124			nns_resolver: H160::from_slice(
125				&hex::decode("50ac1c37690cc2cfc594472833cf57505d5f46de")
126					.expect("Static hex string for NNS resolver should always be valid"),
127			),
128			allows_transmission_on_fault: false,
129		}
130	}
131}
132
133impl NeoConfig {
134	pub fn new(json_config: &str) -> Result<Self, serde_json::Error> {
135		let mut config: NeoConfig = serde_json::from_str(json_config)?;
136		config.allows_transmission_on_fault = false;
137		Ok(config)
138	}
139
140	pub fn set_network(&mut self, magic: u32) -> Result<(), &'static str> {
141		// u32 can't exceed 0xFFFFFFFF, so this check is redundant
142		// Keeping the function signature for API compatibility
143
144		self.network = Some(magic);
145		Ok(())
146	}
147
148	pub fn get_max_valid_until_block_increment(&self) -> u32 {
149		(MAX_VALID_UNTIL_BLOCK_INCREMENT_BASE / self.milliseconds_per_block as u64) as u32
150	}
151
152	pub fn mainnet() -> Self {
153		let mut hardforks = HashMap::new();
154		hardforks.insert("HF_Aspidochelone".to_string(), 1730000);
155		hardforks.insert("HF_Basilisk".to_string(), 4120000);
156		hardforks.insert("HF_Cockatrice".to_string(), 5450000);
157		hardforks.insert("HF_Domovoi".to_string(), 5570000);
158
159		NeoConfig {
160			network: Some(860833102),
161			address_version: 53,
162			milliseconds_per_block: 15000,
163			max_transactions_per_block: 512,
164			memory_pool_max_transactions: 50000,
165			max_traceable_blocks: 2102400,
166			hardforks,
167			initial_gas_distribution: 5200000000000000,
168			validators_count: 7,
169			standby_committee: vec![
170				"03b209fd4f53a7170ea4444e0cb0a6bb6a53c2bd016926989cf85f9b0fba17a70c".to_string(),
171				"02df48f60e8f3e01c48ff40b9b7f1310d7a8b2a193188befe1c2e3df740e895093".to_string(),
172				"03b8d9d5771d8f513aa0869b9cc8d50986403b78c6da36890638c3d46a5adce04a".to_string(),
173				"02ca0e27697b9c248f6f16e085fd0061e26f44da85b58ee835c110caa5ec3ba554".to_string(),
174				"024c7b7fb6c310fccf1ba33b082519d82964ea93868d676662d4a59ad548df0e7d".to_string(),
175				"02aaec38470f6aad0042c6e877cfd8087d2676b0f516fddd362801b9bd3936399e".to_string(),
176				"02486fd15702c4490a26703112a5cc1d0923fd697a33406bd5a1c00e0013b09a70".to_string(),
177				"023a36c72844610b4d34d1968662424011bf783ca9d984efa19a20babf5582f3fe".to_string(),
178				"03708b860c1de5d87f5b151a12c2a99feebd2e8b315ee8e7cf8aa19692a9e18379".to_string(),
179				"03c6aa6e12638b36e88adc1ccdceac4db9929575c3e03576c617c49cce7114a050".to_string(),
180				"03204223f8c86b8cd5c89ef12e4f0dbb314172e9241e30c9ef2293790793537cf0".to_string(),
181				"02a62c915cf19c7f19a50ec217e79fac2439bbaad658493de0c7d8ffa92ab0aa62".to_string(),
182				"03409f31f0d66bdc2f70a9730b66fe186658f84a8018204db01c106edc36553cd0".to_string(),
183				"0288342b141c30dc8ffcde0204929bb46aed5756b41ef4a56778d15ada8f0c6654".to_string(),
184				"020f2887f41474cfeb11fd262e982051c1541418137c02a0f4961af911045de639".to_string(),
185				"0222038884bbd1d8ff109ed3bdef3542e768eef76c1247aea8bc8171f532928c30".to_string(),
186				"03d281b42002647f0113f36c7b8efb30db66078dfaaa9ab3ff76d043a98d512fde".to_string(),
187				"02504acbc1f4b3bdad1d86d6e1a08603771db135a73e61c9d565ae06a1938cd2ad".to_string(),
188				"0226933336f1b75baa42d42b71d9091508b638046d19abd67f4e119bf64a7cfb4d".to_string(),
189				"03cdcea66032b82f5c30450e381e5295cae85c5e6943af716cc6b646352a6067dc".to_string(),
190				"02cd5a5547119e24feaa7c2a0f37b8c9366216bab7054de0065c9be42084003c8a".to_string(),
191			],
192			seed_list: vec![
193				"seed1.neo.org:10333".to_string(),
194				"seed2.neo.org:10333".to_string(),
195				"seed3.neo.org:10333".to_string(),
196				"seed4.neo.org:10333".to_string(),
197				"seed5.neo.org:10333".to_string(),
198			],
199			nns_resolver: H160::from_slice(
200				&hex::decode("50ac1c37690cc2cfc594472833cf57505d5f46de")
201					.expect("Static hex string for NNS resolver should always be valid"),
202			),
203			allows_transmission_on_fault: false,
204		}
205	}
206}
207
208#[derive(Clone, Debug)]
209pub struct Counter {
210	count: Arc<Mutex<u32>>,
211}
212
213impl Hash for Counter {
214	fn hash<H: Hasher>(&self, state: &mut H) {
215		if let Ok(count) = self.count.lock() {
216			count.hash(state);
217		} else {
218			// If we can't lock the mutex, hash a default value
219			0u32.hash(state);
220		}
221	}
222}
223
224impl PartialEq for Counter {
225	fn eq(&self, other: &Self) -> bool {
226		match (self.count.lock(), other.count.lock()) {
227			(Ok(self_count), Ok(other_count)) => *self_count == *other_count,
228			_ => false, // If we can't lock either mutex, consider them not equal
229		}
230	}
231}
232
233impl Counter {
234	pub fn new() -> Self {
235		Counter { count: Arc::new(Mutex::new(1)) }
236	}
237
238	pub fn get_and_increment(&self) -> u32 {
239		if let Ok(mut count) = self.count.lock() {
240			let v: u32 = *count;
241			*count += 1;
242			v
243		} else {
244			// If we can't lock the mutex, return a default value
245			// This is a fallback to avoid panicking
246			1
247		}
248	}
249}