Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Dynamic EVM assertions #2695

Merged
merged 69 commits into from
May 8, 2024
Merged

Dynamic EVM assertions #2695

merged 69 commits into from
May 8, 2024

Conversation

kziemianek
Copy link
Member

General

This PR adds foundation for creating user defined runtime assertions called Dynamic Assertions

Dynamic Assertion is a assertion logic represented by code/binary that can be added to parachain's storage by any account and executed by dynamic assertion runtime inside sidechain's sgx enclave.

The main purpose of dynamic assertions is to provide the infrastructure for the community to freely define and create assertions. Secondary goal is to remove assertions written in Rust that are baked into identity-worker's code.

Dynamic assertion has an access to:

  1. user id graph
  2. assertion secrets

Assertion secret is a string encrypted with worker's shielding key that is added during dynamic assertion creation and is passed to assertion execution. It can be an API-KEY used for authorizing request sent during execution.

Included assertions:

  • A1 - uses only sidechain's state
  • A20 - reaches out to HTTP server without authentication
  • A6 - reaches out to X api with authentication

This evm assertion runtime implementation should allow for fulfilling any of the scenarios above. It might need further extension in order to support other cases.

Assertions are propagated to sidechain through parachain's event sync mechanism and are kept in memory + sealed to file.
Storage implementation is far from ideal and we should aim in the future for it's improvement.

Writing evm dynamic assertions

It should be possible to use any language that compiles to valid evm byte code (I tested only Solidity). Some of the features are still available but it doesn't make sense to use them in assertions because each assertion is executed inside clean evm runtime, for example writing to evm storage doesn't make sense because it's purged after the execution.

Prerequisites for evm dynamic assertions:

  • smart contract must have function with signature function execute(Identity[] memory identities, string[] memory secrets) public
  • should be compiled with solc 0.8.11 (the most recent version tested)

Abstract DynamicAssertion contract can be used for easier development. It contains virtual execute function matching signature above. It has also various util functions to work with precompiles and IDGraph data structures available during the execution.

Reaching out to HTTP servers from assertion

EVM assertion runtime contains various precompiles providing ability for making HTTP calls and extracting data using JSONPointer .

Example of getting followers count from X api:

string memory url = concatenateStrings("http://https://api.twitter.com/2/users/by/username/", string(identities[i].value));
string memory full_url = concatenateStrings(url, "?user.fields=public_metrics");
HttpHeader[] memory headers = new HttpHeader[](1);
// we expect first secret to be twitter api key
headers[0] = HttpHeader("authorization", secrets[0]);
int64 followers_count = GetI64(full_url, "/data/public_metrics/followers_count", headers);

List of precompiles:

  • 0x03E8 - GetI64 - for getting I64 value from HTTP server
  • 0x03E9 - GetBool - for getting bool value from HTTP server
  • 0x03EA - GetString - for getting string value from HTTP server
  • 0x041B - toHex - for turning bytes into hex string

Assertion's Solidity source code can be found under litentry-parachain/tee-worker/litentry/core/assertion-build/src/dynamic/contracts.

@kziemianek kziemianek added the C1-noteworthy Non-breaking change but is worth noticing for client label Apr 26, 2024
@kziemianek kziemianek requested a review from a team April 26, 2024 14:19
Copy link
Contributor

@silva-fj silva-fj left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It looks pretty good overall, the idea of dynamic assertions is quite nice.

I have a few observations. Since we are storing the assertions/smart contracts in the parachain, why don't we use that state instead of storing them also in a sealed file? or (if my assumption that there could by a sync issue in a multi worker setup is correct), how about storing this data on the sidechain storage?

@kziemianek
Copy link
Member Author

It looks pretty good overall, the idea of dynamic assertions is quite nice.If i'

I have a few observations. Since we are storing the assertions/smart contracts in the parachain, why don't we use that state instead of storing them also in a sealed file? or (if my assumption that there could by a sync issue in a multi worker setup is correct), how about storing this data on the sidechain storage?

Thanks @silva-fj for review.

Getting state directly from parachain's store was my first choice but it requires parachain block header in order to verify date see get_storage_verified. That would lead us to stoing parachain's block headers by workers.

There should be no sync issue because after initial sync workers will continously process parachain's events and apply changes to local state. Additionaly for data that is not used/produced by STF I see no point for using sidechain's storage.

Copy link
Collaborator

@Kailai-Wang Kailai-Wang left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Not much I can complain, good job 👍

We might need a mechanism to "forcibly" sync the parachain assertion registry at once in case we lose the track of the events, but that's a general question between parachain <> worker sync

@kziemianek kziemianek enabled auto-merge (squash) May 8, 2024 08:42
@kziemianek kziemianek merged commit 5e37d1a into dev May 8, 2024
32 checks passed
@kziemianek kziemianek deleted the solidity-assertions branch May 15, 2024 23:20
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
C1-noteworthy Non-breaking change but is worth noticing for client
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

3 participants