Was ist der schnellste Weg, um eine Transaktion zu schürfen, damit ich Verträge schnell testen kann?

Ich entwickle ein solides automatisiertes Testframework in nodejs, das Ereignisse/Protokollierung ausgiebig verwendet. Die Verwendung von Ereignissen eliminiert (glaube ich) alle RPC-Simulatoren da draußen. Es ist auch frustrierend, Simulatorproblemen nachzujagen, ich würde lieber einen echten Server verwenden, der so modifiziert ist, dass er schneller läuft.

Ich habe Geth gehackt, um Transaktionen alle 4 Sekunden statt 15-20 Sekunden abzubauen, aber es ist immer noch zu langsam. Ich möchte so schnell laufen, wie die VM Code ausführen kann.

Ich werde meinen Patch an Geth senden, um dies zu tun, aber ich und andere hätten wirklich gerne eine bessere Antwort auf diese Frage. Es verlangsamt die Entwicklung wirklich, mehrere Sekunden warten zu müssen, bis jede Transaktion abgeschlossen ist. Die Ausführung meiner Testsuite mit etwa 60 Transaktionen dauert etwa 4-5 Minuten, und meine Testsuite wird immer länger ...

Bitte raten Sie mir, dies noch schneller als die von mir vorgeschlagene Antwort zu machen, oder auch einen alternativen Vorschlag.

Antworten (3)

Patch to geth, damit es mir schneller geht. Ich hätte wirklich gerne Hilfe dabei, dies etwa 2x-4x schneller zu machen als jetzt, aber es ist 5x schneller als Stock Geth:

[EDIT vom 9. März 2016 – dieser neue Patch mint jetzt jede Sekunde. Meine Komponententests, die 78 Transaktionen ausführen, werden in etwa 160 Sekunden ausgeführt. Ich sollte einen Gist dafür veröffentlichen ...]

    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.

Hier ist meine genesis.json. Es gibt viele andere Beispiele da draußen:

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

~

Und schließlich die alles wichtige Befehlszeile. Beachten Sie, dass ich die Gaskosten auf 50 Wei anstelle von 50 Gwei geändert habe. Ich hätte es wahrscheinlich besser machen können, einfach einem Haufen Konten 10 Millionen Ether zu geben. Außerdem muss ich das Lesen eines Skripts hinzufügen, das alle Konten entsperrt:

#!/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

~

Mir wurde gesagt, dass testrpc jetzt Ereignisse unterstützt. Ich werde es versuchen, wenn ich etwas Zeit habe.

Test-RPC ist eine großartige Anwendung, um genau dies zu tun. Es führt eine simulierte Blockchain aus, mit der Sie sich über RPC über web3 verbinden können, und muss überhaupt nicht geschürft oder vernetzt werden.

An einem Punkt unterstützte testrpc keine Ereignisse. Es scheint jetzt. Außerdem brauche ich einen Server, keine Bibliothek, weil ich eine Mehrparteienanwendung mache. Allerdings werde ich es mal versuchen
Eigentlich ist es ein Server. Ich habe mich vertan
Wie sieht das im Vergleich zu github.com/ethereumjs/testrpc aus?
Dieser läuft auf einem abgespeckten NodeJS-Client, der, den ich gepostet habe, läuft auf einem Fork des Python-Clients. Das JS sieht jedoch so aus, als ob es jetzt Ereignisse unterstützt, also könnte das besser sein.
Ich habe kürzlich den nodejs testrpc im Vergleich zum obigen Geth-Patch getestet. Ob Sie es glauben oder nicht, mit dem obigen Patch geht Minen schneller. Etwas ist seit der früheren Version von ethereumjs/testrpc passiert, um es zu verlangsamen.

Eine Alternative ist die Verwendung von pyethereum.tester, kurz pytester (und nicht zu verwechseln mit py.test).

pytester ist Teil von pyethereum , dem Python-Client der Ethereum Foundation, der (wie Geth) einem Sicherheitsaudit unterzogen wurde, und Teil des Ethereum Bounty Program . Stimmen Sie zu, dass es frustrierend ist, Simulatorproblemen nachzujagen, und ich würde es nicht als eines klassifizieren: Es war sehr zuverlässig und ein Fehler, der mit Pytester gefunden wurde, könnte durchaus ein Konsensproblem in Pyethereum selbst sein und ein Kopfgeld wert sein.

https://github.com/ethereum/pyethereum/wiki/Using-pyethereum.tester

Da Sie speziell nach dem Mining gefragt haben, finden Sie hier ein Beispiel für das Mining von 105 Blöcken 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 funktioniert auch mit Solidity-Code. Der Ethereum-Wecker verwendet Pytester, um viele Blöcke abzubauen, damit er beispielsweise testen kann, ob die Uhr weit in der Zukunft aufwacht. Das wait_for_blockist über Populus , ein Framework , das Pytester verwendet; Populus hat auch die Möglichkeit, mit einem tatsächlichen Geth-Knoten zu testen.

Ein weiteres Solidity-Beispiel , das auf die Leistungsfähigkeit von pytester zum Testen beliebig komplexer Szenarien hinweist, ist ether_ad unter Ethereums dapp-bin .

Nun, ich verwende nodejs, nicht Python. Kann ich pytest einfach so einrichten, dass es auf einem Socket wie Geth lauscht, aber so schnell wie möglich, ohne (oder zumindest sehr wenig) Python-Code schreiben zu müssen?
Ich bin mir nicht sicher, ob Pytester so verwendet werden kann: Wäre großartig, wenn es möglich wäre, und im Moment ist es vielleicht am besten, auf gitter.im/ethereum/pyethereum zu fragen (wahrscheinlich schnellere Antwort auf diese Weise).