<commit_before># -*- encoding : ascii-8bit -*-

require 'forwardable'

module Ethereum

  ##
  # External calls that can be made from inside the VM. To use the EVM with a
  # different blockchain system, database, set parameters for testing, just
  # swap out the functions here.
  #
  class ExternalCall

    extend Forwardable
    def_delegators :@block, :get_code, :get_balance, :set_balance, :get_storage_data, :set_storage_data, :add_refund, :account_exists

    def initialize(block, tx)
      @block = block
      @tx = tx
    end

    def log_storage(x)
      @block.account_to_dict(x)[:storage]
    end

    def add_suicide(x)
      @block.suicides.push x
    end

    def block_hash(x)
      d = @block.number - x
      if d > 0 && d <= 256
        @block.get_ancestor_hash d
      else
        Constant::BYTE_EMPTY
      end
    end

    def block_coinbase
      @block.coinbase
    end

    def block_timestamp
      @block.timestamp
    end

    def block_number
      @block.number
    end

    def block_difficulty
      @block.difficulty
    end

    def block_gas_limit
      @block.gas_limit
    end

    def log(addr, topics, data)
      @block.add_log Log.new(addr, topics, data)
    end

    def tx_origin
      @tx.sender
    end

    def tx_gasprice
      @tx.gasprice
    end

    def post_homestead_hardfork
      @block.number >= @block.config[:homestead_fork_blknum]
    end

    def create(msg)
      sender = Utils.normalize_address(msg.sender, allow_blank: true)

      @block.increment_nonce msg.sender if tx_origin != msg.sender

      nonce = Utils.encode_int(@block.get_nonce(msg.sender) - 1)
      msg.to = Utils.mk_contract_address sender, nonce

      balance = get_balance(msg.to)
      if balance > 0
        set_balance msg.to, balance
        @block.set_nonce msg.to, 0
        @block.set_code msg.to, Constant::BYTE_EMPTY
        @block.reset_storage msg.to
      end

      msg.is_create = true

      code = msg.data.extract_all
      msg.data = VM::CallData.new [], 0, 0

      res, gas, dat = apply_msg msg, code

      if res.true?
        return 1, gas, msg.to if dat.empty?

        gcost = dat.size * Opcodes::GCONTRACTBYTE
        if gas >= gcost
          gas -= gcost
        else
          dat = []

          if @block.number >= @block.config[:homestead_fork_blknum]
            return 0, 0, Constant::BYTE_EMPTY
          end

          log_msg.debug "CONTRACT creation oog have=#{gas} want=#{gcost}"
        end

        @block.set_code msg.to, Utils.int_array_to_bytes(dat)
        return 1, gas, msg.to
      else
        return 0, gas, Constant::BYTE_EMPTY<commit_msg>no contract created on OOG<commit_after># -*- encoding : ascii-8bit -*-

require 'forwardable'

module Ethereum

  ##
  # External calls that can be made from inside the VM. To use the EVM with a
  # different blockchain system, database, set parameters for testing, just
  # swap out the functions here.
  #
  class ExternalCall

    extend Forwardable
    def_delegators :@block, :get_code, :get_balance, :set_balance, :get_storage_data, :set_storage_data, :add_refund, :account_exists

    def initialize(block, tx)
      @block = block
      @tx = tx
    end

    def log_storage(x)
      @block.account_to_dict(x)[:storage]
    end

    def add_suicide(x)
      @block.suicides.push x
    end

    def block_hash(x)
      d = @block.number - x
      if d > 0 && d <= 256
        @block.get_ancestor_hash d
      else
        Constant::BYTE_EMPTY
      end
    end

    def block_coinbase
      @block.coinbase
    end

    def block_timestamp
      @block.timestamp
    end

    def block_number
      @block.number
    end

    def block_difficulty
      @block.difficulty
    end

    def block_gas_limit
      @block.gas_limit
    end

    def log(addr, topics, data)
      @block.add_log Log.new(addr, topics, data)
    end

    def tx_origin
      @tx.sender
    end

    def tx_gasprice
      @tx.gasprice
    end

    def post_homestead_hardfork
      @block.number >= @block.config[:homestead_fork_blknum]
    end

    def create(msg)
      sender = Utils.normalize_address(msg.sender, allow_blank: true)

      @block.increment_nonce msg.sender if tx_origin != msg.sender

      nonce = Utils.encode_int(@block.get_nonce(msg.sender) - 1)
      msg.to = Utils.mk_contract_address sender, nonce

      balance = get_balance(msg.to)
      if balance > 0
        set_balance msg.to, balance
        @block.set_nonce msg.to, 0
        @block.set_code msg.to, Constant::BYTE_EMPTY
        @block.reset_storage msg.to
      end

      msg.is_create = true

      code = msg.data.extract_all
      msg.data = VM::CallData.new [], 0, 0
      snapshot = @block.snapshot

      res, gas, dat = apply_msg msg, code

      if res.true?
        return 1, gas, msg.to if dat.empty?

        gcost = dat.size * Opcodes::GCONTRACTBYTE
        if gas >= gcost
          gas -= gcost
        else
          dat = []
          log_msg.debug "CONTRACT creation oog have=#{gas} want=#{gcost}"

          if @block.number >= @block.config[:homestead_fork_blknum]
            @block.revert snapshot
            return 0, 0, Constant::BYTE_EMPTY
          end
        end

        @block.set_code msg.to, Utils.int_array_to_bytes(dat)
        return 1, gas, msg.to
      else
        return 0, gas, Constant::BYTE_EMPTY
{'fraction_non_alphanumeric': 0.08901799100449775, 'fraction_numerical': 0.005622188905547227, 'mean_word_length': 2.182468694096601, 'pattern_counts': {'":': 0, '<': 5, '<?xml version=': 0, '>': 13, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '640392', 'n_tokens_mistral': 1823, 'n_tokens_neox': 1721, 'n_words': 445}