-
Notifications
You must be signed in to change notification settings - Fork 1k
/
send_transaction_test.go
110 lines (94 loc) · 3.99 KB
/
send_transaction_test.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
package commands_test
import (
"bytes"
"crypto/ecdsa"
"math/big"
"testing"
"github.com/holiman/uint256"
"github.com/ledgerwatch/erigon-lib/gointerfaces/sentry"
"github.com/ledgerwatch/erigon-lib/gointerfaces/txpool"
"github.com/ledgerwatch/erigon-lib/kv/kvcache"
"github.com/ledgerwatch/erigon/cmd/rpcdaemon22/commands"
"github.com/ledgerwatch/erigon/cmd/rpcdaemon22/rpcdaemontest"
"github.com/ledgerwatch/erigon/common"
"github.com/ledgerwatch/erigon/common/u256"
"github.com/ledgerwatch/erigon/core"
"github.com/ledgerwatch/erigon/core/types"
"github.com/ledgerwatch/erigon/eth/protocols/eth"
"github.com/ledgerwatch/erigon/params"
"github.com/ledgerwatch/erigon/rlp"
"github.com/ledgerwatch/erigon/turbo/rpchelper"
"github.com/ledgerwatch/erigon/turbo/snapshotsync"
"github.com/ledgerwatch/erigon/turbo/stages"
"github.com/stretchr/testify/require"
)
func TestSendRawTransaction(t *testing.T) {
t.Skip("Flaky test")
m, require := stages.Mock(t), require.New(t)
chain, err := core.GenerateChain(m.ChainConfig, m.Genesis, m.Engine, m.DB, 1, func(i int, b *core.BlockGen) {
b.SetCoinbase(common.Address{1})
}, false /* intermediateHashes */)
require.NoError(err)
{ // Do 1 step to start txPool
// Send NewBlock message
b, err := rlp.EncodeToBytes(ð.NewBlockPacket{
Block: chain.TopBlock,
TD: big.NewInt(1), // This is ignored anyway
})
require.NoError(err)
m.ReceiveWg.Add(1)
for _, err = range m.Send(&sentry.InboundMessage{Id: sentry.MessageId_NEW_BLOCK, Data: b, PeerId: m.PeerId}) {
require.NoError(err)
}
// Send all the headers
b, err = rlp.EncodeToBytes(ð.BlockHeadersPacket66{
RequestId: 1,
BlockHeadersPacket: chain.Headers,
})
require.NoError(err)
m.ReceiveWg.Add(1)
for _, err = range m.Send(&sentry.InboundMessage{Id: sentry.MessageId_BLOCK_HEADERS, Data: b, PeerId: m.PeerId}) {
require.NoError(err)
}
m.ReceiveWg.Wait() // Wait for all messages to be processed before we proceeed
initialCycle := true
highestSeenHeader := chain.TopBlock.NumberU64()
if _, err := stages.StageLoopStep(m.Ctx, m.DB, m.Sync, highestSeenHeader, m.Notifications, initialCycle, m.UpdateHead, nil); err != nil {
t.Fatal(err)
}
}
expectValue := uint64(1234)
txn, err := types.SignTx(types.NewTransaction(0, common.Address{1}, uint256.NewInt(expectValue), params.TxGas, uint256.NewInt(10*params.GWei), nil), *types.LatestSignerForChainID(m.ChainConfig.ChainID), m.Key)
require.NoError(err)
ctx, conn := rpcdaemontest.CreateTestGrpcConn(t, m)
txPool := txpool.NewTxpoolClient(conn)
ff := rpchelper.New(ctx, nil, txPool, txpool.NewMiningClient(conn), func() {})
stateCache := kvcache.New(kvcache.DefaultCoherentConfig)
api := commands.NewEthAPI(commands.NewBaseApi(ff, stateCache, snapshotsync.NewBlockReader(), nil, nil, false), m.DB, nil, txPool, nil, 5000000)
buf := bytes.NewBuffer(nil)
err = txn.MarshalBinary(buf)
require.NoError(err)
txsCh := make(chan []types.Transaction, 1)
id := ff.SubscribePendingTxs(txsCh)
defer ff.UnsubscribePendingTxs(id)
_, err = api.SendRawTransaction(ctx, buf.Bytes())
require.NoError(err)
got := <-txsCh
require.Equal(expectValue, got[0].GetValue().Uint64())
//send same tx second time and expect error
_, err = api.SendRawTransaction(ctx, buf.Bytes())
require.NotNil(err)
require.Equal("ALREADY_EXISTS: already known", err.Error())
m.ReceiveWg.Wait()
//TODO: make propagation easy to test - now race
//time.Sleep(time.Second)
//sent := m.SentMessage(0)
//require.Equal(eth.ToProto[m.MultiClient.Protocol()][eth.NewPooledTransactionHashesMsg], sent.Id)
}
func transaction(nonce uint64, gaslimit uint64, key *ecdsa.PrivateKey) types.Transaction {
return pricedTransaction(nonce, gaslimit, u256.Num1, key)
}
func pricedTransaction(nonce uint64, gaslimit uint64, gasprice *uint256.Int, key *ecdsa.PrivateKey) types.Transaction {
tx, _ := types.SignTx(types.NewTransaction(nonce, common.Address{}, uint256.NewInt(100), gaslimit, gasprice, nil), *types.LatestSignerForChainID(big.NewInt(1337)), key)
return tx
}