From 8214b1cc5c3275178a47f6ed46d6bf4d4adce845 Mon Sep 17 00:00:00 2001
From: Aleksey Proshutisnkiy <justprosh@users.noreply.github.com>
Date: Mon, 13 Dec 2021 19:40:16 +0300
Subject: [PATCH] Fix revocations logic (#34)

---
 Cargo.lock                  | 130 +++++++++++------------
 Cargo.toml                  |   1 +
 aqua/package.json           |   2 +-
 aqua/trust-graph-api.aqua   |   4 +-
 aqua/trust-graph.aqua       |   6 +-
 example/index.ts            |   2 +-
 keypair/src/rsa.rs          |   4 +-
 keypair/src/signature.rs    |   2 +-
 service/Cargo.toml          |   2 +-
 service/src/dto.rs          |  14 +--
 service/src/results.rs      |  14 +--
 service/src/service_api.rs  |   8 +-
 service/src/storage_impl.rs |  84 +++++++++++----
 service/src/tests.rs        |  87 ++++++++++++---
 src/chain.rs                |  47 ++++++++
 src/lib.rs                  |   3 +-
 src/revoke.rs               |  22 ++--
 src/trust_graph.rs          |  41 +++----
 src/trust_graph_storage.rs  |   8 +-
 src/trust_node.rs           | 206 ------------------------------------
 src/trust_relation.rs       |  15 +--
 21 files changed, 320 insertions(+), 382 deletions(-)
 create mode 100644 src/chain.rs
 delete mode 100644 src/trust_node.rs

diff --git a/Cargo.lock b/Cargo.lock
index dd15940..040dabd 100644
--- a/Cargo.lock
+++ b/Cargo.lock
@@ -39,9 +39,9 @@ dependencies = [
 
 [[package]]
 name = "anyhow"
-version = "1.0.45"
+version = "1.0.51"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "ee10e43ae4a853c0a3591d4e2ada1719e553be18199d9da9d4a83f5927c2f5c7"
+checksum = "8b26702f315f53b6071259e15dd9d64528213b44d61de1ec926eca7715d62203"
 
 [[package]]
 name = "arrayref"
@@ -529,9 +529,9 @@ dependencies = [
 
 [[package]]
 name = "ed25519"
-version = "1.2.0"
+version = "1.3.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "4620d40f6d2601794401d6dd95a5cf69b6c157852539470eeda433a99b3c0efc"
+checksum = "74e1069e39f1454367eb2de793ed062fac4c35c2934b76a81d90dd9abcd28816"
 dependencies = [
  "serde",
  "signature",
@@ -656,9 +656,9 @@ checksum = "37ab347416e802de484e4d03c7316c48f1ecb56574dfd4a46a80f173ce1de04d"
 
 [[package]]
 name = "fluence-app-service"
-version = "0.9.0"
+version = "0.10.2"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "58d92fd37b7673513efafb0d1e0c366b8d6f297b74e9bfcda27c452f400af70a"
+checksum = "01c66660de99826038c5ec4ad0f5dccf10b1c8a15924aeaa5315ab49d718bfc9"
 dependencies = [
  "fluence-faas",
  "log",
@@ -819,9 +819,9 @@ dependencies = [
 
 [[package]]
 name = "futures"
-version = "0.3.17"
+version = "0.3.18"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "a12aa0eb539080d55c3f2d45a67c3b58b6b0773c1a3ca2dfec66d58c97fd66ca"
+checksum = "8cd0210d8c325c245ff06fd95a3b13689a1a276ac8cfa8e8720cb840bfb84b9e"
 dependencies = [
  "futures-channel",
  "futures-core",
@@ -834,9 +834,9 @@ dependencies = [
 
 [[package]]
 name = "futures-channel"
-version = "0.3.17"
+version = "0.3.18"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "5da6ba8c3bb3c165d3c7319fc1cc8304facf1fb8db99c5de877183c08a273888"
+checksum = "7fc8cd39e3dbf865f7340dce6a2d401d24fd37c6fe6c4f0ee0de8bfca2252d27"
 dependencies = [
  "futures-core",
  "futures-sink",
@@ -844,15 +844,15 @@ dependencies = [
 
 [[package]]
 name = "futures-core"
-version = "0.3.17"
+version = "0.3.18"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "88d1c26957f23603395cd326b0ffe64124b818f4449552f960d815cfba83a53d"
+checksum = "629316e42fe7c2a0b9a65b47d159ceaa5453ab14e8f0a3c5eedbb8cd55b4a445"
 
 [[package]]
 name = "futures-executor"
-version = "0.3.17"
+version = "0.3.18"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "45025be030969d763025784f7f355043dc6bc74093e4ecc5000ca4dc50d8745c"
+checksum = "7b808bf53348a36cab739d7e04755909b9fcaaa69b7d7e588b37b6ec62704c97"
 dependencies = [
  "futures-core",
  "futures-task",
@@ -862,18 +862,16 @@ dependencies = [
 
 [[package]]
 name = "futures-io"
-version = "0.3.17"
+version = "0.3.18"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "522de2a0fe3e380f1bc577ba0474108faf3f6b18321dbf60b3b9c39a75073377"
+checksum = "e481354db6b5c353246ccf6a728b0c5511d752c08da7260546fc0933869daa11"
 
 [[package]]
 name = "futures-macro"
-version = "0.3.17"
+version = "0.3.18"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "18e4a4b95cea4b4ccbcf1c5675ca7c4ee4e9e75eb79944d07defde18068f79bb"
+checksum = "a89f17b21645bc4ed773c69af9c9a0effd4a3f1a3876eadd453469f8854e7fdd"
 dependencies = [
- "autocfg",
- "proc-macro-hack",
  "proc-macro2",
  "quote",
  "syn",
@@ -881,15 +879,15 @@ dependencies = [
 
 [[package]]
 name = "futures-sink"
-version = "0.3.17"
+version = "0.3.18"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "36ea153c13024fe480590b3e3d4cad89a0cfacecc24577b68f86c6ced9c2bc11"
+checksum = "996c6442437b62d21a32cd9906f9c41e7dc1e19a9579843fad948696769305af"
 
 [[package]]
 name = "futures-task"
-version = "0.3.17"
+version = "0.3.18"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "1d3d00f4eddb73e498a54394f228cd55853bdf059259e8e7bc6e69d408892e99"
+checksum = "dabf1872aaab32c886832f2276d2f5399887e2bd613698a02359e4ea83f8de12"
 
 [[package]]
 name = "futures-timer"
@@ -899,11 +897,10 @@ checksum = "e64b03909df88034c26dc1547e8970b91f98bdb65165d6a4e9110d94263dbb2c"
 
 [[package]]
 name = "futures-util"
-version = "0.3.17"
+version = "0.3.18"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "36568465210a3a6ee45e1f165136d68671471a501e632e9a98d96872222b5481"
+checksum = "41d22213122356472061ac0f1ab2cee28d2bac8491410fd68c2af53d1cedb83e"
 dependencies = [
- "autocfg",
  "futures-channel",
  "futures-core",
  "futures-io",
@@ -913,8 +910,6 @@ dependencies = [
  "memchr",
  "pin-project-lite",
  "pin-utils",
- "proc-macro-hack",
- "proc-macro-nested",
  "slab",
 ]
 
@@ -1147,9 +1142,9 @@ dependencies = [
 
 [[package]]
 name = "itertools"
-version = "0.10.1"
+version = "0.10.3"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "69ddb889f9d0d08a67338271fa9b62996bc788c7796a5c18cf057420aaed5eaf"
+checksum = "a9a9d19fa1e79b6215ff29b9d6880b706147f16e9b1dbb1e4e5947b5b02bc5e3"
 dependencies = [
  "either",
 ]
@@ -1196,9 +1191,9 @@ dependencies = [
 
 [[package]]
 name = "libc"
-version = "0.2.107"
+version = "0.2.109"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "fbe5e23404da5b4f555ef85ebed98fb4083e55a00c317800bc2a50ede9f3d219"
+checksum = "f98a04dce437184842841303488f70d0188c5f51437d2a834dc097eafa909a01"
 
 [[package]]
 name = "libsecp256k1"
@@ -1261,9 +1256,9 @@ checksum = "3e2e65a1a2e43cfcb47a895c4c8b10d1f4a61097f9f254f183aee60cad9c651d"
 
 [[package]]
 name = "marine-build-rs-generator"
-version = "0.4.0"
+version = "0.4.1"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "c81d725ea49f554e23d3a0eb9464fcdad0bc190e42bb5a5a27699fb56557177c"
+checksum = "0108407ef0528984cd5b226e6d69552b1658b205f60c83305ca33179d6e9eee1"
 dependencies = [
  "marine-test-macro-impl",
 ]
@@ -1303,7 +1298,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "edd97bd85072fc540763769be153a7c8ee83391e668b37ef96d6c48decec2cd5"
 dependencies = [
  "anyhow",
- "itertools 0.10.1",
+ "itertools 0.10.3",
  "marine-it-interfaces",
  "marine-module-interface",
  "nom",
@@ -1362,7 +1357,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "06bc36ef268bf7436916f1fa9b0c84104692a717ea5eef3c90b9f25c3407f6b7"
 dependencies = [
  "anyhow",
- "itertools 0.10.1",
+ "itertools 0.10.3",
  "marine-it-interfaces",
  "nom",
  "semver 0.11.0",
@@ -1398,9 +1393,9 @@ dependencies = [
 
 [[package]]
 name = "marine-rs-sdk-test"
-version = "0.4.0"
+version = "0.4.1"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "fe77591c893dcfda3acd02b89ad42102a6739ead8200717e4cf325c52ba7001e"
+checksum = "03e286a347527936cf97456b928bd6271e0d39fc1c6b78e99461f00e6d74f018"
 dependencies = [
  "fluence-app-service",
  "marine-build-rs-generator",
@@ -1451,9 +1446,9 @@ dependencies = [
 
 [[package]]
 name = "marine-test-macro"
-version = "0.4.0"
+version = "0.4.1"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "b6c73a012946439eb619375cc825f008ac74489092f826fe596e465d355542cf"
+checksum = "bf4d0463358f6c2459089ef8f130983dc911fd0c2aa4cb7c6b59de206f4a816e"
 dependencies = [
  "marine-test-macro-impl",
  "proc-macro-error",
@@ -1464,13 +1459,13 @@ dependencies = [
 
 [[package]]
 name = "marine-test-macro-impl"
-version = "0.4.0"
+version = "0.4.1"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "fa833b78d05abb43ca46c2c85cce1e664bde4b8b1926ae2bd420aba426a9b22a"
+checksum = "b8f4f1ae0ba20e9241e8882e6eb1b2302daa479d67eee5badb54b1520e17c0cb"
 dependencies = [
  "darling 0.12.4",
  "fluence-app-service",
- "itertools 0.10.1",
+ "itertools 0.10.3",
  "marine-it-parser",
  "proc-macro-error",
  "proc-macro2",
@@ -1520,9 +1515,9 @@ dependencies = [
 
 [[package]]
 name = "memoffset"
-version = "0.6.4"
+version = "0.6.5"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "59accc507f1338036a0477ef61afdae33cde60840f4dfe481319ce3ad116ddf9"
+checksum = "5aa361d4faea93603064a027415f07bd8e1d5c88c9fbf68bf56a285428fd79ce"
 dependencies = [
  "autocfg",
 ]
@@ -1597,6 +1592,12 @@ dependencies = [
  "version_check",
 ]
 
+[[package]]
+name = "nonempty"
+version = "0.7.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "e9e591e719385e6ebaeb5ce5d3887f7d5676fceca6411d1925ccc95745f3d6f7"
+
 [[package]]
 name = "num-integer"
 version = "0.1.44"
@@ -1803,9 +1804,9 @@ checksum = "8b870d8c151b6f2fb93e84a13146138f05d02ed11c7e7c54f8826aaaf7c9f184"
 
 [[package]]
 name = "pkg-config"
-version = "0.3.22"
+version = "0.3.23"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "12295df4f294471248581bc09bef3c38a5e46f1e36d6a37353621a0c6c357e1f"
+checksum = "d1a3ea4f0dd7f1f3e512cf97bf100819aa547f36a6eccac8dbaae839eb92363e"
 
 [[package]]
 name = "polyplets"
@@ -1858,23 +1859,11 @@ dependencies = [
  "version_check",
 ]
 
-[[package]]
-name = "proc-macro-hack"
-version = "0.5.19"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "dbf0c48bc1d91375ae5c3cd81e3722dff1abcf81a30960240640d223f59fe0e5"
-
-[[package]]
-name = "proc-macro-nested"
-version = "0.1.7"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "bc881b2c22681370c6a780e47af9840ef841837bc98118431d4e1868bd0c1086"
-
 [[package]]
 name = "proc-macro2"
-version = "1.0.32"
+version = "1.0.33"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "ba508cc11742c0dc5c1659771673afbab7a0efab23aa17e854cbab0837ed0b43"
+checksum = "fb37d2df5df740e582f28f8560cf425f52bb267d872fe58358eadb554909f07a"
 dependencies = [
  "unicode-xid",
 ]
@@ -2219,9 +2208,9 @@ dependencies = [
 
 [[package]]
 name = "ryu"
-version = "1.0.5"
+version = "1.0.6"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "71d301d4193d031abdd79ff7e3dd721168a9572ef3fe51a1517aba235bd8f86e"
+checksum = "3c9613b5a66ab9ba26415184cfc41156594925a9cf3a2057e57f31ff145f6568"
 
 [[package]]
 name = "safe-transmute"
@@ -2319,9 +2308,9 @@ dependencies = [
 
 [[package]]
 name = "serde_json"
-version = "1.0.69"
+version = "1.0.72"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "e466864e431129c7e0d3476b92f20458e5879919a0596c6472738d9fa2d342f8"
+checksum = "d0ffa0837f2dfa6fb90868c2b5468cad482e175f7dad97e7421951e663f2b527"
 dependencies = [
  "itoa",
  "ryu",
@@ -2425,9 +2414,9 @@ checksum = "6bdef32e8150c2a081110b42772ffe7d7c9032b606bc226c8260fd97e0976601"
 
 [[package]]
 name = "syn"
-version = "1.0.81"
+version = "1.0.82"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "f2afee18b8beb5a596ecb4a2dce128c719b4ba399d34126b9e4396e3f9860966"
+checksum = "8daf5dd0bb60cbd4137b1b587d2fc0ae729bc07cf01cd70b36a1ed5ade3b9d59"
 dependencies = [
  "proc-macro2",
  "quote",
@@ -2531,6 +2520,7 @@ dependencies = [
  "fluence-fork-libp2p-core",
  "fluence-keypair",
  "log",
+ "nonempty",
  "rand 0.7.3",
  "ref-cast",
  "serde",
@@ -2543,7 +2533,7 @@ dependencies = [
 
 [[package]]
 name = "trust-graph-wasm"
-version = "0.2.1"
+version = "0.3.0"
 dependencies = [
  "anyhow",
  "bincode",
@@ -2848,7 +2838,7 @@ dependencies = [
  "fluence-it-types",
  "it-lilo",
  "it-to-bytes",
- "itertools 0.10.1",
+ "itertools 0.10.3",
  "log",
  "nom",
  "safe-transmute",
diff --git a/Cargo.toml b/Cargo.toml
index 8e3f099..11f8c91 100644
--- a/Cargo.toml
+++ b/Cargo.toml
@@ -23,6 +23,7 @@ serde_with = "1.6.0"
 thiserror = "1.0.23"
 sha2 = "0.9.5"
 rand = "0.7.0"
+nonempty = "0.7.0"
 
 [workspace]
 members = [
diff --git a/aqua/package.json b/aqua/package.json
index 4cbb4f6..6a21c1a 100644
--- a/aqua/package.json
+++ b/aqua/package.json
@@ -1,6 +1,6 @@
 {
   "name": "@fluencelabs/trust-graph",
-  "version": "0.1.12",
+  "version": "0.2.0",
   "description": "Aqua Trust Graph API library",
   "files": [
     "*.aqua"
diff --git a/aqua/trust-graph-api.aqua b/aqua/trust-graph-api.aqua
index e33d449..65bfbcd 100644
--- a/aqua/trust-graph-api.aqua
+++ b/aqua/trust-graph-api.aqua
@@ -67,10 +67,10 @@ func issue_revocation(node: string, revoked_peer_id: string, revoked_by_peer_id:
         result <- TrustGraph.issue_revocation(revoked_peer_id, revoked_by_peer_id, revoked_at_sec, signature_bytes)
     <- result
 
-func revoke(node: string, revoke: Revoke) -> RevokeResult:
+func revoke(node: string, revocation: Revocation) -> RevokeResult:
     on node:
         timestamp_sec <- Peer.timestamp_sec()
-        result <- TrustGraph.revoke(revoke, timestamp_sec)
+        result <- TrustGraph.revoke(revocation, timestamp_sec)
     <- result
 
 service TrustOp("op"):
diff --git a/aqua/trust-graph.aqua b/aqua/trust-graph.aqua
index 7516815..5bed864 100644
--- a/aqua/trust-graph.aqua
+++ b/aqua/trust-graph.aqua
@@ -38,7 +38,7 @@ data InsertResult:
   success: bool
   error: string
 
-data Revoke:
+data Revocation:
   revoked_peer_id: string
   revoked_at: u64
   signature: string
@@ -48,7 +48,7 @@ data Revoke:
 data IssueRevocationResult:
   success: bool
   error: string
-  revoke: Revoke
+  revocation: Revocation
 
 data IssueTrustResult:
   success: bool
@@ -83,5 +83,5 @@ service TrustGraph("trust-graph"):
   insert_cert_raw(certificate: string, timestamp_sec: u64) -> InsertResult
   issue_revocation(revoked_peer_id: string, revoked_by_peer_id: string, revoked_at_sec: u64, signature_bytes: []u8) -> IssueRevocationResult
   issue_trust(issued_for_peer_id: string, expires_at_sec: u64, issued_at_sec: u64, trust_bytes: []u8) -> IssueTrustResult
-  revoke(revoke: Revoke, timestamp_sec: u64) -> RevokeResult
+  revoke(revoke: Revocation, timestamp_sec: u64) -> RevokeResult
   verify_trust(trust: Trust, issuer_peer_id: string, timestamp_sec: u64) -> VerifyTrustResult
diff --git a/example/index.ts b/example/index.ts
index 1954eb4..76c769b 100644
--- a/example/index.ts
+++ b/example/index.ts
@@ -65,7 +65,7 @@ async function revoke_helper(node: string, issuer_kp: KeyPair, revoked_by_peer_i
     let revocation = await tg.issue_revocation(node, revoked_peer_id, revoked_by_peer_id, revoked_at_sec, Array.from(signed_metadata));
     assert(revocation.success)
 
-    let result_add = await tg.revoke(node, revocation.revoke);
+    let result_add = await tg.revoke(node, revocation.revocation);
     assert(result_add.success)
 }
 
diff --git a/keypair/src/rsa.rs b/keypair/src/rsa.rs
index 1f816bf..86f9e78 100644
--- a/keypair/src/rsa.rs
+++ b/keypair/src/rsa.rs
@@ -43,7 +43,7 @@ impl Keypair {
     ///
     /// [RFC5208]: https://tools.ietf.org/html/rfc5208#section-5
     pub fn from_pkcs8(der: &mut [u8]) -> Result<Self, DecodingError> {
-        let kp = RsaKeyPair::from_pkcs8(&der).map_err(|_| DecodingError::Rsa)?;
+        let kp = RsaKeyPair::from_pkcs8(der).map_err(|_| DecodingError::Rsa)?;
         der.zeroize();
         Ok(Keypair(Arc::new(kp)))
     }
@@ -57,7 +57,7 @@ impl Keypair {
     pub fn sign(&self, data: &[u8]) -> Result<Vec<u8>, SigningError> {
         let mut signature = vec![0; self.0.public_modulus_len()];
         let rng = SystemRandom::new();
-        match self.0.sign(&RSA_PKCS1_SHA256, &rng, &data, &mut signature) {
+        match self.0.sign(&RSA_PKCS1_SHA256, &rng, data, &mut signature) {
             Ok(()) => Ok(signature),
             Err(_) => Err(SigningError::Rsa),
         }
diff --git a/keypair/src/signature.rs b/keypair/src/signature.rs
index f794c8b..fc89472 100644
--- a/keypair/src/signature.rs
+++ b/keypair/src/signature.rs
@@ -98,7 +98,7 @@ impl Signature {
 
     pub fn get_raw_signature(&self) -> RawSignature {
         RawSignature {
-            bytes: self.to_vec().clone().to_vec(),
+            bytes: self.to_vec().to_vec(),
             sig_type: self.get_signature_type(),
         }
     }
diff --git a/service/Cargo.toml b/service/Cargo.toml
index 05292fd..b9d5835 100644
--- a/service/Cargo.toml
+++ b/service/Cargo.toml
@@ -1,6 +1,6 @@
 [package]
 name = "trust-graph-wasm"
-version = "0.2.1"
+version = "0.3.0"
 authors = ["Fluence Labs"]
 edition = "2018"
 description = "trust graph wasm"
diff --git a/service/src/dto.rs b/service/src/dto.rs
index f51c7cf..df48e3c 100644
--- a/service/src/dto.rs
+++ b/service/src/dto.rs
@@ -113,7 +113,7 @@ impl From<trust_graph::Trust> for Trust {
 
 #[marine]
 #[derive(Default)]
-pub struct Revoke {
+pub struct Revocation {
     /// who is revoked
     pub revoked_peer_id: String,
     /// date when revocation was created
@@ -126,10 +126,10 @@ pub struct Revoke {
     pub revoked_by: String,
 }
 
-impl TryFrom<Revoke> for trust_graph::Revoke {
+impl TryFrom<Revocation> for trust_graph::Revocation {
     type Error = DtoConversionError;
 
-    fn try_from(r: Revoke) -> Result<Self, Self::Error> {
+    fn try_from(r: Revocation) -> Result<Self, Self::Error> {
         let revoked_pk = PublicKey::try_from(
             PeerId::from_str(&r.revoked_peer_id)
                 .map_err(|e| PeerIdDecodeError(format!("{:?}", e)))?,
@@ -142,7 +142,7 @@ impl TryFrom<Revoke> for trust_graph::Revoke {
         let signature = bs58::decode(&r.signature).into_vec()?;
         let signature = Signature::from_bytes(KeyFormat::from_str(&r.sig_type)?, signature);
         let revoked_at = Duration::from_secs(r.revoked_at);
-        return Ok(trust_graph::Revoke {
+        return Ok(trust_graph::Revocation {
             pk: revoked_pk,
             revoked_at,
             revoked_by: revoked_by_pk,
@@ -151,14 +151,14 @@ impl TryFrom<Revoke> for trust_graph::Revoke {
     }
 }
 
-impl From<trust_graph::Revoke> for Revoke {
-    fn from(r: trust_graph::Revoke) -> Self {
+impl From<trust_graph::Revocation> for Revocation {
+    fn from(r: trust_graph::Revocation) -> Self {
         let revoked_by = r.revoked_by.to_peer_id().to_base58();
         let revoked_peer_id = r.pk.to_peer_id().to_base58();
         let raw_signature = r.signature.get_raw_signature();
         let signature = bs58::encode(raw_signature.bytes).into_string();
         let revoked_at = r.revoked_at.as_secs();
-        return Revoke {
+        return Revocation {
             revoked_peer_id,
             revoked_at,
             signature,
diff --git a/service/src/results.rs b/service/src/results.rs
index 578ed70..f5eaa9c 100644
--- a/service/src/results.rs
+++ b/service/src/results.rs
@@ -1,4 +1,4 @@
-use crate::dto::{Certificate, Revoke, Trust};
+use crate::dto::{Certificate, Revocation, Trust};
 use crate::error::ServiceError;
 use marine_rs_sdk::marine;
 
@@ -216,21 +216,21 @@ impl From<Result<Vec<u8>, ServiceError>> for GetRevokeBytesResult {
 pub struct IssueRevocationResult {
     pub success: bool,
     pub error: String,
-    pub revoke: Revoke,
+    pub revocation: Revocation,
 }
 
-impl From<Result<Revoke, ServiceError>> for IssueRevocationResult {
-    fn from(result: Result<Revoke, ServiceError>) -> Self {
+impl From<Result<Revocation, ServiceError>> for IssueRevocationResult {
+    fn from(result: Result<Revocation, ServiceError>) -> Self {
         match result {
-            Ok(revoke) => IssueRevocationResult {
+            Ok(revocation) => IssueRevocationResult {
                 success: true,
                 error: "".to_string(),
-                revoke,
+                revocation,
             },
             Err(e) => IssueRevocationResult {
                 success: false,
                 error: format!("{}", e),
-                revoke: Revoke::default(),
+                revocation: Revocation::default(),
             },
         }
     }
diff --git a/service/src/service_api.rs b/service/src/service_api.rs
index 20cb631..6408d80 100644
--- a/service/src/service_api.rs
+++ b/service/src/service_api.rs
@@ -1,4 +1,4 @@
-use crate::dto::{Certificate, Revoke, Trust};
+use crate::dto::{Certificate, Revocation, Trust};
 use crate::error::ServiceError;
 use crate::misc::{check_timestamp_tetraplets, extract_public_key, with_tg, wrapped_try};
 use crate::results::{
@@ -201,7 +201,7 @@ fn add_trust(trust: Trust, issuer_peer_id: String, timestamp_sec: u64) -> AddTru
 fn get_revoke_bytes(revoked_peer_id: String, revoked_at: u64) -> GetRevokeBytesResult {
     wrapped_try(|| {
         let public_key = extract_public_key(revoked_peer_id)?;
-        Ok(trust_graph::Revoke::signature_bytes(
+        Ok(trust_graph::Revocation::signature_bytes(
             &public_key,
             Duration::from_secs(revoked_at),
         ))
@@ -222,13 +222,13 @@ fn issue_revocation(
 
         let revoked_at = Duration::from_secs(revoked_at_sec);
         let signature = Signature::from_bytes(revoked_by_pk.get_key_format(), signature_bytes);
-        Ok(trust_graph::Revoke::new(revoked_pk, revoked_by_pk, revoked_at, signature).into())
+        Ok(trust_graph::Revocation::new(revoked_pk, revoked_by_pk, revoked_at, signature).into())
     })
     .into()
 }
 
 #[marine]
-fn revoke(revoke: Revoke, timestamp_sec: u64) -> RevokeResult {
+fn revoke(revoke: Revocation, timestamp_sec: u64) -> RevokeResult {
     with_tg(|tg| {
         check_timestamp_tetraplets(&marine_rs_sdk::get_call_parameters(), 1)?;
 
diff --git a/service/src/storage_impl.rs b/service/src/storage_impl.rs
index 4d8568d..854f363 100644
--- a/service/src/storage_impl.rs
+++ b/service/src/storage_impl.rs
@@ -17,12 +17,12 @@ use std::str::FromStr;
 use std::time::Duration;
 use thiserror::Error as ThisError;
 use trust_graph::{
-    Auth, PublicKeyHashable as PK, PublicKeyHashable, Revoke, Storage, StorageError, Trust,
+    Auth, PublicKeyHashable as PK, PublicKeyHashable, Revocation, Storage, StorageError, Trust,
     TrustRelation, WeightFactor,
 };
 
 static AUTH_TYPE: i64 = 0;
-static REVOKE_TYPE: i64 = 1;
+static REVOCATION_TYPE: i64 = 1;
 pub static DB_PATH: &str = "/tmp/trust-graph.sqlite";
 
 pub fn create_tables() {
@@ -72,7 +72,7 @@ impl SQLiteStorage {
                 }
             }
 
-            Some(TrustRelation::Revoke(revoke)) => {
+            Some(TrustRelation::Revocation(revoke)) => {
                 if revoke.revoked_at < relation.issued_at() {
                     self.insert(relation)?;
                 }
@@ -85,6 +85,35 @@ impl SQLiteStorage {
 
         Ok(())
     }
+
+    fn get_relations(
+        &self,
+        issued_for: &PublicKeyHashable,
+        relation_type: i64,
+    ) -> Result<Vec<TrustRelation>, SQLiteStorageError> {
+        let mut cursor = self
+            .connection
+            .prepare(
+                "SELECT relation_type, issued_for, issued_by, issued_at, expires_at, signature \
+             FROM trust_relations WHERE issued_for = ? and relation_type = ?",
+            )?
+            .cursor();
+
+        cursor.bind(&[
+            Value::String(format!("{}", issued_for)),
+            Value::Integer(relation_type),
+        ])?;
+        let mut relations: Vec<TrustRelation> = vec![];
+
+        while let Some(row) = cursor.next()? {
+            match parse_relation(row) {
+                Ok(r) => relations.push(r),
+                Err(e) => log::error!("parse_relation: {:?}", e),
+            }
+        }
+
+        Ok(relations)
+    }
 }
 
 #[derive(ThisError, Debug)]
@@ -143,7 +172,7 @@ fn parse_relation(row: &[Value]) -> Result<TrustRelation, SQLiteStorageError> {
             issued_by: issued_by.into(),
         }))
     } else {
-        Ok(TrustRelation::Revoke(Revoke {
+        Ok(TrustRelation::Revocation(Revocation {
             pk: issued_for.into(),
             revoked_at: issued_at,
             revoked_by: issued_by.into(),
@@ -189,25 +218,34 @@ impl Storage for SQLiteStorage {
     }
 
     /// return all auths issued for pk
-    fn get_authorizations(&self, pk: &PublicKeyHashable) -> Result<Vec<Auth>, Self::Error> {
-        let mut cursor = self
-            .connection
-            .prepare(
-                "SELECT relation_type, issued_for, issued_by, issued_at, expires_at, signature \
-             FROM trust_relations WHERE issued_for = ? and relation_type = ?",
-            )?
-            .cursor();
+    fn get_authorizations(&self, issued_for: &PublicKeyHashable) -> Result<Vec<Auth>, Self::Error> {
+        Ok(self
+            .get_relations(issued_for, AUTH_TYPE)?
+            .into_iter()
+            .fold(vec![], |mut acc, r| {
+                if let TrustRelation::Auth(a) = r {
+                    acc.push(a);
+                }
 
-        cursor.bind(&[Value::String(format!("{}", pk)), Value::Integer(AUTH_TYPE)])?;
-        let mut auths: Vec<Auth> = vec![];
+                acc
+            }))
+    }
 
-        while let Some(row) = cursor.next()? {
-            if let TrustRelation::Auth(auth) = parse_relation(row)? {
-                auths.push(auth);
-            }
-        }
+    /// return all revocations issued for pk
+    fn get_revocations(
+        &self,
+        issued_for: &PublicKeyHashable,
+    ) -> Result<Vec<Revocation>, Self::Error> {
+        Ok(self
+            .get_relations(issued_for, REVOCATION_TYPE)?
+            .into_iter()
+            .fold(vec![], |mut acc, r| {
+                if let TrustRelation::Revocation(revocation) = r {
+                    acc.push(revocation);
+                }
 
-        Ok(auths)
+                acc
+            }))
     }
 
     fn insert(&mut self, relation: TrustRelation) -> Result<(), Self::Error> {
@@ -217,7 +255,7 @@ impl Storage for SQLiteStorage {
 
         let relation_type = match relation {
             TrustRelation::Auth(_) => AUTH_TYPE,
-            TrustRelation::Revoke(_) => REVOKE_TYPE,
+            TrustRelation::Revocation(_) => REVOCATION_TYPE,
         };
 
         statement.bind(1, &Value::Integer(relation_type))?;
@@ -293,8 +331,8 @@ impl Storage for SQLiteStorage {
         Ok(roots)
     }
 
-    fn revoke(&mut self, revoke: Revoke) -> Result<(), Self::Error> {
-        self.update_relation(TrustRelation::Revoke(revoke))
+    fn revoke(&mut self, revoke: Revocation) -> Result<(), Self::Error> {
+        self.update_relation(TrustRelation::Revocation(revoke))
     }
 
     fn update_auth(&mut self, auth: Auth, _cur_time: Duration) -> Result<(), Self::Error> {
diff --git a/service/src/tests.rs b/service/src/tests.rs
index f035a76..35cde98 100644
--- a/service/src/tests.rs
+++ b/service/src/tests.rs
@@ -23,7 +23,7 @@ mod service_tests {
     use fluence_keypair::KeyPair;
     use libp2p_core::PeerId;
     use marine_rs_sdk::{CallParameters, SecurityTetraplet};
-    use marine_test_env::trust_graph::{Certificate, Revoke, ServiceInterface, Trust};
+    use marine_test_env::trust_graph::{Certificate, Revocation, ServiceInterface, Trust};
     use rusqlite::Connection;
     use std::collections::HashMap;
     use std::time::{SystemTime, UNIX_EPOCH};
@@ -200,7 +200,7 @@ mod service_tests {
         issuer_kp: &KeyPair,
         revoked_peer_id: &PeerId,
         revoked_at_sec: u64,
-    ) -> Revoke {
+    ) -> Revocation {
         let result = trust_graph.get_revoke_bytes(revoked_peer_id.to_base58(), revoked_at_sec);
         assert!(result.success, "{}", result.error);
 
@@ -214,14 +214,14 @@ mod service_tests {
         assert!(issue_result.success, "{}", issue_result.error);
 
         let revoke_result = trust_graph.revoke_cp(
-            issue_result.revoke.clone(),
+            issue_result.revocation.clone(),
             revoked_at_sec,
             get_correct_timestamp_cp(1),
         );
 
         assert!(revoke_result.success, "{}", revoke_result.error);
 
-        issue_result.revoke
+        issue_result.revocation
     }
 
     fn generate_trust_chain_with(
@@ -436,39 +436,98 @@ mod service_tests {
         assert_eq!(certs.len(), 0);
     }
 
+    /// 1. peer `A` gives trusts to `B`
+    /// 2. weight of `B` is not 0
+    /// 3. peer `A` revokes `B`
+    /// 4. there is no path from `A` to `B`, weight of `A` is 0
     #[test]
-    fn revoke_test() {
+    fn trust_direct_revoke_test() {
         let mut trust_graph = marine_test_env::trust_graph::ServiceInterface::new();
         clear_env();
 
-        let root_kp = KeyPair::generate_ed25519();
+        let peerA_kp = KeyPair::generate_ed25519();
         let mut cur_time = 100u64;
-        add_root_with_trust(&mut trust_graph, &root_kp, cur_time, cur_time + 9999, 4u32);
+        add_root_with_trust(&mut trust_graph, &peerA_kp, cur_time, cur_time + 9999, 4u32);
 
-        let trust_kp = KeyPair::generate_ed25519();
+        let peerB_kp = KeyPair::generate_ed25519();
         add_trust(
             &mut trust_graph,
-            &root_kp,
-            &trust_kp.get_peer_id(),
+            &peerA_kp,
+            &peerB_kp.get_peer_id(),
             cur_time,
             cur_time + 99999,
         );
 
-        let weight = get_weight(&mut trust_graph, trust_kp.get_peer_id(), cur_time);
+        let weight = get_weight(&mut trust_graph, peerB_kp.get_peer_id(), cur_time);
         assert_ne!(weight, 0u32);
 
         cur_time += 1;
+        // A revokes B and cancels trust
         revoke(
             &mut trust_graph,
-            &root_kp,
-            &trust_kp.get_peer_id(),
+            &peerA_kp,
+            &peerB_kp.get_peer_id(),
             cur_time,
         );
 
-        let weight = get_weight(&mut trust_graph, trust_kp.get_peer_id(), cur_time);
+        let weight = get_weight(&mut trust_graph, peerB_kp.get_peer_id(), cur_time);
         assert_eq!(weight, 0u32);
     }
 
+    /// There is chain of trusts [0] -> [1] -> [2] -> [3] -> [4]
+    /// 1. [1] revokes [4]
+    /// 2. there is no path from [0] to [4], weight of [4] is 0
+    /// 3. [0] gives trust to [2]
+    /// 4. now there is path [0] -> [2] -> [3] -> [4]
+    /// 5. weight of [4] is not 0
+    #[test]
+    fn indirect_revoke_test() {
+        let mut trust_graph = marine_test_env::trust_graph::ServiceInterface::new();
+        clear_env();
+
+        let (key_pairs, trusts) =
+            generate_trust_chain_with_len(&mut trust_graph, 5, HashMap::new());
+        let mut cur_time = current_time();
+
+        let root_peer_id = key_pairs[0].get_peer_id();
+        add_root_peer_id(&mut trust_graph, root_peer_id, 2);
+        add_trusts(&mut trust_graph, &trusts, cur_time);
+
+        let target_peer_id = key_pairs[4].get_peer_id();
+        let revoked_by = &key_pairs[1];
+        let weight = get_weight(&mut trust_graph, target_peer_id, cur_time);
+        assert_ne!(weight, 0u32);
+
+        cur_time += 1;
+        // [1] revokes [4]
+        revoke(&mut trust_graph, &revoked_by, &target_peer_id, cur_time);
+
+        // now there are no path from root to [4]
+        let weight = get_weight(&mut trust_graph, target_peer_id, cur_time);
+        assert_eq!(weight, 0u32);
+
+        // [0] trusts [2]
+        add_trust(
+            &mut trust_graph,
+            &key_pairs[0],
+            &key_pairs[2].get_peer_id(),
+            cur_time,
+            cur_time + 99999,
+        );
+        // [2] trusts [4]
+        add_trust(
+            &mut trust_graph,
+            &key_pairs[2],
+            &target_peer_id,
+            cur_time,
+            cur_time + 99999,
+        );
+
+        // now we have [0] -> [2] -> [4] path
+        let weight = get_weight(&mut trust_graph, target_peer_id, cur_time);
+        assert_ne!(weight, 0u32);
+    }
+
     #[test]
     fn test_add_one_trust_to_cert_last() {
         let mut trust_graph = ServiceInterface::new();
diff --git a/src/chain.rs b/src/chain.rs
new file mode 100644
index 0000000..23091f5
--- /dev/null
+++ b/src/chain.rs
@@ -0,0 +1,47 @@
+/*
+ * 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 crate::{Auth, PublicKeyHashable, Revocation};
+use fluence_keypair::PublicKey;
+use nonempty::NonEmpty;
+use std::collections::HashSet;
+
+#[derive(Clone)]
+pub(crate) struct Chain {
+    pub(crate) auths: NonEmpty<Auth>,
+    revoked_by: HashSet<PublicKeyHashable>,
+}
+impl Chain {
+    pub(crate) fn new(auths: NonEmpty<Auth>, revocations: Vec<Revocation>) -> Self {
+        let mut chain = Self {
+            auths,
+            revoked_by: Default::default(),
+        };
+        chain.add_revocations(revocations);
+
+        chain
+    }
+    pub(crate) fn can_be_extended_by(&self, pk: &PublicKey) -> bool {
+        !self.revoked_by.contains(pk.as_ref())
+            && !self.auths.iter().any(|a| a.trust.issued_for.eq(pk))
+    }
+
+    pub(crate) fn add_revocations(&mut self, revocations: Vec<Revocation>) {
+        revocations.into_iter().for_each(move |r| {
+            self.revoked_by.insert(r.revoked_by.into());
+        });
+    }
+}
diff --git a/src/lib.rs b/src/lib.rs
index ad57023..2b1c191 100644
--- a/src/lib.rs
+++ b/src/lib.rs
@@ -29,6 +29,7 @@
 
 mod certificate;
 pub mod certificate_serde;
+mod chain;
 mod misc;
 mod public_key_hashable;
 mod revoke;
@@ -40,7 +41,7 @@ mod trust_relation;
 pub use crate::certificate::{Certificate, CertificateError};
 pub use crate::misc::current_time;
 pub use crate::public_key_hashable::PublicKeyHashable;
-pub use crate::revoke::Revoke;
+pub use crate::revoke::Revocation;
 pub use crate::trust::{Trust, TrustError};
 pub use crate::trust_graph::{TrustGraph, TrustGraphError, WeightFactor, MAX_WEIGHT_FACTOR};
 pub use crate::trust_graph_storage::{Storage, StorageError};
diff --git a/src/revoke.rs b/src/revoke.rs
index 43e37cf..22aa426 100644
--- a/src/revoke.rs
+++ b/src/revoke.rs
@@ -36,7 +36,7 @@ pub enum RevokeError {
 /// "A document" that cancels trust created before.
 /// TODO delete pk from Revoke (it is already in a trust node)
 #[derive(Clone, Debug, Serialize, Deserialize)]
-pub struct Revoke {
+pub struct Revocation {
     /// who is revoked
     pub pk: PublicKey,
     /// date when revocation was created
@@ -47,7 +47,7 @@ pub struct Revoke {
     pub signature: Signature,
 }
 
-impl Revoke {
+impl Revocation {
     #[allow(dead_code)]
     pub fn new(
         pk: PublicKey,
@@ -66,10 +66,10 @@ impl Revoke {
     /// Creates new revocation signed by a revoker.
     #[allow(dead_code)]
     pub fn create(revoker: &KeyPair, to_revoke: PublicKey, revoked_at: Duration) -> Self {
-        let msg = Revoke::signature_bytes(&to_revoke, revoked_at);
+        let msg = Revocation::signature_bytes(&to_revoke, revoked_at);
         let signature = revoker.sign(&msg).unwrap();
 
-        Revoke::new(to_revoke, revoker.public(), revoked_at, signature)
+        Revocation::new(to_revoke, revoker.public(), revoked_at, signature)
     }
 
     pub fn signature_bytes(pk: &PublicKey, revoked_at: Duration) -> Vec<u8> {
@@ -83,8 +83,8 @@ impl Revoke {
     }
 
     /// Verifies that revocation is cryptographically correct.
-    pub fn verify(revoke: &Revoke) -> Result<(), RevokeError> {
-        let msg = Revoke::signature_bytes(&revoke.pk, revoke.revoked_at);
+    pub fn verify(revoke: &Revocation) -> Result<(), RevokeError> {
+        let msg = Revocation::signature_bytes(&revoke.pk, revoke.revoked_at);
 
         revoke
             .revoked_by
@@ -104,9 +104,9 @@ mod tests {
 
         let duration = Duration::new(100, 0);
 
-        let revoke = Revoke::create(&revoker, to_revoke.public(), duration);
+        let revoke = Revocation::create(&revoker, to_revoke.public(), duration);
 
-        assert_eq!(Revoke::verify(&revoke).is_ok(), true);
+        assert_eq!(Revocation::verify(&revoke).is_ok(), true);
     }
 
     #[test]
@@ -116,16 +116,16 @@ mod tests {
 
         let duration = Duration::new(100, 0);
 
-        let revoke = Revoke::create(&revoker, to_revoke.public(), duration);
+        let revoke = Revocation::create(&revoker, to_revoke.public(), duration);
 
         let duration2 = Duration::new(95, 0);
-        let corrupted_revoke = Revoke::new(
+        let corrupted_revoke = Revocation::new(
             to_revoke.public(),
             revoker.public(),
             duration2,
             revoke.signature,
         );
 
-        assert_eq!(Revoke::verify(&corrupted_revoke).is_ok(), false);
+        assert_eq!(Revocation::verify(&corrupted_revoke).is_ok(), false);
     }
 }
diff --git a/src/trust_graph.rs b/src/trust_graph.rs
index 4927bd1..a69445b 100644
--- a/src/trust_graph.rs
+++ b/src/trust_graph.rs
@@ -16,8 +16,9 @@
 
 use crate::certificate::CertificateError::CertificateLengthError;
 use crate::certificate::{Certificate, CertificateError};
+use crate::chain::Chain;
 use crate::public_key_hashable::PublicKeyHashable as PK;
-use crate::revoke::Revoke;
+use crate::revoke::Revocation;
 use crate::revoke::RevokeError;
 use crate::trust::Trust;
 use crate::trust_graph::TrustGraphError::{
@@ -27,6 +28,7 @@ use crate::trust_graph_storage::Storage;
 use crate::trust_relation::Auth;
 use crate::{StorageError, TrustError};
 use fluence_keypair::public_key::PublicKey;
+use nonempty::NonEmpty;
 use std::borrow::Borrow;
 use std::collections::{HashSet, VecDeque};
 use std::convert::{From, Into};
@@ -93,7 +95,7 @@ impl From<TrustGraphError> for String {
 }
 
 pub fn get_weight_from_factor(wf: WeightFactor) -> u32 {
-    2u32.pow(MAX_WEIGHT_FACTOR.checked_sub(wf).unwrap_or(0u32))
+    2u32.pow(MAX_WEIGHT_FACTOR.saturating_sub(wf))
 }
 
 impl<S> TrustGraph<S>
@@ -245,12 +247,14 @@ where
         roots: HashSet<&PK>,
     ) -> Result<Vec<Vec<Auth>>, TrustGraphError> {
         // queue to collect all chains in the trust graph (each chain is a path in the trust graph)
-        let mut chains_queue: VecDeque<Vec<Auth>> = VecDeque::new();
+        let mut chains_queue: VecDeque<Chain> = VecDeque::new();
 
         let node_auths: Vec<Auth> = self.storage.get_authorizations(pk)?;
+        let node_revocations = self.storage.get_revocations(pk)?;
+
         // put all auth in the queue as the first possible paths through the graph
         for auth in node_auths {
-            chains_queue.push_back(vec![auth]);
+            chains_queue.push_back(Chain::new(NonEmpty::new(auth), node_revocations.clone()));
         }
 
         // List of all chains that converge (terminate) to known roots
@@ -261,22 +265,21 @@ where
                 .pop_front()
                 .expect("`chains_queue` always has at least one element");
 
-            let last = cur_chain
-                .last()
-                .expect("`cur_chain` always has at least one element");
+            let last = cur_chain.auths.last();
 
             let auths = self
                 .storage
                 .get_authorizations(&last.issued_by.clone().into())?;
 
             for auth in auths {
-                // if there is auth, that we not visited in the current chain, copy chain and append this auth
-                if !cur_chain
-                    .iter()
-                    .any(|a| a.trust.issued_for == auth.issued_by)
-                {
+                // if there is auth, that we not visited in the current chain and no revocations to any chain member --  copy chain and append this auth
+                if cur_chain.can_be_extended_by(&auth.issued_by) {
                     let mut new_chain = cur_chain.clone();
-                    new_chain.push(auth);
+                    new_chain.add_revocations(
+                        self.storage
+                            .get_revocations(&auth.issued_by.clone().into())?,
+                    );
+                    new_chain.auths.push(auth);
                     chains_queue.push_back(new_chain);
                 }
             }
@@ -289,8 +292,8 @@ where
             let issued_by: &PK = last.issued_by.as_ref();
             let converges_to_root = roots.contains(issued_by);
 
-            if self_signed && converges_to_root && cur_chain.len() > 1 {
-                terminated_chains.push(cur_chain);
+            if self_signed && converges_to_root && cur_chain.auths.len() > 1 {
+                terminated_chains.push(cur_chain.auths.into());
             }
         }
 
@@ -334,9 +337,11 @@ where
     }
 
     /// Mark public key as revoked.
-    pub fn revoke(&mut self, revoke: Revoke) -> Result<(), TrustGraphError> {
-        Revoke::verify(&revoke)?;
+    /// Every chain that contains path from `revoked_by` to revoked `pk`
+    /// will be excluded from valid certificates until revocation canceled by giving trust
+    pub fn revoke(&mut self, revocation: Revocation) -> Result<(), TrustGraphError> {
+        Revocation::verify(&revocation)?;
 
-        Ok(self.storage.revoke(revoke)?)
+        Ok(self.storage.revoke(revocation)?)
     }
 }
diff --git a/src/trust_graph_storage.rs b/src/trust_graph_storage.rs
index 4bbcbb8..d932751 100644
--- a/src/trust_graph_storage.rs
+++ b/src/trust_graph_storage.rs
@@ -1,5 +1,5 @@
 use crate::public_key_hashable::PublicKeyHashable as PK;
-use crate::revoke::Revoke;
+use crate::revoke::Revocation;
 use crate::trust_graph::WeightFactor;
 use crate::trust_relation::{Auth, TrustRelation};
 use std::fmt::Display;
@@ -16,13 +16,15 @@ pub trait Storage {
         issued_by: &PK,
     ) -> Result<Option<TrustRelation>, Self::Error>;
 
-    fn get_authorizations(&self, pk: &PK) -> Result<Vec<Auth>, Self::Error>;
+    fn get_authorizations(&self, issued_for: &PK) -> Result<Vec<Auth>, Self::Error>;
+    fn get_revocations(&self, issued_for: &PK) -> Result<Vec<Revocation>, Self::Error>;
+
     fn insert(&mut self, node: TrustRelation) -> Result<(), Self::Error>;
 
     fn get_root_weight_factor(&self, pk: &PK) -> Result<Option<WeightFactor>, Self::Error>;
     fn add_root_weight_factor(&mut self, pk: PK, weight: WeightFactor) -> Result<(), Self::Error>;
     fn root_keys(&self) -> Result<Vec<PK>, Self::Error>;
-    fn revoke(&mut self, revoke: Revoke) -> Result<(), Self::Error>;
+    fn revoke(&mut self, revocation: Revocation) -> Result<(), Self::Error>;
     fn update_auth(&mut self, auth: Auth, cur_time: Duration) -> Result<(), Self::Error>;
     fn remove_expired(&mut self, current_time: Duration) -> Result<(), Self::Error>;
 }
diff --git a/src/trust_node.rs b/src/trust_node.rs
deleted file mode 100644
index 33465d4..0000000
--- a/src/trust_node.rs
+++ /dev/null
@@ -1,206 +0,0 @@
-/*
- * Copyright 2020 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 crate::public_key_hashable::PublicKeyHashable;
-use crate::revoke::Revoke;
-use crate::trust::Trust;
-use failure::_core::time::Duration;
-use fluence_keypair::public_key::PublicKey;
-use serde::{Deserialize, Serialize};
-use serde_with::serde_as;
-use std::collections::HashMap;
-
-#[derive(Debug, Clone, Serialize, Deserialize)]
-enum TrustRelation {
-    Auth(Auth),
-    Revoke(Revoke),
-}
-
-impl TrustRelation {
-    /// Returns timestamp of when this relation was created
-    pub fn issued_at(&self) -> Duration {
-        match self {
-            TrustRelation::Auth(auth) => auth.trust.issued_at,
-            TrustRelation::Revoke(revoke) => revoke.revoked_at,
-        }
-    }
-
-    /// Returns public key of the creator of this relation
-    pub fn issued_by(&self) -> &PublicKey {
-        match self {
-            TrustRelation::Auth(auth) => &auth.issued_by,
-            TrustRelation::Revoke(revoke) => &revoke.revoked_by,
-        }
-    }
-}
-
-/// Represents who give a certificate
-#[derive(Debug, Clone, Serialize, Deserialize)]
-pub struct Auth {
-    /// proof of this authorization
-    pub trust: Trust,
-    /// the issuer of this authorization
-    pub issued_by: PublicKey,
-}
-
-/// An element of trust graph that store relations (trust or revoke)
-/// that given by some owners of public keys.
-#[serde_as]
-#[derive(Debug, Serialize, Deserialize, Clone)]
-pub struct TrustNode {
-    /// identity key of this element
-    pub pk: PublicKey,
-
-    /// one public key could be authorized or revoked by multiple certificates
-    #[serde_as(as = "Vec<(_, _)>")]
-    trust_relations: HashMap<PublicKeyHashable, TrustRelation>,
-
-    /// for maintain
-    pub verified_at: Duration,
-}
-
-#[allow(dead_code)]
-impl TrustNode {
-    pub fn new(pk: PublicKey, verified_at: Duration) -> Self {
-        Self {
-            pk,
-            trust_relations: HashMap::new(),
-            verified_at,
-        }
-    }
-
-    pub fn get_auth(&self, pk: PublicKey) -> Option<Auth> {
-        match self.trust_relations.get(&pk.into()) {
-            Some(TrustRelation::Auth(auth)) => Some(auth.clone()),
-            _ => None,
-        }
-    }
-
-    pub fn get_revoke(&self, pk: PublicKey) -> Option<Revoke> {
-        match self.trust_relations.get(&pk.into()) {
-            Some(TrustRelation::Revoke(rev)) => Some(rev.clone()),
-            _ => None,
-        }
-    }
-
-    pub fn authorizations(&self) -> impl Iterator<Item = &Auth> + '_ {
-        self.trust_relations.values().filter_map(|tr| {
-            if let TrustRelation::Auth(auth) = tr {
-                Some(auth)
-            } else {
-                None
-            }
-        })
-    }
-
-    pub fn revocations(&self) -> impl Iterator<Item = &Revoke> + '_ {
-        self.trust_relations.values().filter_map(|tr| {
-            if let TrustRelation::Revoke(revoke) = tr {
-                Some(revoke)
-            } else {
-                None
-            }
-        })
-    }
-
-    /// Adds authorization. If the trust node already has this authorization,
-    /// add auth with later expiration date.
-    pub fn update_auth(&mut self, auth: Auth) {
-        self.update_relation(TrustRelation::Auth(auth));
-    }
-
-    // insert new trust relation, ignore if there is another one with same public key
-    fn insert(&mut self, pk: PublicKeyHashable, tr: TrustRelation) {
-        self.trust_relations.insert(pk, tr);
-    }
-
-    fn update_relation(&mut self, relation: TrustRelation) {
-        let issued_by = relation.issued_by().as_ref();
-
-        match self.trust_relations.get(issued_by) {
-            Some(TrustRelation::Auth(auth)) => {
-                if auth.trust.issued_at < relation.issued_at() {
-                    self.insert(issued_by.clone(), relation)
-                }
-            }
-            Some(TrustRelation::Revoke(existed_revoke)) => {
-                if existed_revoke.revoked_at < relation.issued_at() {
-                    self.insert(issued_by.clone(), relation)
-                }
-            }
-            None => self.insert(issued_by.clone(), relation),
-        };
-    }
-
-    pub fn update_revoke(&mut self, revoke: Revoke) {
-        self.update_relation(TrustRelation::Revoke(revoke));
-    }
-}
-
-#[cfg(test)]
-mod tests {
-    use std::time::Duration;
-
-    use fluence_keypair::key_pair::KeyPair;
-
-    use super::*;
-
-    #[test]
-    fn test_auth_and_revoke_trust_node() {
-        let kp = KeyPair::generate_ed25519();
-
-        let now = Duration::new(50, 0);
-        let past = Duration::new(5, 0);
-        let future = Duration::new(500, 0);
-
-        let mut trust_node = TrustNode {
-            pk: kp.public(),
-            trust_relations: HashMap::new(),
-            verified_at: now,
-        };
-
-        let truster = KeyPair::generate_ed25519();
-
-        let revoke = Revoke::create(&truster, kp.public(), now);
-
-        trust_node.update_revoke(revoke);
-
-        assert!(trust_node.get_revoke(truster.public()).is_some());
-
-        let old_trust = Trust::create(&truster, kp.public(), Duration::new(60, 0), past);
-
-        let old_auth = Auth {
-            trust: old_trust,
-            issued_by: truster.public(),
-        };
-
-        trust_node.update_auth(old_auth);
-
-        assert!(trust_node.get_revoke(truster.public()).is_some());
-        assert!(trust_node.get_auth(truster.public()).is_none());
-
-        let trust = Trust::create(&truster, kp.public(), Duration::new(60, 0), future);
-        let auth = Auth {
-            trust,
-            issued_by: truster.public(),
-        };
-
-        trust_node.update_auth(auth);
-
-        assert!(trust_node.get_auth(truster.public()).is_some());
-        assert!(trust_node.get_revoke(truster.public()).is_none());
-    }
-}
diff --git a/src/trust_relation.rs b/src/trust_relation.rs
index 9a66c76..3f3a109 100644
--- a/src/trust_relation.rs
+++ b/src/trust_relation.rs
@@ -14,7 +14,7 @@
  * limitations under the License.
  */
 
-use crate::revoke::Revoke;
+use crate::revoke::Revocation;
 use crate::trust::Trust;
 use failure::_core::time::Duration;
 use fluence_keypair::public_key::PublicKey;
@@ -33,7 +33,7 @@ pub struct Auth {
 #[derive(Debug, Clone, Serialize, Deserialize)]
 pub enum TrustRelation {
     Auth(Auth),
-    Revoke(Revoke),
+    Revocation(Revocation),
 }
 
 impl TrustRelation {
@@ -41,7 +41,7 @@ impl TrustRelation {
     pub fn issued_at(&self) -> Duration {
         match self {
             TrustRelation::Auth(auth) => auth.trust.issued_at,
-            TrustRelation::Revoke(revoke) => revoke.revoked_at,
+            TrustRelation::Revocation(r) => r.revoked_at,
         }
     }
 
@@ -49,28 +49,29 @@ impl TrustRelation {
     pub fn issued_by(&self) -> &PublicKey {
         match self {
             TrustRelation::Auth(auth) => &auth.issued_by,
-            TrustRelation::Revoke(revoke) => &revoke.revoked_by,
+            TrustRelation::Revocation(r) => &r.revoked_by,
         }
     }
 
     pub fn issued_for(&self) -> &PublicKey {
         match self {
             TrustRelation::Auth(auth) => &auth.trust.issued_for,
-            TrustRelation::Revoke(revoke) => &revoke.pk,
+            TrustRelation::Revocation(r) => &r.pk,
         }
     }
 
     pub fn expires_at(&self) -> Duration {
         match self {
             TrustRelation::Auth(auth) => auth.trust.expires_at,
-            TrustRelation::Revoke(_) => Duration::from_secs(0),
+            // revocations never expire
+            TrustRelation::Revocation(_) => Duration::from_secs(0),
         }
     }
 
     pub fn signature(&self) -> &Signature {
         match self {
             TrustRelation::Auth(auth) => &auth.trust.signature,
-            TrustRelation::Revoke(revoke) => &revoke.signature,
+            TrustRelation::Revocation(r) => &r.signature,
         }
     }
 }