So stellen Sie gleichzeitig signierte Transaktionen in die Warteschlange

Ich habe einen einfachen API-Server geschrieben NodeJS, der web3(Version 1 Beta 27) verwendet, um mit einem Remote-Paritätsknoten zu interagieren.

Der Kern des Anrufs ist wie folgt

const invoke = async (req, res) => {
  const { params: { address } } = req
  try {
    const theContract = new web3.eth.Contract(abi, contractAddress, { from: SENDER_ADDRESS })
    const fn = theContract.methods.doTheThing(address)
    const account = web3.eth.accounts.privateKeyToAccount(PRIVATE_KEY)
    const data = fn.encodeABI()
    const nonce = await web3.eth.getTransactionCount(SENDER_ADDRESS, 'pending')
    const payload = {
      nonce,
      data,
      gas,
      from: SENDER_ADDRESS,
      to: contractAddress
    }
    const signedTx = await account.signTransaction(payload, account.privateKey)
    const { rawTransaction } = signedTx
    const response = await web3.eth.sendSignedTransaction(rawTransaction)
    const { transactionHash: tx } = response
    res.json({ tx })
  } catch (err) {
    res.status(500).json({ error: err.message })
  }
}

Dies funktioniert perfekt, wenn ich die API nur einmal aufrufe, und es funktioniert sogar gut, wenn ich einige Aufrufe mache, die sich ungefähr überschneiden. (getestet mit curl mit einer Reihe von Terminalfenstern)

Aber wenn ich ein Skript verwende, um die API viele Male gleichzeitig aufzurufen (was eine vernünftige Simulation einer realen Bedingung ist), schlagen die meisten Aufrufe fehlThere is another transaction with same nonce in the queue.

Eine Lösung, die mir empfohlen wurde, besteht darin, eine personalAdresse in Parity selbst zu erstellen, anstatt eine Adresse in Form eines öffentlichen/privaten Schlüsselpaars auf meinem Computer zu erstellen, aber das scheint keine Best-Practice-Lösung zu sein.

Das Problem ist, dass web3.eth.getTransactionCount(SENDER_ADDRESS, 'pending')dasselbe zurückgegeben wird, noncewenn die API zu schnell aufgerufen wird. Ein Gedanke ist, dass ich es einfach wiederholen könnte, wenn der abgefangene Fehler die There is another transaction with same nonce in the queue.Nachricht enthält, aber das scheint, gelinde gesagt, zerbrechlich zu sein.

Was ist der richtige Weg, um gleichzeitige Anfragen wie diese in die Warteschlange zu stellen?

Sie müssen Ihre eigene Logik implementieren, um die Nonce zu handhaben. Dies ist ein sehr häufiges Problem. Das Einfachste, was Sie tun können, ist, die Nonce einmal vom Knoten abzurufen und sie jedes Mal im Speicher zu inkrementieren, wenn Sie eine neue Transaktion signieren und senden möchten. Das ist natürlich ein sehr naiver Ansatz. Sie müssen sich um fehlgeschlagene Transaktionen kümmern, z. B. aufgrund eines Netzwerkfehlers, und sicherstellen, dass Sie keine Nonce-Lücke erstellen, dh Transaktionen mit einer größeren Nonce als der aktuellen senden
Hast du dafür eine gute Lösung gefunden?

Antworten (1)

Sie können eine Batch-Anfrage verwenden, mit der Sie bestimmte Bestelltransaktionen senden können:

http://web3js.readthedocs.io/en/1.0/web3-eth.html?highlight=batch#batchrequest

Batch-Anfrage hilft nicht, da jeder API-Aufruf völlig unabhängig voneinander ist.
Ich verstehe nicht. Was ist das Problem? Mit Batch können Sie sich für jeden Anruf/jede Transaktion, die Sie tätigen möchten, in die Warteschlange stellen. Es interessiert nicht, was drin ist.
Die API ruft die Funktion nur mit einer Adresse auf. Tausende unabhängiger externer Entitäten können die API aufrufen. Jeder Aufruf an die API schließt sich gegenseitig aus, sodass nichts gestapelt werden muss.
Ah, ok, Missverständnis. Dazu gibt es meines Wissens nach keine Möglichkeit. Blockchain soll nicht schnell sein (zumindest vorerst)