arnaucube
arnaucube/hermez-nodePublic Self-hosted repository
hermez-node/test/ethclient_test.go
test/ethclient_test.goRaw
  1package test
  2
  3import (
  4	"context"
  5	"crypto/ecdsa"
  6	"encoding/binary"
  7	"math/big"
  8	"testing"
  9	"time"
 10
 11	ethCommon "github.com/ethereum/go-ethereum/common"
 12	ethCrypto "github.com/ethereum/go-ethereum/crypto"
 13	"github.com/hermeznetwork/hermez-node/common"
 14	"github.com/hermeznetwork/hermez-node/eth"
 15	"github.com/iden3/go-iden3-crypto/babyjub"
 16	"github.com/stretchr/testify/assert"
 17	"github.com/stretchr/testify/require"
 18)
 19
 20type timer struct {
 21	time int64
 22}
 23
 24func (t *timer) Time() int64 {
 25	currentTime := t.time
 26	t.time++
 27	return currentTime
 28}
 29
 30func TestClientInterface(t *testing.T) {
 31	var c eth.ClientInterface
 32	var timer timer
 33	clientSetup := NewClientSetupExample()
 34	client := NewClient(true, &timer, ethCommon.Address{}, clientSetup)
 35	c = client
 36	require.NotNil(t, c)
 37}
 38
 39func TestClientEth(t *testing.T) {
 40	var timer timer
 41	clientSetup := NewClientSetupExample()
 42	c := NewClient(true, &timer, ethCommon.Address{}, clientSetup)
 43	blockNum, err := c.EthCurrentBlock()
 44	require.Nil(t, err)
 45	assert.Equal(t, int64(0), blockNum)
 46
 47	block, err := c.EthBlockByNumber(context.TODO(), 0)
 48	require.Nil(t, err)
 49	assert.Equal(t, int64(0), block.EthBlockNum)
 50	assert.Equal(t, time.Unix(0, 0), block.Timestamp)
 51	assert.Equal(t, "0x0000000000000000000000000000000000000000000000000000000000000000", block.Hash.Hex())
 52	assert.Equal(t, int64(0), c.blockNum)
 53
 54	// Mine some empty blocks
 55
 56	c.CtlMineBlock()
 57	assert.Equal(t, int64(1), c.blockNum)
 58	c.CtlMineBlock()
 59	assert.Equal(t, int64(2), c.blockNum)
 60
 61	block, err = c.EthBlockByNumber(context.TODO(), 2)
 62	require.Nil(t, err)
 63	assert.Equal(t, int64(2), block.EthBlockNum)
 64	assert.Equal(t, time.Unix(2, 0), block.Timestamp)
 65}
 66
 67func TestClientAuction(t *testing.T) {
 68	addrWithdraw := ethCommon.HexToAddress("0x6b175474e89094c44da98b954eedeac495271d0f")
 69	addrForge := ethCommon.HexToAddress("0xCfAA413eEb796f328620a3630Ae39124cabcEa92")
 70	addrForge2 := ethCommon.HexToAddress("0x1fCb4ac309428feCc61B1C8cA5823C15A5e1a800")
 71
 72	var timer timer
 73	clientSetup := NewClientSetupExample()
 74	clientSetup.AuctionVariables.ClosedAuctionSlots = 2
 75	clientSetup.AuctionVariables.OpenAuctionSlots = 100
 76	c := NewClient(true, &timer, addrWithdraw, clientSetup)
 77
 78	_, err := c.AuctionBid(0, big.NewInt(1), addrForge)
 79	assert.Equal(t, errBidClosed, err)
 80
 81	_, err = c.AuctionBid(102, big.NewInt(1), addrForge)
 82	assert.Equal(t, errBidNotOpen, err)
 83
 84	_, err = c.AuctionBid(101, big.NewInt(16), addrForge)
 85	assert.Equal(t, errCoordNotReg, err)
 86
 87	_, err = c.AuctionRegisterCoordinator(addrForge, "https://foo.bar")
 88	assert.Nil(t, err)
 89
 90	_, err = c.AuctionBid(3, big.NewInt(1), addrForge)
 91	assert.Equal(t, errBidBelowMin, err)
 92
 93	_, err = c.AuctionBid(3, big.NewInt(16), addrForge)
 94	assert.Nil(t, err)
 95
 96	_, err = c.AuctionRegisterCoordinator(addrForge2, "https://foo2.bar")
 97	assert.Nil(t, err)
 98
 99	_, err = c.AuctionBid(3, big.NewInt(16), addrForge2)
100	assert.Equal(t, errBidBelowMin, err)
101
102	_, err = c.AuctionBid(3, big.NewInt(17), addrForge2)
103	assert.Nil(t, err)
104
105	c.CtlMineBlock()
106
107	blockNum, err := c.EthCurrentBlock()
108	require.Nil(t, err)
109
110	auctionEvents, _, err := c.AuctionEventsByBlock(blockNum)
111	require.Nil(t, err)
112	assert.Equal(t, 2, len(auctionEvents.NewBid))
113}
114
115func TestClientRollup(t *testing.T) {
116	token1Addr := ethCommon.HexToAddress("0x6b175474e89094c44da98b954eedeac495271d0f")
117
118	var timer timer
119	clientSetup := NewClientSetupExample()
120	c := NewClient(true, &timer, ethCommon.Address{}, clientSetup)
121
122	// Add a token
123
124	tx, err := c.RollupAddToken(token1Addr)
125	require.Nil(t, err)
126	assert.NotNil(t, tx)
127
128	// Add some L1UserTxs
129	// Create Accounts
130
131	const N = 16
132	var keys [N]*keys
133	for i := 0; i < N; i++ {
134		keys[i] = genKeys(int64(i))
135		l1UserTx := common.L1Tx{
136			FromIdx:     common.Idx(0),
137			FromEthAddr: keys[i].Addr,
138			FromBJJ:     keys[i].BJJPublicKey,
139			TokenID:     common.TokenID(0),
140			LoadAmount:  big.NewInt(10 + int64(i)),
141		}
142		c.CtlAddL1TxUser(&l1UserTx)
143	}
144	c.CtlMineBlock()
145
146	blockNum, err := c.EthCurrentBlock()
147	require.Nil(t, err)
148	rollupEvents, _, err := c.RollupEventsByBlock(blockNum)
149	require.Nil(t, err)
150	assert.Equal(t, N, len(rollupEvents.L1UserTx))
151	assert.Equal(t, 1, len(rollupEvents.AddToken))
152
153	// Forge a batch
154
155	c.CtlAddBatch(&eth.RollupForgeBatchArgs{
156		NewLastIdx:        0,
157		NewStRoot:         big.NewInt(1),
158		NewExitRoot:       big.NewInt(100),
159		L1CoordinatorTxs:  []*common.L1Tx{},
160		L2Txs:             []*common.L2Tx{},
161		FeeIdxCoordinator: make([]common.Idx, eth.FeeIdxCoordinatorLen),
162		VerifierIdx:       0,
163		L1Batch:           true,
164	})
165	c.CtlMineBlock()
166
167	blockNumA, err := c.EthCurrentBlock()
168	require.Nil(t, err)
169	rollupEvents, hashA, err := c.RollupEventsByBlock(blockNumA)
170	require.Nil(t, err)
171	assert.Equal(t, 0, len(rollupEvents.L1UserTx))
172	assert.Equal(t, 0, len(rollupEvents.AddToken))
173	assert.Equal(t, 1, len(rollupEvents.ForgeBatch))
174
175	// Simulate reorg discarding last mined block
176
177	c.CtlRollback()
178	c.CtlMineBlock()
179
180	blockNumB, err := c.EthCurrentBlock()
181	require.Nil(t, err)
182	rollupEvents, hashB, err := c.RollupEventsByBlock(blockNumA)
183	require.Nil(t, err)
184	assert.Equal(t, 0, len(rollupEvents.L1UserTx))
185	assert.Equal(t, 0, len(rollupEvents.AddToken))
186	assert.Equal(t, 0, len(rollupEvents.ForgeBatch))
187
188	assert.Equal(t, blockNumA, blockNumB)
189	assert.NotEqual(t, hashA, hashB)
190
191	// Forge again
192	rollupForgeBatchArgs0 := &eth.RollupForgeBatchArgs{
193		NewLastIdx:        0,
194		NewStRoot:         big.NewInt(1),
195		NewExitRoot:       big.NewInt(100),
196		L1CoordinatorTxs:  []*common.L1Tx{},
197		L2Txs:             []*common.L2Tx{},
198		FeeIdxCoordinator: make([]common.Idx, eth.FeeIdxCoordinatorLen),
199		VerifierIdx:       0,
200		L1Batch:           true,
201	}
202	c.CtlAddBatch(rollupForgeBatchArgs0)
203	c.CtlMineBlock()
204
205	// Retrieve ForgeBatchArguments starting from the events
206
207	blockNum, err = c.EthCurrentBlock()
208	require.Nil(t, err)
209	rollupEvents, _, err = c.RollupEventsByBlock(blockNum)
210	require.Nil(t, err)
211
212	rollupForgeBatchArgs1, err := c.RollupForgeBatchArgs(rollupEvents.ForgeBatch[0].EthTxHash)
213	require.Nil(t, err)
214	assert.Equal(t, rollupForgeBatchArgs0, rollupForgeBatchArgs1)
215}
216
217type keys struct {
218	BJJSecretKey *babyjub.PrivateKey
219	BJJPublicKey *babyjub.PublicKey
220	Addr         ethCommon.Address
221}
222
223func genKeys(i int64) *keys {
224	i++ // i = 0 doesn't work for the ecdsa key generation
225	var sk babyjub.PrivateKey
226	binary.LittleEndian.PutUint64(sk[:], uint64(i))
227
228	// eth address
229	var key ecdsa.PrivateKey
230	key.D = big.NewInt(i) // only for testing
231	key.PublicKey.X, key.PublicKey.Y = ethCrypto.S256().ScalarBaseMult(key.D.Bytes())
232	key.Curve = ethCrypto.S256()
233	addr := ethCrypto.PubkeyToAddress(key.PublicKey)
234
235	return &keys{
236		BJJSecretKey: &sk,
237		BJJPublicKey: sk.Public(),
238		Addr:         addr,
239	}
240}