code: def binary_gas_search(state: BaseState, transaction: BaseTransaction, tolerance: int=1) -> int:
      
      if not hasattr(transaction, 'sender'):
          raise TypeError(
              "Transaction is missing attribute sender.",
              "If sending an unsigned transaction, use SpoofTransaction and provide the",
              "sender using the 'from' parameter")
  
      minimum_transaction = SpoofTransaction(
          transaction,
          gas=transaction.intrinsic_gas,
          gas_price=0,
      )
  
      if _get_computation_error(state, minimum_transaction) is None:
          return transaction.intrinsic_gas
  
      maximum_transaction = SpoofTransaction(
          transaction,
          gas=state.gas_limit,
          gas_price=0,
      )
      error = _get_computation_error(state, maximum_transaction)
      if error is not None:
          raise error
  
      minimum_viable = state.gas_limit
      maximum_out_of_gas = transaction.intrinsic_gas
      while minimum_viable - maximum_out_of_gas > tolerance:
          midpoint = (minimum_viable + maximum_out_of_gas) // 2
          test_transaction = SpoofTransaction(transaction, gas=midpoint)
          if _get_computation_error(state, test_transaction) is None:
              minimum_viable = midpoint
          else:
              maximum_out_of_gas = midpoint
  
      return minimum_viable
docs: Run the transaction with various gas limits, progressively
      approaching the minimum needed to succeed without an OutOfGas exception.
  
      The starting range of possible estimates is:
      [transaction.intrinsic_gas, state.gas_limit].
      After the first OutOfGas exception, the range is: (largest_limit_out_of_gas, state.gas_limit].
      After the first run not out of gas, the range is: (largest_limit_out_of_gas, smallest_success].
  
      :param int tolerance: When the range of estimates is less than tolerance,
          return the top of the range.
      :returns int: The smallest confirmed gas to not throw an OutOfGas exception,
          subject to tolerance. If OutOfGas is thrown at block limit, return block limit.
      :raises VMError: if the computation fails even when given the block gas_limit to complete