Sha256: 633e2915a96bbebd102f7f2d33ed1e5111e1b209842ceadbc8c909be69f9827f

Contents?: true

Size: 1.52 KB

Versions: 3

Compression:

Stored size: 1.52 KB

Contents

module Etherlite
  class NonceManager
    @@nonce_cache = {}
    @@nonce_mutex = Mutex.new

    def self.clear_cache
      @@nonce_cache = {}
    end

    def initialize(_connection)
      @connection = _connection
    end

    def last_nonce_for(_normalized_address)
      last_nonce = @@nonce_cache[_normalized_address]
      last_nonce = last_observed_nonce_for(_normalized_address) if last_nonce.nil?
      last_nonce
    end

    def with_next_nonce_for(_normalized_address, replace: false, nonce: nil)
      @@nonce_mutex.synchronize do
        return yield nonce if nonce.present?

        next_nonce = last_nonce_for(_normalized_address)
        next_nonce += 1 if next_nonce.negative? || !replace # if first tx, don't replace

        begin
          result = yield next_nonce
          @@nonce_cache[_normalized_address] = next_nonce if caching_enabled?
          return result
        rescue
          # if yield fails, cant be sure about transaction status so must rely again on observing.
          @@nonce_cache.delete _normalized_address if caching_enabled?
          raise
        end
      end
    end

    private

    def last_observed_nonce_for(_normalized_address)
      if @connection.use_parity
        @connection.parity_next_nonce('0x' + _normalized_address) - 1
      else
        # https://github.com/ethereum/go-ethereum/issues/2736
        @connection.eth_get_transaction_count('0x' + _normalized_address, 'pending') - 1
      end
    end

    def caching_enabled?
      Etherlite.config.enable_nonce_cache
    end
  end
end

Version data entries

3 entries across 3 versions & 1 rubygems

Version Path
etherlite-0.4.2 lib/etherlite/nonce_manager.rb
etherlite-0.4.1 lib/etherlite/nonce_manager.rb
etherlite-0.4.0 lib/etherlite/nonce_manager.rb