From 120921cc05353d126e5309fa5e4df67f1439881d Mon Sep 17 00:00:00 2001 From: TomL94 Date: Mon, 17 Apr 2023 19:17:49 +0300 Subject: [PATCH 01/51] Implement accessing store directly through the iavl in cGet --- go-cosmwasm/api/callbacks.go | 41 ++++++++++++++-------------------- go-cosmwasm/api/lib.go | 7 +++--- go-cosmwasm/api/store.go | 43 ++++++++++++++++++++++++++++++++++++ go-cosmwasm/lib.go | 2 +- go.mod | 2 +- go.sum | 4 ++-- third_party/build/Cargo.toml | 2 +- 7 files changed, 68 insertions(+), 33 deletions(-) create mode 100644 go-cosmwasm/api/store.go diff --git a/go-cosmwasm/api/callbacks.go b/go-cosmwasm/api/callbacks.go index 4ce92d011..477592681 100644 --- a/go-cosmwasm/api/callbacks.go +++ b/go-cosmwasm/api/callbacks.go @@ -44,6 +44,7 @@ import ( dbm "github.com/tendermint/tm-db" + sdk "github.com/cosmos/cosmos-sdk/types" "github.com/scrtlabs/SecretNetwork/go-cosmwasm/types" ) @@ -88,25 +89,6 @@ type GasMeter interface { /****** DB ********/ -// KVStore copies a subset of types from cosmos-sdk -// We may wish to make this more generic sometime in the future, but not now -// https://github.com/cosmos/cosmos-sdk/blob/bef3689245bab591d7d169abd6bea52db97a70c7/store/types/store.go#L170 -type KVStore interface { - Get(key []byte) []byte - Set(key, value []byte) - Delete(key []byte) - - // Iterator over a domain of keys in ascending order. End is exclusive. - // Start must be less than end, or the Iterator is invalid. - // Iterator must be closed by caller. - // To iterate over entire domain, use store.Iterator(nil, nil) - Iterator(start, end []byte) dbm.Iterator - - // Iterator over a domain of keys in descending order. End is exclusive. - // Start must be less than end, or the Iterator is invalid. - // Iterator must be closed by caller. - ReverseIterator(start, end []byte) dbm.Iterator -} var db_vtable = C.DB_vtable{ read_db: (C.read_db_fn)(C.cGet_cgo), @@ -116,7 +98,7 @@ var db_vtable = C.DB_vtable{ } type DBState struct { - Store KVStore + Store sdk.KVStore // IteratorStackID is used to lookup the proper stack frame for iterators associated with this DB (iterator.go) IteratorStackID uint64 } @@ -126,7 +108,7 @@ type DBState struct { // state := buildDBState(kv, counter) // db := buildDB(&state, &gasMeter) // // then pass db into some FFI function -func buildDBState(kv KVStore, counter uint64) DBState { +func buildDBState(kv sdk.KVStore, counter uint64) DBState { return DBState{ Store: kv, IteratorStackID: counter, @@ -166,11 +148,20 @@ func cGet(ptr *C.db_t, gasMeter *C.gas_meter_t, usedGas *u64, key C.Buffer, val } gm := *(*GasMeter)(unsafe.Pointer(gasMeter)) - kv := *(*KVStore)(unsafe.Pointer(ptr)) + kv := *(*sdk.KVStore)(unsafe.Pointer(ptr)) k := receiveSlice(key) + iavl, err := getIavl(kv) + if err != nil { + return C.GoResult_Panic // Should add another error type + } + gasBefore := gm.GasConsumed() - v := kv.Get(k) + + // Need to pass the verified block_height to cGet + // getWithProof(kv, key, block_height) + + v := iavl.Get(k) gasAfter := gm.GasConsumed() *usedGas = (u64)(gasAfter - gasBefore) @@ -195,7 +186,7 @@ func cSet(ptr *C.db_t, gasMeter *C.gas_meter_t, usedGas *C.uint64_t, key C.Buffe } gm := *(*GasMeter)(unsafe.Pointer(gasMeter)) - kv := *(*KVStore)(unsafe.Pointer(ptr)) + kv := *(*sdk.KVStore)(unsafe.Pointer(ptr)) k := receiveSlice(key) v := receiveSlice(val) @@ -216,7 +207,7 @@ func cDelete(ptr *C.db_t, gasMeter *C.gas_meter_t, usedGas *C.uint64_t, key C.Bu } gm := *(*GasMeter)(unsafe.Pointer(gasMeter)) - kv := *(*KVStore)(unsafe.Pointer(ptr)) + kv := *(*sdk.KVStore)(unsafe.Pointer(ptr)) k := receiveSlice(key) gasBefore := gm.GasConsumed() diff --git a/go-cosmwasm/api/lib.go b/go-cosmwasm/api/lib.go index 74ea4f12b..a9e08db3a 100644 --- a/go-cosmwasm/api/lib.go +++ b/go-cosmwasm/api/lib.go @@ -12,6 +12,7 @@ import ( "runtime" "syscall" + sdk "github.com/cosmos/cosmos-sdk/types" v1types "github.com/scrtlabs/SecretNetwork/go-cosmwasm/types/v1" "github.com/scrtlabs/SecretNetwork/go-cosmwasm/types" @@ -159,7 +160,7 @@ func Instantiate( params []byte, msg []byte, gasMeter *GasMeter, - store KVStore, + store sdk.KVStore, api *GoAPI, querier *Querier, gasLimit uint64, @@ -205,7 +206,7 @@ func Handle( params []byte, msg []byte, gasMeter *GasMeter, - store KVStore, + store sdk.KVStore, api *GoAPI, querier *Querier, gasLimit uint64, @@ -251,7 +252,7 @@ func Query( params []byte, msg []byte, gasMeter *GasMeter, - store KVStore, + store sdk.KVStore, api *GoAPI, querier *Querier, gasLimit uint64, diff --git a/go-cosmwasm/api/store.go b/go-cosmwasm/api/store.go new file mode 100644 index 000000000..b053e40b0 --- /dev/null +++ b/go-cosmwasm/api/store.go @@ -0,0 +1,43 @@ +package api + +import ( + "fmt" + + "github.com/cosmos/cosmos-sdk/store/cache" + "github.com/cosmos/cosmos-sdk/store/iavl" + sdk "github.com/cosmos/cosmos-sdk/types" + abci "github.com/tendermint/tendermint/abci/types" +) + +type storeWithParent interface{ GetParent() sdk.KVStore } + +func getIavl(store sdk.KVStore) (*iavl.Store, error) { + switch st := store.(type) { + case storeWithParent: + return getIavl(st.GetParent()) + case *cache.CommitKVStoreCache: + return getIavl(st.CommitKVStore) + case *iavl.Store: + return st, nil + default: + return nil, fmt.Errorf("store type not supported: %+v", store) + } +} + +func getWithProof(store sdk.KVStore, key []byte, blockHeight int64) (value []byte, proof []byte, err error) { + iavlStore, err := getIavl(store) + if err != nil { + return nil, nil, err + } + + // Query height is (current - 1) because we will probably not have a proof in + // the current height (assuming we're mid execution) + result := iavlStore.Query(abci.RequestQuery{Data: key, Path: "/key", Prove: true, Height: blockHeight - 1 /* NOTE!! this depends on what blockHeight we get here. if it's the verified one it's probably for the past block anyway, so no need to subtract 1 for the height*/}) + + // result.ProofOps.Ops should always contain only one proof + if len(result.ProofOps.Ops) != 1 { + return nil, nil, fmt.Errorf("error in retrieving proof for key: %+v, got: %+v", key, result.ProofOps.Ops) + } + + return result.Value, result.ProofOps.Ops[0].Data, nil +} diff --git a/go-cosmwasm/lib.go b/go-cosmwasm/lib.go index 9f14c0f0d..ff2db6ea4 100644 --- a/go-cosmwasm/lib.go +++ b/go-cosmwasm/lib.go @@ -18,7 +18,7 @@ type CodeHash []byte type WasmCode []byte // KVStore is a reference to some sub-kvstore that is valid for one instance of a code -type KVStore = api.KVStore +type KVStore = sdk.KVStore // GoAPI is a reference to some "precompiles", go callbacks type GoAPI = api.GoAPI diff --git a/go.mod b/go.mod index 2f411fca9..a8d6cfd39 100644 --- a/go.mod +++ b/go.mod @@ -5,7 +5,7 @@ go 1.19 replace ( // dragonberry github.com/confio/ics23/go => github.com/cosmos/cosmos-sdk/ics23/go v0.8.0 - github.com/cosmos/cosmos-sdk => github.com/scrtlabs/cosmos-sdk v0.45.12-secret-1.7 + github.com/cosmos/cosmos-sdk => github.com/scrtlabs/cosmos-sdk v0.45.13-0.20230417160222-a883328081ee // Fix OSX Ledger Connection Issues - Premerged https://github.com/cosmos/ledger-cosmos-go/pull/36/files github.com/cosmos/ledger-cosmos-go => github.com/chillyvee/ledger-cosmos-go v0.12.2 github.com/gogo/protobuf => github.com/regen-network/protobuf v1.3.3-alpha.regen.1 diff --git a/go.sum b/go.sum index 51c14e032..bebc32de7 100644 --- a/go.sum +++ b/go.sum @@ -696,8 +696,8 @@ github.com/ryanuber/columnize v0.0.0-20160712163229-9b3edd62028f/go.mod h1:sm1tb github.com/samuel/go-zookeeper v0.0.0-20190923202752-2cc03de413da/go.mod h1:gi+0XIa01GRL2eRQVjQkKGqKF3SF9vZR/HnPullcV2E= github.com/sasha-s/go-deadlock v0.3.1 h1:sqv7fDNShgjcaxkO0JNcOAlr8B9+cV5Ey/OB71efZx0= github.com/sasha-s/go-deadlock v0.3.1/go.mod h1:F73l+cr82YSh10GxyRI6qZiCgK64VaZjwesgfQ1/iLM= -github.com/scrtlabs/cosmos-sdk v0.45.12-secret-1.7 h1:817+U5L2eb3jO7eQ565cpx2r8PIAeDNv27a4iLgTRvA= -github.com/scrtlabs/cosmos-sdk v0.45.12-secret-1.7/go.mod h1:6n46SDUlhsl+a3+CaO1Xqb35CFxMqMdiouXnhZU2vvQ= +github.com/scrtlabs/cosmos-sdk v0.45.13-0.20230417160222-a883328081ee h1:2QL61KpMgIJGSy95kVjYRnv6CrwaEf4TUc7Uoj5quIk= +github.com/scrtlabs/cosmos-sdk v0.45.13-0.20230417160222-a883328081ee/go.mod h1:6n46SDUlhsl+a3+CaO1Xqb35CFxMqMdiouXnhZU2vvQ= github.com/scrtlabs/tendermint v1.7.1-secret h1:ESBUNKAe6ZUqlXr+AFXnXWbdUt2A1duXd+ekzgkfve4= github.com/scrtlabs/tendermint v1.7.1-secret/go.mod h1:BbUUE0SOvsNFRXQYgY88eo2wyHjbeWweoEG7vd90BaI= github.com/scrtlabs/tm-secret-enclave v1.7.1 h1:TkeF/1rGl1/UwM0AHTmhZhm3uO4edQsAq64Kr/1K22M= diff --git a/third_party/build/Cargo.toml b/third_party/build/Cargo.toml index 7652db7e7..cd3f49a01 100644 --- a/third_party/build/Cargo.toml +++ b/third_party/build/Cargo.toml @@ -8,4 +8,4 @@ edition = "2021" name = "eng_edl" [dependencies] -sgx_edl = { path = "../../third_party/incubator-teaclave-sgx-sdk/sgx_edl"} +sgx_edl = { path = "../../third_party/incubator-teaclave-sgx-sdk/sgx_edl" } From 2473772768dfdbca398fda4d66077aeea932f670 Mon Sep 17 00:00:00 2001 From: TomL94 Date: Tue, 18 Apr 2023 18:26:19 +0300 Subject: [PATCH 02/51] Add block_height to wasm3 context --- .../shared/contract-engine/src/contract_operations.rs | 5 +++++ cosmwasm/enclaves/shared/contract-engine/src/wasm3/mod.rs | 4 ++++ 2 files changed, 9 insertions(+) diff --git a/cosmwasm/enclaves/shared/contract-engine/src/contract_operations.rs b/cosmwasm/enclaves/shared/contract-engine/src/contract_operations.rs index 882ed9c16..b08b67cc8 100644 --- a/cosmwasm/enclaves/shared/contract-engine/src/contract_operations.rs +++ b/cosmwasm/enclaves/shared/contract-engine/src/contract_operations.rs @@ -133,6 +133,7 @@ pub fn init( query_depth, secret_msg.nonce, secret_msg.user_public_key, + base_env.0.block.height, base_env.0.block.time, )?; // let duration = start.elapsed(); @@ -300,6 +301,7 @@ pub fn handle( query_depth, secret_msg.nonce, secret_msg.user_public_key, + block_height, base_env.0.block.time, )?; @@ -424,6 +426,7 @@ pub fn query( query_depth, secret_msg.nonce, secret_msg.user_public_key, + base_env.0.block.height, base_env.0.block.time, )?; @@ -461,6 +464,7 @@ fn start_engine( query_depth: u32, nonce: IoNonce, user_public_key: Ed25519PublicKey, + block_height: u64, timestamp: u64, ) -> Result { crate::wasm3::Engine::new( @@ -473,6 +477,7 @@ fn start_engine( nonce, user_public_key, query_depth, + block_height, timestamp, ) } diff --git a/cosmwasm/enclaves/shared/contract-engine/src/wasm3/mod.rs b/cosmwasm/enclaves/shared/contract-engine/src/wasm3/mod.rs index 5a2d80bb6..be289778a 100644 --- a/cosmwasm/enclaves/shared/contract-engine/src/wasm3/mod.rs +++ b/cosmwasm/enclaves/shared/contract-engine/src/wasm3/mod.rs @@ -98,6 +98,7 @@ pub struct Context { user_public_key: Ed25519PublicKey, kv_cache: KvCache, last_error: Option, + block_height: u64, timestamp: u64, } @@ -197,6 +198,7 @@ impl Engine { user_nonce: IoNonce, user_public_key: Ed25519PublicKey, query_depth: u32, + block_height: u64, timestamp: u64, ) -> Result { let versioned_code = create_module_instance(contract_code, &gas_costs, operation)?; @@ -213,6 +215,7 @@ impl Engine { user_public_key, kv_cache, last_error: None, + block_height, timestamp, }; @@ -822,6 +825,7 @@ fn host_read_db( }, &mut context.kv_cache, &get_encryption_salt(context.timestamp), + context.block_height, ) .map_err(debug_err!("db_read failed to read key from storage"))?; context.use_gas_externally(used_gas); From c7492c0d173169a924e71cacd80d4ca7a44460f5 Mon Sep 17 00:00:00 2001 From: TomL94 Date: Tue, 18 Apr 2023 18:28:27 +0300 Subject: [PATCH 03/51] Add block_height to read_db ocall --- cosmwasm/enclaves/execute/Enclave.edl | 1 + .../enclaves/shared/contract-engine/src/db.rs | 45 ++++++++++++------- .../contract-engine/src/external/ocalls.rs | 1 + 3 files changed, 30 insertions(+), 17 deletions(-) diff --git a/cosmwasm/enclaves/execute/Enclave.edl b/cosmwasm/enclaves/execute/Enclave.edl index 2384821f3..4b3924cce 100644 --- a/cosmwasm/enclaves/execute/Enclave.edl +++ b/cosmwasm/enclaves/execute/Enclave.edl @@ -129,6 +129,7 @@ enclave { Ctx context, [out] UntrustedVmError* vm_error, [out] uint64_t* gas_used, + uint64_t block_height, [out] EnclaveBuffer* value, [in, count=key_len] const uint8_t* key, uintptr_t key_len diff --git a/cosmwasm/enclaves/shared/contract-engine/src/db.rs b/cosmwasm/enclaves/shared/contract-engine/src/db.rs index 4e3fafc9e..d2954666e 100644 --- a/cosmwasm/enclaves/shared/contract-engine/src/db.rs +++ b/cosmwasm/enclaves/shared/contract-engine/src/db.rs @@ -156,6 +156,7 @@ pub fn read_from_encrypted_state( has_write_permissions: bool, kv_cache: &mut KvCache, encryption_salt: &[u8], + block_height: u64, ) -> Result<(Option>, u64), WasmEngineError> { // Try reading with the new encryption format let encrypted_key = EncryptedKey { @@ -168,7 +169,11 @@ pub fn read_from_encrypted_state( let mut maybe_plaintext_value: Option>; let gas_used_first_read: u64; - (maybe_plaintext_value, gas_used_first_read) = match read_db(context, &encrypted_key_bytes) { + (maybe_plaintext_value, gas_used_first_read) = match read_db( + context, + &encrypted_key_bytes, + block_height, + ) { Ok((maybe_encrypted_value_bytes, gas_used)) => match maybe_encrypted_value_bytes { Some(encrypted_value_bytes) => { let encrypted_value: EncryptedValue = bincode2::deserialize(&encrypted_value_bytes).map_err(|err| { @@ -211,23 +216,24 @@ pub fn read_from_encrypted_state( ); let gas_used_second_read: u64; - (maybe_plaintext_value, gas_used_second_read) = match read_db(context, &scrambled_field_name) { - Ok((encrypted_value, gas_used)) => match encrypted_value { - Some(plaintext_value) => { - match decrypt_value_old(&scrambled_field_name, &plaintext_value, contract_key) { - Ok(plaintext_value) => { - let _ = kv_cache.store_in_ro_cache(plaintext_key, &plaintext_value); - Ok((Some(plaintext_value), gas_used)) + (maybe_plaintext_value, gas_used_second_read) = + match read_db(context, &scrambled_field_name, block_height) { + Ok((encrypted_value, gas_used)) => match encrypted_value { + Some(plaintext_value) => { + match decrypt_value_old(&scrambled_field_name, &plaintext_value, contract_key) { + Ok(plaintext_value) => { + let _ = kv_cache.store_in_ro_cache(plaintext_key, &plaintext_value); + Ok((Some(plaintext_value), gas_used)) + } + // This error case is why we have all the matches here. + // If we successfully collected a value, but failed to decrypt it, then we propagate that error. + Err(err) => Err(err), } - // This error case is why we have all the matches here. - // If we successfully collected a value, but failed to decrypt it, then we propagate that error. - Err(err) => Err(err), } - } - None => Ok((None, gas_used)), - }, - Err(err) => Err(err), - }?; + None => Ok((None, gas_used)), + }, + Err(err) => Err(err), + }?; let mut gas_used_write: u64 = 0; if has_write_permissions { @@ -298,7 +304,11 @@ fn field_name_digest(field_name: &[u8], contract_key: &ContractKey) -> [u8; 32] } /// Safe wrapper around reads from the contract storage -fn read_db(context: &Ctx, key: &[u8]) -> Result<(Option>, u64), WasmEngineError> { +fn read_db( + context: &Ctx, + key: &[u8], + block_height: u64, +) -> Result<(Option>, u64), WasmEngineError> { let mut ocall_return = OcallReturn::Success; let mut enclave_buffer = std::mem::MaybeUninit::::uninit(); let mut vm_err = UntrustedVmError::default(); @@ -310,6 +320,7 @@ fn read_db(context: &Ctx, key: &[u8]) -> Result<(Option>, u64), WasmEngi context.unsafe_clone(), (&mut vm_err) as *mut _, (&mut gas_used) as *mut _, + block_height, enclave_buffer.as_mut_ptr(), key.as_ptr(), key.len(), diff --git a/cosmwasm/enclaves/shared/contract-engine/src/external/ocalls.rs b/cosmwasm/enclaves/shared/contract-engine/src/external/ocalls.rs index 53b81884b..7a32e28bf 100644 --- a/cosmwasm/enclaves/shared/contract-engine/src/external/ocalls.rs +++ b/cosmwasm/enclaves/shared/contract-engine/src/external/ocalls.rs @@ -15,6 +15,7 @@ extern "C" { context: Ctx, vm_error: *mut UntrustedVmError, gas_used: *mut u64, + block_height: u64, value: *mut EnclaveBuffer, key: *const u8, key_len: usize, From 445a78fa6c1629c029ad5aa412d8ce3f75f5b9cf Mon Sep 17 00:00:00 2001 From: TomL94 Date: Tue, 18 Apr 2023 18:30:24 +0300 Subject: [PATCH 04/51] Update the read_db api on go-cosmwasm --- go-cosmwasm/api/bindings.h | 2 +- go-cosmwasm/api/callbacks.go | 12 +++++------- go-cosmwasm/api/callbacks_cgo.go | 6 +++--- go-cosmwasm/src/db.rs | 2 ++ 4 files changed, 11 insertions(+), 11 deletions(-) diff --git a/go-cosmwasm/api/bindings.h b/go-cosmwasm/api/bindings.h index 7158efc50..79754cb49 100644 --- a/go-cosmwasm/api/bindings.h +++ b/go-cosmwasm/api/bindings.h @@ -104,7 +104,7 @@ typedef struct GoIter { } GoIter; typedef struct DB_vtable { - int32_t (*read_db)(db_t*, gas_meter_t*, uint64_t*, Buffer, Buffer*, Buffer*); + int32_t (*read_db)(db_t*, gas_meter_t*, uint64_t*, uint64_t, Buffer, Buffer*, Buffer*); int32_t (*write_db)(db_t*, gas_meter_t*, uint64_t*, Buffer, Buffer, Buffer*); int32_t (*remove_db)(db_t*, gas_meter_t*, uint64_t*, Buffer, Buffer*); int32_t (*scan_db)(db_t*, gas_meter_t*, uint64_t*, Buffer, Buffer, int32_t, GoIter*, Buffer*); diff --git a/go-cosmwasm/api/callbacks.go b/go-cosmwasm/api/callbacks.go index 477592681..867aba67e 100644 --- a/go-cosmwasm/api/callbacks.go +++ b/go-cosmwasm/api/callbacks.go @@ -89,7 +89,6 @@ type GasMeter interface { /****** DB ********/ - var db_vtable = C.DB_vtable{ read_db: (C.read_db_fn)(C.cGet_cgo), write_db: (C.write_db_fn)(C.cSet_cgo), @@ -140,7 +139,7 @@ func buildIterator(dbCounter uint64, it dbm.Iterator) C.iterator_t { } //export cGet -func cGet(ptr *C.db_t, gasMeter *C.gas_meter_t, usedGas *u64, key C.Buffer, val *C.Buffer, errOut *C.Buffer) (ret C.GoResult) { +func cGet(ptr *C.db_t, gasMeter *C.gas_meter_t, usedGas *u64, block_height u64, key C.Buffer, val *C.Buffer, errOut *C.Buffer) (ret C.GoResult) { defer recoverPanic(&ret) if ptr == nil || gasMeter == nil || usedGas == nil || val == nil { // we received an invalid pointer @@ -151,15 +150,14 @@ func cGet(ptr *C.db_t, gasMeter *C.gas_meter_t, usedGas *u64, key C.Buffer, val kv := *(*sdk.KVStore)(unsafe.Pointer(ptr)) k := receiveSlice(key) - iavl, err := getIavl(kv) - if err != nil { - return C.GoResult_Panic // Should add another error type - } - gasBefore := gm.GasConsumed() // Need to pass the verified block_height to cGet // getWithProof(kv, key, block_height) + iavl, err := getIavl(kv) + if err != nil { + return C.GoResult_Panic // Should add another error type + } v := iavl.Get(k) gasAfter := gm.GasConsumed() diff --git a/go-cosmwasm/api/callbacks_cgo.go b/go-cosmwasm/api/callbacks_cgo.go index b208d21d3..020e1b3d7 100644 --- a/go-cosmwasm/api/callbacks_cgo.go +++ b/go-cosmwasm/api/callbacks_cgo.go @@ -9,7 +9,7 @@ package api // imports (db) GoResult cSet(db_t *ptr, gas_meter_t *gas_meter, uint64_t *used_gas, Buffer key, Buffer val, Buffer *errOut); -GoResult cGet(db_t *ptr, gas_meter_t *gas_meter, uint64_t *used_gas, Buffer key, Buffer *val, Buffer *errOut); +GoResult cGet(db_t *ptr, gas_meter_t *gas_meter, uint64_t *used_gas, uint64_t block_height, Buffer key, Buffer *val, Buffer *errOut); GoResult cDelete(db_t *ptr, gas_meter_t *gas_meter, uint64_t *used_gas, Buffer key, Buffer *errOut); GoResult cScan(db_t *ptr, gas_meter_t *gas_meter, uint64_t *used_gas, Buffer start, Buffer end, int32_t order, GoIter *out, Buffer *errOut); // imports (iterator) @@ -21,8 +21,8 @@ GoResult cCanonicalAddress(api_t *ptr, Buffer human, Buffer *canon, Buffer *errO GoResult cQueryExternal(querier_t *ptr, uint64_t gas_limit, uint64_t *used_gas, Buffer request, uint32_t query_depth, Buffer *result, Buffer *errOut); // Gateway functions (db) -GoResult cGet_cgo(db_t *ptr, gas_meter_t *gas_meter, uint64_t *used_gas, Buffer key, Buffer *val, Buffer *errOut) { - return cGet(ptr, gas_meter, used_gas, key, val, errOut); +GoResult cGet_cgo(db_t *ptr, gas_meter_t *gas_meter, uint64_t *used_gas, uint64_t block_height, Buffer key, Buffer *val, Buffer *errOut) { + return cGet(ptr, gas_meter, used_gas, block_height, key, val, errOut); } GoResult cSet_cgo(db_t *ptr, gas_meter_t *gas_meter, uint64_t *used_gas, Buffer key, Buffer val, Buffer *errOut) { return cSet(ptr, gas_meter, used_gas, key, val, errOut); diff --git a/go-cosmwasm/src/db.rs b/go-cosmwasm/src/db.rs index c5b5ee441..e26231dfc 100644 --- a/go-cosmwasm/src/db.rs +++ b/go-cosmwasm/src/db.rs @@ -19,6 +19,7 @@ pub struct DB_vtable { *mut db_t, *mut gas_meter_t, *mut u64, + u64, Buffer, *mut Buffer, *mut Buffer, @@ -58,6 +59,7 @@ impl Storage for DB { self.state, self.gas_meter, &mut used_gas as *mut u64, + 0, key_buf, &mut result_buf as *mut Buffer, &mut err as *mut Buffer, From 330ba59b280a4b6fa6395e17f653a364e05f1276 Mon Sep 17 00:00:00 2001 From: TomL94 Date: Tue, 18 Apr 2023 19:32:57 +0300 Subject: [PATCH 05/51] Try to fix the cgo interface --- .../enclaves/shared/contract-engine/src/db.rs | 2 ++ go-cosmwasm/api/callbacks.go | 17 ++++++++++++----- go-cosmwasm/api/callbacks_cgo_mock.go | 2 +- go-cosmwasm/api/callbacks_mock.go | 4 ++-- 4 files changed, 17 insertions(+), 8 deletions(-) diff --git a/cosmwasm/enclaves/shared/contract-engine/src/db.rs b/cosmwasm/enclaves/shared/contract-engine/src/db.rs index d2954666e..101e86c2c 100644 --- a/cosmwasm/enclaves/shared/contract-engine/src/db.rs +++ b/cosmwasm/enclaves/shared/contract-engine/src/db.rs @@ -169,6 +169,7 @@ pub fn read_from_encrypted_state( let mut maybe_plaintext_value: Option>; let gas_used_first_read: u64; + debug!("TOMMM contract_engine::db.rs before read_db"); (maybe_plaintext_value, gas_used_first_read) = match read_db( context, &encrypted_key_bytes, @@ -314,6 +315,7 @@ fn read_db( let mut vm_err = UntrustedVmError::default(); let mut gas_used = 0_u64; + debug!("TOMMM contract-engine::db.rs before ocall_read_db"); let value = unsafe { let status = ocalls::ocall_read_db( (&mut ocall_return) as *mut _, diff --git a/go-cosmwasm/api/callbacks.go b/go-cosmwasm/api/callbacks.go index 867aba67e..63c182dad 100644 --- a/go-cosmwasm/api/callbacks.go +++ b/go-cosmwasm/api/callbacks.go @@ -7,7 +7,7 @@ package api #include "bindings.h" // typedefs for _cgo functions (db) -typedef GoResult (*read_db_fn)(db_t *ptr, gas_meter_t *gas_meter, uint64_t *used_gas, Buffer key, Buffer *val, Buffer *errOut); +typedef GoResult (*read_db_fn)(db_t *ptr, gas_meter_t *gas_meter, uint64_t *used_gas, uint64_t block_height, Buffer key, Buffer *val, Buffer *errOut); typedef GoResult (*write_db_fn)(db_t *ptr, gas_meter_t *gas_meter, uint64_t *used_gas, Buffer key, Buffer val, Buffer *errOut); typedef GoResult (*remove_db_fn)(db_t *ptr, gas_meter_t *gas_meter, uint64_t *used_gas, Buffer key, Buffer *errOut); typedef GoResult (*scan_db_fn)(db_t *ptr, gas_meter_t *gas_meter, uint64_t *used_gas, Buffer start, Buffer end, int32_t order, GoIter *out, Buffer *errOut); @@ -19,7 +19,7 @@ typedef GoResult (*canonicalize_address_fn)(api_t *ptr, Buffer human, Buffer *ca typedef GoResult (*query_external_fn)(querier_t *ptr, uint64_t gas_limit, uint64_t *used_gas, Buffer request, uint32_t query_depth, Buffer *result, Buffer *errOut); // forward declarations (db) -GoResult cGet_cgo(db_t *ptr, gas_meter_t *gas_meter, uint64_t *used_gas, Buffer key, Buffer *val, Buffer *errOut); +GoResult cGet_cgo(db_t *ptr, gas_meter_t *gas_meter, uint64_t *used_gas, uint64_t block_height, Buffer key, Buffer *val, Buffer *errOut); GoResult cSet_cgo(db_t *ptr, gas_meter_t *gas_meter, uint64_t *used_gas, Buffer key, Buffer val, Buffer *errOut); GoResult cDelete_cgo(db_t *ptr, gas_meter_t *gas_meter, uint64_t *used_gas, Buffer key, Buffer *errOut); GoResult cScan_cgo(db_t *ptr, gas_meter_t *gas_meter, uint64_t *used_gas, Buffer start, Buffer end, int32_t order, GoIter *out, Buffer *errOut); @@ -140,6 +140,7 @@ func buildIterator(dbCounter uint64, it dbm.Iterator) C.iterator_t { //export cGet func cGet(ptr *C.db_t, gasMeter *C.gas_meter_t, usedGas *u64, block_height u64, key C.Buffer, val *C.Buffer, errOut *C.Buffer) (ret C.GoResult) { + println("TOMMM inside cGet") defer recoverPanic(&ret) if ptr == nil || gasMeter == nil || usedGas == nil || val == nil { // we received an invalid pointer @@ -154,12 +155,18 @@ func cGet(ptr *C.db_t, gasMeter *C.gas_meter_t, usedGas *u64, block_height u64, // Need to pass the verified block_height to cGet // getWithProof(kv, key, block_height) - iavl, err := getIavl(kv) + // iavl, err := getIavl(kv) + // if err != nil { + // return C.GoResult_Panic // Should add another error type + // } + + v, proof, err := getWithProof(kv, k, int64(block_height)) if err != nil { - return C.GoResult_Panic // Should add another error type + return C.GoResult_Panic } + fmt.Printf("TOMMM proof: %+v", proof) - v := iavl.Get(k) + // v := iavl.Get(k) gasAfter := gm.GasConsumed() *usedGas = (u64)(gasAfter - gasBefore) diff --git a/go-cosmwasm/api/callbacks_cgo_mock.go b/go-cosmwasm/api/callbacks_cgo_mock.go index cafb234be..1a544d136 100644 --- a/go-cosmwasm/api/callbacks_cgo_mock.go +++ b/go-cosmwasm/api/callbacks_cgo_mock.go @@ -10,7 +10,7 @@ package api // //// imports (db) //GoResult cSet(db_t *ptr, gas_meter_t *gas_meter, uint64_t *used_gas, Buffer key, Buffer val); -//GoResult cGet(db_t *ptr, gas_meter_t *gas_meter, uint64_t *used_gas, Buffer key, Buffer *val); +//GoResult cGet(db_t *ptr, gas_meter_t *gas_meter, uint64_t *used_gas, uint64_t block_height, Buffer key, Buffer *val); //GoResult cDelete(db_t *ptr, gas_meter_t *gas_meter, uint64_t *used_gas, Buffer key); //GoResult cScan(db_t *ptr, gas_meter_t *gas_meter, uint64_t *used_gas, Buffer start, Buffer end, int32_t order, GoIter *out); //// imports (iterator) diff --git a/go-cosmwasm/api/callbacks_mock.go b/go-cosmwasm/api/callbacks_mock.go index 5380f08f3..b954138c8 100644 --- a/go-cosmwasm/api/callbacks_mock.go +++ b/go-cosmwasm/api/callbacks_mock.go @@ -7,7 +7,7 @@ package api // #include "bindings.h" // // // typedefs for _cgo functions (db) -// typedef GoResult (*read_db_fn)(db_t *ptr, gas_meter_t *gas_meter, uint64_t *used_gas, Buffer key, Buffer *val); +// typedef GoResult (*read_db_fn)(db_t *ptr, gas_meter_t *gas_meter, uint64_t *used_gas, uint64_t block_height, Buffer key, Buffer *val); // typedef GoResult (*write_db_fn)(db_t *ptr, gas_meter_t *gas_meter, uint64_t *used_gas, Buffer key, Buffer val); // typedef GoResult (*remove_db_fn)(db_t *ptr, gas_meter_t *gas_meter, uint64_t *used_gas, Buffer key); // typedef GoResult (*scan_db_fn)(db_t *ptr, gas_meter_t *gas_meter, uint64_t *used_gas, Buffer start, Buffer end, int32_t order, GoIter *out); @@ -19,7 +19,7 @@ package api // typedef GoResult (*query_external_fn)(querier_t *ptr, uint64_t *used_gas, Buffer request, Buffer *result); // // // forward declarations (db) -// GoResult cGet_cgo(db_t *ptr, gas_meter_t *gas_meter, uint64_t *used_gas, Buffer key, Buffer *val); +// GoResult cGet_cgo(db_t *ptr, gas_meter_t *gas_meter, uint64_t *used_gas, uint64_t block_height, Buffer key, Buffer *val); // GoResult cSet_cgo(db_t *ptr, gas_meter_t *gas_meter, uint64_t *used_gas, Buffer key, Buffer val); // GoResult cDelete_cgo(db_t *ptr, gas_meter_t *gas_meter, uint64_t *used_gas, Buffer key); // GoResult cScan_cgo(db_t *ptr, gas_meter_t *gas_meter, uint64_t *used_gas, Buffer start, Buffer end, int32_t order, GoIter *out); From 49815a7bda90b1f479b9a899851741ef39c3ee72 Mon Sep 17 00:00:00 2001 From: TomL94 Date: Tue, 18 Apr 2023 20:07:06 +0300 Subject: [PATCH 06/51] Fix the ocall interface --- cosmwasm/packages/sgx-vm/src/wasmi/exports.rs | 1 + go-cosmwasm/api/callbacks.go | 7 ++++++- go-cosmwasm/api/callbacks_cgo_mock.go | 4 ++-- 3 files changed, 9 insertions(+), 3 deletions(-) diff --git a/cosmwasm/packages/sgx-vm/src/wasmi/exports.rs b/cosmwasm/packages/sgx-vm/src/wasmi/exports.rs index b7d589032..2fbbcbbdf 100644 --- a/cosmwasm/packages/sgx-vm/src/wasmi/exports.rs +++ b/cosmwasm/packages/sgx-vm/src/wasmi/exports.rs @@ -45,6 +45,7 @@ pub extern "C" fn ocall_read_db( context: Ctx, vm_error: *mut UntrustedVmError, gas_used: *mut u64, + _block_height: u64, value: *mut EnclaveBuffer, key: *const u8, key_len: usize, diff --git a/go-cosmwasm/api/callbacks.go b/go-cosmwasm/api/callbacks.go index 63c182dad..b6c3ea48b 100644 --- a/go-cosmwasm/api/callbacks.go +++ b/go-cosmwasm/api/callbacks.go @@ -140,17 +140,21 @@ func buildIterator(dbCounter uint64, it dbm.Iterator) C.iterator_t { //export cGet func cGet(ptr *C.db_t, gasMeter *C.gas_meter_t, usedGas *u64, block_height u64, key C.Buffer, val *C.Buffer, errOut *C.Buffer) (ret C.GoResult) { - println("TOMMM inside cGet") + println("TOMMM inside cGet1") + fmt.Printf("TOMMM block height: %d\n", block_height) defer recoverPanic(&ret) if ptr == nil || gasMeter == nil || usedGas == nil || val == nil { // we received an invalid pointer return C.GoResult_BadArgument } + println("TOMMM inside cGet2") gm := *(*GasMeter)(unsafe.Pointer(gasMeter)) kv := *(*sdk.KVStore)(unsafe.Pointer(ptr)) k := receiveSlice(key) + println("TOMMM inside cGet3") + gasBefore := gm.GasConsumed() // Need to pass the verified block_height to cGet @@ -159,6 +163,7 @@ func cGet(ptr *C.db_t, gasMeter *C.gas_meter_t, usedGas *u64, block_height u64, // if err != nil { // return C.GoResult_Panic // Should add another error type // } + println("TOMMM inside cGet4") v, proof, err := getWithProof(kv, k, int64(block_height)) if err != nil { diff --git a/go-cosmwasm/api/callbacks_cgo_mock.go b/go-cosmwasm/api/callbacks_cgo_mock.go index 1a544d136..987fadf4e 100644 --- a/go-cosmwasm/api/callbacks_cgo_mock.go +++ b/go-cosmwasm/api/callbacks_cgo_mock.go @@ -22,8 +22,8 @@ package api //GoResult cQueryExternal(querier_t *ptr, uint64_t *used_gas, Buffer request, Buffer *result); // //// Gateway functions (db) -//GoResult cGet_cgo(db_t *ptr, gas_meter_t *gas_meter, uint64_t *used_gas, Buffer key, Buffer *val) { -// return cGet(ptr, gas_meter, used_gas, key, val); +//GoResult cGet_cgo(db_t *ptr, gas_meter_t *gas_meter, uint64_t *used_gas, uint64_t block_height, Buffer key, Buffer *val) { +// return cGet(ptr, gas_meter, used_gas, block_height, key, val); //} //GoResult cSet_cgo(db_t *ptr, gas_meter_t *gas_meter, uint64_t *used_gas, Buffer key, Buffer val) { // return cSet(ptr, gas_meter, used_gas, key, val); From c5b2953467231ce1594af81f363ee3feef9f959f Mon Sep 17 00:00:00 2001 From: Itzik Grossman Date: Mon, 24 Apr 2023 14:34:09 +0300 Subject: [PATCH 07/51] Fixed passing the height to the query --- cosmwasm/packages/sgx-vm/src/testing/storage.rs | 2 +- cosmwasm/packages/sgx-vm/src/traits.rs | 2 +- cosmwasm/packages/sgx-vm/src/wasmi/exports.rs | 16 +++++++++++----- go-cosmwasm/src/db.rs | 4 ++-- 4 files changed, 15 insertions(+), 9 deletions(-) diff --git a/cosmwasm/packages/sgx-vm/src/testing/storage.rs b/cosmwasm/packages/sgx-vm/src/testing/storage.rs index ef6e8eef6..0ff873e35 100644 --- a/cosmwasm/packages/sgx-vm/src/testing/storage.rs +++ b/cosmwasm/packages/sgx-vm/src/testing/storage.rs @@ -56,7 +56,7 @@ impl MockStorage { } impl Storage for MockStorage { - fn get(&self, key: &[u8]) -> FfiResult>> { + fn get(&self, _height: u64, key: &[u8]) -> FfiResult>> { let gas_info = GasInfo::with_externally_used(key.len() as u64); (Ok(self.data.get(key).cloned()), gas_info) } diff --git a/cosmwasm/packages/sgx-vm/src/traits.rs b/cosmwasm/packages/sgx-vm/src/traits.rs index 476a19a6a..52d55da24 100644 --- a/cosmwasm/packages/sgx-vm/src/traits.rs +++ b/cosmwasm/packages/sgx-vm/src/traits.rs @@ -69,7 +69,7 @@ where /// /// Note: Support for differentiating between a non-existent key and a key with empty value /// is not great yet and might not be possible in all backends. But we're trying to get there. - fn get(&self, key: &[u8]) -> FfiResult>>; + fn get(&self, height: u64, key: &[u8]) -> FfiResult>>; #[cfg(feature = "iterator")] /// Allows iteration over a set of key/value pairs, either forwards or backwards. diff --git a/cosmwasm/packages/sgx-vm/src/wasmi/exports.rs b/cosmwasm/packages/sgx-vm/src/wasmi/exports.rs index 2fbbcbbdf..185f83b6e 100644 --- a/cosmwasm/packages/sgx-vm/src/wasmi/exports.rs +++ b/cosmwasm/packages/sgx-vm/src/wasmi/exports.rs @@ -45,7 +45,7 @@ pub extern "C" fn ocall_read_db( context: Ctx, vm_error: *mut UntrustedVmError, gas_used: *mut u64, - _block_height: u64, + block_height: u64, value: *mut EnclaveBuffer, key: *const u8, key_len: usize, @@ -55,6 +55,7 @@ pub extern "C" fn ocall_read_db( context, vm_error, gas_used, + block_height, value, key, key_len, @@ -88,6 +89,7 @@ fn ocall_read_db_concrete( context: Ctx, vm_error: *mut UntrustedVmError, gas_used: *mut u64, + height: u64, value: *mut EnclaveBuffer, key: *const u8, key_len: usize, @@ -96,7 +98,7 @@ fn ocall_read_db_concrete( let implementation = unsafe { get_implementations_from_context(&context).read_db }; - std::panic::catch_unwind(|| implementation(context, key)) + std::panic::catch_unwind(|| implementation(context, height, key)) // Get either an error(`OcallReturn`), or a response(`EnclaveBuffer`) // which will be converted to a success status. .map(|result| -> Result { @@ -369,7 +371,7 @@ unsafe fn store_vm_error(vm_err: VmError, location: *mut UntrustedVmError) { /// appropriate for it. #[allow(clippy::type_complexity)] struct ExportImplementations { - read_db: fn(context: Ctx, key: &[u8]) -> VmResult<(Option>, u64)>, + read_db: fn(context: Ctx, height: u64, key: &[u8]) -> VmResult<(Option>, u64)>, query_chain: fn( context: Ctx, query: &[u8], @@ -425,13 +427,17 @@ unsafe fn get_implementations_from_context(context: &Ctx) -> &ExportImplementati &(*(context.data as *mut FullContext)).implementation } -fn ocall_read_db_impl(mut context: Ctx, key: &[u8]) -> VmResult<(Option>, u64)> +fn ocall_read_db_impl( + mut context: Ctx, + height: u64, + key: &[u8], +) -> VmResult<(Option>, u64)> where S: Storage, Q: Querier, { with_storage_from_context::(&mut context, |storage: &mut S| { - let (ffi_result, gas_info) = storage.get(key); + let (ffi_result, gas_info) = storage.get(height, key); ffi_result .map(|value| (value, gas_info.externally_used)) .map_err(Into::into) diff --git a/go-cosmwasm/src/db.rs b/go-cosmwasm/src/db.rs index e26231dfc..fc745dbee 100644 --- a/go-cosmwasm/src/db.rs +++ b/go-cosmwasm/src/db.rs @@ -50,7 +50,7 @@ pub struct DB { } impl Storage for DB { - fn get(&self, key: &[u8]) -> FfiResult>> { + fn get(&self, height: u64, key: &[u8]) -> FfiResult>> { let key_buf = Buffer::from_vec(key.to_vec()); let mut result_buf = Buffer::default(); let mut err = Buffer::default(); @@ -59,7 +59,7 @@ impl Storage for DB { self.state, self.gas_meter, &mut used_gas as *mut u64, - 0, + height, key_buf, &mut result_buf as *mut Buffer, &mut err as *mut Buffer, From e457e4b26112cbcb4ab0cdf5a68701952966e771 Mon Sep 17 00:00:00 2001 From: TomL94 Date: Thu, 18 May 2023 14:32:15 +0300 Subject: [PATCH 08/51] Fix querying directly from iavl for prefix store --- go-cosmwasm/api/callbacks.go | 2 +- go-cosmwasm/api/store.go | 17 ++++++++++------- go.mod | 2 +- go.sum | 4 ++-- 4 files changed, 14 insertions(+), 11 deletions(-) diff --git a/go-cosmwasm/api/callbacks.go b/go-cosmwasm/api/callbacks.go index b6c3ea48b..d3ccc5888 100644 --- a/go-cosmwasm/api/callbacks.go +++ b/go-cosmwasm/api/callbacks.go @@ -169,7 +169,7 @@ func cGet(ptr *C.db_t, gasMeter *C.gas_meter_t, usedGas *u64, block_height u64, if err != nil { return C.GoResult_Panic } - fmt.Printf("TOMMM proof: %+v", proof) + fmt.Printf("TOMMM proof: %+v\n", proof) // v := iavl.Get(k) gasAfter := gm.GasConsumed() diff --git a/go-cosmwasm/api/store.go b/go-cosmwasm/api/store.go index b053e40b0..1b51b2c70 100644 --- a/go-cosmwasm/api/store.go +++ b/go-cosmwasm/api/store.go @@ -5,34 +5,37 @@ import ( "github.com/cosmos/cosmos-sdk/store/cache" "github.com/cosmos/cosmos-sdk/store/iavl" + "github.com/cosmos/cosmos-sdk/store/prefix" sdk "github.com/cosmos/cosmos-sdk/types" abci "github.com/tendermint/tendermint/abci/types" ) type storeWithParent interface{ GetParent() sdk.KVStore } -func getIavl(store sdk.KVStore) (*iavl.Store, error) { +func getInnerIavl(store sdk.KVStore, key []byte) (iavlStore *iavl.Store, fullKey []byte, err error) { switch st := store.(type) { + case prefix.Store: // Special case for a prefix store to get the prefixed key + return getInnerIavl(st.GetParent(), st.Key(key)) case storeWithParent: - return getIavl(st.GetParent()) + return getInnerIavl(st.GetParent(), key) case *cache.CommitKVStoreCache: - return getIavl(st.CommitKVStore) + return getInnerIavl(st.CommitKVStore, key) case *iavl.Store: - return st, nil + return st, key, nil default: - return nil, fmt.Errorf("store type not supported: %+v", store) + return nil, nil, fmt.Errorf("store type not supported: %+v", store) } } func getWithProof(store sdk.KVStore, key []byte, blockHeight int64) (value []byte, proof []byte, err error) { - iavlStore, err := getIavl(store) + iavlStore, fullKey, err := getInnerIavl(store, key) if err != nil { return nil, nil, err } // Query height is (current - 1) because we will probably not have a proof in // the current height (assuming we're mid execution) - result := iavlStore.Query(abci.RequestQuery{Data: key, Path: "/key", Prove: true, Height: blockHeight - 1 /* NOTE!! this depends on what blockHeight we get here. if it's the verified one it's probably for the past block anyway, so no need to subtract 1 for the height*/}) + result := iavlStore.Query(abci.RequestQuery{Data: fullKey, Path: "/key", Prove: true, Height: blockHeight - 1 /* NOTE!! this depends on what blockHeight we get here. if it's the verified one it's probably for the past block anyway, so no need to subtract 1 for the height*/}) // result.ProofOps.Ops should always contain only one proof if len(result.ProofOps.Ops) != 1 { diff --git a/go.mod b/go.mod index a8d6cfd39..7e476db30 100644 --- a/go.mod +++ b/go.mod @@ -5,7 +5,7 @@ go 1.19 replace ( // dragonberry github.com/confio/ics23/go => github.com/cosmos/cosmos-sdk/ics23/go v0.8.0 - github.com/cosmos/cosmos-sdk => github.com/scrtlabs/cosmos-sdk v0.45.13-0.20230417160222-a883328081ee + github.com/cosmos/cosmos-sdk => github.com/scrtlabs/cosmos-sdk v0.45.13-0.20230518112707-1b9278476b3a // Fix OSX Ledger Connection Issues - Premerged https://github.com/cosmos/ledger-cosmos-go/pull/36/files github.com/cosmos/ledger-cosmos-go => github.com/chillyvee/ledger-cosmos-go v0.12.2 github.com/gogo/protobuf => github.com/regen-network/protobuf v1.3.3-alpha.regen.1 diff --git a/go.sum b/go.sum index bebc32de7..77e32a999 100644 --- a/go.sum +++ b/go.sum @@ -696,8 +696,8 @@ github.com/ryanuber/columnize v0.0.0-20160712163229-9b3edd62028f/go.mod h1:sm1tb github.com/samuel/go-zookeeper v0.0.0-20190923202752-2cc03de413da/go.mod h1:gi+0XIa01GRL2eRQVjQkKGqKF3SF9vZR/HnPullcV2E= github.com/sasha-s/go-deadlock v0.3.1 h1:sqv7fDNShgjcaxkO0JNcOAlr8B9+cV5Ey/OB71efZx0= github.com/sasha-s/go-deadlock v0.3.1/go.mod h1:F73l+cr82YSh10GxyRI6qZiCgK64VaZjwesgfQ1/iLM= -github.com/scrtlabs/cosmos-sdk v0.45.13-0.20230417160222-a883328081ee h1:2QL61KpMgIJGSy95kVjYRnv6CrwaEf4TUc7Uoj5quIk= -github.com/scrtlabs/cosmos-sdk v0.45.13-0.20230417160222-a883328081ee/go.mod h1:6n46SDUlhsl+a3+CaO1Xqb35CFxMqMdiouXnhZU2vvQ= +github.com/scrtlabs/cosmos-sdk v0.45.13-0.20230518112707-1b9278476b3a h1:nS/GwtIHyu30KFIGJU+IKdLJT+4mhn6Bk60SsmQgY10= +github.com/scrtlabs/cosmos-sdk v0.45.13-0.20230518112707-1b9278476b3a/go.mod h1:6n46SDUlhsl+a3+CaO1Xqb35CFxMqMdiouXnhZU2vvQ= github.com/scrtlabs/tendermint v1.7.1-secret h1:ESBUNKAe6ZUqlXr+AFXnXWbdUt2A1duXd+ekzgkfve4= github.com/scrtlabs/tendermint v1.7.1-secret/go.mod h1:BbUUE0SOvsNFRXQYgY88eo2wyHjbeWweoEG7vd90BaI= github.com/scrtlabs/tm-secret-enclave v1.7.1 h1:TkeF/1rGl1/UwM0AHTmhZhm3uO4edQsAq64Kr/1K22M= From d1c5cb151b6225ea943ae84dd676316c3a0f3582 Mon Sep 17 00:00:00 2001 From: TomL94 Date: Thu, 18 May 2023 17:27:04 +0300 Subject: [PATCH 09/51] Return proof all the way to the enclave --- cosmwasm/enclaves/execute/Enclave.edl | 1 + .../enclaves/shared/contract-engine/src/db.rs | 84 +++++++++++-------- .../contract-engine/src/external/ocalls.rs | 1 + .../packages/sgx-vm/src/testing/storage.rs | 4 +- cosmwasm/packages/sgx-vm/src/traits.rs | 2 +- cosmwasm/packages/sgx-vm/src/wasmi/exports.rs | 52 ++++++++---- go-cosmwasm/api/bindings.h | 2 +- go-cosmwasm/api/callbacks.go | 25 ++---- go-cosmwasm/api/callbacks_cgo.go | 6 +- go-cosmwasm/api/callbacks_cgo_mock.go | 6 +- go-cosmwasm/api/callbacks_mock.go | 4 +- go-cosmwasm/src/db.rs | 15 +++- 12 files changed, 118 insertions(+), 84 deletions(-) diff --git a/cosmwasm/enclaves/execute/Enclave.edl b/cosmwasm/enclaves/execute/Enclave.edl index 4b3924cce..ae73c5b9c 100644 --- a/cosmwasm/enclaves/execute/Enclave.edl +++ b/cosmwasm/enclaves/execute/Enclave.edl @@ -131,6 +131,7 @@ enclave { [out] uint64_t* gas_used, uint64_t block_height, [out] EnclaveBuffer* value, + [out] EnclaveBuffer* proof, [in, count=key_len] const uint8_t* key, uintptr_t key_len ) allow (ecall_allocate); diff --git a/cosmwasm/enclaves/shared/contract-engine/src/db.rs b/cosmwasm/enclaves/shared/contract-engine/src/db.rs index 101e86c2c..c77af91d2 100644 --- a/cosmwasm/enclaves/shared/contract-engine/src/db.rs +++ b/cosmwasm/enclaves/shared/contract-engine/src/db.rs @@ -169,15 +169,16 @@ pub fn read_from_encrypted_state( let mut maybe_plaintext_value: Option>; let gas_used_first_read: u64; - debug!("TOMMM contract_engine::db.rs before read_db"); (maybe_plaintext_value, gas_used_first_read) = match read_db( context, &encrypted_key_bytes, block_height, ) { - Ok((maybe_encrypted_value_bytes, gas_used)) => match maybe_encrypted_value_bytes { - Some(encrypted_value_bytes) => { - let encrypted_value: EncryptedValue = bincode2::deserialize(&encrypted_value_bytes).map_err(|err| { + Ok(((maybe_encrypted_value_bytes, maybe_proof), gas_used)) => { + debug!("merkle proof returned from read_db(): {:?}", maybe_proof); + match maybe_encrypted_value_bytes { + Some(encrypted_value_bytes) => { + let encrypted_value: EncryptedValue = bincode2::deserialize(&encrypted_value_bytes).map_err(|err| { warn!( "read_db() got an error while trying to read_from_encrypted_state the value {:?} for key {:?}, stopping wasm: {:?}", encrypted_value_bytes, @@ -187,20 +188,21 @@ pub fn read_from_encrypted_state( WasmEngineError::DecryptionError })?; - match decrypt_value_new( - &encrypted_key.data, - &encrypted_value.data, - contract_key, - &encrypted_value.salt, - ) { - Ok(plaintext_value) => Ok((Some(plaintext_value), gas_used)), - // This error case is why we have all the matches here. - // If we successfully collected a value, but failed to decrypt it, then we propagate that error. - Err(err) => Err(err), + match decrypt_value_new( + &encrypted_key.data, + &encrypted_value.data, + contract_key, + &encrypted_value.salt, + ) { + Ok(plaintext_value) => Ok((Some(plaintext_value), gas_used)), + // This error case is why we have all the matches here. + // If we successfully collected a value, but failed to decrypt it, then we propagate that error. + Err(err) => Err(err), + } } + None => Ok((None, gas_used)), } - None => Ok((None, gas_used)), - }, + } Err(err) => Err(err), }?; @@ -219,20 +221,27 @@ pub fn read_from_encrypted_state( let gas_used_second_read: u64; (maybe_plaintext_value, gas_used_second_read) = match read_db(context, &scrambled_field_name, block_height) { - Ok((encrypted_value, gas_used)) => match encrypted_value { - Some(plaintext_value) => { - match decrypt_value_old(&scrambled_field_name, &plaintext_value, contract_key) { - Ok(plaintext_value) => { - let _ = kv_cache.store_in_ro_cache(plaintext_key, &plaintext_value); - Ok((Some(plaintext_value), gas_used)) + Ok(((encrypted_value, proof), gas_used)) => { + debug!("proof returned from read_db(): {:?}", proof); + match encrypted_value { + Some(plaintext_value) => { + match decrypt_value_old( + &scrambled_field_name, + &plaintext_value, + contract_key, + ) { + Ok(plaintext_value) => { + let _ = kv_cache.store_in_ro_cache(plaintext_key, &plaintext_value); + Ok((Some(plaintext_value), gas_used)) + } + // This error case is why we have all the matches here. + // If we successfully collected a value, but failed to decrypt it, then we propagate that error. + Err(err) => Err(err), } - // This error case is why we have all the matches here. - // If we successfully collected a value, but failed to decrypt it, then we propagate that error. - Err(err) => Err(err), } + None => Ok((None, gas_used)), } - None => Ok((None, gas_used)), - }, + } Err(err) => Err(err), }?; @@ -309,21 +318,22 @@ fn read_db( context: &Ctx, key: &[u8], block_height: u64, -) -> Result<(Option>, u64), WasmEngineError> { +) -> Result<((Option>, Option>), u64), WasmEngineError> { let mut ocall_return = OcallReturn::Success; - let mut enclave_buffer = std::mem::MaybeUninit::::uninit(); + let mut value_buffer = std::mem::MaybeUninit::::uninit(); + let mut proof_buffer = std::mem::MaybeUninit::::uninit(); let mut vm_err = UntrustedVmError::default(); let mut gas_used = 0_u64; - debug!("TOMMM contract-engine::db.rs before ocall_read_db"); - let value = unsafe { + let (value, proof) = unsafe { let status = ocalls::ocall_read_db( (&mut ocall_return) as *mut _, context.unsafe_clone(), (&mut vm_err) as *mut _, (&mut gas_used) as *mut _, block_height, - enclave_buffer.as_mut_ptr(), + value_buffer.as_mut_ptr(), + proof_buffer.as_mut_ptr(), key.as_ptr(), key.len(), ); @@ -340,8 +350,12 @@ fn read_db( match ocall_return { OcallReturn::Success => { - let enclave_buffer = enclave_buffer.assume_init(); - ecalls::recover_buffer(enclave_buffer)? + let value_buffer = value_buffer.assume_init(); + let proof_buffer = proof_buffer.assume_init(); + ( + ecalls::recover_buffer(value_buffer)?, + ecalls::recover_buffer(proof_buffer)?, + ) } OcallReturn::Failure => { return Err(WasmEngineError::FailedOcall(vm_err)); @@ -350,7 +364,7 @@ fn read_db( } }; - Ok((value, gas_used)) + Ok(((value, proof), gas_used)) } /// Safe wrapper around reads from the contract storage diff --git a/cosmwasm/enclaves/shared/contract-engine/src/external/ocalls.rs b/cosmwasm/enclaves/shared/contract-engine/src/external/ocalls.rs index 7a32e28bf..049b3659d 100644 --- a/cosmwasm/enclaves/shared/contract-engine/src/external/ocalls.rs +++ b/cosmwasm/enclaves/shared/contract-engine/src/external/ocalls.rs @@ -17,6 +17,7 @@ extern "C" { gas_used: *mut u64, block_height: u64, value: *mut EnclaveBuffer, + proof: *mut EnclaveBuffer, key: *const u8, key_len: usize, ) -> sgx_status_t; diff --git a/cosmwasm/packages/sgx-vm/src/testing/storage.rs b/cosmwasm/packages/sgx-vm/src/testing/storage.rs index 0ff873e35..42d4dadf7 100644 --- a/cosmwasm/packages/sgx-vm/src/testing/storage.rs +++ b/cosmwasm/packages/sgx-vm/src/testing/storage.rs @@ -56,9 +56,9 @@ impl MockStorage { } impl Storage for MockStorage { - fn get(&self, _height: u64, key: &[u8]) -> FfiResult>> { + fn get(&self, _height: u64, key: &[u8]) -> FfiResult<(Option>, Option>)> { let gas_info = GasInfo::with_externally_used(key.len() as u64); - (Ok(self.data.get(key).cloned()), gas_info) + (Ok((self.data.get(key).cloned(), Some(vec![]))), gas_info) // TODO is it ok to return an empty proof on MockStorage? } #[cfg(feature = "iterator")] diff --git a/cosmwasm/packages/sgx-vm/src/traits.rs b/cosmwasm/packages/sgx-vm/src/traits.rs index 52d55da24..93ae5205d 100644 --- a/cosmwasm/packages/sgx-vm/src/traits.rs +++ b/cosmwasm/packages/sgx-vm/src/traits.rs @@ -69,7 +69,7 @@ where /// /// Note: Support for differentiating between a non-existent key and a key with empty value /// is not great yet and might not be possible in all backends. But we're trying to get there. - fn get(&self, height: u64, key: &[u8]) -> FfiResult>>; + fn get(&self, height: u64, key: &[u8]) -> FfiResult<(Option>, Option>)>; #[cfg(feature = "iterator")] /// Allows iteration over a set of key/value pairs, either forwards or backwards. diff --git a/cosmwasm/packages/sgx-vm/src/wasmi/exports.rs b/cosmwasm/packages/sgx-vm/src/wasmi/exports.rs index 185f83b6e..cd0ec328c 100644 --- a/cosmwasm/packages/sgx-vm/src/wasmi/exports.rs +++ b/cosmwasm/packages/sgx-vm/src/wasmi/exports.rs @@ -47,6 +47,7 @@ pub extern "C" fn ocall_read_db( gas_used: *mut u64, block_height: u64, value: *mut EnclaveBuffer, + proof: *mut EnclaveBuffer, key: *const u8, key_len: usize, ) -> OcallReturn { @@ -57,6 +58,7 @@ pub extern "C" fn ocall_read_db( gas_used, block_height, value, + proof, key, key_len, ) @@ -91,6 +93,7 @@ fn ocall_read_db_concrete( gas_used: *mut u64, height: u64, value: *mut EnclaveBuffer, + proof: *mut EnclaveBuffer, key: *const u8, key_len: usize, ) -> OcallReturn { @@ -101,24 +104,35 @@ fn ocall_read_db_concrete( std::panic::catch_unwind(|| implementation(context, height, key)) // Get either an error(`OcallReturn`), or a response(`EnclaveBuffer`) // which will be converted to a success status. - .map(|result| -> Result { - match result { - Ok((value, gas_cost)) => { - unsafe { *gas_used = gas_cost }; - value - .map(|val| alloc_impl(&val).map_err(|_| OcallReturn::Failure)) - .unwrap_or_else(|| Ok(EnclaveBuffer::default())) - } - Err(err) => { - unsafe { store_vm_error(err, vm_error) }; - Err(OcallReturn::Failure) + .map( + |result| -> Result<(EnclaveBuffer, EnclaveBuffer), OcallReturn> { + match result { + Ok(((value, proof), gas_cost)) => { + unsafe { *gas_used = gas_cost }; + + if let (Some(value), Some(proof)) = (value, proof) { + let val = alloc_impl(&value).map_err(|_| OcallReturn::Failure); + let p = alloc_impl(&proof).map_err(|_| OcallReturn::Failure); + + val.and_then(|val| p.and_then(|p| Ok((val, p)))) + } else { + Ok((EnclaveBuffer::default(), EnclaveBuffer::default())) + } + } + Err(err) => { + unsafe { store_vm_error(err, vm_error) }; + Err(OcallReturn::Failure) + } } - } - }) + }, + ) // Return the result or report the error .map(|result| match result { - Ok(enclave_buffer) => { - unsafe { *value = enclave_buffer }; + Ok((value_buffer, proof_buffer)) => { + unsafe { + *value = value_buffer; + *proof = proof_buffer + }; OcallReturn::Success } Err(err) => err, @@ -371,7 +385,11 @@ unsafe fn store_vm_error(vm_err: VmError, location: *mut UntrustedVmError) { /// appropriate for it. #[allow(clippy::type_complexity)] struct ExportImplementations { - read_db: fn(context: Ctx, height: u64, key: &[u8]) -> VmResult<(Option>, u64)>, + read_db: fn( + context: Ctx, + height: u64, + key: &[u8], + ) -> VmResult<((Option>, Option>), u64)>, query_chain: fn( context: Ctx, query: &[u8], @@ -431,7 +449,7 @@ fn ocall_read_db_impl( mut context: Ctx, height: u64, key: &[u8], -) -> VmResult<(Option>, u64)> +) -> VmResult<((Option>, Option>), u64)> where S: Storage, Q: Querier, diff --git a/go-cosmwasm/api/bindings.h b/go-cosmwasm/api/bindings.h index 79754cb49..1299af060 100644 --- a/go-cosmwasm/api/bindings.h +++ b/go-cosmwasm/api/bindings.h @@ -104,7 +104,7 @@ typedef struct GoIter { } GoIter; typedef struct DB_vtable { - int32_t (*read_db)(db_t*, gas_meter_t*, uint64_t*, uint64_t, Buffer, Buffer*, Buffer*); + int32_t (*read_db)(db_t*, gas_meter_t*, uint64_t*, uint64_t, Buffer, Buffer*, Buffer*, Buffer*); int32_t (*write_db)(db_t*, gas_meter_t*, uint64_t*, Buffer, Buffer, Buffer*); int32_t (*remove_db)(db_t*, gas_meter_t*, uint64_t*, Buffer, Buffer*); int32_t (*scan_db)(db_t*, gas_meter_t*, uint64_t*, Buffer, Buffer, int32_t, GoIter*, Buffer*); diff --git a/go-cosmwasm/api/callbacks.go b/go-cosmwasm/api/callbacks.go index d3ccc5888..98ba1262d 100644 --- a/go-cosmwasm/api/callbacks.go +++ b/go-cosmwasm/api/callbacks.go @@ -7,7 +7,7 @@ package api #include "bindings.h" // typedefs for _cgo functions (db) -typedef GoResult (*read_db_fn)(db_t *ptr, gas_meter_t *gas_meter, uint64_t *used_gas, uint64_t block_height, Buffer key, Buffer *val, Buffer *errOut); +typedef GoResult (*read_db_fn)(db_t *ptr, gas_meter_t *gas_meter, uint64_t *used_gas, uint64_t block_height, Buffer key, Buffer *val, Buffer *merkle_p, Buffer *errOut); typedef GoResult (*write_db_fn)(db_t *ptr, gas_meter_t *gas_meter, uint64_t *used_gas, Buffer key, Buffer val, Buffer *errOut); typedef GoResult (*remove_db_fn)(db_t *ptr, gas_meter_t *gas_meter, uint64_t *used_gas, Buffer key, Buffer *errOut); typedef GoResult (*scan_db_fn)(db_t *ptr, gas_meter_t *gas_meter, uint64_t *used_gas, Buffer start, Buffer end, int32_t order, GoIter *out, Buffer *errOut); @@ -19,7 +19,7 @@ typedef GoResult (*canonicalize_address_fn)(api_t *ptr, Buffer human, Buffer *ca typedef GoResult (*query_external_fn)(querier_t *ptr, uint64_t gas_limit, uint64_t *used_gas, Buffer request, uint32_t query_depth, Buffer *result, Buffer *errOut); // forward declarations (db) -GoResult cGet_cgo(db_t *ptr, gas_meter_t *gas_meter, uint64_t *used_gas, uint64_t block_height, Buffer key, Buffer *val, Buffer *errOut); +GoResult cGet_cgo(db_t *ptr, gas_meter_t *gas_meter, uint64_t *used_gas, uint64_t block_height, Buffer key, Buffer *val, Buffer *merkle_p, Buffer *errOut); GoResult cSet_cgo(db_t *ptr, gas_meter_t *gas_meter, uint64_t *used_gas, Buffer key, Buffer val, Buffer *errOut); GoResult cDelete_cgo(db_t *ptr, gas_meter_t *gas_meter, uint64_t *used_gas, Buffer key, Buffer *errOut); GoResult cScan_cgo(db_t *ptr, gas_meter_t *gas_meter, uint64_t *used_gas, Buffer start, Buffer end, int32_t order, GoIter *out, Buffer *errOut); @@ -139,39 +139,24 @@ func buildIterator(dbCounter uint64, it dbm.Iterator) C.iterator_t { } //export cGet -func cGet(ptr *C.db_t, gasMeter *C.gas_meter_t, usedGas *u64, block_height u64, key C.Buffer, val *C.Buffer, errOut *C.Buffer) (ret C.GoResult) { - println("TOMMM inside cGet1") - fmt.Printf("TOMMM block height: %d\n", block_height) +func cGet(ptr *C.db_t, gasMeter *C.gas_meter_t, usedGas *u64, block_height u64, key C.Buffer, val *C.Buffer, merkle_p *C.Buffer, errOut *C.Buffer) (ret C.GoResult) { defer recoverPanic(&ret) if ptr == nil || gasMeter == nil || usedGas == nil || val == nil { // we received an invalid pointer return C.GoResult_BadArgument } - println("TOMMM inside cGet2") gm := *(*GasMeter)(unsafe.Pointer(gasMeter)) kv := *(*sdk.KVStore)(unsafe.Pointer(ptr)) k := receiveSlice(key) - println("TOMMM inside cGet3") - gasBefore := gm.GasConsumed() - // Need to pass the verified block_height to cGet - // getWithProof(kv, key, block_height) - // iavl, err := getIavl(kv) - // if err != nil { - // return C.GoResult_Panic // Should add another error type - // } - println("TOMMM inside cGet4") - v, proof, err := getWithProof(kv, k, int64(block_height)) if err != nil { return C.GoResult_Panic } - fmt.Printf("TOMMM proof: %+v\n", proof) - // v := iavl.Get(k) gasAfter := gm.GasConsumed() *usedGas = (u64)(gasAfter - gasBefore) @@ -184,6 +169,10 @@ func cGet(ptr *C.db_t, gasMeter *C.gas_meter_t, usedGas *u64, block_height u64, // so if we don't write a non-null address to it, it will understand that // the key it requested does not exist in the kv store + if proof != nil { + *merkle_p = allocateRust(proof) + } + return C.GoResult_Ok } diff --git a/go-cosmwasm/api/callbacks_cgo.go b/go-cosmwasm/api/callbacks_cgo.go index 020e1b3d7..4de7822b2 100644 --- a/go-cosmwasm/api/callbacks_cgo.go +++ b/go-cosmwasm/api/callbacks_cgo.go @@ -9,7 +9,7 @@ package api // imports (db) GoResult cSet(db_t *ptr, gas_meter_t *gas_meter, uint64_t *used_gas, Buffer key, Buffer val, Buffer *errOut); -GoResult cGet(db_t *ptr, gas_meter_t *gas_meter, uint64_t *used_gas, uint64_t block_height, Buffer key, Buffer *val, Buffer *errOut); +GoResult cGet(db_t *ptr, gas_meter_t *gas_meter, uint64_t *used_gas, uint64_t block_height, Buffer key, Buffer *val, Buffer *merkle_p, Buffer *errOut); GoResult cDelete(db_t *ptr, gas_meter_t *gas_meter, uint64_t *used_gas, Buffer key, Buffer *errOut); GoResult cScan(db_t *ptr, gas_meter_t *gas_meter, uint64_t *used_gas, Buffer start, Buffer end, int32_t order, GoIter *out, Buffer *errOut); // imports (iterator) @@ -21,8 +21,8 @@ GoResult cCanonicalAddress(api_t *ptr, Buffer human, Buffer *canon, Buffer *errO GoResult cQueryExternal(querier_t *ptr, uint64_t gas_limit, uint64_t *used_gas, Buffer request, uint32_t query_depth, Buffer *result, Buffer *errOut); // Gateway functions (db) -GoResult cGet_cgo(db_t *ptr, gas_meter_t *gas_meter, uint64_t *used_gas, uint64_t block_height, Buffer key, Buffer *val, Buffer *errOut) { - return cGet(ptr, gas_meter, used_gas, block_height, key, val, errOut); +GoResult cGet_cgo(db_t *ptr, gas_meter_t *gas_meter, uint64_t *used_gas, uint64_t block_height, Buffer key, Buffer *val, Buffer *merkle_p, Buffer *errOut) { + return cGet(ptr, gas_meter, used_gas, block_height, key, val, merkle_p, errOut); } GoResult cSet_cgo(db_t *ptr, gas_meter_t *gas_meter, uint64_t *used_gas, Buffer key, Buffer val, Buffer *errOut) { return cSet(ptr, gas_meter, used_gas, key, val, errOut); diff --git a/go-cosmwasm/api/callbacks_cgo_mock.go b/go-cosmwasm/api/callbacks_cgo_mock.go index 987fadf4e..8702f52ca 100644 --- a/go-cosmwasm/api/callbacks_cgo_mock.go +++ b/go-cosmwasm/api/callbacks_cgo_mock.go @@ -10,7 +10,7 @@ package api // //// imports (db) //GoResult cSet(db_t *ptr, gas_meter_t *gas_meter, uint64_t *used_gas, Buffer key, Buffer val); -//GoResult cGet(db_t *ptr, gas_meter_t *gas_meter, uint64_t *used_gas, uint64_t block_height, Buffer key, Buffer *val); +//GoResult cGet(db_t *ptr, gas_meter_t *gas_meter, uint64_t *used_gas, uint64_t block_height, Buffer key, Buffer *val, Buffer *merkle_p); //GoResult cDelete(db_t *ptr, gas_meter_t *gas_meter, uint64_t *used_gas, Buffer key); //GoResult cScan(db_t *ptr, gas_meter_t *gas_meter, uint64_t *used_gas, Buffer start, Buffer end, int32_t order, GoIter *out); //// imports (iterator) @@ -22,8 +22,8 @@ package api //GoResult cQueryExternal(querier_t *ptr, uint64_t *used_gas, Buffer request, Buffer *result); // //// Gateway functions (db) -//GoResult cGet_cgo(db_t *ptr, gas_meter_t *gas_meter, uint64_t *used_gas, uint64_t block_height, Buffer key, Buffer *val) { -// return cGet(ptr, gas_meter, used_gas, block_height, key, val); +//GoResult cGet_cgo(db_t *ptr, gas_meter_t *gas_meter, uint64_t *used_gas, uint64_t block_height, Buffer key, Buffer *val, Buffer *merkle_p) { +// return cGet(ptr, gas_meter, used_gas, block_height, key, val, merkle_p); //} //GoResult cSet_cgo(db_t *ptr, gas_meter_t *gas_meter, uint64_t *used_gas, Buffer key, Buffer val) { // return cSet(ptr, gas_meter, used_gas, key, val); diff --git a/go-cosmwasm/api/callbacks_mock.go b/go-cosmwasm/api/callbacks_mock.go index b954138c8..7b58e66e3 100644 --- a/go-cosmwasm/api/callbacks_mock.go +++ b/go-cosmwasm/api/callbacks_mock.go @@ -7,7 +7,7 @@ package api // #include "bindings.h" // // // typedefs for _cgo functions (db) -// typedef GoResult (*read_db_fn)(db_t *ptr, gas_meter_t *gas_meter, uint64_t *used_gas, uint64_t block_height, Buffer key, Buffer *val); +// typedef GoResult (*read_db_fn)(db_t *ptr, gas_meter_t *gas_meter, uint64_t *used_gas, uint64_t block_height, Buffer key, Buffer *val, Buffer *merkle_p); // typedef GoResult (*write_db_fn)(db_t *ptr, gas_meter_t *gas_meter, uint64_t *used_gas, Buffer key, Buffer val); // typedef GoResult (*remove_db_fn)(db_t *ptr, gas_meter_t *gas_meter, uint64_t *used_gas, Buffer key); // typedef GoResult (*scan_db_fn)(db_t *ptr, gas_meter_t *gas_meter, uint64_t *used_gas, Buffer start, Buffer end, int32_t order, GoIter *out); @@ -19,7 +19,7 @@ package api // typedef GoResult (*query_external_fn)(querier_t *ptr, uint64_t *used_gas, Buffer request, Buffer *result); // // // forward declarations (db) -// GoResult cGet_cgo(db_t *ptr, gas_meter_t *gas_meter, uint64_t *used_gas, uint64_t block_height, Buffer key, Buffer *val); +// GoResult cGet_cgo(db_t *ptr, gas_meter_t *gas_meter, uint64_t *used_gas, uint64_t block_height, Buffer key, Buffer *val, Buffer *merkle_p); // GoResult cSet_cgo(db_t *ptr, gas_meter_t *gas_meter, uint64_t *used_gas, Buffer key, Buffer val); // GoResult cDelete_cgo(db_t *ptr, gas_meter_t *gas_meter, uint64_t *used_gas, Buffer key); // GoResult cScan_cgo(db_t *ptr, gas_meter_t *gas_meter, uint64_t *used_gas, Buffer start, Buffer end, int32_t order, GoIter *out); diff --git a/go-cosmwasm/src/db.rs b/go-cosmwasm/src/db.rs index fc745dbee..283e1142a 100644 --- a/go-cosmwasm/src/db.rs +++ b/go-cosmwasm/src/db.rs @@ -23,6 +23,7 @@ pub struct DB_vtable { Buffer, *mut Buffer, *mut Buffer, + *mut Buffer, ) -> i32, pub write_db: extern "C" fn(*mut db_t, *mut gas_meter_t, *mut u64, Buffer, Buffer, *mut Buffer) -> i32, @@ -50,9 +51,10 @@ pub struct DB { } impl Storage for DB { - fn get(&self, height: u64, key: &[u8]) -> FfiResult>> { + fn get(&self, height: u64, key: &[u8]) -> FfiResult<(Option>, Option>)> { let key_buf = Buffer::from_vec(key.to_vec()); let mut result_buf = Buffer::default(); + let mut proof_buf = Buffer::default(); let mut err = Buffer::default(); let mut used_gas = 0_u64; let go_result: GoResult = (self.vtable.read_db)( @@ -62,6 +64,7 @@ impl Storage for DB { height, key_buf, &mut result_buf as *mut Buffer, + &mut proof_buf as *mut Buffer, &mut err as *mut Buffer, ) .into(); @@ -88,7 +91,15 @@ impl Storage for DB { } else { Some(unsafe { result_buf.consume() }) }; - (Ok(value), gas_info) + + // We initialize `proof_buf` with a null pointer. If it is not null, that means + // it was initialized by the go code, with values generated by `memory::allocate_rust`. + let proof = if proof_buf.ptr.is_null() { + None + } else { + Some(unsafe { proof_buf.consume() }) + }; + (Ok((value, proof)), gas_info) } /// Allows iteration over a set of key/value pairs, either forwards or backwards. From e2c41da9d4477d4c5a72191721edf7f8705afcb2 Mon Sep 17 00:00:00 2001 From: TomL94 Date: Thu, 18 May 2023 19:00:40 +0300 Subject: [PATCH 10/51] Better errors in go-cosmwasm --- go-cosmwasm/api/callbacks.go | 2 +- go-cosmwasm/api/store.go | 3 +++ 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/go-cosmwasm/api/callbacks.go b/go-cosmwasm/api/callbacks.go index 98ba1262d..64d14f826 100644 --- a/go-cosmwasm/api/callbacks.go +++ b/go-cosmwasm/api/callbacks.go @@ -154,7 +154,7 @@ func cGet(ptr *C.db_t, gasMeter *C.gas_meter_t, usedGas *u64, block_height u64, v, proof, err := getWithProof(kv, k, int64(block_height)) if err != nil { - return C.GoResult_Panic + panic(fmt.Sprintf("error getting merkle proof: %s", err.Error())) } gasAfter := gm.GasConsumed() diff --git a/go-cosmwasm/api/store.go b/go-cosmwasm/api/store.go index 1b51b2c70..6118cab0b 100644 --- a/go-cosmwasm/api/store.go +++ b/go-cosmwasm/api/store.go @@ -41,6 +41,9 @@ func getWithProof(store sdk.KVStore, key []byte, blockHeight int64) (value []byt if len(result.ProofOps.Ops) != 1 { return nil, nil, fmt.Errorf("error in retrieving proof for key: %+v, got: %+v", key, result.ProofOps.Ops) } + if result.ProofOps.Ops[0].Data == nil { + return nil, nil, fmt.Errorf("`iavlStore.Query()` returned an empty value for key: %+v", key) + } return result.Value, result.ProofOps.Ops[0].Data, nil } From 4e4327162ef7a7f05260408201c6ebb013fc23e5 Mon Sep 17 00:00:00 2001 From: TomL94 Date: Thu, 18 May 2023 19:13:29 +0300 Subject: [PATCH 11/51] Clippy it's not you it's me --- cosmwasm/enclaves/shared/contract-engine/src/db.rs | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/cosmwasm/enclaves/shared/contract-engine/src/db.rs b/cosmwasm/enclaves/shared/contract-engine/src/db.rs index c77af91d2..86c04adee 100644 --- a/cosmwasm/enclaves/shared/contract-engine/src/db.rs +++ b/cosmwasm/enclaves/shared/contract-engine/src/db.rs @@ -174,7 +174,7 @@ pub fn read_from_encrypted_state( &encrypted_key_bytes, block_height, ) { - Ok(((maybe_encrypted_value_bytes, maybe_proof), gas_used)) => { + Ok((maybe_encrypted_value_bytes, maybe_proof, gas_used)) => { debug!("merkle proof returned from read_db(): {:?}", maybe_proof); match maybe_encrypted_value_bytes { Some(encrypted_value_bytes) => { @@ -221,7 +221,7 @@ pub fn read_from_encrypted_state( let gas_used_second_read: u64; (maybe_plaintext_value, gas_used_second_read) = match read_db(context, &scrambled_field_name, block_height) { - Ok(((encrypted_value, proof), gas_used)) => { + Ok((encrypted_value, proof, gas_used)) => { debug!("proof returned from read_db(): {:?}", proof); match encrypted_value { Some(plaintext_value) => { @@ -314,11 +314,12 @@ fn field_name_digest(field_name: &[u8], contract_key: &ContractKey) -> [u8; 32] } /// Safe wrapper around reads from the contract storage +#[allow(clippy::type_complexity)] fn read_db( context: &Ctx, key: &[u8], block_height: u64, -) -> Result<((Option>, Option>), u64), WasmEngineError> { +) -> Result<(Option>, Option>, u64), WasmEngineError> { let mut ocall_return = OcallReturn::Success; let mut value_buffer = std::mem::MaybeUninit::::uninit(); let mut proof_buffer = std::mem::MaybeUninit::::uninit(); @@ -364,7 +365,7 @@ fn read_db( } }; - Ok(((value, proof), gas_used)) + Ok((value, proof, gas_used)) } /// Safe wrapper around reads from the contract storage From 223abfce737cf5071d0584d611f103d769874e58 Mon Sep 17 00:00:00 2001 From: toml01 Date: Tue, 13 Jun 2023 18:56:22 +0300 Subject: [PATCH 12/51] demo of getting module hashes --- app/app.go | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/app/app.go b/app/app.go index 2c4253835..29eb0d838 100644 --- a/app/app.go +++ b/app/app.go @@ -21,6 +21,7 @@ import ( "github.com/cosmos/cosmos-sdk/server/config" servertypes "github.com/cosmos/cosmos-sdk/server/types" "github.com/cosmos/cosmos-sdk/simapp" + "github.com/cosmos/cosmos-sdk/store/rootmulti" sdk "github.com/cosmos/cosmos-sdk/types" "github.com/cosmos/cosmos-sdk/types/module" "github.com/cosmos/cosmos-sdk/x/authz" @@ -415,6 +416,19 @@ func (app *SecretNetworkApp) Name() string { return app.BaseApp.Name() } // BeginBlocker application updates every begin block func (app *SecretNetworkApp) BeginBlocker(ctx sdk.Context, req abci.RequestBeginBlock) abci.ResponseBeginBlock { + //////////////// EXPERIMENT //////////////// + multiStore := app.BaseApp.CommitMultiStore() + rootMulti, ok := multiStore.(*rootmulti.Store) + if !ok { + println("TOMMM oops") + } else { + stores := rootMulti.GetStores() + for k, v := range stores { + fmt.Printf("TOMMM root multi stores\nk: %+v\nhash: %+v\n", k.Name(), v.LastCommitID().Hash) + } + } + //////////////// EXPERIMENT //////////////// + return app.mm.BeginBlock(ctx, req) } From 534c94afef8edbfe796f5c66fdee027aba3559a3 Mon Sep 17 00:00:00 2001 From: toml01 Date: Sun, 18 Jun 2023 16:24:32 +0300 Subject: [PATCH 13/51] Return the full prefixed key with the ocall as well + fix a bug in ocall_read_db_concrete --- cosmwasm/enclaves/execute/Enclave.edl | 1 + .../enclaves/shared/contract-engine/src/db.rs | 16 +++++--- .../contract-engine/src/external/ocalls.rs | 1 + .../packages/sgx-vm/src/testing/storage.rs | 21 ++++++---- cosmwasm/packages/sgx-vm/src/traits.rs | 6 ++- cosmwasm/packages/sgx-vm/src/wasmi/exports.rs | 38 ++++++++++++------- go-cosmwasm/api/bindings.h | 2 +- go-cosmwasm/api/callbacks.go | 9 +++-- go-cosmwasm/api/callbacks_cgo.go | 6 +-- go-cosmwasm/api/callbacks_cgo_mock.go | 6 +-- go-cosmwasm/api/callbacks_mock.go | 2 +- go-cosmwasm/api/store.go | 12 +++--- go-cosmwasm/src/db.rs | 19 +++++++++- 13 files changed, 94 insertions(+), 45 deletions(-) diff --git a/cosmwasm/enclaves/execute/Enclave.edl b/cosmwasm/enclaves/execute/Enclave.edl index ae73c5b9c..827eed8b7 100644 --- a/cosmwasm/enclaves/execute/Enclave.edl +++ b/cosmwasm/enclaves/execute/Enclave.edl @@ -132,6 +132,7 @@ enclave { uint64_t block_height, [out] EnclaveBuffer* value, [out] EnclaveBuffer* proof, + [out] EnclaveBuffer* mp_key, [in, count=key_len] const uint8_t* key, uintptr_t key_len ) allow (ecall_allocate); diff --git a/cosmwasm/enclaves/shared/contract-engine/src/db.rs b/cosmwasm/enclaves/shared/contract-engine/src/db.rs index 86c04adee..b5ee210b8 100644 --- a/cosmwasm/enclaves/shared/contract-engine/src/db.rs +++ b/cosmwasm/enclaves/shared/contract-engine/src/db.rs @@ -174,8 +174,9 @@ pub fn read_from_encrypted_state( &encrypted_key_bytes, block_height, ) { - Ok((maybe_encrypted_value_bytes, maybe_proof, gas_used)) => { + Ok((maybe_encrypted_value_bytes, maybe_proof, maybe_mp_key, gas_used)) => { debug!("merkle proof returned from read_db(): {:?}", maybe_proof); + debug!("full key returned from read_db(): {:?}", maybe_mp_key); match maybe_encrypted_value_bytes { Some(encrypted_value_bytes) => { let encrypted_value: EncryptedValue = bincode2::deserialize(&encrypted_value_bytes).map_err(|err| { @@ -221,8 +222,9 @@ pub fn read_from_encrypted_state( let gas_used_second_read: u64; (maybe_plaintext_value, gas_used_second_read) = match read_db(context, &scrambled_field_name, block_height) { - Ok((encrypted_value, proof, gas_used)) => { + Ok((encrypted_value, proof, mp_key, gas_used)) => { debug!("proof returned from read_db(): {:?}", proof); + debug!("full key returned from read_db(): {:?}", mp_key); match encrypted_value { Some(plaintext_value) => { match decrypt_value_old( @@ -319,14 +321,15 @@ fn read_db( context: &Ctx, key: &[u8], block_height: u64, -) -> Result<(Option>, Option>, u64), WasmEngineError> { +) -> Result<(Option>, Option>, Option>, u64), WasmEngineError> { let mut ocall_return = OcallReturn::Success; let mut value_buffer = std::mem::MaybeUninit::::uninit(); let mut proof_buffer = std::mem::MaybeUninit::::uninit(); + let mut mp_key_buffer = std::mem::MaybeUninit::::uninit(); let mut vm_err = UntrustedVmError::default(); let mut gas_used = 0_u64; - let (value, proof) = unsafe { + let (value, proof, mp_key) = unsafe { let status = ocalls::ocall_read_db( (&mut ocall_return) as *mut _, context.unsafe_clone(), @@ -335,6 +338,7 @@ fn read_db( block_height, value_buffer.as_mut_ptr(), proof_buffer.as_mut_ptr(), + mp_key_buffer.as_mut_ptr(), key.as_ptr(), key.len(), ); @@ -353,9 +357,11 @@ fn read_db( OcallReturn::Success => { let value_buffer = value_buffer.assume_init(); let proof_buffer = proof_buffer.assume_init(); + let mp_key_buffer = mp_key_buffer.assume_init(); ( ecalls::recover_buffer(value_buffer)?, ecalls::recover_buffer(proof_buffer)?, + ecalls::recover_buffer(mp_key_buffer)?, ) } OcallReturn::Failure => { @@ -365,7 +371,7 @@ fn read_db( } }; - Ok((value, proof, gas_used)) + Ok((value, proof, mp_key, gas_used)) } /// Safe wrapper around reads from the contract storage diff --git a/cosmwasm/enclaves/shared/contract-engine/src/external/ocalls.rs b/cosmwasm/enclaves/shared/contract-engine/src/external/ocalls.rs index 049b3659d..55a9e82b9 100644 --- a/cosmwasm/enclaves/shared/contract-engine/src/external/ocalls.rs +++ b/cosmwasm/enclaves/shared/contract-engine/src/external/ocalls.rs @@ -18,6 +18,7 @@ extern "C" { block_height: u64, value: *mut EnclaveBuffer, proof: *mut EnclaveBuffer, + mp_key: *mut EnclaveBuffer, key: *const u8, key_len: usize, ) -> sgx_status_t; diff --git a/cosmwasm/packages/sgx-vm/src/testing/storage.rs b/cosmwasm/packages/sgx-vm/src/testing/storage.rs index 42d4dadf7..9dbbdbbc9 100644 --- a/cosmwasm/packages/sgx-vm/src/testing/storage.rs +++ b/cosmwasm/packages/sgx-vm/src/testing/storage.rs @@ -56,9 +56,16 @@ impl MockStorage { } impl Storage for MockStorage { - fn get(&self, _height: u64, key: &[u8]) -> FfiResult<(Option>, Option>)> { + fn get( + &self, + _height: u64, + key: &[u8], + ) -> FfiResult<(Option>, Option>, Option>)> { let gas_info = GasInfo::with_externally_used(key.len() as u64); - (Ok((self.data.get(key).cloned(), Some(vec![]))), gas_info) // TODO is it ok to return an empty proof on MockStorage? + ( + Ok((self.data.get(key).cloned(), Some(vec![]), Some(vec![]))), + gas_info, + ) // TODO is it ok to return an empty proof on MockStorage? } #[cfg(feature = "iterator")] @@ -135,10 +142,10 @@ mod test { #[test] fn get_and_set() { let mut store = MockStorage::new(); - assert_eq!(None, store.get(b"foo").0.unwrap()); + assert_eq!(None, store.get(0, b"foo").0.unwrap().0); store.set(b"foo", b"bar").0.unwrap(); - assert_eq!(Some(b"bar".to_vec()), store.get(b"foo").0.unwrap()); - assert_eq!(None, store.get(b"food").0.unwrap()); + assert_eq!(Some(b"bar".to_vec()), store.get(0, b"foo").0.unwrap().0); + assert_eq!(None, store.get(0, b"food").0.unwrap().0); } #[test] @@ -148,8 +155,8 @@ mod test { store.set(b"food", b"bank").0.unwrap(); store.remove(b"foo").0.unwrap(); - assert_eq!(None, store.get(b"foo").0.unwrap()); - assert_eq!(Some(b"bank".to_vec()), store.get(b"food").0.unwrap()); + assert_eq!(None, store.get(0, b"foo",).0.unwrap().0); + assert_eq!(Some(b"bank".to_vec()), store.get(0, b"food").0.unwrap().0); } #[test] diff --git a/cosmwasm/packages/sgx-vm/src/traits.rs b/cosmwasm/packages/sgx-vm/src/traits.rs index 93ae5205d..dbb2825e3 100644 --- a/cosmwasm/packages/sgx-vm/src/traits.rs +++ b/cosmwasm/packages/sgx-vm/src/traits.rs @@ -69,7 +69,11 @@ where /// /// Note: Support for differentiating between a non-existent key and a key with empty value /// is not great yet and might not be possible in all backends. But we're trying to get there. - fn get(&self, height: u64, key: &[u8]) -> FfiResult<(Option>, Option>)>; + fn get( + &self, + height: u64, + key: &[u8], + ) -> FfiResult<(Option>, Option>, Option>)>; #[cfg(feature = "iterator")] /// Allows iteration over a set of key/value pairs, either forwards or backwards. diff --git a/cosmwasm/packages/sgx-vm/src/wasmi/exports.rs b/cosmwasm/packages/sgx-vm/src/wasmi/exports.rs index cd0ec328c..6df6841b3 100644 --- a/cosmwasm/packages/sgx-vm/src/wasmi/exports.rs +++ b/cosmwasm/packages/sgx-vm/src/wasmi/exports.rs @@ -48,6 +48,7 @@ pub extern "C" fn ocall_read_db( block_height: u64, value: *mut EnclaveBuffer, proof: *mut EnclaveBuffer, + mp_key: *mut EnclaveBuffer, key: *const u8, key_len: usize, ) -> OcallReturn { @@ -59,6 +60,7 @@ pub extern "C" fn ocall_read_db( block_height, value, proof, + mp_key, key, key_len, ) @@ -94,6 +96,7 @@ fn ocall_read_db_concrete( height: u64, value: *mut EnclaveBuffer, proof: *mut EnclaveBuffer, + mp_key: *mut EnclaveBuffer, key: *const u8, key_len: usize, ) -> OcallReturn { @@ -105,19 +108,27 @@ fn ocall_read_db_concrete( // Get either an error(`OcallReturn`), or a response(`EnclaveBuffer`) // which will be converted to a success status. .map( - |result| -> Result<(EnclaveBuffer, EnclaveBuffer), OcallReturn> { + |result| -> Result<(EnclaveBuffer, EnclaveBuffer, EnclaveBuffer), OcallReturn> { match result { - Ok(((value, proof), gas_cost)) => { + Ok(((value, proof, mp_key), gas_cost)) => { unsafe { *gas_used = gas_cost }; - if let (Some(value), Some(proof)) = (value, proof) { - let val = alloc_impl(&value).map_err(|_| OcallReturn::Failure); - let p = alloc_impl(&proof).map_err(|_| OcallReturn::Failure); - - val.and_then(|val| p.and_then(|p| Ok((val, p)))) + let value_buf = if let Some(value) = value { + alloc_impl(&value).map_err(|_| OcallReturn::Failure)? + } else { + EnclaveBuffer::default() + }; + let proof_buf = if let Some(proof) = proof { + alloc_impl(&proof).map_err(|_| OcallReturn::Failure)? + } else { + EnclaveBuffer::default() + }; + let mp_key_buf = if let Some(mp_key) = mp_key { + alloc_impl(&mp_key).map_err(|_| OcallReturn::Failure)? } else { - Ok((EnclaveBuffer::default(), EnclaveBuffer::default())) - } + EnclaveBuffer::default() + }; + Ok((value_buf, proof_buf, mp_key_buf)) } Err(err) => { unsafe { store_vm_error(err, vm_error) }; @@ -128,10 +139,11 @@ fn ocall_read_db_concrete( ) // Return the result or report the error .map(|result| match result { - Ok((value_buffer, proof_buffer)) => { + Ok((value_buffer, proof_buffer, mp_key_buffer)) => { unsafe { *value = value_buffer; - *proof = proof_buffer + *proof = proof_buffer; + *mp_key = mp_key_buffer }; OcallReturn::Success } @@ -389,7 +401,7 @@ struct ExportImplementations { context: Ctx, height: u64, key: &[u8], - ) -> VmResult<((Option>, Option>), u64)>, + ) -> VmResult<((Option>, Option>, Option>), u64)>, query_chain: fn( context: Ctx, query: &[u8], @@ -449,7 +461,7 @@ fn ocall_read_db_impl( mut context: Ctx, height: u64, key: &[u8], -) -> VmResult<((Option>, Option>), u64)> +) -> VmResult<((Option>, Option>, Option>), u64)> where S: Storage, Q: Querier, diff --git a/go-cosmwasm/api/bindings.h b/go-cosmwasm/api/bindings.h index 1299af060..f4173d7e2 100644 --- a/go-cosmwasm/api/bindings.h +++ b/go-cosmwasm/api/bindings.h @@ -104,7 +104,7 @@ typedef struct GoIter { } GoIter; typedef struct DB_vtable { - int32_t (*read_db)(db_t*, gas_meter_t*, uint64_t*, uint64_t, Buffer, Buffer*, Buffer*, Buffer*); + int32_t (*read_db)(db_t*, gas_meter_t*, uint64_t*, uint64_t, Buffer, Buffer*, Buffer*, Buffer*, Buffer*); int32_t (*write_db)(db_t*, gas_meter_t*, uint64_t*, Buffer, Buffer, Buffer*); int32_t (*remove_db)(db_t*, gas_meter_t*, uint64_t*, Buffer, Buffer*); int32_t (*scan_db)(db_t*, gas_meter_t*, uint64_t*, Buffer, Buffer, int32_t, GoIter*, Buffer*); diff --git a/go-cosmwasm/api/callbacks.go b/go-cosmwasm/api/callbacks.go index 64d14f826..c09d796d8 100644 --- a/go-cosmwasm/api/callbacks.go +++ b/go-cosmwasm/api/callbacks.go @@ -19,7 +19,7 @@ typedef GoResult (*canonicalize_address_fn)(api_t *ptr, Buffer human, Buffer *ca typedef GoResult (*query_external_fn)(querier_t *ptr, uint64_t gas_limit, uint64_t *used_gas, Buffer request, uint32_t query_depth, Buffer *result, Buffer *errOut); // forward declarations (db) -GoResult cGet_cgo(db_t *ptr, gas_meter_t *gas_meter, uint64_t *used_gas, uint64_t block_height, Buffer key, Buffer *val, Buffer *merkle_p, Buffer *errOut); +GoResult cGet_cgo(db_t *ptr, gas_meter_t *gas_meter, uint64_t *used_gas, uint64_t block_height, Buffer key, Buffer *val, Buffer *merkle_p, Buffer *mp_key, Buffer *errOut); GoResult cSet_cgo(db_t *ptr, gas_meter_t *gas_meter, uint64_t *used_gas, Buffer key, Buffer val, Buffer *errOut); GoResult cDelete_cgo(db_t *ptr, gas_meter_t *gas_meter, uint64_t *used_gas, Buffer key, Buffer *errOut); GoResult cScan_cgo(db_t *ptr, gas_meter_t *gas_meter, uint64_t *used_gas, Buffer start, Buffer end, int32_t order, GoIter *out, Buffer *errOut); @@ -139,7 +139,7 @@ func buildIterator(dbCounter uint64, it dbm.Iterator) C.iterator_t { } //export cGet -func cGet(ptr *C.db_t, gasMeter *C.gas_meter_t, usedGas *u64, block_height u64, key C.Buffer, val *C.Buffer, merkle_p *C.Buffer, errOut *C.Buffer) (ret C.GoResult) { +func cGet(ptr *C.db_t, gasMeter *C.gas_meter_t, usedGas *u64, block_height u64, key C.Buffer, val *C.Buffer, merkle_p *C.Buffer, mp_key *C.Buffer, errOut *C.Buffer) (ret C.GoResult) { defer recoverPanic(&ret) if ptr == nil || gasMeter == nil || usedGas == nil || val == nil { // we received an invalid pointer @@ -152,7 +152,7 @@ func cGet(ptr *C.db_t, gasMeter *C.gas_meter_t, usedGas *u64, block_height u64, gasBefore := gm.GasConsumed() - v, proof, err := getWithProof(kv, k, int64(block_height)) + v, proof, mpKey, err := getWithProof(kv, k, int64(block_height)) if err != nil { panic(fmt.Sprintf("error getting merkle proof: %s", err.Error())) } @@ -172,6 +172,9 @@ func cGet(ptr *C.db_t, gasMeter *C.gas_meter_t, usedGas *u64, block_height u64, if proof != nil { *merkle_p = allocateRust(proof) } + if mpKey != nil { + *mp_key = allocateRust(mpKey) + } return C.GoResult_Ok } diff --git a/go-cosmwasm/api/callbacks_cgo.go b/go-cosmwasm/api/callbacks_cgo.go index 4de7822b2..b07dd9d34 100644 --- a/go-cosmwasm/api/callbacks_cgo.go +++ b/go-cosmwasm/api/callbacks_cgo.go @@ -9,7 +9,7 @@ package api // imports (db) GoResult cSet(db_t *ptr, gas_meter_t *gas_meter, uint64_t *used_gas, Buffer key, Buffer val, Buffer *errOut); -GoResult cGet(db_t *ptr, gas_meter_t *gas_meter, uint64_t *used_gas, uint64_t block_height, Buffer key, Buffer *val, Buffer *merkle_p, Buffer *errOut); +GoResult cGet(db_t *ptr, gas_meter_t *gas_meter, uint64_t *used_gas, uint64_t block_height, Buffer key, Buffer *val, Buffer *merkle_p, Buffer *mp_key, Buffer *errOut); GoResult cDelete(db_t *ptr, gas_meter_t *gas_meter, uint64_t *used_gas, Buffer key, Buffer *errOut); GoResult cScan(db_t *ptr, gas_meter_t *gas_meter, uint64_t *used_gas, Buffer start, Buffer end, int32_t order, GoIter *out, Buffer *errOut); // imports (iterator) @@ -21,8 +21,8 @@ GoResult cCanonicalAddress(api_t *ptr, Buffer human, Buffer *canon, Buffer *errO GoResult cQueryExternal(querier_t *ptr, uint64_t gas_limit, uint64_t *used_gas, Buffer request, uint32_t query_depth, Buffer *result, Buffer *errOut); // Gateway functions (db) -GoResult cGet_cgo(db_t *ptr, gas_meter_t *gas_meter, uint64_t *used_gas, uint64_t block_height, Buffer key, Buffer *val, Buffer *merkle_p, Buffer *errOut) { - return cGet(ptr, gas_meter, used_gas, block_height, key, val, merkle_p, errOut); +GoResult cGet_cgo(db_t *ptr, gas_meter_t *gas_meter, uint64_t *used_gas, uint64_t block_height, Buffer key, Buffer *val, Buffer *merkle_p, Buffer *mp_key, Buffer *errOut) { + return cGet(ptr, gas_meter, used_gas, block_height, key, val, merkle_p, mp_key, errOut); } GoResult cSet_cgo(db_t *ptr, gas_meter_t *gas_meter, uint64_t *used_gas, Buffer key, Buffer val, Buffer *errOut) { return cSet(ptr, gas_meter, used_gas, key, val, errOut); diff --git a/go-cosmwasm/api/callbacks_cgo_mock.go b/go-cosmwasm/api/callbacks_cgo_mock.go index 8702f52ca..a464bfdbc 100644 --- a/go-cosmwasm/api/callbacks_cgo_mock.go +++ b/go-cosmwasm/api/callbacks_cgo_mock.go @@ -10,7 +10,7 @@ package api // //// imports (db) //GoResult cSet(db_t *ptr, gas_meter_t *gas_meter, uint64_t *used_gas, Buffer key, Buffer val); -//GoResult cGet(db_t *ptr, gas_meter_t *gas_meter, uint64_t *used_gas, uint64_t block_height, Buffer key, Buffer *val, Buffer *merkle_p); +//GoResult cGet(db_t *ptr, gas_meter_t *gas_meter, uint64_t *used_gas, uint64_t block_height, Buffer key, Buffer *val, Buffer *merkle_p, Buffer *mp_key); //GoResult cDelete(db_t *ptr, gas_meter_t *gas_meter, uint64_t *used_gas, Buffer key); //GoResult cScan(db_t *ptr, gas_meter_t *gas_meter, uint64_t *used_gas, Buffer start, Buffer end, int32_t order, GoIter *out); //// imports (iterator) @@ -22,8 +22,8 @@ package api //GoResult cQueryExternal(querier_t *ptr, uint64_t *used_gas, Buffer request, Buffer *result); // //// Gateway functions (db) -//GoResult cGet_cgo(db_t *ptr, gas_meter_t *gas_meter, uint64_t *used_gas, uint64_t block_height, Buffer key, Buffer *val, Buffer *merkle_p) { -// return cGet(ptr, gas_meter, used_gas, block_height, key, val, merkle_p); +//GoResult cGet_cgo(db_t *ptr, gas_meter_t *gas_meter, uint64_t *used_gas, uint64_t block_height, Buffer key, Buffer *val, Buffer *merkle_p, Buffer *mp_key) { +// return cGet(ptr, gas_meter, used_gas, block_height, key, val, merkle_p, mp_key); //} //GoResult cSet_cgo(db_t *ptr, gas_meter_t *gas_meter, uint64_t *used_gas, Buffer key, Buffer val) { // return cSet(ptr, gas_meter, used_gas, key, val); diff --git a/go-cosmwasm/api/callbacks_mock.go b/go-cosmwasm/api/callbacks_mock.go index 7b58e66e3..360e16d66 100644 --- a/go-cosmwasm/api/callbacks_mock.go +++ b/go-cosmwasm/api/callbacks_mock.go @@ -19,7 +19,7 @@ package api // typedef GoResult (*query_external_fn)(querier_t *ptr, uint64_t *used_gas, Buffer request, Buffer *result); // // // forward declarations (db) -// GoResult cGet_cgo(db_t *ptr, gas_meter_t *gas_meter, uint64_t *used_gas, uint64_t block_height, Buffer key, Buffer *val, Buffer *merkle_p); +// GoResult cGet_cgo(db_t *ptr, gas_meter_t *gas_meter, uint64_t *used_gas, uint64_t block_height, Buffer key, Buffer *val, Buffer *merkle_p, Buffer *mp_key); // GoResult cSet_cgo(db_t *ptr, gas_meter_t *gas_meter, uint64_t *used_gas, Buffer key, Buffer val); // GoResult cDelete_cgo(db_t *ptr, gas_meter_t *gas_meter, uint64_t *used_gas, Buffer key); // GoResult cScan_cgo(db_t *ptr, gas_meter_t *gas_meter, uint64_t *used_gas, Buffer start, Buffer end, int32_t order, GoIter *out); diff --git a/go-cosmwasm/api/store.go b/go-cosmwasm/api/store.go index 6118cab0b..0b460aab3 100644 --- a/go-cosmwasm/api/store.go +++ b/go-cosmwasm/api/store.go @@ -27,23 +27,23 @@ func getInnerIavl(store sdk.KVStore, key []byte) (iavlStore *iavl.Store, fullKey } } -func getWithProof(store sdk.KVStore, key []byte, blockHeight int64) (value []byte, proof []byte, err error) { +func getWithProof(store sdk.KVStore, key []byte, blockHeight int64) (value []byte, proof []byte, fullKey []byte, err error) { iavlStore, fullKey, err := getInnerIavl(store, key) if err != nil { - return nil, nil, err + return nil, nil, nil, err } // Query height is (current - 1) because we will probably not have a proof in // the current height (assuming we're mid execution) - result := iavlStore.Query(abci.RequestQuery{Data: fullKey, Path: "/key", Prove: true, Height: blockHeight - 1 /* NOTE!! this depends on what blockHeight we get here. if it's the verified one it's probably for the past block anyway, so no need to subtract 1 for the height*/}) + result := iavlStore.Query(abci.RequestQuery{Data: fullKey, Path: "/key", Prove: true, Height: blockHeight - 1}) // result.ProofOps.Ops should always contain only one proof if len(result.ProofOps.Ops) != 1 { - return nil, nil, fmt.Errorf("error in retrieving proof for key: %+v, got: %+v", key, result.ProofOps.Ops) + return nil, nil, nil, fmt.Errorf("error in retrieving proof for key: %+v, got: %+v", key, result.ProofOps.Ops) } if result.ProofOps.Ops[0].Data == nil { - return nil, nil, fmt.Errorf("`iavlStore.Query()` returned an empty value for key: %+v", key) + return nil, nil, nil, fmt.Errorf("`iavlStore.Query()` returned an empty value for key: %+v", key) } - return result.Value, result.ProofOps.Ops[0].Data, nil + return result.Value, result.ProofOps.Ops[0].Data, fullKey, nil } diff --git a/go-cosmwasm/src/db.rs b/go-cosmwasm/src/db.rs index 283e1142a..1b6248d1e 100644 --- a/go-cosmwasm/src/db.rs +++ b/go-cosmwasm/src/db.rs @@ -24,6 +24,7 @@ pub struct DB_vtable { *mut Buffer, *mut Buffer, *mut Buffer, + *mut Buffer, ) -> i32, pub write_db: extern "C" fn(*mut db_t, *mut gas_meter_t, *mut u64, Buffer, Buffer, *mut Buffer) -> i32, @@ -51,10 +52,15 @@ pub struct DB { } impl Storage for DB { - fn get(&self, height: u64, key: &[u8]) -> FfiResult<(Option>, Option>)> { + fn get( + &self, + height: u64, + key: &[u8], + ) -> FfiResult<(Option>, Option>, Option>)> { let key_buf = Buffer::from_vec(key.to_vec()); let mut result_buf = Buffer::default(); let mut proof_buf = Buffer::default(); + let mut mp_key_buf = Buffer::default(); let mut err = Buffer::default(); let mut used_gas = 0_u64; let go_result: GoResult = (self.vtable.read_db)( @@ -65,6 +71,7 @@ impl Storage for DB { key_buf, &mut result_buf as *mut Buffer, &mut proof_buf as *mut Buffer, + &mut mp_key_buf as *mut Buffer, &mut err as *mut Buffer, ) .into(); @@ -99,7 +106,15 @@ impl Storage for DB { } else { Some(unsafe { proof_buf.consume() }) }; - (Ok((value, proof)), gas_info) + + // We initialize `proof_buf` with a null pointer. If it is not null, that means + // it was initialized by the go code, with values generated by `memory::allocate_rust`. + let mp_key = if mp_key_buf.ptr.is_null() { + None + } else { + Some(unsafe { mp_key_buf.consume() }) + }; + (Ok((value, proof, mp_key)), gas_info) } /// Allows iteration over a set of key/value pairs, either forwards or backwards. From fcaa7224136e28b6d075931ab9b6a3b660cb12b0 Mon Sep 17 00:00:00 2001 From: toml01 Date: Tue, 13 Jun 2023 18:56:22 +0300 Subject: [PATCH 14/51] demo of getting module hashes --- app/app.go | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/app/app.go b/app/app.go index 2c4253835..29eb0d838 100644 --- a/app/app.go +++ b/app/app.go @@ -21,6 +21,7 @@ import ( "github.com/cosmos/cosmos-sdk/server/config" servertypes "github.com/cosmos/cosmos-sdk/server/types" "github.com/cosmos/cosmos-sdk/simapp" + "github.com/cosmos/cosmos-sdk/store/rootmulti" sdk "github.com/cosmos/cosmos-sdk/types" "github.com/cosmos/cosmos-sdk/types/module" "github.com/cosmos/cosmos-sdk/x/authz" @@ -415,6 +416,19 @@ func (app *SecretNetworkApp) Name() string { return app.BaseApp.Name() } // BeginBlocker application updates every begin block func (app *SecretNetworkApp) BeginBlocker(ctx sdk.Context, req abci.RequestBeginBlock) abci.ResponseBeginBlock { + //////////////// EXPERIMENT //////////////// + multiStore := app.BaseApp.CommitMultiStore() + rootMulti, ok := multiStore.(*rootmulti.Store) + if !ok { + println("TOMMM oops") + } else { + stores := rootMulti.GetStores() + for k, v := range stores { + fmt.Printf("TOMMM root multi stores\nk: %+v\nhash: %+v\n", k.Name(), v.LastCommitID().Hash) + } + } + //////////////// EXPERIMENT //////////////// + return app.mm.BeginBlock(ctx, req) } From 8cada85e9e50416b3754aac09a4e89c84035355d Mon Sep 17 00:00:00 2001 From: toml01 Date: Wed, 14 Jun 2023 13:00:09 +0300 Subject: [PATCH 15/51] Implement storesRootsFromMultiStore() --- app/app.go | 54 +++++++++++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 53 insertions(+), 1 deletion(-) diff --git a/app/app.go b/app/app.go index 29eb0d838..0ceda97b4 100644 --- a/app/app.go +++ b/app/app.go @@ -1,11 +1,13 @@ package app import ( + "encoding/binary" "fmt" "io" "net/http" "os" "path/filepath" + "sort" "github.com/scrtlabs/SecretNetwork/app/keepers" icaauth "github.com/scrtlabs/SecretNetwork/x/mauth" @@ -23,6 +25,7 @@ import ( "github.com/cosmos/cosmos-sdk/simapp" "github.com/cosmos/cosmos-sdk/store/rootmulti" sdk "github.com/cosmos/cosmos-sdk/types" + "github.com/cosmos/cosmos-sdk/types/kv" "github.com/cosmos/cosmos-sdk/types/module" "github.com/cosmos/cosmos-sdk/x/authz" ica "github.com/cosmos/ibc-go/v3/modules/apps/27-interchain-accounts" @@ -424,14 +427,63 @@ func (app *SecretNetworkApp) BeginBlocker(ctx sdk.Context, req abci.RequestBegin } else { stores := rootMulti.GetStores() for k, v := range stores { - fmt.Printf("TOMMM root multi stores\nk: %+v\nhash: %+v\n", k.Name(), v.LastCommitID().Hash) + fmt.Printf("TOMMM store %s hash: %+v\n", k.Name(), v.LastCommitID().Hash) } } + + fmt.Printf("TOMMM respective app hash: %+v\n", rootMulti.LastCommitID().Hash) //////////////// EXPERIMENT //////////////// return app.mm.BeginBlock(ctx, req) } +func storesRootsFromMultiStore(rootMulti *rootmulti.Store) [][]byte { + stores := rootMulti.GetStores() + kvs := kv.Pairs{} + + for k, v := range stores { + // Stores of type StoreTypeTransient don't participate in AppHash calculation + if v.GetStoreType() == sdk.StoreTypeTransient { + continue + } + + kvs.Pairs = append(kvs.Pairs, kv.Pair{Key: []byte(k.Name()), Value: v.LastCommitID().Hash}) + } + + // Have to sort in order to calculate the correct AppHash + sort.Sort(kvs) + + storeRoots := make([][]byte, len(kvs.Pairs)) + for i, kvp := range kvs.Pairs { + storeRoots[i] = pairBytes(kvp) + } + + return storeRoots +} + +// This is a copy of an internal cosmos-sdk function: https://github.com/scrtlabs/cosmos-sdk/blob/1b9278476b3ac897d8ebb90241008476850bf212/store/internal/maps/maps.go#LL152C1-L152C1 +// pairBytes returns key || value, with both the +// key and value length prefixed. +func pairBytes(kv kv.Pair) []byte { + // In the worst case: + // * 8 bytes to Uvarint encode the length of the key + // * 8 bytes to Uvarint encode the length of the value + // So preallocate for the worst case, which will in total + // be a maximum of 14 bytes wasted, if len(key)=1, len(value)=1, + // but that's going to rare. + buf := make([]byte, 8+len(kv.Key)+8+len(kv.Value)) + + // Encode the key, prefixed with its length. + nlk := binary.PutUvarint(buf, uint64(len(kv.Key))) + nk := copy(buf[nlk:], kv.Key) + + // Encode the value, prefixing with its length. + nlv := binary.PutUvarint(buf[nlk+nk:], uint64(len(kv.Value))) + nv := copy(buf[nlk+nk+nlv:], kv.Value) + + return buf[:nlk+nk+nlv+nv] +} + // EndBlocker application updates every end block func (app *SecretNetworkApp) EndBlocker(ctx sdk.Context, req abci.RequestEndBlock) abci.ResponseEndBlock { return app.mm.EndBlock(ctx, req) From bda2c52fff5200e97874ebaa1ee4b1125ffa98c3 Mon Sep 17 00:00:00 2001 From: toml01 Date: Wed, 14 Jun 2023 13:25:25 +0300 Subject: [PATCH 16/51] Fix storesRootsFromMultiStore (hash value of store hash) --- app/app.go | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/app/app.go b/app/app.go index 0ceda97b4..aa9e253fb 100644 --- a/app/app.go +++ b/app/app.go @@ -87,6 +87,7 @@ import ( "github.com/gorilla/mux" "github.com/rakyll/statik/fs" abci "github.com/tendermint/tendermint/abci/types" + "github.com/tendermint/tendermint/crypto/tmhash" tmjson "github.com/tendermint/tendermint/libs/json" tmlog "github.com/tendermint/tendermint/libs/log" tmos "github.com/tendermint/tendermint/libs/os" @@ -447,7 +448,7 @@ func storesRootsFromMultiStore(rootMulti *rootmulti.Store) [][]byte { continue } - kvs.Pairs = append(kvs.Pairs, kv.Pair{Key: []byte(k.Name()), Value: v.LastCommitID().Hash}) + kvs.Pairs = append(kvs.Pairs, kv.Pair{Key: []byte(k.Name()), Value: tmhash.Sum(v.LastCommitID().Hash)}) } // Have to sort in order to calculate the correct AppHash From 5d28c260931742cc93c8b56ae7b36eaa2241ef5b Mon Sep 17 00:00:00 2001 From: toml01 Date: Thu, 15 Jun 2023 12:30:30 +0300 Subject: [PATCH 17/51] Some plumbing --- app/app.go | 33 ++++++---- cosmwasm/enclaves/execute/Enclave.edl | 6 ++ .../shared/block-verifier/src/ecalls.rs | 24 ++++++- cosmwasm/packages/sgx-vm/src/lib.rs | 16 ++--- cosmwasm/packages/sgx-vm/src/proofs.rs | 65 +++++++++++++++++++ go-cosmwasm/api/bindings.h | 2 + go-cosmwasm/api/lib.go | 12 ++++ go-cosmwasm/api/lib_mock.go | 4 ++ go-cosmwasm/src/lib.rs | 24 ++++++- 9 files changed, 159 insertions(+), 27 deletions(-) create mode 100644 cosmwasm/packages/sgx-vm/src/proofs.rs diff --git a/app/app.go b/app/app.go index aa9e253fb..6f2294b6a 100644 --- a/app/app.go +++ b/app/app.go @@ -10,6 +10,7 @@ import ( "sort" "github.com/scrtlabs/SecretNetwork/app/keepers" + gocosmwasm "github.com/scrtlabs/SecretNetwork/go-cosmwasm/api" icaauth "github.com/scrtlabs/SecretNetwork/x/mauth" "github.com/cosmos/cosmos-sdk/baseapp" @@ -420,25 +421,27 @@ func (app *SecretNetworkApp) Name() string { return app.BaseApp.Name() } // BeginBlocker application updates every begin block func (app *SecretNetworkApp) BeginBlocker(ctx sdk.Context, req abci.RequestBeginBlock) abci.ResponseBeginBlock { - //////////////// EXPERIMENT //////////////// multiStore := app.BaseApp.CommitMultiStore() rootMulti, ok := multiStore.(*rootmulti.Store) if !ok { - println("TOMMM oops") + panic("app's multi store is not of type *rootmulti.Store") } else { - stores := rootMulti.GetStores() - for k, v := range stores { - fmt.Printf("TOMMM store %s hash: %+v\n", k.Name(), v.LastCommitID().Hash) + storeRoots := storesRootsFromMultiStore(rootMulti) + rootsBytes, err := storeRoots.Marshal() + if err != nil { + panic(err) } - } - fmt.Printf("TOMMM respective app hash: %+v\n", rootMulti.LastCommitID().Hash) - //////////////// EXPERIMENT //////////////// + err = gocosmwasm.SubmitModulesStoreRoots(rootsBytes) + if err != nil { + panic(err) + } + } return app.mm.BeginBlock(ctx, req) } -func storesRootsFromMultiStore(rootMulti *rootmulti.Store) [][]byte { +func storesRootsFromMultiStore(rootMulti *rootmulti.Store) kv.Pairs { //[][]byte { stores := rootMulti.GetStores() kvs := kv.Pairs{} @@ -454,12 +457,14 @@ func storesRootsFromMultiStore(rootMulti *rootmulti.Store) [][]byte { // Have to sort in order to calculate the correct AppHash sort.Sort(kvs) - storeRoots := make([][]byte, len(kvs.Pairs)) - for i, kvp := range kvs.Pairs { - storeRoots[i] = pairBytes(kvp) - } + return kvs + + // storeRoots := make([][]byte, len(kvs.Pairs)) + // for i, kvp := range kvs.Pairs { + // storeRoots[i] = pairBytes(kvp) + // } - return storeRoots + // return storeRoots } // This is a copy of an internal cosmos-sdk function: https://github.com/scrtlabs/cosmos-sdk/blob/1b9278476b3ac897d8ebb90241008476850bf212/store/internal/maps/maps.go#LL152C1-L152C1 diff --git a/cosmwasm/enclaves/execute/Enclave.edl b/cosmwasm/enclaves/execute/Enclave.edl index 827eed8b7..8a961b939 100644 --- a/cosmwasm/enclaves/execute/Enclave.edl +++ b/cosmwasm/enclaves/execute/Enclave.edl @@ -117,6 +117,12 @@ enclave { // [in, count=in_next_validator_set_len] const uint8_t* in_next_validator_set, // uintptr_t in_next_validator_set_len ); + + public sgx_status_t ecall_submit_store_roots( + [in, count=in_roots_len] const uint8_t* in_roots, + uintptr_t in_roots_len + ); + }; untrusted { diff --git a/cosmwasm/enclaves/shared/block-verifier/src/ecalls.rs b/cosmwasm/enclaves/shared/block-verifier/src/ecalls.rs index 6da7d7d84..913ec3558 100644 --- a/cosmwasm/enclaves/shared/block-verifier/src/ecalls.rs +++ b/cosmwasm/enclaves/shared/block-verifier/src/ecalls.rs @@ -43,6 +43,25 @@ macro_rules! validate_input_length { }; } +#[no_mangle] +#[allow(unused_variables)] +pub unsafe extern "C" fn ecall_submit_store_roots( + in_roots: *const u8, + in_roots_len: u32, +) -> sgx_status_t { + validate_input_length!(in_roots_len, "roots", MAX_VARIABLE_LENGTH); + validate_const_ptr!( + in_roots, + in_roots_len as usize, + sgx_status_t::SGX_ERROR_INVALID_PARAMETER + ); + + let store_roots_slice = slice::from_raw_parts(in_roots, in_roots_len as usize); + debug!("store_roots_slice: {:?}", store_roots_slice); + + return sgx_status_t::SGX_SUCCESS; +} + /// # Safety /// This function reads buffers which must be correctly initialized by the caller, /// see safety section of slice::[from_raw_parts](https://doc.rust-lang.org/std/slice/fn.from_raw_parts.html#safety) @@ -214,7 +233,10 @@ pub unsafe extern "C" fn ecall_submit_block_signatures( } } - message_verifier.set_block_info(signed_header.header.height.value(), signed_header.header.time.unix_timestamp_nanos()); + message_verifier.set_block_info( + signed_header.header.height.value(), + signed_header.header.time.unix_timestamp_nanos(), + ); } #[cfg(feature = "random")] diff --git a/cosmwasm/packages/sgx-vm/src/lib.rs b/cosmwasm/packages/sgx-vm/src/lib.rs index a3e75bc66..1f92124d0 100644 --- a/cosmwasm/packages/sgx-vm/src/lib.rs +++ b/cosmwasm/packages/sgx-vm/src/lib.rs @@ -8,11 +8,7 @@ mod conversion; mod errors; mod features; mod ffi; -// mod imports; mod instance; -// mod memory; -// mod middleware; -// mod modules; mod serde; pub mod testing; mod traits; @@ -21,6 +17,7 @@ mod traits; mod attestation; mod enclave; mod enclave_config; +mod proofs; mod seed; mod wasmi; @@ -39,10 +36,6 @@ pub use crate::errors::{ pub use crate::features::features_from_csv; pub use crate::ffi::{FfiError, FfiResult, GasInfo}; pub use crate::instance::{GasReport, Instance}; -pub use enclave_config::{configure_enclave, EnclaveRuntimeConfig}; -/* -pub use crate::modules::FileSystemCache; -*/ pub use crate::serde::{from_slice, to_vec}; pub use crate::traits::{Api, Extern, Querier, Storage}; @@ -51,9 +44,10 @@ pub use crate::traits::StorageIterator; // Secret Network specific exports pub use crate::attestation::{create_attestation_report_u, untrusted_get_encrypted_seed}; +pub use crate::proofs::untrusted_submit_store_roots; +pub use crate::random::untrusted_submit_block_signatures; pub use crate::seed::{ - untrusted_health_check, untrusted_init_bootstrap, - untrusted_init_node, untrusted_key_gen, + untrusted_health_check, untrusted_init_bootstrap, untrusted_init_node, untrusted_key_gen, }; -pub use crate::random::untrusted_submit_block_signatures; +pub use enclave_config::{configure_enclave, EnclaveRuntimeConfig}; diff --git a/cosmwasm/packages/sgx-vm/src/proofs.rs b/cosmwasm/packages/sgx-vm/src/proofs.rs new file mode 100644 index 000000000..99ed5586c --- /dev/null +++ b/cosmwasm/packages/sgx-vm/src/proofs.rs @@ -0,0 +1,65 @@ +use sgx_types::*; + +use log::{debug, error, warn}; + +use crate::enclave::ENCLAVE_DOORBELL; + +extern "C" { + pub fn ecall_submit_store_roots( + eid: sgx_enclave_id_t, + retval: *mut sgx_status_t, + in_roots: *const u8, + in_roots_len: u32, + ) -> sgx_status_t; +} + +pub fn untrusted_submit_store_roots(roots: &[u8]) -> SgxResult<()> { + debug!("Hello from just before - untrusted_submit_store_roots"); + + const RETRY_LIMIT: i32 = 3; + + let mut retry_count = 0; + + // this is here so we can + loop { + let (retval, status) = submit_store_roots_impl(roots)?; + if status != sgx_status_t::SGX_SUCCESS { + return Err(status); + } else if retval != sgx_status_t::SGX_SUCCESS { + if retval == sgx_status_t::SGX_ERROR_FILE_RECOVERY_NEEDED { + warn!( + "Validator set read by enclave was mismatched with current height.. retrying" + ); + // retry with + std::thread::sleep(std::time::Duration::from_millis(500)); + retry_count += 1; + + if retry_count == RETRY_LIMIT { + error!("Validator timed out while waiting for correct validator set"); + return Err(retval); + } + } else { + return Err(retval); + } + } else { + return Ok(()); + } + } +} + +fn submit_store_roots_impl(roots: &[u8]) -> SgxResult<(sgx_status_t, sgx_status_t)> { + // Bind the token to a local variable to ensure its + // destructor runs in the end of the function + let enclave_access_token = ENCLAVE_DOORBELL + .get_access(1) // This can never be recursive + .ok_or(sgx_status_t::SGX_ERROR_BUSY)?; + let enclave = (*enclave_access_token)?; + + let eid = enclave.geteid(); + let mut retval = sgx_status_t::SGX_SUCCESS; + + // let status = unsafe { ecall_get_encrypted_seed(eid, &mut retval, cert, cert_len, & mut seed) }; + let status = + unsafe { ecall_submit_store_roots(eid, &mut retval, roots.as_ptr(), roots.len() as u32) }; + Ok((retval, status)) +} diff --git a/go-cosmwasm/api/bindings.h b/go-cosmwasm/api/bindings.h index f4173d7e2..428668b83 100644 --- a/go-cosmwasm/api/bindings.h +++ b/go-cosmwasm/api/bindings.h @@ -220,3 +220,5 @@ Buffer submit_block_signatures(Buffer header, Buffer txs, Buffer random, Buffer *err); + +bool submit_store_roots(Buffer roots, Buffer *err); diff --git a/go-cosmwasm/api/lib.go b/go-cosmwasm/api/lib.go index a9e08db3a..2f2681a84 100644 --- a/go-cosmwasm/api/lib.go +++ b/go-cosmwasm/api/lib.go @@ -68,6 +68,18 @@ func SubmitBlockSignatures(header []byte, commit []byte, txs []byte, encRandom [ return receiveVector(res), nil } +func SubmitModulesStoreRoots(roots []byte) error { + errmsg := C.Buffer{} + rootsSlice := sendSlice(roots) + defer freeAfterSend(rootsSlice) + + _, err := C.submit_store_roots(rootsSlice, &errmsg) + if err != nil { + return errorWithMessage(err, errmsg) + } + return nil +} + func InitBootstrap(spid []byte, apiKey []byte) ([]byte, error) { errmsg := C.Buffer{} spidSlice := sendSlice(spid) diff --git a/go-cosmwasm/api/lib_mock.go b/go-cosmwasm/api/lib_mock.go index ca007ae18..b1361490e 100644 --- a/go-cosmwasm/api/lib_mock.go +++ b/go-cosmwasm/api/lib_mock.go @@ -43,6 +43,10 @@ func SubmitBlockSignatures(header []byte, commit []byte, txs []byte, random []by return nil, nil } +func SubmitModulesStoreRoots(roots []byte) error { + return nil +} + func LoadSeedToEnclave(masterKey []byte, seed []byte, apiKey []byte) (bool, error) { return true, nil } diff --git a/go-cosmwasm/src/lib.rs b/go-cosmwasm/src/lib.rs index fd6e05915..5f3c734ca 100644 --- a/go-cosmwasm/src/lib.rs +++ b/go-cosmwasm/src/lib.rs @@ -221,11 +221,33 @@ pub extern "C" fn init_cache( } } +#[no_mangle] +pub extern "C" fn submit_store_roots(roots: Buffer, err: Option<&mut Buffer>) -> bool { + let roots_slice = match unsafe { roots.read() } { + None => { + set_error(Error::empty_arg("roots"), err); + return false; + } + Some(r) => r, + }; + + match cosmwasm_sgx_vm::untrusted_submit_store_roots(roots_slice) { + Err(e) => { + set_error(Error::enclave_err(e.to_string()), err); + false + } + Ok(()) => { + clear_error(); + true + } + } +} + #[no_mangle] pub extern "C" fn submit_block_signatures( header: Buffer, commit: Buffer, - txs: Buffer, + txs: Buffer, random: Buffer, // val_set: Buffer, // next_val_set: Buffer, From 3276cd4abfd549b88c6e3c835556937e62498db4 Mon Sep 17 00:00:00 2001 From: toml01 Date: Thu, 15 Jun 2023 17:15:52 +0300 Subject: [PATCH 18/51] Construct app hash --- cosmwasm/enclaves/Cargo.lock | 548 +++++++++++------- .../enclaves/shared/block-verifier/Cargo.toml | 18 +- .../shared/block-verifier/src/ecalls.rs | 38 +- 3 files changed, 393 insertions(+), 211 deletions(-) diff --git a/cosmwasm/enclaves/Cargo.lock b/cosmwasm/enclaves/Cargo.lock index 00183ca2f..a54c45f9d 100644 --- a/cosmwasm/enclaves/Cargo.lock +++ b/cosmwasm/enclaves/Cargo.lock @@ -8,7 +8,7 @@ version = "0.4.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0b613b8e1e3cf911a086f53f03bf286f52fd7a7258e4fa606f0ef220d39d8877" dependencies = [ - "generic-array 0.14.6", + "generic-array 0.14.7", ] [[package]] @@ -41,9 +41,9 @@ dependencies = [ [[package]] name = "aho-corasick" -version = "0.7.19" +version = "1.0.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b4f55bd91a0978cbfd91c457a164bab8b4001c833b7f323132c0a4e1922dd44e" +checksum = "43f6cb1bf222025340178f382c426f13757b2960e89779dfcb319c32542a5a41" dependencies = [ "memchr", ] @@ -64,9 +64,9 @@ source = "git+https://github.com/mesalock-linux/anyhow-sgx#9b7763f58b5dedc11f388 [[package]] name = "anyhow" -version = "1.0.66" +version = "1.0.71" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "216261ddc8289130e551ddcd5ce8a064710c0d064a4d2895c67151c92b5443f6" +checksum = "9c7d0618f0e0b7e8ff11427422b64564d5fb0be1940354bfe2e0529b18a9d9b8" [[package]] name = "atty" @@ -74,7 +74,7 @@ version = "0.2.14" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d9b39be18770d11421cdb1b9947a45dd3f37e93092cbf377614828a319d5fee8" dependencies = [ - "hermit-abi", + "hermit-abi 0.1.19", "libc", "winapi", ] @@ -184,16 +184,16 @@ version = "0.9.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "4152116fd6e9dadb291ae18fc1ec3575ed6d84c29642d97890f4b4a3417297e4" dependencies = [ - "generic-array 0.14.6", + "generic-array 0.14.7", ] [[package]] name = "block-buffer" -version = "0.10.3" +version = "0.10.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "69cce20737498f97b993470a6e536b8523f0af7892a4f928cceb1ac5e52ebe7e" +checksum = "3078c7629b62d3f0439517fa394996acacc5cbc91c5a20d8c658e77abd503a71" dependencies = [ - "generic-array 0.14.6", + "generic-array 0.14.7", ] [[package]] @@ -209,10 +209,12 @@ dependencies = [ name = "block-verifier" version = "0.1.0" dependencies = [ + "cosmos-sdk-proto", "cosmos_proto", "enclave_crypto", "enclave_utils", "hex", + "integer-encoding", "lazy_static", "log", "protobuf", @@ -221,7 +223,7 @@ dependencies = [ "sgx_types", "tendermint", "tendermint-light-client-verifier", - "tendermint-proto", + "tendermint-proto 0.28.0", ] [[package]] @@ -250,7 +252,7 @@ version = "1.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "89b2fd2a0dcf38d7971e2194b6b6eebab45ae01067456a7fd93d5547a61b70be" dependencies = [ - "serde 1.0.147", + "serde 1.0.164", ] [[package]] @@ -263,18 +265,18 @@ dependencies = [ "log", "proc-macro2", "quote", - "serde 1.0.147", - "serde_json 1.0.87", - "syn", + "serde 1.0.164", + "serde_json 1.0.96", + "syn 1.0.109", "tempfile", "toml", ] [[package]] name = "cc" -version = "1.0.73" +version = "1.0.79" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2fff2a6927b3bb87f9595d67196a70493f627687a71d87a0d692242c33f58c11" +checksum = "50d30906286121d95be3d479533b458f87493b30a4b5f79a607db8f5d11aa91f" [[package]] name = "cexpr" @@ -313,14 +315,14 @@ version = "0.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7ee52072ec15386f770805afd189a01c8841be8696bed250fa2f13c4c0d6dfb7" dependencies = [ - "generic-array 0.14.6", + "generic-array 0.14.7", ] [[package]] name = "clang-sys" -version = "1.4.0" +version = "1.6.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fa2e27ae6ab525c3d369ded447057bca5438d86dc3a68f6faafb8269ba82ebf3" +checksum = "c688fc74432808e3eb684cae8830a86be1d66a2bd58e1f248ed0960a590baf6f" dependencies = [ "glob", "libc", @@ -358,6 +360,17 @@ version = "0.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "6245d59a3e82a7fc217c5828a6692dbc6dfb63a0c8c90495621f7b9d79704a0e" +[[package]] +name = "cosmos-sdk-proto" +version = "0.16.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c4776e787b24d9568dd61d3237eeb4eb321d622fb881b858c7b82806420e87d4" +dependencies = [ + "prost 0.11.9", + "prost-types", + "tendermint-proto 0.27.0", +] + [[package]] name = "cosmos_proto" version = "1.6.0" @@ -369,9 +382,9 @@ dependencies = [ [[package]] name = "cpufeatures" -version = "0.2.5" +version = "0.2.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "28d997bd5e24a5928dd43e46dc529867e207907fe0b239c3477d924f7f2ca320" +checksum = "3e4c1eaa2012c47becbbad2ab175484c2a84d1185b566fb2cc5b8707343dfe58" dependencies = [ "libc", ] @@ -388,7 +401,7 @@ version = "0.1.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1bfb12502f3fc46cca1bb51ac28df9d618d813cdc3d2f25b9fe775a34af26bb3" dependencies = [ - "generic-array 0.14.6", + "generic-array 0.14.7", "typenum", ] @@ -399,7 +412,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b1d1a86f49236c215f271d40892d5fc950490551400b02ef360692c29815c714" dependencies = [ "cipher", - "generic-array 0.14.6", + "generic-array 0.14.7", "subtle", ] @@ -410,7 +423,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "6d2301688392eb071b0bf1a37be05c469d3cc4dbbd95df672fe28ab021e6a096" dependencies = [ "quote", - "syn", + "syn 1.0.109", ] [[package]] @@ -492,7 +505,7 @@ version = "0.3.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "bd2735a791158376708f9347fe8faba9667589d82427ef3aed6794a8981de3d9" dependencies = [ - "generic-array 0.14.6", + "generic-array 0.14.7", ] [[package]] @@ -505,7 +518,7 @@ dependencies = [ "proc-macro2", "quote", "rustc_version", - "syn", + "syn 1.0.109", ] [[package]] @@ -523,16 +536,16 @@ version = "0.9.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d3dd60d1080a57a05ab032377049e0591415d2b31afd7028356dbf3cc6dcb066" dependencies = [ - "generic-array 0.14.6", + "generic-array 0.14.7", ] [[package]] name = "digest" -version = "0.10.6" +version = "0.10.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8168378f4e5023e7218c89c891c0fd8ecdb5e5e4f18cb78f38cf245dd021e76f" +checksum = "9ed9a281f7bc9b7576e61468ba615a66a5c8cfdff42420a70aa82701a3b1e292" dependencies = [ - "block-buffer 0.10.3", + "block-buffer 0.10.4", "crypto-common", ] @@ -598,9 +611,9 @@ dependencies = [ [[package]] name = "either" -version = "1.8.0" +version = "1.8.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "90e5c1c8368803113bf0c9584fc495a58b86dc8a29edbf8fe877d21d9507e797" +checksum = "7fcaabb2fef8c910e7f4c7ce9f67a1283a1715879a7c230ca9d6d1ae31f16d91" [[package]] name = "enclave-ffi-types" @@ -638,7 +651,7 @@ dependencies = [ "pwasm-utils", "rand_chacha", "rand_core", - "secp256k1 0.24.2", + "secp256k1 0.24.3", "serde 1.0.118", "serde_json 1.0.60", "sgx_tstd", @@ -719,6 +732,27 @@ dependencies = [ "termcolor", ] +[[package]] +name = "errno" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4bcfec3a70f97c962c307b2d2c56e358cf1d00b558d74262b5f929ee8cc7e73a" +dependencies = [ + "errno-dragonfly", + "libc", + "windows-sys", +] + +[[package]] +name = "errno-dragonfly" +version = "0.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "aa68f1b12764fab894d2755d2518754e71b4fd80ecfb822714a1206c2aab39bf" +dependencies = [ + "cc", + "libc", +] + [[package]] name = "fake-simd" version = "0.1.2" @@ -727,9 +761,9 @@ checksum = "e88a8acf291dafb59c2d96e8f59828f3838bb1a70398823ade51a84de6a6deed" [[package]] name = "fastrand" -version = "1.8.0" +version = "1.9.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a7a407cfaa3385c4ae6b23e84623d48c2798d06e3e6a1878f7f59f17b3f86499" +checksum = "e51093e27b0797c359783294ca4f0a911c270184cb10f85783b118614a1501be" dependencies = [ "instant", ] @@ -745,9 +779,9 @@ dependencies = [ [[package]] name = "futures" -version = "0.3.26" +version = "0.3.28" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "13e2792b0ff0340399d58445b88fd9770e3489eff258a4cbc1523418f12abf84" +checksum = "23342abe12aba583913b2e62f22225ff9c950774065e4bfb61a19cd9770fec40" dependencies = [ "futures-channel", "futures-core", @@ -759,9 +793,9 @@ dependencies = [ [[package]] name = "futures-channel" -version = "0.3.26" +version = "0.3.28" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2e5317663a9089767a1ec00a487df42e0ca174b61b4483213ac24448e4664df5" +checksum = "955518d47e09b25bbebc7a18df10b81f0c766eaf4c4f1cccef2fca5f2a4fb5f2" dependencies = [ "futures-core", "futures-sink", @@ -769,33 +803,33 @@ dependencies = [ [[package]] name = "futures-core" -version = "0.3.26" +version = "0.3.28" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ec90ff4d0fe1f57d600049061dc6bb68ed03c7d2fbd697274c41805dcb3f8608" +checksum = "4bca583b7e26f571124fe5b7561d49cb2868d79116cfa0eefce955557c6fee8c" [[package]] name = "futures-io" -version = "0.3.26" +version = "0.3.28" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bfb8371b6fb2aeb2d280374607aeabfc99d95c72edfe51692e42d3d7f0d08531" +checksum = "4fff74096e71ed47f8e023204cfd0aa1289cd54ae5430a9523be060cdb849964" [[package]] name = "futures-sink" -version = "0.3.26" +version = "0.3.28" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f310820bb3e8cfd46c80db4d7fb8353e15dfff853a127158425f31e0be6c8364" +checksum = "f43be4fe21a13b9781a69afa4985b0f6ee0e1afab2c6f454a8cf30e2b2237b6e" [[package]] name = "futures-task" -version = "0.3.26" +version = "0.3.28" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dcf79a1bf610b10f42aea489289c5a2c478a786509693b80cd39c44ccd936366" +checksum = "76d3d132be6c0e6aa1534069c705a74a5997a356c0dc2f86a47765e5617c5b65" [[package]] name = "futures-util" -version = "0.3.26" +version = "0.3.28" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9c1d6de3acfef38d2be4b1f543f553131788603495be83da675e180c8d6b7bd1" +checksum = "26b01e40b772d54cf6c6d721c1d1abd0647a0106a12ecaa1c186273392a69533" dependencies = [ "futures-core", "futures-sink", @@ -815,9 +849,9 @@ dependencies = [ [[package]] name = "generic-array" -version = "0.14.6" +version = "0.14.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bff49e947297f3312447abdca79f45f4738097cc82b06e72054d2223f601f1b9" +checksum = "85649ca51fd72272d7821adaf274ad91c288277713d9c18820d8499a7ff69e9a" dependencies = [ "typenum", "version_check", @@ -836,9 +870,9 @@ dependencies = [ [[package]] name = "getrandom" -version = "0.2.8" +version = "0.2.10" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c05aeb6a22b8f62540c194aac980f2115af067bfe15a0734d7277a768d396b31" +checksum = "be4136b2a15dd319360be1c07d9933517ccf0be8f16bf62a3bee4f0d618df427" dependencies = [ "cfg-if 1.0.0", "libc", @@ -847,9 +881,9 @@ dependencies = [ [[package]] name = "glob" -version = "0.3.0" +version = "0.3.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9b919933a397b79c37e33b77bb2aa3dc8eb6e165ad809e58ff75bc7db2e34574" +checksum = "d2fabcfbdc87f4758337ca535fb41a6d701b65693ce38287d856d1674551ec9b" [[package]] name = "hashbrown_tstd" @@ -873,6 +907,12 @@ dependencies = [ "libc", ] +[[package]] +name = "hermit-abi" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fed44880c466736ef9a5c5b5facefb5ed0785676d0c02d612db14e54f0d84286" + [[package]] name = "hex" version = "0.4.3" @@ -904,7 +944,7 @@ source = "git+https://github.com/scrtlabs/impl-trait-for-tuples?tag=v0.2.2-secre dependencies = [ "proc-macro2", "quote", - "syn", + "syn 1.0.109", ] [[package]] @@ -916,6 +956,23 @@ dependencies = [ "cfg-if 1.0.0", ] +[[package]] +name = "integer-encoding" +version = "3.0.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8bb03732005da905c88227371639bf1ad885cc712789c011c31c5fb3ab3ccf02" + +[[package]] +name = "io-lifetimes" +version = "1.0.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "eae7b9aee968036d54dce06cebaefd919e4472e753296daccd6d344e3e2df0c2" +dependencies = [ + "hermit-abi 0.3.1", + "libc", + "windows-sys", +] + [[package]] name = "itertools" version = "0.8.2" @@ -944,15 +1001,18 @@ dependencies = [ [[package]] name = "itoa" -version = "1.0.4" +version = "1.0.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4217ad341ebadf8d8e724e264f13e593e0648f5b3e94b3896a5df283be015ecc" +checksum = "453ad9f582a441959e5f0d088b02ce04cfe8d51a8eaf077f12ac6d3e94164ca6" [[package]] name = "keccak" -version = "0.1.2" +version = "0.1.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f9b7d56ba4a8344d6be9729995e6b06f928af29998cdf79fe390cbf6b1fee838" +checksum = "8f6d5ed8676d904364de097082f4e7d240b571b67989ced0240f08b7f966f940" +dependencies = [ + "cpufeatures", +] [[package]] name = "lazy_static" @@ -974,9 +1034,9 @@ checksum = "884e2677b40cc8c339eaefcb701c32ef1fd2493d71118dc0ca4b6a736c93bd67" [[package]] name = "libc" -version = "0.2.137" +version = "0.2.146" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fc7fcc620a3bff7cdd7a365be3376c97191aeaccc2a603e600951e452615bf89" +checksum = "f92be4933c13fd498862a9e02a3055f8a8d9c039ce33db97306fd5a6caa7f29b" [[package]] name = "libloading" @@ -994,20 +1054,23 @@ version = "0.1.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7fc7aa29613bd6a620df431842069224d8bc9011086b1db4c0e0cd47fa03ec9a" +[[package]] +name = "linux-raw-sys" +version = "0.3.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ef53942eb7bf7ff43a617b3e2c1c4a5ecf5944a7c1bc12d7ee39bbb15e5c1519" + [[package]] name = "log" -version = "0.4.17" +version = "0.4.19" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "abb12e687cfb44aa40f41fc3978ef76448f9b6038cad6aef4259d3c095a2382e" -dependencies = [ - "cfg-if 1.0.0", -] +checksum = "b06a4cde4c0f271a446782e3eff8de789548ce57dbc8eca9292c27f4a42004b4" [[package]] name = "lru" -version = "0.7.1" +version = "0.7.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "469898e909a1774d844793b347135a0cd344ca2f69d082013ecb8061a2229a3a" +checksum = "e999beba7b6e8345721bd280141ed958096a2e4abdf74f67ff4ce49b4b54e47a" [[package]] name = "memchr" @@ -1023,9 +1086,9 @@ checksum = "71d96e3f3c0b6325d8ccd83c33b28acb183edcb6c67938ba104ec546854b0882" [[package]] name = "nom" -version = "5.1.2" +version = "5.1.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ffb4262d26ed83a1c0a33a38fe2bb15797329c85770da05e6b828ddb782627af" +checksum = "08959a387a676302eebf4ddbcbc611da04285579f76f88ee0506c63b1a61dd4b" dependencies = [ "memchr", "version_check", @@ -1050,7 +1113,7 @@ checksum = "876a53fff98e03a936a674b29568b0e605f06b29372c2489ff4de23f1949743d" dependencies = [ "proc-macro2", "quote", - "syn", + "syn 1.0.109", ] [[package]] @@ -1104,29 +1167,29 @@ dependencies = [ [[package]] name = "num_enum" -version = "0.5.7" +version = "0.5.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cf5395665662ef45796a4ff5486c5d41d29e0c09640af4c5f17fd94ee2c119c9" +checksum = "1f646caf906c20226733ed5b1374287eb97e3c2a5c227ce668c1f2ce20ae57c9" dependencies = [ "num_enum_derive", ] [[package]] name = "num_enum_derive" -version = "0.5.7" +version = "0.5.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3b0498641e53dd6ac1a4f22547548caa6864cc4933784319cd1775271c5a46ce" +checksum = "dcbff9bc912032c62bf65ef1d5aea88983b420f4f839db1e9b0c281a25c9c799" dependencies = [ "proc-macro2", "quote", - "syn", + "syn 1.0.109", ] [[package]] name = "once_cell" -version = "1.15.0" +version = "1.18.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e82dad04139b71a90c080c8463fe0dc7902db5192d939bd0950f074d014339e1" +checksum = "dd8b5dd2ae5ed71462c540258bedcb51965123ad7e7ccf4b9a8cafaa4a63576d" [[package]] name = "opaque-debug" @@ -1148,9 +1211,9 @@ checksum = "ddfc878dac00da22f8f61e7af3157988424567ab01d9920b962ef7dcbd7cd865" [[package]] name = "paste" -version = "1.0.11" +version = "1.0.12" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d01a5bd0424d00070b0098dd17ebca6f961a959dead1dbcbbbc1d1cd8d3deeba" +checksum = "9f746c4065a8fa3fe23974dd82f15431cc8d40779821001404d10d2e79ca7d79" [[package]] name = "peeking_take_while" @@ -1172,15 +1235,15 @@ checksum = "8b870d8c151b6f2fb93e84a13146138f05d02ed11c7e7c54f8826aaaf7c9f184" [[package]] name = "ppv-lite86" -version = "0.2.16" +version = "0.2.17" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "eb9f9e6e233e5c4a35559a617bf40a4ec447db2e84c20b55a6f83167b7e57872" +checksum = "5b40af805b3121feab8a3c29f04d8ad262fa8e0561883e7653e024ae4479e6de" [[package]] name = "proc-macro2" -version = "1.0.47" +version = "1.0.60" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5ea3d908b0e36316caf9e9e2c4625cdde190a7e6f440d794667ed17a1855e725" +checksum = "dec2b086b7a862cf4de201096214fa870344cf922b2b30c167badb3af3195406" dependencies = [ "unicode-ident", ] @@ -1196,12 +1259,12 @@ dependencies = [ [[package]] name = "prost" -version = "0.11.6" +version = "0.11.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "21dc42e00223fc37204bd4aa177e69420c604ca4a183209a8f9de30c6d934698" +checksum = "0b82eaa1d779e9a4bc1c3217db8ffbeabaae1dca241bf70183242128d48681cd" dependencies = [ "bytes 1.4.0", - "prost-derive 0.11.6", + "prost-derive 0.11.9", ] [[package]] @@ -1213,30 +1276,29 @@ dependencies = [ "itertools 0.8.2", "proc-macro2", "quote", - "syn", + "syn 1.0.109", ] [[package]] name = "prost-derive" -version = "0.11.6" +version = "0.11.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8bda8c0881ea9f722eb9629376db3d0b903b462477c1aafcb0566610ac28ac5d" +checksum = "e5d2d8d10f3c6ded6da8b05b5fb3b8a5082514344d56c9f871412d29b4e075b4" dependencies = [ - "anyhow 1.0.66", + "anyhow 1.0.71", "itertools 0.10.5", "proc-macro2", "quote", - "syn", + "syn 1.0.109", ] [[package]] name = "prost-types" -version = "0.11.6" +version = "0.11.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a5e0526209433e96d83d750dd81a99118edbc55739e7e61a46764fd2ad537788" +checksum = "213622a1460818959ac1181aaeb2dc9c7f63df720db7d788b3e24eacd1983e13" dependencies = [ - "bytes 1.4.0", - "prost 0.11.6", + "prost 0.11.9", ] [[package]] @@ -1261,7 +1323,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9ac70cfc8935f5db2a29c0929db697035d02284011a9b78a5ef5d48092ce9673" dependencies = [ "log", - "which 4.3.0", + "which 4.4.0", ] [[package]] @@ -1289,9 +1351,9 @@ dependencies = [ [[package]] name = "quote" -version = "1.0.21" +version = "1.0.28" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bbe448f377a7d6961e30f5955f9b8d106c3f5e449d493ee1b125c1d43c2b5179" +checksum = "1b9ab9c7eadfd8df19006f1cf1a4aed13540ed5cbc047010ece5826e10825488" dependencies = [ "proc-macro2", ] @@ -1324,22 +1386,31 @@ dependencies = [ "bitflags", ] +[[package]] +name = "redox_syscall" +version = "0.3.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "567664f262709473930a4bf9e51bf2ebf3348f2e748ccc50dea20646858f8f29" +dependencies = [ + "bitflags", +] + [[package]] name = "redox_users" version = "0.4.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b033d837a7cf162d7993aded9304e30a83213c648b6e389db233191f891e5c2b" dependencies = [ - "getrandom 0.2.8", - "redox_syscall", + "getrandom 0.2.10", + "redox_syscall 0.2.16", "thiserror", ] [[package]] name = "regex" -version = "1.7.0" +version = "1.8.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e076559ef8e241f2ae3479e36f97bd5741c0330689e217ad51ce2c76808b868a" +checksum = "d0ab3ca65655bb1e41f2a8c8cd662eb4fb035e67c3f78da1d61dffe89d07300f" dependencies = [ "aho-corasick", "memchr", @@ -1348,18 +1419,9 @@ dependencies = [ [[package]] name = "regex-syntax" -version = "0.6.28" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "456c603be3e8d448b072f410900c09faf164fbce2d480456f50eea6e25f9c848" - -[[package]] -name = "remove_dir_all" -version = "0.5.3" +version = "0.7.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3acd125665422973a33ac9d3dd2df85edad0f4ae9b00dafb1a05e43a9f5ef8e7" -dependencies = [ - "winapi", -] +checksum = "436b050e76ed2903236f032a59761c1eb99e1b0aead2c257922771dab1fc8c78" [[package]] name = "ring" @@ -1398,6 +1460,20 @@ dependencies = [ "semver", ] +[[package]] +name = "rustix" +version = "0.37.20" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b96e891d04aa506a6d1f318d2771bcb1c7dfda84e126660ace067c9b474bb2c0" +dependencies = [ + "bitflags", + "errno", + "io-lifetimes", + "libc", + "linux-raw-sys", + "windows-sys", +] + [[package]] name = "rustls" version = "0.19.0" @@ -1412,9 +1488,9 @@ dependencies = [ [[package]] name = "ryu" -version = "1.0.11" +version = "1.0.13" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4501abdff3ae82a1c1b477a17252eb69cee9e66eb915c1abaa4f44d873df9f09" +checksum = "f91339c0467de62360649f8d3e185ca8de4224ff281f66000de5eb2a77a79041" [[package]] name = "sct" @@ -1428,9 +1504,9 @@ dependencies = [ [[package]] name = "secp256k1" -version = "0.24.2" +version = "0.24.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d9512ffd81e3a3503ed401f79c33168b9148c75038956039166cd750eaa037c3" +checksum = "6b1629c9c557ef9b293568b338dddfc8208c98a18c59d722a9d53f859d9c9b62" dependencies = [ "secp256k1-sys 0.6.1", ] @@ -1441,7 +1517,7 @@ version = "0.26.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "4124a35fe33ae14259c490fd70fa199a32b9ce9502f2ee6bc4f81ec06fa65894" dependencies = [ - "secp256k1-sys 0.8.0", + "secp256k1-sys 0.8.1", ] [[package]] @@ -1455,9 +1531,9 @@ dependencies = [ [[package]] name = "secp256k1-sys" -version = "0.8.0" +version = "0.8.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "642a62736682fdd8c71da0eb273e453c8ac74e33b9fb310e22ba5b03ec7651ff" +checksum = "70a129b9e9efbfb223753b9163c4ab3b13cff7fd9c7f010fbac25ab4099fa07e" dependencies = [ "cc", ] @@ -1517,9 +1593,9 @@ dependencies = [ [[package]] name = "semver" -version = "1.0.14" +version = "1.0.17" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e25dfac463d778e353db5be2449d1cce89bd6fd23c9f1ea21310ce6e5a1b29c4" +checksum = "bebd363326d05ec3e2f532ab7660680f3b02130d780c299bca73469d521bc0ed" [[package]] name = "serde" @@ -1532,11 +1608,11 @@ dependencies = [ [[package]] name = "serde" -version = "1.0.147" +version = "1.0.164" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d193d69bae983fc11a79df82342761dfbf28a99fc8d203dca4c3c1b590948965" +checksum = "9e8c8cf938e98f769bc164923b06dce91cea1751522f46f8466461af04c9027d" dependencies = [ - "serde_derive 1.0.147", + "serde_derive 1.0.164", ] [[package]] @@ -1545,7 +1621,7 @@ version = "0.11.9" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "416bda436f9aab92e02c8e10d49a15ddd339cea90b6e340fe51ed97abb548294" dependencies = [ - "serde 1.0.147", + "serde 1.0.164", ] [[package]] @@ -1555,18 +1631,18 @@ source = "git+https://github.com/mesalock-linux/serde-sgx#db0226f1d5d70fca6b96af dependencies = [ "proc-macro2", "quote", - "syn", + "syn 1.0.109", ] [[package]] name = "serde_derive" -version = "1.0.147" +version = "1.0.164" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4f1d362ca8fc9c3e3a7484440752472d68a6caa98f1ab81d99b5dfe517cec852" +checksum = "d9735b638ccc51c28bf6914d90a2e9725b377144fc612c49a611fddd1b631d68" dependencies = [ "proc-macro2", "quote", - "syn", + "syn 2.0.18", ] [[package]] @@ -1582,24 +1658,24 @@ dependencies = [ [[package]] name = "serde_json" -version = "1.0.87" +version = "1.0.96" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6ce777b7b150d76b9cf60d28b55f5847135a003f7d7350c6be7a773508ce7d45" +checksum = "057d394a50403bcac12672b2b18fb387ab6d289d957dab67dd201875391e52f1" dependencies = [ - "itoa 1.0.4", + "itoa 1.0.6", "ryu", - "serde 1.0.147", + "serde 1.0.164", ] [[package]] name = "serde_repr" -version = "0.1.10" +version = "0.1.12" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9a5ec9fa74a20ebbe5d9ac23dac1fc96ba0ecfe9f50f2843b52e537b10fbcb4e" +checksum = "bcec881020c684085e55a25f7fd888954d56609ef363479dc5a1305eb0d40cab" dependencies = [ "proc-macro2", "quote", - "syn", + "syn 2.0.18", ] [[package]] @@ -1728,16 +1804,16 @@ checksum = "82e6b795fe2e3b1e845bafcb27aa35405c4d47cdfc92af5fc8d3002f76cebdc0" dependencies = [ "cfg-if 1.0.0", "cpufeatures", - "digest 0.10.6", + "digest 0.10.7", ] [[package]] name = "sha3" -version = "0.10.6" +version = "0.10.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bdf0c33fae925bdc080598b84bc15c55e7b9a4a43b3c704da051f977469691c9" +checksum = "75872d278a8f37ef87fa0ddbda7802605cb18344497949862c0d4dcb291eba60" dependencies = [ - "digest 0.10.6", + "digest 0.10.7", "keccak", ] @@ -1805,9 +1881,9 @@ dependencies = [ [[package]] name = "syn" -version = "1.0.103" +version = "1.0.109" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a864042229133ada95abf3b54fdc62ef5ccabe9515b64717bcb9a1919e59445d" +checksum = "72b64191b275b66ffe2469e8af2c1cfe3bafa67b529ead792a6d0160888b4237" dependencies = [ "proc-macro2", "quote", @@ -1815,35 +1891,34 @@ dependencies = [ ] [[package]] -name = "synstructure" -version = "0.12.6" +name = "syn" +version = "2.0.18" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f36bdaa60a83aca3921b5259d5400cbf5e90fc51931376a9bd4a0eb79aa7210f" +checksum = "32d41677bcbe24c20c52e7c70b0d8db04134c5d1066bf98662e2871ad200ea3e" dependencies = [ "proc-macro2", "quote", - "syn", - "unicode-xid", + "unicode-ident", ] [[package]] name = "tempfile" -version = "3.3.0" +version = "3.6.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5cdb1ef4eaeeaddc8fbd371e5017057064af0911902ef36b39801f67cc6d79e4" +checksum = "31c0432476357e58790aaa47a8efb0c5138f137343f3b5f23bd36a27e3b0a6d6" dependencies = [ + "autocfg 1.1.0", "cfg-if 1.0.0", "fastrand", - "libc", - "redox_syscall", - "remove_dir_all", - "winapi", + "redox_syscall 0.3.5", + "rustix", + "windows-sys", ] [[package]] name = "tendermint" version = "0.28.0" -source = "git+https://github.com/scrtlabs/tendermint-rs?branch=fix-val-set-parsing#4019839ff894e531fbe4187f8461e4395d203220" +source = "git+https://github.com/scrtlabs/tendermint-rs?branch=fix-val-set-parsing#b75754a49981f8e52fa12b8c17a38ebda575f807" dependencies = [ "bytes 1.4.0", "ed25519", @@ -1852,17 +1927,17 @@ dependencies = [ "futures", "num-traits 0.2.15", "once_cell", - "prost 0.11.6", + "prost 0.11.9", "prost-types", - "serde 1.0.147", + "serde 1.0.164", "serde_bytes", - "serde_json 1.0.87", + "serde_json 1.0.96", "serde_repr", "sha2 0.9.9", "signature", "subtle", "subtle-encoding", - "tendermint-proto", + "tendermint-proto 0.28.0", "time", "zeroize", ] @@ -1870,27 +1945,45 @@ dependencies = [ [[package]] name = "tendermint-light-client-verifier" version = "0.28.0" -source = "git+https://github.com/scrtlabs/tendermint-rs?branch=fix-val-set-parsing#4019839ff894e531fbe4187f8461e4395d203220" +source = "git+https://github.com/scrtlabs/tendermint-rs?branch=fix-val-set-parsing#b75754a49981f8e52fa12b8c17a38ebda575f807" dependencies = [ "derive_more", "flex-error", - "serde 1.0.147", + "serde 1.0.164", "tendermint", "time", ] +[[package]] +name = "tendermint-proto" +version = "0.27.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d5895470f28c530f8ae8c4071bf8190304ce00bd131d25e81730453124a3375c" +dependencies = [ + "bytes 1.4.0", + "flex-error", + "num-derive", + "num-traits 0.2.15", + "prost 0.11.9", + "prost-types", + "serde 1.0.164", + "serde_bytes", + "subtle-encoding", + "time", +] + [[package]] name = "tendermint-proto" version = "0.28.0" -source = "git+https://github.com/scrtlabs/tendermint-rs?branch=fix-val-set-parsing#4019839ff894e531fbe4187f8461e4395d203220" +source = "git+https://github.com/scrtlabs/tendermint-rs?branch=fix-val-set-parsing#b75754a49981f8e52fa12b8c17a38ebda575f807" dependencies = [ "bytes 1.4.0", "flex-error", "num-derive", "num-traits 0.2.15", - "prost 0.11.6", + "prost 0.11.9", "prost-types", - "serde 1.0.147", + "serde 1.0.164", "serde_bytes", "subtle-encoding", "time", @@ -1898,9 +1991,9 @@ dependencies = [ [[package]] name = "termcolor" -version = "1.1.3" +version = "1.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bab24d30b911b2376f3a13cc2cd443142f0c81dda04c118693e35b3835757755" +checksum = "be55cf8942feac5c765c2c993422806843c9a9a45d4d5c407ad6dd2ea95eb9b6" dependencies = [ "winapi-util", ] @@ -1916,22 +2009,22 @@ dependencies = [ [[package]] name = "thiserror" -version = "1.0.37" +version = "1.0.40" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "10deb33631e3c9018b9baf9dcbbc4f737320d2b576bac10f6aefa048fa407e3e" +checksum = "978c9a314bd8dc99be594bc3c175faaa9794be04a5a5e153caba6915336cebac" dependencies = [ "thiserror-impl", ] [[package]] name = "thiserror-impl" -version = "1.0.37" +version = "1.0.40" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "982d17546b47146b28f7c22e3d08465f6b8903d0ea13c1660d9d84a6e7adcdbb" +checksum = "f9456a42c5b0d803c8cd86e73dd7cc9edd429499f37a3550d286d5e86720569f" dependencies = [ "proc-macro2", "quote", - "syn", + "syn 2.0.18", ] [[package]] @@ -1940,7 +2033,7 @@ version = "0.3.17" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a561bf4617eebd33bca6434b988f39ed798e527f51a1e797d0ee4f61c0a38376" dependencies = [ - "serde 1.0.147", + "serde 1.0.164", "time-core", "time-macros", ] @@ -1962,18 +2055,18 @@ dependencies = [ [[package]] name = "toml" -version = "0.5.9" +version = "0.5.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8d82e1a7758622a465f8cee077614c73484dac5b836c02ff6a40d5d1010324d7" +checksum = "f4f7f0dd8d50a853a531c426359045b1998f04219d88799810762cd4ad314234" dependencies = [ - "serde 1.0.147", + "serde 1.0.164", ] [[package]] name = "typenum" -version = "1.15.0" +version = "1.16.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dcf81ac59edc17cc8697ff311e8f5ef2d99fcbd9817b34cec66f90b6c3dfd987" +checksum = "497961ef93d974e23eb6f433eb5fe1b7930b659f06d12dec6fc44a8f554c0bba" [[package]] name = "uint" @@ -1989,15 +2082,15 @@ dependencies = [ [[package]] name = "unicode-ident" -version = "1.0.5" +version = "1.0.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6ceab39d59e4c9499d4e5a8ee0e2735b891bb7308ac83dfb4e80cad195c9f6f3" +checksum = "b15811caf2415fb889178633e7724bad2509101cde276048e013b9def5e51fa0" [[package]] name = "unicode-segmentation" -version = "1.10.0" +version = "1.10.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0fdbf052a0783de01e944a6ce7a8cb939e295b1e7be835a1112c3b9a7f047a5a" +checksum = "1dd624098567895118886609431a7c3b8f516e41d30e0643f03d94592a147e36" [[package]] name = "unicode-width" @@ -2005,12 +2098,6 @@ version = "0.1.10" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c0edd1e5b14653f783770bce4a4dabb4a5108a5370a5f5d8cfe8710c361f6c8b" -[[package]] -name = "unicode-xid" -version = "0.2.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f962df74c8c05a667b5ee8bcf162993134c104e96440b663c8daa176dc772d8c" - [[package]] name = "untrusted" version = "0.7.1" @@ -2040,7 +2127,7 @@ name = "walrus" version = "0.19.0" source = "git+https://github.com/scrtlabs/walrus?rev=c5777d4#c5777d43d78b437cef94aaa939d3be115dfeee6a" dependencies = [ - "anyhow 1.0.66", + "anyhow 1.0.71", "id-arena", "leb128", "log", @@ -2056,7 +2143,7 @@ dependencies = [ "heck", "proc-macro2", "quote", - "syn", + "syn 1.0.109", ] [[package]] @@ -2145,9 +2232,9 @@ dependencies = [ [[package]] name = "which" -version = "4.3.0" +version = "4.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1c831fbbee9e129a8cf93e7747a82da9d95ba8e16621cae60ec2cdc849bacb7b" +checksum = "2441c784c52b289a054b7201fc93253e288f094e2f4be9058343127c4226a269" dependencies = [ "either", "libc", @@ -2185,6 +2272,72 @@ version = "0.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f" +[[package]] +name = "windows-sys" +version = "0.48.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "677d2418bec65e3338edb076e806bc1ec15693c5d0104683f2efe857f61056a9" +dependencies = [ + "windows-targets", +] + +[[package]] +name = "windows-targets" +version = "0.48.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7b1eb6f0cd7c80c79759c929114ef071b87354ce476d9d94271031c0497adfd5" +dependencies = [ + "windows_aarch64_gnullvm", + "windows_aarch64_msvc", + "windows_i686_gnu", + "windows_i686_msvc", + "windows_x86_64_gnu", + "windows_x86_64_gnullvm", + "windows_x86_64_msvc", +] + +[[package]] +name = "windows_aarch64_gnullvm" +version = "0.48.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "91ae572e1b79dba883e0d315474df7305d12f569b400fcf90581b06062f7e1bc" + +[[package]] +name = "windows_aarch64_msvc" +version = "0.48.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b2ef27e0d7bdfcfc7b868b317c1d32c641a6fe4629c171b8928c7b08d98d7cf3" + +[[package]] +name = "windows_i686_gnu" +version = "0.48.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "622a1962a7db830d6fd0a69683c80a18fda201879f0f447f065a3b7467daa241" + +[[package]] +name = "windows_i686_msvc" +version = "0.48.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4542c6e364ce21bf45d69fdd2a8e455fa38d316158cfd43b3ac1c5b1b19f8e00" + +[[package]] +name = "windows_x86_64_gnu" +version = "0.48.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ca2b8a661f7628cbd23440e50b05d705db3686f894fc9580820623656af974b1" + +[[package]] +name = "windows_x86_64_gnullvm" +version = "0.48.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7896dbc1f41e08872e9d5e8f8baa8fdd2677f29468c4e156210174edc7f7b953" + +[[package]] +name = "windows_x86_64_msvc" +version = "0.48.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1a515f5799fe4961cb532f983ce2b23082366b898e52ffbce459c86f67c8378a" + [[package]] name = "x25519-dalek" version = "1.2.0" @@ -2218,12 +2371,11 @@ dependencies = [ [[package]] name = "zeroize_derive" -version = "1.3.2" +version = "1.4.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3f8f187641dad4f680d25c4bfc4225b418165984179f26ca76ec4fb6441d3a17" +checksum = "ce36e65b0d2999d2aafac989fb249189a141aee1f53c612c1f37d72631959f69" dependencies = [ "proc-macro2", "quote", - "syn", - "synstructure", + "syn 2.0.18", ] diff --git a/cosmwasm/enclaves/shared/block-verifier/Cargo.toml b/cosmwasm/enclaves/shared/block-verifier/Cargo.toml index aeca2ed98..157af85dd 100644 --- a/cosmwasm/enclaves/shared/block-verifier/Cargo.toml +++ b/cosmwasm/enclaves/shared/block-verifier/Cargo.toml @@ -15,7 +15,7 @@ verify-validator-whitelist = [] [target.'cfg(not(target_env = "sgx"))'.dependencies] sgx_tstd = { rev = "d2d339cbb005f676bb700059bd51dc689c025f6b", git = "https://github.com/apache/teaclave-sgx-sdk.git", features = [ ] } -sgx_trts = {rev = "d2d339cbb005f676bb700059bd51dc689c025f6b", git = "https://github.com/apache/teaclave-sgx-sdk.git" } +sgx_trts = { rev = "d2d339cbb005f676bb700059bd51dc689c025f6b", git = "https://github.com/apache/teaclave-sgx-sdk.git" } sgx_types = { rev = "d2d339cbb005f676bb700059bd51dc689c025f6b", git = "https://github.com/apache/teaclave-sgx-sdk.git" } [dependencies] @@ -24,16 +24,10 @@ tendermint-proto = { git = "https://github.com/scrtlabs/tendermint-rs", branch = tendermint-light-client-verifier = { git = "https://github.com/scrtlabs/tendermint-rs", branch = "fix-val-set-parsing", default-features = false } lazy_static = "1.4.0" log = "0.4.17" - -enclave_crypto = {path ="../crypto"} -enclave_utils = {path ="../utils"} - -cosmos_proto = {path="../cosmos-proto"} - +enclave_crypto = { path = "../crypto" } +enclave_utils = { path = "../utils" } +cosmos_proto = { path = "../cosmos-proto" } protobuf = { version = "2.25.2" } hex = { version = "0.4.3" } - -# cosmrs = { version = "0.11.0", default-features = false } - - - +cosmos-sdk-proto = { version = "0.16.0", default-features = false } +integer-encoding = "3.0.4" diff --git a/cosmwasm/enclaves/shared/block-verifier/src/ecalls.rs b/cosmwasm/enclaves/shared/block-verifier/src/ecalls.rs index 913ec3558..4d8b3b740 100644 --- a/cosmwasm/enclaves/shared/block-verifier/src/ecalls.rs +++ b/cosmwasm/enclaves/shared/block-verifier/src/ecalls.rs @@ -1,6 +1,10 @@ +use cosmos_sdk_proto::cosmos::base::kv::v1beta1::{Pair, Pairs}; +use cosmos_sdk_proto::traits::Message; +use integer_encoding::VarInt; use std::slice; use tendermint::block::Commit; use tendermint::block::Header; +use tendermint::merkle; use tendermint_proto::Protobuf; use sgx_types::sgx_status_t; @@ -57,11 +61,43 @@ pub unsafe extern "C" fn ecall_submit_store_roots( ); let store_roots_slice = slice::from_raw_parts(in_roots, in_roots_len as usize); - debug!("store_roots_slice: {:?}", store_roots_slice); + + let store_roots: Pairs = Pairs::decode(store_roots_slice).unwrap(); + let mut store_roots_bytes = vec![]; + + // Encode all key-value pairs to bytes + for root in store_roots.pairs { + store_roots_bytes.push(pair_to_bytes(root)); + } + + let h = merkle::simple_hash_from_byte_vectors(store_roots_bytes); + debug!("received app_hash: {:?}", h); return sgx_status_t::SGX_SUCCESS; } +// This is a copy of a cosmos-sdk function: https://github.com/scrtlabs/cosmos-sdk/blob/1b9278476b3ac897d8ebb90241008476850bf212/store/internal/maps/maps.go#LL152C1-L152C1 +// Returns key || value, with both the key and value length prefixed. +fn pair_to_bytes(kv: Pair) -> Vec { + // In the worst case: + // * 8 bytes to Uvarint encode the length of the key + // * 8 bytes to Uvarint encode the length of the value + // So preallocate for the worst case, which will in total + // be a maximum of 14 bytes wasted, if len(key)=1, len(value)=1, + // but that's going to rare. + let mut buf = vec![]; + + // Encode the key, prefixed with its length. + buf.extend_from_slice(&(kv.key.len()).encode_var_vec()); + buf.extend_from_slice(&kv.key); + + // Encode the value, prefixing with its length. + buf.extend_from_slice(&(kv.value.len()).encode_var_vec()); + buf.extend_from_slice(&kv.value); + + return buf; +} + /// # Safety /// This function reads buffers which must be correctly initialized by the caller, /// see safety section of slice::[from_raw_parts](https://doc.rust-lang.org/std/slice/fn.from_raw_parts.html#safety) From 2442ad998ad12c1c50c638a96e48437e848f972e Mon Sep 17 00:00:00 2001 From: toml01 Date: Sun, 18 Jun 2023 17:29:14 +0300 Subject: [PATCH 19/51] send the compute root as well --- .vscode/settings.json | 3 ++- app/app.go | 12 ++++------ cosmwasm/enclaves/execute/Enclave.edl | 4 +++- .../shared/block-verifier/src/ecalls.rs | 10 ++++++++ .../enclaves/shared/contract-engine/src/db.rs | 20 +++++++++------- cosmwasm/packages/sgx-vm/src/proofs.rs | 23 +++++++++++++++---- go-cosmwasm/api/bindings.h | 2 +- go-cosmwasm/api/lib.go | 6 +++-- go-cosmwasm/api/lib_mock.go | 2 +- go-cosmwasm/src/lib.rs | 15 ++++++++++-- 10 files changed, 68 insertions(+), 29 deletions(-) diff --git a/.vscode/settings.json b/.vscode/settings.json index 179ffa0aa..9854a1fe5 100644 --- a/.vscode/settings.json +++ b/.vscode/settings.json @@ -14,7 +14,8 @@ "integration-tests/contract-v0.10/Cargo.toml", "go-cosmwasm/Cargo.toml", "integration-tests/contract-v0.10/Cargo.toml", - "check-hw/Cargo.toml" + "check-hw/Cargo.toml", + "./cosmwasm/enclaves/shared/block-verifier/Cargo.toml" ], "rust-analyzer.diagnostics.experimental.enable": true, "rust-analyzer.rustfmt.rangeFormatting.enable": true, diff --git a/app/app.go b/app/app.go index 6f2294b6a..be6195530 100644 --- a/app/app.go +++ b/app/app.go @@ -432,7 +432,10 @@ func (app *SecretNetworkApp) BeginBlocker(ctx sdk.Context, req abci.RequestBegin panic(err) } - err = gocosmwasm.SubmitModulesStoreRoots(rootsBytes) + computeKv := rootMulti.GetCommitKVStore(sdk.NewKVStoreKey(compute.StoreKey)) + computeRoot := computeKv.LastCommitID().Hash + + err = gocosmwasm.SubmitModulesStoreRoots(rootsBytes, computeRoot) if err != nil { panic(err) } @@ -458,13 +461,6 @@ func storesRootsFromMultiStore(rootMulti *rootmulti.Store) kv.Pairs { //[][]byte sort.Sort(kvs) return kvs - - // storeRoots := make([][]byte, len(kvs.Pairs)) - // for i, kvp := range kvs.Pairs { - // storeRoots[i] = pairBytes(kvp) - // } - - // return storeRoots } // This is a copy of an internal cosmos-sdk function: https://github.com/scrtlabs/cosmos-sdk/blob/1b9278476b3ac897d8ebb90241008476850bf212/store/internal/maps/maps.go#LL152C1-L152C1 diff --git a/cosmwasm/enclaves/execute/Enclave.edl b/cosmwasm/enclaves/execute/Enclave.edl index 8a961b939..4145ab971 100644 --- a/cosmwasm/enclaves/execute/Enclave.edl +++ b/cosmwasm/enclaves/execute/Enclave.edl @@ -120,7 +120,9 @@ enclave { public sgx_status_t ecall_submit_store_roots( [in, count=in_roots_len] const uint8_t* in_roots, - uintptr_t in_roots_len + uintptr_t in_roots_len, + [in, count=in_compute_root_len] const uint8_t* in_compute_root, + uintptr_t in_compute_root_len ); }; diff --git a/cosmwasm/enclaves/shared/block-verifier/src/ecalls.rs b/cosmwasm/enclaves/shared/block-verifier/src/ecalls.rs index 4d8b3b740..162aeef47 100644 --- a/cosmwasm/enclaves/shared/block-verifier/src/ecalls.rs +++ b/cosmwasm/enclaves/shared/block-verifier/src/ecalls.rs @@ -52,6 +52,8 @@ macro_rules! validate_input_length { pub unsafe extern "C" fn ecall_submit_store_roots( in_roots: *const u8, in_roots_len: u32, + in_compute_root: *const u8, + in_compute_root_len: u32, ) -> sgx_status_t { validate_input_length!(in_roots_len, "roots", MAX_VARIABLE_LENGTH); validate_const_ptr!( @@ -59,8 +61,15 @@ pub unsafe extern "C" fn ecall_submit_store_roots( in_roots_len as usize, sgx_status_t::SGX_ERROR_INVALID_PARAMETER ); + validate_input_length!(in_compute_root_len, "roots", MAX_VARIABLE_LENGTH); + validate_const_ptr!( + in_compute_root, + in_compute_root_len as usize, + sgx_status_t::SGX_ERROR_INVALID_PARAMETER + ); let store_roots_slice = slice::from_raw_parts(in_roots, in_roots_len as usize); + let compute_root_slice = slice::from_raw_parts(in_compute_root, in_compute_root_len as usize); let store_roots: Pairs = Pairs::decode(store_roots_slice).unwrap(); let mut store_roots_bytes = vec![]; @@ -72,6 +81,7 @@ pub unsafe extern "C" fn ecall_submit_store_roots( let h = merkle::simple_hash_from_byte_vectors(store_roots_bytes); debug!("received app_hash: {:?}", h); + debug!("received compute_root: {:?}", compute_root_slice); return sgx_status_t::SGX_SUCCESS; } diff --git a/cosmwasm/enclaves/shared/contract-engine/src/db.rs b/cosmwasm/enclaves/shared/contract-engine/src/db.rs index b5ee210b8..739f91e11 100644 --- a/cosmwasm/enclaves/shared/contract-engine/src/db.rs +++ b/cosmwasm/enclaves/shared/contract-engine/src/db.rs @@ -177,17 +177,21 @@ pub fn read_from_encrypted_state( Ok((maybe_encrypted_value_bytes, maybe_proof, maybe_mp_key, gas_used)) => { debug!("merkle proof returned from read_db(): {:?}", maybe_proof); debug!("full key returned from read_db(): {:?}", maybe_mp_key); + debug!( + "enc value returned from read_db(): {:?}", + maybe_encrypted_value_bytes + ); match maybe_encrypted_value_bytes { Some(encrypted_value_bytes) => { let encrypted_value: EncryptedValue = bincode2::deserialize(&encrypted_value_bytes).map_err(|err| { - warn!( - "read_db() got an error while trying to read_from_encrypted_state the value {:?} for key {:?}, stopping wasm: {:?}", - encrypted_value_bytes, - encrypted_key_bytes, - err.to_string() - ); - WasmEngineError::DecryptionError - })?; + warn!( + "read_db() got an error while trying to read_from_encrypted_state the value {:?} for key {:?}, stopping wasm: {:?}", + encrypted_value_bytes, + encrypted_key_bytes, + err.to_string() + ); + WasmEngineError::DecryptionError + })?; match decrypt_value_new( &encrypted_key.data, diff --git a/cosmwasm/packages/sgx-vm/src/proofs.rs b/cosmwasm/packages/sgx-vm/src/proofs.rs index 99ed5586c..3a9968cae 100644 --- a/cosmwasm/packages/sgx-vm/src/proofs.rs +++ b/cosmwasm/packages/sgx-vm/src/proofs.rs @@ -10,10 +10,12 @@ extern "C" { retval: *mut sgx_status_t, in_roots: *const u8, in_roots_len: u32, + in_compute_root: *const u8, + in_compute_root_len: u32, ) -> sgx_status_t; } -pub fn untrusted_submit_store_roots(roots: &[u8]) -> SgxResult<()> { +pub fn untrusted_submit_store_roots(roots: &[u8], compute_root: &[u8]) -> SgxResult<()> { debug!("Hello from just before - untrusted_submit_store_roots"); const RETRY_LIMIT: i32 = 3; @@ -22,7 +24,7 @@ pub fn untrusted_submit_store_roots(roots: &[u8]) -> SgxResult<()> { // this is here so we can loop { - let (retval, status) = submit_store_roots_impl(roots)?; + let (retval, status) = submit_store_roots_impl(roots, compute_root)?; if status != sgx_status_t::SGX_SUCCESS { return Err(status); } else if retval != sgx_status_t::SGX_SUCCESS { @@ -47,7 +49,10 @@ pub fn untrusted_submit_store_roots(roots: &[u8]) -> SgxResult<()> { } } -fn submit_store_roots_impl(roots: &[u8]) -> SgxResult<(sgx_status_t, sgx_status_t)> { +fn submit_store_roots_impl( + roots: &[u8], + compute_root: &[u8], +) -> SgxResult<(sgx_status_t, sgx_status_t)> { // Bind the token to a local variable to ensure its // destructor runs in the end of the function let enclave_access_token = ENCLAVE_DOORBELL @@ -59,7 +64,15 @@ fn submit_store_roots_impl(roots: &[u8]) -> SgxResult<(sgx_status_t, sgx_status_ let mut retval = sgx_status_t::SGX_SUCCESS; // let status = unsafe { ecall_get_encrypted_seed(eid, &mut retval, cert, cert_len, & mut seed) }; - let status = - unsafe { ecall_submit_store_roots(eid, &mut retval, roots.as_ptr(), roots.len() as u32) }; + let status = unsafe { + ecall_submit_store_roots( + eid, + &mut retval, + roots.as_ptr(), + roots.len() as u32, + compute_root.as_ptr(), + compute_root.len() as u32, + ) + }; Ok((retval, status)) } diff --git a/go-cosmwasm/api/bindings.h b/go-cosmwasm/api/bindings.h index 428668b83..2255277a1 100644 --- a/go-cosmwasm/api/bindings.h +++ b/go-cosmwasm/api/bindings.h @@ -221,4 +221,4 @@ Buffer submit_block_signatures(Buffer header, Buffer random, Buffer *err); -bool submit_store_roots(Buffer roots, Buffer *err); +bool submit_store_roots(Buffer roots, Buffer compute_root, Buffer *err); diff --git a/go-cosmwasm/api/lib.go b/go-cosmwasm/api/lib.go index 2f2681a84..4014f8eec 100644 --- a/go-cosmwasm/api/lib.go +++ b/go-cosmwasm/api/lib.go @@ -68,12 +68,14 @@ func SubmitBlockSignatures(header []byte, commit []byte, txs []byte, encRandom [ return receiveVector(res), nil } -func SubmitModulesStoreRoots(roots []byte) error { +func SubmitModulesStoreRoots(roots []byte, computeRoot []byte) error { errmsg := C.Buffer{} rootsSlice := sendSlice(roots) defer freeAfterSend(rootsSlice) + computeRootSlice := sendSlice(computeRoot) + defer freeAfterSend(computeRootSlice) - _, err := C.submit_store_roots(rootsSlice, &errmsg) + _, err := C.submit_store_roots(rootsSlice, computeRootSlice, &errmsg) if err != nil { return errorWithMessage(err, errmsg) } diff --git a/go-cosmwasm/api/lib_mock.go b/go-cosmwasm/api/lib_mock.go index b1361490e..b7a00bf9f 100644 --- a/go-cosmwasm/api/lib_mock.go +++ b/go-cosmwasm/api/lib_mock.go @@ -43,7 +43,7 @@ func SubmitBlockSignatures(header []byte, commit []byte, txs []byte, random []by return nil, nil } -func SubmitModulesStoreRoots(roots []byte) error { +func SubmitModulesStoreRoots(roots []byte, computeRoot []byte) error { return nil } diff --git a/go-cosmwasm/src/lib.rs b/go-cosmwasm/src/lib.rs index 5f3c734ca..58273cb4e 100644 --- a/go-cosmwasm/src/lib.rs +++ b/go-cosmwasm/src/lib.rs @@ -222,7 +222,11 @@ pub extern "C" fn init_cache( } #[no_mangle] -pub extern "C" fn submit_store_roots(roots: Buffer, err: Option<&mut Buffer>) -> bool { +pub extern "C" fn submit_store_roots( + roots: Buffer, + compute_root: Buffer, + err: Option<&mut Buffer>, +) -> bool { let roots_slice = match unsafe { roots.read() } { None => { set_error(Error::empty_arg("roots"), err); @@ -230,8 +234,15 @@ pub extern "C" fn submit_store_roots(roots: Buffer, err: Option<&mut Buffer>) -> } Some(r) => r, }; + let compute_root_slice = match unsafe { compute_root.read() } { + None => { + set_error(Error::empty_arg("compute_root"), err); + return false; + } + Some(r) => r, + }; - match cosmwasm_sgx_vm::untrusted_submit_store_roots(roots_slice) { + match cosmwasm_sgx_vm::untrusted_submit_store_roots(roots_slice, compute_root_slice) { Err(e) => { set_error(Error::enclave_err(e.to_string()), err); false From bf4de89c71d75fc1e49d7526acd2e12e9c0c8329 Mon Sep 17 00:00:00 2001 From: toml01 Date: Sun, 18 Jun 2023 18:58:21 +0300 Subject: [PATCH 20/51] READ_PROOFER static struct --- .../enclaves/shared/block-verifier/src/lib.rs | 19 +++++++++---------- .../shared/block-verifier/src/read_proofs.rs | 7 +++++++ 2 files changed, 16 insertions(+), 10 deletions(-) create mode 100644 cosmwasm/enclaves/shared/block-verifier/src/read_proofs.rs diff --git a/cosmwasm/enclaves/shared/block-verifier/src/lib.rs b/cosmwasm/enclaves/shared/block-verifier/src/lib.rs index 140237605..b09c2ab5a 100644 --- a/cosmwasm/enclaves/shared/block-verifier/src/lib.rs +++ b/cosmwasm/enclaves/shared/block-verifier/src/lib.rs @@ -1,30 +1,29 @@ -#[cfg(not(target_env = "sgx"))] -extern crate sgx_tstd as std; - extern crate alloc; extern crate core; +#[cfg(not(target_env = "sgx"))] +extern crate sgx_tstd as std; extern crate sgx_types; pub mod r#const; pub mod ecalls; - +#[cfg(any(feature = "verify-validator-whitelist", feature = "test"))] +pub mod validator_whitelist; pub mod wasm_messages; -pub use wasm_messages::VERIFIED_MESSAGES; - +mod read_proofs; mod txs; -#[cfg(any(feature = "verify-validator-whitelist", feature = "test"))] -pub mod validator_whitelist; - use lazy_static::lazy_static; use log::debug; - +use read_proofs::ReadProofer; +use std::sync::SgxMutex; use tendermint_light_client_verifier::types::UntrustedBlockState; use tendermint_light_client_verifier::{ProdVerifier, Verdict}; +pub use wasm_messages::VERIFIED_MESSAGES; lazy_static! { static ref VERIFIER: ProdVerifier = ProdVerifier::default(); + static ref READ_PROOFER: SgxMutex = SgxMutex::new(ReadProofer::default()); } pub fn verify_block(untrusted_block: &UntrustedBlockState) -> bool { diff --git a/cosmwasm/enclaves/shared/block-verifier/src/read_proofs.rs b/cosmwasm/enclaves/shared/block-verifier/src/read_proofs.rs new file mode 100644 index 000000000..1c4962ffa --- /dev/null +++ b/cosmwasm/enclaves/shared/block-verifier/src/read_proofs.rs @@ -0,0 +1,7 @@ +#[derive(Default)] +pub struct ReadProofer { + pub app_hash: [u8; 32], + pub store_merkle_root: Vec, +} + +// pub fn verify_ From bd46e69990524931fe6adbb257d2c0ce94313da2 Mon Sep 17 00:00:00 2001 From: toml01 Date: Sun, 18 Jun 2023 18:58:49 +0300 Subject: [PATCH 21/51] Verify input to ecall_submit_store_roots and populate READ_PROOFER --- .../shared/block-verifier/src/ecalls.rs | 26 +++++++++++++++++-- 1 file changed, 24 insertions(+), 2 deletions(-) diff --git a/cosmwasm/enclaves/shared/block-verifier/src/ecalls.rs b/cosmwasm/enclaves/shared/block-verifier/src/ecalls.rs index 162aeef47..a2d74f253 100644 --- a/cosmwasm/enclaves/shared/block-verifier/src/ecalls.rs +++ b/cosmwasm/enclaves/shared/block-verifier/src/ecalls.rs @@ -1,5 +1,6 @@ use cosmos_sdk_proto::cosmos::base::kv::v1beta1::{Pair, Pairs}; use cosmos_sdk_proto::traits::Message; +use enclave_crypto::hash::sha; use integer_encoding::VarInt; use std::slice; use tendermint::block::Commit; @@ -9,7 +10,7 @@ use tendermint_proto::Protobuf; use sgx_types::sgx_status_t; -use crate::{txs, verify_block}; +use crate::{txs, verify_block, READ_PROOFER}; use log::{debug, error}; use enclave_utils::{validate_const_ptr, validate_mut_ptr}; @@ -74,14 +75,35 @@ pub unsafe extern "C" fn ecall_submit_store_roots( let store_roots: Pairs = Pairs::decode(store_roots_slice).unwrap(); let mut store_roots_bytes = vec![]; + // Make sure that the provided AppHash contains the provided compute store root + // The AppHash merkle is built using sha256(root) of every module + let compute_h = sha::sha_256(compute_root_slice); + if !store_roots + .pairs + .as_slice() + .iter() + .any(|p| p.value == compute_h.to_vec()) + { + return sgx_status_t::SGX_ERROR_INVALID_PARAMETER; + }; + // Encode all key-value pairs to bytes for root in store_roots.pairs { + debug!("TOMMM key: {:?}", String::from_utf8_lossy(&root.key)); + debug!("TOMMM val: {:?}", root.value); store_roots_bytes.push(pair_to_bytes(root)); } - let h = merkle::simple_hash_from_byte_vectors(store_roots_bytes); + debug!("received app_hash: {:?}", h); debug!("received compute_root: {:?}", compute_root_slice); + debug!( + "TOMMM hashed compute_root: {:?}", + sha::sha_256(compute_root_slice) + ); + + let mut rp = READ_PROOFER.lock().unwrap(); + rp.app_hash = h; return sgx_status_t::SGX_SUCCESS; } From 4833c86fb4e366f199a22c88f237460d7a29c50f Mon Sep 17 00:00:00 2001 From: toml01 Date: Sun, 18 Jun 2023 19:06:52 +0300 Subject: [PATCH 22/51] Add verification in ecall_submit_block_signatures() --- cosmwasm/enclaves/shared/block-verifier/src/ecalls.rs | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/cosmwasm/enclaves/shared/block-verifier/src/ecalls.rs b/cosmwasm/enclaves/shared/block-verifier/src/ecalls.rs index a2d74f253..f2c30dd86 100644 --- a/cosmwasm/enclaves/shared/block-verifier/src/ecalls.rs +++ b/cosmwasm/enclaves/shared/block-verifier/src/ecalls.rs @@ -84,6 +84,7 @@ pub unsafe extern "C" fn ecall_submit_store_roots( .iter() .any(|p| p.value == compute_h.to_vec()) { + error!("could not verify compute store root!"); return sgx_status_t::SGX_ERROR_INVALID_PARAMETER; }; @@ -249,7 +250,7 @@ pub unsafe extern "C" fn ecall_submit_block_signatures( #[cfg(feature = "random")] let validator_hash = validator_set.hash(); - let signed_header = SignedHeader::new(header, commit).unwrap(); + let signed_header = SignedHeader::new(header.clone(), commit).unwrap(); let untrusted_block = tendermint_light_client_verifier::types::UntrustedBlockState { signed_header: &signed_header, validators: &validator_set, @@ -324,6 +325,11 @@ pub unsafe extern "C" fn ecall_submit_block_signatures( decrypted_random.copy_from_slice(&*decrypted); } + if READ_PROOFER.lock().unwrap().app_hash != header.app_hash.as_bytes() { + error!("error verifying app hash!"); + return sgx_status_t::SGX_ERROR_INVALID_PARAMETER; + } + debug!( "Done verifying block height: {:?}", validator_set_for_height.height From f181e08d42ae2bb98eef03d4d8837ebf80bc6b6a Mon Sep 17 00:00:00 2001 From: toml01 Date: Sun, 18 Jun 2023 19:10:00 +0300 Subject: [PATCH 23/51] clippy --- cosmwasm/enclaves/shared/block-verifier/src/ecalls.rs | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/cosmwasm/enclaves/shared/block-verifier/src/ecalls.rs b/cosmwasm/enclaves/shared/block-verifier/src/ecalls.rs index f2c30dd86..4414580ab 100644 --- a/cosmwasm/enclaves/shared/block-verifier/src/ecalls.rs +++ b/cosmwasm/enclaves/shared/block-verifier/src/ecalls.rs @@ -48,6 +48,10 @@ macro_rules! validate_input_length { }; } +/// # Safety +/// This function reads buffers which must be correctly initialized by the caller, +/// see safety section of slice::[from_raw_parts](https://doc.rust-lang.org/std/slice/fn.from_raw_parts.html#safety) +/// #[no_mangle] #[allow(unused_variables)] pub unsafe extern "C" fn ecall_submit_store_roots( @@ -106,7 +110,7 @@ pub unsafe extern "C" fn ecall_submit_store_roots( let mut rp = READ_PROOFER.lock().unwrap(); rp.app_hash = h; - return sgx_status_t::SGX_SUCCESS; + sgx_status_t::SGX_SUCCESS } // This is a copy of a cosmos-sdk function: https://github.com/scrtlabs/cosmos-sdk/blob/1b9278476b3ac897d8ebb90241008476850bf212/store/internal/maps/maps.go#LL152C1-L152C1 @@ -128,7 +132,7 @@ fn pair_to_bytes(kv: Pair) -> Vec { buf.extend_from_slice(&(kv.value.len()).encode_var_vec()); buf.extend_from_slice(&kv.value); - return buf; + buf } /// # Safety From 2a0f39d0ade192fcbff4568e8dbebb86d06785eb Mon Sep 17 00:00:00 2001 From: toml01 Date: Mon, 19 Jun 2023 11:28:35 +0300 Subject: [PATCH 24/51] don't verify apphash for the first block --- cosmwasm/enclaves/shared/block-verifier/src/ecalls.rs | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/cosmwasm/enclaves/shared/block-verifier/src/ecalls.rs b/cosmwasm/enclaves/shared/block-verifier/src/ecalls.rs index 4414580ab..34acfe873 100644 --- a/cosmwasm/enclaves/shared/block-verifier/src/ecalls.rs +++ b/cosmwasm/enclaves/shared/block-verifier/src/ecalls.rs @@ -329,8 +329,12 @@ pub unsafe extern "C" fn ecall_submit_block_signatures( decrypted_random.copy_from_slice(&*decrypted); } - if READ_PROOFER.lock().unwrap().app_hash != header.app_hash.as_bytes() { + // AppHash calculation is different for the first block + let rp = READ_PROOFER.lock().unwrap(); + if header.height.value() != 1 && rp.app_hash != header.app_hash.as_bytes() { error!("error verifying app hash!"); + debug!("calculated app_hash bytes {:?}", rp.app_hash); + debug!("header app_hash bytes {:?}", header.app_hash.as_bytes()); return sgx_status_t::SGX_ERROR_INVALID_PARAMETER; } From f42fd7266a3d06067a0affc9487920d555bfbd73 Mon Sep 17 00:00:00 2001 From: toml01 Date: Tue, 20 Jun 2023 19:24:51 +0300 Subject: [PATCH 25/51] Verifying merkle proofs for every read. Still buggy for queries --- cosmwasm/enclaves/Cargo.lock | 26 ++++++++++++ .../enclaves/shared/block-verifier/Cargo.toml | 6 +++ .../shared/block-verifier/src/ecalls.rs | 1 + .../enclaves/shared/block-verifier/src/lib.rs | 2 +- .../shared/block-verifier/src/read_proofs.rs | 26 +++++++++++- .../enclaves/shared/contract-engine/src/db.rs | 40 +++++++++---------- go-cosmwasm/api/store.go | 3 ++ 7 files changed, 82 insertions(+), 22 deletions(-) diff --git a/cosmwasm/enclaves/Cargo.lock b/cosmwasm/enclaves/Cargo.lock index a54c45f9d..ab4db9e5d 100644 --- a/cosmwasm/enclaves/Cargo.lock +++ b/cosmwasm/enclaves/Cargo.lock @@ -214,9 +214,11 @@ dependencies = [ "enclave_crypto", "enclave_utils", "hex", + "ics23", "integer-encoding", "lazy_static", "log", + "prost 0.11.9", "protobuf", "sgx_trts", "sgx_tstd", @@ -931,6 +933,21 @@ version = "2.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9a3a5bfb195931eeb336b2a7b4d761daec841b97f947d34394601737a7bba5e4" +[[package]] +name = "ics23" +version = "0.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ca44b684ce1859cff746ff46f5765ab72e12e3c06f76a8356db8f9a2ecf43f17" +dependencies = [ + "anyhow 1.0.71", + "bytes 1.4.0", + "hex", + "prost 0.11.9", + "ripemd", + "sha2 0.10.6", + "sha3", +] + [[package]] name = "id-arena" version = "2.2.1" @@ -1434,6 +1451,15 @@ dependencies = [ "untrusted", ] +[[package]] +name = "ripemd" +version = "0.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bd124222d17ad93a644ed9d011a40f4fb64aa54275c08cc216524a9ea82fb09f" +dependencies = [ + "digest 0.10.7", +] + [[package]] name = "ripemd160" version = "0.9.1" diff --git a/cosmwasm/enclaves/shared/block-verifier/Cargo.toml b/cosmwasm/enclaves/shared/block-verifier/Cargo.toml index 157af85dd..7eaab0738 100644 --- a/cosmwasm/enclaves/shared/block-verifier/Cargo.toml +++ b/cosmwasm/enclaves/shared/block-verifier/Cargo.toml @@ -31,3 +31,9 @@ protobuf = { version = "2.25.2" } hex = { version = "0.4.3" } cosmos-sdk-proto = { version = "0.16.0", default-features = false } integer-encoding = "3.0.4" +ics23 = { version = "0.9.0", default-features = false, features = [ + "host-functions", +] } +prost = { version = "0.11", default-features = false, features = [ + "prost-derive", +] } diff --git a/cosmwasm/enclaves/shared/block-verifier/src/ecalls.rs b/cosmwasm/enclaves/shared/block-verifier/src/ecalls.rs index 34acfe873..0021fb26c 100644 --- a/cosmwasm/enclaves/shared/block-verifier/src/ecalls.rs +++ b/cosmwasm/enclaves/shared/block-verifier/src/ecalls.rs @@ -109,6 +109,7 @@ pub unsafe extern "C" fn ecall_submit_store_roots( let mut rp = READ_PROOFER.lock().unwrap(); rp.app_hash = h; + rp.store_merkle_root = compute_root_slice.to_vec(); sgx_status_t::SGX_SUCCESS } diff --git a/cosmwasm/enclaves/shared/block-verifier/src/lib.rs b/cosmwasm/enclaves/shared/block-verifier/src/lib.rs index b09c2ab5a..351dae672 100644 --- a/cosmwasm/enclaves/shared/block-verifier/src/lib.rs +++ b/cosmwasm/enclaves/shared/block-verifier/src/lib.rs @@ -10,7 +10,7 @@ pub mod ecalls; pub mod validator_whitelist; pub mod wasm_messages; -mod read_proofs; +pub mod read_proofs; mod txs; use lazy_static::lazy_static; diff --git a/cosmwasm/enclaves/shared/block-verifier/src/read_proofs.rs b/cosmwasm/enclaves/shared/block-verifier/src/read_proofs.rs index 1c4962ffa..bfd1c3746 100644 --- a/cosmwasm/enclaves/shared/block-verifier/src/read_proofs.rs +++ b/cosmwasm/enclaves/shared/block-verifier/src/read_proofs.rs @@ -1,7 +1,31 @@ +use ics23::{ + iavl_spec, verify_membership, verify_non_membership, CommitmentProof, HostFunctionsManager, +}; +use log::*; +use prost::Message; + +use crate::READ_PROOFER; + #[derive(Default)] pub struct ReadProofer { pub app_hash: [u8; 32], pub store_merkle_root: Vec, } -// pub fn verify_ +pub fn verify_read(key: &[u8], value: Option>, proof: &CommitmentProof) -> bool { + let root = &READ_PROOFER.lock().unwrap().store_merkle_root; + + debug!("TOMMM key {:?}", key); + debug!("TOMMM value {:?}", value); + debug!("TOMMM proof {:?}", proof); + debug!("TOMMM root {:?}", root); + + match value { + Some(v) => verify_membership::(proof, &iavl_spec(), root, key, &v), + None => verify_non_membership::(proof, &iavl_spec(), root, key), + } +} + +pub fn comm_proof_from_bytes(proof: &[u8]) -> Result { + CommitmentProof::decode(proof) +} diff --git a/cosmwasm/enclaves/shared/contract-engine/src/db.rs b/cosmwasm/enclaves/shared/contract-engine/src/db.rs index 739f91e11..a4221ea4b 100644 --- a/cosmwasm/enclaves/shared/contract-engine/src/db.rs +++ b/cosmwasm/enclaves/shared/contract-engine/src/db.rs @@ -1,22 +1,19 @@ +use block_verifier::read_proofs::{comm_proof_from_bytes, verify_read}; use enclave_crypto::consts::{ CONSENSUS_SEED_VERSION, ENCRYPTED_KEY_MAGIC_BYTES, STATE_ENCRYPTION_VERSION, }; use enclave_crypto::key_manager::SeedsHolder; +use enclave_crypto::{sha_256, AESKey, Kdf, SIVEncryptable, KEY_MANAGER}; +use enclave_ffi_types::{Ctx, EnclaveBuffer, OcallReturn, UntrustedVmError}; +use enclave_utils::kv_cache::KvCache; use log::*; - +use serde::{Deserialize, Serialize}; use sgx_types::sgx_status_t; -use enclave_ffi_types::{Ctx, EnclaveBuffer, OcallReturn, UntrustedVmError}; - -use enclave_crypto::{sha_256, AESKey, Kdf, SIVEncryptable, KEY_MANAGER}; - use crate::external::{ecalls, ocalls}; -use enclave_utils::kv_cache::KvCache; - use super::contract_validation::ContractKey; use super::errors::WasmEngineError; -use serde::{Deserialize, Serialize}; #[derive(Serialize, Deserialize)] struct EncryptedKey { @@ -174,13 +171,7 @@ pub fn read_from_encrypted_state( &encrypted_key_bytes, block_height, ) { - Ok((maybe_encrypted_value_bytes, maybe_proof, maybe_mp_key, gas_used)) => { - debug!("merkle proof returned from read_db(): {:?}", maybe_proof); - debug!("full key returned from read_db(): {:?}", maybe_mp_key); - debug!( - "enc value returned from read_db(): {:?}", - maybe_encrypted_value_bytes - ); + Ok((maybe_encrypted_value_bytes, gas_used)) => { match maybe_encrypted_value_bytes { Some(encrypted_value_bytes) => { let encrypted_value: EncryptedValue = bincode2::deserialize(&encrypted_value_bytes).map_err(|err| { @@ -226,9 +217,7 @@ pub fn read_from_encrypted_state( let gas_used_second_read: u64; (maybe_plaintext_value, gas_used_second_read) = match read_db(context, &scrambled_field_name, block_height) { - Ok((encrypted_value, proof, mp_key, gas_used)) => { - debug!("proof returned from read_db(): {:?}", proof); - debug!("full key returned from read_db(): {:?}", mp_key); + Ok((encrypted_value, gas_used)) => { match encrypted_value { Some(plaintext_value) => { match decrypt_value_old( @@ -325,7 +314,7 @@ fn read_db( context: &Ctx, key: &[u8], block_height: u64, -) -> Result<(Option>, Option>, Option>, u64), WasmEngineError> { +) -> Result<(Option>, u64), WasmEngineError> { let mut ocall_return = OcallReturn::Success; let mut value_buffer = std::mem::MaybeUninit::::uninit(); let mut proof_buffer = std::mem::MaybeUninit::::uninit(); @@ -375,7 +364,18 @@ fn read_db( } }; - Ok((value, proof, mp_key, gas_used)) + if let (Some(proof), Some(mp_key)) = (proof, mp_key) { + let comm_proof = + comm_proof_from_bytes(&proof).map_err(|_| WasmEngineError::HostMisbehavior)?; + if !verify_read(&mp_key, value.clone(), &comm_proof) { + error!("could not verify merkle proof"); + return Err(WasmEngineError::HostMisbehavior); + } + + Ok((value, gas_used)) + } else { + Err(WasmEngineError::HostMisbehavior) + } } /// Safe wrapper around reads from the contract storage diff --git a/go-cosmwasm/api/store.go b/go-cosmwasm/api/store.go index 0b460aab3..36bbb0e06 100644 --- a/go-cosmwasm/api/store.go +++ b/go-cosmwasm/api/store.go @@ -38,6 +38,9 @@ func getWithProof(store sdk.KVStore, key []byte, blockHeight int64) (value []byt result := iavlStore.Query(abci.RequestQuery{Data: fullKey, Path: "/key", Prove: true, Height: blockHeight - 1}) // result.ProofOps.Ops should always contain only one proof + if result.ProofOps == nil { + return nil, nil, nil, fmt.Errorf("error in retrieving key: %+v, got: %s", key, result.Log) + } if len(result.ProofOps.Ops) != 1 { return nil, nil, nil, fmt.Errorf("error in retrieving proof for key: %+v, got: %+v", key, result.ProofOps.Ops) } From 399689c9a01a18ebfe5f5642631cf0141264a378 Mon Sep 17 00:00:00 2001 From: toml01 Date: Sun, 18 Jun 2023 16:24:32 +0300 Subject: [PATCH 26/51] Return the full prefixed key with the ocall as well + fix a bug in ocall_read_db_concrete --- cosmwasm/enclaves/execute/Enclave.edl | 1 + .../enclaves/shared/contract-engine/src/db.rs | 16 +++++--- .../contract-engine/src/external/ocalls.rs | 1 + .../packages/sgx-vm/src/testing/storage.rs | 21 ++++++---- cosmwasm/packages/sgx-vm/src/traits.rs | 6 ++- cosmwasm/packages/sgx-vm/src/wasmi/exports.rs | 38 ++++++++++++------- go-cosmwasm/api/bindings.h | 2 +- go-cosmwasm/api/callbacks.go | 9 +++-- go-cosmwasm/api/callbacks_cgo.go | 6 +-- go-cosmwasm/api/callbacks_cgo_mock.go | 6 +-- go-cosmwasm/api/callbacks_mock.go | 2 +- go-cosmwasm/api/store.go | 12 +++--- go-cosmwasm/src/db.rs | 19 +++++++++- 13 files changed, 94 insertions(+), 45 deletions(-) diff --git a/cosmwasm/enclaves/execute/Enclave.edl b/cosmwasm/enclaves/execute/Enclave.edl index ae73c5b9c..827eed8b7 100644 --- a/cosmwasm/enclaves/execute/Enclave.edl +++ b/cosmwasm/enclaves/execute/Enclave.edl @@ -132,6 +132,7 @@ enclave { uint64_t block_height, [out] EnclaveBuffer* value, [out] EnclaveBuffer* proof, + [out] EnclaveBuffer* mp_key, [in, count=key_len] const uint8_t* key, uintptr_t key_len ) allow (ecall_allocate); diff --git a/cosmwasm/enclaves/shared/contract-engine/src/db.rs b/cosmwasm/enclaves/shared/contract-engine/src/db.rs index 86c04adee..b5ee210b8 100644 --- a/cosmwasm/enclaves/shared/contract-engine/src/db.rs +++ b/cosmwasm/enclaves/shared/contract-engine/src/db.rs @@ -174,8 +174,9 @@ pub fn read_from_encrypted_state( &encrypted_key_bytes, block_height, ) { - Ok((maybe_encrypted_value_bytes, maybe_proof, gas_used)) => { + Ok((maybe_encrypted_value_bytes, maybe_proof, maybe_mp_key, gas_used)) => { debug!("merkle proof returned from read_db(): {:?}", maybe_proof); + debug!("full key returned from read_db(): {:?}", maybe_mp_key); match maybe_encrypted_value_bytes { Some(encrypted_value_bytes) => { let encrypted_value: EncryptedValue = bincode2::deserialize(&encrypted_value_bytes).map_err(|err| { @@ -221,8 +222,9 @@ pub fn read_from_encrypted_state( let gas_used_second_read: u64; (maybe_plaintext_value, gas_used_second_read) = match read_db(context, &scrambled_field_name, block_height) { - Ok((encrypted_value, proof, gas_used)) => { + Ok((encrypted_value, proof, mp_key, gas_used)) => { debug!("proof returned from read_db(): {:?}", proof); + debug!("full key returned from read_db(): {:?}", mp_key); match encrypted_value { Some(plaintext_value) => { match decrypt_value_old( @@ -319,14 +321,15 @@ fn read_db( context: &Ctx, key: &[u8], block_height: u64, -) -> Result<(Option>, Option>, u64), WasmEngineError> { +) -> Result<(Option>, Option>, Option>, u64), WasmEngineError> { let mut ocall_return = OcallReturn::Success; let mut value_buffer = std::mem::MaybeUninit::::uninit(); let mut proof_buffer = std::mem::MaybeUninit::::uninit(); + let mut mp_key_buffer = std::mem::MaybeUninit::::uninit(); let mut vm_err = UntrustedVmError::default(); let mut gas_used = 0_u64; - let (value, proof) = unsafe { + let (value, proof, mp_key) = unsafe { let status = ocalls::ocall_read_db( (&mut ocall_return) as *mut _, context.unsafe_clone(), @@ -335,6 +338,7 @@ fn read_db( block_height, value_buffer.as_mut_ptr(), proof_buffer.as_mut_ptr(), + mp_key_buffer.as_mut_ptr(), key.as_ptr(), key.len(), ); @@ -353,9 +357,11 @@ fn read_db( OcallReturn::Success => { let value_buffer = value_buffer.assume_init(); let proof_buffer = proof_buffer.assume_init(); + let mp_key_buffer = mp_key_buffer.assume_init(); ( ecalls::recover_buffer(value_buffer)?, ecalls::recover_buffer(proof_buffer)?, + ecalls::recover_buffer(mp_key_buffer)?, ) } OcallReturn::Failure => { @@ -365,7 +371,7 @@ fn read_db( } }; - Ok((value, proof, gas_used)) + Ok((value, proof, mp_key, gas_used)) } /// Safe wrapper around reads from the contract storage diff --git a/cosmwasm/enclaves/shared/contract-engine/src/external/ocalls.rs b/cosmwasm/enclaves/shared/contract-engine/src/external/ocalls.rs index 049b3659d..55a9e82b9 100644 --- a/cosmwasm/enclaves/shared/contract-engine/src/external/ocalls.rs +++ b/cosmwasm/enclaves/shared/contract-engine/src/external/ocalls.rs @@ -18,6 +18,7 @@ extern "C" { block_height: u64, value: *mut EnclaveBuffer, proof: *mut EnclaveBuffer, + mp_key: *mut EnclaveBuffer, key: *const u8, key_len: usize, ) -> sgx_status_t; diff --git a/cosmwasm/packages/sgx-vm/src/testing/storage.rs b/cosmwasm/packages/sgx-vm/src/testing/storage.rs index 42d4dadf7..9dbbdbbc9 100644 --- a/cosmwasm/packages/sgx-vm/src/testing/storage.rs +++ b/cosmwasm/packages/sgx-vm/src/testing/storage.rs @@ -56,9 +56,16 @@ impl MockStorage { } impl Storage for MockStorage { - fn get(&self, _height: u64, key: &[u8]) -> FfiResult<(Option>, Option>)> { + fn get( + &self, + _height: u64, + key: &[u8], + ) -> FfiResult<(Option>, Option>, Option>)> { let gas_info = GasInfo::with_externally_used(key.len() as u64); - (Ok((self.data.get(key).cloned(), Some(vec![]))), gas_info) // TODO is it ok to return an empty proof on MockStorage? + ( + Ok((self.data.get(key).cloned(), Some(vec![]), Some(vec![]))), + gas_info, + ) // TODO is it ok to return an empty proof on MockStorage? } #[cfg(feature = "iterator")] @@ -135,10 +142,10 @@ mod test { #[test] fn get_and_set() { let mut store = MockStorage::new(); - assert_eq!(None, store.get(b"foo").0.unwrap()); + assert_eq!(None, store.get(0, b"foo").0.unwrap().0); store.set(b"foo", b"bar").0.unwrap(); - assert_eq!(Some(b"bar".to_vec()), store.get(b"foo").0.unwrap()); - assert_eq!(None, store.get(b"food").0.unwrap()); + assert_eq!(Some(b"bar".to_vec()), store.get(0, b"foo").0.unwrap().0); + assert_eq!(None, store.get(0, b"food").0.unwrap().0); } #[test] @@ -148,8 +155,8 @@ mod test { store.set(b"food", b"bank").0.unwrap(); store.remove(b"foo").0.unwrap(); - assert_eq!(None, store.get(b"foo").0.unwrap()); - assert_eq!(Some(b"bank".to_vec()), store.get(b"food").0.unwrap()); + assert_eq!(None, store.get(0, b"foo",).0.unwrap().0); + assert_eq!(Some(b"bank".to_vec()), store.get(0, b"food").0.unwrap().0); } #[test] diff --git a/cosmwasm/packages/sgx-vm/src/traits.rs b/cosmwasm/packages/sgx-vm/src/traits.rs index 93ae5205d..dbb2825e3 100644 --- a/cosmwasm/packages/sgx-vm/src/traits.rs +++ b/cosmwasm/packages/sgx-vm/src/traits.rs @@ -69,7 +69,11 @@ where /// /// Note: Support for differentiating between a non-existent key and a key with empty value /// is not great yet and might not be possible in all backends. But we're trying to get there. - fn get(&self, height: u64, key: &[u8]) -> FfiResult<(Option>, Option>)>; + fn get( + &self, + height: u64, + key: &[u8], + ) -> FfiResult<(Option>, Option>, Option>)>; #[cfg(feature = "iterator")] /// Allows iteration over a set of key/value pairs, either forwards or backwards. diff --git a/cosmwasm/packages/sgx-vm/src/wasmi/exports.rs b/cosmwasm/packages/sgx-vm/src/wasmi/exports.rs index cd0ec328c..6df6841b3 100644 --- a/cosmwasm/packages/sgx-vm/src/wasmi/exports.rs +++ b/cosmwasm/packages/sgx-vm/src/wasmi/exports.rs @@ -48,6 +48,7 @@ pub extern "C" fn ocall_read_db( block_height: u64, value: *mut EnclaveBuffer, proof: *mut EnclaveBuffer, + mp_key: *mut EnclaveBuffer, key: *const u8, key_len: usize, ) -> OcallReturn { @@ -59,6 +60,7 @@ pub extern "C" fn ocall_read_db( block_height, value, proof, + mp_key, key, key_len, ) @@ -94,6 +96,7 @@ fn ocall_read_db_concrete( height: u64, value: *mut EnclaveBuffer, proof: *mut EnclaveBuffer, + mp_key: *mut EnclaveBuffer, key: *const u8, key_len: usize, ) -> OcallReturn { @@ -105,19 +108,27 @@ fn ocall_read_db_concrete( // Get either an error(`OcallReturn`), or a response(`EnclaveBuffer`) // which will be converted to a success status. .map( - |result| -> Result<(EnclaveBuffer, EnclaveBuffer), OcallReturn> { + |result| -> Result<(EnclaveBuffer, EnclaveBuffer, EnclaveBuffer), OcallReturn> { match result { - Ok(((value, proof), gas_cost)) => { + Ok(((value, proof, mp_key), gas_cost)) => { unsafe { *gas_used = gas_cost }; - if let (Some(value), Some(proof)) = (value, proof) { - let val = alloc_impl(&value).map_err(|_| OcallReturn::Failure); - let p = alloc_impl(&proof).map_err(|_| OcallReturn::Failure); - - val.and_then(|val| p.and_then(|p| Ok((val, p)))) + let value_buf = if let Some(value) = value { + alloc_impl(&value).map_err(|_| OcallReturn::Failure)? + } else { + EnclaveBuffer::default() + }; + let proof_buf = if let Some(proof) = proof { + alloc_impl(&proof).map_err(|_| OcallReturn::Failure)? + } else { + EnclaveBuffer::default() + }; + let mp_key_buf = if let Some(mp_key) = mp_key { + alloc_impl(&mp_key).map_err(|_| OcallReturn::Failure)? } else { - Ok((EnclaveBuffer::default(), EnclaveBuffer::default())) - } + EnclaveBuffer::default() + }; + Ok((value_buf, proof_buf, mp_key_buf)) } Err(err) => { unsafe { store_vm_error(err, vm_error) }; @@ -128,10 +139,11 @@ fn ocall_read_db_concrete( ) // Return the result or report the error .map(|result| match result { - Ok((value_buffer, proof_buffer)) => { + Ok((value_buffer, proof_buffer, mp_key_buffer)) => { unsafe { *value = value_buffer; - *proof = proof_buffer + *proof = proof_buffer; + *mp_key = mp_key_buffer }; OcallReturn::Success } @@ -389,7 +401,7 @@ struct ExportImplementations { context: Ctx, height: u64, key: &[u8], - ) -> VmResult<((Option>, Option>), u64)>, + ) -> VmResult<((Option>, Option>, Option>), u64)>, query_chain: fn( context: Ctx, query: &[u8], @@ -449,7 +461,7 @@ fn ocall_read_db_impl( mut context: Ctx, height: u64, key: &[u8], -) -> VmResult<((Option>, Option>), u64)> +) -> VmResult<((Option>, Option>, Option>), u64)> where S: Storage, Q: Querier, diff --git a/go-cosmwasm/api/bindings.h b/go-cosmwasm/api/bindings.h index 1299af060..f4173d7e2 100644 --- a/go-cosmwasm/api/bindings.h +++ b/go-cosmwasm/api/bindings.h @@ -104,7 +104,7 @@ typedef struct GoIter { } GoIter; typedef struct DB_vtable { - int32_t (*read_db)(db_t*, gas_meter_t*, uint64_t*, uint64_t, Buffer, Buffer*, Buffer*, Buffer*); + int32_t (*read_db)(db_t*, gas_meter_t*, uint64_t*, uint64_t, Buffer, Buffer*, Buffer*, Buffer*, Buffer*); int32_t (*write_db)(db_t*, gas_meter_t*, uint64_t*, Buffer, Buffer, Buffer*); int32_t (*remove_db)(db_t*, gas_meter_t*, uint64_t*, Buffer, Buffer*); int32_t (*scan_db)(db_t*, gas_meter_t*, uint64_t*, Buffer, Buffer, int32_t, GoIter*, Buffer*); diff --git a/go-cosmwasm/api/callbacks.go b/go-cosmwasm/api/callbacks.go index 64d14f826..c09d796d8 100644 --- a/go-cosmwasm/api/callbacks.go +++ b/go-cosmwasm/api/callbacks.go @@ -19,7 +19,7 @@ typedef GoResult (*canonicalize_address_fn)(api_t *ptr, Buffer human, Buffer *ca typedef GoResult (*query_external_fn)(querier_t *ptr, uint64_t gas_limit, uint64_t *used_gas, Buffer request, uint32_t query_depth, Buffer *result, Buffer *errOut); // forward declarations (db) -GoResult cGet_cgo(db_t *ptr, gas_meter_t *gas_meter, uint64_t *used_gas, uint64_t block_height, Buffer key, Buffer *val, Buffer *merkle_p, Buffer *errOut); +GoResult cGet_cgo(db_t *ptr, gas_meter_t *gas_meter, uint64_t *used_gas, uint64_t block_height, Buffer key, Buffer *val, Buffer *merkle_p, Buffer *mp_key, Buffer *errOut); GoResult cSet_cgo(db_t *ptr, gas_meter_t *gas_meter, uint64_t *used_gas, Buffer key, Buffer val, Buffer *errOut); GoResult cDelete_cgo(db_t *ptr, gas_meter_t *gas_meter, uint64_t *used_gas, Buffer key, Buffer *errOut); GoResult cScan_cgo(db_t *ptr, gas_meter_t *gas_meter, uint64_t *used_gas, Buffer start, Buffer end, int32_t order, GoIter *out, Buffer *errOut); @@ -139,7 +139,7 @@ func buildIterator(dbCounter uint64, it dbm.Iterator) C.iterator_t { } //export cGet -func cGet(ptr *C.db_t, gasMeter *C.gas_meter_t, usedGas *u64, block_height u64, key C.Buffer, val *C.Buffer, merkle_p *C.Buffer, errOut *C.Buffer) (ret C.GoResult) { +func cGet(ptr *C.db_t, gasMeter *C.gas_meter_t, usedGas *u64, block_height u64, key C.Buffer, val *C.Buffer, merkle_p *C.Buffer, mp_key *C.Buffer, errOut *C.Buffer) (ret C.GoResult) { defer recoverPanic(&ret) if ptr == nil || gasMeter == nil || usedGas == nil || val == nil { // we received an invalid pointer @@ -152,7 +152,7 @@ func cGet(ptr *C.db_t, gasMeter *C.gas_meter_t, usedGas *u64, block_height u64, gasBefore := gm.GasConsumed() - v, proof, err := getWithProof(kv, k, int64(block_height)) + v, proof, mpKey, err := getWithProof(kv, k, int64(block_height)) if err != nil { panic(fmt.Sprintf("error getting merkle proof: %s", err.Error())) } @@ -172,6 +172,9 @@ func cGet(ptr *C.db_t, gasMeter *C.gas_meter_t, usedGas *u64, block_height u64, if proof != nil { *merkle_p = allocateRust(proof) } + if mpKey != nil { + *mp_key = allocateRust(mpKey) + } return C.GoResult_Ok } diff --git a/go-cosmwasm/api/callbacks_cgo.go b/go-cosmwasm/api/callbacks_cgo.go index 4de7822b2..b07dd9d34 100644 --- a/go-cosmwasm/api/callbacks_cgo.go +++ b/go-cosmwasm/api/callbacks_cgo.go @@ -9,7 +9,7 @@ package api // imports (db) GoResult cSet(db_t *ptr, gas_meter_t *gas_meter, uint64_t *used_gas, Buffer key, Buffer val, Buffer *errOut); -GoResult cGet(db_t *ptr, gas_meter_t *gas_meter, uint64_t *used_gas, uint64_t block_height, Buffer key, Buffer *val, Buffer *merkle_p, Buffer *errOut); +GoResult cGet(db_t *ptr, gas_meter_t *gas_meter, uint64_t *used_gas, uint64_t block_height, Buffer key, Buffer *val, Buffer *merkle_p, Buffer *mp_key, Buffer *errOut); GoResult cDelete(db_t *ptr, gas_meter_t *gas_meter, uint64_t *used_gas, Buffer key, Buffer *errOut); GoResult cScan(db_t *ptr, gas_meter_t *gas_meter, uint64_t *used_gas, Buffer start, Buffer end, int32_t order, GoIter *out, Buffer *errOut); // imports (iterator) @@ -21,8 +21,8 @@ GoResult cCanonicalAddress(api_t *ptr, Buffer human, Buffer *canon, Buffer *errO GoResult cQueryExternal(querier_t *ptr, uint64_t gas_limit, uint64_t *used_gas, Buffer request, uint32_t query_depth, Buffer *result, Buffer *errOut); // Gateway functions (db) -GoResult cGet_cgo(db_t *ptr, gas_meter_t *gas_meter, uint64_t *used_gas, uint64_t block_height, Buffer key, Buffer *val, Buffer *merkle_p, Buffer *errOut) { - return cGet(ptr, gas_meter, used_gas, block_height, key, val, merkle_p, errOut); +GoResult cGet_cgo(db_t *ptr, gas_meter_t *gas_meter, uint64_t *used_gas, uint64_t block_height, Buffer key, Buffer *val, Buffer *merkle_p, Buffer *mp_key, Buffer *errOut) { + return cGet(ptr, gas_meter, used_gas, block_height, key, val, merkle_p, mp_key, errOut); } GoResult cSet_cgo(db_t *ptr, gas_meter_t *gas_meter, uint64_t *used_gas, Buffer key, Buffer val, Buffer *errOut) { return cSet(ptr, gas_meter, used_gas, key, val, errOut); diff --git a/go-cosmwasm/api/callbacks_cgo_mock.go b/go-cosmwasm/api/callbacks_cgo_mock.go index 8702f52ca..a464bfdbc 100644 --- a/go-cosmwasm/api/callbacks_cgo_mock.go +++ b/go-cosmwasm/api/callbacks_cgo_mock.go @@ -10,7 +10,7 @@ package api // //// imports (db) //GoResult cSet(db_t *ptr, gas_meter_t *gas_meter, uint64_t *used_gas, Buffer key, Buffer val); -//GoResult cGet(db_t *ptr, gas_meter_t *gas_meter, uint64_t *used_gas, uint64_t block_height, Buffer key, Buffer *val, Buffer *merkle_p); +//GoResult cGet(db_t *ptr, gas_meter_t *gas_meter, uint64_t *used_gas, uint64_t block_height, Buffer key, Buffer *val, Buffer *merkle_p, Buffer *mp_key); //GoResult cDelete(db_t *ptr, gas_meter_t *gas_meter, uint64_t *used_gas, Buffer key); //GoResult cScan(db_t *ptr, gas_meter_t *gas_meter, uint64_t *used_gas, Buffer start, Buffer end, int32_t order, GoIter *out); //// imports (iterator) @@ -22,8 +22,8 @@ package api //GoResult cQueryExternal(querier_t *ptr, uint64_t *used_gas, Buffer request, Buffer *result); // //// Gateway functions (db) -//GoResult cGet_cgo(db_t *ptr, gas_meter_t *gas_meter, uint64_t *used_gas, uint64_t block_height, Buffer key, Buffer *val, Buffer *merkle_p) { -// return cGet(ptr, gas_meter, used_gas, block_height, key, val, merkle_p); +//GoResult cGet_cgo(db_t *ptr, gas_meter_t *gas_meter, uint64_t *used_gas, uint64_t block_height, Buffer key, Buffer *val, Buffer *merkle_p, Buffer *mp_key) { +// return cGet(ptr, gas_meter, used_gas, block_height, key, val, merkle_p, mp_key); //} //GoResult cSet_cgo(db_t *ptr, gas_meter_t *gas_meter, uint64_t *used_gas, Buffer key, Buffer val) { // return cSet(ptr, gas_meter, used_gas, key, val); diff --git a/go-cosmwasm/api/callbacks_mock.go b/go-cosmwasm/api/callbacks_mock.go index 7b58e66e3..360e16d66 100644 --- a/go-cosmwasm/api/callbacks_mock.go +++ b/go-cosmwasm/api/callbacks_mock.go @@ -19,7 +19,7 @@ package api // typedef GoResult (*query_external_fn)(querier_t *ptr, uint64_t *used_gas, Buffer request, Buffer *result); // // // forward declarations (db) -// GoResult cGet_cgo(db_t *ptr, gas_meter_t *gas_meter, uint64_t *used_gas, uint64_t block_height, Buffer key, Buffer *val, Buffer *merkle_p); +// GoResult cGet_cgo(db_t *ptr, gas_meter_t *gas_meter, uint64_t *used_gas, uint64_t block_height, Buffer key, Buffer *val, Buffer *merkle_p, Buffer *mp_key); // GoResult cSet_cgo(db_t *ptr, gas_meter_t *gas_meter, uint64_t *used_gas, Buffer key, Buffer val); // GoResult cDelete_cgo(db_t *ptr, gas_meter_t *gas_meter, uint64_t *used_gas, Buffer key); // GoResult cScan_cgo(db_t *ptr, gas_meter_t *gas_meter, uint64_t *used_gas, Buffer start, Buffer end, int32_t order, GoIter *out); diff --git a/go-cosmwasm/api/store.go b/go-cosmwasm/api/store.go index 6118cab0b..0b460aab3 100644 --- a/go-cosmwasm/api/store.go +++ b/go-cosmwasm/api/store.go @@ -27,23 +27,23 @@ func getInnerIavl(store sdk.KVStore, key []byte) (iavlStore *iavl.Store, fullKey } } -func getWithProof(store sdk.KVStore, key []byte, blockHeight int64) (value []byte, proof []byte, err error) { +func getWithProof(store sdk.KVStore, key []byte, blockHeight int64) (value []byte, proof []byte, fullKey []byte, err error) { iavlStore, fullKey, err := getInnerIavl(store, key) if err != nil { - return nil, nil, err + return nil, nil, nil, err } // Query height is (current - 1) because we will probably not have a proof in // the current height (assuming we're mid execution) - result := iavlStore.Query(abci.RequestQuery{Data: fullKey, Path: "/key", Prove: true, Height: blockHeight - 1 /* NOTE!! this depends on what blockHeight we get here. if it's the verified one it's probably for the past block anyway, so no need to subtract 1 for the height*/}) + result := iavlStore.Query(abci.RequestQuery{Data: fullKey, Path: "/key", Prove: true, Height: blockHeight - 1}) // result.ProofOps.Ops should always contain only one proof if len(result.ProofOps.Ops) != 1 { - return nil, nil, fmt.Errorf("error in retrieving proof for key: %+v, got: %+v", key, result.ProofOps.Ops) + return nil, nil, nil, fmt.Errorf("error in retrieving proof for key: %+v, got: %+v", key, result.ProofOps.Ops) } if result.ProofOps.Ops[0].Data == nil { - return nil, nil, fmt.Errorf("`iavlStore.Query()` returned an empty value for key: %+v", key) + return nil, nil, nil, fmt.Errorf("`iavlStore.Query()` returned an empty value for key: %+v", key) } - return result.Value, result.ProofOps.Ops[0].Data, nil + return result.Value, result.ProofOps.Ops[0].Data, fullKey, nil } diff --git a/go-cosmwasm/src/db.rs b/go-cosmwasm/src/db.rs index 283e1142a..1b6248d1e 100644 --- a/go-cosmwasm/src/db.rs +++ b/go-cosmwasm/src/db.rs @@ -24,6 +24,7 @@ pub struct DB_vtable { *mut Buffer, *mut Buffer, *mut Buffer, + *mut Buffer, ) -> i32, pub write_db: extern "C" fn(*mut db_t, *mut gas_meter_t, *mut u64, Buffer, Buffer, *mut Buffer) -> i32, @@ -51,10 +52,15 @@ pub struct DB { } impl Storage for DB { - fn get(&self, height: u64, key: &[u8]) -> FfiResult<(Option>, Option>)> { + fn get( + &self, + height: u64, + key: &[u8], + ) -> FfiResult<(Option>, Option>, Option>)> { let key_buf = Buffer::from_vec(key.to_vec()); let mut result_buf = Buffer::default(); let mut proof_buf = Buffer::default(); + let mut mp_key_buf = Buffer::default(); let mut err = Buffer::default(); let mut used_gas = 0_u64; let go_result: GoResult = (self.vtable.read_db)( @@ -65,6 +71,7 @@ impl Storage for DB { key_buf, &mut result_buf as *mut Buffer, &mut proof_buf as *mut Buffer, + &mut mp_key_buf as *mut Buffer, &mut err as *mut Buffer, ) .into(); @@ -99,7 +106,15 @@ impl Storage for DB { } else { Some(unsafe { proof_buf.consume() }) }; - (Ok((value, proof)), gas_info) + + // We initialize `proof_buf` with a null pointer. If it is not null, that means + // it was initialized by the go code, with values generated by `memory::allocate_rust`. + let mp_key = if mp_key_buf.ptr.is_null() { + None + } else { + Some(unsafe { mp_key_buf.consume() }) + }; + (Ok((value, proof, mp_key)), gas_info) } /// Allows iteration over a set of key/value pairs, either forwards or backwards. From c0102a2b8696f7fc24112e9b0978aa6ae80bc543 Mon Sep 17 00:00:00 2001 From: toml01 Date: Wed, 14 Jun 2023 13:00:09 +0300 Subject: [PATCH 27/51] Implement storesRootsFromMultiStore() --- app/app.go | 54 +++++++++++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 53 insertions(+), 1 deletion(-) diff --git a/app/app.go b/app/app.go index 29eb0d838..0ceda97b4 100644 --- a/app/app.go +++ b/app/app.go @@ -1,11 +1,13 @@ package app import ( + "encoding/binary" "fmt" "io" "net/http" "os" "path/filepath" + "sort" "github.com/scrtlabs/SecretNetwork/app/keepers" icaauth "github.com/scrtlabs/SecretNetwork/x/mauth" @@ -23,6 +25,7 @@ import ( "github.com/cosmos/cosmos-sdk/simapp" "github.com/cosmos/cosmos-sdk/store/rootmulti" sdk "github.com/cosmos/cosmos-sdk/types" + "github.com/cosmos/cosmos-sdk/types/kv" "github.com/cosmos/cosmos-sdk/types/module" "github.com/cosmos/cosmos-sdk/x/authz" ica "github.com/cosmos/ibc-go/v3/modules/apps/27-interchain-accounts" @@ -424,14 +427,63 @@ func (app *SecretNetworkApp) BeginBlocker(ctx sdk.Context, req abci.RequestBegin } else { stores := rootMulti.GetStores() for k, v := range stores { - fmt.Printf("TOMMM root multi stores\nk: %+v\nhash: %+v\n", k.Name(), v.LastCommitID().Hash) + fmt.Printf("TOMMM store %s hash: %+v\n", k.Name(), v.LastCommitID().Hash) } } + + fmt.Printf("TOMMM respective app hash: %+v\n", rootMulti.LastCommitID().Hash) //////////////// EXPERIMENT //////////////// return app.mm.BeginBlock(ctx, req) } +func storesRootsFromMultiStore(rootMulti *rootmulti.Store) [][]byte { + stores := rootMulti.GetStores() + kvs := kv.Pairs{} + + for k, v := range stores { + // Stores of type StoreTypeTransient don't participate in AppHash calculation + if v.GetStoreType() == sdk.StoreTypeTransient { + continue + } + + kvs.Pairs = append(kvs.Pairs, kv.Pair{Key: []byte(k.Name()), Value: v.LastCommitID().Hash}) + } + + // Have to sort in order to calculate the correct AppHash + sort.Sort(kvs) + + storeRoots := make([][]byte, len(kvs.Pairs)) + for i, kvp := range kvs.Pairs { + storeRoots[i] = pairBytes(kvp) + } + + return storeRoots +} + +// This is a copy of an internal cosmos-sdk function: https://github.com/scrtlabs/cosmos-sdk/blob/1b9278476b3ac897d8ebb90241008476850bf212/store/internal/maps/maps.go#LL152C1-L152C1 +// pairBytes returns key || value, with both the +// key and value length prefixed. +func pairBytes(kv kv.Pair) []byte { + // In the worst case: + // * 8 bytes to Uvarint encode the length of the key + // * 8 bytes to Uvarint encode the length of the value + // So preallocate for the worst case, which will in total + // be a maximum of 14 bytes wasted, if len(key)=1, len(value)=1, + // but that's going to rare. + buf := make([]byte, 8+len(kv.Key)+8+len(kv.Value)) + + // Encode the key, prefixed with its length. + nlk := binary.PutUvarint(buf, uint64(len(kv.Key))) + nk := copy(buf[nlk:], kv.Key) + + // Encode the value, prefixing with its length. + nlv := binary.PutUvarint(buf[nlk+nk:], uint64(len(kv.Value))) + nv := copy(buf[nlk+nk+nlv:], kv.Value) + + return buf[:nlk+nk+nlv+nv] +} + // EndBlocker application updates every end block func (app *SecretNetworkApp) EndBlocker(ctx sdk.Context, req abci.RequestEndBlock) abci.ResponseEndBlock { return app.mm.EndBlock(ctx, req) From 8536106879fbdd5d1e3f4e3bb9b691014309eb2f Mon Sep 17 00:00:00 2001 From: toml01 Date: Wed, 14 Jun 2023 13:25:25 +0300 Subject: [PATCH 28/51] Fix storesRootsFromMultiStore (hash value of store hash) --- app/app.go | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/app/app.go b/app/app.go index 0ceda97b4..aa9e253fb 100644 --- a/app/app.go +++ b/app/app.go @@ -87,6 +87,7 @@ import ( "github.com/gorilla/mux" "github.com/rakyll/statik/fs" abci "github.com/tendermint/tendermint/abci/types" + "github.com/tendermint/tendermint/crypto/tmhash" tmjson "github.com/tendermint/tendermint/libs/json" tmlog "github.com/tendermint/tendermint/libs/log" tmos "github.com/tendermint/tendermint/libs/os" @@ -447,7 +448,7 @@ func storesRootsFromMultiStore(rootMulti *rootmulti.Store) [][]byte { continue } - kvs.Pairs = append(kvs.Pairs, kv.Pair{Key: []byte(k.Name()), Value: v.LastCommitID().Hash}) + kvs.Pairs = append(kvs.Pairs, kv.Pair{Key: []byte(k.Name()), Value: tmhash.Sum(v.LastCommitID().Hash)}) } // Have to sort in order to calculate the correct AppHash From da858d3d98f6e2f832363aa3642a2746b4a28a07 Mon Sep 17 00:00:00 2001 From: toml01 Date: Thu, 15 Jun 2023 12:30:30 +0300 Subject: [PATCH 29/51] Some plumbing --- app/app.go | 33 ++++++---- cosmwasm/enclaves/execute/Enclave.edl | 6 ++ .../shared/block-verifier/src/ecalls.rs | 24 ++++++- cosmwasm/packages/sgx-vm/src/lib.rs | 16 ++--- cosmwasm/packages/sgx-vm/src/proofs.rs | 65 +++++++++++++++++++ go-cosmwasm/api/bindings.h | 2 + go-cosmwasm/api/lib.go | 12 ++++ go-cosmwasm/api/lib_mock.go | 4 ++ go-cosmwasm/src/lib.rs | 24 ++++++- 9 files changed, 159 insertions(+), 27 deletions(-) create mode 100644 cosmwasm/packages/sgx-vm/src/proofs.rs diff --git a/app/app.go b/app/app.go index aa9e253fb..6f2294b6a 100644 --- a/app/app.go +++ b/app/app.go @@ -10,6 +10,7 @@ import ( "sort" "github.com/scrtlabs/SecretNetwork/app/keepers" + gocosmwasm "github.com/scrtlabs/SecretNetwork/go-cosmwasm/api" icaauth "github.com/scrtlabs/SecretNetwork/x/mauth" "github.com/cosmos/cosmos-sdk/baseapp" @@ -420,25 +421,27 @@ func (app *SecretNetworkApp) Name() string { return app.BaseApp.Name() } // BeginBlocker application updates every begin block func (app *SecretNetworkApp) BeginBlocker(ctx sdk.Context, req abci.RequestBeginBlock) abci.ResponseBeginBlock { - //////////////// EXPERIMENT //////////////// multiStore := app.BaseApp.CommitMultiStore() rootMulti, ok := multiStore.(*rootmulti.Store) if !ok { - println("TOMMM oops") + panic("app's multi store is not of type *rootmulti.Store") } else { - stores := rootMulti.GetStores() - for k, v := range stores { - fmt.Printf("TOMMM store %s hash: %+v\n", k.Name(), v.LastCommitID().Hash) + storeRoots := storesRootsFromMultiStore(rootMulti) + rootsBytes, err := storeRoots.Marshal() + if err != nil { + panic(err) } - } - fmt.Printf("TOMMM respective app hash: %+v\n", rootMulti.LastCommitID().Hash) - //////////////// EXPERIMENT //////////////// + err = gocosmwasm.SubmitModulesStoreRoots(rootsBytes) + if err != nil { + panic(err) + } + } return app.mm.BeginBlock(ctx, req) } -func storesRootsFromMultiStore(rootMulti *rootmulti.Store) [][]byte { +func storesRootsFromMultiStore(rootMulti *rootmulti.Store) kv.Pairs { //[][]byte { stores := rootMulti.GetStores() kvs := kv.Pairs{} @@ -454,12 +457,14 @@ func storesRootsFromMultiStore(rootMulti *rootmulti.Store) [][]byte { // Have to sort in order to calculate the correct AppHash sort.Sort(kvs) - storeRoots := make([][]byte, len(kvs.Pairs)) - for i, kvp := range kvs.Pairs { - storeRoots[i] = pairBytes(kvp) - } + return kvs + + // storeRoots := make([][]byte, len(kvs.Pairs)) + // for i, kvp := range kvs.Pairs { + // storeRoots[i] = pairBytes(kvp) + // } - return storeRoots + // return storeRoots } // This is a copy of an internal cosmos-sdk function: https://github.com/scrtlabs/cosmos-sdk/blob/1b9278476b3ac897d8ebb90241008476850bf212/store/internal/maps/maps.go#LL152C1-L152C1 diff --git a/cosmwasm/enclaves/execute/Enclave.edl b/cosmwasm/enclaves/execute/Enclave.edl index 827eed8b7..8a961b939 100644 --- a/cosmwasm/enclaves/execute/Enclave.edl +++ b/cosmwasm/enclaves/execute/Enclave.edl @@ -117,6 +117,12 @@ enclave { // [in, count=in_next_validator_set_len] const uint8_t* in_next_validator_set, // uintptr_t in_next_validator_set_len ); + + public sgx_status_t ecall_submit_store_roots( + [in, count=in_roots_len] const uint8_t* in_roots, + uintptr_t in_roots_len + ); + }; untrusted { diff --git a/cosmwasm/enclaves/shared/block-verifier/src/ecalls.rs b/cosmwasm/enclaves/shared/block-verifier/src/ecalls.rs index 6da7d7d84..913ec3558 100644 --- a/cosmwasm/enclaves/shared/block-verifier/src/ecalls.rs +++ b/cosmwasm/enclaves/shared/block-verifier/src/ecalls.rs @@ -43,6 +43,25 @@ macro_rules! validate_input_length { }; } +#[no_mangle] +#[allow(unused_variables)] +pub unsafe extern "C" fn ecall_submit_store_roots( + in_roots: *const u8, + in_roots_len: u32, +) -> sgx_status_t { + validate_input_length!(in_roots_len, "roots", MAX_VARIABLE_LENGTH); + validate_const_ptr!( + in_roots, + in_roots_len as usize, + sgx_status_t::SGX_ERROR_INVALID_PARAMETER + ); + + let store_roots_slice = slice::from_raw_parts(in_roots, in_roots_len as usize); + debug!("store_roots_slice: {:?}", store_roots_slice); + + return sgx_status_t::SGX_SUCCESS; +} + /// # Safety /// This function reads buffers which must be correctly initialized by the caller, /// see safety section of slice::[from_raw_parts](https://doc.rust-lang.org/std/slice/fn.from_raw_parts.html#safety) @@ -214,7 +233,10 @@ pub unsafe extern "C" fn ecall_submit_block_signatures( } } - message_verifier.set_block_info(signed_header.header.height.value(), signed_header.header.time.unix_timestamp_nanos()); + message_verifier.set_block_info( + signed_header.header.height.value(), + signed_header.header.time.unix_timestamp_nanos(), + ); } #[cfg(feature = "random")] diff --git a/cosmwasm/packages/sgx-vm/src/lib.rs b/cosmwasm/packages/sgx-vm/src/lib.rs index a3e75bc66..1f92124d0 100644 --- a/cosmwasm/packages/sgx-vm/src/lib.rs +++ b/cosmwasm/packages/sgx-vm/src/lib.rs @@ -8,11 +8,7 @@ mod conversion; mod errors; mod features; mod ffi; -// mod imports; mod instance; -// mod memory; -// mod middleware; -// mod modules; mod serde; pub mod testing; mod traits; @@ -21,6 +17,7 @@ mod traits; mod attestation; mod enclave; mod enclave_config; +mod proofs; mod seed; mod wasmi; @@ -39,10 +36,6 @@ pub use crate::errors::{ pub use crate::features::features_from_csv; pub use crate::ffi::{FfiError, FfiResult, GasInfo}; pub use crate::instance::{GasReport, Instance}; -pub use enclave_config::{configure_enclave, EnclaveRuntimeConfig}; -/* -pub use crate::modules::FileSystemCache; -*/ pub use crate::serde::{from_slice, to_vec}; pub use crate::traits::{Api, Extern, Querier, Storage}; @@ -51,9 +44,10 @@ pub use crate::traits::StorageIterator; // Secret Network specific exports pub use crate::attestation::{create_attestation_report_u, untrusted_get_encrypted_seed}; +pub use crate::proofs::untrusted_submit_store_roots; +pub use crate::random::untrusted_submit_block_signatures; pub use crate::seed::{ - untrusted_health_check, untrusted_init_bootstrap, - untrusted_init_node, untrusted_key_gen, + untrusted_health_check, untrusted_init_bootstrap, untrusted_init_node, untrusted_key_gen, }; -pub use crate::random::untrusted_submit_block_signatures; +pub use enclave_config::{configure_enclave, EnclaveRuntimeConfig}; diff --git a/cosmwasm/packages/sgx-vm/src/proofs.rs b/cosmwasm/packages/sgx-vm/src/proofs.rs new file mode 100644 index 000000000..99ed5586c --- /dev/null +++ b/cosmwasm/packages/sgx-vm/src/proofs.rs @@ -0,0 +1,65 @@ +use sgx_types::*; + +use log::{debug, error, warn}; + +use crate::enclave::ENCLAVE_DOORBELL; + +extern "C" { + pub fn ecall_submit_store_roots( + eid: sgx_enclave_id_t, + retval: *mut sgx_status_t, + in_roots: *const u8, + in_roots_len: u32, + ) -> sgx_status_t; +} + +pub fn untrusted_submit_store_roots(roots: &[u8]) -> SgxResult<()> { + debug!("Hello from just before - untrusted_submit_store_roots"); + + const RETRY_LIMIT: i32 = 3; + + let mut retry_count = 0; + + // this is here so we can + loop { + let (retval, status) = submit_store_roots_impl(roots)?; + if status != sgx_status_t::SGX_SUCCESS { + return Err(status); + } else if retval != sgx_status_t::SGX_SUCCESS { + if retval == sgx_status_t::SGX_ERROR_FILE_RECOVERY_NEEDED { + warn!( + "Validator set read by enclave was mismatched with current height.. retrying" + ); + // retry with + std::thread::sleep(std::time::Duration::from_millis(500)); + retry_count += 1; + + if retry_count == RETRY_LIMIT { + error!("Validator timed out while waiting for correct validator set"); + return Err(retval); + } + } else { + return Err(retval); + } + } else { + return Ok(()); + } + } +} + +fn submit_store_roots_impl(roots: &[u8]) -> SgxResult<(sgx_status_t, sgx_status_t)> { + // Bind the token to a local variable to ensure its + // destructor runs in the end of the function + let enclave_access_token = ENCLAVE_DOORBELL + .get_access(1) // This can never be recursive + .ok_or(sgx_status_t::SGX_ERROR_BUSY)?; + let enclave = (*enclave_access_token)?; + + let eid = enclave.geteid(); + let mut retval = sgx_status_t::SGX_SUCCESS; + + // let status = unsafe { ecall_get_encrypted_seed(eid, &mut retval, cert, cert_len, & mut seed) }; + let status = + unsafe { ecall_submit_store_roots(eid, &mut retval, roots.as_ptr(), roots.len() as u32) }; + Ok((retval, status)) +} diff --git a/go-cosmwasm/api/bindings.h b/go-cosmwasm/api/bindings.h index f4173d7e2..428668b83 100644 --- a/go-cosmwasm/api/bindings.h +++ b/go-cosmwasm/api/bindings.h @@ -220,3 +220,5 @@ Buffer submit_block_signatures(Buffer header, Buffer txs, Buffer random, Buffer *err); + +bool submit_store_roots(Buffer roots, Buffer *err); diff --git a/go-cosmwasm/api/lib.go b/go-cosmwasm/api/lib.go index a9e08db3a..2f2681a84 100644 --- a/go-cosmwasm/api/lib.go +++ b/go-cosmwasm/api/lib.go @@ -68,6 +68,18 @@ func SubmitBlockSignatures(header []byte, commit []byte, txs []byte, encRandom [ return receiveVector(res), nil } +func SubmitModulesStoreRoots(roots []byte) error { + errmsg := C.Buffer{} + rootsSlice := sendSlice(roots) + defer freeAfterSend(rootsSlice) + + _, err := C.submit_store_roots(rootsSlice, &errmsg) + if err != nil { + return errorWithMessage(err, errmsg) + } + return nil +} + func InitBootstrap(spid []byte, apiKey []byte) ([]byte, error) { errmsg := C.Buffer{} spidSlice := sendSlice(spid) diff --git a/go-cosmwasm/api/lib_mock.go b/go-cosmwasm/api/lib_mock.go index ca007ae18..b1361490e 100644 --- a/go-cosmwasm/api/lib_mock.go +++ b/go-cosmwasm/api/lib_mock.go @@ -43,6 +43,10 @@ func SubmitBlockSignatures(header []byte, commit []byte, txs []byte, random []by return nil, nil } +func SubmitModulesStoreRoots(roots []byte) error { + return nil +} + func LoadSeedToEnclave(masterKey []byte, seed []byte, apiKey []byte) (bool, error) { return true, nil } diff --git a/go-cosmwasm/src/lib.rs b/go-cosmwasm/src/lib.rs index fd6e05915..5f3c734ca 100644 --- a/go-cosmwasm/src/lib.rs +++ b/go-cosmwasm/src/lib.rs @@ -221,11 +221,33 @@ pub extern "C" fn init_cache( } } +#[no_mangle] +pub extern "C" fn submit_store_roots(roots: Buffer, err: Option<&mut Buffer>) -> bool { + let roots_slice = match unsafe { roots.read() } { + None => { + set_error(Error::empty_arg("roots"), err); + return false; + } + Some(r) => r, + }; + + match cosmwasm_sgx_vm::untrusted_submit_store_roots(roots_slice) { + Err(e) => { + set_error(Error::enclave_err(e.to_string()), err); + false + } + Ok(()) => { + clear_error(); + true + } + } +} + #[no_mangle] pub extern "C" fn submit_block_signatures( header: Buffer, commit: Buffer, - txs: Buffer, + txs: Buffer, random: Buffer, // val_set: Buffer, // next_val_set: Buffer, From f6a34684fd29b8316669a6b2b1333ea37b8a1475 Mon Sep 17 00:00:00 2001 From: toml01 Date: Thu, 15 Jun 2023 17:15:52 +0300 Subject: [PATCH 30/51] Construct app hash --- cosmwasm/enclaves/Cargo.lock | 548 +++++++++++------- .../enclaves/shared/block-verifier/Cargo.toml | 18 +- .../shared/block-verifier/src/ecalls.rs | 38 +- 3 files changed, 393 insertions(+), 211 deletions(-) diff --git a/cosmwasm/enclaves/Cargo.lock b/cosmwasm/enclaves/Cargo.lock index 00183ca2f..a54c45f9d 100644 --- a/cosmwasm/enclaves/Cargo.lock +++ b/cosmwasm/enclaves/Cargo.lock @@ -8,7 +8,7 @@ version = "0.4.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0b613b8e1e3cf911a086f53f03bf286f52fd7a7258e4fa606f0ef220d39d8877" dependencies = [ - "generic-array 0.14.6", + "generic-array 0.14.7", ] [[package]] @@ -41,9 +41,9 @@ dependencies = [ [[package]] name = "aho-corasick" -version = "0.7.19" +version = "1.0.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b4f55bd91a0978cbfd91c457a164bab8b4001c833b7f323132c0a4e1922dd44e" +checksum = "43f6cb1bf222025340178f382c426f13757b2960e89779dfcb319c32542a5a41" dependencies = [ "memchr", ] @@ -64,9 +64,9 @@ source = "git+https://github.com/mesalock-linux/anyhow-sgx#9b7763f58b5dedc11f388 [[package]] name = "anyhow" -version = "1.0.66" +version = "1.0.71" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "216261ddc8289130e551ddcd5ce8a064710c0d064a4d2895c67151c92b5443f6" +checksum = "9c7d0618f0e0b7e8ff11427422b64564d5fb0be1940354bfe2e0529b18a9d9b8" [[package]] name = "atty" @@ -74,7 +74,7 @@ version = "0.2.14" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d9b39be18770d11421cdb1b9947a45dd3f37e93092cbf377614828a319d5fee8" dependencies = [ - "hermit-abi", + "hermit-abi 0.1.19", "libc", "winapi", ] @@ -184,16 +184,16 @@ version = "0.9.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "4152116fd6e9dadb291ae18fc1ec3575ed6d84c29642d97890f4b4a3417297e4" dependencies = [ - "generic-array 0.14.6", + "generic-array 0.14.7", ] [[package]] name = "block-buffer" -version = "0.10.3" +version = "0.10.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "69cce20737498f97b993470a6e536b8523f0af7892a4f928cceb1ac5e52ebe7e" +checksum = "3078c7629b62d3f0439517fa394996acacc5cbc91c5a20d8c658e77abd503a71" dependencies = [ - "generic-array 0.14.6", + "generic-array 0.14.7", ] [[package]] @@ -209,10 +209,12 @@ dependencies = [ name = "block-verifier" version = "0.1.0" dependencies = [ + "cosmos-sdk-proto", "cosmos_proto", "enclave_crypto", "enclave_utils", "hex", + "integer-encoding", "lazy_static", "log", "protobuf", @@ -221,7 +223,7 @@ dependencies = [ "sgx_types", "tendermint", "tendermint-light-client-verifier", - "tendermint-proto", + "tendermint-proto 0.28.0", ] [[package]] @@ -250,7 +252,7 @@ version = "1.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "89b2fd2a0dcf38d7971e2194b6b6eebab45ae01067456a7fd93d5547a61b70be" dependencies = [ - "serde 1.0.147", + "serde 1.0.164", ] [[package]] @@ -263,18 +265,18 @@ dependencies = [ "log", "proc-macro2", "quote", - "serde 1.0.147", - "serde_json 1.0.87", - "syn", + "serde 1.0.164", + "serde_json 1.0.96", + "syn 1.0.109", "tempfile", "toml", ] [[package]] name = "cc" -version = "1.0.73" +version = "1.0.79" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2fff2a6927b3bb87f9595d67196a70493f627687a71d87a0d692242c33f58c11" +checksum = "50d30906286121d95be3d479533b458f87493b30a4b5f79a607db8f5d11aa91f" [[package]] name = "cexpr" @@ -313,14 +315,14 @@ version = "0.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7ee52072ec15386f770805afd189a01c8841be8696bed250fa2f13c4c0d6dfb7" dependencies = [ - "generic-array 0.14.6", + "generic-array 0.14.7", ] [[package]] name = "clang-sys" -version = "1.4.0" +version = "1.6.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fa2e27ae6ab525c3d369ded447057bca5438d86dc3a68f6faafb8269ba82ebf3" +checksum = "c688fc74432808e3eb684cae8830a86be1d66a2bd58e1f248ed0960a590baf6f" dependencies = [ "glob", "libc", @@ -358,6 +360,17 @@ version = "0.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "6245d59a3e82a7fc217c5828a6692dbc6dfb63a0c8c90495621f7b9d79704a0e" +[[package]] +name = "cosmos-sdk-proto" +version = "0.16.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c4776e787b24d9568dd61d3237eeb4eb321d622fb881b858c7b82806420e87d4" +dependencies = [ + "prost 0.11.9", + "prost-types", + "tendermint-proto 0.27.0", +] + [[package]] name = "cosmos_proto" version = "1.6.0" @@ -369,9 +382,9 @@ dependencies = [ [[package]] name = "cpufeatures" -version = "0.2.5" +version = "0.2.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "28d997bd5e24a5928dd43e46dc529867e207907fe0b239c3477d924f7f2ca320" +checksum = "3e4c1eaa2012c47becbbad2ab175484c2a84d1185b566fb2cc5b8707343dfe58" dependencies = [ "libc", ] @@ -388,7 +401,7 @@ version = "0.1.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1bfb12502f3fc46cca1bb51ac28df9d618d813cdc3d2f25b9fe775a34af26bb3" dependencies = [ - "generic-array 0.14.6", + "generic-array 0.14.7", "typenum", ] @@ -399,7 +412,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b1d1a86f49236c215f271d40892d5fc950490551400b02ef360692c29815c714" dependencies = [ "cipher", - "generic-array 0.14.6", + "generic-array 0.14.7", "subtle", ] @@ -410,7 +423,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "6d2301688392eb071b0bf1a37be05c469d3cc4dbbd95df672fe28ab021e6a096" dependencies = [ "quote", - "syn", + "syn 1.0.109", ] [[package]] @@ -492,7 +505,7 @@ version = "0.3.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "bd2735a791158376708f9347fe8faba9667589d82427ef3aed6794a8981de3d9" dependencies = [ - "generic-array 0.14.6", + "generic-array 0.14.7", ] [[package]] @@ -505,7 +518,7 @@ dependencies = [ "proc-macro2", "quote", "rustc_version", - "syn", + "syn 1.0.109", ] [[package]] @@ -523,16 +536,16 @@ version = "0.9.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d3dd60d1080a57a05ab032377049e0591415d2b31afd7028356dbf3cc6dcb066" dependencies = [ - "generic-array 0.14.6", + "generic-array 0.14.7", ] [[package]] name = "digest" -version = "0.10.6" +version = "0.10.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8168378f4e5023e7218c89c891c0fd8ecdb5e5e4f18cb78f38cf245dd021e76f" +checksum = "9ed9a281f7bc9b7576e61468ba615a66a5c8cfdff42420a70aa82701a3b1e292" dependencies = [ - "block-buffer 0.10.3", + "block-buffer 0.10.4", "crypto-common", ] @@ -598,9 +611,9 @@ dependencies = [ [[package]] name = "either" -version = "1.8.0" +version = "1.8.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "90e5c1c8368803113bf0c9584fc495a58b86dc8a29edbf8fe877d21d9507e797" +checksum = "7fcaabb2fef8c910e7f4c7ce9f67a1283a1715879a7c230ca9d6d1ae31f16d91" [[package]] name = "enclave-ffi-types" @@ -638,7 +651,7 @@ dependencies = [ "pwasm-utils", "rand_chacha", "rand_core", - "secp256k1 0.24.2", + "secp256k1 0.24.3", "serde 1.0.118", "serde_json 1.0.60", "sgx_tstd", @@ -719,6 +732,27 @@ dependencies = [ "termcolor", ] +[[package]] +name = "errno" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4bcfec3a70f97c962c307b2d2c56e358cf1d00b558d74262b5f929ee8cc7e73a" +dependencies = [ + "errno-dragonfly", + "libc", + "windows-sys", +] + +[[package]] +name = "errno-dragonfly" +version = "0.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "aa68f1b12764fab894d2755d2518754e71b4fd80ecfb822714a1206c2aab39bf" +dependencies = [ + "cc", + "libc", +] + [[package]] name = "fake-simd" version = "0.1.2" @@ -727,9 +761,9 @@ checksum = "e88a8acf291dafb59c2d96e8f59828f3838bb1a70398823ade51a84de6a6deed" [[package]] name = "fastrand" -version = "1.8.0" +version = "1.9.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a7a407cfaa3385c4ae6b23e84623d48c2798d06e3e6a1878f7f59f17b3f86499" +checksum = "e51093e27b0797c359783294ca4f0a911c270184cb10f85783b118614a1501be" dependencies = [ "instant", ] @@ -745,9 +779,9 @@ dependencies = [ [[package]] name = "futures" -version = "0.3.26" +version = "0.3.28" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "13e2792b0ff0340399d58445b88fd9770e3489eff258a4cbc1523418f12abf84" +checksum = "23342abe12aba583913b2e62f22225ff9c950774065e4bfb61a19cd9770fec40" dependencies = [ "futures-channel", "futures-core", @@ -759,9 +793,9 @@ dependencies = [ [[package]] name = "futures-channel" -version = "0.3.26" +version = "0.3.28" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2e5317663a9089767a1ec00a487df42e0ca174b61b4483213ac24448e4664df5" +checksum = "955518d47e09b25bbebc7a18df10b81f0c766eaf4c4f1cccef2fca5f2a4fb5f2" dependencies = [ "futures-core", "futures-sink", @@ -769,33 +803,33 @@ dependencies = [ [[package]] name = "futures-core" -version = "0.3.26" +version = "0.3.28" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ec90ff4d0fe1f57d600049061dc6bb68ed03c7d2fbd697274c41805dcb3f8608" +checksum = "4bca583b7e26f571124fe5b7561d49cb2868d79116cfa0eefce955557c6fee8c" [[package]] name = "futures-io" -version = "0.3.26" +version = "0.3.28" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bfb8371b6fb2aeb2d280374607aeabfc99d95c72edfe51692e42d3d7f0d08531" +checksum = "4fff74096e71ed47f8e023204cfd0aa1289cd54ae5430a9523be060cdb849964" [[package]] name = "futures-sink" -version = "0.3.26" +version = "0.3.28" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f310820bb3e8cfd46c80db4d7fb8353e15dfff853a127158425f31e0be6c8364" +checksum = "f43be4fe21a13b9781a69afa4985b0f6ee0e1afab2c6f454a8cf30e2b2237b6e" [[package]] name = "futures-task" -version = "0.3.26" +version = "0.3.28" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dcf79a1bf610b10f42aea489289c5a2c478a786509693b80cd39c44ccd936366" +checksum = "76d3d132be6c0e6aa1534069c705a74a5997a356c0dc2f86a47765e5617c5b65" [[package]] name = "futures-util" -version = "0.3.26" +version = "0.3.28" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9c1d6de3acfef38d2be4b1f543f553131788603495be83da675e180c8d6b7bd1" +checksum = "26b01e40b772d54cf6c6d721c1d1abd0647a0106a12ecaa1c186273392a69533" dependencies = [ "futures-core", "futures-sink", @@ -815,9 +849,9 @@ dependencies = [ [[package]] name = "generic-array" -version = "0.14.6" +version = "0.14.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bff49e947297f3312447abdca79f45f4738097cc82b06e72054d2223f601f1b9" +checksum = "85649ca51fd72272d7821adaf274ad91c288277713d9c18820d8499a7ff69e9a" dependencies = [ "typenum", "version_check", @@ -836,9 +870,9 @@ dependencies = [ [[package]] name = "getrandom" -version = "0.2.8" +version = "0.2.10" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c05aeb6a22b8f62540c194aac980f2115af067bfe15a0734d7277a768d396b31" +checksum = "be4136b2a15dd319360be1c07d9933517ccf0be8f16bf62a3bee4f0d618df427" dependencies = [ "cfg-if 1.0.0", "libc", @@ -847,9 +881,9 @@ dependencies = [ [[package]] name = "glob" -version = "0.3.0" +version = "0.3.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9b919933a397b79c37e33b77bb2aa3dc8eb6e165ad809e58ff75bc7db2e34574" +checksum = "d2fabcfbdc87f4758337ca535fb41a6d701b65693ce38287d856d1674551ec9b" [[package]] name = "hashbrown_tstd" @@ -873,6 +907,12 @@ dependencies = [ "libc", ] +[[package]] +name = "hermit-abi" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fed44880c466736ef9a5c5b5facefb5ed0785676d0c02d612db14e54f0d84286" + [[package]] name = "hex" version = "0.4.3" @@ -904,7 +944,7 @@ source = "git+https://github.com/scrtlabs/impl-trait-for-tuples?tag=v0.2.2-secre dependencies = [ "proc-macro2", "quote", - "syn", + "syn 1.0.109", ] [[package]] @@ -916,6 +956,23 @@ dependencies = [ "cfg-if 1.0.0", ] +[[package]] +name = "integer-encoding" +version = "3.0.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8bb03732005da905c88227371639bf1ad885cc712789c011c31c5fb3ab3ccf02" + +[[package]] +name = "io-lifetimes" +version = "1.0.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "eae7b9aee968036d54dce06cebaefd919e4472e753296daccd6d344e3e2df0c2" +dependencies = [ + "hermit-abi 0.3.1", + "libc", + "windows-sys", +] + [[package]] name = "itertools" version = "0.8.2" @@ -944,15 +1001,18 @@ dependencies = [ [[package]] name = "itoa" -version = "1.0.4" +version = "1.0.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4217ad341ebadf8d8e724e264f13e593e0648f5b3e94b3896a5df283be015ecc" +checksum = "453ad9f582a441959e5f0d088b02ce04cfe8d51a8eaf077f12ac6d3e94164ca6" [[package]] name = "keccak" -version = "0.1.2" +version = "0.1.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f9b7d56ba4a8344d6be9729995e6b06f928af29998cdf79fe390cbf6b1fee838" +checksum = "8f6d5ed8676d904364de097082f4e7d240b571b67989ced0240f08b7f966f940" +dependencies = [ + "cpufeatures", +] [[package]] name = "lazy_static" @@ -974,9 +1034,9 @@ checksum = "884e2677b40cc8c339eaefcb701c32ef1fd2493d71118dc0ca4b6a736c93bd67" [[package]] name = "libc" -version = "0.2.137" +version = "0.2.146" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fc7fcc620a3bff7cdd7a365be3376c97191aeaccc2a603e600951e452615bf89" +checksum = "f92be4933c13fd498862a9e02a3055f8a8d9c039ce33db97306fd5a6caa7f29b" [[package]] name = "libloading" @@ -994,20 +1054,23 @@ version = "0.1.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7fc7aa29613bd6a620df431842069224d8bc9011086b1db4c0e0cd47fa03ec9a" +[[package]] +name = "linux-raw-sys" +version = "0.3.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ef53942eb7bf7ff43a617b3e2c1c4a5ecf5944a7c1bc12d7ee39bbb15e5c1519" + [[package]] name = "log" -version = "0.4.17" +version = "0.4.19" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "abb12e687cfb44aa40f41fc3978ef76448f9b6038cad6aef4259d3c095a2382e" -dependencies = [ - "cfg-if 1.0.0", -] +checksum = "b06a4cde4c0f271a446782e3eff8de789548ce57dbc8eca9292c27f4a42004b4" [[package]] name = "lru" -version = "0.7.1" +version = "0.7.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "469898e909a1774d844793b347135a0cd344ca2f69d082013ecb8061a2229a3a" +checksum = "e999beba7b6e8345721bd280141ed958096a2e4abdf74f67ff4ce49b4b54e47a" [[package]] name = "memchr" @@ -1023,9 +1086,9 @@ checksum = "71d96e3f3c0b6325d8ccd83c33b28acb183edcb6c67938ba104ec546854b0882" [[package]] name = "nom" -version = "5.1.2" +version = "5.1.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ffb4262d26ed83a1c0a33a38fe2bb15797329c85770da05e6b828ddb782627af" +checksum = "08959a387a676302eebf4ddbcbc611da04285579f76f88ee0506c63b1a61dd4b" dependencies = [ "memchr", "version_check", @@ -1050,7 +1113,7 @@ checksum = "876a53fff98e03a936a674b29568b0e605f06b29372c2489ff4de23f1949743d" dependencies = [ "proc-macro2", "quote", - "syn", + "syn 1.0.109", ] [[package]] @@ -1104,29 +1167,29 @@ dependencies = [ [[package]] name = "num_enum" -version = "0.5.7" +version = "0.5.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cf5395665662ef45796a4ff5486c5d41d29e0c09640af4c5f17fd94ee2c119c9" +checksum = "1f646caf906c20226733ed5b1374287eb97e3c2a5c227ce668c1f2ce20ae57c9" dependencies = [ "num_enum_derive", ] [[package]] name = "num_enum_derive" -version = "0.5.7" +version = "0.5.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3b0498641e53dd6ac1a4f22547548caa6864cc4933784319cd1775271c5a46ce" +checksum = "dcbff9bc912032c62bf65ef1d5aea88983b420f4f839db1e9b0c281a25c9c799" dependencies = [ "proc-macro2", "quote", - "syn", + "syn 1.0.109", ] [[package]] name = "once_cell" -version = "1.15.0" +version = "1.18.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e82dad04139b71a90c080c8463fe0dc7902db5192d939bd0950f074d014339e1" +checksum = "dd8b5dd2ae5ed71462c540258bedcb51965123ad7e7ccf4b9a8cafaa4a63576d" [[package]] name = "opaque-debug" @@ -1148,9 +1211,9 @@ checksum = "ddfc878dac00da22f8f61e7af3157988424567ab01d9920b962ef7dcbd7cd865" [[package]] name = "paste" -version = "1.0.11" +version = "1.0.12" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d01a5bd0424d00070b0098dd17ebca6f961a959dead1dbcbbbc1d1cd8d3deeba" +checksum = "9f746c4065a8fa3fe23974dd82f15431cc8d40779821001404d10d2e79ca7d79" [[package]] name = "peeking_take_while" @@ -1172,15 +1235,15 @@ checksum = "8b870d8c151b6f2fb93e84a13146138f05d02ed11c7e7c54f8826aaaf7c9f184" [[package]] name = "ppv-lite86" -version = "0.2.16" +version = "0.2.17" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "eb9f9e6e233e5c4a35559a617bf40a4ec447db2e84c20b55a6f83167b7e57872" +checksum = "5b40af805b3121feab8a3c29f04d8ad262fa8e0561883e7653e024ae4479e6de" [[package]] name = "proc-macro2" -version = "1.0.47" +version = "1.0.60" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5ea3d908b0e36316caf9e9e2c4625cdde190a7e6f440d794667ed17a1855e725" +checksum = "dec2b086b7a862cf4de201096214fa870344cf922b2b30c167badb3af3195406" dependencies = [ "unicode-ident", ] @@ -1196,12 +1259,12 @@ dependencies = [ [[package]] name = "prost" -version = "0.11.6" +version = "0.11.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "21dc42e00223fc37204bd4aa177e69420c604ca4a183209a8f9de30c6d934698" +checksum = "0b82eaa1d779e9a4bc1c3217db8ffbeabaae1dca241bf70183242128d48681cd" dependencies = [ "bytes 1.4.0", - "prost-derive 0.11.6", + "prost-derive 0.11.9", ] [[package]] @@ -1213,30 +1276,29 @@ dependencies = [ "itertools 0.8.2", "proc-macro2", "quote", - "syn", + "syn 1.0.109", ] [[package]] name = "prost-derive" -version = "0.11.6" +version = "0.11.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8bda8c0881ea9f722eb9629376db3d0b903b462477c1aafcb0566610ac28ac5d" +checksum = "e5d2d8d10f3c6ded6da8b05b5fb3b8a5082514344d56c9f871412d29b4e075b4" dependencies = [ - "anyhow 1.0.66", + "anyhow 1.0.71", "itertools 0.10.5", "proc-macro2", "quote", - "syn", + "syn 1.0.109", ] [[package]] name = "prost-types" -version = "0.11.6" +version = "0.11.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a5e0526209433e96d83d750dd81a99118edbc55739e7e61a46764fd2ad537788" +checksum = "213622a1460818959ac1181aaeb2dc9c7f63df720db7d788b3e24eacd1983e13" dependencies = [ - "bytes 1.4.0", - "prost 0.11.6", + "prost 0.11.9", ] [[package]] @@ -1261,7 +1323,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9ac70cfc8935f5db2a29c0929db697035d02284011a9b78a5ef5d48092ce9673" dependencies = [ "log", - "which 4.3.0", + "which 4.4.0", ] [[package]] @@ -1289,9 +1351,9 @@ dependencies = [ [[package]] name = "quote" -version = "1.0.21" +version = "1.0.28" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bbe448f377a7d6961e30f5955f9b8d106c3f5e449d493ee1b125c1d43c2b5179" +checksum = "1b9ab9c7eadfd8df19006f1cf1a4aed13540ed5cbc047010ece5826e10825488" dependencies = [ "proc-macro2", ] @@ -1324,22 +1386,31 @@ dependencies = [ "bitflags", ] +[[package]] +name = "redox_syscall" +version = "0.3.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "567664f262709473930a4bf9e51bf2ebf3348f2e748ccc50dea20646858f8f29" +dependencies = [ + "bitflags", +] + [[package]] name = "redox_users" version = "0.4.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b033d837a7cf162d7993aded9304e30a83213c648b6e389db233191f891e5c2b" dependencies = [ - "getrandom 0.2.8", - "redox_syscall", + "getrandom 0.2.10", + "redox_syscall 0.2.16", "thiserror", ] [[package]] name = "regex" -version = "1.7.0" +version = "1.8.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e076559ef8e241f2ae3479e36f97bd5741c0330689e217ad51ce2c76808b868a" +checksum = "d0ab3ca65655bb1e41f2a8c8cd662eb4fb035e67c3f78da1d61dffe89d07300f" dependencies = [ "aho-corasick", "memchr", @@ -1348,18 +1419,9 @@ dependencies = [ [[package]] name = "regex-syntax" -version = "0.6.28" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "456c603be3e8d448b072f410900c09faf164fbce2d480456f50eea6e25f9c848" - -[[package]] -name = "remove_dir_all" -version = "0.5.3" +version = "0.7.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3acd125665422973a33ac9d3dd2df85edad0f4ae9b00dafb1a05e43a9f5ef8e7" -dependencies = [ - "winapi", -] +checksum = "436b050e76ed2903236f032a59761c1eb99e1b0aead2c257922771dab1fc8c78" [[package]] name = "ring" @@ -1398,6 +1460,20 @@ dependencies = [ "semver", ] +[[package]] +name = "rustix" +version = "0.37.20" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b96e891d04aa506a6d1f318d2771bcb1c7dfda84e126660ace067c9b474bb2c0" +dependencies = [ + "bitflags", + "errno", + "io-lifetimes", + "libc", + "linux-raw-sys", + "windows-sys", +] + [[package]] name = "rustls" version = "0.19.0" @@ -1412,9 +1488,9 @@ dependencies = [ [[package]] name = "ryu" -version = "1.0.11" +version = "1.0.13" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4501abdff3ae82a1c1b477a17252eb69cee9e66eb915c1abaa4f44d873df9f09" +checksum = "f91339c0467de62360649f8d3e185ca8de4224ff281f66000de5eb2a77a79041" [[package]] name = "sct" @@ -1428,9 +1504,9 @@ dependencies = [ [[package]] name = "secp256k1" -version = "0.24.2" +version = "0.24.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d9512ffd81e3a3503ed401f79c33168b9148c75038956039166cd750eaa037c3" +checksum = "6b1629c9c557ef9b293568b338dddfc8208c98a18c59d722a9d53f859d9c9b62" dependencies = [ "secp256k1-sys 0.6.1", ] @@ -1441,7 +1517,7 @@ version = "0.26.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "4124a35fe33ae14259c490fd70fa199a32b9ce9502f2ee6bc4f81ec06fa65894" dependencies = [ - "secp256k1-sys 0.8.0", + "secp256k1-sys 0.8.1", ] [[package]] @@ -1455,9 +1531,9 @@ dependencies = [ [[package]] name = "secp256k1-sys" -version = "0.8.0" +version = "0.8.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "642a62736682fdd8c71da0eb273e453c8ac74e33b9fb310e22ba5b03ec7651ff" +checksum = "70a129b9e9efbfb223753b9163c4ab3b13cff7fd9c7f010fbac25ab4099fa07e" dependencies = [ "cc", ] @@ -1517,9 +1593,9 @@ dependencies = [ [[package]] name = "semver" -version = "1.0.14" +version = "1.0.17" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e25dfac463d778e353db5be2449d1cce89bd6fd23c9f1ea21310ce6e5a1b29c4" +checksum = "bebd363326d05ec3e2f532ab7660680f3b02130d780c299bca73469d521bc0ed" [[package]] name = "serde" @@ -1532,11 +1608,11 @@ dependencies = [ [[package]] name = "serde" -version = "1.0.147" +version = "1.0.164" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d193d69bae983fc11a79df82342761dfbf28a99fc8d203dca4c3c1b590948965" +checksum = "9e8c8cf938e98f769bc164923b06dce91cea1751522f46f8466461af04c9027d" dependencies = [ - "serde_derive 1.0.147", + "serde_derive 1.0.164", ] [[package]] @@ -1545,7 +1621,7 @@ version = "0.11.9" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "416bda436f9aab92e02c8e10d49a15ddd339cea90b6e340fe51ed97abb548294" dependencies = [ - "serde 1.0.147", + "serde 1.0.164", ] [[package]] @@ -1555,18 +1631,18 @@ source = "git+https://github.com/mesalock-linux/serde-sgx#db0226f1d5d70fca6b96af dependencies = [ "proc-macro2", "quote", - "syn", + "syn 1.0.109", ] [[package]] name = "serde_derive" -version = "1.0.147" +version = "1.0.164" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4f1d362ca8fc9c3e3a7484440752472d68a6caa98f1ab81d99b5dfe517cec852" +checksum = "d9735b638ccc51c28bf6914d90a2e9725b377144fc612c49a611fddd1b631d68" dependencies = [ "proc-macro2", "quote", - "syn", + "syn 2.0.18", ] [[package]] @@ -1582,24 +1658,24 @@ dependencies = [ [[package]] name = "serde_json" -version = "1.0.87" +version = "1.0.96" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6ce777b7b150d76b9cf60d28b55f5847135a003f7d7350c6be7a773508ce7d45" +checksum = "057d394a50403bcac12672b2b18fb387ab6d289d957dab67dd201875391e52f1" dependencies = [ - "itoa 1.0.4", + "itoa 1.0.6", "ryu", - "serde 1.0.147", + "serde 1.0.164", ] [[package]] name = "serde_repr" -version = "0.1.10" +version = "0.1.12" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9a5ec9fa74a20ebbe5d9ac23dac1fc96ba0ecfe9f50f2843b52e537b10fbcb4e" +checksum = "bcec881020c684085e55a25f7fd888954d56609ef363479dc5a1305eb0d40cab" dependencies = [ "proc-macro2", "quote", - "syn", + "syn 2.0.18", ] [[package]] @@ -1728,16 +1804,16 @@ checksum = "82e6b795fe2e3b1e845bafcb27aa35405c4d47cdfc92af5fc8d3002f76cebdc0" dependencies = [ "cfg-if 1.0.0", "cpufeatures", - "digest 0.10.6", + "digest 0.10.7", ] [[package]] name = "sha3" -version = "0.10.6" +version = "0.10.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bdf0c33fae925bdc080598b84bc15c55e7b9a4a43b3c704da051f977469691c9" +checksum = "75872d278a8f37ef87fa0ddbda7802605cb18344497949862c0d4dcb291eba60" dependencies = [ - "digest 0.10.6", + "digest 0.10.7", "keccak", ] @@ -1805,9 +1881,9 @@ dependencies = [ [[package]] name = "syn" -version = "1.0.103" +version = "1.0.109" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a864042229133ada95abf3b54fdc62ef5ccabe9515b64717bcb9a1919e59445d" +checksum = "72b64191b275b66ffe2469e8af2c1cfe3bafa67b529ead792a6d0160888b4237" dependencies = [ "proc-macro2", "quote", @@ -1815,35 +1891,34 @@ dependencies = [ ] [[package]] -name = "synstructure" -version = "0.12.6" +name = "syn" +version = "2.0.18" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f36bdaa60a83aca3921b5259d5400cbf5e90fc51931376a9bd4a0eb79aa7210f" +checksum = "32d41677bcbe24c20c52e7c70b0d8db04134c5d1066bf98662e2871ad200ea3e" dependencies = [ "proc-macro2", "quote", - "syn", - "unicode-xid", + "unicode-ident", ] [[package]] name = "tempfile" -version = "3.3.0" +version = "3.6.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5cdb1ef4eaeeaddc8fbd371e5017057064af0911902ef36b39801f67cc6d79e4" +checksum = "31c0432476357e58790aaa47a8efb0c5138f137343f3b5f23bd36a27e3b0a6d6" dependencies = [ + "autocfg 1.1.0", "cfg-if 1.0.0", "fastrand", - "libc", - "redox_syscall", - "remove_dir_all", - "winapi", + "redox_syscall 0.3.5", + "rustix", + "windows-sys", ] [[package]] name = "tendermint" version = "0.28.0" -source = "git+https://github.com/scrtlabs/tendermint-rs?branch=fix-val-set-parsing#4019839ff894e531fbe4187f8461e4395d203220" +source = "git+https://github.com/scrtlabs/tendermint-rs?branch=fix-val-set-parsing#b75754a49981f8e52fa12b8c17a38ebda575f807" dependencies = [ "bytes 1.4.0", "ed25519", @@ -1852,17 +1927,17 @@ dependencies = [ "futures", "num-traits 0.2.15", "once_cell", - "prost 0.11.6", + "prost 0.11.9", "prost-types", - "serde 1.0.147", + "serde 1.0.164", "serde_bytes", - "serde_json 1.0.87", + "serde_json 1.0.96", "serde_repr", "sha2 0.9.9", "signature", "subtle", "subtle-encoding", - "tendermint-proto", + "tendermint-proto 0.28.0", "time", "zeroize", ] @@ -1870,27 +1945,45 @@ dependencies = [ [[package]] name = "tendermint-light-client-verifier" version = "0.28.0" -source = "git+https://github.com/scrtlabs/tendermint-rs?branch=fix-val-set-parsing#4019839ff894e531fbe4187f8461e4395d203220" +source = "git+https://github.com/scrtlabs/tendermint-rs?branch=fix-val-set-parsing#b75754a49981f8e52fa12b8c17a38ebda575f807" dependencies = [ "derive_more", "flex-error", - "serde 1.0.147", + "serde 1.0.164", "tendermint", "time", ] +[[package]] +name = "tendermint-proto" +version = "0.27.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d5895470f28c530f8ae8c4071bf8190304ce00bd131d25e81730453124a3375c" +dependencies = [ + "bytes 1.4.0", + "flex-error", + "num-derive", + "num-traits 0.2.15", + "prost 0.11.9", + "prost-types", + "serde 1.0.164", + "serde_bytes", + "subtle-encoding", + "time", +] + [[package]] name = "tendermint-proto" version = "0.28.0" -source = "git+https://github.com/scrtlabs/tendermint-rs?branch=fix-val-set-parsing#4019839ff894e531fbe4187f8461e4395d203220" +source = "git+https://github.com/scrtlabs/tendermint-rs?branch=fix-val-set-parsing#b75754a49981f8e52fa12b8c17a38ebda575f807" dependencies = [ "bytes 1.4.0", "flex-error", "num-derive", "num-traits 0.2.15", - "prost 0.11.6", + "prost 0.11.9", "prost-types", - "serde 1.0.147", + "serde 1.0.164", "serde_bytes", "subtle-encoding", "time", @@ -1898,9 +1991,9 @@ dependencies = [ [[package]] name = "termcolor" -version = "1.1.3" +version = "1.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bab24d30b911b2376f3a13cc2cd443142f0c81dda04c118693e35b3835757755" +checksum = "be55cf8942feac5c765c2c993422806843c9a9a45d4d5c407ad6dd2ea95eb9b6" dependencies = [ "winapi-util", ] @@ -1916,22 +2009,22 @@ dependencies = [ [[package]] name = "thiserror" -version = "1.0.37" +version = "1.0.40" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "10deb33631e3c9018b9baf9dcbbc4f737320d2b576bac10f6aefa048fa407e3e" +checksum = "978c9a314bd8dc99be594bc3c175faaa9794be04a5a5e153caba6915336cebac" dependencies = [ "thiserror-impl", ] [[package]] name = "thiserror-impl" -version = "1.0.37" +version = "1.0.40" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "982d17546b47146b28f7c22e3d08465f6b8903d0ea13c1660d9d84a6e7adcdbb" +checksum = "f9456a42c5b0d803c8cd86e73dd7cc9edd429499f37a3550d286d5e86720569f" dependencies = [ "proc-macro2", "quote", - "syn", + "syn 2.0.18", ] [[package]] @@ -1940,7 +2033,7 @@ version = "0.3.17" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a561bf4617eebd33bca6434b988f39ed798e527f51a1e797d0ee4f61c0a38376" dependencies = [ - "serde 1.0.147", + "serde 1.0.164", "time-core", "time-macros", ] @@ -1962,18 +2055,18 @@ dependencies = [ [[package]] name = "toml" -version = "0.5.9" +version = "0.5.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8d82e1a7758622a465f8cee077614c73484dac5b836c02ff6a40d5d1010324d7" +checksum = "f4f7f0dd8d50a853a531c426359045b1998f04219d88799810762cd4ad314234" dependencies = [ - "serde 1.0.147", + "serde 1.0.164", ] [[package]] name = "typenum" -version = "1.15.0" +version = "1.16.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dcf81ac59edc17cc8697ff311e8f5ef2d99fcbd9817b34cec66f90b6c3dfd987" +checksum = "497961ef93d974e23eb6f433eb5fe1b7930b659f06d12dec6fc44a8f554c0bba" [[package]] name = "uint" @@ -1989,15 +2082,15 @@ dependencies = [ [[package]] name = "unicode-ident" -version = "1.0.5" +version = "1.0.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6ceab39d59e4c9499d4e5a8ee0e2735b891bb7308ac83dfb4e80cad195c9f6f3" +checksum = "b15811caf2415fb889178633e7724bad2509101cde276048e013b9def5e51fa0" [[package]] name = "unicode-segmentation" -version = "1.10.0" +version = "1.10.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0fdbf052a0783de01e944a6ce7a8cb939e295b1e7be835a1112c3b9a7f047a5a" +checksum = "1dd624098567895118886609431a7c3b8f516e41d30e0643f03d94592a147e36" [[package]] name = "unicode-width" @@ -2005,12 +2098,6 @@ version = "0.1.10" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c0edd1e5b14653f783770bce4a4dabb4a5108a5370a5f5d8cfe8710c361f6c8b" -[[package]] -name = "unicode-xid" -version = "0.2.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f962df74c8c05a667b5ee8bcf162993134c104e96440b663c8daa176dc772d8c" - [[package]] name = "untrusted" version = "0.7.1" @@ -2040,7 +2127,7 @@ name = "walrus" version = "0.19.0" source = "git+https://github.com/scrtlabs/walrus?rev=c5777d4#c5777d43d78b437cef94aaa939d3be115dfeee6a" dependencies = [ - "anyhow 1.0.66", + "anyhow 1.0.71", "id-arena", "leb128", "log", @@ -2056,7 +2143,7 @@ dependencies = [ "heck", "proc-macro2", "quote", - "syn", + "syn 1.0.109", ] [[package]] @@ -2145,9 +2232,9 @@ dependencies = [ [[package]] name = "which" -version = "4.3.0" +version = "4.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1c831fbbee9e129a8cf93e7747a82da9d95ba8e16621cae60ec2cdc849bacb7b" +checksum = "2441c784c52b289a054b7201fc93253e288f094e2f4be9058343127c4226a269" dependencies = [ "either", "libc", @@ -2185,6 +2272,72 @@ version = "0.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f" +[[package]] +name = "windows-sys" +version = "0.48.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "677d2418bec65e3338edb076e806bc1ec15693c5d0104683f2efe857f61056a9" +dependencies = [ + "windows-targets", +] + +[[package]] +name = "windows-targets" +version = "0.48.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7b1eb6f0cd7c80c79759c929114ef071b87354ce476d9d94271031c0497adfd5" +dependencies = [ + "windows_aarch64_gnullvm", + "windows_aarch64_msvc", + "windows_i686_gnu", + "windows_i686_msvc", + "windows_x86_64_gnu", + "windows_x86_64_gnullvm", + "windows_x86_64_msvc", +] + +[[package]] +name = "windows_aarch64_gnullvm" +version = "0.48.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "91ae572e1b79dba883e0d315474df7305d12f569b400fcf90581b06062f7e1bc" + +[[package]] +name = "windows_aarch64_msvc" +version = "0.48.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b2ef27e0d7bdfcfc7b868b317c1d32c641a6fe4629c171b8928c7b08d98d7cf3" + +[[package]] +name = "windows_i686_gnu" +version = "0.48.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "622a1962a7db830d6fd0a69683c80a18fda201879f0f447f065a3b7467daa241" + +[[package]] +name = "windows_i686_msvc" +version = "0.48.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4542c6e364ce21bf45d69fdd2a8e455fa38d316158cfd43b3ac1c5b1b19f8e00" + +[[package]] +name = "windows_x86_64_gnu" +version = "0.48.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ca2b8a661f7628cbd23440e50b05d705db3686f894fc9580820623656af974b1" + +[[package]] +name = "windows_x86_64_gnullvm" +version = "0.48.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7896dbc1f41e08872e9d5e8f8baa8fdd2677f29468c4e156210174edc7f7b953" + +[[package]] +name = "windows_x86_64_msvc" +version = "0.48.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1a515f5799fe4961cb532f983ce2b23082366b898e52ffbce459c86f67c8378a" + [[package]] name = "x25519-dalek" version = "1.2.0" @@ -2218,12 +2371,11 @@ dependencies = [ [[package]] name = "zeroize_derive" -version = "1.3.2" +version = "1.4.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3f8f187641dad4f680d25c4bfc4225b418165984179f26ca76ec4fb6441d3a17" +checksum = "ce36e65b0d2999d2aafac989fb249189a141aee1f53c612c1f37d72631959f69" dependencies = [ "proc-macro2", "quote", - "syn", - "synstructure", + "syn 2.0.18", ] diff --git a/cosmwasm/enclaves/shared/block-verifier/Cargo.toml b/cosmwasm/enclaves/shared/block-verifier/Cargo.toml index aeca2ed98..157af85dd 100644 --- a/cosmwasm/enclaves/shared/block-verifier/Cargo.toml +++ b/cosmwasm/enclaves/shared/block-verifier/Cargo.toml @@ -15,7 +15,7 @@ verify-validator-whitelist = [] [target.'cfg(not(target_env = "sgx"))'.dependencies] sgx_tstd = { rev = "d2d339cbb005f676bb700059bd51dc689c025f6b", git = "https://github.com/apache/teaclave-sgx-sdk.git", features = [ ] } -sgx_trts = {rev = "d2d339cbb005f676bb700059bd51dc689c025f6b", git = "https://github.com/apache/teaclave-sgx-sdk.git" } +sgx_trts = { rev = "d2d339cbb005f676bb700059bd51dc689c025f6b", git = "https://github.com/apache/teaclave-sgx-sdk.git" } sgx_types = { rev = "d2d339cbb005f676bb700059bd51dc689c025f6b", git = "https://github.com/apache/teaclave-sgx-sdk.git" } [dependencies] @@ -24,16 +24,10 @@ tendermint-proto = { git = "https://github.com/scrtlabs/tendermint-rs", branch = tendermint-light-client-verifier = { git = "https://github.com/scrtlabs/tendermint-rs", branch = "fix-val-set-parsing", default-features = false } lazy_static = "1.4.0" log = "0.4.17" - -enclave_crypto = {path ="../crypto"} -enclave_utils = {path ="../utils"} - -cosmos_proto = {path="../cosmos-proto"} - +enclave_crypto = { path = "../crypto" } +enclave_utils = { path = "../utils" } +cosmos_proto = { path = "../cosmos-proto" } protobuf = { version = "2.25.2" } hex = { version = "0.4.3" } - -# cosmrs = { version = "0.11.0", default-features = false } - - - +cosmos-sdk-proto = { version = "0.16.0", default-features = false } +integer-encoding = "3.0.4" diff --git a/cosmwasm/enclaves/shared/block-verifier/src/ecalls.rs b/cosmwasm/enclaves/shared/block-verifier/src/ecalls.rs index 913ec3558..4d8b3b740 100644 --- a/cosmwasm/enclaves/shared/block-verifier/src/ecalls.rs +++ b/cosmwasm/enclaves/shared/block-verifier/src/ecalls.rs @@ -1,6 +1,10 @@ +use cosmos_sdk_proto::cosmos::base::kv::v1beta1::{Pair, Pairs}; +use cosmos_sdk_proto::traits::Message; +use integer_encoding::VarInt; use std::slice; use tendermint::block::Commit; use tendermint::block::Header; +use tendermint::merkle; use tendermint_proto::Protobuf; use sgx_types::sgx_status_t; @@ -57,11 +61,43 @@ pub unsafe extern "C" fn ecall_submit_store_roots( ); let store_roots_slice = slice::from_raw_parts(in_roots, in_roots_len as usize); - debug!("store_roots_slice: {:?}", store_roots_slice); + + let store_roots: Pairs = Pairs::decode(store_roots_slice).unwrap(); + let mut store_roots_bytes = vec![]; + + // Encode all key-value pairs to bytes + for root in store_roots.pairs { + store_roots_bytes.push(pair_to_bytes(root)); + } + + let h = merkle::simple_hash_from_byte_vectors(store_roots_bytes); + debug!("received app_hash: {:?}", h); return sgx_status_t::SGX_SUCCESS; } +// This is a copy of a cosmos-sdk function: https://github.com/scrtlabs/cosmos-sdk/blob/1b9278476b3ac897d8ebb90241008476850bf212/store/internal/maps/maps.go#LL152C1-L152C1 +// Returns key || value, with both the key and value length prefixed. +fn pair_to_bytes(kv: Pair) -> Vec { + // In the worst case: + // * 8 bytes to Uvarint encode the length of the key + // * 8 bytes to Uvarint encode the length of the value + // So preallocate for the worst case, which will in total + // be a maximum of 14 bytes wasted, if len(key)=1, len(value)=1, + // but that's going to rare. + let mut buf = vec![]; + + // Encode the key, prefixed with its length. + buf.extend_from_slice(&(kv.key.len()).encode_var_vec()); + buf.extend_from_slice(&kv.key); + + // Encode the value, prefixing with its length. + buf.extend_from_slice(&(kv.value.len()).encode_var_vec()); + buf.extend_from_slice(&kv.value); + + return buf; +} + /// # Safety /// This function reads buffers which must be correctly initialized by the caller, /// see safety section of slice::[from_raw_parts](https://doc.rust-lang.org/std/slice/fn.from_raw_parts.html#safety) From b69816c0bcc309c1624ed896a5b1e0b8bc69e81d Mon Sep 17 00:00:00 2001 From: toml01 Date: Sun, 18 Jun 2023 17:29:14 +0300 Subject: [PATCH 31/51] send the compute root as well --- .vscode/settings.json | 3 ++- app/app.go | 12 ++++------ cosmwasm/enclaves/execute/Enclave.edl | 4 +++- .../shared/block-verifier/src/ecalls.rs | 10 ++++++++ .../enclaves/shared/contract-engine/src/db.rs | 20 +++++++++------- cosmwasm/packages/sgx-vm/src/proofs.rs | 23 +++++++++++++++---- go-cosmwasm/api/bindings.h | 2 +- go-cosmwasm/api/lib.go | 6 +++-- go-cosmwasm/api/lib_mock.go | 2 +- go-cosmwasm/src/lib.rs | 15 ++++++++++-- 10 files changed, 68 insertions(+), 29 deletions(-) diff --git a/.vscode/settings.json b/.vscode/settings.json index 179ffa0aa..9854a1fe5 100644 --- a/.vscode/settings.json +++ b/.vscode/settings.json @@ -14,7 +14,8 @@ "integration-tests/contract-v0.10/Cargo.toml", "go-cosmwasm/Cargo.toml", "integration-tests/contract-v0.10/Cargo.toml", - "check-hw/Cargo.toml" + "check-hw/Cargo.toml", + "./cosmwasm/enclaves/shared/block-verifier/Cargo.toml" ], "rust-analyzer.diagnostics.experimental.enable": true, "rust-analyzer.rustfmt.rangeFormatting.enable": true, diff --git a/app/app.go b/app/app.go index 6f2294b6a..be6195530 100644 --- a/app/app.go +++ b/app/app.go @@ -432,7 +432,10 @@ func (app *SecretNetworkApp) BeginBlocker(ctx sdk.Context, req abci.RequestBegin panic(err) } - err = gocosmwasm.SubmitModulesStoreRoots(rootsBytes) + computeKv := rootMulti.GetCommitKVStore(sdk.NewKVStoreKey(compute.StoreKey)) + computeRoot := computeKv.LastCommitID().Hash + + err = gocosmwasm.SubmitModulesStoreRoots(rootsBytes, computeRoot) if err != nil { panic(err) } @@ -458,13 +461,6 @@ func storesRootsFromMultiStore(rootMulti *rootmulti.Store) kv.Pairs { //[][]byte sort.Sort(kvs) return kvs - - // storeRoots := make([][]byte, len(kvs.Pairs)) - // for i, kvp := range kvs.Pairs { - // storeRoots[i] = pairBytes(kvp) - // } - - // return storeRoots } // This is a copy of an internal cosmos-sdk function: https://github.com/scrtlabs/cosmos-sdk/blob/1b9278476b3ac897d8ebb90241008476850bf212/store/internal/maps/maps.go#LL152C1-L152C1 diff --git a/cosmwasm/enclaves/execute/Enclave.edl b/cosmwasm/enclaves/execute/Enclave.edl index 8a961b939..4145ab971 100644 --- a/cosmwasm/enclaves/execute/Enclave.edl +++ b/cosmwasm/enclaves/execute/Enclave.edl @@ -120,7 +120,9 @@ enclave { public sgx_status_t ecall_submit_store_roots( [in, count=in_roots_len] const uint8_t* in_roots, - uintptr_t in_roots_len + uintptr_t in_roots_len, + [in, count=in_compute_root_len] const uint8_t* in_compute_root, + uintptr_t in_compute_root_len ); }; diff --git a/cosmwasm/enclaves/shared/block-verifier/src/ecalls.rs b/cosmwasm/enclaves/shared/block-verifier/src/ecalls.rs index 4d8b3b740..162aeef47 100644 --- a/cosmwasm/enclaves/shared/block-verifier/src/ecalls.rs +++ b/cosmwasm/enclaves/shared/block-verifier/src/ecalls.rs @@ -52,6 +52,8 @@ macro_rules! validate_input_length { pub unsafe extern "C" fn ecall_submit_store_roots( in_roots: *const u8, in_roots_len: u32, + in_compute_root: *const u8, + in_compute_root_len: u32, ) -> sgx_status_t { validate_input_length!(in_roots_len, "roots", MAX_VARIABLE_LENGTH); validate_const_ptr!( @@ -59,8 +61,15 @@ pub unsafe extern "C" fn ecall_submit_store_roots( in_roots_len as usize, sgx_status_t::SGX_ERROR_INVALID_PARAMETER ); + validate_input_length!(in_compute_root_len, "roots", MAX_VARIABLE_LENGTH); + validate_const_ptr!( + in_compute_root, + in_compute_root_len as usize, + sgx_status_t::SGX_ERROR_INVALID_PARAMETER + ); let store_roots_slice = slice::from_raw_parts(in_roots, in_roots_len as usize); + let compute_root_slice = slice::from_raw_parts(in_compute_root, in_compute_root_len as usize); let store_roots: Pairs = Pairs::decode(store_roots_slice).unwrap(); let mut store_roots_bytes = vec![]; @@ -72,6 +81,7 @@ pub unsafe extern "C" fn ecall_submit_store_roots( let h = merkle::simple_hash_from_byte_vectors(store_roots_bytes); debug!("received app_hash: {:?}", h); + debug!("received compute_root: {:?}", compute_root_slice); return sgx_status_t::SGX_SUCCESS; } diff --git a/cosmwasm/enclaves/shared/contract-engine/src/db.rs b/cosmwasm/enclaves/shared/contract-engine/src/db.rs index b5ee210b8..739f91e11 100644 --- a/cosmwasm/enclaves/shared/contract-engine/src/db.rs +++ b/cosmwasm/enclaves/shared/contract-engine/src/db.rs @@ -177,17 +177,21 @@ pub fn read_from_encrypted_state( Ok((maybe_encrypted_value_bytes, maybe_proof, maybe_mp_key, gas_used)) => { debug!("merkle proof returned from read_db(): {:?}", maybe_proof); debug!("full key returned from read_db(): {:?}", maybe_mp_key); + debug!( + "enc value returned from read_db(): {:?}", + maybe_encrypted_value_bytes + ); match maybe_encrypted_value_bytes { Some(encrypted_value_bytes) => { let encrypted_value: EncryptedValue = bincode2::deserialize(&encrypted_value_bytes).map_err(|err| { - warn!( - "read_db() got an error while trying to read_from_encrypted_state the value {:?} for key {:?}, stopping wasm: {:?}", - encrypted_value_bytes, - encrypted_key_bytes, - err.to_string() - ); - WasmEngineError::DecryptionError - })?; + warn!( + "read_db() got an error while trying to read_from_encrypted_state the value {:?} for key {:?}, stopping wasm: {:?}", + encrypted_value_bytes, + encrypted_key_bytes, + err.to_string() + ); + WasmEngineError::DecryptionError + })?; match decrypt_value_new( &encrypted_key.data, diff --git a/cosmwasm/packages/sgx-vm/src/proofs.rs b/cosmwasm/packages/sgx-vm/src/proofs.rs index 99ed5586c..3a9968cae 100644 --- a/cosmwasm/packages/sgx-vm/src/proofs.rs +++ b/cosmwasm/packages/sgx-vm/src/proofs.rs @@ -10,10 +10,12 @@ extern "C" { retval: *mut sgx_status_t, in_roots: *const u8, in_roots_len: u32, + in_compute_root: *const u8, + in_compute_root_len: u32, ) -> sgx_status_t; } -pub fn untrusted_submit_store_roots(roots: &[u8]) -> SgxResult<()> { +pub fn untrusted_submit_store_roots(roots: &[u8], compute_root: &[u8]) -> SgxResult<()> { debug!("Hello from just before - untrusted_submit_store_roots"); const RETRY_LIMIT: i32 = 3; @@ -22,7 +24,7 @@ pub fn untrusted_submit_store_roots(roots: &[u8]) -> SgxResult<()> { // this is here so we can loop { - let (retval, status) = submit_store_roots_impl(roots)?; + let (retval, status) = submit_store_roots_impl(roots, compute_root)?; if status != sgx_status_t::SGX_SUCCESS { return Err(status); } else if retval != sgx_status_t::SGX_SUCCESS { @@ -47,7 +49,10 @@ pub fn untrusted_submit_store_roots(roots: &[u8]) -> SgxResult<()> { } } -fn submit_store_roots_impl(roots: &[u8]) -> SgxResult<(sgx_status_t, sgx_status_t)> { +fn submit_store_roots_impl( + roots: &[u8], + compute_root: &[u8], +) -> SgxResult<(sgx_status_t, sgx_status_t)> { // Bind the token to a local variable to ensure its // destructor runs in the end of the function let enclave_access_token = ENCLAVE_DOORBELL @@ -59,7 +64,15 @@ fn submit_store_roots_impl(roots: &[u8]) -> SgxResult<(sgx_status_t, sgx_status_ let mut retval = sgx_status_t::SGX_SUCCESS; // let status = unsafe { ecall_get_encrypted_seed(eid, &mut retval, cert, cert_len, & mut seed) }; - let status = - unsafe { ecall_submit_store_roots(eid, &mut retval, roots.as_ptr(), roots.len() as u32) }; + let status = unsafe { + ecall_submit_store_roots( + eid, + &mut retval, + roots.as_ptr(), + roots.len() as u32, + compute_root.as_ptr(), + compute_root.len() as u32, + ) + }; Ok((retval, status)) } diff --git a/go-cosmwasm/api/bindings.h b/go-cosmwasm/api/bindings.h index 428668b83..2255277a1 100644 --- a/go-cosmwasm/api/bindings.h +++ b/go-cosmwasm/api/bindings.h @@ -221,4 +221,4 @@ Buffer submit_block_signatures(Buffer header, Buffer random, Buffer *err); -bool submit_store_roots(Buffer roots, Buffer *err); +bool submit_store_roots(Buffer roots, Buffer compute_root, Buffer *err); diff --git a/go-cosmwasm/api/lib.go b/go-cosmwasm/api/lib.go index 2f2681a84..4014f8eec 100644 --- a/go-cosmwasm/api/lib.go +++ b/go-cosmwasm/api/lib.go @@ -68,12 +68,14 @@ func SubmitBlockSignatures(header []byte, commit []byte, txs []byte, encRandom [ return receiveVector(res), nil } -func SubmitModulesStoreRoots(roots []byte) error { +func SubmitModulesStoreRoots(roots []byte, computeRoot []byte) error { errmsg := C.Buffer{} rootsSlice := sendSlice(roots) defer freeAfterSend(rootsSlice) + computeRootSlice := sendSlice(computeRoot) + defer freeAfterSend(computeRootSlice) - _, err := C.submit_store_roots(rootsSlice, &errmsg) + _, err := C.submit_store_roots(rootsSlice, computeRootSlice, &errmsg) if err != nil { return errorWithMessage(err, errmsg) } diff --git a/go-cosmwasm/api/lib_mock.go b/go-cosmwasm/api/lib_mock.go index b1361490e..b7a00bf9f 100644 --- a/go-cosmwasm/api/lib_mock.go +++ b/go-cosmwasm/api/lib_mock.go @@ -43,7 +43,7 @@ func SubmitBlockSignatures(header []byte, commit []byte, txs []byte, random []by return nil, nil } -func SubmitModulesStoreRoots(roots []byte) error { +func SubmitModulesStoreRoots(roots []byte, computeRoot []byte) error { return nil } diff --git a/go-cosmwasm/src/lib.rs b/go-cosmwasm/src/lib.rs index 5f3c734ca..58273cb4e 100644 --- a/go-cosmwasm/src/lib.rs +++ b/go-cosmwasm/src/lib.rs @@ -222,7 +222,11 @@ pub extern "C" fn init_cache( } #[no_mangle] -pub extern "C" fn submit_store_roots(roots: Buffer, err: Option<&mut Buffer>) -> bool { +pub extern "C" fn submit_store_roots( + roots: Buffer, + compute_root: Buffer, + err: Option<&mut Buffer>, +) -> bool { let roots_slice = match unsafe { roots.read() } { None => { set_error(Error::empty_arg("roots"), err); @@ -230,8 +234,15 @@ pub extern "C" fn submit_store_roots(roots: Buffer, err: Option<&mut Buffer>) -> } Some(r) => r, }; + let compute_root_slice = match unsafe { compute_root.read() } { + None => { + set_error(Error::empty_arg("compute_root"), err); + return false; + } + Some(r) => r, + }; - match cosmwasm_sgx_vm::untrusted_submit_store_roots(roots_slice) { + match cosmwasm_sgx_vm::untrusted_submit_store_roots(roots_slice, compute_root_slice) { Err(e) => { set_error(Error::enclave_err(e.to_string()), err); false From fd689b2e673a7b301a2911cd22258ec825dfd273 Mon Sep 17 00:00:00 2001 From: toml01 Date: Wed, 28 Jun 2023 18:32:07 +0100 Subject: [PATCH 32/51] refactor merkle proofs to be on it's own crate + add a feature flag --- cosmwasm/enclaves/Cargo.lock | 24 +++- cosmwasm/enclaves/Cargo.toml | 3 +- cosmwasm/enclaves/execute/Cargo.toml | 29 +++-- .../enclaves/shared/block-verifier/Cargo.toml | 10 +- .../shared/block-verifier/src/ecalls.rs | 116 +++--------------- .../enclaves/shared/block-verifier/src/lib.rs | 4 - .../shared/contract-engine/Cargo.toml | 14 ++- .../enclaves/shared/contract-engine/src/db.rs | 11 +- .../enclaves/shared/read-verifier/Cargo.toml | 29 +++++ .../shared/read-verifier/src/ecalls.rs | 114 +++++++++++++++++ .../enclaves/shared/read-verifier/src/lib.rs | 14 +++ .../src/read_proofs.rs | 0 go-cosmwasm/api/store.go | 2 +- 13 files changed, 236 insertions(+), 134 deletions(-) create mode 100644 cosmwasm/enclaves/shared/read-verifier/Cargo.toml create mode 100644 cosmwasm/enclaves/shared/read-verifier/src/ecalls.rs create mode 100644 cosmwasm/enclaves/shared/read-verifier/src/lib.rs rename cosmwasm/enclaves/shared/{block-verifier => read-verifier}/src/read_proofs.rs (100%) diff --git a/cosmwasm/enclaves/Cargo.lock b/cosmwasm/enclaves/Cargo.lock index ab4db9e5d..e3cb2e5c2 100644 --- a/cosmwasm/enclaves/Cargo.lock +++ b/cosmwasm/enclaves/Cargo.lock @@ -209,17 +209,14 @@ dependencies = [ name = "block-verifier" version = "0.1.0" dependencies = [ - "cosmos-sdk-proto", "cosmos_proto", "enclave_crypto", "enclave_utils", "hex", - "ics23", - "integer-encoding", "lazy_static", "log", - "prost 0.11.9", "protobuf", + "read-verifier", "sgx_trts", "sgx_tstd", "sgx_types", @@ -653,6 +650,7 @@ dependencies = [ "pwasm-utils", "rand_chacha", "rand_core", + "read-verifier", "secp256k1 0.24.3", "serde 1.0.118", "serde_json 1.0.60", @@ -1394,6 +1392,23 @@ dependencies = [ "sgx_tstd", ] +[[package]] +name = "read-verifier" +version = "0.1.0" +dependencies = [ + "cosmos-sdk-proto", + "enclave_crypto", + "enclave_utils", + "ics23", + "integer-encoding", + "lazy_static", + "log", + "prost 0.11.9", + "sgx_tstd", + "sgx_types", + "tendermint", +] + [[package]] name = "redox_syscall" version = "0.2.16" @@ -1587,6 +1602,7 @@ dependencies = [ "num-bigint", "parity-wasm", "pwasm-utils", + "read-verifier", "rustls", "serde 1.0.118", "serde_json 1.0.60", diff --git a/cosmwasm/enclaves/Cargo.toml b/cosmwasm/enclaves/Cargo.toml index a052880e4..adae5b5ab 100644 --- a/cosmwasm/enclaves/Cargo.toml +++ b/cosmwasm/enclaves/Cargo.toml @@ -11,7 +11,8 @@ members = [ "shared/cosmwasm-types/v1.0", "shared/cosmwasm-types/v0.10", "shared/cosmwasm-types/generic", - "shared/block-verifier" + "shared/block-verifier", + "shared/read-verifier", ] exclude = ["test"] diff --git a/cosmwasm/enclaves/execute/Cargo.toml b/cosmwasm/enclaves/execute/Cargo.toml index 08a939896..077f2af62 100644 --- a/cosmwasm/enclaves/execute/Cargo.toml +++ b/cosmwasm/enclaves/execute/Cargo.toml @@ -21,13 +21,25 @@ production = [ "log/max_level_warn", "log/release_max_level_warn", "block-verifier/production", - "block-verifier/verify-validator-whitelist" + "block-verifier/verify-validator-whitelist", ] debug-print = ["enclave_contract_engine/debug-print"] -test = ["enclave_contract_engine/test", "enclave_crypto/test", "enclave_cosmos_types/test", "block-verifier/test"] +test = [ + "enclave_contract_engine/test", + "enclave_crypto/test", + "enclave_cosmos_types/test", + "block-verifier/test", +] use_seed_service_on_bootstrap = [] epid_whitelist_disabled = [] -light-client-validation = ["enclave_contract_engine/light-client-validation", "block-verifier/light-client-validation"] +light-client-validation = [ + "enclave_contract_engine/light-client-validation", + "block-verifier/light-client-validation", +] +read-db-proofs = [ + "enclave_contract_engine/read-db-proofs", + "block-verifier/read-db-proofs", +] random = ["enclave_contract_engine/random"] verify-validator-whitelist = ["block-verifier/verify-validator-whitelist"] @@ -36,8 +48,8 @@ verify-validator-whitelist = ["block-verifier/verify-validator-whitelist"] # when compiling to the "sgx" target, we pull this from the target root with an "extern crate" directive [target.'cfg(not(target_env = "sgx"))'.dependencies] sgx_tstd = { rev = "d2d339cbb005f676bb700059bd51dc689c025f6b", git = "https://github.com/apache/teaclave-sgx-sdk.git", features = [ - "backtrace", - "untrusted_time" + "backtrace", + "untrusted_time", ] } sgx_types = { rev = "d2d339cbb005f676bb700059bd51dc689c025f6b", git = "https://github.com/apache/teaclave-sgx-sdk.git" } @@ -54,7 +66,7 @@ enclave_utils = { path = "../shared/utils" } enclave_cosmos_types = { path = "../shared/cosmos-types", optional = true } serde = { git = "https://github.com/mesalock-linux/serde-sgx", features = [ - "derive" + "derive", ] } serde_json = { git = "https://github.com/mesalock-linux/serde-json-sgx" } ctor = "0.1.13" @@ -75,9 +87,12 @@ bit-vec = { version = "0.6", default-features = false } lazy_static = "1.4" hex = "0.4.2" log = "0.4.17" -simple_logger = { version = "2.3.0", default-features = false, features = ["stderr"] } +simple_logger = { version = "2.3.0", default-features = false, features = [ + "stderr", +] } block-verifier = { path = "../shared/block-verifier", default-features = false } +read-verifier = { path = "../shared/read-verifier" } time = "=0.3.17" diff --git a/cosmwasm/enclaves/shared/block-verifier/Cargo.toml b/cosmwasm/enclaves/shared/block-verifier/Cargo.toml index 7eaab0738..c14181aae 100644 --- a/cosmwasm/enclaves/shared/block-verifier/Cargo.toml +++ b/cosmwasm/enclaves/shared/block-verifier/Cargo.toml @@ -10,6 +10,7 @@ random = [] light-client-validation = [] production = [] verify-validator-whitelist = [] +read-db-proofs = ["read-verifier"] # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html [target.'cfg(not(target_env = "sgx"))'.dependencies] @@ -19,6 +20,7 @@ sgx_trts = { rev = "d2d339cbb005f676bb700059bd51dc689c025f6b", git = "https://gi sgx_types = { rev = "d2d339cbb005f676bb700059bd51dc689c025f6b", git = "https://github.com/apache/teaclave-sgx-sdk.git" } [dependencies] +read-verifier = { path = "../read-verifier", optional = true } tendermint = { git = "https://github.com/scrtlabs/tendermint-rs", branch = "fix-val-set-parsing", default-features = false } tendermint-proto = { git = "https://github.com/scrtlabs/tendermint-rs", branch = "fix-val-set-parsing", default-features = false } tendermint-light-client-verifier = { git = "https://github.com/scrtlabs/tendermint-rs", branch = "fix-val-set-parsing", default-features = false } @@ -29,11 +31,3 @@ enclave_utils = { path = "../utils" } cosmos_proto = { path = "../cosmos-proto" } protobuf = { version = "2.25.2" } hex = { version = "0.4.3" } -cosmos-sdk-proto = { version = "0.16.0", default-features = false } -integer-encoding = "3.0.4" -ics23 = { version = "0.9.0", default-features = false, features = [ - "host-functions", -] } -prost = { version = "0.11", default-features = false, features = [ - "prost-derive", -] } diff --git a/cosmwasm/enclaves/shared/block-verifier/src/ecalls.rs b/cosmwasm/enclaves/shared/block-verifier/src/ecalls.rs index 0021fb26c..8851e49bd 100644 --- a/cosmwasm/enclaves/shared/block-verifier/src/ecalls.rs +++ b/cosmwasm/enclaves/shared/block-verifier/src/ecalls.rs @@ -1,19 +1,18 @@ -use cosmos_sdk_proto::cosmos::base::kv::v1beta1::{Pair, Pairs}; -use cosmos_sdk_proto::traits::Message; -use enclave_crypto::hash::sha; -use integer_encoding::VarInt; use std::slice; use tendermint::block::Commit; use tendermint::block::Header; -use tendermint::merkle; use tendermint_proto::Protobuf; use sgx_types::sgx_status_t; -use crate::{txs, verify_block, READ_PROOFER}; +use crate::{txs, verify_block}; use log::{debug, error}; use enclave_utils::{validate_const_ptr, validate_mut_ptr}; + +#[cfg(feature = "read-db-proofs")] +use read_verifier::READ_PROOFER; + use tendermint::block::signed_header::SignedHeader; use tendermint::validator::Set; use tendermint::Hash::Sha256; @@ -48,94 +47,6 @@ macro_rules! validate_input_length { }; } -/// # Safety -/// This function reads buffers which must be correctly initialized by the caller, -/// see safety section of slice::[from_raw_parts](https://doc.rust-lang.org/std/slice/fn.from_raw_parts.html#safety) -/// -#[no_mangle] -#[allow(unused_variables)] -pub unsafe extern "C" fn ecall_submit_store_roots( - in_roots: *const u8, - in_roots_len: u32, - in_compute_root: *const u8, - in_compute_root_len: u32, -) -> sgx_status_t { - validate_input_length!(in_roots_len, "roots", MAX_VARIABLE_LENGTH); - validate_const_ptr!( - in_roots, - in_roots_len as usize, - sgx_status_t::SGX_ERROR_INVALID_PARAMETER - ); - validate_input_length!(in_compute_root_len, "roots", MAX_VARIABLE_LENGTH); - validate_const_ptr!( - in_compute_root, - in_compute_root_len as usize, - sgx_status_t::SGX_ERROR_INVALID_PARAMETER - ); - - let store_roots_slice = slice::from_raw_parts(in_roots, in_roots_len as usize); - let compute_root_slice = slice::from_raw_parts(in_compute_root, in_compute_root_len as usize); - - let store_roots: Pairs = Pairs::decode(store_roots_slice).unwrap(); - let mut store_roots_bytes = vec![]; - - // Make sure that the provided AppHash contains the provided compute store root - // The AppHash merkle is built using sha256(root) of every module - let compute_h = sha::sha_256(compute_root_slice); - if !store_roots - .pairs - .as_slice() - .iter() - .any(|p| p.value == compute_h.to_vec()) - { - error!("could not verify compute store root!"); - return sgx_status_t::SGX_ERROR_INVALID_PARAMETER; - }; - - // Encode all key-value pairs to bytes - for root in store_roots.pairs { - debug!("TOMMM key: {:?}", String::from_utf8_lossy(&root.key)); - debug!("TOMMM val: {:?}", root.value); - store_roots_bytes.push(pair_to_bytes(root)); - } - let h = merkle::simple_hash_from_byte_vectors(store_roots_bytes); - - debug!("received app_hash: {:?}", h); - debug!("received compute_root: {:?}", compute_root_slice); - debug!( - "TOMMM hashed compute_root: {:?}", - sha::sha_256(compute_root_slice) - ); - - let mut rp = READ_PROOFER.lock().unwrap(); - rp.app_hash = h; - rp.store_merkle_root = compute_root_slice.to_vec(); - - sgx_status_t::SGX_SUCCESS -} - -// This is a copy of a cosmos-sdk function: https://github.com/scrtlabs/cosmos-sdk/blob/1b9278476b3ac897d8ebb90241008476850bf212/store/internal/maps/maps.go#LL152C1-L152C1 -// Returns key || value, with both the key and value length prefixed. -fn pair_to_bytes(kv: Pair) -> Vec { - // In the worst case: - // * 8 bytes to Uvarint encode the length of the key - // * 8 bytes to Uvarint encode the length of the value - // So preallocate for the worst case, which will in total - // be a maximum of 14 bytes wasted, if len(key)=1, len(value)=1, - // but that's going to rare. - let mut buf = vec![]; - - // Encode the key, prefixed with its length. - buf.extend_from_slice(&(kv.key.len()).encode_var_vec()); - buf.extend_from_slice(&kv.key); - - // Encode the value, prefixing with its length. - buf.extend_from_slice(&(kv.value.len()).encode_var_vec()); - buf.extend_from_slice(&kv.value); - - buf -} - /// # Safety /// This function reads buffers which must be correctly initialized by the caller, /// see safety section of slice::[from_raw_parts](https://doc.rust-lang.org/std/slice/fn.from_raw_parts.html#safety) @@ -330,13 +241,16 @@ pub unsafe extern "C" fn ecall_submit_block_signatures( decrypted_random.copy_from_slice(&*decrypted); } - // AppHash calculation is different for the first block - let rp = READ_PROOFER.lock().unwrap(); - if header.height.value() != 1 && rp.app_hash != header.app_hash.as_bytes() { - error!("error verifying app hash!"); - debug!("calculated app_hash bytes {:?}", rp.app_hash); - debug!("header app_hash bytes {:?}", header.app_hash.as_bytes()); - return sgx_status_t::SGX_ERROR_INVALID_PARAMETER; + #[cfg(feature = "read-db-proofs")] + { + // AppHash calculation is different for the first block + let rp = READ_PROOFER.lock().unwrap(); + if header.height.value() != 1 && rp.app_hash != header.app_hash.as_bytes() { + error!("error verifying app hash!"); + debug!("calculated app_hash bytes {:?}", rp.app_hash); + debug!("header app_hash bytes {:?}", header.app_hash.as_bytes()); + return sgx_status_t::SGX_ERROR_INVALID_PARAMETER; + } } debug!( diff --git a/cosmwasm/enclaves/shared/block-verifier/src/lib.rs b/cosmwasm/enclaves/shared/block-verifier/src/lib.rs index 351dae672..5bda8e744 100644 --- a/cosmwasm/enclaves/shared/block-verifier/src/lib.rs +++ b/cosmwasm/enclaves/shared/block-verifier/src/lib.rs @@ -10,20 +10,16 @@ pub mod ecalls; pub mod validator_whitelist; pub mod wasm_messages; -pub mod read_proofs; mod txs; use lazy_static::lazy_static; use log::debug; -use read_proofs::ReadProofer; -use std::sync::SgxMutex; use tendermint_light_client_verifier::types::UntrustedBlockState; use tendermint_light_client_verifier::{ProdVerifier, Verdict}; pub use wasm_messages::VERIFIED_MESSAGES; lazy_static! { static ref VERIFIER: ProdVerifier = ProdVerifier::default(); - static ref READ_PROOFER: SgxMutex = SgxMutex::new(ReadProofer::default()); } pub fn verify_block(untrusted_block: &UntrustedBlockState) -> bool { diff --git a/cosmwasm/enclaves/shared/contract-engine/Cargo.toml b/cosmwasm/enclaves/shared/contract-engine/Cargo.toml index 03ff030f7..5f18559ac 100644 --- a/cosmwasm/enclaves/shared/contract-engine/Cargo.toml +++ b/cosmwasm/enclaves/shared/contract-engine/Cargo.toml @@ -11,14 +11,19 @@ test = [] wasm3 = [] wasmi-engine = ["wasmi", "parity-wasm", "pwasm-utils"] light-client-validation = ["block-verifier"] -random = ["cw_types_generic/random", "cw_types_v1/random", "cw_types_v010/random"] +read-db-proofs = ["read-verifier"] +random = [ + "cw_types_generic/random", + "cw_types_v1/random", + "cw_types_v010/random", +] # This annotation is here to trick the IDE into showing us type information about this crate. # We always compile to the "sgx" target, so this will always be false. # when compiling to the "sgx" target, we pull this from the target root with an "extern crate" directive [target.'cfg(not(target_env = "sgx"))'.dependencies] sgx_tstd = { path = "../../../../third_party/incubator-teaclave-sgx-sdk/sgx_tstd", features = [ - "backtrace" + "backtrace", ] } sgx_types = { path = "../../../../third_party/incubator-teaclave-sgx-sdk/sgx_types" } @@ -32,7 +37,7 @@ cw_types_v1 = { path = "../cosmwasm-types/v1.0" } cw_types_generic = { path = "../cosmwasm-types/generic" } enclave_utils = { path = "../utils" } serde = { git = "https://github.com/mesalock-linux/serde-sgx", features = [ - "derive" + "derive", ] } serde_json = { git = "https://github.com/mesalock-linux/serde-json-sgx" } base64 = { rev = "dc7389e10817b078f289386b3b6a852ab6c4c021", git = "https://github.com/mesalock-linux/rust-base64-sgx" } @@ -54,7 +59,8 @@ rand_core = "0.5.0" rand_chacha = { version = "0.2.1", default-features = false } bincode2 = { git = "https://github.com/scrtlabs/bincode2-sgx", rev = "bdf9f458eaf41778d64cb812ed8fcad64ffd72a9" } -block-verifier = {path = "../block-verifier", optional = true } +block-verifier = { path = "../block-verifier", optional = true } +read-verifier = { path = "../read-verifier", optional = true } [dependencies.wasmi] git = "https://github.com/paritytech/wasmi" diff --git a/cosmwasm/enclaves/shared/contract-engine/src/db.rs b/cosmwasm/enclaves/shared/contract-engine/src/db.rs index a4221ea4b..a750be576 100644 --- a/cosmwasm/enclaves/shared/contract-engine/src/db.rs +++ b/cosmwasm/enclaves/shared/contract-engine/src/db.rs @@ -1,4 +1,3 @@ -use block_verifier::read_proofs::{comm_proof_from_bytes, verify_read}; use enclave_crypto::consts::{ CONSENSUS_SEED_VERSION, ENCRYPTED_KEY_MAGIC_BYTES, STATE_ENCRYPTION_VERSION, }; @@ -7,6 +6,8 @@ use enclave_crypto::{sha_256, AESKey, Kdf, SIVEncryptable, KEY_MANAGER}; use enclave_ffi_types::{Ctx, EnclaveBuffer, OcallReturn, UntrustedVmError}; use enclave_utils::kv_cache::KvCache; use log::*; +#[cfg(feature = "read-verifier")] +use read_verifier::read_proofs::{comm_proof_from_bytes, verify_read}; use serde::{Deserialize, Serialize}; use sgx_types::sgx_status_t; @@ -364,6 +365,7 @@ fn read_db( } }; + #[cfg(feature = "read-db-proofs")] if let (Some(proof), Some(mp_key)) = (proof, mp_key) { let comm_proof = comm_proof_from_bytes(&proof).map_err(|_| WasmEngineError::HostMisbehavior)?; @@ -371,11 +373,12 @@ fn read_db( error!("could not verify merkle proof"); return Err(WasmEngineError::HostMisbehavior); } - - Ok((value, gas_used)) + debug!("proof verified!"); } else { - Err(WasmEngineError::HostMisbehavior) + return Err(WasmEngineError::HostMisbehavior); } + + Ok((value, gas_used)) } /// Safe wrapper around reads from the contract storage diff --git a/cosmwasm/enclaves/shared/read-verifier/Cargo.toml b/cosmwasm/enclaves/shared/read-verifier/Cargo.toml new file mode 100644 index 000000000..d75b079d4 --- /dev/null +++ b/cosmwasm/enclaves/shared/read-verifier/Cargo.toml @@ -0,0 +1,29 @@ +[package] +name = "read-verifier" +version = "0.1.0" +edition = "2018" + +[features] +default = [] + +# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html + +[target.'cfg(not(target_env = "sgx"))'.dependencies] +sgx_tstd = { rev = "d2d339cbb005f676bb700059bd51dc689c025f6b", git = "https://github.com/apache/teaclave-sgx-sdk.git", features = [ +] } +sgx_types = { rev = "d2d339cbb005f676bb700059bd51dc689c025f6b", git = "https://github.com/apache/teaclave-sgx-sdk.git" } + +[dependencies] +tendermint = { git = "https://github.com/scrtlabs/tendermint-rs", branch = "fix-val-set-parsing", default-features = false } +lazy_static = "1.4.0" +log = "0.4.17" +cosmos-sdk-proto = { version = "0.16.0", default-features = false } +ics23 = { version = "0.9.0", default-features = false, features = [ + "host-functions", +] } +prost = { version = "0.11", default-features = false, features = [ + "prost-derive", +] } +integer-encoding = "3.0.4" +enclave_utils = { path = "../utils" } +enclave_crypto = { path = "../crypto" } diff --git a/cosmwasm/enclaves/shared/read-verifier/src/ecalls.rs b/cosmwasm/enclaves/shared/read-verifier/src/ecalls.rs new file mode 100644 index 000000000..dfafadf96 --- /dev/null +++ b/cosmwasm/enclaves/shared/read-verifier/src/ecalls.rs @@ -0,0 +1,114 @@ +use cosmos_sdk_proto::cosmos::base::kv::v1beta1::{Pair, Pairs}; +use cosmos_sdk_proto::traits::Message; +use enclave_crypto::hash::sha; +use enclave_utils::validate_const_ptr; +use integer_encoding::VarInt; +use log::{debug, error}; +use sgx_types::sgx_status_t; +use std::slice; +use tendermint::merkle; + +use crate::READ_PROOFER; + +const MAX_VARIABLE_LENGTH: u32 = 100_000; + +// TODO this is the same macro as in `block-verifier` - dedup when possible +macro_rules! validate_input_length { + ($input:expr, $var_name:expr, $constant:expr) => { + if $input > $constant { + error!( + "Error: {} ({}) is larger than the constant value ({})", + $var_name, $input, $constant + ); + return sgx_status_t::SGX_ERROR_INVALID_PARAMETER; + } + }; +} + +/// # Safety +/// This function reads buffers which must be correctly initialized by the caller, +/// see safety section of slice::[from_raw_parts](https://doc.rust-lang.org/std/slice/fn.from_raw_parts.html#safety) +/// +#[no_mangle] +#[allow(unused_variables)] +pub unsafe extern "C" fn ecall_submit_store_roots( + in_roots: *const u8, + in_roots_len: u32, + in_compute_root: *const u8, + in_compute_root_len: u32, +) -> sgx_status_t { + validate_input_length!(in_roots_len, "roots", MAX_VARIABLE_LENGTH); + validate_const_ptr!( + in_roots, + in_roots_len as usize, + sgx_status_t::SGX_ERROR_INVALID_PARAMETER + ); + validate_input_length!(in_compute_root_len, "roots", MAX_VARIABLE_LENGTH); + validate_const_ptr!( + in_compute_root, + in_compute_root_len as usize, + sgx_status_t::SGX_ERROR_INVALID_PARAMETER + ); + + let store_roots_slice = slice::from_raw_parts(in_roots, in_roots_len as usize); + let compute_root_slice = slice::from_raw_parts(in_compute_root, in_compute_root_len as usize); + + let store_roots: Pairs = Pairs::decode(store_roots_slice).unwrap(); + let mut store_roots_bytes = vec![]; + + // Make sure that the provided AppHash contains the provided compute store root + // The AppHash merkle is built using sha256(root) of every module + let compute_h = sha::sha_256(compute_root_slice); + if !store_roots + .pairs + .as_slice() + .iter() + .any(|p| p.value == compute_h.to_vec()) + { + error!("could not verify compute store root!"); + return sgx_status_t::SGX_ERROR_INVALID_PARAMETER; + }; + + // Encode all key-value pairs to bytes + for root in store_roots.pairs { + debug!("TOMMM key: {:?}", String::from_utf8_lossy(&root.key)); + debug!("TOMMM val: {:?}", root.value); + store_roots_bytes.push(pair_to_bytes(root)); + } + let h = merkle::simple_hash_from_byte_vectors(store_roots_bytes); + + debug!("received app_hash: {:?}", h); + debug!("received compute_root: {:?}", compute_root_slice); + debug!( + "TOMMM hashed compute_root: {:?}", + sha::sha_256(compute_root_slice) + ); + + let mut rp = READ_PROOFER.lock().unwrap(); + rp.app_hash = h; + rp.store_merkle_root = compute_root_slice.to_vec(); + + sgx_status_t::SGX_SUCCESS +} + +// This is a copy of a cosmos-sdk function: https://github.com/scrtlabs/cosmos-sdk/blob/1b9278476b3ac897d8ebb90241008476850bf212/store/internal/maps/maps.go#LL152C1-L152C1 +// Returns key || value, with both the key and value length prefixed. +fn pair_to_bytes(kv: Pair) -> Vec { + // In the worst case: + // * 8 bytes to Uvarint encode the length of the key + // * 8 bytes to Uvarint encode the length of the value + // So preallocate for the worst case, which will in total + // be a maximum of 14 bytes wasted, if len(key)=1, len(value)=1, + // but that's going to rare. + let mut buf = vec![]; + + // Encode the key, prefixed with its length. + buf.extend_from_slice(&(kv.key.len()).encode_var_vec()); + buf.extend_from_slice(&kv.key); + + // Encode the value, prefixing with its length. + buf.extend_from_slice(&(kv.value.len()).encode_var_vec()); + buf.extend_from_slice(&kv.value); + + buf +} diff --git a/cosmwasm/enclaves/shared/read-verifier/src/lib.rs b/cosmwasm/enclaves/shared/read-verifier/src/lib.rs new file mode 100644 index 000000000..3a91900f0 --- /dev/null +++ b/cosmwasm/enclaves/shared/read-verifier/src/lib.rs @@ -0,0 +1,14 @@ +pub mod ecalls; +pub mod read_proofs; + +#[cfg(not(target_env = "sgx"))] +extern crate sgx_tstd as std; +extern crate sgx_types; + +use crate::read_proofs::ReadProofer; +use lazy_static::lazy_static; +use std::sync::SgxMutex; + +lazy_static! { + pub static ref READ_PROOFER: SgxMutex = SgxMutex::new(ReadProofer::default()); +} diff --git a/cosmwasm/enclaves/shared/block-verifier/src/read_proofs.rs b/cosmwasm/enclaves/shared/read-verifier/src/read_proofs.rs similarity index 100% rename from cosmwasm/enclaves/shared/block-verifier/src/read_proofs.rs rename to cosmwasm/enclaves/shared/read-verifier/src/read_proofs.rs diff --git a/go-cosmwasm/api/store.go b/go-cosmwasm/api/store.go index 36bbb0e06..dda29a2ef 100644 --- a/go-cosmwasm/api/store.go +++ b/go-cosmwasm/api/store.go @@ -39,7 +39,7 @@ func getWithProof(store sdk.KVStore, key []byte, blockHeight int64) (value []byt // result.ProofOps.Ops should always contain only one proof if result.ProofOps == nil { - return nil, nil, nil, fmt.Errorf("error in retrieving key: %+v, got: %s", key, result.Log) + return nil, nil, nil, fmt.Errorf("error in retrieving key: %+v for height: %d, got: %s", key, blockHeight-1, result.Log) } if len(result.ProofOps.Ops) != 1 { return nil, nil, nil, fmt.Errorf("error in retrieving proof for key: %+v, got: %+v", key, result.ProofOps.Ops) From add04bbf4d4db4bbcef9b9bd9b31266502f9939f Mon Sep 17 00:00:00 2001 From: toml01 Date: Sun, 2 Jul 2023 12:14:26 +0100 Subject: [PATCH 33/51] app.go cleanup --- app/app.go | 26 +------------------------- 1 file changed, 1 insertion(+), 25 deletions(-) diff --git a/app/app.go b/app/app.go index be6195530..5c5d2f436 100644 --- a/app/app.go +++ b/app/app.go @@ -1,7 +1,6 @@ package app import ( - "encoding/binary" "fmt" "io" "net/http" @@ -444,7 +443,7 @@ func (app *SecretNetworkApp) BeginBlocker(ctx sdk.Context, req abci.RequestBegin return app.mm.BeginBlock(ctx, req) } -func storesRootsFromMultiStore(rootMulti *rootmulti.Store) kv.Pairs { //[][]byte { +func storesRootsFromMultiStore(rootMulti *rootmulti.Store) kv.Pairs { stores := rootMulti.GetStores() kvs := kv.Pairs{} @@ -463,29 +462,6 @@ func storesRootsFromMultiStore(rootMulti *rootmulti.Store) kv.Pairs { //[][]byte return kvs } -// This is a copy of an internal cosmos-sdk function: https://github.com/scrtlabs/cosmos-sdk/blob/1b9278476b3ac897d8ebb90241008476850bf212/store/internal/maps/maps.go#LL152C1-L152C1 -// pairBytes returns key || value, with both the -// key and value length prefixed. -func pairBytes(kv kv.Pair) []byte { - // In the worst case: - // * 8 bytes to Uvarint encode the length of the key - // * 8 bytes to Uvarint encode the length of the value - // So preallocate for the worst case, which will in total - // be a maximum of 14 bytes wasted, if len(key)=1, len(value)=1, - // but that's going to rare. - buf := make([]byte, 8+len(kv.Key)+8+len(kv.Value)) - - // Encode the key, prefixed with its length. - nlk := binary.PutUvarint(buf, uint64(len(kv.Key))) - nk := copy(buf[nlk:], kv.Key) - - // Encode the value, prefixing with its length. - nlv := binary.PutUvarint(buf[nlk+nk:], uint64(len(kv.Value))) - nv := copy(buf[nlk+nk+nlv:], kv.Value) - - return buf[:nlk+nk+nlv+nv] -} - // EndBlocker application updates every end block func (app *SecretNetworkApp) EndBlocker(ctx sdk.Context, req abci.RequestEndBlock) abci.ResponseEndBlock { return app.mm.EndBlock(ctx, req) From 81596e8700e144803128346a51f3fa0f9e3373a9 Mon Sep 17 00:00:00 2001 From: Itzik Grossman Date: Tue, 25 Jul 2023 22:50:00 +0300 Subject: [PATCH 34/51] Fixed read db tests without feature Added block-long state cache (todo: tests) --- cosmwasm/enclaves/execute/Enclave.edl | 2 +- cosmwasm/enclaves/execute/src/lib.rs | 2 + .../enclaves/execute/src/sdk_entrypoints.rs | 59 +++++++++++++++++++ cosmwasm/enclaves/ffi-types/cbindgen.toml | 1 + cosmwasm/enclaves/ffi-types/src/lib.rs | 3 +- cosmwasm/enclaves/ffi-types/src/types.rs | 10 ++++ .../block-verifier/src/wasm_messages.rs | 10 ++-- .../shared/contract-engine/src/block_cache.rs | 15 +++++ .../src/contract_operations.rs | 2 - .../src/contract_validation.rs | 6 ++ .../enclaves/shared/contract-engine/src/db.rs | 23 +++++--- .../shared/contract-engine/src/lib.rs | 3 + .../shared/contract-engine/src/wasm3/mod.rs | 35 +++++++++-- .../shared/read-verifier/src/ecalls.rs | 44 +------------- cosmwasm/packages/sgx-vm/src/proofs.rs | 47 ++++++--------- go-cosmwasm/Cargo.toml | 1 + go-cosmwasm/api/bindings.h | 1 + go-cosmwasm/api/callbacks.go | 32 ++++++++++ go-cosmwasm/api/callbacks_cgo.go | 5 ++ go-cosmwasm/src/db.rs | 22 +++++++ 20 files changed, 231 insertions(+), 92 deletions(-) create mode 100644 cosmwasm/enclaves/execute/src/sdk_entrypoints.rs create mode 100644 cosmwasm/enclaves/shared/contract-engine/src/block_cache.rs diff --git a/cosmwasm/enclaves/execute/Enclave.edl b/cosmwasm/enclaves/execute/Enclave.edl index 4145ab971..334989944 100644 --- a/cosmwasm/enclaves/execute/Enclave.edl +++ b/cosmwasm/enclaves/execute/Enclave.edl @@ -118,7 +118,7 @@ enclave { // uintptr_t in_next_validator_set_len ); - public sgx_status_t ecall_submit_store_roots( + public SdkBeginBlockerResult ecall_app_begin_blocker( [in, count=in_roots_len] const uint8_t* in_roots, uintptr_t in_roots_len, [in, count=in_compute_root_len] const uint8_t* in_compute_root, diff --git a/cosmwasm/enclaves/execute/src/lib.rs b/cosmwasm/enclaves/execute/src/lib.rs index 9cde4f623..e22549b24 100644 --- a/cosmwasm/enclaves/execute/src/lib.rs +++ b/cosmwasm/enclaves/execute/src/lib.rs @@ -4,6 +4,7 @@ #[cfg(not(target_env = "sgx"))] extern crate sgx_tstd as std; +extern crate core; extern crate sgx_trts; extern crate sgx_types; @@ -15,6 +16,7 @@ pub use block_verifier::ecalls::ecall_submit_block_signatures; // Force linking to all the ecalls/ocalls in this package pub use enclave_contract_engine; pub mod registration; +mod sdk_entrypoints; mod tests; #[cfg(feature = "production")] diff --git a/cosmwasm/enclaves/execute/src/sdk_entrypoints.rs b/cosmwasm/enclaves/execute/src/sdk_entrypoints.rs new file mode 100644 index 000000000..3e87111ea --- /dev/null +++ b/cosmwasm/enclaves/execute/src/sdk_entrypoints.rs @@ -0,0 +1,59 @@ +use core::slice; +pub use enclave_contract_engine::clear_block_cache; +use enclave_ffi_types::SdkBeginBlockerResult; +use enclave_utils::validate_const_ptr; +use read_verifier::ecalls::submit_store_roots; + +use log::error; + +use sgx_types::sgx_status_t; + +const MAX_VARIABLE_LENGTH: u32 = 100_000; + +// TODO this is the same macro as in `block-verifier` - dedup when possible +macro_rules! validate_input_length { + ($input:expr, $var_name:expr, $constant:expr) => { + if $input > $constant { + error!( + "Error: {} ({}) is larger than the constant value ({})", + $var_name, $input, $constant + ); + return SdkBeginBlockerResult::BadVariableLength; + } + }; +} + +#[no_mangle] +pub unsafe extern "C" fn ecall_app_begin_blocker( + in_roots: *const u8, + in_roots_len: u32, + in_compute_root: *const u8, + in_compute_root_len: u32, +) -> SdkBeginBlockerResult { + clear_block_cache(); + + validate_input_length!(in_roots_len, "roots", MAX_VARIABLE_LENGTH); + validate_const_ptr!( + in_roots, + in_roots_len as usize, + SdkBeginBlockerResult::BadVariableLength + ); + validate_input_length!(in_compute_root_len, "compute_roots", MAX_VARIABLE_LENGTH); + validate_const_ptr!( + in_compute_root, + in_compute_root_len as usize, + SdkBeginBlockerResult::BadVariableLength + ); + + let store_roots_slice = slice::from_raw_parts(in_roots, in_roots_len as usize); + let compute_root_slice = slice::from_raw_parts(in_compute_root, in_compute_root_len as usize); + + match submit_store_roots(store_roots_slice, compute_root_slice) { + sgx_status_t::SGX_SUCCESS => SdkBeginBlockerResult::Success, + sgx_status_t::SGX_ERROR_INVALID_PARAMETER => SdkBeginBlockerResult::BadVariable, + _ => SdkBeginBlockerResult::Failure, + } +} + +#[no_mangle] +pub unsafe extern "C" fn end_blocker() {} diff --git a/cosmwasm/enclaves/ffi-types/cbindgen.toml b/cosmwasm/enclaves/ffi-types/cbindgen.toml index 2f13f1c5c..fa01c92f5 100644 --- a/cosmwasm/enclaves/ffi-types/cbindgen.toml +++ b/cosmwasm/enclaves/ffi-types/cbindgen.toml @@ -40,6 +40,7 @@ include = [ "OcallReturn", "HealthCheckResult", "RuntimeConfiguration", + "SdkBeginBlockerResult" ] exclude = [] prefix = "" diff --git a/cosmwasm/enclaves/ffi-types/src/lib.rs b/cosmwasm/enclaves/ffi-types/src/lib.rs index 9c7cd5633..fe887804e 100644 --- a/cosmwasm/enclaves/ffi-types/src/lib.rs +++ b/cosmwasm/enclaves/ffi-types/src/lib.rs @@ -5,7 +5,8 @@ mod types; pub use types::{ Ctx, EnclaveBuffer, EnclaveError, HandleResult, HealthCheckResult, InitResult, NodeAuthResult, - OcallReturn, QueryResult, RuntimeConfiguration, UntrustedVmError, UserSpaceBuffer, + OcallReturn, QueryResult, RuntimeConfiguration, SdkBeginBlockerResult, UntrustedVmError, + UserSpaceBuffer, }; // On input, the encrypted seed is expected to contain 3 values: diff --git a/cosmwasm/enclaves/ffi-types/src/types.rs b/cosmwasm/enclaves/ffi-types/src/types.rs index 602b0dcd6..71202dd6b 100644 --- a/cosmwasm/enclaves/ffi-types/src/types.rs +++ b/cosmwasm/enclaves/ffi-types/src/types.rs @@ -134,6 +134,8 @@ pub enum EnclaveError { FailedUnseal, #[display(fmt = "failed to authenticate secret contract")] FailedContractAuthentication, + #[display(fmt = "failed to save to cache")] + FailedSaveToCache, #[display(fmt = "failed to deserialize data")] FailedToDeserialize, #[display(fmt = "failed to serialize data")] @@ -173,6 +175,14 @@ pub enum EnclaveError { Unknown, } +#[repr(C)] +#[derive(Debug, Display, PartialEq, Eq)] +pub enum SdkBeginBlockerResult { + Success, + Failure, + BadVariableLength, + BadVariable, +} /// This type represents the possible error conditions that can be encountered in the /// enclave while authenticating a new node in the network. /// cbindgen:prefix-with-name diff --git a/cosmwasm/enclaves/shared/block-verifier/src/wasm_messages.rs b/cosmwasm/enclaves/shared/block-verifier/src/wasm_messages.rs index 108dba5d1..c3d115a71 100644 --- a/cosmwasm/enclaves/shared/block-verifier/src/wasm_messages.rs +++ b/cosmwasm/enclaves/shared/block-verifier/src/wasm_messages.rs @@ -3,6 +3,11 @@ use cosmos_proto::tx::tx::Tx; use lazy_static::lazy_static; use std::sync::SgxMutex; + +lazy_static! { + pub static ref VERIFIED_MESSAGES: SgxMutex = + SgxMutex::new(VerifiedWasmMessages::default()); +} // use cosmrs::{tx as cosmtx, Tx}; // use enclave_utils::tx_bytes::TxBytesForHeight; // use log::error; @@ -87,11 +92,6 @@ impl VerifiedWasmMessages { } } -lazy_static! { - pub static ref VERIFIED_MESSAGES: SgxMutex = - SgxMutex::new(VerifiedWasmMessages::default()); -} - #[cfg(feature = "test")] pub mod tests { diff --git a/cosmwasm/enclaves/shared/contract-engine/src/block_cache.rs b/cosmwasm/enclaves/shared/contract-engine/src/block_cache.rs new file mode 100644 index 000000000..8a53a7949 --- /dev/null +++ b/cosmwasm/enclaves/shared/contract-engine/src/block_cache.rs @@ -0,0 +1,15 @@ +use crate::contract_validation::ContractKey; +use alloc::collections::BTreeMap; +use enclave_utils::kv_cache::KvCache; +use std::sync::SgxMutex; + +lazy_static::lazy_static! { + pub static ref BLOCK_CACHE: SgxMutex> = + SgxMutex::new(BTreeMap::default()); +} + +pub fn clear_block_cache() { + let mut cache = BLOCK_CACHE.lock().unwrap(); + + cache.clear(); +} diff --git a/cosmwasm/enclaves/shared/contract-engine/src/contract_operations.rs b/cosmwasm/enclaves/shared/contract-engine/src/contract_operations.rs index b08b67cc8..022b7a15b 100644 --- a/cosmwasm/enclaves/shared/contract-engine/src/contract_operations.rs +++ b/cosmwasm/enclaves/shared/contract-engine/src/contract_operations.rs @@ -163,7 +163,6 @@ pub fn init( // trace!("Time elapsed in engine.init: {:?}", duration); *used_gas = engine.gas_used(); - let output = result?; engine @@ -331,7 +330,6 @@ pub fn handle( let mut output = result?; - // This gets refunded because it will get charged later by the sdk let refund_cache_gas = engine .flush_cache() .map_err(|_| EnclaveError::FailedFunctionCall)?; diff --git a/cosmwasm/enclaves/shared/contract-engine/src/contract_validation.rs b/cosmwasm/enclaves/shared/contract-engine/src/contract_validation.rs index dc01cbcfa..603cf247e 100644 --- a/cosmwasm/enclaves/shared/contract-engine/src/contract_validation.rs +++ b/cosmwasm/enclaves/shared/contract-engine/src/contract_validation.rs @@ -44,6 +44,12 @@ fn is_subslice(larger: &[u8], smaller: &[u8]) -> bool { false } +#[cfg(feature = "light-client-validation")] +pub fn is_last_msg_in_block() -> bool { + let verified_msgs = VERIFIED_MESSAGES.lock().unwrap(); + return verified_msgs.remaining() == 0; +} + #[cfg(feature = "light-client-validation")] pub fn verify_block_info(base_env: &BaseEnv) -> Result<(), EnclaveError> { let verified_msgs = VERIFIED_MESSAGES.lock().unwrap(); diff --git a/cosmwasm/enclaves/shared/contract-engine/src/db.rs b/cosmwasm/enclaves/shared/contract-engine/src/db.rs index a750be576..38022a324 100644 --- a/cosmwasm/enclaves/shared/contract-engine/src/db.rs +++ b/cosmwasm/enclaves/shared/contract-engine/src/db.rs @@ -323,7 +323,7 @@ fn read_db( let mut vm_err = UntrustedVmError::default(); let mut gas_used = 0_u64; - let (value, proof, mp_key) = unsafe { + let (value, proof, mp_key): (Option>, Option>, Option>) = unsafe { let status = ocalls::ocall_read_db( (&mut ocall_return) as *mut _, context.unsafe_clone(), @@ -350,13 +350,20 @@ fn read_db( match ocall_return { OcallReturn::Success => { let value_buffer = value_buffer.assume_init(); - let proof_buffer = proof_buffer.assume_init(); - let mp_key_buffer = mp_key_buffer.assume_init(); - ( - ecalls::recover_buffer(value_buffer)?, - ecalls::recover_buffer(proof_buffer)?, - ecalls::recover_buffer(mp_key_buffer)?, - ) + + #[cfg(feature = "read-db-proofs")] + { + let proof_buffer = proof_buffer.assume_init(); + let mp_key_buffer = mp_key_buffer.assume_init(); + ( + ecalls::recover_buffer(value_buffer)?, + ecalls::recover_buffer(proof_buffer)?, + ecalls::recover_buffer(mp_key_buffer)?, + ) + } + + #[cfg(not(feature = "read-db-proofs"))] + (ecalls::recover_buffer(value_buffer)?, None, None) } OcallReturn::Failure => { return Err(WasmEngineError::FailedOcall(vm_err)); diff --git a/cosmwasm/enclaves/shared/contract-engine/src/lib.rs b/cosmwasm/enclaves/shared/contract-engine/src/lib.rs index 4ebc002ee..e19db4ae3 100644 --- a/cosmwasm/enclaves/shared/contract-engine/src/lib.rs +++ b/cosmwasm/enclaves/shared/contract-engine/src/lib.rs @@ -5,8 +5,10 @@ #[cfg(not(target_env = "sgx"))] extern crate sgx_tstd as std; +extern crate alloc; extern crate sgx_types; +mod block_cache; mod contract_operations; mod contract_validation; mod cosmwasm_config; @@ -24,6 +26,7 @@ mod wasm; #[cfg(feature = "wasm3")] mod wasm3; +pub use block_cache::clear_block_cache; pub use contract_operations::{handle, init, query}; #[cfg(feature = "test")] diff --git a/cosmwasm/enclaves/shared/contract-engine/src/wasm3/mod.rs b/cosmwasm/enclaves/shared/contract-engine/src/wasm3/mod.rs index be289778a..92a965912 100644 --- a/cosmwasm/enclaves/shared/contract-engine/src/wasm3/mod.rs +++ b/cosmwasm/enclaves/shared/contract-engine/src/wasm3/mod.rs @@ -1,3 +1,4 @@ +use alloc::collections::BTreeMap; use std::convert::{TryFrom, TryInto}; use log::*; @@ -24,9 +25,9 @@ use crate::query_chain::encrypt_and_query_chain; use crate::random::MSG_COUNTER; use crate::types::IoNonce; +use crate::block_cache::BLOCK_CACHE; use gas::{get_exhausted_amount, get_remaining_gas, use_gas}; use module_cache::create_module_instance; - mod gas; pub mod module_cache; mod validation; @@ -533,6 +534,16 @@ impl Engine { // todo: optimize to only charge for writes that change chain state let total_gas_to_refund = self.context.kv_cache.drain_gas_tracker(); + debug!("Before saving to cache"); + // store kv cache into the block cache - if we access this key later in the block we will want to + let mut block_cache = BLOCK_CACHE.lock().unwrap(); + block_cache.insert( + self.context.contract_key.clone(), + self.context.kv_cache.clone(), + ); + + debug!("After saving to cache"); + let keys: Vec<(Vec, Vec)> = self .context .kv_cache @@ -798,9 +809,7 @@ fn host_read_db( debug!("db_read reading key {}", show_bytes(&state_key_name)); - let value = context.kv_cache.read(&state_key_name); - - if let Some(unwrapped) = value { + if let Some(unwrapped) = context.kv_cache.read(&state_key_name) { debug!("Got value from cache"); let ptr_to_region_in_wasm_vm = write_to_memory(instance, &unwrapped).map_err(|err| { debug!( @@ -813,6 +822,24 @@ fn host_read_db( return Ok(ptr_to_region_in_wasm_vm as i32); } + let block_cache = BLOCK_CACHE.lock().unwrap(); + + if let Some(kv_cache) = block_cache.get(context.contract_key.as_slice()) { + if let Some(unwrapped) = kv_cache.read(&state_key_name) { + debug!("Got value from cache"); + let ptr_to_region_in_wasm_vm = + write_to_memory(instance, &unwrapped).map_err(|err| { + debug!( + "read_db() error while trying to allocate {} bytes for the value", + unwrapped.len(), + ); + err + })?; + + return Ok(ptr_to_region_in_wasm_vm as i32); + } + } + debug!("Missed value in cache"); let (value, used_gas) = read_from_encrypted_state( &state_key_name, diff --git a/cosmwasm/enclaves/shared/read-verifier/src/ecalls.rs b/cosmwasm/enclaves/shared/read-verifier/src/ecalls.rs index dfafadf96..5a2393540 100644 --- a/cosmwasm/enclaves/shared/read-verifier/src/ecalls.rs +++ b/cosmwasm/enclaves/shared/read-verifier/src/ecalls.rs @@ -10,49 +10,7 @@ use tendermint::merkle; use crate::READ_PROOFER; -const MAX_VARIABLE_LENGTH: u32 = 100_000; - -// TODO this is the same macro as in `block-verifier` - dedup when possible -macro_rules! validate_input_length { - ($input:expr, $var_name:expr, $constant:expr) => { - if $input > $constant { - error!( - "Error: {} ({}) is larger than the constant value ({})", - $var_name, $input, $constant - ); - return sgx_status_t::SGX_ERROR_INVALID_PARAMETER; - } - }; -} - -/// # Safety -/// This function reads buffers which must be correctly initialized by the caller, -/// see safety section of slice::[from_raw_parts](https://doc.rust-lang.org/std/slice/fn.from_raw_parts.html#safety) -/// -#[no_mangle] -#[allow(unused_variables)] -pub unsafe extern "C" fn ecall_submit_store_roots( - in_roots: *const u8, - in_roots_len: u32, - in_compute_root: *const u8, - in_compute_root_len: u32, -) -> sgx_status_t { - validate_input_length!(in_roots_len, "roots", MAX_VARIABLE_LENGTH); - validate_const_ptr!( - in_roots, - in_roots_len as usize, - sgx_status_t::SGX_ERROR_INVALID_PARAMETER - ); - validate_input_length!(in_compute_root_len, "roots", MAX_VARIABLE_LENGTH); - validate_const_ptr!( - in_compute_root, - in_compute_root_len as usize, - sgx_status_t::SGX_ERROR_INVALID_PARAMETER - ); - - let store_roots_slice = slice::from_raw_parts(in_roots, in_roots_len as usize); - let compute_root_slice = slice::from_raw_parts(in_compute_root, in_compute_root_len as usize); - +pub fn submit_store_roots(store_roots_slice: &[u8], compute_root_slice: &[u8]) -> sgx_status_t { let store_roots: Pairs = Pairs::decode(store_roots_slice).unwrap(); let mut store_roots_bytes = vec![]; diff --git a/cosmwasm/packages/sgx-vm/src/proofs.rs b/cosmwasm/packages/sgx-vm/src/proofs.rs index 3a9968cae..b9bb50362 100644 --- a/cosmwasm/packages/sgx-vm/src/proofs.rs +++ b/cosmwasm/packages/sgx-vm/src/proofs.rs @@ -1,13 +1,16 @@ use sgx_types::*; +use enclave_ffi_types::SdkBeginBlockerResult; use log::{debug, error, warn}; use crate::enclave::ENCLAVE_DOORBELL; +const RETRY_LIMIT: i32 = 3; + extern "C" { - pub fn ecall_submit_store_roots( + pub fn ecall_app_begin_blocker( eid: sgx_enclave_id_t, - retval: *mut sgx_status_t, + retval: *mut SdkBeginBlockerResult, in_roots: *const u8, in_roots_len: u32, in_compute_root: *const u8, @@ -18,41 +21,29 @@ extern "C" { pub fn untrusted_submit_store_roots(roots: &[u8], compute_root: &[u8]) -> SgxResult<()> { debug!("Hello from just before - untrusted_submit_store_roots"); - const RETRY_LIMIT: i32 = 3; - - let mut retry_count = 0; - - // this is here so we can - loop { + for _ in 0..RETRY_LIMIT { let (retval, status) = submit_store_roots_impl(roots, compute_root)?; + if status != sgx_status_t::SGX_SUCCESS { return Err(status); - } else if retval != sgx_status_t::SGX_SUCCESS { - if retval == sgx_status_t::SGX_ERROR_FILE_RECOVERY_NEEDED { - warn!( - "Validator set read by enclave was mismatched with current height.. retrying" - ); - // retry with - std::thread::sleep(std::time::Duration::from_millis(500)); - retry_count += 1; - - if retry_count == RETRY_LIMIT { - error!("Validator timed out while waiting for correct validator set"); - return Err(retval); - } - } else { - return Err(retval); - } - } else { + } else if retval == SdkBeginBlockerResult::Success { return Ok(()); + } else if retval == SdkBeginBlockerResult::Failure { + warn!("Validator set read by enclave was mismatched with current height.. retrying"); + std::thread::sleep(std::time::Duration::from_millis(500)); + } else { + return Err(sgx_status_t::SGX_ERROR_UNEXPECTED); } } + + error!("Validator timed out while waiting for correct validator set"); + Err(sgx_status_t::SGX_ERROR_UNEXPECTED) // or any appropriate error } fn submit_store_roots_impl( roots: &[u8], compute_root: &[u8], -) -> SgxResult<(sgx_status_t, sgx_status_t)> { +) -> SgxResult<(SdkBeginBlockerResult, sgx_status_t)> { // Bind the token to a local variable to ensure its // destructor runs in the end of the function let enclave_access_token = ENCLAVE_DOORBELL @@ -61,11 +52,11 @@ fn submit_store_roots_impl( let enclave = (*enclave_access_token)?; let eid = enclave.geteid(); - let mut retval = sgx_status_t::SGX_SUCCESS; + let mut retval = SdkBeginBlockerResult::Success; // let status = unsafe { ecall_get_encrypted_seed(eid, &mut retval, cert, cert_len, & mut seed) }; let status = unsafe { - ecall_submit_store_roots( + ecall_app_begin_blocker( eid, &mut retval, roots.as_ptr(), diff --git a/go-cosmwasm/Cargo.toml b/go-cosmwasm/Cargo.toml index 9c643c26f..2abe4ccb1 100644 --- a/go-cosmwasm/Cargo.toml +++ b/go-cosmwasm/Cargo.toml @@ -39,6 +39,7 @@ query-node = ["cosmwasm-sgx-vm/query-node"] light-client-validation = [] random = [] verify-validator-whitelist = [] +read-db-proofs = [] [dependencies] cosmwasm-std = { package = "secret-cosmwasm-std", features = ["iterator"], version = "0.10.1"} diff --git a/go-cosmwasm/api/bindings.h b/go-cosmwasm/api/bindings.h index 2255277a1..0fba0016b 100644 --- a/go-cosmwasm/api/bindings.h +++ b/go-cosmwasm/api/bindings.h @@ -104,6 +104,7 @@ typedef struct GoIter { } GoIter; typedef struct DB_vtable { + int32_t (*read_db_no_proof)(db_t*, gas_meter_t*, uint64_t*, Buffer, Buffer*, Buffer*); int32_t (*read_db)(db_t*, gas_meter_t*, uint64_t*, uint64_t, Buffer, Buffer*, Buffer*, Buffer*, Buffer*); int32_t (*write_db)(db_t*, gas_meter_t*, uint64_t*, Buffer, Buffer, Buffer*); int32_t (*remove_db)(db_t*, gas_meter_t*, uint64_t*, Buffer, Buffer*); diff --git a/go-cosmwasm/api/callbacks.go b/go-cosmwasm/api/callbacks.go index c09d796d8..091b265fb 100644 --- a/go-cosmwasm/api/callbacks.go +++ b/go-cosmwasm/api/callbacks.go @@ -8,6 +8,7 @@ package api // typedefs for _cgo functions (db) typedef GoResult (*read_db_fn)(db_t *ptr, gas_meter_t *gas_meter, uint64_t *used_gas, uint64_t block_height, Buffer key, Buffer *val, Buffer *merkle_p, Buffer *errOut); +typedef GoResult (*read_db_no_proof_fn)(db_t *ptr, gas_meter_t *gas_meter, uint64_t *used_gas, Buffer key, Buffer *val, Buffer *errOut); typedef GoResult (*write_db_fn)(db_t *ptr, gas_meter_t *gas_meter, uint64_t *used_gas, Buffer key, Buffer val, Buffer *errOut); typedef GoResult (*remove_db_fn)(db_t *ptr, gas_meter_t *gas_meter, uint64_t *used_gas, Buffer key, Buffer *errOut); typedef GoResult (*scan_db_fn)(db_t *ptr, gas_meter_t *gas_meter, uint64_t *used_gas, Buffer start, Buffer end, int32_t order, GoIter *out, Buffer *errOut); @@ -19,6 +20,7 @@ typedef GoResult (*canonicalize_address_fn)(api_t *ptr, Buffer human, Buffer *ca typedef GoResult (*query_external_fn)(querier_t *ptr, uint64_t gas_limit, uint64_t *used_gas, Buffer request, uint32_t query_depth, Buffer *result, Buffer *errOut); // forward declarations (db) +GoResult cGetNoProof_cgo(db_t *ptr, gas_meter_t *gas_meter, uint64_t *used_gas, Buffer key, Buffer *val, Buffer *errOut); GoResult cGet_cgo(db_t *ptr, gas_meter_t *gas_meter, uint64_t *used_gas, uint64_t block_height, Buffer key, Buffer *val, Buffer *merkle_p, Buffer *mp_key, Buffer *errOut); GoResult cSet_cgo(db_t *ptr, gas_meter_t *gas_meter, uint64_t *used_gas, Buffer key, Buffer val, Buffer *errOut); GoResult cDelete_cgo(db_t *ptr, gas_meter_t *gas_meter, uint64_t *used_gas, Buffer key, Buffer *errOut); @@ -91,6 +93,7 @@ type GasMeter interface { var db_vtable = C.DB_vtable{ read_db: (C.read_db_fn)(C.cGet_cgo), + read_db_no_proof: (C.read_db_no_proof_fn)(C.cGetNoProof_cgo), write_db: (C.write_db_fn)(C.cSet_cgo), remove_db: (C.remove_db_fn)(C.cDelete_cgo), scan_db: (C.scan_db_fn)(C.cScan_cgo), @@ -138,6 +141,35 @@ func buildIterator(dbCounter uint64, it dbm.Iterator) C.iterator_t { } } +//export cGetNoProof +func cGetNoProof(ptr *C.db_t, gasMeter *C.gas_meter_t, usedGas *u64, key C.Buffer, val *C.Buffer, _ *C.Buffer) (ret C.GoResult) { + defer recoverPanic(&ret) + if ptr == nil || gasMeter == nil || usedGas == nil || val == nil { + // we received an invalid pointer + return C.GoResult_BadArgument + } + + gm := *(*GasMeter)(unsafe.Pointer(gasMeter)) + kv := *(*sdk.KVStore)(unsafe.Pointer(ptr)) + k := receiveSlice(key) + + gasBefore := gm.GasConsumed() + v := kv.Get(k) + gasAfter := gm.GasConsumed() + *usedGas = (u64)(gasAfter - gasBefore) + + // v will equal nil when the key is missing + // https://github.com/cosmos/cosmos-sdk/blob/1083fa948e347135861f88e07ec76b0314296832/store/types/store.go#L174 + if v != nil { + *val = allocateRust(v) + } + // else: the Buffer on the rust side is initialised as a "null" buffer, + // so if we don't write a non-null address to it, it will understand that + // the key it requested does not exist in the kv store + + return C.GoResult_Ok +} + //export cGet func cGet(ptr *C.db_t, gasMeter *C.gas_meter_t, usedGas *u64, block_height u64, key C.Buffer, val *C.Buffer, merkle_p *C.Buffer, mp_key *C.Buffer, errOut *C.Buffer) (ret C.GoResult) { defer recoverPanic(&ret) diff --git a/go-cosmwasm/api/callbacks_cgo.go b/go-cosmwasm/api/callbacks_cgo.go index b07dd9d34..1eb6bc2a1 100644 --- a/go-cosmwasm/api/callbacks_cgo.go +++ b/go-cosmwasm/api/callbacks_cgo.go @@ -9,6 +9,7 @@ package api // imports (db) GoResult cSet(db_t *ptr, gas_meter_t *gas_meter, uint64_t *used_gas, Buffer key, Buffer val, Buffer *errOut); +GoResult cGetNoProof(db_t *ptr, gas_meter_t *gas_meter, uint64_t *used_gas, Buffer key, Buffer *val, Buffer *errOut); GoResult cGet(db_t *ptr, gas_meter_t *gas_meter, uint64_t *used_gas, uint64_t block_height, Buffer key, Buffer *val, Buffer *merkle_p, Buffer *mp_key, Buffer *errOut); GoResult cDelete(db_t *ptr, gas_meter_t *gas_meter, uint64_t *used_gas, Buffer key, Buffer *errOut); GoResult cScan(db_t *ptr, gas_meter_t *gas_meter, uint64_t *used_gas, Buffer start, Buffer end, int32_t order, GoIter *out, Buffer *errOut); @@ -21,6 +22,10 @@ GoResult cCanonicalAddress(api_t *ptr, Buffer human, Buffer *canon, Buffer *errO GoResult cQueryExternal(querier_t *ptr, uint64_t gas_limit, uint64_t *used_gas, Buffer request, uint32_t query_depth, Buffer *result, Buffer *errOut); // Gateway functions (db) +GoResult cGetNoProof_cgo(db_t *ptr, gas_meter_t *gas_meter, uint64_t *used_gas, Buffer key, Buffer *val, Buffer *errOut) { + return cGetNoProof(ptr, gas_meter, used_gas, key, val, errOut); +} + GoResult cGet_cgo(db_t *ptr, gas_meter_t *gas_meter, uint64_t *used_gas, uint64_t block_height, Buffer key, Buffer *val, Buffer *merkle_p, Buffer *mp_key, Buffer *errOut) { return cGet(ptr, gas_meter, used_gas, block_height, key, val, merkle_p, mp_key, errOut); } diff --git a/go-cosmwasm/src/db.rs b/go-cosmwasm/src/db.rs index 1b6248d1e..c7b66a932 100644 --- a/go-cosmwasm/src/db.rs +++ b/go-cosmwasm/src/db.rs @@ -15,6 +15,14 @@ pub struct db_t { // and then check it when converting to GoResult manually #[repr(C)] pub struct DB_vtable { + pub read_db_no_proof: extern "C" fn( + *mut db_t, + *mut gas_meter_t, + *mut u64, + Buffer, + *mut Buffer, + *mut Buffer, + ) -> i32, pub read_db: extern "C" fn( *mut db_t, *mut gas_meter_t, @@ -63,6 +71,8 @@ impl Storage for DB { let mut mp_key_buf = Buffer::default(); let mut err = Buffer::default(); let mut used_gas = 0_u64; + + #[cfg(feature = "read-db-proofs")] let go_result: GoResult = (self.vtable.read_db)( self.state, self.gas_meter, @@ -75,6 +85,18 @@ impl Storage for DB { &mut err as *mut Buffer, ) .into(); + + #[cfg(not(feature = "read-db-proofs"))] + let go_result: GoResult = (self.vtable.read_db_no_proof)( + self.state, + self.gas_meter, + &mut used_gas as *mut u64, + key_buf, + &mut result_buf as *mut Buffer, + &mut err as *mut Buffer, + ) + .into(); + let gas_info = GasInfo::with_externally_used(used_gas); let _key = unsafe { key_buf.consume() }; From 77480d08f9e43ab32356fc1153f4320665e97666 Mon Sep 17 00:00:00 2001 From: Itzik Grossman Date: Wed, 26 Jul 2023 17:55:57 +0300 Subject: [PATCH 35/51] Add merging of multiple kv-caches for the same contract --- .../shared/contract-engine/src/block_cache.rs | 34 +++++++++++++++++-- .../shared/contract-engine/src/wasm3/mod.rs | 2 +- .../enclaves/shared/utils/src/kv_cache.rs | 14 ++++++++ 3 files changed, 47 insertions(+), 3 deletions(-) diff --git a/cosmwasm/enclaves/shared/contract-engine/src/block_cache.rs b/cosmwasm/enclaves/shared/contract-engine/src/block_cache.rs index 8a53a7949..5683532a1 100644 --- a/cosmwasm/enclaves/shared/contract-engine/src/block_cache.rs +++ b/cosmwasm/enclaves/shared/contract-engine/src/block_cache.rs @@ -1,11 +1,41 @@ use crate::contract_validation::ContractKey; +use alloc::collections::btree_map::Entry; use alloc::collections::BTreeMap; use enclave_utils::kv_cache::KvCache; use std::sync::SgxMutex; lazy_static::lazy_static! { - pub static ref BLOCK_CACHE: SgxMutex> = - SgxMutex::new(BTreeMap::default()); + pub static ref BLOCK_CACHE: SgxMutex = + SgxMutex::new(CacheMap::default()); +} + +#[derive(Default)] +pub struct CacheMap(pub BTreeMap); + +impl CacheMap { + pub fn insert(&mut self, key: ContractKey, kv_cache: KvCache) { + match self.0.entry(key) { + Entry::Occupied(mut entry) => { + // If the key is already present in the map, merge the old and new KvCache + entry.get_mut().merge(kv_cache); + } + Entry::Vacant(entry) => { + // If the key is not present in the map, insert the new KvCache + entry.insert(kv_cache); + } + } + } + pub fn get(&self, key: &ContractKey) -> Option<&KvCache> { + self.0.get(key) + } + + pub fn get_or_insert(&mut self, key: ContractKey) -> &mut KvCache { + self.0.entry(key).or_insert_with(KvCache::new) + } + + pub fn clear(&mut self) { + self.0.clear(); + } } pub fn clear_block_cache() { diff --git a/cosmwasm/enclaves/shared/contract-engine/src/wasm3/mod.rs b/cosmwasm/enclaves/shared/contract-engine/src/wasm3/mod.rs index 92a965912..030f40448 100644 --- a/cosmwasm/enclaves/shared/contract-engine/src/wasm3/mod.rs +++ b/cosmwasm/enclaves/shared/contract-engine/src/wasm3/mod.rs @@ -824,7 +824,7 @@ fn host_read_db( let block_cache = BLOCK_CACHE.lock().unwrap(); - if let Some(kv_cache) = block_cache.get(context.contract_key.as_slice()) { + if let Some(kv_cache) = block_cache.get(&context.contract_key) { if let Some(unwrapped) = kv_cache.read(&state_key_name) { debug!("Got value from cache"); let ptr_to_region_in_wasm_vm = diff --git a/cosmwasm/enclaves/shared/utils/src/kv_cache.rs b/cosmwasm/enclaves/shared/utils/src/kv_cache.rs index 480962870..76a6e9497 100644 --- a/cosmwasm/enclaves/shared/utils/src/kv_cache.rs +++ b/cosmwasm/enclaves/shared/utils/src/kv_cache.rs @@ -56,4 +56,18 @@ impl KvCache { items } + + pub fn merge(&mut self, other: KvCache) { + for (key, value) in other.writeable_cache { + self.write(&key, &value); + } + + for (key, value) in other.readable_cache { + self.store_in_ro_cache(&key, &value); + } + + // merging gas_tracker could be simply taking the maximum of two or summing them up + // I am assuming summing here, please adjust it according to your needs + self.gas_tracker += other.gas_tracker; + } } From da2c772355b903217483eb6d12033842ebb77d31 Mon Sep 17 00:00:00 2001 From: Itzik Grossman Date: Wed, 26 Jul 2023 18:19:49 +0300 Subject: [PATCH 36/51] Add merging of multiple kv-caches for the same contract --- .../shared/contract-engine/src/block_cache.rs | 117 ++++++++++++++++++ .../shared/contract-engine/src/lib.rs | 4 + 2 files changed, 121 insertions(+) diff --git a/cosmwasm/enclaves/shared/contract-engine/src/block_cache.rs b/cosmwasm/enclaves/shared/contract-engine/src/block_cache.rs index 5683532a1..feafe0fcd 100644 --- a/cosmwasm/enclaves/shared/contract-engine/src/block_cache.rs +++ b/cosmwasm/enclaves/shared/contract-engine/src/block_cache.rs @@ -43,3 +43,120 @@ pub fn clear_block_cache() { cache.clear(); } + +#[cfg(feature = "test")] +pub mod tests { + use crate::block_cache::CacheMap; + use crate::contract_validation::ContractKey; + use enclave_utils::kv_cache::KvCache; + + pub fn test_insert_into_cachemap() { + let mut cm = CacheMap::default(); + let mut kv_cache = KvCache::new(); + + let key0: ContractKey = [0u8; 64]; + + kv_cache.store_in_ro_cache(b"a", b"b"); + kv_cache.store_in_ro_cache(b"x", b"y"); + + cm.insert(key0, kv_cache); + + let kv2 = cm.get(&key0); + + assert!(kv2.is_some()); + + let value = kv2.unwrap().read(b"a"); + + assert!(value.is_some()); + + assert_eq!(value.unwrap().as_slice(), b"b"); + } + + pub fn test_clear_cachemap() { + let mut cm = CacheMap::default(); + let mut kv_cache = KvCache::new(); + + let key0: ContractKey = [0u8; 64]; + + kv_cache.store_in_ro_cache(b"a", b"b"); + kv_cache.store_in_ro_cache(b"x", b"y"); + + cm.insert(key0, kv_cache); + + let kv2 = cm.get(&key0); + + assert!(kv2.is_some()); + + let value = kv2.unwrap().read(b"a"); + + assert!(value.is_some()); + + assert_eq!(value.unwrap().as_slice(), b"b"); + + cm.clear(); + + let kv2 = cm.get(&key0); + + assert!(kv2.is_none()) + } + + pub fn test_merge_into_cachemap() { + let mut cm = CacheMap::default(); + let mut kv_cache = KvCache::new(); + let mut kv_cache2 = KvCache::new(); + + let key0: ContractKey = [0u8; 64]; + + kv_cache.write(b"test", b"this"); + kv_cache.write(b"toast", b"bread"); + kv_cache.store_in_ro_cache(b"a", b"b"); + kv_cache.store_in_ro_cache(b"1", b"2"); + kv_cache2.write(b"test", b"other"); + kv_cache2.write(b"food", b"pizza"); + kv_cache2.store_in_ro_cache(b"a", b"c"); + kv_cache2.store_in_ro_cache(b"xy", b"zw"); + + cm.insert(key0.clone(), kv_cache); + cm.insert(key0, kv_cache2); + + let kv2 = cm.get(&key0); + + assert!(kv2.is_some()); + + let value = kv2.unwrap().read(b"a"); + + assert!(value.is_some()); + + assert_eq!(value.unwrap().as_slice(), b"c"); + + let value = kv2.unwrap().read(b"1"); + + assert!(value.is_some()); + + assert_eq!(value.unwrap().as_slice(), b"2"); + + let value = kv2.unwrap().read(b"xy"); + + assert!(value.is_some()); + + assert_eq!(value.unwrap().as_slice(), b"zw"); + + let value = kv2.unwrap().read(b"test"); + + assert!(value.is_some()); + + assert_eq!(value.unwrap().as_slice(), b"other"); + + let value = kv2.unwrap().read(b"food"); + + assert!(value.is_some()); + + assert_eq!(value.unwrap().as_slice(), b"pizza"); + + let value = kv2.unwrap().read(b"toast"); + + assert!(value.is_some()); + + assert_eq!(value.unwrap().as_slice(), b"bread"); + } +} diff --git a/cosmwasm/enclaves/shared/contract-engine/src/lib.rs b/cosmwasm/enclaves/shared/contract-engine/src/lib.rs index e19db4ae3..f5ff47a20 100644 --- a/cosmwasm/enclaves/shared/contract-engine/src/lib.rs +++ b/cosmwasm/enclaves/shared/contract-engine/src/lib.rs @@ -31,6 +31,7 @@ pub use contract_operations::{handle, init, query}; #[cfg(feature = "test")] pub mod tests { + use crate::block_cache; use crate::types; /// Catch failures like the standard test runner, and print similar information per test. @@ -57,6 +58,9 @@ pub mod tests { count_failures!(failures, { types::tests::test_new_from_slice(); + block_cache::tests::test_insert_into_cachemap(); + block_cache::tests::test_merge_into_cachemap(); + block_cache::tests::test_clear_cachemap(); }); if failures != 0 { From 45f9911431b90f2e60bb4418ad94760bc6d09325 Mon Sep 17 00:00:00 2001 From: Itzik Grossman Date: Wed, 26 Jul 2023 18:27:53 +0300 Subject: [PATCH 37/51] fixed clippy warnings --- cosmwasm/enclaves/shared/block-verifier/src/ecalls.rs | 11 ++++++++--- .../shared/contract-engine/src/block_cache.rs | 1 + cosmwasm/enclaves/shared/contract-engine/src/db.rs | 1 + .../enclaves/shared/contract-engine/src/wasm3/mod.rs | 6 +----- cosmwasm/enclaves/shared/read-verifier/src/ecalls.rs | 2 -- 5 files changed, 11 insertions(+), 10 deletions(-) diff --git a/cosmwasm/enclaves/shared/block-verifier/src/ecalls.rs b/cosmwasm/enclaves/shared/block-verifier/src/ecalls.rs index 8851e49bd..57ded8698 100644 --- a/cosmwasm/enclaves/shared/block-verifier/src/ecalls.rs +++ b/cosmwasm/enclaves/shared/block-verifier/src/ecalls.rs @@ -166,7 +166,7 @@ pub unsafe extern "C" fn ecall_submit_block_signatures( #[cfg(feature = "random")] let validator_hash = validator_set.hash(); - let signed_header = SignedHeader::new(header.clone(), commit).unwrap(); + let signed_header = SignedHeader::new(header, commit).unwrap(); let untrusted_block = tendermint_light_client_verifier::types::UntrustedBlockState { signed_header: &signed_header, validators: &validator_set, @@ -245,10 +245,15 @@ pub unsafe extern "C" fn ecall_submit_block_signatures( { // AppHash calculation is different for the first block let rp = READ_PROOFER.lock().unwrap(); - if header.height.value() != 1 && rp.app_hash != header.app_hash.as_bytes() { + if signed_header.header.height.value() != 1 + && rp.app_hash != signed_header.header.app_hash.as_bytes() + { error!("error verifying app hash!"); debug!("calculated app_hash bytes {:?}", rp.app_hash); - debug!("header app_hash bytes {:?}", header.app_hash.as_bytes()); + debug!( + "header app_hash bytes {:?}", + signed_header.header.app_hash.as_bytes() + ); return sgx_status_t::SGX_ERROR_INVALID_PARAMETER; } } diff --git a/cosmwasm/enclaves/shared/contract-engine/src/block_cache.rs b/cosmwasm/enclaves/shared/contract-engine/src/block_cache.rs index feafe0fcd..7512cf87b 100644 --- a/cosmwasm/enclaves/shared/contract-engine/src/block_cache.rs +++ b/cosmwasm/enclaves/shared/contract-engine/src/block_cache.rs @@ -29,6 +29,7 @@ impl CacheMap { self.0.get(key) } + #[allow(dead_code)] pub fn get_or_insert(&mut self, key: ContractKey) -> &mut KvCache { self.0.entry(key).or_insert_with(KvCache::new) } diff --git a/cosmwasm/enclaves/shared/contract-engine/src/db.rs b/cosmwasm/enclaves/shared/contract-engine/src/db.rs index 38022a324..53c992f8a 100644 --- a/cosmwasm/enclaves/shared/contract-engine/src/db.rs +++ b/cosmwasm/enclaves/shared/contract-engine/src/db.rs @@ -323,6 +323,7 @@ fn read_db( let mut vm_err = UntrustedVmError::default(); let mut gas_used = 0_u64; + #[allow(unused_variables)] let (value, proof, mp_key): (Option>, Option>, Option>) = unsafe { let status = ocalls::ocall_read_db( (&mut ocall_return) as *mut _, diff --git a/cosmwasm/enclaves/shared/contract-engine/src/wasm3/mod.rs b/cosmwasm/enclaves/shared/contract-engine/src/wasm3/mod.rs index 030f40448..0e9b70991 100644 --- a/cosmwasm/enclaves/shared/contract-engine/src/wasm3/mod.rs +++ b/cosmwasm/enclaves/shared/contract-engine/src/wasm3/mod.rs @@ -1,4 +1,3 @@ -use alloc::collections::BTreeMap; use std::convert::{TryFrom, TryInto}; use log::*; @@ -537,10 +536,7 @@ impl Engine { debug!("Before saving to cache"); // store kv cache into the block cache - if we access this key later in the block we will want to let mut block_cache = BLOCK_CACHE.lock().unwrap(); - block_cache.insert( - self.context.contract_key.clone(), - self.context.kv_cache.clone(), - ); + block_cache.insert(self.context.contract_key, self.context.kv_cache.clone()); debug!("After saving to cache"); diff --git a/cosmwasm/enclaves/shared/read-verifier/src/ecalls.rs b/cosmwasm/enclaves/shared/read-verifier/src/ecalls.rs index 5a2393540..d78efc347 100644 --- a/cosmwasm/enclaves/shared/read-verifier/src/ecalls.rs +++ b/cosmwasm/enclaves/shared/read-verifier/src/ecalls.rs @@ -1,11 +1,9 @@ use cosmos_sdk_proto::cosmos::base::kv::v1beta1::{Pair, Pairs}; use cosmos_sdk_proto::traits::Message; use enclave_crypto::hash::sha; -use enclave_utils::validate_const_ptr; use integer_encoding::VarInt; use log::{debug, error}; use sgx_types::sgx_status_t; -use std::slice; use tendermint::merkle; use crate::READ_PROOFER; From b0849cd49b3e8aa659aeb5a20f4c915ff7cd401d Mon Sep 17 00:00:00 2001 From: Itzik Grossman Date: Wed, 26 Jul 2023 19:09:14 +0300 Subject: [PATCH 38/51] Fixed tests (remove from cache missing in remove_db because the branch isn't updated ) --- cosmwasm/enclaves/shared/contract-engine/src/block_cache.rs | 6 ++++++ cosmwasm/enclaves/shared/contract-engine/src/wasm3/mod.rs | 6 ++++++ cosmwasm/enclaves/shared/utils/src/kv_cache.rs | 5 +++++ 3 files changed, 17 insertions(+) diff --git a/cosmwasm/enclaves/shared/contract-engine/src/block_cache.rs b/cosmwasm/enclaves/shared/contract-engine/src/block_cache.rs index 7512cf87b..4511a3cbf 100644 --- a/cosmwasm/enclaves/shared/contract-engine/src/block_cache.rs +++ b/cosmwasm/enclaves/shared/contract-engine/src/block_cache.rs @@ -29,6 +29,12 @@ impl CacheMap { self.0.get(key) } + pub fn remove_from_kv_cache(&mut self, contract_key: &ContractKey, key: &[u8]) { + if let Some(kv_cache) = self.0.get_mut(contract_key) { + kv_cache.remove(key); + } + } + #[allow(dead_code)] pub fn get_or_insert(&mut self, key: ContractKey) -> &mut KvCache { self.0.entry(key).or_insert_with(KvCache::new) diff --git a/cosmwasm/enclaves/shared/contract-engine/src/wasm3/mod.rs b/cosmwasm/enclaves/shared/contract-engine/src/wasm3/mod.rs index 0e9b70991..53170cc5a 100644 --- a/cosmwasm/enclaves/shared/contract-engine/src/wasm3/mod.rs +++ b/cosmwasm/enclaves/shared/contract-engine/src/wasm3/mod.rs @@ -885,6 +885,12 @@ fn host_remove_db( debug!("db_remove removing key {}", show_bytes(&state_key_name)); + // Also remove the key from the cache to avoid rewriting it + context.kv_cache.remove(&state_key_name); + + let mut block_cache = BLOCK_CACHE.lock().unwrap(); + block_cache.remove_from_kv_cache(&context.contract_key, &state_key_name); + let used_gas = remove_from_encrypted_state(&state_key_name, &context.context, &context.contract_key)?; context.use_gas_externally(used_gas); diff --git a/cosmwasm/enclaves/shared/utils/src/kv_cache.rs b/cosmwasm/enclaves/shared/utils/src/kv_cache.rs index 76a6e9497..47db78c1a 100644 --- a/cosmwasm/enclaves/shared/utils/src/kv_cache.rs +++ b/cosmwasm/enclaves/shared/utils/src/kv_cache.rs @@ -42,6 +42,11 @@ impl KvCache { } } + pub fn remove(&mut self, key: &[u8]) { + self.writeable_cache.remove(key); + self.readable_cache.remove(key); + } + pub fn drain_gas_tracker(&mut self) -> u64 { let gas_used = self.gas_tracker; self.gas_tracker = 0; From 855b0b66dc7b342e557036cfa313ad43065890bf Mon Sep 17 00:00:00 2001 From: Itzik Grossman Date: Wed, 26 Jul 2023 19:36:38 +0300 Subject: [PATCH 39/51] Merged proofs branch with master (does it work?) --- app/app.go | 4 +- cosmwasm/enclaves/Cargo.lock | 83 ++++++++++++++++++- cosmwasm/enclaves/execute/src/ecalls.rs | 2 + .../src/submit_block_signatures.rs | 15 ++++ cosmwasm/packages/sgx-vm/src/lib.rs | 3 - go-cosmwasm/Cargo.lock | 76 +++++++++-------- go-cosmwasm/lib.go | 1 + go.mod | 2 +- go.sum | 4 +- 9 files changed, 144 insertions(+), 46 deletions(-) diff --git a/app/app.go b/app/app.go index 3edc0ebab..2341754d4 100644 --- a/app/app.go +++ b/app/app.go @@ -9,11 +9,9 @@ import ( "sort" ibcfeetypes "github.com/cosmos/ibc-go/v4/modules/apps/29-fee/types" + gocosmwasm "github.com/scrtlabs/SecretNetwork/go-cosmwasm/api" ibcswitchtypes "github.com/scrtlabs/SecretNetwork/x/emergencybutton/types" packetforwardtypes "github.com/strangelove-ventures/packet-forward-middleware/v4/router/types" - "github.com/scrtlabs/SecretNetwork/app/keepers" - gocosmwasm "github.com/scrtlabs/SecretNetwork/go-cosmwasm/api" - icaauth "github.com/scrtlabs/SecretNetwork/x/mauth" "github.com/cosmos/cosmos-sdk/baseapp" "github.com/cosmos/cosmos-sdk/client" diff --git a/cosmwasm/enclaves/Cargo.lock b/cosmwasm/enclaves/Cargo.lock index 8f78001e5..3dfc55ca0 100644 --- a/cosmwasm/enclaves/Cargo.lock +++ b/cosmwasm/enclaves/Cargo.lock @@ -223,12 +223,13 @@ dependencies = [ "lazy_static", "log", "protobuf", + "read-verifier", "sgx_trts", "sgx_tstd", "sgx_types", "tendermint", "tendermint-light-client-verifier", - "tendermint-proto", + "tendermint-proto 0.28.0", ] [[package]] @@ -365,6 +366,17 @@ version = "0.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "6245d59a3e82a7fc217c5828a6692dbc6dfb63a0c8c90495621f7b9d79704a0e" +[[package]] +name = "cosmos-sdk-proto" +version = "0.16.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c4776e787b24d9568dd61d3237eeb4eb321d622fb881b858c7b82806420e87d4" +dependencies = [ + "prost 0.11.6", + "prost-types", + "tendermint-proto 0.27.0", +] + [[package]] name = "cosmos_proto" version = "1.6.0" @@ -645,6 +657,7 @@ dependencies = [ "pwasm-utils", "rand_chacha", "rand_core", + "read-verifier", "secp256k1 0.24.2", "serde 1.0.118", "serde_json 1.0.60", @@ -899,6 +912,21 @@ version = "2.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9a3a5bfb195931eeb336b2a7b4d761daec841b97f947d34394601737a7bba5e4" +[[package]] +name = "ics23" +version = "0.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ca44b684ce1859cff746ff46f5765ab72e12e3c06f76a8356db8f9a2ecf43f17" +dependencies = [ + "anyhow 1.0.66", + "bytes 1.4.0", + "hex", + "prost 0.11.6", + "ripemd", + "sha2 0.10.6", + "sha3", +] + [[package]] name = "id-arena" version = "2.2.1" @@ -924,6 +952,12 @@ dependencies = [ "cfg-if 1.0.0", ] +[[package]] +name = "integer-encoding" +version = "3.0.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8bb03732005da905c88227371639bf1ad885cc712789c011c31c5fb3ab3ccf02" + [[package]] name = "itertools" version = "0.8.2" @@ -1323,6 +1357,23 @@ dependencies = [ "sgx_tstd", ] +[[package]] +name = "read-verifier" +version = "0.1.0" +dependencies = [ + "cosmos-sdk-proto", + "enclave_crypto", + "enclave_utils", + "ics23", + "integer-encoding", + "lazy_static", + "log", + "prost 0.11.6", + "sgx_tstd", + "sgx_types", + "tendermint", +] + [[package]] name = "redox_syscall" version = "0.2.16" @@ -1380,6 +1431,15 @@ dependencies = [ "untrusted", ] +[[package]] +name = "ripemd" +version = "0.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bd124222d17ad93a644ed9d011a40f4fb64aa54275c08cc216524a9ea82fb09f" +dependencies = [ + "digest 0.10.6", +] + [[package]] name = "ripemd160" version = "0.9.1" @@ -1493,6 +1553,7 @@ dependencies = [ "num-bigint", "parity-wasm", "pwasm-utils", + "read-verifier", "rustls", "serde 1.0.118", "serde_json 1.0.60", @@ -1870,7 +1931,7 @@ dependencies = [ "signature", "subtle", "subtle-encoding", - "tendermint-proto", + "tendermint-proto 0.28.0", "time", "zeroize", ] @@ -1887,6 +1948,24 @@ dependencies = [ "time", ] +[[package]] +name = "tendermint-proto" +version = "0.27.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d5895470f28c530f8ae8c4071bf8190304ce00bd131d25e81730453124a3375c" +dependencies = [ + "bytes 1.4.0", + "flex-error", + "num-derive", + "num-traits 0.2.15", + "prost 0.11.6", + "prost-types", + "serde 1.0.147", + "serde_bytes", + "subtle-encoding", + "time", +] + [[package]] name = "tendermint-proto" version = "0.28.0" diff --git a/cosmwasm/enclaves/execute/src/ecalls.rs b/cosmwasm/enclaves/execute/src/ecalls.rs index 40db781d6..cf2d3cb54 100644 --- a/cosmwasm/enclaves/execute/src/ecalls.rs +++ b/cosmwasm/enclaves/execute/src/ecalls.rs @@ -1,5 +1,7 @@ use sgx_types::sgx_status_t; +pub use read_verifier::ecalls::ecall_submit_store_roots; + /// # Safety /// This function reads buffers which must be correctly initialized by the caller, /// see safety section of slice::[from_raw_parts](https://doc.rust-lang.org/std/slice/fn.from_raw_parts.html#safety) diff --git a/cosmwasm/enclaves/shared/block-verifier/src/submit_block_signatures.rs b/cosmwasm/enclaves/shared/block-verifier/src/submit_block_signatures.rs index a2a9d6373..a50f8402f 100644 --- a/cosmwasm/enclaves/shared/block-verifier/src/submit_block_signatures.rs +++ b/cosmwasm/enclaves/shared/block-verifier/src/submit_block_signatures.rs @@ -1,5 +1,8 @@ use std::slice; +#[cfg(feature = "read-db-proofs")] +use read_verifier::READ_PROOFER; + use tendermint_proto::Protobuf; use sgx_types::sgx_status_t; @@ -143,6 +146,18 @@ pub unsafe fn submit_block_signatures_impl( decrypted_random.copy_from_slice(&decrypted); } + #[cfg(feature = "read-db-proofs")] + { + // AppHash calculation is different for the first block + let rp = READ_PROOFER.lock().unwrap(); + if header.header.height.value() != 1 && rp.app_hash != header.header.app_hash.as_bytes() { + error!("error verifying app hash!"); + debug!("calculated app_hash bytes {:?}", rp.app_hash); + debug!("header app_hash bytes {:?}", header.app_hash.as_bytes()); + return sgx_status_t::SGX_ERROR_INVALID_PARAMETER; + } + } + debug!( "Done verifying block height: {:?}", header.header.height.value() diff --git a/cosmwasm/packages/sgx-vm/src/lib.rs b/cosmwasm/packages/sgx-vm/src/lib.rs index 06a259f24..daddde525 100644 --- a/cosmwasm/packages/sgx-vm/src/lib.rs +++ b/cosmwasm/packages/sgx-vm/src/lib.rs @@ -46,9 +46,6 @@ pub use crate::traits::StorageIterator; pub use crate::attestation::{ create_attestation_report_u, untrusted_get_encrypted_genesis_seed, untrusted_get_encrypted_seed, }; -pub use crate::seed::{ - untrusted_health_check, untrusted_init_bootstrap, untrusted_init_node, untrusted_key_gen, -}; pub use crate::proofs::untrusted_submit_store_roots; pub use crate::random::untrusted_submit_block_signatures; diff --git a/go-cosmwasm/Cargo.lock b/go-cosmwasm/Cargo.lock index 2650f0cb0..9c5ec4a3b 100644 --- a/go-cosmwasm/Cargo.lock +++ b/go-cosmwasm/Cargo.lock @@ -32,7 +32,7 @@ version = "0.2.14" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d9b39be18770d11421cdb1b9947a45dd3f37e93092cbf377614828a319d5fee8" dependencies = [ - "hermit-abi", + "hermit-abi 0.1.15", "libc", "winapi", ] @@ -71,9 +71,9 @@ checksum = "cf1de2fe8c75bc145a2f577add951f8134889b4795d47466a54a5c846d691693" [[package]] name = "block-buffer" -version = "0.9.0" +version = "0.10.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4152116fd6e9dadb291ae18fc1ec3575ed6d84c29642d97890f4b4a3417297e4" +checksum = "3078c7629b62d3f0439517fa394996acacc5cbc91c5a20d8c658e77abd503a71" dependencies = [ "generic-array", ] @@ -171,6 +171,16 @@ dependencies = [ "libc", ] +[[package]] +name = "crypto-common" +version = "0.1.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1bfb12502f3fc46cca1bb51ac28df9d618d813cdc3d2f25b9fe775a34af26bb3" +dependencies = [ + "generic-array", + "typenum", +] + [[package]] name = "ctor" version = "0.1.15" @@ -194,11 +204,12 @@ dependencies = [ [[package]] name = "digest" -version = "0.9.0" +version = "0.10.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d3dd60d1080a57a05ab032377049e0591415d2b31afd7028356dbf3cc6dcb066" +checksum = "9ed9a281f7bc9b7576e61468ba615a66a5c8cfdff42420a70aa82701a3b1e292" dependencies = [ - "generic-array", + "block-buffer", + "crypto-common", ] [[package]] @@ -306,6 +317,12 @@ dependencies = [ "libc", ] +[[package]] +name = "hermit-abi" +version = "0.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "443144c8cdadd93ebf52ddb4056d257f5b52c04d3c804e657d19eb73fc33668b" + [[package]] name = "hex" version = "0.4.3" @@ -350,12 +367,9 @@ dependencies = [ [[package]] name = "log" -version = "0.4.17" +version = "0.4.19" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "abb12e687cfb44aa40f41fc3978ef76448f9b6038cad6aef4259d3c095a2382e" -dependencies = [ - "cfg-if 1.0.0", -] +checksum = "b06a4cde4c0f271a446782e3eff8de789548ce57dbc8eca9292c27f4a42004b4" [[package]] name = "memmap" @@ -378,11 +392,11 @@ dependencies = [ [[package]] name = "num_cpus" -version = "1.14.0" +version = "1.16.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f6058e64324c71e02bc2b150e4f3bc8286db6c83092132ffa3f6b1eab0f9def5" +checksum = "4161fcb6d602d4d2081af7c3a45852d875a03dd337a6bfdd6e06407b61342a43" dependencies = [ - "hermit-abi", + "hermit-abi 0.3.2", "libc", ] @@ -392,12 +406,6 @@ version = "0.20.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1ab52be62400ca80aa00285d25253d7f7c437b7375c4de678f5405d3afe82ca5" -[[package]] -name = "opaque-debug" -version = "0.3.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "624a8340c38c1b80fd549087862da4ba43e08858af025b236e509b6649fc13d5" - [[package]] name = "parity-wasm" version = "0.41.0" @@ -437,18 +445,18 @@ checksum = "237a5ed80e274dbc66f86bd59c1e25edc039660be53194b5fe0a482e0f2612ea" [[package]] name = "proc-macro2" -version = "1.0.56" +version = "1.0.66" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2b63bdb0cd06f1f4dedf69b254734f9b45af66e4a031e42a7480257d9898b435" +checksum = "18fb31db3f9bddb2ea821cde30a9f70117e3f119938b5ee630b7403aa6e2ead9" dependencies = [ "unicode-ident", ] [[package]] name = "quote" -version = "1.0.26" +version = "1.0.32" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4424af4bf778aae2051a77b60283332f386554255d722233d09fbfc7e30da2fc" +checksum = "50f3b39ccfb720540debaa0164757101c08ecb8d326b15358ce76a62c7e85965" dependencies = [ "proc-macro2", ] @@ -574,9 +582,9 @@ dependencies = [ [[package]] name = "serde" -version = "1.0.159" +version = "1.0.175" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3c04e8343c3daeec41f58990b9d77068df31209f2af111e059e9fe9646693065" +checksum = "5d25439cd7397d044e2748a6fe2432b5e85db703d6d097bd014b3c0ad1ebff0b" dependencies = [ "serde_derive", ] @@ -592,13 +600,13 @@ dependencies = [ [[package]] name = "serde_derive" -version = "1.0.159" +version = "1.0.175" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4c614d17805b093df4b147b51339e7e44bf05ef59fba1e45d83500bcfb4d8585" +checksum = "b23f7ade6f110613c0d63858ddb8b94c1041f550eab58a16b371bdf2c9c80ab4" dependencies = [ "proc-macro2", "quote", - "syn 2.0.13", + "syn 2.0.27", ] [[package]] @@ -641,15 +649,13 @@ dependencies = [ [[package]] name = "sha2" -version = "0.9.9" +version = "0.10.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4d58a1e1bf39749807d89cf2d98ac2dfa0ff1cb3faa38fbb64dd88ac8013d800" +checksum = "479fb9d862239e610720565ca91403019f2f00410f1864c5aa7479b950a76ed8" dependencies = [ - "block-buffer", "cfg-if 1.0.0", "cpufeatures", "digest", - "opaque-debug", ] [[package]] @@ -710,9 +716,9 @@ dependencies = [ [[package]] name = "syn" -version = "2.0.13" +version = "2.0.27" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4c9da457c5285ac1f936ebd076af6dac17a61cfe7826f2076b4d015cf47bc8ec" +checksum = "b60f673f44a8255b9c8c657daf66a596d435f2da81a555b06dc644d080ba45e0" dependencies = [ "proc-macro2", "quote", diff --git a/go-cosmwasm/lib.go b/go-cosmwasm/lib.go index 2ca3e87f3..51759223d 100644 --- a/go-cosmwasm/lib.go +++ b/go-cosmwasm/lib.go @@ -4,6 +4,7 @@ import ( "encoding/json" "fmt" + sdk "github.com/cosmos/cosmos-sdk/types" "github.com/scrtlabs/SecretNetwork/go-cosmwasm/api" types "github.com/scrtlabs/SecretNetwork/go-cosmwasm/types" v010types "github.com/scrtlabs/SecretNetwork/go-cosmwasm/types/v010" diff --git a/go.mod b/go.mod index 70e4dc3ee..953fc1a61 100644 --- a/go.mod +++ b/go.mod @@ -5,7 +5,7 @@ go 1.19 replace ( // dragonberry github.com/confio/ics23/go => github.com/cosmos/cosmos-sdk/ics23/go v0.8.0 - github.com/cosmos/cosmos-sdk => github.com/scrtlabs/cosmos-sdk v0.45.13-0.20230518112707-1b9278476b3a + github.com/cosmos/cosmos-sdk => github.com/scrtlabs/cosmos-sdk v0.45.13-0.20230726163133-dc2b5eab1db5 // last-marker-in-baseapp branch // github.com/cosmos/cosmos-sdk => github.com/scrtlabs/cosmos-sdk v0.45.13-0.20230409144936-ac748ac472c2 // Fix OSX Ledger Connection Issues - Premerged https://github.com/cosmos/ledger-cosmos-go/pull/36/files diff --git a/go.sum b/go.sum index f461aea3d..b24110f02 100644 --- a/go.sum +++ b/go.sum @@ -685,8 +685,8 @@ github.com/ryanuber/columnize v0.0.0-20160712163229-9b3edd62028f/go.mod h1:sm1tb github.com/samuel/go-zookeeper v0.0.0-20190923202752-2cc03de413da/go.mod h1:gi+0XIa01GRL2eRQVjQkKGqKF3SF9vZR/HnPullcV2E= github.com/sasha-s/go-deadlock v0.3.1 h1:sqv7fDNShgjcaxkO0JNcOAlr8B9+cV5Ey/OB71efZx0= github.com/sasha-s/go-deadlock v0.3.1/go.mod h1:F73l+cr82YSh10GxyRI6qZiCgK64VaZjwesgfQ1/iLM= -github.com/scrtlabs/cosmos-sdk v0.45.13-0.20230409144936-ac748ac472c2 h1:qkBemXVTX140G4uBbqrkXioG0uU5gWns6F79As7V7gk= -github.com/scrtlabs/cosmos-sdk v0.45.13-0.20230409144936-ac748ac472c2/go.mod h1:6n46SDUlhsl+a3+CaO1Xqb35CFxMqMdiouXnhZU2vvQ= +github.com/scrtlabs/cosmos-sdk v0.45.13-0.20230726163133-dc2b5eab1db5 h1:t0YeSrVF+jYgIidlWPyFwicTTJwmq815r3m5sx7jyAE= +github.com/scrtlabs/cosmos-sdk v0.45.13-0.20230726163133-dc2b5eab1db5/go.mod h1:6n46SDUlhsl+a3+CaO1Xqb35CFxMqMdiouXnhZU2vvQ= github.com/scrtlabs/tendermint v1.9.0-scrt h1:WohrW4d2lYVBWkYkv9QtPDG6CKOOaxSX5gtDQZ5oRVE= github.com/scrtlabs/tendermint v1.9.0-scrt/go.mod h1:wBQs1xza37rbFHU1vFOWqc3dmcciGDHYLfzpoN5uqhw= github.com/scrtlabs/tm-secret-enclave v1.9.6 h1:pTQpq1jEU/6m+jThuxl8RFggsG83qLPG/1R8TEI62AE= From 406a303c5774ea0f2e97a5eeecc492ef4a4b9809 Mon Sep 17 00:00:00 2001 From: Itzik Grossman Date: Wed, 26 Jul 2023 19:37:37 +0300 Subject: [PATCH 40/51] Merged proofs branch with master (does it work?) --- go-cosmwasm/Cargo.toml | 1 + 1 file changed, 1 insertion(+) diff --git a/go-cosmwasm/Cargo.toml b/go-cosmwasm/Cargo.toml index 9c643c26f..2abe4ccb1 100644 --- a/go-cosmwasm/Cargo.toml +++ b/go-cosmwasm/Cargo.toml @@ -39,6 +39,7 @@ query-node = ["cosmwasm-sgx-vm/query-node"] light-client-validation = [] random = [] verify-validator-whitelist = [] +read-db-proofs = [] [dependencies] cosmwasm-std = { package = "secret-cosmwasm-std", features = ["iterator"], version = "0.10.1"} From 5696bcb1da19ab0b076f6cb25c635fb62444b15a Mon Sep 17 00:00:00 2001 From: Itzik Grossman Date: Mon, 31 Jul 2023 00:06:08 +0300 Subject: [PATCH 41/51] Merge master with the cache changes --- cosmwasm/enclaves/execute/src/ecalls.rs | 2 -- cosmwasm/enclaves/execute/src/lib.rs | 2 ++ cosmwasm/enclaves/execute/src/sdk_entrypoints.rs | 8 ++++++++ .../shared/contract-engine/src/contract_validation.rs | 6 ------ 4 files changed, 10 insertions(+), 8 deletions(-) diff --git a/cosmwasm/enclaves/execute/src/ecalls.rs b/cosmwasm/enclaves/execute/src/ecalls.rs index cf2d3cb54..40db781d6 100644 --- a/cosmwasm/enclaves/execute/src/ecalls.rs +++ b/cosmwasm/enclaves/execute/src/ecalls.rs @@ -1,7 +1,5 @@ use sgx_types::sgx_status_t; -pub use read_verifier::ecalls::ecall_submit_store_roots; - /// # Safety /// This function reads buffers which must be correctly initialized by the caller, /// see safety section of slice::[from_raw_parts](https://doc.rust-lang.org/std/slice/fn.from_raw_parts.html#safety) diff --git a/cosmwasm/enclaves/execute/src/lib.rs b/cosmwasm/enclaves/execute/src/lib.rs index f4578a931..3110a4675 100644 --- a/cosmwasm/enclaves/execute/src/lib.rs +++ b/cosmwasm/enclaves/execute/src/lib.rs @@ -18,6 +18,8 @@ pub mod registration; mod sdk_entrypoints; mod tests; +pub use sdk_entrypoints::ecall_app_begin_blocker; + #[cfg(feature = "production")] #[ctor] fn init_logger() { diff --git a/cosmwasm/enclaves/execute/src/sdk_entrypoints.rs b/cosmwasm/enclaves/execute/src/sdk_entrypoints.rs index 3e87111ea..b62b56f82 100644 --- a/cosmwasm/enclaves/execute/src/sdk_entrypoints.rs +++ b/cosmwasm/enclaves/execute/src/sdk_entrypoints.rs @@ -23,6 +23,11 @@ macro_rules! validate_input_length { }; } +/// # Safety +/// This function must only be called with valid pointers and lengths. +/// - `in_roots` and `in_roots_len`: must point to a valid sequence of bytes representing roots. +/// - `in_compute_root` and `in_compute_root_len`: must point to a valid sequence of bytes representing compute roots. +/// It's the caller's responsibility to ensure that the pointers are valid and the lengths are correct. #[no_mangle] pub unsafe extern "C" fn ecall_app_begin_blocker( in_roots: *const u8, @@ -55,5 +60,8 @@ pub unsafe extern "C" fn ecall_app_begin_blocker( } } +/// # Safety +/// This function's safety requirements depend on the expected implementation. +/// Since the function body is empty, there are currently no specific safety concerns. #[no_mangle] pub unsafe extern "C" fn end_blocker() {} diff --git a/cosmwasm/enclaves/shared/contract-engine/src/contract_validation.rs b/cosmwasm/enclaves/shared/contract-engine/src/contract_validation.rs index b4b6e6d29..7dd7757a5 100644 --- a/cosmwasm/enclaves/shared/contract-engine/src/contract_validation.rs +++ b/cosmwasm/enclaves/shared/contract-engine/src/contract_validation.rs @@ -50,12 +50,6 @@ fn is_subslice(larger: &[u8], smaller: &[u8]) -> bool { false } -#[cfg(feature = "light-client-validation")] -pub fn is_last_msg_in_block() -> bool { - let verified_msgs = VERIFIED_MESSAGES.lock().unwrap(); - return verified_msgs.remaining() == 0; -} - #[cfg(feature = "light-client-validation")] pub fn verify_block_info(base_env: &BaseEnv) -> Result<(), EnclaveError> { let verified_msgs = VERIFIED_MESSAGES.lock().unwrap(); From a18dd5fec762a252a957e542a018cb5f5219c1fa Mon Sep 17 00:00:00 2001 From: Cashmaney Date: Mon, 31 Jul 2023 17:30:59 +0300 Subject: [PATCH 42/51] Update go-lint.yml --- .github/workflows/go-lint.yml | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/.github/workflows/go-lint.yml b/.github/workflows/go-lint.yml index 6fa25afc8..a3babe99e 100644 --- a/.github/workflows/go-lint.yml +++ b/.github/workflows/go-lint.yml @@ -19,6 +19,10 @@ jobs: with: go-version: 1.19 - uses: actions/checkout@v3 + - name: make bin-data-sw + run: | + go install github.com/jteeuwen/go-bindata/go-bindata@latest + make bin-data-sw - name: golangci-lint uses: golangci/golangci-lint-action@v3 with: From b1d8448d1a584a09fd0fcc24776f9b6ca3879722 Mon Sep 17 00:00:00 2001 From: Cashmaney Date: Mon, 31 Jul 2023 17:38:20 +0300 Subject: [PATCH 43/51] Update .golangci.yml --- .golangci.yml | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/.golangci.yml b/.golangci.yml index 0dca22359..3e209b427 100644 --- a/.golangci.yml +++ b/.golangci.yml @@ -2,7 +2,8 @@ run: tests: false # # timeout for analysis, e.g. 30s, 5m, default is 1m timeout: 5m - + skip_files: + - x/registration/internal/types/ias_bin_sw.go linters: disable-all: true enable: From 3349a07da3fb05e3b109089a3b6ba5ee452e63a5 Mon Sep 17 00:00:00 2001 From: Cashmaney Date: Mon, 31 Jul 2023 17:42:04 +0300 Subject: [PATCH 44/51] Update .golangci.yml --- .golangci.yml | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/.golangci.yml b/.golangci.yml index 3e209b427..b0b65c6a0 100644 --- a/.golangci.yml +++ b/.golangci.yml @@ -2,8 +2,10 @@ run: tests: false # # timeout for analysis, e.g. 30s, 5m, default is 1m timeout: 5m - skip_files: - - x/registration/internal/types/ias_bin_sw.go + skip-files: + - x/registration/internal/types/reg_keys.go # uses auto generated code + - x/registration/internal/types/ias_bin.*?.go # auto generated + linters: disable-all: true enable: From 7b2b85d90ae0af27637e6380cdeb3bd409552810 Mon Sep 17 00:00:00 2001 From: Itzik Grossman Date: Mon, 31 Jul 2023 17:46:33 +0300 Subject: [PATCH 45/51] fumpt --- go-cosmwasm/api/callbacks.go | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/go-cosmwasm/api/callbacks.go b/go-cosmwasm/api/callbacks.go index d1c7c8f1f..4add136fb 100644 --- a/go-cosmwasm/api/callbacks.go +++ b/go-cosmwasm/api/callbacks.go @@ -92,11 +92,11 @@ type GasMeter interface { /****** DB ********/ var db_vtable = C.DB_vtable{ - read_db: (C.read_db_fn)(C.cGet_cgo), - read_db_no_proof: (C.read_db_no_proof_fn)(C.cGetNoProof_cgo), - write_db: (C.write_db_fn)(C.cSet_cgo), - remove_db: (C.remove_db_fn)(C.cDelete_cgo), - scan_db: (C.scan_db_fn)(C.cScan_cgo), + read_db: (C.read_db_fn)(C.cGet_cgo), + read_db_no_proof: (C.read_db_no_proof_fn)(C.cGetNoProof_cgo), + write_db: (C.write_db_fn)(C.cSet_cgo), + remove_db: (C.remove_db_fn)(C.cDelete_cgo), + scan_db: (C.scan_db_fn)(C.cScan_cgo), } type DBState struct { From 2060e157a0a798b825c8ba24451cccb08b44950a Mon Sep 17 00:00:00 2001 From: Cashmaney Date: Tue, 1 Aug 2023 15:40:32 +0300 Subject: [PATCH 46/51] Update Dockerfile --- deployment/dockerfiles/Dockerfile | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/deployment/dockerfiles/Dockerfile b/deployment/dockerfiles/Dockerfile index dcc55c1ad..766cea0b7 100644 --- a/deployment/dockerfiles/Dockerfile +++ b/deployment/dockerfiles/Dockerfile @@ -26,7 +26,7 @@ WORKDIR /go/src/github.com/enigmampc/SecretNetwork/ COPY rust-toolchain rust-toolchain RUN rustup component add rust-src -RUN --mount=type=cache,target=/root/.cargo/registry cargo install xargo --version 0.3.25 +RUN cargo install xargo --version 0.3.25 # Add submodules COPY third_party third_party @@ -53,7 +53,7 @@ ENV MITIGATION_CVE_2020_0551=${MITIGATION_CVE_2020_0551} COPY rust-toolchain rust-toolchain RUN rustup component add rust-src -RUN --mount=type=cache,target=/root/.cargo/registry cargo install xargo --version 0.3.25 +RUN cargo install xargo --version 0.3.25 # Add submodules COPY third_party third_party @@ -64,7 +64,7 @@ COPY cosmwasm cosmwasm/ WORKDIR /go/src/github.com/enigmampc/SecretNetwork/go-cosmwasm -RUN --mount=type=cache,target=/root/.cargo/registry . /opt/sgxsdk/environment && env \ +RUN . /opt/sgxsdk/environment && env \ && MITIGATION_CVE_2020_0551=${MITIGATION_CVE_2020_0551} VERSION=${VERSION} FEATURES=${FEATURES} FEATURES_U=${FEATURES_U} SGX_MODE=${SGX_MODE} make build-rust ENTRYPOINT ["/bin/bash"] @@ -316,7 +316,7 @@ ENV FEATURES_U=${FEATURES_U} WORKDIR /go/src/github.com/enigmampc/SecretNetwork/go-cosmwasm # Ignore $FEATURES because it should never be `production` -RUN --mount=type=cache,target=/root/.cargo/registry . /opt/sgxsdk/environment && env \ +RUN . /opt/sgxsdk/environment && env \ && VERSION=${VERSION} FEATURES="" FEATURES_U=${FEATURES_U} SGX_MODE=HW make build-rust # Set working directory for the build @@ -338,7 +338,7 @@ WORKDIR /go/src/github.com/enigmampc/SecretNetwork/check-hw COPY ./deployment/docker/builder/create_check_hw_tar.sh . -RUN --mount=type=cache,target=/root/.cargo/registry . /opt/sgxsdk/environment && env && make +RUN . /opt/sgxsdk/environment && env && make RUN cp ../go-cosmwasm/librust_cosmwasm_enclave.signed.so ./check_hw_enclave.so ENTRYPOINT ["/bin/bash", "create_check_hw_tar.sh"] From 7bc88bf77ef06ab23deed1a62f88755628612e37 Mon Sep 17 00:00:00 2001 From: toml01 Date: Mon, 30 Oct 2023 14:29:09 +0200 Subject: [PATCH 47/51] Add dependencies for merkle proofs --- cosmwasm/enclaves/Cargo.lock | 14 ++---- cosmwasm/enclaves/execute/Cargo.toml | 19 +++++--- cosmwasm/enclaves/execute/src/ecalls.rs | 65 +++++++++++++++++++++++++ 3 files changed, 80 insertions(+), 18 deletions(-) diff --git a/cosmwasm/enclaves/Cargo.lock b/cosmwasm/enclaves/Cargo.lock index cffcdca42..44d25e209 100644 --- a/cosmwasm/enclaves/Cargo.lock +++ b/cosmwasm/enclaves/Cargo.lock @@ -215,8 +215,8 @@ dependencies = [ name = "block-verifier" version = "0.1.0" dependencies = [ - "cosmos-sdk-proto", "base64 0.21.1", + "cosmos-sdk-proto", "cosmos_proto", "enclave_crypto", "enclave_utils", @@ -1439,15 +1439,6 @@ version = "0.7.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "436b050e76ed2903236f032a59761c1eb99e1b0aead2c257922771dab1fc8c78" -[[package]] -name = "remove_dir_all" -version = "0.5.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3acd125665422973a33ac9d3dd2df85edad0f4ae9b00dafb1a05e43a9f5ef8e7" -dependencies = [ - "winapi", -] - [[package]] name = "ring" version = "0.16.19" @@ -1571,6 +1562,7 @@ dependencies = [ "bit-vec", "block-verifier", "chrono", + "cosmos-sdk-proto", "ctor", "derive_more", "enclave-ffi-types", @@ -1580,6 +1572,7 @@ dependencies = [ "enclave_utils", "hex", "httparse", + "integer-encoding", "itertools 0.8.2", "lazy_static", "log", @@ -1595,6 +1588,7 @@ dependencies = [ "sgx_tstd", "sgx_types", "simple_logger", + "tendermint", "time", "uuid", "webpki", diff --git a/cosmwasm/enclaves/execute/Cargo.toml b/cosmwasm/enclaves/execute/Cargo.toml index c65850fb5..7122f6870 100644 --- a/cosmwasm/enclaves/execute/Cargo.toml +++ b/cosmwasm/enclaves/execute/Cargo.toml @@ -21,25 +21,25 @@ production = [ "log/max_level_warn", "log/release_max_level_warn", "block-verifier/production", - "block-verifier/verify-validator-whitelist" + "block-verifier/verify-validator-whitelist", ] debug-print = ["enclave_contract_engine/debug-print"] test = [ "enclave_contract_engine/test", "enclave_crypto/test", "enclave_cosmos_types/test", - "block-verifier/test" + "block-verifier/test", ] use_seed_service_on_bootstrap = [] epid_whitelist_disabled = [] light-client-validation = [ "enclave_contract_engine/light-client-validation", - "block-verifier" + "block-verifier", ] random = ["enclave_contract_engine/random", "enclave_crypto/random"] verify-validator-whitelist = [ "block-verifier/verify-validator-whitelist", - "light-client-validation" + "light-client-validation", ] go-tests = [] check-hw = [] @@ -50,7 +50,7 @@ check-hw = [] [target.'cfg(not(target_env = "sgx"))'.dependencies] sgx_tstd = { rev = "d2d339cbb005f676bb700059bd51dc689c025f6b", git = "https://github.com/apache/teaclave-sgx-sdk.git", features = [ "backtrace", - "untrusted_time" + "untrusted_time", ] } sgx_types = { rev = "d2d339cbb005f676bb700059bd51dc689c025f6b", git = "https://github.com/apache/teaclave-sgx-sdk.git" } @@ -64,14 +64,14 @@ enclave_crypto = { path = "../shared/crypto" } enclave_utils = { path = "../shared/utils" } enclave_cosmos_types = { path = "../shared/cosmos-types", optional = true } serde = { git = "https://github.com/mesalock-linux/serde-sgx", features = [ - "derive" + "derive", ] } serde_json = { git = "https://github.com/mesalock-linux/serde-json-sgx" } ctor = "0.1.13" derive_more = "0.99" pwasm-utils = { version = "0.12.0", default-features = false } parity-wasm = { version = "0.45.0", default-features = false, features = [ - "sign_ext" + "sign_ext", ] } base64 = { rev = "dc7389e10817b078f289386b3b6a852ab6c4c021", git = "https://github.com/mesalock-linux/rust-base64-sgx" } # for attestation @@ -85,10 +85,13 @@ lazy_static = "1.4" hex = "0.4.2" log = "0.4.17" simple_logger = { version = "2.3.0", default-features = false, features = [ - "stderr" + "stderr", ] } block-verifier = { path = "../shared/block-verifier", optional = true } time = "=0.3.17" +tendermint = { git = "https://github.com/scrtlabs/tendermint-rs", branch = "fix-val-set-parsing", default-features = false } +cosmos-sdk-proto = { version = "0.16.0", default-features = false } +integer-encoding = "3.0.4" [dependencies.webpki] git = "https://github.com/mesalock-linux/webpki" diff --git a/cosmwasm/enclaves/execute/src/ecalls.rs b/cosmwasm/enclaves/execute/src/ecalls.rs index 40db781d6..cd9a54e2a 100644 --- a/cosmwasm/enclaves/execute/src/ecalls.rs +++ b/cosmwasm/enclaves/execute/src/ecalls.rs @@ -1,4 +1,8 @@ +use cosmos_sdk_proto::cosmos::base::kv::v1beta1::{Pair, Pairs}; +use cosmos_sdk_proto::traits::Message; +use integer_encoding::VarInt; use sgx_types::sgx_status_t; +use tendermint::merkle; /// # Safety /// This function reads buffers which must be correctly initialized by the caller, @@ -45,3 +49,64 @@ pub unsafe extern "C" fn ecall_submit_block_signatures( sgx_status_t::SGX_ERROR_ECALL_NOT_ALLOWED } } + +#[no_mangle] +#[allow(unused_variables)] +pub unsafe extern "C" fn ecall_submit_store_roots( + in_roots: *const u8, + in_roots_len: u32, + in_compute_root: *const u8, + in_compute_root_len: u32, +) -> sgx_status_t { + validate_input_length!(in_roots_len, "roots", MAX_VARIABLE_LENGTH); + validate_const_ptr!( + in_roots, + in_roots_len as usize, + sgx_status_t::SGX_ERROR_INVALID_PARAMETER + ); + validate_input_length!(in_compute_root_len, "roots", MAX_VARIABLE_LENGTH); + validate_const_ptr!( + in_compute_root, + in_compute_root_len as usize, + sgx_status_t::SGX_ERROR_INVALID_PARAMETER + ); + + let store_roots_slice = slice::from_raw_parts(in_roots, in_roots_len as usize); + let compute_root_slice = slice::from_raw_parts(in_compute_root, in_compute_root_len as usize); + + let store_roots: Pairs = Pairs::decode(store_roots_slice).unwrap(); + let mut store_roots_bytes = vec![]; + + // Encode all key-value pairs to bytes + for root in store_roots.pairs { + store_roots_bytes.push(pair_to_bytes(root)); + } + + let h = merkle::simple_hash_from_byte_vectors(store_roots_bytes); + debug!("received app_hash: {:?}", h); + debug!("received compute_root: {:?}", compute_root_slice); + + return sgx_status_t::SGX_SUCCESS; +} + +// This is a copy of a cosmos-sdk function: https://github.com/scrtlabs/cosmos-sdk/blob/1b9278476b3ac897d8ebb90241008476850bf212/store/internal/maps/maps.go#LL152C1-L152C1 +// Returns key || value, with both the key and value length prefixed. +fn pair_to_bytes(kv: Pair) -> Vec { + // In the worst case: + // * 8 bytes to Uvarint encode the length of the key + // * 8 bytes to Uvarint encode the length of the value + // So preallocate for the worst case, which will in total + // be a maximum of 14 bytes wasted, if len(key)=1, len(value)=1, + // but that's going to rare. + let mut buf = vec![]; + + // Encode the key, prefixed with its length. + buf.extend_from_slice(&(kv.key.len()).encode_var_vec()); + buf.extend_from_slice(&kv.key); + + // Encode the value, prefixing with its length. + buf.extend_from_slice(&(kv.value.len()).encode_var_vec()); + buf.extend_from_slice(&kv.value); + + return buf; +} From df929f2def2264110b0bd4de8a6b0f4e4dfd11de Mon Sep 17 00:00:00 2001 From: toml01 Date: Mon, 30 Oct 2023 15:43:02 +0200 Subject: [PATCH 48/51] compilation and clippy --- cosmwasm/enclaves/execute/src/ecalls.rs | 21 +++++++++++++++---- .../src/contract_operations.rs | 1 + 2 files changed, 18 insertions(+), 4 deletions(-) diff --git a/cosmwasm/enclaves/execute/src/ecalls.rs b/cosmwasm/enclaves/execute/src/ecalls.rs index cd9a54e2a..266515c95 100644 --- a/cosmwasm/enclaves/execute/src/ecalls.rs +++ b/cosmwasm/enclaves/execute/src/ecalls.rs @@ -1,9 +1,15 @@ use cosmos_sdk_proto::cosmos::base::kv::v1beta1::{Pair, Pairs}; use cosmos_sdk_proto::traits::Message; +use enclave_utils::{validate_const_ptr, validate_input_length}; use integer_encoding::VarInt; +use log::{debug, error}; use sgx_types::sgx_status_t; +use std::slice; use tendermint::merkle; +const MAX_MERKLE_ROOT_LENGTH: u32 = 32; +const MAX_ROOTS_LENGTH: u32 = 20 * MAX_MERKLE_ROOT_LENGTH; + /// # Safety /// This function reads buffers which must be correctly initialized by the caller, /// see safety section of slice::[from_raw_parts](https://doc.rust-lang.org/std/slice/fn.from_raw_parts.html#safety) @@ -58,13 +64,20 @@ pub unsafe extern "C" fn ecall_submit_store_roots( in_compute_root: *const u8, in_compute_root_len: u32, ) -> sgx_status_t { - validate_input_length!(in_roots_len, "roots", MAX_VARIABLE_LENGTH); + let failed_call = || sgx_status_t::SGX_ERROR_INVALID_PARAMETER; + + validate_input_length!(in_roots_len, "roots", MAX_ROOTS_LENGTH, failed_call()); validate_const_ptr!( in_roots, in_roots_len as usize, sgx_status_t::SGX_ERROR_INVALID_PARAMETER ); - validate_input_length!(in_compute_root_len, "roots", MAX_VARIABLE_LENGTH); + validate_input_length!( + in_compute_root_len, + "compute_root", + MAX_MERKLE_ROOT_LENGTH, + failed_call() + ); validate_const_ptr!( in_compute_root, in_compute_root_len as usize, @@ -86,7 +99,7 @@ pub unsafe extern "C" fn ecall_submit_store_roots( debug!("received app_hash: {:?}", h); debug!("received compute_root: {:?}", compute_root_slice); - return sgx_status_t::SGX_SUCCESS; + sgx_status_t::SGX_SUCCESS } // This is a copy of a cosmos-sdk function: https://github.com/scrtlabs/cosmos-sdk/blob/1b9278476b3ac897d8ebb90241008476850bf212/store/internal/maps/maps.go#LL152C1-L152C1 @@ -108,5 +121,5 @@ fn pair_to_bytes(kv: Pair) -> Vec { buf.extend_from_slice(&(kv.value.len()).encode_var_vec()); buf.extend_from_slice(&kv.value); - return buf; + buf } diff --git a/cosmwasm/enclaves/shared/contract-engine/src/contract_operations.rs b/cosmwasm/enclaves/shared/contract-engine/src/contract_operations.rs index 7fd98cc58..3c5affd3f 100644 --- a/cosmwasm/enclaves/shared/contract-engine/src/contract_operations.rs +++ b/cosmwasm/enclaves/shared/contract-engine/src/contract_operations.rs @@ -370,6 +370,7 @@ pub fn migrate( query_depth, secret_msg.nonce, secret_msg.user_public_key, + block_height, base_env.0.block.time, )?; // let duration = start.elapsed(); From cf60e62e37dd8c9bec85650928059f100dbd12bc Mon Sep 17 00:00:00 2001 From: Cashmaney Date: Wed, 1 Nov 2023 00:47:27 +0700 Subject: [PATCH 49/51] Fix all the stuff I broke :( --- .../actions/check-objdump/package-lock.json | 292 +++++++++--------- cosmwasm/enclaves/Cargo.lock | 81 +++-- cosmwasm/enclaves/ffi-types/cbindgen.toml | 2 +- .../enclaves/shared/contract-engine/src/db.rs | 8 +- .../shared/contract-engine/src/wasm3/mod.rs | 8 +- go-cosmwasm/api/lib.go | 4 +- go.mod | 2 +- go.sum | 4 +- 8 files changed, 197 insertions(+), 204 deletions(-) diff --git a/.github/actions/check-objdump/package-lock.json b/.github/actions/check-objdump/package-lock.json index 1976fd2a9..e10e1f2e7 100644 --- a/.github/actions/check-objdump/package-lock.json +++ b/.github/actions/check-objdump/package-lock.json @@ -1,146 +1,146 @@ -{ - "name": "actions-download-file", - "version": "1.3.0", - "lockfileVersion": 3, - "requires": true, - "packages": { - "": { - "name": "actions-download-file", - "version": "1.3.0", - "license": "MIT", - "dependencies": { - "@actions/core": "^1.10.0", - "node-fetch": "3.3.1" - }, - "devDependencies": { - "@vercel/ncc": "^0.36.1" - } - }, - "node_modules/@actions/core": { - "version": "1.10.0", - "resolved": "https://registry.npmjs.org/@actions/core/-/core-1.10.0.tgz", - "integrity": "sha512-2aZDDa3zrrZbP5ZYg159sNoLRb61nQ7awl5pSvIq5Qpj81vwDzdMRKzkWJGJuwVvWpvZKx7vspJALyvaaIQyug==", - "dependencies": { - "@actions/http-client": "^2.0.1", - "uuid": "^8.3.2" - } - }, - "node_modules/@actions/http-client": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/@actions/http-client/-/http-client-2.1.0.tgz", - "integrity": "sha512-BonhODnXr3amchh4qkmjPMUO8mFi/zLaaCeCAJZqch8iQqyDnVIkySjB38VHAC8IJ+bnlgfOqlhpyCUZHlQsqw==", - "dependencies": { - "tunnel": "^0.0.6" - } - }, - "node_modules/@vercel/ncc": { - "version": "0.36.1", - "resolved": "https://registry.npmjs.org/@vercel/ncc/-/ncc-0.36.1.tgz", - "integrity": "sha512-S4cL7Taa9yb5qbv+6wLgiKVZ03Qfkc4jGRuiUQMQ8HGBD5pcNRnHeYM33zBvJE4/zJGjJJ8GScB+WmTsn9mORw==", - "dev": true, - "bin": { - "ncc": "dist/ncc/cli.js" - } - }, - "node_modules/data-uri-to-buffer": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/data-uri-to-buffer/-/data-uri-to-buffer-4.0.1.tgz", - "integrity": "sha512-0R9ikRb668HB7QDxT1vkpuUBtqc53YyAwMwGeUFKRojY/NWKvdZ+9UYtRfGmhqNbRkTSVpMbmyhXipFFv2cb/A==", - "engines": { - "node": ">= 12" - } - }, - "node_modules/fetch-blob": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/fetch-blob/-/fetch-blob-3.2.0.tgz", - "integrity": "sha512-7yAQpD2UMJzLi1Dqv7qFYnPbaPx7ZfFK6PiIxQ4PfkGPyNyl2Ugx+a/umUonmKqjhM4DnfbMvdX6otXq83soQQ==", - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/jimmywarting" - }, - { - "type": "paypal", - "url": "https://paypal.me/jimmywarting" - } - ], - "dependencies": { - "node-domexception": "^1.0.0", - "web-streams-polyfill": "^3.0.3" - }, - "engines": { - "node": "^12.20 || >= 14.13" - } - }, - "node_modules/formdata-polyfill": { - "version": "4.0.10", - "resolved": "https://registry.npmjs.org/formdata-polyfill/-/formdata-polyfill-4.0.10.tgz", - "integrity": "sha512-buewHzMvYL29jdeQTVILecSaZKnt/RJWjoZCF5OW60Z67/GmSLBkOFM7qh1PI3zFNtJbaZL5eQu1vLfazOwj4g==", - "dependencies": { - "fetch-blob": "^3.1.2" - }, - "engines": { - "node": ">=12.20.0" - } - }, - "node_modules/node-domexception": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/node-domexception/-/node-domexception-1.0.0.tgz", - "integrity": "sha512-/jKZoMpw0F8GRwl4/eLROPA3cfcXtLApP0QzLmUT/HuPCZWyB7IY9ZrMeKw2O/nFIqPQB3PVM9aYm0F312AXDQ==", - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/jimmywarting" - }, - { - "type": "github", - "url": "https://paypal.me/jimmywarting" - } - ], - "engines": { - "node": ">=10.5.0" - } - }, - "node_modules/node-fetch": { - "version": "3.3.1", - "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-3.3.1.tgz", - "integrity": "sha512-cRVc/kyto/7E5shrWca1Wsea4y6tL9iYJE5FBCius3JQfb/4P4I295PfhgbJQBLTx6lATE4z+wK0rPM4VS2uow==", - "dependencies": { - "data-uri-to-buffer": "^4.0.0", - "fetch-blob": "^3.1.4", - "formdata-polyfill": "^4.0.10" - }, - "engines": { - "node": "^12.20.0 || ^14.13.1 || >=16.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/node-fetch" - } - }, - "node_modules/tunnel": { - "version": "0.0.6", - "resolved": "https://registry.npmjs.org/tunnel/-/tunnel-0.0.6.tgz", - "integrity": "sha512-1h/Lnq9yajKY2PEbBadPXj3VxsDDu844OnaAo52UVmIzIvwwtBPIuNvkjuzBlTWpfJyUbG3ez0KSBibQkj4ojg==", - "engines": { - "node": ">=0.6.11 <=0.7.0 || >=0.7.3" - } - }, - "node_modules/uuid": { - "version": "8.3.2", - "resolved": "https://registry.npmjs.org/uuid/-/uuid-8.3.2.tgz", - "integrity": "sha512-+NYs2QeMWy+GWFOEm9xnn6HCDp0l7QBD7ml8zLUmJ+93Q5NF0NocErnwkTkXVFNiX3/fpC6afS8Dhb/gz7R7eg==", - "bin": { - "uuid": "dist/bin/uuid" - } - }, - "node_modules/web-streams-polyfill": { - "version": "3.2.1", - "resolved": "https://registry.npmjs.org/web-streams-polyfill/-/web-streams-polyfill-3.2.1.tgz", - "integrity": "sha512-e0MO3wdXWKrLbL0DgGnUV7WHVuw9OUvL4hjgnPkIeEvESk74gAITi5G606JtZPp39cd8HA9VQzCIvA49LpPN5Q==", - "engines": { - "node": ">= 8" - } - } - } -} +{ + "name": "actions-download-file", + "version": "1.3.0", + "lockfileVersion": 3, + "requires": true, + "packages": { + "": { + "name": "actions-download-file", + "version": "1.3.0", + "license": "MIT", + "dependencies": { + "@actions/core": "^1.10.0", + "node-fetch": "3.3.1" + }, + "devDependencies": { + "@vercel/ncc": "^0.36.1" + } + }, + "node_modules/@actions/core": { + "version": "1.10.0", + "resolved": "https://registry.npmjs.org/@actions/core/-/core-1.10.0.tgz", + "integrity": "sha512-2aZDDa3zrrZbP5ZYg159sNoLRb61nQ7awl5pSvIq5Qpj81vwDzdMRKzkWJGJuwVvWpvZKx7vspJALyvaaIQyug==", + "dependencies": { + "@actions/http-client": "^2.0.1", + "uuid": "^8.3.2" + } + }, + "node_modules/@actions/http-client": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/@actions/http-client/-/http-client-2.1.0.tgz", + "integrity": "sha512-BonhODnXr3amchh4qkmjPMUO8mFi/zLaaCeCAJZqch8iQqyDnVIkySjB38VHAC8IJ+bnlgfOqlhpyCUZHlQsqw==", + "dependencies": { + "tunnel": "^0.0.6" + } + }, + "node_modules/@vercel/ncc": { + "version": "0.36.1", + "resolved": "https://registry.npmjs.org/@vercel/ncc/-/ncc-0.36.1.tgz", + "integrity": "sha512-S4cL7Taa9yb5qbv+6wLgiKVZ03Qfkc4jGRuiUQMQ8HGBD5pcNRnHeYM33zBvJE4/zJGjJJ8GScB+WmTsn9mORw==", + "dev": true, + "bin": { + "ncc": "dist/ncc/cli.js" + } + }, + "node_modules/data-uri-to-buffer": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/data-uri-to-buffer/-/data-uri-to-buffer-4.0.1.tgz", + "integrity": "sha512-0R9ikRb668HB7QDxT1vkpuUBtqc53YyAwMwGeUFKRojY/NWKvdZ+9UYtRfGmhqNbRkTSVpMbmyhXipFFv2cb/A==", + "engines": { + "node": ">= 12" + } + }, + "node_modules/fetch-blob": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/fetch-blob/-/fetch-blob-3.2.0.tgz", + "integrity": "sha512-7yAQpD2UMJzLi1Dqv7qFYnPbaPx7ZfFK6PiIxQ4PfkGPyNyl2Ugx+a/umUonmKqjhM4DnfbMvdX6otXq83soQQ==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/jimmywarting" + }, + { + "type": "paypal", + "url": "https://paypal.me/jimmywarting" + } + ], + "dependencies": { + "node-domexception": "^1.0.0", + "web-streams-polyfill": "^3.0.3" + }, + "engines": { + "node": "^12.20 || >= 14.13" + } + }, + "node_modules/formdata-polyfill": { + "version": "4.0.10", + "resolved": "https://registry.npmjs.org/formdata-polyfill/-/formdata-polyfill-4.0.10.tgz", + "integrity": "sha512-buewHzMvYL29jdeQTVILecSaZKnt/RJWjoZCF5OW60Z67/GmSLBkOFM7qh1PI3zFNtJbaZL5eQu1vLfazOwj4g==", + "dependencies": { + "fetch-blob": "^3.1.2" + }, + "engines": { + "node": ">=12.20.0" + } + }, + "node_modules/node-domexception": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/node-domexception/-/node-domexception-1.0.0.tgz", + "integrity": "sha512-/jKZoMpw0F8GRwl4/eLROPA3cfcXtLApP0QzLmUT/HuPCZWyB7IY9ZrMeKw2O/nFIqPQB3PVM9aYm0F312AXDQ==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/jimmywarting" + }, + { + "type": "github", + "url": "https://paypal.me/jimmywarting" + } + ], + "engines": { + "node": ">=10.5.0" + } + }, + "node_modules/node-fetch": { + "version": "3.3.1", + "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-3.3.1.tgz", + "integrity": "sha512-cRVc/kyto/7E5shrWca1Wsea4y6tL9iYJE5FBCius3JQfb/4P4I295PfhgbJQBLTx6lATE4z+wK0rPM4VS2uow==", + "dependencies": { + "data-uri-to-buffer": "^4.0.0", + "fetch-blob": "^3.1.4", + "formdata-polyfill": "^4.0.10" + }, + "engines": { + "node": "^12.20.0 || ^14.13.1 || >=16.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/node-fetch" + } + }, + "node_modules/tunnel": { + "version": "0.0.6", + "resolved": "https://registry.npmjs.org/tunnel/-/tunnel-0.0.6.tgz", + "integrity": "sha512-1h/Lnq9yajKY2PEbBadPXj3VxsDDu844OnaAo52UVmIzIvwwtBPIuNvkjuzBlTWpfJyUbG3ez0KSBibQkj4ojg==", + "engines": { + "node": ">=0.6.11 <=0.7.0 || >=0.7.3" + } + }, + "node_modules/uuid": { + "version": "8.3.2", + "resolved": "https://registry.npmjs.org/uuid/-/uuid-8.3.2.tgz", + "integrity": "sha512-+NYs2QeMWy+GWFOEm9xnn6HCDp0l7QBD7ml8zLUmJ+93Q5NF0NocErnwkTkXVFNiX3/fpC6afS8Dhb/gz7R7eg==", + "bin": { + "uuid": "dist/bin/uuid" + } + }, + "node_modules/web-streams-polyfill": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/web-streams-polyfill/-/web-streams-polyfill-3.2.1.tgz", + "integrity": "sha512-e0MO3wdXWKrLbL0DgGnUV7WHVuw9OUvL4hjgnPkIeEvESk74gAITi5G606JtZPp39cd8HA9VQzCIvA49LpPN5Q==", + "engines": { + "node": ">= 8" + } + } + } +} diff --git a/cosmwasm/enclaves/Cargo.lock b/cosmwasm/enclaves/Cargo.lock index 3dfc55ca0..32237d99f 100644 --- a/cosmwasm/enclaves/Cargo.lock +++ b/cosmwasm/enclaves/Cargo.lock @@ -216,10 +216,12 @@ name = "block-verifier" version = "0.1.0" dependencies = [ "base64 0.21.1", + "cosmos-sdk-proto", "cosmos_proto", "enclave_crypto", "enclave_utils", "hex", + "integer-encoding", "lazy_static", "log", "protobuf", @@ -379,7 +381,7 @@ dependencies = [ [[package]] name = "cosmos_proto" -version = "1.6.0" +version = "1.11.0" dependencies = [ "dirs", "protobuf", @@ -462,7 +464,7 @@ dependencies = [ [[package]] name = "cw_types_generic" -version = "1.6.0" +version = "1.11.0" dependencies = [ "base64 0.13.1", "cw_types_v010", @@ -476,7 +478,7 @@ dependencies = [ [[package]] name = "cw_types_v010" -version = "1.6.0" +version = "1.11.0" dependencies = [ "base64 0.13.0 (git+https://github.com/mesalock-linux/rust-base64-sgx?rev=dc7389e10817b078f289386b3b6a852ab6c4c021)", "bech32", @@ -490,7 +492,7 @@ dependencies = [ [[package]] name = "cw_types_v1" -version = "1.6.0" +version = "1.11.0" dependencies = [ "base64 0.13.0 (git+https://github.com/mesalock-linux/rust-base64-sgx?rev=dc7389e10817b078f289386b3b6a852ab6c4c021)", "bech32", @@ -632,7 +634,7 @@ dependencies = [ [[package]] name = "enclave_contract_engine" -version = "1.6.0" +version = "1.11.0" dependencies = [ "base64 0.13.0 (git+https://github.com/mesalock-linux/rust-base64-sgx?rev=dc7389e10817b078f289386b3b6a852ab6c4c021)", "bech32", @@ -652,7 +654,7 @@ dependencies = [ "lazy_static", "log", "lru", - "parity-wasm", + "parity-wasm 0.45.0", "protobuf", "pwasm-utils", "rand_chacha", @@ -661,6 +663,7 @@ dependencies = [ "secp256k1 0.24.2", "serde 1.0.118", "serde_json 1.0.60", + "sgx_rand", "sgx_tstd", "sgx_types", "sha2 0.8.2", @@ -671,7 +674,7 @@ dependencies = [ [[package]] name = "enclave_cosmos_types" -version = "1.6.0" +version = "1.11.0" dependencies = [ "cosmos_proto", "cw_types_v010", @@ -690,7 +693,7 @@ dependencies = [ [[package]] name = "enclave_crypto" -version = "1.6.0" +version = "1.11.0" dependencies = [ "aes-siv", "cosmos_proto", @@ -715,9 +718,10 @@ dependencies = [ [[package]] name = "enclave_utils" -version = "1.6.0" +version = "1.11.0" dependencies = [ "enclave-ffi-types", + "enclave_crypto", "lazy_static", "log", "serde 1.0.118", @@ -1188,6 +1192,12 @@ version = "0.41.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ddfc878dac00da22f8f61e7af3157988424567ab01d9920b962ef7dcbd7cd865" +[[package]] +name = "parity-wasm" +version = "0.45.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e1ad0aff30c1da14b1254fcb2af73e1fa9a28670e584a626f53a369d0e157304" + [[package]] name = "paste" version = "1.0.11" @@ -1326,7 +1336,7 @@ checksum = "4f7a12f176deee919f4ba55326ee17491c8b707d0987aed822682c821b660192" dependencies = [ "byteorder", "log", - "parity-wasm", + "parity-wasm 0.41.0", ] [[package]] @@ -1532,12 +1542,13 @@ dependencies = [ [[package]] name = "secret-enclave" -version = "1.6.0" +version = "1.11.0" dependencies = [ "base64 0.13.0 (git+https://github.com/mesalock-linux/rust-base64-sgx?rev=dc7389e10817b078f289386b3b6a852ab6c4c021)", "bit-vec", "block-verifier", "chrono", + "cosmos-sdk-proto", "ctor", "derive_more", "enclave-ffi-types", @@ -1547,11 +1558,12 @@ dependencies = [ "enclave_utils", "hex", "httparse", + "integer-encoding", "itertools 0.8.2", "lazy_static", "log", "num-bigint", - "parity-wasm", + "parity-wasm 0.45.0", "pwasm-utils", "read-verifier", "rustls", @@ -1563,6 +1575,7 @@ dependencies = [ "sgx_tstd", "sgx_types", "simple_logger", + "tendermint", "time", "uuid", "webpki", @@ -1570,20 +1583,6 @@ dependencies = [ "yasna", ] -[[package]] -name = "secret-query-enclave" -version = "1.4.0" -dependencies = [ - "ctor", - "enclave_contract_engine", - "enclave_utils", - "lazy_static", - "log", - "sgx_tstd", - "sgx_types", - "simple_logger", -] - [[package]] name = "semver" version = "1.0.14" @@ -1673,11 +1672,11 @@ dependencies = [ [[package]] name = "sgx_alloc" -version = "1.1.5" +version = "1.1.6" [[package]] name = "sgx_backtrace_sys" -version = "1.1.5" +version = "1.1.6" dependencies = [ "cc", "sgx_build_helper", @@ -1686,22 +1685,22 @@ dependencies = [ [[package]] name = "sgx_build_helper" -version = "1.1.5" +version = "1.1.6" [[package]] name = "sgx_demangle" -version = "1.1.5" +version = "1.1.6" [[package]] name = "sgx_libc" -version = "1.1.5" +version = "1.1.6" dependencies = [ "sgx_types", ] [[package]] name = "sgx_rand" -version = "1.1.5" +version = "1.1.6" dependencies = [ "sgx_trts", "sgx_tstd", @@ -1710,14 +1709,14 @@ dependencies = [ [[package]] name = "sgx_tcrypto" -version = "1.1.5" +version = "1.1.6" dependencies = [ "sgx_types", ] [[package]] name = "sgx_tprotected_fs" -version = "1.1.5" +version = "1.1.6" dependencies = [ "sgx_trts", "sgx_types", @@ -1725,7 +1724,7 @@ dependencies = [ [[package]] name = "sgx_trts" -version = "1.1.5" +version = "1.1.6" dependencies = [ "sgx_libc", "sgx_types", @@ -1733,14 +1732,14 @@ dependencies = [ [[package]] name = "sgx_tse" -version = "1.1.5" +version = "1.1.6" dependencies = [ "sgx_types", ] [[package]] name = "sgx_tstd" -version = "1.1.5" +version = "1.1.6" dependencies = [ "hashbrown_tstd", "sgx_alloc", @@ -1755,11 +1754,11 @@ dependencies = [ [[package]] name = "sgx_types" -version = "1.1.5" +version = "1.1.6" [[package]] name = "sgx_unwind" -version = "1.1.5" +version = "1.1.6" dependencies = [ "sgx_build_helper", ] @@ -2184,7 +2183,7 @@ dependencies = [ "memory_units", "num-rational", "num-traits 0.2.15", - "parity-wasm", + "parity-wasm 0.41.0", "wasmi-validation", ] @@ -2193,7 +2192,7 @@ name = "wasmi-validation" version = "0.3.0" source = "git+https://github.com/paritytech/wasmi?rev=84d2764594d80425373bf4949a58fa3df3d624c3#84d2764594d80425373bf4949a58fa3df3d624c3" dependencies = [ - "parity-wasm", + "parity-wasm 0.41.0", ] [[package]] diff --git a/cosmwasm/enclaves/ffi-types/cbindgen.toml b/cosmwasm/enclaves/ffi-types/cbindgen.toml index da09dd914..6d90e397b 100644 --- a/cosmwasm/enclaves/ffi-types/cbindgen.toml +++ b/cosmwasm/enclaves/ffi-types/cbindgen.toml @@ -76,7 +76,7 @@ derive_gte = false rename_variants = "None" # must_use = "MUST_USE_ENUM" add_sentinel = false -prefix_with_name = false +prefix_with_name = true derive_helper_methods = false derive_const_casts = false derive_mut_casts = false diff --git a/cosmwasm/enclaves/shared/contract-engine/src/db.rs b/cosmwasm/enclaves/shared/contract-engine/src/db.rs index 44ef96395..53c992f8a 100644 --- a/cosmwasm/enclaves/shared/contract-engine/src/db.rs +++ b/cosmwasm/enclaves/shared/contract-engine/src/db.rs @@ -172,13 +172,7 @@ pub fn read_from_encrypted_state( &encrypted_key_bytes, block_height, ) { - Ok((maybe_encrypted_value_bytes, maybe_proof, maybe_mp_key, gas_used)) => { - debug!("merkle proof returned from read_db(): {:?}", maybe_proof); - debug!("full key returned from read_db(): {:?}", maybe_mp_key); - debug!( - "enc value returned from read_db(): {:?}", - maybe_encrypted_value_bytes - ); + Ok((maybe_encrypted_value_bytes, gas_used)) => { match maybe_encrypted_value_bytes { Some(encrypted_value_bytes) => { let encrypted_value: EncryptedValue = bincode2::deserialize(&encrypted_value_bytes).map_err(|err| { diff --git a/cosmwasm/enclaves/shared/contract-engine/src/wasm3/mod.rs b/cosmwasm/enclaves/shared/contract-engine/src/wasm3/mod.rs index 6d2999d9c..4f0a7f988 100644 --- a/cosmwasm/enclaves/shared/contract-engine/src/wasm3/mod.rs +++ b/cosmwasm/enclaves/shared/contract-engine/src/wasm3/mod.rs @@ -648,11 +648,11 @@ impl Engine { debug!("Before saving to cache"); // store kv cache into the block cache - if we access this key later in the block we will want to let mut block_cache = BLOCK_CACHE.lock().unwrap(); - block_cache.insert(self.context.contract_key, self.context.kv_cache.clone()); + block_cache.insert(self.context.og_contract_key, self.context.kv_cache.clone()); debug!("After saving to cache"); - let keys: Vec<(Vec, Vec)> = self + let mut keys: Vec<(Vec, Vec)> = self .context .kv_cache .flush() @@ -936,7 +936,7 @@ fn host_read_db( let block_cache = BLOCK_CACHE.lock().unwrap(); - if let Some(kv_cache) = block_cache.get(&context.contract_key) { + if let Some(kv_cache) = block_cache.get(&context.og_contract_key) { if let Some(unwrapped) = kv_cache.read(&state_key_name) { debug!("Got value from cache"); let ptr_to_region_in_wasm_vm = @@ -1006,7 +1006,7 @@ fn host_remove_db( context.kv_cache.remove(&state_key_name); let mut block_cache = BLOCK_CACHE.lock().unwrap(); - block_cache.remove_from_kv_cache(&context.contract_key, &state_key_name); + block_cache.remove_from_kv_cache(&context.og_contract_key, &state_key_name); let used_gas = remove_from_encrypted_state(&state_key_name, &context.context, &context.og_contract_key)?; diff --git a/go-cosmwasm/api/lib.go b/go-cosmwasm/api/lib.go index 87430479e..56f566c3c 100644 --- a/go-cosmwasm/api/lib.go +++ b/go-cosmwasm/api/lib.go @@ -223,7 +223,7 @@ func UpdateAdmin( code_id []byte, params []byte, gasMeter *GasMeter, - store KVStore, + store sdk.KVStore, api *GoAPI, querier *Querier, gasLimit uint64, @@ -277,7 +277,7 @@ func Instantiate( params []byte, msg []byte, gasMeter *GasMeter, - store KVStore, + store sdk.KVStore, api *GoAPI, querier *Querier, gasLimit uint64, diff --git a/go.mod b/go.mod index c5c91edd5..ac6b7f0f1 100644 --- a/go.mod +++ b/go.mod @@ -4,7 +4,7 @@ go 1.21 replace ( github.com/cometbft/cometbft => github.com/scrtlabs/tendermint v1.9.0-scrt.0.20230802144651-d62916253d52 - github.com/cosmos/cosmos-sdk => github.com/scrtlabs/cosmos-sdk v0.45.13-0.20230802150248-ea64f27dc58d + github.com/cosmos/cosmos-sdk => github.com/scrtlabs/cosmos-sdk v0.45.13-0.20231031173040-27822360f460 // Fix OSX Ledger Connection Issues - Premerged https://github.com/cosmos/ledger-cosmos-go/pull/36/files github.com/cosmos/ledger-cosmos-go => github.com/chillyvee/ledger-cosmos-go v0.12.2 github.com/gogo/protobuf => github.com/regen-network/protobuf v1.3.3-alpha.regen.1 diff --git a/go.sum b/go.sum index 2d867262b..cd9f36d1e 100644 --- a/go.sum +++ b/go.sum @@ -934,8 +934,8 @@ github.com/sasha-s/go-deadlock v0.3.1 h1:sqv7fDNShgjcaxkO0JNcOAlr8B9+cV5Ey/OB71e github.com/sasha-s/go-deadlock v0.3.1/go.mod h1:F73l+cr82YSh10GxyRI6qZiCgK64VaZjwesgfQ1/iLM= github.com/schollz/closestmatch v2.1.0+incompatible/go.mod h1:RtP1ddjLong6gTkbtmuhtR2uUrrJOpYzYRvbcPAid+g= github.com/sclevine/agouti v3.0.0+incompatible/go.mod h1:b4WX9W9L1sfQKXeJf1mUTLZKJ48R1S7H23Ji7oFO5Bw= -github.com/scrtlabs/cosmos-sdk v0.45.13-0.20230802150248-ea64f27dc58d h1:J52TETA52GtOOCBYPfmZoOOSM7Nr/GjhsH6RvdaHKMU= -github.com/scrtlabs/cosmos-sdk v0.45.13-0.20230802150248-ea64f27dc58d/go.mod h1:kOvNW8eRcR6zcO9yEfDa+iexTXdb+/QxHL1OqSEqfAo= +github.com/scrtlabs/cosmos-sdk v0.45.13-0.20231031173040-27822360f460 h1:Jk4ieH8h6Zbv0zZkDEHxkwJn8pRvjc1+rylkn7FX5f0= +github.com/scrtlabs/cosmos-sdk v0.45.13-0.20231031173040-27822360f460/go.mod h1:kOvNW8eRcR6zcO9yEfDa+iexTXdb+/QxHL1OqSEqfAo= github.com/scrtlabs/tendermint v1.9.0-scrt.0.20230802144651-d62916253d52 h1:25rvoh2dQgzOOGPj/t1tPKApeeRrcUZtQXZ6wu6mE54= github.com/scrtlabs/tendermint v1.9.0-scrt.0.20230802144651-d62916253d52/go.mod h1:H9SALxhCLtq/RwZLDUo/A7q7ri4GSDeZzJDx/mqA23E= github.com/scrtlabs/tm-secret-enclave v1.11.1 h1:UFPMS8XGrgx0SVTcHF0JmM/7nw17sQRMJ3PCg6rlGQA= From 616819352129119bb801ed16304213cdd21af7b3 Mon Sep 17 00:00:00 2001 From: Cashmaney Date: Wed, 1 Nov 2023 14:09:21 +0700 Subject: [PATCH 50/51] Fix all the stuff I broke :( --- cosmwasm/enclaves/execute/Enclave.edl | 12 ++-- cosmwasm/enclaves/execute/src/ecalls.rs | 92 ++++++++++++------------- cosmwasm/packages/sgx-vm/src/proofs.rs | 46 +++++-------- go-cosmwasm/api/callbacks.go | 2 +- 4 files changed, 71 insertions(+), 81 deletions(-) diff --git a/cosmwasm/enclaves/execute/Enclave.edl b/cosmwasm/enclaves/execute/Enclave.edl index 6584f3909..90a9a6778 100644 --- a/cosmwasm/enclaves/execute/Enclave.edl +++ b/cosmwasm/enclaves/execute/Enclave.edl @@ -169,12 +169,12 @@ enclave { ); - public sgx_status_t ecall_submit_store_roots( - [in, count=in_roots_len] const uint8_t* in_roots, - uintptr_t in_roots_len, - [in, count=in_compute_root_len] const uint8_t* in_compute_root, - uintptr_t in_compute_root_len - ); + //public sgx_status_t ecall_submit_store_roots( + // [in, count=in_roots_len] const uint8_t* in_roots, + // uintptr_t in_roots_len, + // [in, count=in_compute_root_len] const uint8_t* in_compute_root, + // uintptr_t in_compute_root_len + //); }; diff --git a/cosmwasm/enclaves/execute/src/ecalls.rs b/cosmwasm/enclaves/execute/src/ecalls.rs index 266515c95..117808cdd 100644 --- a/cosmwasm/enclaves/execute/src/ecalls.rs +++ b/cosmwasm/enclaves/execute/src/ecalls.rs @@ -55,52 +55,52 @@ pub unsafe extern "C" fn ecall_submit_block_signatures( sgx_status_t::SGX_ERROR_ECALL_NOT_ALLOWED } } - -#[no_mangle] -#[allow(unused_variables)] -pub unsafe extern "C" fn ecall_submit_store_roots( - in_roots: *const u8, - in_roots_len: u32, - in_compute_root: *const u8, - in_compute_root_len: u32, -) -> sgx_status_t { - let failed_call = || sgx_status_t::SGX_ERROR_INVALID_PARAMETER; - - validate_input_length!(in_roots_len, "roots", MAX_ROOTS_LENGTH, failed_call()); - validate_const_ptr!( - in_roots, - in_roots_len as usize, - sgx_status_t::SGX_ERROR_INVALID_PARAMETER - ); - validate_input_length!( - in_compute_root_len, - "compute_root", - MAX_MERKLE_ROOT_LENGTH, - failed_call() - ); - validate_const_ptr!( - in_compute_root, - in_compute_root_len as usize, - sgx_status_t::SGX_ERROR_INVALID_PARAMETER - ); - - let store_roots_slice = slice::from_raw_parts(in_roots, in_roots_len as usize); - let compute_root_slice = slice::from_raw_parts(in_compute_root, in_compute_root_len as usize); - - let store_roots: Pairs = Pairs::decode(store_roots_slice).unwrap(); - let mut store_roots_bytes = vec![]; - - // Encode all key-value pairs to bytes - for root in store_roots.pairs { - store_roots_bytes.push(pair_to_bytes(root)); - } - - let h = merkle::simple_hash_from_byte_vectors(store_roots_bytes); - debug!("received app_hash: {:?}", h); - debug!("received compute_root: {:?}", compute_root_slice); - - sgx_status_t::SGX_SUCCESS -} +// +// #[no_mangle] +// #[allow(unused_variables)] +// pub unsafe extern "C" fn ecall_submit_store_roots( +// in_roots: *const u8, +// in_roots_len: u32, +// in_compute_root: *const u8, +// in_compute_root_len: u32, +// ) -> sgx_status_t { +// let failed_call = || sgx_status_t::SGX_ERROR_INVALID_PARAMETER; +// +// validate_input_length!(in_roots_len, "roots", MAX_ROOTS_LENGTH, failed_call()); +// validate_const_ptr!( +// in_roots, +// in_roots_len as usize, +// sgx_status_t::SGX_ERROR_INVALID_PARAMETER +// ); +// validate_input_length!( +// in_compute_root_len, +// "compute_root", +// MAX_MERKLE_ROOT_LENGTH, +// failed_call() +// ); +// validate_const_ptr!( +// in_compute_root, +// in_compute_root_len as usize, +// sgx_status_t::SGX_ERROR_INVALID_PARAMETER +// ); +// +// let store_roots_slice = slice::from_raw_parts(in_roots, in_roots_len as usize); +// let compute_root_slice = slice::from_raw_parts(in_compute_root, in_compute_root_len as usize); +// +// let store_roots: Pairs = Pairs::decode(store_roots_slice).unwrap(); +// let mut store_roots_bytes = vec![]; +// +// // Encode all key-value pairs to bytes +// for root in store_roots.pairs { +// store_roots_bytes.push(pair_to_bytes(root)); +// } +// +// let h = merkle::simple_hash_from_byte_vectors(store_roots_bytes); +// debug!("received app_hash: {:?}", h); +// debug!("received compute_root: {:?}", compute_root_slice); +// +// sgx_status_t::SGX_SUCCESS +// } // This is a copy of a cosmos-sdk function: https://github.com/scrtlabs/cosmos-sdk/blob/1b9278476b3ac897d8ebb90241008476850bf212/store/internal/maps/maps.go#LL152C1-L152C1 // Returns key || value, with both the key and value length prefixed. diff --git a/cosmwasm/packages/sgx-vm/src/proofs.rs b/cosmwasm/packages/sgx-vm/src/proofs.rs index e90d1f455..b9bb50362 100644 --- a/cosmwasm/packages/sgx-vm/src/proofs.rs +++ b/cosmwasm/packages/sgx-vm/src/proofs.rs @@ -5,10 +5,12 @@ use log::{debug, error, warn}; use crate::enclave::ENCLAVE_DOORBELL; +const RETRY_LIMIT: i32 = 3; + extern "C" { - pub fn ecall_submit_store_roots( + pub fn ecall_app_begin_blocker( eid: sgx_enclave_id_t, - retval: *mut sgx_status_t, + retval: *mut SdkBeginBlockerResult, in_roots: *const u8, in_roots_len: u32, in_compute_root: *const u8, @@ -19,41 +21,29 @@ extern "C" { pub fn untrusted_submit_store_roots(roots: &[u8], compute_root: &[u8]) -> SgxResult<()> { debug!("Hello from just before - untrusted_submit_store_roots"); - const RETRY_LIMIT: i32 = 3; - - let mut retry_count = 0; - - // this is here so we can - loop { + for _ in 0..RETRY_LIMIT { let (retval, status) = submit_store_roots_impl(roots, compute_root)?; + if status != sgx_status_t::SGX_SUCCESS { return Err(status); - } else if retval != sgx_status_t::SGX_SUCCESS { - if retval == sgx_status_t::SGX_ERROR_FILE_RECOVERY_NEEDED { - warn!( - "Validator set read by enclave was mismatched with current height.. retrying" - ); - // retry with - std::thread::sleep(std::time::Duration::from_millis(500)); - retry_count += 1; - - if retry_count == RETRY_LIMIT { - error!("Validator timed out while waiting for correct validator set"); - return Err(retval); - } - } else { - return Err(retval); - } - } else { + } else if retval == SdkBeginBlockerResult::Success { return Ok(()); + } else if retval == SdkBeginBlockerResult::Failure { + warn!("Validator set read by enclave was mismatched with current height.. retrying"); + std::thread::sleep(std::time::Duration::from_millis(500)); + } else { + return Err(sgx_status_t::SGX_ERROR_UNEXPECTED); } } + + error!("Validator timed out while waiting for correct validator set"); + Err(sgx_status_t::SGX_ERROR_UNEXPECTED) // or any appropriate error } fn submit_store_roots_impl( roots: &[u8], compute_root: &[u8], -) -> SgxResult<(sgx_status_t, sgx_status_t)> { +) -> SgxResult<(SdkBeginBlockerResult, sgx_status_t)> { // Bind the token to a local variable to ensure its // destructor runs in the end of the function let enclave_access_token = ENCLAVE_DOORBELL @@ -62,11 +52,11 @@ fn submit_store_roots_impl( let enclave = (*enclave_access_token)?; let eid = enclave.geteid(); - let mut retval = sgx_status_t::SGX_SUCCESS; + let mut retval = SdkBeginBlockerResult::Success; // let status = unsafe { ecall_get_encrypted_seed(eid, &mut retval, cert, cert_len, & mut seed) }; let status = unsafe { - ecall_submit_store_roots( + ecall_app_begin_blocker( eid, &mut retval, roots.as_ptr(), diff --git a/go-cosmwasm/api/callbacks.go b/go-cosmwasm/api/callbacks.go index 71bbcba16..4add136fb 100644 --- a/go-cosmwasm/api/callbacks.go +++ b/go-cosmwasm/api/callbacks.go @@ -171,7 +171,7 @@ func cGetNoProof(ptr *C.db_t, gasMeter *C.gas_meter_t, usedGas *u64, key C.Buffe } //export cGet -func cGet(ptr *C.db_t, gasMeter *C.gas_meter_t, usedGas *u64, block_height u64, key C.Buffer, val *C.Buffer, merkle_p *C.Buffer, mp_key *C.Buffer, errOut *C.Buffer) (ret C.GoResult) { +func cGet(ptr *C.db_t, gasMeter *C.gas_meter_t, usedGas *u64, block_height u64, key C.Buffer, val *C.Buffer, merkle_p *C.Buffer, mp_key *C.Buffer, _ *C.Buffer) (ret C.GoResult) { defer recoverPanic(&ret) if ptr == nil || gasMeter == nil || usedGas == nil || val == nil { // we received an invalid pointer From 72b87f7d4924f004b3600a2230a7e745cd942f73 Mon Sep 17 00:00:00 2001 From: Cashmaney Date: Wed, 1 Nov 2023 14:10:40 +0700 Subject: [PATCH 51/51] Fix all the stuff I broke :( --- cosmwasm/enclaves/execute/src/ecalls.rs | 78 ------------------------- 1 file changed, 78 deletions(-) diff --git a/cosmwasm/enclaves/execute/src/ecalls.rs b/cosmwasm/enclaves/execute/src/ecalls.rs index 117808cdd..40db781d6 100644 --- a/cosmwasm/enclaves/execute/src/ecalls.rs +++ b/cosmwasm/enclaves/execute/src/ecalls.rs @@ -1,14 +1,4 @@ -use cosmos_sdk_proto::cosmos::base::kv::v1beta1::{Pair, Pairs}; -use cosmos_sdk_proto::traits::Message; -use enclave_utils::{validate_const_ptr, validate_input_length}; -use integer_encoding::VarInt; -use log::{debug, error}; use sgx_types::sgx_status_t; -use std::slice; -use tendermint::merkle; - -const MAX_MERKLE_ROOT_LENGTH: u32 = 32; -const MAX_ROOTS_LENGTH: u32 = 20 * MAX_MERKLE_ROOT_LENGTH; /// # Safety /// This function reads buffers which must be correctly initialized by the caller, @@ -55,71 +45,3 @@ pub unsafe extern "C" fn ecall_submit_block_signatures( sgx_status_t::SGX_ERROR_ECALL_NOT_ALLOWED } } -// -// #[no_mangle] -// #[allow(unused_variables)] -// pub unsafe extern "C" fn ecall_submit_store_roots( -// in_roots: *const u8, -// in_roots_len: u32, -// in_compute_root: *const u8, -// in_compute_root_len: u32, -// ) -> sgx_status_t { -// let failed_call = || sgx_status_t::SGX_ERROR_INVALID_PARAMETER; -// -// validate_input_length!(in_roots_len, "roots", MAX_ROOTS_LENGTH, failed_call()); -// validate_const_ptr!( -// in_roots, -// in_roots_len as usize, -// sgx_status_t::SGX_ERROR_INVALID_PARAMETER -// ); -// validate_input_length!( -// in_compute_root_len, -// "compute_root", -// MAX_MERKLE_ROOT_LENGTH, -// failed_call() -// ); -// validate_const_ptr!( -// in_compute_root, -// in_compute_root_len as usize, -// sgx_status_t::SGX_ERROR_INVALID_PARAMETER -// ); -// -// let store_roots_slice = slice::from_raw_parts(in_roots, in_roots_len as usize); -// let compute_root_slice = slice::from_raw_parts(in_compute_root, in_compute_root_len as usize); -// -// let store_roots: Pairs = Pairs::decode(store_roots_slice).unwrap(); -// let mut store_roots_bytes = vec![]; -// -// // Encode all key-value pairs to bytes -// for root in store_roots.pairs { -// store_roots_bytes.push(pair_to_bytes(root)); -// } -// -// let h = merkle::simple_hash_from_byte_vectors(store_roots_bytes); -// debug!("received app_hash: {:?}", h); -// debug!("received compute_root: {:?}", compute_root_slice); -// -// sgx_status_t::SGX_SUCCESS -// } - -// This is a copy of a cosmos-sdk function: https://github.com/scrtlabs/cosmos-sdk/blob/1b9278476b3ac897d8ebb90241008476850bf212/store/internal/maps/maps.go#LL152C1-L152C1 -// Returns key || value, with both the key and value length prefixed. -fn pair_to_bytes(kv: Pair) -> Vec { - // In the worst case: - // * 8 bytes to Uvarint encode the length of the key - // * 8 bytes to Uvarint encode the length of the value - // So preallocate for the worst case, which will in total - // be a maximum of 14 bytes wasted, if len(key)=1, len(value)=1, - // but that's going to rare. - let mut buf = vec![]; - - // Encode the key, prefixed with its length. - buf.extend_from_slice(&(kv.key.len()).encode_var_vec()); - buf.extend_from_slice(&kv.key); - - // Encode the value, prefixing with its length. - buf.extend_from_slice(&(kv.value.len()).encode_var_vec()); - buf.extend_from_slice(&kv.value); - - buf -}