Skip to content

Commit

Permalink
Add URL type to Framework (#726)
Browse files Browse the repository at this point in the history
* Add URL type to Framework

* typo

* Changed Url from object

* Update sui_programmability/framework/tests/UrlTests.move

Co-authored-by: Sam Blackshear <sam@mystenlabs.com>

* Update sui_programmability/framework/sources/Url.move

Co-authored-by: Sam Blackshear <sam@mystenlabs.com>

* Update sui_programmability/framework/sources/Url.move

Co-authored-by: Sam Blackshear <sam@mystenlabs.com>

* Revert use constant in abort code

Co-authored-by: Sam Blackshear <sam@mystenlabs.com>
  • Loading branch information
oxade and sblackshear authored Mar 11, 2022
1 parent 3fd6b41 commit 6de3ba8
Show file tree
Hide file tree
Showing 2 changed files with 123 additions and 0 deletions.
75 changes: 75 additions & 0 deletions sui_programmability/framework/sources/Url.move
Original file line number Diff line number Diff line change
@@ -0,0 +1,75 @@
/// URL: standard Uniform Resource Locator string
/// Url: Sui type which wraps a URL
/// UrlCommitment: Sui type which wraps a Url but also includes an immutable commitment
/// to the hash of the resource at the given URL
module Sui::Url {
use Std::ASCII::String;
use Std::Vector;

/// Length of the vector<u8> representing a resource hash
const HASH_VECTOR_LENGTH: u64 = 32;

/// Error code when the length of the hash vector is not HASH_VECTOR_LENGTH
const EHASH_LENGTH_MISMATCH: u64 = 0;

/// Represents an arbitrary URL. Clients rendering values of this type should fetch the resource at `url` and render it using a to-be-defined Sui standard.
struct Url has store, drop {
// TODO: validate URL format
url: String,
}

/// Represents an arbitrary URL plus an immutable commitment to the underlying
/// resource hash. Clients rendering values of this type should fetch the resource at `url`, and then compare it against `resource_hash` using a to-be-defined Sui standard, and (if the two match) render the value using the `Url` standard.
struct UrlCommitment has store, drop {
url: Url,
resource_hash: vector<u8>,
}


// === constructors ===

/// Create a `Url`, with no validation
public fun new_unsafe_url(url: String): Url {
Url { url }
}

/// Create a `UrlCommitment`, and set the immutable hash
public fun new_unsafe_url_commitment(url: Url, resource_hash: vector<u8>): UrlCommitment {
// Length must be exact
assert!(Vector::length(&resource_hash) == HASH_VECTOR_LENGTH, EHASH_LENGTH_MISMATCH);

UrlCommitment { url, resource_hash }
}


// === `Url` functions ===

/// Get inner URL
public fun inner_url(self: &Url): String{
self.url
}

/// Update the inner URL
public fun update(self: &mut Url, url: String) {
self.url = url;
}


// === `UrlCommitment` functions ===

/// Get the hash of the resource at the URL
/// We enforce that the hash is immutable
public fun url_commitment_resource_hash(self: &UrlCommitment): vector<u8> {
self.resource_hash
}

/// Get inner URL
public fun url_commitment_inner_url(self: &UrlCommitment): String{
self.url.url
}

/// Update the URL, but the hash of the object at the URL must never change
public fun url_commitment_update(self: &mut UrlCommitment, url: String) {
update(&mut self.url, url)
}
}
48 changes: 48 additions & 0 deletions sui_programmability/framework/tests/UrlTests.move
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
#[test_only]
module Sui::UrlTests {
use Sui::Url;
use Std::ASCII::Self;

const EHASH_LENGTH_MISMATCH: u64 = 0;
const URL_STRING_MISMATCH: u64 = 1;

#[test]
fun test_basic_url() {
// url strings are not currently validated
let url_str = ASCII::string(x"414243454647");

let url = Url::new_unsafe_url(url_str);
assert!(Url::inner_url(&url) == url_str, URL_STRING_MISMATCH);
}

#[test]
#[expected_failure(abort_code = 0)]
fun test_malformed_hash() {
// url strings are not currently validated
let url_str = ASCII::string(x"414243454647");
// length too short
let hash = x"badf012345";

let url = Url::new_unsafe_url(url_str);
let _ = Url::new_unsafe_url_commitment(url, hash);
}

#[test]
fun test_good_hash() {
// url strings are not currently validated
let url_str = ASCII::string(x"414243454647");
// 32 bytes
let hash = x"1234567890123456789012345678901234567890abcdefabcdefabcdefabcdef";

let url = Url::new_unsafe_url(url_str);
let url_commit = Url::new_unsafe_url_commitment(url, hash);

assert!(Url::url_commitment_resource_hash(&url_commit) == hash, EHASH_LENGTH_MISMATCH);
assert!(Url::url_commitment_inner_url(&url_commit) == url_str, URL_STRING_MISMATCH);

let url_str = ASCII::string(x"37414243454647");

Url::url_commitment_update(&mut url_commit, url_str);
assert!(Url::url_commitment_inner_url(&url_commit) == url_str, URL_STRING_MISMATCH);
}
}

1 comment on commit 6de3ba8

@github-actions
Copy link
Contributor

Choose a reason for hiding this comment

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

Bench results

�[0m�[0m�[1m�[32m Finished�[0m release [optimized] target(s) in 0.27s
�[0m�[0m�[1m�[32m Running�[0m target/release/bench
�[2m2022-03-11T18:24:50.199679Z�[0m �[32m INFO�[0m �[2mbench�[0m�[2m:�[0m Starting benchmark: TransactionsAndCerts
�[2m2022-03-11T18:24:50.199706Z�[0m �[32m INFO�[0m �[2mbench�[0m�[2m:�[0m Preparing accounts.
�[2m2022-03-11T18:24:50.200148Z�[0m �[32m INFO�[0m �[2mbench�[0m�[2m:�[0m Open database on path: "/tmp/DB_3242749F7B4232E6B5A8A77D2A4E837099BA1BCC"
�[2m2022-03-11T18:24:55.288656Z�[0m �[32m INFO�[0m �[2mbench�[0m�[2m:�[0m Preparing transactions.
�[2m2022-03-11T18:25:04.386232Z�[0m �[32m INFO�[0m �[2msui_network::transport�[0m�[2m:�[0m Listening to TCP traffic on 127.0.0.1:9555
�[2m2022-03-11T18:25:05.387674Z�[0m �[32m INFO�[0m �[2mbench�[0m�[2m:�[0m Number of TCP connections: 2
�[2m2022-03-11T18:25:05.387703Z�[0m �[32m INFO�[0m �[2mbench�[0m�[2m:�[0m Set max_in_flight to 500
�[2m2022-03-11T18:25:05.387706Z�[0m �[32m INFO�[0m �[2mbench�[0m�[2m:�[0m Sending requests.
�[2m2022-03-11T18:25:05.392038Z�[0m �[32m INFO�[0m �[2msui_network::network�[0m�[2m:�[0m Sending TCP requests to 127.0.0.1:9555
�[2m2022-03-11T18:25:05.397048Z�[0m �[32m INFO�[0m �[2msui_network::network�[0m�[2m:�[0m Sending TCP requests to 127.0.0.1:9555
�[2m2022-03-11T18:25:06.334576Z�[0m �[32m INFO�[0m �[2msui_core::authority_server�[0m�[2m:�[0m 127.0.0.1:9555 has processed 5000 packets
�[2m2022-03-11T18:25:07.154514Z�[0m �[32m INFO�[0m �[2msui_network::network�[0m�[2m:�[0m In flight 500 Remaining 35000
�[2m2022-03-11T18:25:07.213840Z�[0m �[32m INFO�[0m �[2msui_network::network�[0m�[2m:�[0m In flight 500 Remaining 35000
�[2m2022-03-11T18:25:07.268932Z�[0m �[32m INFO�[0m �[2msui_core::authority_server�[0m�[2m:�[0m 127.0.0.1:9555 has processed 10000 packets
�[2m2022-03-11T18:25:08.187053Z�[0m �[32m INFO�[0m �[2msui_core::authority_server�[0m�[2m:�[0m 127.0.0.1:9555 has processed 15000 packets
�[2m2022-03-11T18:25:09.001065Z�[0m �[32m INFO�[0m �[2msui_network::network�[0m�[2m:�[0m In flight 500 Remaining 30000
�[2m2022-03-11T18:25:09.072959Z�[0m �[32m INFO�[0m �[2msui_network::network�[0m�[2m:�[0m In flight 500 Remaining 30000
�[2m2022-03-11T18:25:09.143313Z�[0m �[32m INFO�[0m �[2msui_core::authority_server�[0m�[2m:�[0m 127.0.0.1:9555 has processed 20000 packets
�[2m2022-03-11T18:25:10.066934Z�[0m �[32m INFO�[0m �[2msui_core::authority_server�[0m�[2m:�[0m 127.0.0.1:9555 has processed 25000 packets
�[2m2022-03-11T18:25:10.890126Z�[0m �[32m INFO�[0m �[2msui_network::network�[0m�[2m:�[0m In flight 500 Remaining 25000
�[2m2022-03-11T18:25:10.947849Z�[0m �[32m INFO�[0m �[2msui_network::network�[0m�[2m:�[0m In flight 500 Remaining 25000
�[2m2022-03-11T18:25:10.991445Z�[0m �[32m INFO�[0m �[2msui_core::authority_server�[0m�[2m:�[0m 127.0.0.1:9555 has processed 30000 packets
�[2m2022-03-11T18:25:11.919582Z�[0m �[32m INFO�[0m �[2msui_core::authority_server�[0m�[2m:�[0m 127.0.0.1:9555 has processed 35000 packets
�[2m2022-03-11T18:25:12.717377Z�[0m �[32m INFO�[0m �[2msui_network::network�[0m�[2m:�[0m In flight 500 Remaining 20000
�[2m2022-03-11T18:25:12.791323Z�[0m �[32m INFO�[0m �[2msui_network::network�[0m�[2m:�[0m In flight 500 Remaining 20000
�[2m2022-03-11T18:25:12.847708Z�[0m �[32m INFO�[0m �[2msui_core::authority_server�[0m�[2m:�[0m 127.0.0.1:9555 has processed 40000 packets
�[2m2022-03-11T18:25:13.791035Z�[0m �[32m INFO�[0m �[2msui_core::authority_server�[0m�[2m:�[0m 127.0.0.1:9555 has processed 45000 packets
�[2m2022-03-11T18:25:14.631608Z�[0m �[32m INFO�[0m �[2msui_network::network�[0m�[2m:�[0m In flight 500 Remaining 15000
�[2m2022-03-11T18:25:14.718446Z�[0m �[32m INFO�[0m �[2msui_network::network�[0m�[2m:�[0m In flight 500 Remaining 15000
�[2m2022-03-11T18:25:14.735640Z�[0m �[32m INFO�[0m �[2msui_core::authority_server�[0m�[2m:�[0m 127.0.0.1:9555 has processed 50000 packets
�[2m2022-03-11T18:25:15.673675Z�[0m �[32m INFO�[0m �[2msui_core::authority_server�[0m�[2m:�[0m 127.0.0.1:9555 has processed 55000 packets
�[2m2022-03-11T18:25:16.491988Z�[0m �[32m INFO�[0m �[2msui_network::network�[0m�[2m:�[0m In flight 500 Remaining 10000
�[2m2022-03-11T18:25:16.573076Z�[0m �[32m INFO�[0m �[2msui_network::network�[0m�[2m:�[0m In flight 500 Remaining 10000
�[2m2022-03-11T18:25:16.613920Z�[0m �[32m INFO�[0m �[2msui_core::authority_server�[0m�[2m:�[0m 127.0.0.1:9555 has processed 60000 packets
�[2m2022-03-11T18:25:17.549435Z�[0m �[32m INFO�[0m �[2msui_core::authority_server�[0m�[2m:�[0m 127.0.0.1:9555 has processed 65000 packets
�[2m2022-03-11T18:25:18.357484Z�[0m �[32m INFO�[0m �[2msui_network::network�[0m�[2m:�[0m In flight 500 Remaining 5000
�[2m2022-03-11T18:25:18.430209Z�[0m �[32m INFO�[0m �[2msui_network::network�[0m�[2m:�[0m In flight 500 Remaining 5000
�[2m2022-03-11T18:25:18.499124Z�[0m �[32m INFO�[0m �[2msui_core::authority_server�[0m�[2m:�[0m 127.0.0.1:9555 has processed 70000 packets
�[2m2022-03-11T18:25:19.449631Z�[0m �[32m INFO�[0m �[2msui_core::authority_server�[0m�[2m:�[0m 127.0.0.1:9555 has processed 75000 packets
�[2m2022-03-11T18:25:20.410195Z�[0m �[32m INFO�[0m �[2msui_network::network�[0m�[2m:�[0m Done sending TCP requests to 127.0.0.1:9555
�[2m2022-03-11T18:25:20.439985Z�[0m �[32m INFO�[0m �[2msui_core::authority_server�[0m�[2m:�[0m 127.0.0.1:9555 has processed 80000 packets
�[2m2022-03-11T18:25:20.489640Z�[0m �[32m INFO�[0m �[2msui_network::network�[0m�[2m:�[0m Done sending TCP requests to 127.0.0.1:9555
�[2m2022-03-11T18:25:20.490209Z�[0m �[32m INFO�[0m �[2mbench�[0m�[2m:�[0m Received 80000 responses.
�[2m2022-03-11T18:25:20.705233Z�[0m �[33m WARN�[0m �[2mbench�[0m�[2m:�[0m Completed benchmark for TransactionsAndCerts
Total time: 15102490us, items: 40000, tx/sec: 2648.569871590711

Please sign in to comment.