оценка скорости выполнения различных опкодов в EVM

С помощью traceTransactionмы можем получить следующие данные:

debug.traceTransaction("0x0cec118d22fbd572bf25c7e4143919e608989bec7da08512f2a6f3171df3b3b8")
{
  gas: 104030,
  returnValue: "0000000000000000000000000000000000000000000000000000000000000001",
  structLogs: [{
      depth: 1,
      error: null,
      gas: 247189,
      gasCost: 3,
      memory: null,
      op: "PUSH1",
      pc: 0,
      stack: [],
      storage: {}
  }, {
      depth: 1,
      error: null,
      gas: 247186,
      gasCost: 3,
      memory: null,
      op: "PUSH1",
      pc: 2,
      stack: ["0000000000000000000000000000000000000000000000000000000000000060"],
      storage: {}
  }, 
...
  {
      depth: 1,
      error: null,
      gas: 165970,
      gasCost: 0,
      memory: ["0000000000000000000000000000000000000000000000000000000000000000", "0000000000000000000000000000000000000000000000000000000000000000", "00000000000000000000000000000000000000000000000000000000000000c0", "532e204d61747468657700000000000000000000000000000000000000000000", "456e676c69736800000000000000000000000000000000000000000000000000", "000000000000000000000000000000000000000000000000000000000000001c", "0000000000000000000000000000000000000000000000000000000000000001"],
      op: "RETURN",
      pc: 349,
      stack: ["00000000000000000000000000000000000000000000000000000000773b82a3", "0000000000000000000000000000000000000000000000000000000000000020", "00000000000000000000000000000000000000000000000000000000000000c0"],
      storage: {
        0000000000000000000000000000000000000000000000000000000000000000: "0000000000000000000000000000000000000000000000000000000000000001",
        290decd9548b62a8d60345a988386fc84ba6bc95484008f6362f93160ef3e563: "532e204d61747468657700000000000000000000000000000000000000000000",
        290decd9548b62a8d60345a988386fc84ba6bc95484008f6362f93160ef3e564: "456e676c69736800000000000000000000000000000000000000000000000000",
        290decd9548b62a8d60345a988386fc84ba6bc95484008f6362f93160ef3e565: "000000000000000000000000000000000000000000000000000000000000001c"
      }
  }]
}

Есть ли способ получить количество времени, которое требуется для opвыполнения каждого кода операции ( )?

Ответы (1)

Вы можете получить время выполнения каждого кода операции, изменив исходный файл и пересобрав, развернув его для тестирования. В файле инструкций есть все опкоды, что вам нужно сделать, это добавить журнал, это так просто. Следующим образом:

  1. Откройте локальный instructionsисходный файл и журнал добавления, который вы хотите знать, время выполнения для каждого кода операции. Например, я добавил лог для инструкции opAdd:

    func opAdd(pc *uint64, evm *EVM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) {
        var startTime = time.Now().UnixNano();
        x, y := stack.pop(), stack.pop()
        stack.push(math.U256(x.Add(x, y)))
        evm.interpreter.intPool.put(y)
        fmt.Println("execute opAdd consume = ",(time.Now().UnixNano() - startTime))
        return nil, nil
    }
    
  2. Восстановить. Сначала перейдите в папку go-ethereum и выполните make allкоманду в терминале. Если все в порядке, в каталоге build/bin была сгенерирована какая-то команда cmd.

  3. Бегать. выполнить команду gethдля перехода в консоль, а затем проверить результат изменения кода. Существует шесть операций opAdd для traceTransactionкоманды. execute opAdd consume = 186 execute opAdd consume = 141 execute opAdd consume = 107 execute opAdd consume = 92 execute opAdd consume = 127 execute opAdd consume = 289

Надеюсь, это поможет ~

этот подход потрясающий, я обязательно это сделаю, но только сейчас, когда я попытался, make allя получил ошибку:core/vm/instructions.go:37: undefined: time in time.Now core/vm/instructions.go:45: undefined: time in time.Now
ок, неважно - просто должен былimport ("time"...)
где будут отображаться эти коды операций? я могу получить к ним доступ через консоль по адресуgeth attach ipc:/Users/s.matthew.english/Library/Ethereum/testnet/geth.ipc
человек, кажется, я не могу заставить это отображаться в выводе консоли черезattach
Привет, если вы добавили log, cd go-ethereumdir, выполните ./build/bin/geth datadir=/Users/s.matthew.english/Library/Ethereum/testnet consoleдля перехода на консоль, а затем вызовите traceTransactionметод.
Я получил этот Fatal: Error starting protocol stack: listen udp :30303: bind: address already in use, и указание другого порта --port "35555"также не сработало. зачем мне вызывать traceTransactionметод?
Вы должны были запустить geth на другом терминале, пожалуйста, завершите процесс владения портом 30303 или запустите новый порт~
хм, но я думаю, что это то, что я сделал, я хотел запустить его в тестовой сети, чтобы я мог вызвать функцию, которую я развернул в конкретном смарт-контракте, я начал gethтакgeth --cache=1048 --testnet --unlock '0xd7a9a61a480d458a1181e0563b07f944df4489a6' --rpc --rpcapi 'eth,net,web3' --rpccorsdomain '*' --rpcaddr localhost --rpcport 8545 --etherbase '0xd7a9a61a480d458a1181e0563b07f944df4489a6' --mine
Да, ты добился успеха? вы можете выполнить debug.traceTransaction(tx_hash)команду~
Итак, я думаю, что это сработало, когда я загрузил узел, он выглядел так: i.stack.imgur.com/UaKs8.jpg Знаете ли вы, почему он выводит эти коды операций еще до того, как я не выполнил ни одной команды?
При переходе в консоль выполняется много команд. Например, в файле консолиWelcome метод будет вызываться при запуске узла, эти методы включают в себя основную информацию о выполненной команде, скомпилированном байт-коде.
есть ли способ выводить эти данные только для опкодов функций/контрактов, которые я вызываю сам?
Фактически, передний журнал выводится только при запуске узла (вы входите в консоль), эти команды используются для проверки версии и среды, они выполняются только один раз, не взаимодействуют с вызовом вашей функции/контракта.