Skip to content

Commit 917468b

Browse files
committed
Add per-chain policy overrides for chain types
Introduce per-chain policy support so individual chains can override chain-type allowlist and cache rules. Adds a ChainPolicyConfig and a `chains: HashMap<Chain, ChainPolicyConfig>` field to ChainTypeConfig, and a chain_policy_config helper. ChainTypesConfig::allows and ::cache_rules now resolve rules with this precedence: explicit ChainConfig -> chain policy -> chain type. Also update imports (primitives::Chain), adjust tests to cover allowlist and cache overrides, and add example entries for thorchain/mayachain in core/apps/dynode/config.yml.
1 parent df635fe commit 917468b

2 files changed

Lines changed: 79 additions & 13 deletions

File tree

core/apps/dynode/config.yml

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -87,6 +87,27 @@ chain_types:
8787
- path: /cosmos/staking/v1beta1/validators
8888
method: GET
8989
ttl: 1d
90+
chains:
91+
thorchain:
92+
allowlist:
93+
- path: /thorchain/inbound_addresses
94+
method: GET
95+
- path: /thorchain/quote/swap
96+
method: GET
97+
- path: /thorchain/tx/status/**
98+
method: GET
99+
cache:
100+
- path: /thorchain/inbound_addresses
101+
method: GET
102+
ttl: 10m
103+
mayachain:
104+
allowlist:
105+
- path: /mayachain/inbound_addresses
106+
method: GET
107+
- path: /mayachain/quote/swap
108+
method: GET
109+
- path: /mayachain/tx/status/**
110+
method: GET
90111
hypercore:
91112
cache:
92113
- path: /info

core/apps/dynode/src/config/chain_types.rs

Lines changed: 58 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
use std::collections::HashMap;
22

3-
use primitives::ChainType;
3+
use primitives::{Chain, ChainType};
44
use serde::Deserialize;
55

66
use crate::jsonrpc_types::RequestType;
@@ -20,7 +20,7 @@ impl ChainTypesConfig {
2020
}
2121

2222
self.chain_type_config(chain_config)
23-
.and_then(|config| config.allowlist.as_ref())
23+
.and_then(|config| config.allowlist(chain_config.chain))
2424
.is_none_or(|allowlist| allowlist.allows(request_type))
2525
}
2626

@@ -29,7 +29,10 @@ impl ChainTypesConfig {
2929
return rules.clone();
3030
}
3131

32-
self.chain_type_config(chain_config).and_then(|config| config.cache.as_ref()).cloned().unwrap_or_default()
32+
self.chain_type_config(chain_config)
33+
.and_then(|config| config.cache(chain_config.chain))
34+
.cloned()
35+
.unwrap_or_default()
3336
}
3437

3538
fn chain_type_config(&self, chain_config: &ChainConfig) -> Option<&ChainTypeConfig> {
@@ -39,6 +42,24 @@ impl ChainTypesConfig {
3942

4043
#[derive(Debug, Clone, Deserialize)]
4144
struct ChainTypeConfig {
45+
#[serde(flatten)]
46+
policy: ChainPolicyConfig,
47+
#[serde(default)]
48+
chains: HashMap<Chain, ChainPolicyConfig>,
49+
}
50+
51+
impl ChainTypeConfig {
52+
fn allowlist(&self, chain: Chain) -> Option<&AllowlistConfig> {
53+
self.chains.get(&chain).and_then(|config| config.allowlist.as_ref()).or(self.policy.allowlist.as_ref())
54+
}
55+
56+
fn cache(&self, chain: Chain) -> Option<&Vec<CacheRule>> {
57+
self.chains.get(&chain).and_then(|config| config.cache.as_ref()).or(self.policy.cache.as_ref())
58+
}
59+
}
60+
61+
#[derive(Debug, Clone, Deserialize)]
62+
struct ChainPolicyConfig {
4263
allowlist: Option<AllowlistConfig>,
4364
cache: Option<Vec<CacheRule>>,
4465
}
@@ -111,19 +132,43 @@ mod tests {
111132
"ethereum": {
112133
"allowlist": [
113134
{ "rpc_method": "eth_call" }
114-
]
135+
],
136+
"chains": {
137+
"ethereum": {
138+
"allowlist": [
139+
{ "rpc_method": "eth_getLogs" }
140+
]
141+
}
142+
}
143+
}
144+
}))
145+
.unwrap();
146+
147+
assert!(!config.allows(&chain_config(Chain::Ethereum), &jsonrpc("eth_call")));
148+
assert!(config.allows(&chain_config(Chain::Ethereum), &jsonrpc("eth_getLogs")));
149+
assert!(config.allows(&chain_config(Chain::Arbitrum), &jsonrpc("eth_call")));
150+
}
151+
152+
#[test]
153+
fn test_chain_cache_replaces_chain_type_cache() {
154+
let config: ChainTypesConfig = serde_json::from_value(json!({
155+
"cosmos": {
156+
"cache": [
157+
{ "path": "/cosmos/staking/v1beta1/validators", "method": "GET", "ttl": "1d" }
158+
],
159+
"chains": {
160+
"thorchain": {
161+
"cache": [
162+
{ "path": "/thorchain/inbound_addresses", "method": "GET", "ttl": "10m" }
163+
]
164+
}
165+
}
115166
}
116167
}))
117168
.unwrap();
118-
let mut chain_config = chain_config(Chain::Ethereum);
119-
chain_config.allowlist = Some(
120-
serde_json::from_value(json!([
121-
{ "rpc_method": "eth_getLogs" }
122-
]))
123-
.unwrap(),
124-
);
125169

126-
assert!(!config.allows(&chain_config, &jsonrpc("eth_call")));
127-
assert!(config.allows(&chain_config, &jsonrpc("eth_getLogs")));
170+
let rules = config.cache_rules(&chain_config(Chain::Thorchain));
171+
assert_eq!(rules.len(), 1);
172+
assert_eq!(rules[0].path.as_deref(), Some("/thorchain/inbound_addresses"));
128173
}
129174
}

0 commit comments

Comments
 (0)