Skip to content

Commit

Permalink
fix(contracts): updated and reformatted contracts (#108)
Browse files Browse the repository at this point in the history
  • Loading branch information
mlegner authored Aug 19, 2024
1 parent ae54bad commit eba7c02
Show file tree
Hide file tree
Showing 19 changed files with 553 additions and 645 deletions.
16 changes: 4 additions & 12 deletions contracts/blob_store/Move.lock
Original file line number Diff line number Diff line change
Expand Up @@ -2,33 +2,25 @@

[move]
version = 2
manifest_digest = "537E35587055E526E85CD04C400536AFFEC5CC0BE833EB4B5FAC245850C34C96"
manifest_digest = "C461A25DAED3234921DF6DD2B4AE93FF11BA907C5A5CF469400757C595C15B68"
deps_digest = "F8BBB0CCB2491CA29A3DF03D6F92277A4F3574266507ACD77214D37ECA3F3082"
dependencies = [
{ name = "Sui" },
]

[[move.package]]
name = "MoveStdlib"
source = { git = "https://github.com/MystenLabs/sui.git", rev = "testnet-v1.29.2", subdir = "crates/sui-framework/packages/move-stdlib" }
source = { git = "https://github.com/MystenLabs/sui.git", rev = "testnet-v1.31.1", subdir = "crates/sui-framework/packages/move-stdlib" }

[[move.package]]
name = "Sui"
source = { git = "https://github.com/MystenLabs/sui.git", rev = "testnet-v1.29.2", subdir = "crates/sui-framework/packages/sui-framework" }
source = { git = "https://github.com/MystenLabs/sui.git", rev = "testnet-v1.31.1", subdir = "crates/sui-framework/packages/sui-framework" }

dependencies = [
{ name = "MoveStdlib" },
]

[move.toolchain-version]
compiler-version = "1.29.2"
compiler-version = "1.30.1"
edition = "2024.beta"
flavor = "sui"

[env]

[env.testnet]
chain-id = "4c78adac"
original-published-id = "0x8bf57168d5acb0e83efa49905a326d0d624ff147955106d94fb09b6abdaa7bbc"
latest-published-id = "0x8bf57168d5acb0e83efa49905a326d0d624ff147955106d94fb09b6abdaa7bbc"
published-version = "1"
2 changes: 1 addition & 1 deletion contracts/blob_store/Move.toml
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ name = "blob_store"
edition = "2024.beta"

[dependencies]
Sui = { git = "https://github.com/MystenLabs/sui.git", subdir = "crates/sui-framework/packages/sui-framework", rev = "testnet-v1.29.2" }
Sui = { git = "https://github.com/MystenLabs/sui.git", subdir = "crates/sui-framework/packages/sui-framework", rev = "testnet-v1.31.1" }

[addresses]
blob_store = "0x0"
Expand Down
147 changes: 61 additions & 86 deletions contracts/blob_store/sources/blob.move
Original file line number Diff line number Diff line change
Expand Up @@ -6,28 +6,29 @@ module blob_store::blob {
use sui::hash;

use blob_store::committee::{Self, CertifiedMessage};
use blob_store::system::{Self, System};
use blob_store::system::System;
use blob_store::storage_resource::{
Storage,
start_epoch,
end_epoch,
storage_size,
fuse_periods,
destroy};
destroy,
};
use blob_store::encoding;
use blob_store::blob_events::{emit_blob_registered, emit_blob_certified};

// A certify blob message structure
const BLOB_CERT_MSG_TYPE: u8 = 1;

// Error codes
const ERROR_INVALID_MSG_TYPE: u64 = 1;
const ERROR_RESOURCE_BOUNDS: u64 = 2;
const ERROR_RESOURCE_SIZE: u64 = 3;
const ERROR_WRONG_EPOCH: u64 = 4;
const ERROR_ALREADY_CERTIFIED: u64 = 5;
const ERROR_INVALID_BLOB_ID: u64 = 6;
const ERROR_NOT_CERTIFIED : u64 = 7;
const EInvalidMsgType: u64 = 1;
const EResourceBounds: u64 = 2;
const EResourceSize: u64 = 3;
const EWrongEpoch: u64 = 4;
const EAlreadyCertified: u64 = 5;
const EInvalidBlobId: u64 = 6;
const ENotCertified: u64 = 7;

// Object definitions

Expand All @@ -39,33 +40,33 @@ module blob_store::blob {
blob_id: u256,
size: u64,
erasure_code_type: u8,
certified: option::Option<u64>, // Store the epoch first certified
certified_epoch: option::Option<u64>, // Store the epoch first certified
storage: Storage,
}

// Accessor functions

public fun stored_epoch(b: &Blob) : u64 {
public fun stored_epoch(b: &Blob): u64 {
b.stored_epoch
}

public fun blob_id(b: &Blob) : u256 {
public fun blob_id(b: &Blob): u256 {
b.blob_id
}

public fun size(b: &Blob) : u64 {
public fun size(b: &Blob): u64 {
b.size
}

public fun erasure_code_type(b: &Blob) : u8 {
public fun erasure_code_type(b: &Blob): u8 {
b.erasure_code_type
}

public fun certified(b: &Blob) : &Option<u64> {
&b.certified
public fun certified_epoch(b: &Blob): &Option<u64> {
&b.certified_epoch
}

public fun storage(b: &Blob) : &Storage {
public fun storage(b: &Blob): &Storage {
&b.storage
}

Expand All @@ -76,8 +77,7 @@ module blob_store::blob {
}

/// Derive the blob_id for a blob given the root_hash, erasure_code_type and size.
public fun derive_blob_id(root_hash: u256, erasure_code_type: u8, size : u64) : u256 {

public fun derive_blob_id(root_hash: u256, erasure_code_type: u8, size: u64): u256 {
let blob_id_struct = BlobIdDerivation {
erasure_code_type,
size,
Expand All @@ -87,7 +87,7 @@ module blob_store::blob {
let serialized = bcs::to_bytes(&blob_id_struct);
let encoded = hash::blake2b256(&serialized);
let mut decoder = bcs::new(encoded);
let blob_id = bcs::peel_u256(&mut decoder);
let blob_id = decoder.peel_u256();
blob_id
}

Expand All @@ -102,28 +102,28 @@ module blob_store::blob {
size: u64,
erasure_code_type: u8,
ctx: &mut TxContext,
) : Blob {

): Blob {
let id = object::new(ctx);
let stored_epoch = system::epoch(sys);
let stored_epoch = sys.epoch();

// Check resource bounds.
assert!(stored_epoch >= start_epoch(&storage), ERROR_RESOURCE_BOUNDS);
assert!(stored_epoch < end_epoch(&storage), ERROR_RESOURCE_BOUNDS);
assert!(stored_epoch >= start_epoch(&storage), EResourceBounds);
assert!(stored_epoch < end_epoch(&storage), EResourceBounds);

// check that the encoded size is less than the storage size
let encoded_size = encoding::encoded_blob_length(
size,
erasure_code_type,
system::n_shards(sys)
sys.n_shards(),
);
assert!(encoded_size <= storage_size(&storage), ERROR_RESOURCE_SIZE);
assert!(encoded_size <= storage_size(&storage), EResourceSize);

// Cryptographically verify that the Blob ID authenticates
// both the size and fe_type.
assert!(derive_blob_id(root_hash, erasure_code_type, size) == blob_id,
ERROR_INVALID_BLOB_ID);

assert!(
derive_blob_id(root_hash, erasure_code_type, size) == blob_id,
EInvalidBlobId,
);

// Emit register event
emit_blob_registered(
Expand All @@ -141,10 +141,9 @@ module blob_store::blob {
size,
//
erasure_code_type,
certified: option::none(),
certified_epoch: option::none(),
storage,
}

}

public struct CertifiedBlobMessage has drop {
Expand All @@ -154,28 +153,21 @@ module blob_store::blob {

/// Construct the certified blob message, note that constructing
/// implies a certified message, that is already checked.
public fun certify_blob_message(
message: CertifiedMessage
) : CertifiedBlobMessage {

public fun certify_blob_message(message: CertifiedMessage): CertifiedBlobMessage {
// Assert type is correct
assert!(committee::intent_type(&message) == BLOB_CERT_MSG_TYPE,
ERROR_INVALID_MSG_TYPE);
assert!(message.intent_type() == BLOB_CERT_MSG_TYPE, EInvalidMsgType);

// The certified blob message contain a blob_id : u256
let epoch = committee::cert_epoch(&message);
let message_body = committee::into_message(message);
let epoch = message.cert_epoch();
let message_body = message.into_message();

let mut bcs_body = bcs::new(message_body);
let blob_id = bcs::peel_u256(&mut bcs_body);
let blob_id = bcs_body.peel_u256();

// On purpose we do not check that nothing is left in the message
// to allow in the future for extensibility.

CertifiedBlobMessage {
epoch,
blob_id,
}
CertifiedBlobMessage { epoch, blob_id }
}

/// Certify that a blob will be available in the storage system until the end epoch of the
Expand All @@ -184,22 +176,21 @@ module blob_store::blob {
sys: &System<WAL>,
message: CertifiedBlobMessage,
blob: &mut Blob,
){

) {
// Check that the blob is registered in the system
assert!(blob_id(blob) == message.blob_id, ERROR_INVALID_BLOB_ID);
assert!(blob_id(blob) == message.blob_id, EInvalidBlobId);

// Check that the blob is not already certified
assert!(!option::is_some(&blob.certified), ERROR_ALREADY_CERTIFIED);
assert!(!blob.certified_epoch.is_some(), EAlreadyCertified);

// Check that the message is from the current epoch
assert!(message.epoch == system::epoch(sys), ERROR_WRONG_EPOCH);
assert!(message.epoch == sys.epoch(), EWrongEpoch);

// Check that the storage in the blob is still valid
assert!(message.epoch < end_epoch(storage(blob)), ERROR_RESOURCE_BOUNDS);
assert!(message.epoch < end_epoch(storage(blob)), EResourceBounds);

// Mark the blob as certified
blob.certified = option::some(message.epoch);
blob.certified_epoch = option::some(message.epoch);

// Emit certified event
emit_blob_certified(
Expand All @@ -219,23 +210,19 @@ module blob_store::blob {
message: vector<u8>,
) {
let certified_msg = committee::verify_quorum_in_epoch(
system::current_committee(sys),
sys.current_committee(),
signature,
members,
message
message,
);
let certified_blob_msg = certify_blob_message(certified_msg);
certify_with_certified_msg(sys, certified_blob_msg, blob);
}

/// After the period of validity expires for the blob we can destroy the blob resource.
public fun destroy_blob<WAL>(
sys: &System<WAL>,
blob: Blob,
){

let current_epoch = system::epoch(sys);
assert!(current_epoch >= end_epoch(storage(&blob)), ERROR_RESOURCE_BOUNDS);
public fun destroy_blob<WAL>(sys: &System<WAL>, blob: Blob) {
let current_epoch = sys.epoch();
assert!(current_epoch >= end_epoch(storage(&blob)), EResourceBounds);

// Destroy the blob
let Blob {
Expand All @@ -244,50 +231,45 @@ module blob_store::blob {
blob_id: _,
size: _,
erasure_code_type: _,
certified: _,
certified_epoch: _,
storage,
} = blob;

object::delete(id);
id.delete();
destroy(storage);
}

/// Extend the period of validity of a blob with a new storage resource.
/// The new storage resource must be the same size as the storage resource
/// used in the blob, and have a longer period of validity.
public fun extend<WAL>(
sys: &System<WAL>,
blob: &mut Blob,
extension: Storage){

public fun extend<WAL>(sys: &System<WAL>, blob: &mut Blob, extension: Storage) {
// We only extend certified blobs within their period of validity
// with storage that extends this period. First we check for these
// conditions.

// Assert this is a certified blob
assert!(option::is_some(&blob.certified), ERROR_NOT_CERTIFIED);
assert!(blob.certified_epoch.is_some(), ENotCertified);

// Check the blob is within its availability period
assert!(system::epoch(sys) < end_epoch(storage(blob)), ERROR_RESOURCE_BOUNDS);
assert!(sys.epoch() < end_epoch(storage(blob)), EResourceBounds);

// Check that the extension is valid, and the end
// period of the extension is after the current period.
assert!(end_epoch(&extension) > end_epoch(storage(blob)), ERROR_RESOURCE_BOUNDS);
assert!(end_epoch(&extension) > end_epoch(storage(blob)), EResourceBounds);

// Note: if the amounts do not match there will be an abort here.
fuse_periods(&mut blob.storage , extension);
fuse_periods(&mut blob.storage, extension);

// Emit certified event
//
// Note: We use the original certified period since for the purposes of
// reconfiguration this is the committee that has a quorum that hold the
// resource.
emit_blob_certified(
*option::borrow(&blob.certified),
*option::borrow(&blob.certified_epoch),
blob.blob_id,
end_epoch(storage(blob)),
);

}

// Testing Functions
Expand All @@ -301,29 +283,22 @@ module blob_store::blob {
blob_id: _,
size: _,
erasure_code_type: _,
certified: _,
certified_epoch: _,
storage,
} = b;

object::delete(id);
id.delete();
destroy(storage);
}

#[test_only]
// Accessor for blob
public fun message_blob_id(m: &CertifiedBlobMessage) : u256 {
public fun message_blob_id(m: &CertifiedBlobMessage): u256 {
m.blob_id
}

#[test_only]
public fun certified_blob_message_for_testing(
epoch: u64,
blob_id: u256,
) : CertifiedBlobMessage {
CertifiedBlobMessage {
epoch,
blob_id,
}
public fun certified_blob_message_for_testing(epoch: u64, blob_id: u256): CertifiedBlobMessage {
CertifiedBlobMessage { epoch, blob_id }
}

}
Loading

0 comments on commit eba7c02

Please sign in to comment.