Skip to content

Commit

Permalink
feat: P-861 add params support for evm dynamic assertion (#2812)
Browse files Browse the repository at this point in the history
  • Loading branch information
higherordertech authored Jun 17, 2024
1 parent 2b30554 commit 190401a
Show file tree
Hide file tree
Showing 18 changed files with 111 additions and 61 deletions.
8 changes: 4 additions & 4 deletions primitives/core/src/assertion/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,7 @@ use web3_nft::Web3NftType;
pub mod web3_token;
use web3_token::Web3TokenType;

use crate::{AccountId, ParameterString};
use crate::{AccountId, DynamicParams, ParameterString};

use parity_scale_codec::{Decode, Encode, MaxEncodedLen};
use scale_info::TypeInfo;
Expand Down Expand Up @@ -138,7 +138,7 @@ pub enum Assertion {
NftHolder(Web3NftType),

#[codec(index = 27)]
Dynamic(H160) // smart contract code identifier
Dynamic(H160, DynamicParams) // smart contract code identifier, abi encoded smart contract params
}

impl Assertion {
Expand Down Expand Up @@ -186,7 +186,7 @@ impl Assertion {
Self::TokenHoldingAmount(t_type) => t_type.get_supported_networks(),
Self::PlatformUser(p_type) => p_type.get_supported_networks(),
Self::NftHolder(t_type) => t_type.get_supported_networks(),
Self::Dynamic(_) => all_web3networks(),
Self::Dynamic(..) => all_web3networks(),
}
}

Expand All @@ -195,7 +195,7 @@ impl Assertion {
#[allow(clippy::match_like_matches_macro)]
pub fn skip_identity_filtering(&self) -> bool {
match self {
Self::A1 | Self::Dynamic(_) => true,
Self::A1 | Self::Dynamic(..) => true,
_ => false,
}
}
Expand Down
2 changes: 2 additions & 0 deletions primitives/core/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,8 @@ pub use types::*;

pub type ParameterString = BoundedVec<u8, ConstU32<64>>;

pub type DynamicParams = BoundedVec<u8, ConstU32<1024>>;

/// Common types of parachains.
mod types {
use sp_runtime::{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -30,10 +30,10 @@ use litentry_primitives::{
aes_decrypt, AchainableAmount, AchainableAmountHolding, AchainableAmountToken,
AchainableAmounts, AchainableBasic, AchainableBetweenPercents, AchainableClassOfYear,
AchainableDate, AchainableDateInterval, AchainableDatePercent, AchainableParams,
AchainableToken, Assertion, BnbDigitDomainType, BoundedWeb3Network, ContestType, EVMTokenType,
GenericDiscordRoleType, Identity, OneBlockCourseType, ParameterString, PlatformUserType,
RequestAesKey, SoraQuizType, VIP3MembershipCardLevel, Web3Network, Web3NftType, Web3TokenType,
REQUEST_AES_KEY_LEN,
AchainableToken, Assertion, BnbDigitDomainType, BoundedWeb3Network, ContestType, DynamicParams,
EVMTokenType, GenericDiscordRoleType, Identity, OneBlockCourseType, ParameterString,
PlatformUserType, RequestAesKey, SoraQuizType, VIP3MembershipCardLevel, Web3Network,
Web3NftType, Web3TokenType, REQUEST_AES_KEY_LEN,
};
use sp_core::{Pair, H160};

Expand Down Expand Up @@ -156,8 +156,11 @@ pub struct A2Arg {

#[derive(Args, Debug)]
pub struct DynamicArg {
//hex encoded smart contract id
// hex encoded smart contract id
pub smart_contract_id: String,
// hex encoded smart contract params
// can use this online tool to encode params: https://abi.hashex.org/
pub smart_contract_param: String,
}

#[derive(Args, Debug)]
Expand Down Expand Up @@ -631,7 +634,17 @@ impl Command {
Command::Dynamic(arg) => {
let decoded_id = hex::decode(&arg.smart_contract_id.clone()).unwrap();
let id_bytes: [u8; 20] = decoded_id.try_into().unwrap();
Assertion::Dynamic(H160::from(id_bytes))
let params = hex::decode(&arg.smart_contract_param.clone()).unwrap();
let params_len = params.len();
let truncated_params = DynamicParams::truncate_from(params);
let truncated_params_len = truncated_params.len();
if params_len > truncated_params_len {
println!(
"The dynamic params length {} is over the maximum value {}",
params_len, truncated_params_len
);
}
Assertion::Dynamic(H160::from(id_bytes), truncated_params)
},
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ export default {
TokenHoldingAmount: "Web3TokenType",
PlatformUser: "PlatformUserType",
NftHolder: "Web3NftType",
Dynamic: "([u8;20])",
Dynamic: "([u8;20],Bytes)",
},
},
AssertionSupportedNetwork: {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,8 @@ import "./DynamicAssertion.sol";
contract A1 is DynamicAssertion {
function execute(
Identity[] memory identities,
string[] memory /*secrets*/
string[] memory /*secrets*/,
bytes memory /*params*/
)
public
override
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,8 @@ import "./DynamicAssertion.sol";
contract A20 is DynamicAssertion {
function execute(
Identity[] memory identities,
string[] memory /*secrets*/
string[] memory /*secrets*/,
bytes memory /*params*/
)
public
override
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,11 @@ import "./libraries/Identities.sol";
import "./DynamicAssertion.sol";

contract A6 is DynamicAssertion {
function execute(Identity[] memory identities, string[] memory secrets)
function execute(
Identity[] memory identities,
string[] memory secrets,
bytes memory /*params*/
)
public
override
returns (
Expand Down Expand Up @@ -135,6 +139,6 @@ contract A6 is DynamicAssertion {
pure
returns (string memory)
{
return concatenateStrings("Bearer ", apiKey);
return string(abi.encodePacked("Bearer ", apiKey));
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,11 @@ import "./libraries/Identities.sol";
abstract contract DynamicAssertion {
string schema_url;

function execute(Identity[] memory identities, string[] memory secrets)
function execute(
Identity[] memory identities,
string[] memory secrets,
bytes memory params
)
public
virtual
returns (
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,11 @@ import "../libraries/Identities.sol";
import "../DynamicAssertion.sol";

abstract contract TokenHoldingAmount is DynamicAssertion {
function execute(Identity[] memory identities, string[] memory secrets)
function execute(
Identity[] memory identities,
string[] memory secrets,
bytes memory /*params*/
)
public
override
returns (
Expand Down
53 changes: 34 additions & 19 deletions tee-worker/litentry/core/assertion-build/src/dynamic/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -30,15 +30,18 @@ pub fn build<
>(
req: &AssertionBuildRequest,
smart_contract_id: SC::Id,
smart_contract_params: DynamicParams,
repository: Arc<SC>,
) -> Result<Credential> {
let executor = EvmAssertionExecutor { assertion_repository: repository };
let result = executor.execute(smart_contract_id, &req.identities).map_err(|e| {
Error::RequestVCFailed(
Assertion::Dynamic(smart_contract_id),
ErrorDetail::StfError(ErrorString::truncate_from(e.into())),
)
})?;
let result = executor
.execute(smart_contract_id, smart_contract_params.clone().into(), &req.identities)
.map_err(|e| {
Error::RequestVCFailed(
Assertion::Dynamic(smart_contract_id, smart_contract_params.clone()),
ErrorDetail::StfError(ErrorString::truncate_from(e.into())),
)
})?;

let runtime_version = IssuerRuntimeVersion {
parachain: req.parachain_runtime_version,
Expand All @@ -51,7 +54,7 @@ pub fn build<
for assertion in result.assertions {
let logic: AssertionLogic = serde_json::from_str(&assertion).map_err(|e| {
Error::RequestVCFailed(
Assertion::Dynamic(smart_contract_id),
Assertion::Dynamic(smart_contract_id, smart_contract_params.clone()),
ErrorDetail::StfError(ErrorString::truncate_from(format!("{}", e).into())),
)
})?;
Expand All @@ -70,7 +73,7 @@ pub fn build<
Err(e) => {
error!("Generate unsigned credential failed {:?}", e);
Err(Error::RequestVCFailed(
Assertion::Dynamic(smart_contract_id),
Assertion::Dynamic(smart_contract_id, smart_contract_params),
e.into_error_detail(),
))
},
Expand All @@ -84,7 +87,7 @@ pub mod assertion_test {
use lc_mock_server::run;
use lc_stf_task_sender::AssertionBuildRequest;
use litentry_hex_utils::decode_hex;
use litentry_primitives::{Identity, IdentityString, Web3Network};
use litentry_primitives::{DynamicParams, Identity, IdentityString, Web3Network};
use sp_core::{crypto::AccountId32, H160};

#[test]
Expand All @@ -106,7 +109,7 @@ pub mod assertion_test {
shard: Default::default(),
signer: AccountId32::new([0; 32]),
who: Identity::Twitter(IdentityString::new(vec![])),
assertion: Assertion::Dynamic(hash(1)),
assertion: Assertion::Dynamic(hash(1), DynamicParams::truncate_from(vec![])),
identities: vec![(twitter_identity, vec![]), (substrate_identity, vec![])],
top_hash: Default::default(),
parachain_block_number: Default::default(),
Expand All @@ -121,7 +124,9 @@ pub mod assertion_test {
let repository = InMemorySmartContractRepo::new();

// when
let credential = build(&request, hash(1), repository.into()).unwrap();
let credential =
build(&request, hash(1), DynamicParams::truncate_from(vec![]), repository.into())
.unwrap();

println!("Credential is: {:?}", credential);

Expand All @@ -140,7 +145,7 @@ pub mod assertion_test {
shard: Default::default(),
signer: AccountId32::new([0; 32]),
who: Identity::Twitter(IdentityString::new(vec![])),
assertion: Assertion::Dynamic(hash(0)),
assertion: Assertion::Dynamic(hash(0), DynamicParams::truncate_from(vec![])),
identities: vec![(twitter_identity, vec![]), (substrate_identity, vec![])],
top_hash: Default::default(),
parachain_block_number: Default::default(),
Expand All @@ -155,7 +160,9 @@ pub mod assertion_test {
let repository = InMemorySmartContractRepo::new();

// when
let credential = build(&request, hash(0), repository.into()).unwrap();
let credential =
build(&request, hash(0), DynamicParams::truncate_from(vec![]), repository.into())
.unwrap();

println!("Credential is: {:?}", credential);

Expand All @@ -176,7 +183,7 @@ pub mod assertion_test {
shard: Default::default(),
signer: AccountId32::new([0; 32]),
who: Identity::Twitter(IdentityString::new(vec![])),
assertion: Assertion::Dynamic(hash(2)),
assertion: Assertion::Dynamic(hash(2), DynamicParams::truncate_from(vec![])),
identities: vec![(twitter_identity, vec![]), (substrate_identity, vec![])],
top_hash: Default::default(),
parachain_block_number: Default::default(),
Expand All @@ -191,7 +198,9 @@ pub mod assertion_test {
let repository = InMemorySmartContractRepo::new();

// when
let credential = build(&request, hash(2), repository.into()).unwrap();
let credential =
build(&request, hash(2), DynamicParams::truncate_from(vec![]), repository.into())
.unwrap();

println!("Credential is: {:?}", credential);

Expand All @@ -209,7 +218,7 @@ pub mod assertion_test {
shard: Default::default(),
signer: AccountId32::new([0; 32]),
who: Identity::Twitter(IdentityString::new(vec![])),
assertion: Assertion::Dynamic(hash(0)),
assertion: Assertion::Dynamic(hash(0), DynamicParams::truncate_from(vec![])),
identities: vec![(twitter_identity, vec![])],
top_hash: Default::default(),
parachain_block_number: Default::default(),
Expand All @@ -224,7 +233,9 @@ pub mod assertion_test {
let repository = InMemorySmartContractRepo::new();

// when
let credential = build(&request, hash(0), repository.into()).unwrap();
let credential =
build(&request, hash(0), DynamicParams::truncate_from(vec![]), repository.into())
.unwrap();

// then
assert!(!credential.credential_subject.values[0]);
Expand All @@ -249,12 +260,14 @@ pub mod assertion_test {
let network = Web3Network::BitcoinP2tr;
let identities = vec![(Identity::Bitcoin(address), vec![network])];
let smart_contract_id = hash(3);
let smart_contract_params =
DynamicParams::truncate_from(ethabi::encode(&[ethabi::Token::String("ordi".into())]));

let request = AssertionBuildRequest {
shard: Default::default(),
signer: AccountId32::new([0; 32]),
who: Identity::Substrate(AccountId32::new([0; 32]).into()),
assertion: Assertion::Dynamic(smart_contract_id),
assertion: Assertion::Dynamic(smart_contract_id, smart_contract_params.clone()),
identities,
top_hash: Default::default(),
parachain_block_number: Default::default(),
Expand All @@ -269,7 +282,9 @@ pub mod assertion_test {
let repository = InMemorySmartContractRepo::new();

// when
let credential = build(&request, smart_contract_id, repository.into()).unwrap();
let credential =
build(&request, smart_contract_id, smart_contract_params.clone(), repository.into())
.unwrap();

println!("Credential is: {:?}", credential);

Expand Down
Loading

0 comments on commit 190401a

Please sign in to comment.