Незавершенные транзакции удалены из txpool в geth

Мы работали над нагрузочным тестированием нашей частной сети блокчейнов, используя geth и Web3j. Транзакции отправляются с помощью Web3j.

Мы отправляем 100 транзакций, где в каждом блоке есть место примерно для 25 из них (из-за лимита газа). Когда транзакции получены на нашем локальном узле, это печатается:

TRACE[07-26|10:15:53] Pooled new future transaction            hash=20453e…f2ec96 from=0x992a03b1bb4cc56929f2d21eaf34779d0562c9a7 to=0x32f1e2e74122efd01bd666750c5afc18c4ce3f91
TRACE[07-26|10:15:53] Promoting queued transaction             hash=20453e…f2ec96
INFO [07-26|10:15:53] Submitted transaction                    fullhash=0x20453ef67cba4d3549603f7a0bc0505d170a8fc2adeac849dc1a8c2fa3f2ec96 recipient=0x32f1e2e74122efd01bd666750c5afc18c4ce3f91
TRACE[07-26|10:15:53] Broadcast transaction                    hash=20453e…f2ec96 recipients=2
DEBUG[07-26|10:15:54] Transaction pool status report           executable=43 queued=0 stales=9

Когда все транзакции отправлены, пул транзакций нашего локального узла имеет значение txpool.status:

{
  pending: 100,
  queued: 0
}  

Затем мы начинаем майнить на нашем локальном узле.

INFO [07-26|10:20:41] Starting mining operation 
TRACE[07-26|10:20:41] Gas limit exceeded for current block     sender=0x992a03b1bb4cc56929f2d21eaf34779d0562c9a7
INFO [07-26|10:20:41] Commit new mining work                   number=8383 txs=25 uncles=0 elapsed=18.063ms
TRACE[07-26|10:20:41] Started ethash search for new nonces     miner=0 seed=4567440808604611913
DEBUG[07-26|10:20:42] Transaction pool status report           executable=100 queued=0 stales=8
TRACE[07-26|10:20:48] Ethash nonce found and reported          miner=0 attempts=313611  nonce=4567440808604925524
INFO [07-26|10:20:48] Successfully sealed new block            number=8383 hash=774d72…ba62fc
DEBUG[07-26|10:20:48] Trie cache stats after commit            misses=11 unloads=2
INFO [07-26|10:20:48] 🔗 block reached canonical chain          number=8378 hash=81b120…f0867f
INFO [07-26|10:20:48] 🔨 mined potential block                  number=8383 hash=774d72…ba62fc
TRACE[07-26|10:20:48] Transaction failed, will be removed      hash=05c537…979f0b err="invalid nonce: have 731, expected 756"
INFO [07-26|10:20:48] Commit new mining work                   number=8384 txs=0  uncles=0 elapsed=957.166µs
TRACE[07-26|10:20:48] Propagated block                         hash=774d72…ba62fc recipients=1 duration=2562047h47m16.854s
TRACE[07-26|10:20:48] Announced block                          hash=774d72…ba62fc recipients=2 duration=2562047h47m16.8

После майнинга одного блока с 25 транзакциями наш txpool теперь пуст.

{
  pending: 0,
  queued: 0
}

Только 25 из 100 транзакций были добыты, а остальные были удалены (похоже, они объявлены как старые ожидающие транзакции). Тогда мой вопрос. Это предполагаемое поведение или мы что-то упускаем? Если это сделано намеренно, есть ли у кого-нибудь советы, как разрешить отправку нескольких транзакций с одного и того же адреса и узла?

РЕДАКТИРОВАТЬ:

Мы создали супервизора для проверки подтвержденных транзакций и попытки повторной отправки транзакций, если они были потеряны. При повторной отправке транзакций получаем ошибку:

-32000 know transaction: transaction_hash

Однако при ручной отправке eth.getTransactionReciept(transaction_hash) возвращается null.

Где хранятся известные транзакции и почему они не майнятся? (их нет в txpool)

Транзакции отправляются с одного и того же адреса? Если это так, это может быть проблема, связанная с nonce.
Транзакции отправляются с одного и того же адреса, но, поскольку все они имеют статус ожидающих, я думаю, что уведомления верны? Возможно, geth выбирает для майнинга самые новые транзакции, и поэтому анонсы других транзакций устарели?
Я вижу аналогичные результаты со следующим кодом: var arr = [] ; for (i = 1 ; i<= 110; i++){ arr.push(eth.sendTransaction({from: eth.coinbase, to: eth.accounts[1], value: web3.toWei( i/1000 + 1 , 'szabo')}))}создает 110 ожидающих txns, но когда майнинг завершен, добывается только около 105. Итак, eth.getTransactionReceipt(arr[100]) даст мне результат, но то же самое с arr[109] даст нуль. Те отсутствующие txns потеряны - не в txpool и т. Д. Nonces различаются.
Я был в состоянии испытать подобные симптомы и поймать их в журнале. См. этот выпуск: github.com/ethereum/go-ethereum/issues/14893 .

Ответы (2)

результат в порядке. Сначала я отправляю 110 транзакций, результат txpool.status

{
    pending: 110,
    queued: 0
}

а затем начать добычу, все транзакции были заминированы. Таким образом введите описание изображения здесь, tx_pool не отбрасывает транзакции. В исходных файлах go-ethereum файл tx_pool.go имеет дело с логикой транзакций, некоторые транзакции будут удалены, если tx_pool заполнен, размер пула превышает 4096+1024, источник выглядит следующим образом:

// If the transaction pool is full, discard underpriced transactions
if uint64(len(pool.all)) >= pool.config.GlobalSlots+pool.config.GlobalQueue {
    // If the new transaction is underpriced, don't accept it
    if pool.priced.Underpriced(tx, pool.locals) {
        log.Trace("Discarding underpriced transaction", "hash", hash, "price", tx.GasPrice())
        underpricedTxCounter.Inc(1)
        return false, ErrUnderpriced
    }
    // New transaction is better than our worse ones, make room for it
    drop := pool.priced.Discard(len(pool.all)-int(pool.config.GlobalSlots+pool.config.GlobalQueue-1), pool.locals)
    for _, tx := range drop {
        log.Trace("Discarding freshly underpriced transaction", "hash", tx.Hash(), "price", tx.GasPrice())
        underpricedTxCounter.Inc(1)
        pool.removeTx(tx.Hash())
    }
}

так что перелива нет.

Были ли все транзакции включены в один блок или вам нужно было майнить несколько блоков, чтобы включить их все?
Я столкнулся с этой проблемой при переполнении 210. но я обнаружил, что это связано с gasLimit, каждый блок содержит txs = gasLimit / per_tx_gas (тест 21000), если есть больше txs, они будут упакованы в следующий новый блок. Итак, я настроил большой gasLimit в файле genesis.json:{ "config": { "chainId": 10, "homesteadBlock": 0, "eip155Block": 0, "eip158Block": 0 }, "difficulty": "0x400000", "gasLimit": "2100000000000000000", "alloc": { "0xf85209fa42a3445362d82636c470b6e1e4bc7a33": { "balance": "30000000000000000000000" } } }
и я отправляю 10249 транзакций, затем начинаю добычу, все транзакции включают новый блок. из-за слишком большого количества txs результат getBlock(blockNum) будет за пределами экрана, поэтому я использую результат печати JSON RPC: curl -X POST --data '{"jsonrpc":"2.0","method":"eth_getBlockTransactionCountByHash ","params":["0x5e678f610a98799edaf8664ddc988332af6301513aace6a92b65a823491afcc0"],"id":1}' localhost:8545 {"jsonrpc":"2.0","id":1,"result":"0x2809"} вы найдете подробную логику в методе tx_pool.demoteUnexecutables.

Похоже на ошибку, которую только что исправили: https://github.com/ethereum/go-ethereum/issues/14893 .