From 2d5c4e38926b0e0953ba52e82f67345e81b50d30 Mon Sep 17 00:00:00 2001 From: tbenr Date: Sat, 24 Nov 2018 21:42:16 +0100 Subject: [PATCH] fixes #6601 Signed-off-by: Julien Eluard --- src/status_im/extensions/core.cljs | 11 +++- src/status_im/extensions/ethereum.cljs | 59 ++++++++++++++++++- .../status_im/test/extensions/ethereum.cljs | 50 ++++++++++++++++ test/cljs/status_im/test/runner.cljs | 2 + 4 files changed, 120 insertions(+), 2 deletions(-) create mode 100644 test/cljs/status_im/test/extensions/ethereum.cljs diff --git a/src/status_im/extensions/core.cljs b/src/status_im/extensions/core.cljs index e8ea04fd13..a1e742be4a 100644 --- a/src/status_im/extensions/core.cljs +++ b/src/status_im/extensions/core.cljs @@ -305,7 +305,16 @@ :method? :string :params? :vector :nonce? :string - :on-result? :event}} + :on-result :event}} + 'ethereum/logs + {:permissions [:read] + :value :extensions/ethereum-logs + :arguments {:fromBlock? :string + :toBlock? :string + :address? :vector + :topics? :vector + :blockhash? :string + :on-result :event}} 'ethereum/call {:permissions [:read] :value :extensions/ethereum-call diff --git a/src/status_im/extensions/ethereum.cljs b/src/status_im/extensions/ethereum.cljs index dfcda4e650..d2fc505f9b 100644 --- a/src/status_im/extensions/ethereum.cljs +++ b/src/status_im/extensions/ethereum.cljs @@ -9,7 +9,10 @@ [status-im.utils.ethereum.abi-spec :as abi-spec] [status-im.utils.fx :as fx] [status-im.utils.handlers :as handlers] - [status-im.utils.money :as money])) + [status-im.utils.money :as money] + [clojure.string :as string] + [status-im.utils.types :as types] + [status-im.native-module.core :as status])) (handlers/register-handler-fx :extensions/transaction-on-result @@ -72,3 +75,57 @@ (abi-spec/decode (string/replace result-str #"0x" "") outputs) :else result-str)] (re-frame/dispatch (on-result (merge {:result result} (when %1 {:error %1})))))]}))) + +;; eth_getLogs implementation + +(defn- event-topic-enc [event params] + (let [eventid (str event "(" (string/join "," params) ")")] + (abi-spec/sha3 eventid))) + +(defn- types-mapping [type] + (cond + (= "bool" type) :bool + (string/starts-with? type "uint") :uint + (string/starts-with? type "int") :int + (string/starts-with? type "address") :address + (string/starts-with? type "bytes") :bytes + (string/starts-with? type "fixed") :bytes + :else :bytes)) + +(defn- values-topic-enc [type values] + (let [mapped-type (types-mapping type)] + (mapv #(str "0x" (abi-spec/enc {:type mapped-type :value %})) values))) + +(defn- parse-topic [t] + (cond + (or (nil? t) (string? t)) t ;; nil topic ;; immediate topic (extension encode topic by its own) ;; vector of immediate topics + (vector? t) (mapv parse-topic t) ;; descend in vector elements + (map? t) ;; simplified topic interface, we need to encode + (let [{:keys [event params type values]} t] + (cond + (some? event) (event-topic-enc event params);; event params topic + (some? type) (values-topic-enc type values) ;; indexed values topic + :else nil)) ;; error + :else nil)) + +(defn- ensure-hex-bn [block] + (cond + (nil? block) block + (re-matches #"^[0-9]+$" block) (str "0x" (abi-spec/number-to-hex block)) + :else block)) + +(handlers/register-handler-fx + :extensions/ethereum-logs + (fn [_ [_ _ {:keys [fromBlock toBlock address topics blockhash on-result]}]] + (let [parsed-topics (mapv parse-topic topics) + args {:jsonrpc "2.0" + :method constants/web3-get-logs + :params [{:fromBlock (ensure-hex-bn fromBlock) + :toBlock (ensure-hex-bn toBlock) + :address address + :topics parsed-topics + :blockhash blockhash}]} + payload (types/clj->json args)] + (status/call-private-rpc payload #(let [{:keys [error result]} (types/json->clj %1) + response (merge {:result result} (when error {:error error}))] + (re-frame/dispatch (on-result response))))))) \ No newline at end of file diff --git a/test/cljs/status_im/test/extensions/ethereum.cljs b/test/cljs/status_im/test/extensions/ethereum.cljs new file mode 100644 index 0000000000..13a4808312 --- /dev/null +++ b/test/cljs/status_im/test/extensions/ethereum.cljs @@ -0,0 +1,50 @@ +(ns status-im.test.extensions.ethereum + (:require [cljs.test :refer-macros [deftest is testing]] + [status-im.extensions.ethereum :as ethereum])) + +; ethereum/logs + +(deftest test-parse-topic-events + (testing "topic parsing check - events" + (is (= ["0xddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef" + "0x29f31b934498b0deabbe211b01cc30eee6475abf0f0d553e7eb8ca71deeb24b3"] + (ethereum/parse-topic [{:event "Transfer" :params ["address" "address" "uint256"]} + {:event "drawBet" :params ["uint256" "uint8" "int8" "address" "uint256"]}]))))) + +(deftest test-parse-topic-indexed-values-address + (testing "topic parsing check - indexed values address" + (is (= ["0x000000000000000000000000299b18709d4aacbda99048721448f65893a0c73a" + "0x00000000000000000000000094eaa5fa6b313968b2abd6da375ef28077d95d53"] + (ethereum/parse-topic {:type "address" :values ["0x299b18709d4aacbda99048721448f65893a0c73a" "0x94eaa5fa6b313968b2abd6da375ef28077d95d53"]}))))) + +(deftest test-parse-topic-indexed-values-uint256 + (testing "topic parsing check - indexed values uint256" + (is (= ["0x00000000000000000000000000000000000000000000000000000000000003fd" + "0x0000000000000000000000000000000000000000000000000000000000000078"] + (ethereum/parse-topic {:type "uint256" :values ["0x3fd" "120"]}))))) + +(deftest test-parse-topic-indexed-values-direct + (testing "topic parsing check - indexed values direct" + (is (= ["0x00000000000000000000000000000000000000000000000000000000000003fd" + "0x0000000000000000000000000000000000000000000000000000000000000078"] + (ethereum/parse-topic ["0x00000000000000000000000000000000000000000000000000000000000003fd" + "0x0000000000000000000000000000000000000000000000000000000000000078"]))))) + +(deftest test-parse-topic-indexed-nil + (testing "topic parsing check - nil" + (is (= ["0x00000000000000000000000000000000000000000000000000000000000003fd" + nil] + (ethereum/parse-topic ["0x00000000000000000000000000000000000000000000000000000000000003fd" + nil]))))) + +(deftest test-ensure-hex-bn-nonnumber + (is (= "latest" (ethereum/ensure-hex-bn "latest")))) + +(deftest test-ensure-hex-bn-int + (is (= "0xa" (ethereum/ensure-hex-bn "10")))) + +(deftest test-ensure-hex-bn-hex + (is (= "0xf" (ethereum/ensure-hex-bn "0xf")))) + +(deftest test-ensure-hex-bn-nil + (is (= nil (ethereum/ensure-hex-bn nil)))) \ No newline at end of file diff --git a/test/cljs/status_im/test/runner.cljs b/test/cljs/status_im/test/runner.cljs index cc72e68c37..4ff314dd0b 100644 --- a/test/cljs/status_im/test/runner.cljs +++ b/test/cljs/status_im/test/runner.cljs @@ -4,6 +4,7 @@ [status-im.test.data-store.chats] [status-im.test.data-store.realm.core] [status-im.test.extensions.core] + [status-im.test.extensions.ethereum] [status-im.test.browser.core] [status-im.test.browser.permissions] [status-im.test.wallet.subs] @@ -123,4 +124,5 @@ 'status-im.test.ui.screens.currency-settings.models 'status-im.test.ui.screens.wallet.db 'status-im.test.browser.core + 'status-im.test.extensions.ethereum 'status-im.test.browser.permissions)