Repository: keep-starknet-strange/beerus
Pull request #311 (2023-03-20 18:24:17)

Addition of first ethereum endpoint: feat/ethereum_blockNumber
<!--- Please provide a general summary of your changes in the title above -->
Addition of first ethereum endpoint: feat/ethereum_blockNumber

# Pull Request type

<!-- Please try to limit your pull request to one type; submit multiple pull requests if needed. -->

Please check the type of change your PR introduces:

- [ ] Bugfix
- [X] Feature
- [ ] Code style update (formatting, renaming)
- [ ] Refactoring (no functional changes, no API changes)
- [ ] Build-related changes
- [ ] Documentation content changes
- [ ] Testing
- [ ] Other (please describe):

# What is the current behavior?
Ethereum endpoints are not implemented

<!-- Please describe the current behavior that you are modifying, or link to a relevant issue. -->

Issue Number: #290 

# What is the new behavior?

<!-- Please describe the behavior or changes that are being added by this PR. -->

The endpoint has been added + boilerplate to add other eth endpoints

# Does this introduce a breaking change?

- [ ] Yes
- [X] No

<!-- If this does introduce a breaking change, please describe the impact and migration path for existing applications below. -->

# Other information

<!-- Any other information that is important to this PR, such as screenshots of how the component looks before and after the change. -->

Addition of test boilerplate for eth endpoints is needed to be able to test these new endpoints


phklive: I have added the first eth_endpoint: ethereum_blockNumber, also i have renamed the existing endpoints to starknet_ to be able to defferentiate between eth and stark.

Next step would be to add tests.
drspacemn: If possible I prefer to keep the namespaced version of the RPC server. I’m fairly certain jsonrpsee allows you to extend the server methods with another namespace
phklive: Resolved conflicts, ready to merge 👍


Patch:
diff --git a/crates/beerus-rpc/src/api.rs b/crates/beerus-rpc/src/api.rs
index 1f58eed..b396500 100644
--- a/crates/beerus-rpc/src/api.rs
+++ b/crates/beerus-rpc/src/api.rs
@@ -59,87 +59,92 @@ impl From<BeerusApiError> for Error {
     }
 }
 
-#[rpc(server, client, namespace = "starknet")]
+#[rpc(server, client)]
 pub trait BeerusApi {
-    #[method(name = "l2_to_l1_messages")]
-    async fn l2_to_l1_messages(&self, msg_hash: U256) -> Result<U256, Error>;
+    // Ethereum endpoints
+    #[method(name = "ethereum_blockNumber")]
+    async fn ethereum_block_number(&self) -> Result<u64, Error>;
 
-    #[method(name = "chainId")]
-    async fn chain_id(&self) -> Result<String, Error>;
+    // Starknet endpoints
+    #[method(name = "starknet_l2_to_l1_messages")]
+    async fn starknet_l2_to_l1_messages(&self, msg_hash: U256) -> Result<U256, Error>;
 
-    #[method(name = "getNonce")]
-    async fn get_nonce(&self, contract_address: String) -> Result<String, Error>;
+    #[method(name = "starknet_chainId")]
+    async fn starknet_chain_id(&self) -> Result<String, Error>;
 
-    #[method(name = "blockNumber")]
-    async fn block_number(&self) -> Result<u64, Error>;
+    #[method(name = "starknet_getNonce")]
+    async fn starknet_get_nonce(&self, contract_address: String) -> Result<String, Error>;
 
-    #[method(name = "getBlockTransactionCount")]
-    async fn get_block_transaction_count(
+    #[method(name = "starknet_blockNumber")]
+    async fn starknet_block_number(&self) -> Result<u64, Error>;
+
+    #[method(name = "starknet_getBlockTransactionCount")]
+    async fn starknet_get_block_transaction_count(
         &self,
         block_id_type: String,
         block_id: String,
     ) -> Result<u64, Error>;
 
-    #[method(name = "getClassAt")]
-    async fn get_class_at(
+    #[method(name = "starknet_getClassAt")]
+    async fn starknet_get_class_at(
         &self,
         block_id_type: String,
         block_id: String,
         contract_address: String,
     ) -> Result<ContractClass, Error>;
 
-    #[method(name = "blockHashAndNumber")]
-    async fn block_hash_and_number(&self) -> Result<BlockHashAndNumber, Error>;
+    #[method(name = "starknet_blockHashAndNumber")]
+    async fn starknet_block_hash_and_number(&self) -> Result<BlockHashAndNumber, Error>;
 
-    #[method(name = "getBlockWithTxHashes")]
-    async fn get_block_with_tx_hashes(
+    #[method(name = "starknet_getBlockWithTxHashes")]
+    async fn starknet_get_block_with_tx_hashes(
         &self,
         block_id_type: String,
         block_id: String,
     ) -> Result<MaybePendingBlockWithTxHashes, Error>;
 
-    #[method(name = "getTransactionByBlockIdAndIndex")]
-    async fn get_transaction_by_block_id_and_index(
+    #[method(name = "starknet_getTransactionByBlockIdAndIndex")]
+    async fn starknet_get_transaction_by_block_id_and_index(
         &self,
         block_id_type: &str,
         block_id: &str,
         index: &str,
     ) -> Result<Transaction, Error>;
 
-    #[method(name = "getBlockWithTxs")]
-    async fn get_block_with_txs(
+    #[method(name = "starknet_getBlockWithTxs")]
+    async fn starknet_get_block_with_txs(
         &self,
         block_id_type: &str,
         block_id: &str,
     ) -> Result<MaybePendingBlockWithTxs, Error>;
 
-    #[method(name = "getStateUpdate")]
-    async fn get_state_update(
+    #[method(name = "starknet_getStateUpdate")]
+    async fn starknet_get_state_update(
         &self,
         block_id_type: String,
         block_id: String,
     ) -> Result<StateUpdate, Error>;
 
-    #[method(name = "syncing")]
-    async fn syncing(&self) -> Result<SyncStatusType, Error>;
+    #[method(name = "starknet_syncing")]
+    async fn starknet_syncing(&self) -> Result<SyncStatusType, Error>;
 
-    #[method(name = "l1_to_l2_messages")]
-    async fn l1_to_l2_messages(&self, msg_hash: U256) -> Result<U256, Error>;
+    #[method(name = "starknet_l1_to_l2_messages")]
+    async fn starknet_l1_to_l2_messages(&self, msg_hash: U256) -> Result<U256, Error>;
 
-    #[method(name = "l1_to_l2_message_nonce")]
-    async fn l1_to_l2_message_nonce(&self) -> Result<U256, Error>;
+    #[method(name = "starknet_l1_to_l2_message_nonce")]
+    async fn starknet_l1_to_l2_message_nonce(&self) -> Result<U256, Error>;
 
-    #[method(name = "l1_to_l2_message_cancellations")]
-    async fn l1_to_l2_message_cancellations(&self, msg_hash: U256) -> Result<U256, Error>;
+    #[method(name = "starknet_l1_to_l2_message_cancellations")]
+    async fn starknet_l1_to_l2_message_cancellations(&self, msg_hash: U256) -> Result<U256, Error>;
 
-    #[method(name = "getTransactionReceipt")]
-    async fn get_transaction_receipt(
+    #[method(name = "starknet_getTransactionReceipt")]
+    async fn starknet_get_transaction_receipt(
         &self,
         tx_hash: String,
     ) -> Result<MaybePendingTransactionReceipt, Error>;
 
-    #[method(name = "getClassHash")]
-    async fn get_class_hash(
+    #[method(name = "starknet_getClassHash")]
+    async fn starknet_get_class_hash(
         &self,
         block_id_type: String,
         block_id: String,
diff --git a/crates/beerus-rpc/src/lib.rs b/crates/beerus-rpc/src/lib.rs
index 819d96a..0f8a080 100644
--- a/crates/beerus-rpc/src/lib.rs
+++ b/crates/beerus-rpc/src/lib.rs
@@ -43,7 +43,19 @@ impl BeerusRpc {
 
 #[async_trait]
 impl BeerusApiServer for BeerusRpc {
-    async fn l2_to_l1_messages(&self, msg_hash: U256) -> Result<U256, Error> {
+    // Ethereum functions
+    async fn ethereum_block_number(&self) -> Result<u64, Error> {
+        self.beerus
+            .ethereum_lightclient
+            .read()
+            .await
+            .get_block_number()
+            .await
+            .map_err(|_| Error::from(BeerusApiError::BlockNotFound))
+    }
+
+    // Starknet functions
+    async fn starknet_l2_to_l1_messages(&self, msg_hash: U256) -> Result<U256, Error> {
         Ok(self
             .beerus
             .starknet_l2_to_l1_messages(msg_hash)
@@ -51,7 +63,7 @@ impl BeerusApiServer for BeerusRpc {
             .unwrap())
     }
 
-    async fn chain_id(&self) -> Result<String, Error> {
+    async fn starknet_chain_id(&self) -> Result<String, Error> {
         let chain_id = self
             .beerus
             .starknet_lightclient
@@ -63,7 +75,15 @@ impl BeerusApiServer for BeerusRpc {
         Ok(chain_id)
     }
 
-    async fn get_nonce(&self, contract_address: String) -> Result<String, Error> {
+    async fn starknet_block_number(&self) -> Result<u64, Error> {
+        self.beerus
+            .starknet_lightclient
+            .block_number()
+            .await
+            .map_err(|_| Error::from(BeerusApiError::BlockNotFound))
+    }
+
+    async fn starknet_get_nonce(&self, contract_address: String) -> Result<String, Error> {
         let contract_address = FieldElement::from_hex_be(&contract_address).unwrap();
         let nonce = self
             .beerus
@@ -74,18 +94,7 @@ impl BeerusApiServer for BeerusRpc {
         Ok(nonce)
     }
 
-    async fn block_number(&self) -> Result<u64, Error> {
-        let block_number = self
-            .beerus
-            .starknet_lightclient
-            .block_number()
-            .await
-            .unwrap();
-
-        Ok(block_number)
-    }
-
-    async fn get_block_transaction_count(
+    async fn starknet_get_block_transaction_count(
         &self,
         block_id_type: String,
         block_id: String,
@@ -101,7 +110,7 @@ impl BeerusApiServer for BeerusRpc {
         Ok(block_transaction_count)
     }
 
-    async fn block_hash_and_number(&self) -> Result<BlockHashAndNumber, Error> {
+    async fn starknet_block_hash_and_number(&self) -> Result<BlockHashAndNumber, Error> {
         Ok(self
             .beerus
             .starknet_lightclient
@@ -110,7 +119,7 @@ impl BeerusApiServer for BeerusRpc {
             .unwrap())
     }
 
-    async fn get_class_at(
+    async fn starknet_get_class_at(
         &self,
         block_id_type: String,
         block_id: String,
@@ -126,7 +135,7 @@ impl BeerusApiServer for BeerusRpc {
             .unwrap())
     }
 
-    async fn get_block_with_tx_hashes(
+    async fn starknet_get_block_with_tx_hashes(
         &self,
         block_id_type: String,
         block_id: String,
@@ -139,7 +148,7 @@ impl BeerusApiServer for BeerusRpc {
             .map_err(|_| Error::from(BeerusApiError::BlockNotFound))
     }
 
-    async fn get_transaction_by_block_id_and_index(
+    async fn starknet_get_transaction_by_block_id_and_index(
         &self,
         block_id_type: &str,
         block_id: &str,
@@ -161,7 +170,7 @@ impl BeerusApiServer for BeerusRpc {
         Ok(result)
     }
 
-    async fn get_block_with_txs(
+    async fn starknet_get_block_with_txs(
         &self,
         block_id_type: &str,
         block_id: &str,
@@ -180,7 +189,7 @@ impl BeerusApiServer for BeerusRpc {
         Ok(result)
     }
 
-    async fn get_state_update(
+    async fn starknet_get_state_update(
         &self,
         block_id_type: String,
         block_id: String,
@@ -194,12 +203,12 @@ impl BeerusApiServer for BeerusRpc {
             .unwrap())
     }
 
-    async fn syncing(&self) -> Result<SyncStatusType, Error> {
+    async fn starknet_syncing(&self) -> Result<SyncStatusType, Error> {
         let sync_status_type = self.beerus.starknet_lightclient.syncing().await.unwrap();
         Ok(sync_status_type)
     }
 
-    async fn l1_to_l2_messages(&self, msg_hash: U256) -> Result<U256, Error> {
+    async fn starknet_l1_to_l2_messages(&self, msg_hash: U256) -> Result<U256, Error> {
         Ok(self
             .beerus
             .starknet_l1_to_l2_messages(msg_hash)
@@ -207,12 +216,12 @@ impl BeerusApiServer for BeerusRpc {
             .unwrap())
     }
 
-    async fn l1_to_l2_message_nonce(&self) -> Result<U256, Error> {
+    async fn starknet_l1_to_l2_message_nonce(&self) -> Result<U256, Error> {
         let nonce = self.beerus.starknet_l1_to_l2_message_nonce().await.unwrap();
         Ok(nonce)
     }
 
-    async fn l1_to_l2_message_cancellations(&self, msg_hash: U256) -> Result<U256, Error> {
+    async fn starknet_l1_to_l2_message_cancellations(&self, msg_hash: U256) -> Result<U256, Error> {
         Ok(self
             .beerus
             .starknet_l1_to_l2_message_cancellations(msg_hash)
@@ -220,7 +229,7 @@ impl BeerusApiServer for BeerusRpc {
             .unwrap())
     }
 
-    async fn get_transaction_receipt(
+    async fn starknet_get_transaction_receipt(
         &self,
         tx_hash: String,
     ) -> Result<MaybePendingTransactionReceipt, Error> {
@@ -233,7 +242,7 @@ impl BeerusApiServer for BeerusRpc {
             .unwrap())
     }
 
-    async fn get_class_hash(
+    async fn starknet_get_class_hash(
         &self,
         block_id_type: String,
         block_id: String,
diff --git a/examples/beerus-rpc/ethereum_blockNumber.hurl b/examples/beerus-rpc/ethereum_blockNumber.hurl
new file mode 100644
index 0000000..ab79802
--- /dev/null
+++ b/examples/beerus-rpc/ethereum_blockNumber.hurl
@@ -0,0 +1,5 @@
+POST http://0.0.0.0:3030
+Content-Type: application/json
+{
+    "jsonrpc":"2.0","method":"ethereum_blockNumber","params":[],"id":1
+}


Test patch:
diff --git a/crates/beerus-rpc/tests/rpc.rs b/crates/beerus-rpc/tests/rpc.rs
index a7f6885..5fbf379 100644
--- a/crates/beerus-rpc/tests/rpc.rs
+++ b/crates/beerus-rpc/tests/rpc.rs
@@ -7,17 +7,17 @@ mod tests {
     use jsonrpsee::types::error::ErrorObjectOwned;
 
     #[tokio::test]
-    async fn block_number_ok() {
+    async fn starknet_block_number_ok() {
         let beerus_rpc = setup_beerus_rpc().await;
-        let block_number = beerus_rpc.block_number().await.unwrap();
+        let block_number = beerus_rpc.starknet_block_number().await.unwrap();
         assert_eq!(block_number, 19640);
     }
 
     #[tokio::test]
-    async fn block_transaction_count_ok() {
+    async fn starknet_block_transaction_count_ok() {
         let beerus_rpc = setup_beerus_rpc().await;
         let transaction_count = beerus_rpc
-            .get_block_transaction_count("tag".to_string(), "latest".to_string())
+            .starknet_get_block_transaction_count("tag".to_string(), "latest".to_string())
             .await
             .unwrap();
 
@@ -25,10 +25,10 @@ mod tests {
     }
 
     #[tokio::test]
-    async fn error_response_block_not_found() {
+    async fn starknet_error_response_block_not_found() {
         let beerus_rpc = setup_beerus_rpc().await;
         let err = beerus_rpc
-            .get_block_with_tx_hashes("number".to_string(), "22050".to_string())
+            .starknet_get_block_with_tx_hashes("number".to_string(), "22050".to_string())
             .await
             .unwrap_err();