This repository has been archived by the owner on Sep 13, 2022. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 43
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
feat(service)!: add authorization service for mempool (#320)
* feat: add authorization service * feat: mempool check authorization by service * add set admin function * tmp * feat: verify signature when new authorization * feat: register multi_signature * encode json twice * fix * refactor executor * test: update muta sdk version for checking multi sig with mempool changes * fix unit test * cargo fmt * fix decode may panic * cargo clippy * change verify signature api * test(e2e): add multi signature testcase Co-authored-by: homura <[email protected]> Co-authored-by: zero.qn <[email protected]>
- Loading branch information
1 parent
f8f16cd
commit a3c3433
Showing
27 changed files
with
622 additions
and
241 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,25 @@ | ||
[package] | ||
name = "authorization" | ||
version = "0.1.0" | ||
authors = ["Muta Dev <[email protected]>"] | ||
edition = "2018" | ||
repository = "https://github.com/nervosnetwork/muta" | ||
|
||
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html | ||
|
||
[dependencies] | ||
binding-macro = { path = "../../binding-macro" } | ||
protocol = { path = "../../protocol", package = "muta-protocol" } | ||
|
||
serde = { version = "1.0", features = ["derive"] } | ||
serde_json = "1.0" | ||
rlp = "0.4" | ||
bytes = "0.5" | ||
derive_more = "0.99" | ||
byteorder = "1.3" | ||
muta-codec-derive = "0.2" | ||
|
||
[dev-dependencies] | ||
cita_trie = "2.0" | ||
async-trait = "0.1" | ||
framework = { path = "../../framework" } |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,127 @@ | ||
mod types; | ||
|
||
use binding_macro::{cycles, genesis, service}; | ||
use protocol::traits::{ExecutorParams, ServiceResponse, ServiceSDK, StoreMap}; | ||
use protocol::types::{Address, ServiceContext}; | ||
|
||
use crate::types::{ | ||
AddVerifiedItemPayload, InitGenesisPayload, RemoveVerifiedItemPayload, SetAdminPayload, | ||
}; | ||
|
||
const AUTHORIZATION_ADMIN_KEY: &str = "authotization_admin"; | ||
const MULTI_SIG_SERVICE: &str = "multi_signature"; | ||
const MULTI_SIG_METHOD: &str = "verify_signature"; | ||
|
||
pub struct AuthorizationService<SDK> { | ||
sdk: SDK, | ||
verified_map: Box<dyn StoreMap<String, String>>, | ||
} | ||
|
||
#[service] | ||
impl<SDK: ServiceSDK> AuthorizationService<SDK> { | ||
pub fn new(mut sdk: SDK) -> Self { | ||
let mut verified_map: Box<dyn StoreMap<String, String>> = | ||
sdk.alloc_or_recover_map("authotization"); | ||
|
||
verified_map.insert(MULTI_SIG_SERVICE.to_owned(), MULTI_SIG_METHOD.to_owned()); | ||
|
||
Self { sdk, verified_map } | ||
} | ||
|
||
#[genesis] | ||
fn init_genesis(&mut self, payload: InitGenesisPayload) { | ||
let service_names = payload.register_service_names; | ||
let function_names = payload.verified_method_names; | ||
assert!(service_names.len() == function_names.len()); | ||
|
||
self.sdk | ||
.set_value(AUTHORIZATION_ADMIN_KEY.to_string(), payload.admin); | ||
|
||
for item in service_names.into_iter().zip(function_names.into_iter()) { | ||
self.verified_map.insert(item.0, item.1); | ||
} | ||
} | ||
|
||
#[cycles(210_00)] | ||
#[read] | ||
fn check_authorization(&self, ctx: ServiceContext, payload: String) -> ServiceResponse<()> { | ||
for (service_name, mathod_name) in self.verified_map.iter() { | ||
let resp = self._do_verify(&ctx, &service_name, &mathod_name, &payload); | ||
if resp.is_error() { | ||
return ServiceResponse::<()>::from_error( | ||
102, | ||
format!( | ||
"verify transaction {:?} error {:?}", | ||
mathod_name, resp.error_message | ||
), | ||
); | ||
} | ||
} | ||
|
||
ServiceResponse::from_succeed(()) | ||
} | ||
|
||
#[cycles(210_00)] | ||
#[write] | ||
fn add_verified_item( | ||
&mut self, | ||
ctx: ServiceContext, | ||
payload: AddVerifiedItemPayload, | ||
) -> ServiceResponse<()> { | ||
if !self._is_admin(&ctx) { | ||
return ServiceResponse::<()>::from_error(103, "Invalid caller".to_owned()); | ||
} | ||
|
||
self.verified_map | ||
.insert(payload.service_name, payload.method_name); | ||
ServiceResponse::from_succeed(()) | ||
} | ||
|
||
#[cycles(210_00)] | ||
#[write] | ||
fn remove_verified_item( | ||
&mut self, | ||
ctx: ServiceContext, | ||
payload: RemoveVerifiedItemPayload, | ||
) -> ServiceResponse<()> { | ||
if !self._is_admin(&ctx) { | ||
return ServiceResponse::<()>::from_error(103, "Invalid caller".to_owned()); | ||
} | ||
|
||
self.verified_map.remove(&payload.service_name); | ||
ServiceResponse::from_succeed(()) | ||
} | ||
|
||
#[cycles(210_00)] | ||
#[write] | ||
fn set_admin(&mut self, ctx: ServiceContext, payload: SetAdminPayload) -> ServiceResponse<()> { | ||
if !self._is_admin(&ctx) { | ||
return ServiceResponse::<()>::from_error(103, "Invalid caller".to_owned()); | ||
} | ||
|
||
self.sdk | ||
.set_value(AUTHORIZATION_ADMIN_KEY.to_string(), payload.new_admin); | ||
|
||
ServiceResponse::from_succeed(()) | ||
} | ||
|
||
fn _do_verify( | ||
&self, | ||
ctx: &ServiceContext, | ||
service_name: &str, | ||
method_name: &str, | ||
payload_json: &str, | ||
) -> ServiceResponse<String> { | ||
self.sdk | ||
.read(&ctx, None, service_name, method_name, &payload_json) | ||
} | ||
|
||
fn _is_admin(&self, ctx: &ServiceContext) -> bool { | ||
let admin: Address = self | ||
.sdk | ||
.get_value(&AUTHORIZATION_ADMIN_KEY.to_string()) | ||
.expect("must have an admin"); | ||
|
||
ctx.get_caller() == admin | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,29 @@ | ||
use muta_codec_derive::RlpFixedCodec; | ||
use serde::{Deserialize, Serialize}; | ||
|
||
use protocol::fixed_codec::{FixedCodec, FixedCodecError}; | ||
use protocol::types::{Address, Bytes}; | ||
use protocol::ProtocolResult; | ||
|
||
#[derive(RlpFixedCodec, Deserialize, Serialize, Clone, Debug)] | ||
pub struct InitGenesisPayload { | ||
pub admin: Address, | ||
pub register_service_names: Vec<String>, | ||
pub verified_method_names: Vec<String>, | ||
} | ||
|
||
#[derive(RlpFixedCodec, Deserialize, Serialize, Clone, Debug)] | ||
pub struct AddVerifiedItemPayload { | ||
pub service_name: String, | ||
pub method_name: String, | ||
} | ||
|
||
#[derive(RlpFixedCodec, Deserialize, Serialize, Clone, Debug)] | ||
pub struct RemoveVerifiedItemPayload { | ||
pub service_name: String, | ||
} | ||
|
||
#[derive(RlpFixedCodec, Deserialize, Serialize, Clone, Debug)] | ||
pub struct SetAdminPayload { | ||
pub new_admin: Address, | ||
} |
Oops, something went wrong.