Re-use dropped nonces

This commit is contained in:
Vitaliy Vlasov 2018-04-17 20:32:02 +03:00
parent b20bbb08cf
commit c6fadaad1a
No known key found for this signature in database
GPG Key ID: A7D57C347F2B2964
1 changed files with 34 additions and 24 deletions

View File

@ -53,28 +53,32 @@
(throw (ex-info "Make sure you provided proper credentials in appropriate resources/config.edn" (throw (ex-info "Make sure you provided proper credentials in appropriate resources/config.edn"
{:password password :file-path file-path})))))) {:password password :file-path file-path}))))))
(def highest-nonce (atom nil))
(def nonces-dropped (atom (clojure.lang.PersistentQueue/EMPTY)))
(defn get-nonce [] (defn get-nonce []
(let [current-nonce (atom nil)] (if (seq @nonces-dropped)
(fn [] (let [nonce (peek @nonces-dropped)]
(swap! nonces-dropped pop)
nonce)
(let [nonce (.. (.ethGetTransactionCount (create-web3j) (let [nonce (.. (.ethGetTransactionCount (create-web3j)
(env :eth-account) (env :eth-account)
DefaultBlockParameterName/LATEST) DefaultBlockParameterName/LATEST)
sendAsync sendAsync
get get
getTransactionCount)] getTransactionCount)]
(if (= nonce @current-nonce) (if (or (nil? @highest-nonce)
(throw (Exception. (str "Attempting to create transaction with the same nonce: " nonce))) (> nonce @highest-nonce))
(swap! current-nonce (constantly nonce))) (reset! highest-nonce nonce)
nonce)))) (swap! highest-nonce inc)))))
(def get-nonce-fn (get-nonce))
(defn get-signed-tx [gas-price gas-limit to data] (defn get-signed-tx [gas-price gas-limit to data nonce]
"Create a sign a raw transaction. "Create a sign a raw transaction.
'From' argument is not needed as it's already 'From' argument is not needed as it's already
encoded in credentials. encoded in credentials.
See https://web3j.readthedocs.io/en/latest/transactions.html#offline-transaction-signing" See https://web3j.readthedocs.io/en/latest/transactions.html#offline-transaction-signing"
(let [nonce (get-nonce-fn) (let [tx (RawTransaction/createTransaction
tx (RawTransaction/createTransaction
nonce nonce
gas-price gas-price
gas-limit gas-limit
@ -155,7 +159,7 @@
(cond (cond
;; Ignore any responses that have mismatching request ID ;; Ignore any responses that have mismatching request ID
(not= (:id result) request-id) (not= (:id result) request-id)
(log/error "Geth returned an invalid json-rpc request ID, ignoring response") (throw (ex-info "Geth returned an invalid json-rpc request ID, ignoring response"))
;; If request ID matches but contains error, throw ;; If request ID matches but contains error, throw
(:error result) (:error result)
@ -266,16 +270,22 @@
(merge {:to contract})) (merge {:to contract}))
gas (if gas-limit gas-limit gas (if gas-limit gas-limit
(estimate-gas from contract value params)) (estimate-gas from contract value params))
nonce (when (offline-signing?) (get-nonce))
params (if (offline-signing?) params (if (offline-signing?)
(get-signed-tx (biginteger gas-price) (get-signed-tx (biginteger gas-price)
(hex->big-integer gas) (hex->big-integer gas)
contract contract
data) data
nonce)
(assoc params :gas gas))] (assoc params :gas gas))]
(if (offline-signing?) (if (offline-signing?)
(try
(eth-rpc (eth-rpc
"eth_sendRawTransaction" "eth_sendRawTransaction"
[params]) [params])
(catch Throwable ex
(swap! nonces-dropped conj nonce)
(throw ex)))
(eth-rpc (eth-rpc
"personal_sendTransaction" "personal_sendTransaction"
[params (eth-password)])))) [params (eth-password)]))))