135 lines
5.1 KiB
Bash
135 lines
5.1 KiB
Bash
|
|
#!/bin/bash
|
||
|
|
# Investigate why transactions persist after pool clearing
|
||
|
|
# Checks if transactions are in blockchain state vs transaction pool
|
||
|
|
|
||
|
|
set -euo pipefail
|
||
|
|
|
||
|
|
RPC_URL="${RPC_URL:-http://192.168.11.211:8545}"
|
||
|
|
DEPLOYER="${DEPLOYER:-0x4A666F96fC8764181194447A7dFdb7d471b301C8}"
|
||
|
|
|
||
|
|
# Colors
|
||
|
|
RED='\033[0;31m'
|
||
|
|
GREEN='\033[0;32m'
|
||
|
|
YELLOW='\033[1;33m'
|
||
|
|
BLUE='\033[0;34m'
|
||
|
|
CYAN='\033[0;36m'
|
||
|
|
NC='\033[0m'
|
||
|
|
|
||
|
|
log_info() { echo -e "${BLUE}[INFO]${NC} $1"; }
|
||
|
|
log_success() { echo -e "${GREEN}[✓]${NC} $1"; }
|
||
|
|
log_warn() { echo -e "${YELLOW}[⚠]${NC} $1"; }
|
||
|
|
log_error() { echo -e "${RED}[✗]${NC} $1"; }
|
||
|
|
log_section() { echo -e "\n${CYAN}━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━${NC}"; echo -e "${CYAN}$1${NC}"; echo -e "${CYAN}━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━${NC}\n"; }
|
||
|
|
|
||
|
|
echo "=== Transaction Persistence Investigation ==="
|
||
|
|
echo ""
|
||
|
|
|
||
|
|
# Check RPC connectivity
|
||
|
|
if ! timeout 5 cast chain-id --rpc-url "$RPC_URL" >/dev/null 2>&1; then
|
||
|
|
log_error "RPC not accessible"
|
||
|
|
exit 1
|
||
|
|
fi
|
||
|
|
|
||
|
|
# Get nonce status
|
||
|
|
log_section "Nonce Status"
|
||
|
|
LATEST_HEX=$(cast rpc eth_getTransactionCount "$DEPLOYER" latest --rpc-url "$RPC_URL" 2>/dev/null | tr -d '"')
|
||
|
|
PENDING_HEX=$(cast rpc eth_getTransactionCount "$DEPLOYER" pending --rpc-url "$RPC_URL" 2>/dev/null | tr -d '"')
|
||
|
|
LATEST_DEC=$(cast --to-dec "$LATEST_HEX" 2>/dev/null || echo "0")
|
||
|
|
PENDING_DEC=$(cast --to-dec "$PENDING_HEX" 2>/dev/null || echo "0")
|
||
|
|
PENDING_COUNT=$((PENDING_DEC - LATEST_DEC))
|
||
|
|
|
||
|
|
echo "Latest nonce: $LATEST_DEC ($LATEST_HEX)"
|
||
|
|
echo "Pending nonce: $PENDING_DEC ($PENDING_HEX)"
|
||
|
|
echo "Pending count: $PENDING_COUNT"
|
||
|
|
echo ""
|
||
|
|
|
||
|
|
if [ "$PENDING_COUNT" -eq 0 ]; then
|
||
|
|
log_success "No pending transactions"
|
||
|
|
exit 0
|
||
|
|
fi
|
||
|
|
|
||
|
|
# Check transaction pool
|
||
|
|
log_section "Transaction Pool Check"
|
||
|
|
TXPOOL_CONTENT=$(cast rpc txpool_content --rpc-url "$RPC_URL" 2>/dev/null || echo "{}")
|
||
|
|
|
||
|
|
if echo "$TXPOOL_CONTENT" | jq -e '.pending."'$DEPLOYER'"' >/dev/null 2>&1; then
|
||
|
|
TXPOOL_COUNT=$(echo "$TXPOOL_CONTENT" | jq -r '.pending."'$DEPLOYER'" | length' 2>/dev/null || echo "0")
|
||
|
|
if [ "$TXPOOL_COUNT" -gt 0 ]; then
|
||
|
|
log_warn "Found $TXPOOL_COUNT transactions in txpool"
|
||
|
|
echo "$TXPOOL_CONTENT" | jq -r '.pending."'$DEPLOYER'" | to_entries[] | " Nonce \(.key): \(.value.hash // "no hash")"' 2>/dev/null | head -10
|
||
|
|
else
|
||
|
|
log_info "No transactions in txpool (but pending nonce suggests they exist)"
|
||
|
|
fi
|
||
|
|
else
|
||
|
|
log_info "No transactions in txpool for deployer"
|
||
|
|
fi
|
||
|
|
|
||
|
|
# Check blockchain state
|
||
|
|
log_section "Blockchain State Check"
|
||
|
|
echo "Checking if transactions are in blockchain state..."
|
||
|
|
|
||
|
|
FOUND_IN_BLOCKCHAIN=0
|
||
|
|
NOT_FOUND=0
|
||
|
|
|
||
|
|
for nonce in $(seq $((LATEST_DEC + 1)) $PENDING_DEC); do
|
||
|
|
NONCE_HEX=$(printf '0x%x' $nonce)
|
||
|
|
|
||
|
|
# Try to find transaction by checking recent blocks
|
||
|
|
FOUND=false
|
||
|
|
|
||
|
|
# Check last 100 blocks for this nonce
|
||
|
|
LATEST_BLOCK=$(cast block-number --rpc-url "$RPC_URL" 2>/dev/null)
|
||
|
|
LATEST_BLOCK_DEC=$(cast --to-dec "$LATEST_BLOCK" 2>/dev/null || echo "0")
|
||
|
|
|
||
|
|
for block_offset in $(seq 0 100); do
|
||
|
|
BLOCK_NUM=$((LATEST_BLOCK_DEC - block_offset))
|
||
|
|
if [ "$BLOCK_NUM" -lt 0 ]; then
|
||
|
|
break
|
||
|
|
fi
|
||
|
|
|
||
|
|
BLOCK_HEX=$(printf '0x%x' $BLOCK_NUM)
|
||
|
|
TX_COUNT=$(cast rpc eth_getBlockTransactionCountByNumber "$BLOCK_HEX" --rpc-url "$RPC_URL" 2>/dev/null | tr -d '"')
|
||
|
|
TX_COUNT_DEC=$(cast --to-dec "$TX_COUNT" 2>/dev/null || echo "0")
|
||
|
|
|
||
|
|
# Check each transaction in block
|
||
|
|
for tx_idx in $(seq 0 $((TX_COUNT_DEC - 1))); do
|
||
|
|
TX_IDX_HEX=$(printf '0x%x' $tx_idx)
|
||
|
|
TX=$(cast rpc eth_getTransactionByBlockNumberAndIndex "$BLOCK_HEX" "$TX_IDX_HEX" --rpc-url "$RPC_URL" 2>/dev/null || echo "{}")
|
||
|
|
TX_NONCE=$(echo "$TX" | jq -r '.nonce // empty' 2>/dev/null || echo "")
|
||
|
|
TX_FROM=$(echo "$TX" | jq -r '.from // empty' 2>/dev/null || echo "")
|
||
|
|
|
||
|
|
if [ "$TX_NONCE" = "$NONCE_HEX" ] && [ "$TX_FROM" = "$(echo $DEPLOYER | tr '[:upper:]' '[:lower:]')" ]; then
|
||
|
|
TX_HASH=$(echo "$TX" | jq -r '.hash // empty' 2>/dev/null || echo "")
|
||
|
|
echo " Nonce $nonce: Found in block $BLOCK_NUM (hash: $TX_HASH)"
|
||
|
|
FOUND=true
|
||
|
|
FOUND_IN_BLOCKCHAIN=$((FOUND_IN_BLOCKCHAIN + 1))
|
||
|
|
break 2
|
||
|
|
fi
|
||
|
|
done
|
||
|
|
done
|
||
|
|
|
||
|
|
if [ "$FOUND" = false ]; then
|
||
|
|
echo " Nonce $nonce: Not found in blockchain"
|
||
|
|
NOT_FOUND=$((NOT_FOUND + 1))
|
||
|
|
fi
|
||
|
|
done
|
||
|
|
|
||
|
|
echo ""
|
||
|
|
log_section "Summary"
|
||
|
|
echo "Transactions in blockchain: $FOUND_IN_BLOCKCHAIN"
|
||
|
|
echo "Transactions not found: $NOT_FOUND"
|
||
|
|
echo ""
|
||
|
|
|
||
|
|
if [ "$NOT_FOUND" -gt 0 ]; then
|
||
|
|
log_warn "Some transactions are not in blockchain but show as pending"
|
||
|
|
echo ""
|
||
|
|
echo "Possible causes:"
|
||
|
|
echo " 1. Transactions are in RPC's internal state but not propagated"
|
||
|
|
echo " 2. Transactions were rejected but nonce not advanced"
|
||
|
|
echo " 3. RPC database needs clearing (beyond transaction pool)"
|
||
|
|
echo ""
|
||
|
|
echo "Recommendation:"
|
||
|
|
echo " - Use next nonce ($PENDING_DEC) to skip stuck transactions"
|
||
|
|
echo " - Or clear RPC database completely (requires service restart)"
|
||
|
|
fi
|