1use urma_core::format::Urma;
2pub struct Limits;
3impl Limits {
4 pub const INPUT_BYTES: usize = 16 * 1024 * 1024;
5 pub const RECORDS: usize = Self::INPUT_BYTES / Urma::CHUNK_BYTES;
6 pub const CONTAINER_BYTES: usize = 12 + Self::RECORDS * (4 + Urma::PRIVATE_RECORD_BYTES);
7 pub const OBJECTS: usize = 64;
8}
9
10use crate::error::{Context, Error};
11use serde_json::Value;
12
13pub fn confirmations(value: &Value) -> Result<i64, Error> {
14 match value.get("confirmations") {
15 Some(number) => number.as_i64().context("invalid confirmations"),
16 None => Ok(0),
17 }
18}
19
20#[derive(Clone, Copy)]
21pub enum RpcScope<'a> {
22 Node,
23 Wallet(&'a str),
24}
25impl<'a> From<Option<&'a str>> for RpcScope<'a> {
26 fn from(wallet: Option<&'a str>) -> Self {
27 match wallet {
28 Some(name) => Self::Wallet(name),
29 None => Self::Node,
30 }
31 }
32}
33#[derive(Clone, Copy)]
34pub enum ScanEnd {
35 Tip,
36 Height(u64),
37}
38#[derive(Clone, Copy)]
39pub enum RevealSelection {
40 All,
41 First(usize),
42}
43impl RevealSelection {
44 pub fn count(self, total: usize) -> usize {
45 match self {
46 Self::All => total,
47 Self::First(count) => count.min(total),
48 }
49 }
50}
51#[derive(Clone, Copy)]
52pub enum TxPresence {
53 Missing,
54 Observed(i64),
55}
56impl TxPresence {
57 pub fn confirmed(self) -> bool {
58 match self {
59 Self::Missing => false,
60 Self::Observed(count) => count > 0,
61 }
62 }
63}
64
65#[derive(Clone, Copy)]
66pub enum MempoolPresence {
67 Absent,
68 Present,
69}
70impl From<Option<usize>> for RevealSelection {
71 fn from(count: Option<usize>) -> Self {
72 match count {
73 Some(n) => Self::First(n),
74 None => Self::All,
75 }
76 }
77}
78pub const MAX_OBJECTS: usize = Limits::OBJECTS;
79pub const MAX_DIRECTORY_RECORDS: usize = MAX_OBJECTS * Limits::RECORDS;
80pub const LITECOIN_NETWORK: &str = "litecoin-testnet";
81pub const LITECOIN_GENESIS: &str = urma_chain::observation::Chain::LITECOIN_TESTNET_GENESIS;
82pub const LITECOIN_RPC_PORT: u16 = 19332;
83pub const LITECOIN_RETURN_LITOSHIS: u64 = 1_000;
84pub const LITECOIN_MAX_FEE_LITOSHIS: u64 = 500_000;
85pub const LITECOIN_MAX_SCAN_BLOCKS: u64 = 10_000;
86pub const LITECOIN_MAX_SCAN_BYTES: usize = 256 * 1024 * 1024;
87pub const LITECOIN_MAX_JOURNAL_BYTES: usize = 4_000_000;
88pub const RELAY_MAX_BUDGET_SATS: u64 = 500_000;
89pub const SOURCE_MAX_BLOCK_BYTES: usize = 4_000_000;
90pub const SOURCE_MAX_JSON_BYTES: usize = 1_000_000;
91pub const SOURCE_MAX_UTXOS: usize = 1_000;
92pub const SOURCE_MAX_SCAN_BLOCKS: u64 = 10_000;
93pub const SOURCE_MAX_SCAN_BYTES: usize = 256 * 1024 * 1024;
94pub const BITCOIN_RETURN_SATS: u64 = 1_000;
95pub const BITCOIN_MAX_FEE_SATS: u64 = 500_000;
96pub const BITCOIN_MAX_FEE_RATE: u64 = 100;
97
98pub const PUBLIC_METHODS: [&str; 10] = [
99 "getblockhash",
100 "getblockchaininfo",
101 "getrawtransaction",
102 "getblockheader",
103 "getblock",
104 "getrawmempool",
105 "gettxout",
106 "addressutxos",
107 "testmempoolaccept",
108 "sendrawtransaction",
109];
110pub const ABSENT_TRANSACTION: &str = "transaction not found on selected network";
111pub const ABSENT_RECORD: &str = "transaction or block not found on selected network";
112pub const MAX_PROVIDERS: usize = 8;
113pub const TIP_RACE_WIDTH: usize = 2;
114pub const PROVIDER_BREAKER_FAILURES: u32 = 3;
115pub const PROVIDER_BREAKER_WINDOW: std::time::Duration = std::time::Duration::from_secs(30);
116pub const PROVIDER_RETRY_DEFAULT: std::time::Duration = std::time::Duration::from_secs(60);
117pub const PROVIDER_RETRY_MAX: std::time::Duration = std::time::Duration::from_secs(300);
118pub const PROVIDER_PACING: std::time::Duration = std::time::Duration::from_millis(300);
119pub const RPC_GATEWAY_WINDOW: std::time::Duration = std::time::Duration::from_secs(60);
120pub const RPC_GATEWAY_WINDOW_REQUESTS: u8 = 5;
121pub const LOCAL_PROVIDER_LABEL: &str = "local validating node";
122pub const ELECTRUM_PROTOCOL: &str = "1.4";
123pub const ELECTRUM_CONNECT_TIMEOUT: std::time::Duration = std::time::Duration::from_secs(10);
124pub const ELECTRUM_MAX_LINE_BYTES: usize = 4 * 1024 * 1024;
125pub const ELECTRUM_UNSPENT_CACHE: std::time::Duration = std::time::Duration::from_secs(30);
126pub const WALLET_VERIFY_OUTPUTS: usize = 64;
127pub const WALLET_GAP: u32 = 20;
128pub const WALLET_RANGE: u32 = 1000;
129pub const WALLET_MAX_COINS: usize = 1000;
130pub const WALLET_MAX_INPUTS: usize = 50;
131pub const SUBMISSION_ACK_WINDOW: std::time::Duration = std::time::Duration::from_secs(180);
132pub const AWAITING_PARENT: &str = "awaiting parent propagation across sources";
133pub const MISSING_INPUT_REJECTIONS: [&str; 2] =
134 ["missing-inputs", "bad-txns-inputs-missingorspent"];
135pub const SUBMISSION_PRESENCE_CHECKS: u32 = 3;
136pub const SUBMISSION_PRESENCE_DELAY: std::time::Duration = std::time::Duration::from_secs(4);
137pub const ELECTRUM_PROBE_METHODS: [&str; 5] = [
138 "server.features",
139 "blockchain.transaction.id_from_pos",
140 "blockchain.transaction.get",
141 "blockchain.scripthash.get_balance",
142 "blockchain.scripthash.listunspent",
143];
144
145pub fn method_timeout(method: &str) -> std::time::Duration {
146 match method {
147 "getblock" => std::time::Duration::from_secs(60),
148 "getrawmempool" | "addressutxos" => std::time::Duration::from_secs(30),
149 _ => std::time::Duration::from_secs(12),
150 }
151}
152
153pub const STANDARD_TX_WEIGHT: u64 = 400_000;
154pub const PUBLICATION_BUFFER_WEIGHT: u64 = 7_960_000;
155pub const PUBLICATION_PENDING_COMMITS: usize = 24;
156pub const PUBLICATION_COMMIT_VBYTES: u64 = 90_000;
157pub const LITECOIN_DUST_RELAY_FEE: u64 = 30_000;
158
159pub const P2P_PROTOCOL_VERSION: u32 = 70015;
160pub const P2P_USER_AGENT: &str = "/urma:0.2.2/";
161pub const P2P_MAX_PEERS: usize = 8;
162pub const P2P_DIAL_CONCURRENCY: usize = 24;
163pub const P2P_REDIAL_BACKOFF_SECS: u64 = 30;
164pub const P2P_GOOD_PEERS: usize = 64;
165pub const P2P_POLL_MESSAGES: usize = 64;
166pub const P2P_POLL_READ_TIMEOUT_MILLIS: u64 = 1000;
167pub const P2P_GOSSIP_FUTURE_SECS: u64 = 600;
168pub const P2P_GOSSIP_PENALTY_SECS: u64 = 5 * 24 * 60 * 60;
169pub const P2P_IPV6_ROUTE_PROBE: &str = "[2001:4860:4860::8888]:53";
170pub const P2P_CONNECT_TIMEOUT_SECS: u64 = 2;
171pub const P2P_TOP_UP_BUDGET_SECS: u64 = 6;
172pub const P2P_HANDSHAKE_TIMEOUT_SECS: u64 = 15;
173pub const P2P_READ_TIMEOUT_SECS: u64 = 20;
174pub const P2P_HEADERS_TIMEOUT_SECS: u64 = 8;
175pub const P2P_BLOCK_TIMEOUT_SECS: u64 = 60;
176pub const P2P_BLOCK_PEER_TIMEOUT_SECS: u64 = 8;
177pub const P2P_MAX_PAYLOAD_BYTES: usize = 8_000_000;
178pub const P2P_MAX_HEADERS_PER_MESSAGE: usize = 2000;
179pub const P2P_MAX_INVENTORY: usize = 50_000;
180pub const P2P_MAX_ADDRESSES: usize = 1000;
181pub const P2P_ADDRESS_POOL: usize = 1000;
182pub const P2P_HEADER_CACHE_MAX: usize = 1_000_000;
183pub const P2P_HEADER_CACHE_REVALIDATE: usize = 2016;
184pub const P2P_BLOCK_CACHE_BYTES: usize = 64 * 1024 * 1024;
185pub const P2P_TIP_REFRESH_SECS: u64 = 20;
186pub const P2P_MAX_FUTURE_SECS: u32 = 7200;
187pub const P2P_MEDIAN_TIME_SPAN: usize = 11;
188pub const P2P_LIMITED_PEER_DEPTH: u64 = 288;
189pub const P2P_HEIGHT_SLACK: u64 = 12;
190pub const P2P_IDLE_POLL_MILLIS: u64 = 250;
191pub const P2P_LOCATOR_LINEAR: usize = 10;
192pub const P2P_LITECOIN_NODE_MWEB: u64 = 1 << 24;
193pub const P2P_SEED_INTERVAL_SECS: u64 = 60;
194pub const P2P_SEED_TIMEOUT_SECS: u64 = 3;
195pub const P2P_FETCH_ATTEMPTS: usize = 4;
196pub const P2P_POW_WORKERS: usize = 4;
197pub const P2P_PREFETCH_BLOCKS: u64 = 4;
198
199pub struct Checkpoint {
200 pub height: u64,
201 pub header: &'static str,
202 pub next_hash: &'static str,
203}
204
205pub const LITECOIN_MAINNET_CHECKPOINT: Checkpoint = Checkpoint {
206 height: 3_187_295,
207 header: "14000020931d31f868aaaad00ab3d07bfb30e1adf261e843ea1efe367ea85ed4d50b0beccbee28d90e5dc1495e97786a8dc63e6b741e1ca8ef6226323ed5039c5d74fa7e73d7bd6adda82e1930924a09",
208 next_hash: "17976eb8639d9274e2f0b96314aa4cd259c976eecd7100c1c3bbf7c2ad31ed7a",
209};
210
211pub const LITECOIN_TESTNET_CHECKPOINT: Checkpoint = Checkpoint {
212 height: 4_904_927,
213 header: "000000206a866190a6c8e920929c51bc5b3318eb8fb68bd411ae365a5d922f33059816bc6c23b147db3e44528fd06f87e19e876788df08f5323a1ad46f2c863910ef02762125c06affff0f1ec0003c2f",
214 next_hash: "ed607657d250aa0a76e6a6e6c451bfa313f93c727a0bb96ba371e9007200e843",
215};
216
217pub fn publication_return(chain: urma_chain::observation::Chain) -> u64 {
218 use urma_chain::observation::Chain;
219 match chain {
220 Chain::LitecoinTestnet | Chain::LitecoinMainnet => 110 * LITECOIN_DUST_RELAY_FEE / 1000,
221 Chain::BitcoinMainnet | Chain::BitcoinRegtest | Chain::BitcoinTestnet4 => 1000,
222 }
223}