diff --git a/move/sources/api.move b/move/sources/api.move index b1af451..fa89c74 100644 --- a/move/sources/api.move +++ b/move/sources/api.move @@ -5,6 +5,10 @@ module dtp::api { use dtp::kvalues::{Self}; use dtp::host::{Host}; + use dtp::transport_control::{TransportControl}; + use dtp::pipe::{Pipe}; + use dtp::inner_pipe::{InnerPipe}; + use dtp::conn_objects::{ConnObjects}; // === Friends === @@ -24,29 +28,149 @@ module dtp::api { // === Public-Friend Functions === // Functions to add services to an Host. - public entry fun add_service_ping(host: &mut Host, args: vector, ctx: &mut TxContext) : vector + // Cannot change the signature. Can you change the implementation? + + // WebApp Old Contract 1 <--- Still working with Contract 2, just by changing the address of the contract. + // New Contract 2 + // + // + // public: more composeable + // + // entry: Cannot be called by other packages. + // + // public entry: Callable from CLI, Explorer etc... + // + public fun add_service_ping(host: &mut Host, args: &vector, ctx: &mut TxContext) : vector { - let kvargs = kvalues::from_bytes(&args); + let kvargs = kvalues::from_bytes(args); let ret_value = dtp::api_impl::add_service_ping(host, &kvargs, ctx); kvalues::to_bytes(&ret_value) } // JSON-RPC 2.0 service - public entry fun add_service_json_rpc(host: &mut Host, args: vector, ctx: &mut TxContext) : vector + public fun add_service_json_rpc(host: &mut Host, args: &vector, ctx: &mut TxContext) : vector { - let kvargs = kvalues::from_bytes(&args); + let kvargs = kvalues::from_bytes(args); let ret_value = dtp::api_impl::add_service_json_rpc(host, &kvargs, ctx); kvalues::to_bytes(&ret_value) } - // Returns IDs of objects needed to start exchanging data (TransportControl, Pipes, InnerPipes...). - public entry fun open_connection(service_idx: u8, cli_host: &mut Host, srv_host: &mut Host, args: vector, ctx: &mut TxContext): (ConnObjects, vector) + // Attempt to open a bi-directional client/server connection. + // + // This operation is all on-chain, therefore there is no guarantee that the + // server is actually running. It is recommended to check first the health + // status of the server Host. + // + // Returns: + // IDs of all objects needed to start exchanging data (TransportControl, Pipes, InnerPipes...). + // (These IDs can also be recovered through slow discovery). + // + public fun open_connection(service_idx: u8, cli_host: &mut Host, srv_host: &mut Host, args: &vector, ctx: &mut TxContext): (ConnObjects, vector) { - let kvargs = kvalues::from_bytes(&args); + let kvargs = kvalues::from_bytes(args); let (conn_objects, ret_value) = dtp::api_impl::open_connection(service_idx, cli_host, srv_host, &kvargs, ctx); (conn_objects, kvalues::to_bytes(&ret_value)) } + // Transmit a request toward the server. + // + // The encoding of the 'data' depends on the service. + public fun send_request(service_idx: u8, data: &vector, args: &vector, ctx: &mut TxContext): vector + { + let kvargs = kvalues::from_bytes(args); + let ret_value = dtp::api_impl::send_request(service_idx, data, &kvargs, ctx); + kvalues::to_bytes(&ret_value) + } + + // Transmit a response toward the client. + // + // The encoding of the 'data' depends on the service. + public fun send_response(service_idx: u8, data: &vector, seq_number: u64, args: &vector, ctx: &mut TxContext): vector + { + let kvargs = kvalues::from_bytes(args); + let ret_value = dtp::api_impl::send_response(service_idx, data, seq_number, &kvargs, ctx); + kvalues::to_bytes(&ret_value) + } + + // Transmit a notification toward the peer (no response expected). + // + // The encoding of the 'data' depends on the service. + public fun send_notification(service_idx: u8, data: &vector, args: &vector, ctx: &mut TxContext): vector + { + let kvargs = kvalues::from_bytes(args); + let ret_value = dtp::api_impl::send_notification(service_idx, data, &kvargs, ctx); + kvalues::to_bytes(&ret_value) + } + + + // Sync Protocol + // + // Any end-point must perform the following two steps from time to time: + // 1) Call fast_sync_ipipe() for every owned ipipe with its related owned pipe. + // 2) Call slow_sync_pipe() for the owned pipe and shared transport control. + public fun fast_sync_ipipe(ipipe: &mut InnerPipe, pipe: &mut Pipe, args: &vector, ctx: &mut TxContext) : vector + { + let kvargs = kvalues::from_bytes(args); + let ret_value = dtp::api_impl::fast_sync_ipipe(ipipe, pipe, &kvargs, ctx); + kvalues::to_bytes(&ret_value) + } + + public fun slow_sync_pipe(pipe: &mut Pipe, tc: &mut TransportControl, args: &vector, ctx: &mut TxContext) : vector + { + let kvargs = kvalues::from_bytes(args); + let ret_value = dtp::api_impl::slow_sync_pipe(pipe, tc, &kvargs, ctx); + kvalues::to_bytes(&ret_value) + } + + + // Close of a connection. + // + // Closing of a connection should be done by both the client and server (in any order). + // + // Once a side initiate a closure, the other side will receive an event instructing to + // follow up with its own closure call. + // + // An half-closed connection is forced closed after a timeout (in the order of epochs). + // + // Upon normal first side closure: + // - The caller loose ownership of its Pipe and InnerPipes objects. These are transfered + // to a DTP DAO for security reason (prevent further transfer). The objects are eventually + // deleted after a fair data retention time. The DAO participants are rewarded with the + // storage fund recovered. + // + // - The caller will immediately be unable to send more data. The peer will *eventually* be + // blocked. Depending of the service, blocking will happen after a few epochs, MBytes or + // response/request limit reached. + // + // Upon normal second side closure: + // - Both sides will no longuer be able to transfer any data. + // - The escrow is run a last time with consideraton that both side followed the protocol. + // + // Upon half-closed connection timeout: + // - The escrow is run a last time with consideration that one side side failed to follow the protocol. + // - An endpoint cannot delete its Pipe and InnerPipes objects. They are instead to be + // transfered to the DTP DAO for disposal. + // + + public(friend) fun close_ipipe(ipipe: InnerPipe, pipe: &mut Pipe, args: &vector, ctx: &mut TxContext ) : vector { + let kvargs = kvalues::from_bytes(args); + let ret_value = dtp::api_impl::close_ipipe(ipipe, pipe, &kvargs, ctx); + kvalues::to_bytes(&ret_value) + } + + public(friend) fun close_pipe(pipe: &mut Pipe, tc: &mut TransportControl, args: &vector, ctx: &mut TxContext) : vector { + let kvargs = kvalues::from_bytes(args); + let ret_value = dtp::api_impl::close_pipe(pipe, tc, &kvargs, ctx); + kvalues::to_bytes(&ret_value) + } + + public fun close_connection(service_idx: u8, host: &mut Host, peer_host: &Host, tc: &mut TransportControl, args: &vector, ctx: &mut TxContext): vector + { + let kvargs = kvalues::from_bytes(args); + let ret_value = dtp::api_impl::close_connection(service_idx, host, peer_host, tc, &kvargs, ctx); + kvalues::to_bytes(&ret_value) + } + // === Private Functions === // === Test Functions === diff --git a/move/sources/api_impl.move b/move/sources/api_impl.move index 4ecfc99..44ce6cc 100644 --- a/move/sources/api_impl.move +++ b/move/sources/api_impl.move @@ -6,6 +6,9 @@ module dtp::api_impl { use dtp::host::{Host}; use dtp::transport_control::{Self}; use dtp::conn_objects::{Self,ConnObjects}; + use dtp::transport_control::{TransportControl}; + use dtp::pipe::{Pipe}; + use dtp::inner_pipe::{Self,InnerPipe}; use dtp::kvalues::{Self,KValues}; // === Friends === @@ -54,6 +57,58 @@ module dtp::api_impl { (conn, kvalues::new()) } + // Can this be replaced with a an array of _ipipe objects instead of calling multiple times? + public(friend) fun close_ipipe(ipipe: InnerPipe, _pipe: &mut Pipe, _kvargs: &KValues, _ctx: &mut TxContext ) : KValues { + inner_pipe::delete(ipipe); + kvalues::new() + } + + public(friend) fun close_pipe(_pipe: &mut Pipe, _tc: &mut TransportControl, _kvargs: &KValues, _ctx: &mut TxContext) : KValues { + kvalues::new() + } + + public(friend) fun close_connection(_service_idx: u8, _host: &mut Host, _peer_host: &Host, _tc: &mut TransportControl, _kvargs: &KValues, _ctx: &mut TxContext): KValues + { + kvalues::new() + } + + // Any end-point must perform the following two steps from time to time: + // 1) Call sync_ipipe() for every owned ipipe. + // 2) Call sync_pipe() for the owned pipe. + public(friend) fun fast_sync_ipipe(_ipipe: &mut InnerPipe, _pipe: &mut Pipe, _kvargs: &KValues, _ctx: &mut TxContext) : KValues + { + kvalues::new() + } + + public(friend) fun slow_sync_pipe(_pipe: &mut Pipe, _tc: &mut TransportControl, _kvargs: &KValues, _ctx: &mut TxContext) : KValues + { + kvalues::new() + } + + // Transmit a request toward the server. + // + // The encoding of the 'data' depends on the service. + public(friend) fun send_request(_service_idx: u8, _data: &vector, _kvargs: &KValues, _ctx: &mut TxContext): KValues + { + kvalues::new() + } + + // Transmit a response toward the client. + // + // The encoding of the 'data' depends on the service. + public(friend) fun send_response(_service_idx: u8, _data: &vector, _seq_number: u64, _kvargs: &KValues, _ctx: &mut TxContext): KValues + { + kvalues::new() + } + + // Transmit a notification toward the peer (no response expected). + // + // The encoding of the 'data' depends on the service. + public(friend) fun send_notification(_service_idx: u8, _data: &vector, _kvargs: &KValues, _ctx: &mut TxContext): KValues + { + kvalues::new() + } + // === Private Functions === // === Test Functions === diff --git a/move/sources/inner_pipe.move b/move/sources/inner_pipe.move index b06ac5b..a859bb8 100644 --- a/move/sources/inner_pipe.move +++ b/move/sources/inner_pipe.move @@ -18,6 +18,7 @@ module dtp::inner_pipe { // === Friends === friend dtp::host; friend dtp::pipe; + friend dtp::api_impl; #[test_only] friend dtp::tests_pipe;