mirror of
https://github.com/fluencelabs/examples
synced 2025-04-25 10:42:16 +00:00
Add section 5: Decentralized Oracles With Fluence And Aqua (#35)
* init quickstart-5 * update consensus calc, tests * update serivce, aqua * update service and deploymnt * update aqua, air * add seq version * update aquq * update examples * add fold, no fold to aqua * update par * update service, aqua with err value * update tests with err_val * add connect check, remove peer.connect funcs * update Readme * move body to gitbook
This commit is contained in:
parent
e61bc8b9d4
commit
dafd1a9296
26
quickstart/5-oracle-service/Cargo.toml
Normal file
26
quickstart/5-oracle-service/Cargo.toml
Normal file
@ -0,0 +1,26 @@
|
|||||||
|
[package]
|
||||||
|
name = "quickstart-5-timestamp-oracle"
|
||||||
|
version = "0.1.0"
|
||||||
|
authors = ["boneyard93501 <4523011+boneyard93501@users.noreply.github.com>"]
|
||||||
|
edition = "2018"
|
||||||
|
description = "ts-cons, a Marine wasi module"
|
||||||
|
license = "Apache-2.0"
|
||||||
|
|
||||||
|
[[bin]]
|
||||||
|
name = "ts_oracle"
|
||||||
|
path = "src/main.rs"
|
||||||
|
|
||||||
|
[dependencies]
|
||||||
|
marine-rs-sdk = { version = "0.6.14", features = ["logger"] }
|
||||||
|
log = "0.4.14"
|
||||||
|
# picorand = "0.1.1"
|
||||||
|
nanorand = { version = "0.6.1", default-features = false, features = [
|
||||||
|
"wyrand",
|
||||||
|
] }
|
||||||
|
|
||||||
|
[dev-dependencies]
|
||||||
|
marine-rs-sdk-test = "0.4.0"
|
||||||
|
|
||||||
|
[dev]
|
||||||
|
[profile.release]
|
||||||
|
opt-level = "s"
|
3
quickstart/5-oracle-service/Readme.md
Normal file
3
quickstart/5-oracle-service/Readme.md
Normal file
@ -0,0 +1,3 @@
|
|||||||
|
# 5. Decentralized Oracles With Fluence And Aqua
|
||||||
|
|
||||||
|
See the gitbook [documentation]( https://doc.fluence.dev/docs/quick-start/5.-decentralized-oracles-with-fluence-and-aqua) for the tutorial.
|
88
quickstart/5-oracle-service/aqua/ts_oracle.aqua
Normal file
88
quickstart/5-oracle-service/aqua/ts_oracle.aqua
Normal file
@ -0,0 +1,88 @@
|
|||||||
|
|
||||||
|
alias PeerId : string
|
||||||
|
alias Base58String : string
|
||||||
|
alias Hash : string
|
||||||
|
|
||||||
|
-- const N_KNEIGHBORS = 19
|
||||||
|
|
||||||
|
data Contact:
|
||||||
|
peer_id: string
|
||||||
|
addresses: []string
|
||||||
|
|
||||||
|
data Info:
|
||||||
|
external_addresses: []string
|
||||||
|
|
||||||
|
service Op("op"):
|
||||||
|
string_to_b58(s: string) -> Base58String
|
||||||
|
concat_strings(a: string, b: string) -> string
|
||||||
|
|
||||||
|
service MyOp("op"):
|
||||||
|
identity(u: u64)
|
||||||
|
identity_string(s:string)
|
||||||
|
|
||||||
|
service MyOpBool("op"):
|
||||||
|
identity(b: bool)
|
||||||
|
|
||||||
|
service Kademlia("kad"):
|
||||||
|
neighborhood(key: Base58String, already_hashed: ?bool, count: ?u32) -> []PeerId
|
||||||
|
merge(target: Base58String, left: []string, right: []string, count: ?u32) -> []string
|
||||||
|
|
||||||
|
service Peer("peer"):
|
||||||
|
is_connected(peer: PeerId) -> bool
|
||||||
|
connect(id: PeerId, multiaddrs: ?[]string) -> bool
|
||||||
|
get_contact(peer: PeerId) -> Contact
|
||||||
|
identify() -> Info
|
||||||
|
timestamp_ms() -> u64
|
||||||
|
timestamp_sec() -> u64
|
||||||
|
timeout(duration_ms: u64, message: string) -> string
|
||||||
|
|
||||||
|
data Consensus:
|
||||||
|
n: u32
|
||||||
|
consensus_ts: u64
|
||||||
|
consensus: bool
|
||||||
|
support: u32
|
||||||
|
err_str: string
|
||||||
|
|
||||||
|
data Oracle:
|
||||||
|
n: u32
|
||||||
|
avg: f64
|
||||||
|
err_str: string
|
||||||
|
|
||||||
|
service TSOracle("service-id"):
|
||||||
|
ts_frequency(timestamps: []u64, tolerance: u32, threshold: f64, err_value:u64) -> Consensus
|
||||||
|
|
||||||
|
func ts_oracle_with_consensus(tolerance: u32, threshold: f64, err_value:u64, node:string, oracle_service_id:string)-> Consensus, []string:
|
||||||
|
rtt = 1000 -- in ms
|
||||||
|
res: *u64
|
||||||
|
msg = "timeout"
|
||||||
|
dead_peers: *string
|
||||||
|
on node:
|
||||||
|
k <- Op.string_to_b58(node)
|
||||||
|
nodes <- Kademlia.neighborhood(k, nil, nil)
|
||||||
|
for n <- nodes par:
|
||||||
|
status: *string
|
||||||
|
on n:
|
||||||
|
res <- Peer.timestamp_ms()
|
||||||
|
status <<- "success"
|
||||||
|
par status <- Peer.timeout(rtt, msg)
|
||||||
|
if status! != "success":
|
||||||
|
res <<- err_value
|
||||||
|
dead_peers <<- n
|
||||||
|
|
||||||
|
MyOp.identity(res!19)
|
||||||
|
TSOracle oracle_service_id
|
||||||
|
consensus <- TSOracle.ts_frequency(res, tolerance, threshold, err_value)
|
||||||
|
<- consensus, dead_peers
|
||||||
|
|
||||||
|
func ts_oracle_with_bool(tolerance: u32, threshold: f64, err_value:u64, node:string, oracle_service_id:string)-> []bool, []string:
|
||||||
|
res: *bool
|
||||||
|
peers: *string
|
||||||
|
dead_peers: *string
|
||||||
|
on node:
|
||||||
|
k <- Op.string_to_b58(node)
|
||||||
|
nodes <- Kademlia.neighborhood(k, nil, nil)
|
||||||
|
for n <- nodes par:
|
||||||
|
res <- Peer.connect(n, nil)
|
||||||
|
peers <<- n
|
||||||
|
MyOpBool.identity(res!19)
|
||||||
|
<- res, peers
|
6
quickstart/5-oracle-service/configs/Config.toml
Normal file
6
quickstart/5-oracle-service/configs/Config.toml
Normal file
@ -0,0 +1,6 @@
|
|||||||
|
modules_dir = "artifacts/"
|
||||||
|
|
||||||
|
[[module]]
|
||||||
|
name = "ts_oracle"
|
||||||
|
mem_pages_count = 20
|
||||||
|
logger_enabled = true
|
5
quickstart/5-oracle-service/configs/ts_oracle_cfg.json
Normal file
5
quickstart/5-oracle-service/configs/ts_oracle_cfg.json
Normal file
@ -0,0 +1,5 @@
|
|||||||
|
{
|
||||||
|
"name": "ts_oracle",
|
||||||
|
"mem_pages_count": 5,
|
||||||
|
"logger_enabled": false
|
||||||
|
}
|
15
quickstart/5-oracle-service/deployed_service.data
Normal file
15
quickstart/5-oracle-service/deployed_service.data
Normal file
@ -0,0 +1,15 @@
|
|||||||
|
client seed: Ek6bAgs1ymxZhfnH98WNeQ8dEEUuRJ5B8aN7mfgvYSMt
|
||||||
|
client peerId: 12D3KooWLMsHa9CY5efWkBokbryrpUkE7onTFGK6oTvTuovVUtDp
|
||||||
|
relay peerId: 12D3KooWFEwNWcHqi9rtsmDhsYcDbRUCDXH84RC4FW6UfsFWaoHi
|
||||||
|
service id: ec347996-ebd6-4630-8e45-46c2dfcaa3f5
|
||||||
|
service created successfully
|
||||||
|
client seed: FXcSUpuwDPftAMVX5qWiAkuf3f6uSqf7zujw6uM2PzqE
|
||||||
|
client peerId: 12D3KooWSA6zFEWoVazQGR3nfRJCVfZbWuP9UgrTjZZaf62FbtCh
|
||||||
|
relay peerId: 12D3KooWFEwNWcHqi9rtsmDhsYcDbRUCDXH84RC4FW6UfsFWaoHi
|
||||||
|
service id: 754db64e-fe14-49ff-8e08-1a1f7082781f
|
||||||
|
service created successfully
|
||||||
|
client seed: 7UNmJPMWdLmrwAtGrpJXNrrcK7tEZHCjvKbGdSzEizEr
|
||||||
|
client peerId: 12D3KooWBeEsUnMV9MZ6QGMfaxcTvw8mGFEMGDe7rhKN8RQv1Gs8
|
||||||
|
relay peerId: 12D3KooWFEwNWcHqi9rtsmDhsYcDbRUCDXH84RC4FW6UfsFWaoHi
|
||||||
|
service id: 61a86f67-ffc2-4dea-8746-fd4f04d9c75b
|
||||||
|
service created successfully
|
6
quickstart/5-oracle-service/scripts/build.sh
Executable file
6
quickstart/5-oracle-service/scripts/build.sh
Executable file
@ -0,0 +1,6 @@
|
|||||||
|
#!/usr/bin/env bash -o errexit -o nounset -o pipefail
|
||||||
|
|
||||||
|
mkdir -p artifacts
|
||||||
|
rm -f artifacts/*.wasm
|
||||||
|
marine build --release
|
||||||
|
cp target/wasm32-wasi/release/ts_oracle.wasm artifacts/
|
9
quickstart/5-oracle-service/scripts/deploy.sh
Executable file
9
quickstart/5-oracle-service/scripts/deploy.sh
Executable file
@ -0,0 +1,9 @@
|
|||||||
|
#!/usr/bin/env bash -o errexit -o nounset -o pipefail
|
||||||
|
|
||||||
|
fldist --node-id 12D3KooWFEwNWcHqi9rtsmDhsYcDbRUCDXH84RC4FW6UfsFWaoHi \
|
||||||
|
new_service \
|
||||||
|
--ms artifacts/ts_oracle.wasm:configs/ts_oracle_cfg.json \
|
||||||
|
--name ts-oracle \
|
||||||
|
--verbose \
|
||||||
|
>> \
|
||||||
|
deployed_service.data
|
301
quickstart/5-oracle-service/src/main.rs
Normal file
301
quickstart/5-oracle-service/src/main.rs
Normal file
@ -0,0 +1,301 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2021 Fluence Labs Limited
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
use marine_rs_sdk::marine;
|
||||||
|
use marine_rs_sdk::module_manifest;
|
||||||
|
use marine_rs_sdk::WasmLoggerBuilder;
|
||||||
|
// use picorand::{PicoRandGenerate, WyRand, RNG};
|
||||||
|
use nanorand::{Rng, WyRand};
|
||||||
|
|
||||||
|
module_manifest!();
|
||||||
|
|
||||||
|
pub fn main() {
|
||||||
|
WasmLoggerBuilder::new().build().unwrap();
|
||||||
|
}
|
||||||
|
|
||||||
|
#[marine]
|
||||||
|
#[derive(Default, Debug)]
|
||||||
|
pub struct Oracle {
|
||||||
|
pub n: u32,
|
||||||
|
pub avg: f64,
|
||||||
|
pub err_str: String,
|
||||||
|
}
|
||||||
|
#[marine]
|
||||||
|
#[derive(Default, Debug)]
|
||||||
|
pub struct Consensus {
|
||||||
|
pub n: u32,
|
||||||
|
pub consensus_ts: u64,
|
||||||
|
pub consensus: bool,
|
||||||
|
pub support: u32,
|
||||||
|
pub err_str: String,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[marine]
|
||||||
|
pub fn ts_avg(timestamps: Vec<u64>, min_points: u32) -> Oracle {
|
||||||
|
if min_points as usize == 0 {
|
||||||
|
let err_str = "Need to process at least one point".to_string();
|
||||||
|
return Oracle {
|
||||||
|
err_str,
|
||||||
|
n: timestamps.len() as u32,
|
||||||
|
..<_>::default()
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
if timestamps.len() < min_points as usize {
|
||||||
|
return Oracle {
|
||||||
|
err_str: format!(
|
||||||
|
"Expected at least {} points but only got {}.",
|
||||||
|
min_points,
|
||||||
|
timestamps.len(),
|
||||||
|
),
|
||||||
|
n: timestamps.len() as u32,
|
||||||
|
..<_>::default()
|
||||||
|
};
|
||||||
|
}
|
||||||
|
let avg = timestamps.iter().sum::<u64>() as f64 / timestamps.len() as f64;
|
||||||
|
Oracle {
|
||||||
|
n: timestamps.len() as u32,
|
||||||
|
avg,
|
||||||
|
..<_>::default()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[marine]
|
||||||
|
fn ts_frequency(
|
||||||
|
mut timestamps: Vec<u64>,
|
||||||
|
tolerance: u32,
|
||||||
|
threshold: f64,
|
||||||
|
err_value: u64,
|
||||||
|
) -> Consensus {
|
||||||
|
timestamps.retain(|&ts| ts != err_value);
|
||||||
|
if timestamps.len() == 0 {
|
||||||
|
return Consensus {
|
||||||
|
err_str: "Array must have at least one element".to_string(),
|
||||||
|
..<_>::default()
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
if timestamps.len() == 1 {
|
||||||
|
return Consensus {
|
||||||
|
n: 1,
|
||||||
|
consensus_ts: timestamps[0],
|
||||||
|
consensus: true,
|
||||||
|
support: 1,
|
||||||
|
..<_>::default()
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
if threshold < 0f64 || threshold > 1f64 {
|
||||||
|
return Consensus {
|
||||||
|
err_str: "Threshold needs to be between [0.0,1.0]".to_string(),
|
||||||
|
..<_>::default()
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
let rnd_seed: u64 = timestamps.iter().sum();
|
||||||
|
let mut rng = WyRand::new_seed(rnd_seed);
|
||||||
|
let rnd_idx = rng.generate_range(0..timestamps.len());
|
||||||
|
let consensus_ts = timestamps.swap_remove(rnd_idx);
|
||||||
|
let mut support: u32 = 0;
|
||||||
|
for ts in timestamps.iter() {
|
||||||
|
if ts <= &(consensus_ts + tolerance as u64) && ts >= &(consensus_ts - tolerance as u64) {
|
||||||
|
support += 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
let mut consensus = false;
|
||||||
|
if (support as f64 / timestamps.len() as f64) >= threshold {
|
||||||
|
consensus = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
Consensus {
|
||||||
|
n: timestamps.len() as u32,
|
||||||
|
consensus_ts,
|
||||||
|
consensus,
|
||||||
|
support,
|
||||||
|
err_str: "".to_string(),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[cfg(test)]
|
||||||
|
mod tests {
|
||||||
|
use marine_rs_sdk_test::marine_test;
|
||||||
|
|
||||||
|
#[marine_test(config_path = "../configs/Config.toml", modules_dir = "../artifacts")]
|
||||||
|
fn test_mean_good(ts_consensus: marine_test_env::ts_oracle::ModuleInterface) {
|
||||||
|
let data = vec![1u64, 2u64, 3u64];
|
||||||
|
let n = 3;
|
||||||
|
let res = ts_consensus.ts_avg(data, n);
|
||||||
|
assert_eq!(res.avg, 2f64);
|
||||||
|
assert_eq!(res.err_str.len(), 0)
|
||||||
|
}
|
||||||
|
|
||||||
|
#[marine_test(config_path = "../configs/Config.toml", modules_dir = "../artifacts")]
|
||||||
|
fn test_mean_fail(ts_consensus: marine_test_env::ts_oracle::ModuleInterface) {
|
||||||
|
let data = vec![1u64, 2u64, 3u64];
|
||||||
|
let n = 0;
|
||||||
|
let res = ts_consensus.ts_avg(data, n);
|
||||||
|
assert_eq!(
|
||||||
|
res.err_str,
|
||||||
|
"Need to process at least one point".to_string()
|
||||||
|
);
|
||||||
|
|
||||||
|
let data = vec![1u64];
|
||||||
|
let n = 3;
|
||||||
|
let res = ts_consensus.ts_avg(data, n);
|
||||||
|
assert!(res.err_str.contains("Expected at least"));
|
||||||
|
}
|
||||||
|
|
||||||
|
#[marine_test(config_path = "../configs/Config.toml", modules_dir = "../artifacts")]
|
||||||
|
fn test_err_val(ts_consensus: marine_test_env::ts_oracle::ModuleInterface) {
|
||||||
|
let data = vec![0, 1, 1, 1];
|
||||||
|
let tolerance = 3u32;
|
||||||
|
let threshold: f64 = 0.66;
|
||||||
|
let err_val: u64 = 0;
|
||||||
|
let res = ts_consensus.ts_frequency(data.clone(), tolerance, threshold, err_val);
|
||||||
|
assert_eq!(res.consensus_ts, 1);
|
||||||
|
assert_eq!(res.n, data.len() as u32 - 2);
|
||||||
|
assert_eq!(res.err_str.len(), 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
#[marine_test(config_path = "../configs/Config.toml", modules_dir = "../artifacts")]
|
||||||
|
fn ts_validation_good_consensus(ts_consensus: marine_test_env::ts_oracle::ModuleInterface) {
|
||||||
|
let data = vec![
|
||||||
|
1636961969u64,
|
||||||
|
1636961970u64,
|
||||||
|
1636961969u64,
|
||||||
|
1636961968u64,
|
||||||
|
1636961969u64,
|
||||||
|
1636961971u64,
|
||||||
|
];
|
||||||
|
let tolerance = 3u32;
|
||||||
|
let threshold: f64 = 0.66;
|
||||||
|
let err_val: u64 = 0;
|
||||||
|
let res = ts_consensus.ts_frequency(data.clone(), tolerance, threshold, err_val);
|
||||||
|
assert_eq!(res.n, (data.len() - 1) as u32);
|
||||||
|
assert_eq!(res.support, (data.len() - 1) as u32);
|
||||||
|
assert_eq!(res.err_str.len(), 0);
|
||||||
|
assert!(res.consensus);
|
||||||
|
assert!(data.contains(&res.consensus_ts));
|
||||||
|
}
|
||||||
|
#[marine_test(config_path = "../configs/Config.toml", modules_dir = "../artifacts")]
|
||||||
|
fn ts_validation_good_no_support(ts_consensus: marine_test_env::ts_oracle::ModuleInterface) {
|
||||||
|
let data = vec![
|
||||||
|
1636961969u64,
|
||||||
|
1636961970u64,
|
||||||
|
1636961969u64,
|
||||||
|
1636961968u64,
|
||||||
|
1636961969u64,
|
||||||
|
1636961971u64,
|
||||||
|
];
|
||||||
|
let tolerance = 0u32;
|
||||||
|
let threshold: f64 = 0.66;
|
||||||
|
let err_val: u64 = 0;
|
||||||
|
let res = ts_consensus.ts_frequency(data.clone(), tolerance, threshold, err_val);
|
||||||
|
assert_eq!(res.n, (data.len() - 1) as u32);
|
||||||
|
assert_eq!(res.support, 0u32);
|
||||||
|
assert_eq!(res.err_str.len(), 0);
|
||||||
|
assert!(data.contains(&res.consensus_ts));
|
||||||
|
}
|
||||||
|
|
||||||
|
#[marine_test(config_path = "../configs/Config.toml", modules_dir = "../artifacts")]
|
||||||
|
fn ts_validation_good_consensus_true(
|
||||||
|
ts_consensus: marine_test_env::ts_oracle::ModuleInterface,
|
||||||
|
) {
|
||||||
|
let data = vec![
|
||||||
|
1636961969u64,
|
||||||
|
1636961970u64,
|
||||||
|
1636961969u64,
|
||||||
|
1636961968u64,
|
||||||
|
1636961969u64,
|
||||||
|
1636961969u64,
|
||||||
|
1636961971u64,
|
||||||
|
];
|
||||||
|
let tolerance = 3u32;
|
||||||
|
let threshold: f64 = 0.66;
|
||||||
|
let err_val: u64 = 0;
|
||||||
|
let res = ts_consensus.ts_frequency(data.clone(), tolerance, threshold, err_val);
|
||||||
|
assert_eq!(res.n, (data.len() - 1) as u32);
|
||||||
|
assert_eq!(res.support, (data.len() - 1) as u32);
|
||||||
|
assert_eq!(res.err_str.len(), 0);
|
||||||
|
assert!(data.contains(&res.consensus_ts));
|
||||||
|
}
|
||||||
|
|
||||||
|
#[marine_test(config_path = "../configs/Config.toml", modules_dir = "../artifacts")]
|
||||||
|
fn ts_validation_good_consensus_false(
|
||||||
|
ts_consensus: marine_test_env::ts_oracle::ModuleInterface,
|
||||||
|
) {
|
||||||
|
let data = vec![
|
||||||
|
1636961969u64,
|
||||||
|
1636961970u64,
|
||||||
|
1636961969u64,
|
||||||
|
1636961968u64,
|
||||||
|
1636961969u64,
|
||||||
|
1636961971u64,
|
||||||
|
];
|
||||||
|
let tolerance = 0u32;
|
||||||
|
let threshold: f64 = 0.66;
|
||||||
|
let err_val: u64 = 0;
|
||||||
|
let res = ts_consensus.ts_frequency(data.clone(), tolerance, threshold, err_val);
|
||||||
|
assert_eq!(res.n, (data.len() - 1) as u32);
|
||||||
|
assert_eq!(res.support, 0u32);
|
||||||
|
assert_eq!(res.err_str.len(), 0);
|
||||||
|
assert!(!res.consensus);
|
||||||
|
assert!(data.contains(&res.consensus_ts));
|
||||||
|
}
|
||||||
|
|
||||||
|
#[marine_test(config_path = "../configs/Config.toml", modules_dir = "../artifacts")]
|
||||||
|
fn ts_validation_good_no_consensus(ts_consensus: marine_test_env::ts_oracle::ModuleInterface) {
|
||||||
|
let data = vec![1636961965u64, 1636961969u64, 1636961972u64];
|
||||||
|
let tolerance = 1u32;
|
||||||
|
let threshold: f64 = 0.66;
|
||||||
|
let err_val: u64 = 0;
|
||||||
|
let res = ts_consensus.ts_frequency(data.clone(), tolerance, threshold, err_val);
|
||||||
|
assert_eq!(res.n, (data.len() - 1) as u32);
|
||||||
|
assert_eq!(res.support, 0 as u32);
|
||||||
|
assert_eq!(res.err_str.len(), 0);
|
||||||
|
assert!(data.contains(&res.consensus_ts));
|
||||||
|
}
|
||||||
|
|
||||||
|
#[marine_test(config_path = "../configs/Config.toml", modules_dir = "../artifacts")]
|
||||||
|
fn ts_validation_good_one(ts_consensus: marine_test_env::ts_oracle::ModuleInterface) {
|
||||||
|
let data = vec![1636961969u64];
|
||||||
|
let tolerance = 3u32;
|
||||||
|
let threshold: f64 = 0.66;
|
||||||
|
let err_val: u64 = 0;
|
||||||
|
let res = ts_consensus.ts_frequency(data.clone(), tolerance, threshold, err_val);
|
||||||
|
assert_eq!(res.consensus_ts, data[0]);
|
||||||
|
assert_eq!(res.support, data.len() as u32);
|
||||||
|
assert_eq!(res.n, data.len() as u32);
|
||||||
|
assert_eq!(res.err_str.len(), 0usize);
|
||||||
|
}
|
||||||
|
|
||||||
|
#[marine_test(config_path = "../configs/Config.toml", modules_dir = "../artifacts")]
|
||||||
|
fn ts_validation_bad_empty(ts_consensus: marine_test_env::ts_oracle::ModuleInterface) {
|
||||||
|
let data = vec![];
|
||||||
|
let tolerance = 3u32;
|
||||||
|
let threshold: f64 = 0.66;
|
||||||
|
let err_val: u64 = 0;
|
||||||
|
let res = ts_consensus.ts_frequency(data, tolerance, threshold, err_val);
|
||||||
|
assert_eq!(res.n, 0);
|
||||||
|
assert_eq!(res.support, 0);
|
||||||
|
assert_eq!(res.consensus_ts, 0);
|
||||||
|
assert_eq!(
|
||||||
|
res.err_str,
|
||||||
|
"Array must have at least one element".to_string()
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
Loading…
x
Reference in New Issue
Block a user