Какой самый быстрый способ майнить транзакцию, чтобы я мог быстро протестировать контракты?

Я разрабатываю автоматизированную тестовую среду Solidity в nodejs, которая широко использует события/регистрацию. Использование событий устраняет (я полагаю) все симуляторы RPC. Также утомительно решать проблемы с симулятором, я бы предпочел использовать настоящий сервер, модифицированный для более быстрой работы.

Я взломал geth для майнинга транзакций каждые 4 секунды вместо 15-20 секунд, но это все равно слишком медленно. Я хотел бы работать так быстро, как виртуальная машина может выполнять код.

Я собираюсь опубликовать свой патч на geth, чтобы сделать это, но я и другие действительно хотели бы получить лучший ответ на этот вопрос. Это действительно замедляет разработку, когда приходится ждать несколько секунд для завершения каждой транзакции. Мой тестовый набор из примерно 60 транзакций занимает около 4-5 минут, и мой тестовый набор становится все длиннее...

Пожалуйста, посоветуйте сделать этот гет еще быстрее, чем ответ, который я предлагаю, или альтернативное предложение.

Ответы (3)

Патч для geth, чтобы ускорить майнинг. Мне бы очень хотелось помочь сделать это примерно в 2-4 раза быстрее, чем сейчас, но в 5 раз быстрее, чем стандартный гет:

[9 марта 2016 г. РЕДАКТИРОВАТЬ - этот новый патч теперь майнит каждую секунду. Мои модульные тесты, выполняющие 78 транзакций, выполняются примерно за 160 секунд. Я должен выложить Gist для этого...]

    diff --git a/eth/fetcher/fetcher.go b/eth/fetcher/fetcher.go
index d88d919..f03fd30 100644
--- a/eth/fetcher/fetcher.go
+++ b/eth/fetcher/fetcher.go
@@ -34,7 +34,7 @@ import (
 const (
    arriveTimeout = 500 * time.Millisecond // Time allowance before an announced block is explicitlrd
    gatherSlack   = 100 * time.Millisecond // Interval used to collate almost-expired announces witfs
-   fetchTimeout  = 5 * time.Second        // Maximum alloted time to return an explicitly requestebk
+   fetchTimeout  = 1 * time.Second        // Maximum alloted time to return an explicitly requestebk
    maxUncleDist  = 7                      // Maximum allowed backward distance from the chain head
    maxQueueDist  = 32                     // Maximum allowed distance from the chain head to queue
    hashLimit     = 256                    // Maximum number of unique blocks a peer may have annoued
diff --git a/eth/peer.go b/eth/peer.go
index 15ba22f..0201057 100644
--- a/eth/peer.go
+++ b/eth/peer.go
@@ -41,7 +41,7 @@ var (
 const (
    maxKnownTxs      = 32768 // Maximum transactions hashes to keep in the known list (prevent DOS)
    maxKnownBlocks   = 1024  // Maximum block hashes to keep in the known list (prevent DOS)
-   handshakeTimeout = 5 * time.Second
+   handshakeTimeout = 1 * time.Second
 )

 // PeerInfo represents a short summary of the Ethereum sub-protocol metadata known
diff --git a/miner/worker.go b/miner/worker.go
index 754a6fc..2b62b59 100644
--- a/miner/worker.go
+++ b/miner/worker.go
@@ -466,7 +466,7 @@ func (self *worker) commitNewWork() {
            tstamp = parent.Time().Int64() + 1
    }
    // this will ensure we're not going off too far in the future
-   if now := time.Now().Unix(); tstamp > now+4 {
+   if now := time.Now().Unix(); tstamp > now {
            wait := time.Duration(tstamp-now) * time.Second
            glog.V(logger.Info).Infoln("We are too far in the future. Waiting for", wait)
            time.Sleep(wait)
diff --git a/p2p/rlpx.go b/p2p/rlpx.go
index aaa7338..ce82eb7 100644
--- a/p2p/rlpx.go
+++ b/p2p/rlpx.go
@@ -57,7 +57,7 @@ const (

    // total timeout for encryption handshake and protocol
    // handshake in both directions.
-   handshakeTimeout = 5 * time.Second
+   handshakeTimeout = 2 * time.Second

    // This is the timeout for sending the disconnect reason.
    // This is shorter than the usual timeout because we don't want
diff --git a/params/protocol_params.go b/params/protocol_params.go
index dcc17e0..21a49c5 100755
--- a/params/protocol_params.go
+++ b/params/protocol_params.go
@@ -29,10 +29,10 @@ var (
    CallNewAccountGas      = big.NewInt(25000)  // Paid for CALL when the destination address didn'e.
    TxGas                  = big.NewInt(21000)  // Per transaction. NOTE: Not payable on data of cas.
    TxDataZeroGas          = big.NewInt(4)      // Per byte of data attached to a transaction that u.
-   DifficultyBoundDivisor = big.NewInt(2048)   // The bound divisor of the difficulty, used in thep.
+   DifficultyBoundDivisor = big.NewInt(1)      // The bound divisor of the difficulty, used in thep.
    QuadCoeffDiv           = big.NewInt(512)    // Divisor for the quadratic particle of the memoryo.
-   GenesisDifficulty      = big.NewInt(131072) // Difficulty of the Genesis block.
-   DurationLimit          = big.NewInt(13)     // The decision boundary on the blocktime duration e.
+   GenesisDifficulty      = big.NewInt(1)      // Difficulty of the Genesis block.
+   DurationLimit          = big.NewInt(1)      // The decision boundary on the blocktime duration e.
    SstoreSetGas           = big.NewInt(20000)  // Once per SLOAD operation.
    LogDataGas             = big.NewInt(8)      // Per byte in a LOG* operation's data.
    CallStipend            = big.NewInt(2300)   // Free gas given at beginning of call.
@@ -57,7 +57,7 @@ var (
    CreateDataGas        = big.NewInt(200)    //
    Ripemd160Gas         = big.NewInt(600)    //
    Ripemd160WordGas     = big.NewInt(120)    //
-   MinimumDifficulty    = big.NewInt(131072) // The minimum that the difficulty may ever be.
+   MinimumDifficulty    = big.NewInt(1)      // The minimum that the difficulty may ever be.
    CallCreateDepth      = big.NewInt(1024)   // Maximum depth of call/create stack.
    ExpGas               = big.NewInt(10)     // Once per EXP instuction.
    LogGas               = big.NewInt(375)    // Per LOG* operation.

Вот мой genesis.json. Там много других примеров:

{
    "nonce": "0xdeadbeefdeadbeef",
    "timestamp": "0x0",
    "parentHash":     "0x0000000000000000000000000000000000000000000000000000000000000000",
    "extraData": "0x0",
    "gasLimit": "0x8000000",
    "difficulty": "0x001",
    "mixhash": "0x0000000000000000000000000000000000000000000000000000000000000000",
    "coinbase": "0x3333333333333333333333333333333333333333",
    "alloc": {
        "0x662eb875377b1288f07baa6139432553b7b8b03e": {
            "balance": "1000000000000000000000"
         }
    }
}

~

И, наконец, вся важная командная строка. Примечание. Я изменил стоимость газа на 50 вэй вместо 50 Гвэй. Я, наверное, мог бы поступить лучше, если бы просто дал группе аккаунтов 10 миллионов эфира. Также мне нужно добавить чтение скрипта, который разблокирует все аккаунты:

#!/bin/bash
bin/geth --datadir /home/Pauls/testing/00 --port 30310 --rpc --rpcport 8110 --networkid 4567890 --dev --lightkdf --nodiscover --maxpeers 0 --vmdebug --verbosity 6 --pprof --genesis /home/Pauls/sandboxes/myproj/bin/genesis.json --gpomin "50" --gpomax "50" --pprofport 6110 console 2> /home/Pauls/testing/00/geth.log

~

мне сказали, что testrpc теперь поддерживает события. Я попробую, когда у меня будет немного времени.

Test-RPC — отличное приложение для этого. Он запускает смоделированный блокчейн, к которому вы можете подключиться через RPC через web3, и вообще не требует майнинга или сети.

В какой-то момент testrpc не поддерживал события. Кажется, сейчас. Кроме того, мне нужен сервер, а не библиотека, потому что я делаю многопользовательское приложение. Однако я попробую
На самом деле это сервер. я оговорился
Итак, как это соотносится с github.com/ethereumjs/testrpc?
Тот работает на урезанном клиенте NodeJS, тот, который я опубликовал, работает на форке клиента python. Похоже, что JS теперь поддерживает события, так что это может быть лучше.
Недавно я тестировал nodejs testrpc по сравнению с вышеуказанным патчем geth. Хотите верьте, хотите нет, но гет добывает быстрее с вышеуказанным патчем. Что-то произошло с более ранней версией ethereumjs/testrpc, что замедлило его.

Альтернативой является использование pyethereum.tester, для краткости pytester (не путать с py.test).

pytester является частью pyethereum , python-клиента Ethereum Foundation, который прошел аудит безопасности (как и Geth) и является частью Ethereum Bounty Program . Согласитесь, разочаровывать поиск проблем с симулятором, и я бы не стал классифицировать его как таковой: он был очень надежным, и ошибка, обнаруженная с помощью pytester, вполне могла быть проблемой консенсуса в самом pyethereum и заслуживала вознаграждения.

https://github.com/ethereum/pyethereum/wiki/Использование-pyethereum.tester

Поскольку вы специально спрашивали о майнинге, вот пример майнинга 105 блоков s.mine(105):

from ethereum import tester as t
def test_make_reports():
    global initial_gas
    initial_gas = 0
    t.gas_limit = 100000000
    s = t.state()
    c = s.abi_contract('functions/output.se')
    gas_use(s)
    c.initiateOwner(1010101)
    c.reputationFaucet(1010101)
    assert(c.submitReportHash(1010101, 3232, -1, 222, 0)==-2), "Nonexistant event check broken"
    event1 = c.createEvent(1010101, "new event", 5, 1, 2, 2)
    bin_market = c.createMarket(1010101, "new market", 2**58, 100*2**64, 184467440737095516, [event1], 1)
    s.mine(105)
    gas_use(s)
    c.incrementPeriod(1010101)
    report_hash = c.makeHash(0, 2**64, event1)
    gas_use(s)
    print c.submitReportHash(1010101, report_hash, 0, event1, 0)
    assert(c.submitReportHash(1010101, report_hash, 0, event1, 0)==1), "Report hash submission failed"
    gas_use(s)
    s.mine(55)
    gas_use(s)
    assert(c.submitReport(1010101, 0, 0, 0, 2**64, event1, 2**64)==1), "Report submission failed"
    gas_use(s)
    print c.getUncaughtOutcome(event1)
    gas_use(s)
    print "Test make reports OK"

pytester также работает с кодом Solidity. Будильник Ethereum использует pytester для майнинга множества блоков , чтобы, например, проверить, просыпаются ли часы в далеком будущем. Это wait_for_blockчерез Populus , фреймворк , использующий pytester; В Populus также есть возможность тестирования с использованием реального узла Geth.

Другой пример Solidity , демонстрирующий возможности pytester для тестирования произвольно сложных сценариев, — это ether_ad в dapp-bin Ethereum .

ну, я использую nodejs, а не python. Могу ли я просто настроить pytest для прослушивания сокета, такого как geth, но как можно быстрее, без необходимости писать какой-либо (или, по крайней мере, очень небольшой) код Python?
Я не уверен, что pytester можно использовать таким образом: было бы здорово, если бы он мог, а пока лучше спросить на gitter.im/ethereum/pyethereum (вероятно, так быстрее ответят)