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(1), 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
 53	// Mine some empty blocks
 54
 55	assert.Equal(t, int64(1), c.blockNum)
 56	c.CtlMineBlock()
 57	assert.Equal(t, int64(2), c.blockNum)
 58	c.CtlMineBlock()
 59	assert.Equal(t, int64(3), 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	// Add a token
 67	tokenAddr := ethCommon.HexToAddress("0x44021007485550008e0f9f1f7b506c7d970ad8ce")
 68	constants := eth.ERC20Consts{
 69		Name:     "FooBar",
 70		Symbol:   "FOO",
 71		Decimals: 4,
 72	}
 73	c.CtlAddERC20(tokenAddr, constants)
 74	c.CtlMineBlock()
 75	tokenConstants, err := c.EthERC20Consts(tokenAddr)
 76	require.Nil(t, err)
 77	assert.Equal(t, constants, *tokenConstants)
 78}
 79
 80func TestClientAuction(t *testing.T) {
 81	addrBidder1 := ethCommon.HexToAddress("0x6b175474e89094c44da98b954eedeac495271d0f")
 82	addrBidder2 := ethCommon.HexToAddress("0xc27cadc437d067a6ec869502cc9f7F834cFc087a")
 83	addrForge := ethCommon.HexToAddress("0xCfAA413eEb796f328620a3630Ae39124cabcEa92")
 84	addrForge2 := ethCommon.HexToAddress("0x1fCb4ac309428feCc61B1C8cA5823C15A5e1a800")
 85
 86	var timer timer
 87	clientSetup := NewClientSetupExample()
 88	clientSetup.AuctionVariables.ClosedAuctionSlots = 2
 89	clientSetup.AuctionVariables.OpenAuctionSlots = 4320
 90	clientSetup.AuctionVariables.DefaultSlotSetBid = [6]*big.Int{
 91		big.NewInt(1000), big.NewInt(1100), big.NewInt(1200),
 92		big.NewInt(1300), big.NewInt(1400), big.NewInt(1500)}
 93	c := NewClient(true, &timer, &addrBidder1, clientSetup)
 94
 95	// Check several cases in which bid doesn't succed, and also do 2 successful bids.
 96
 97	_, err := c.AuctionBidSimple(0, big.NewInt(1))
 98	assert.Equal(t, errBidClosed, err)
 99
100	_, err = c.AuctionBidSimple(4322, big.NewInt(1))
101	assert.Equal(t, errBidNotOpen, err)
102
103	// 101 % 6 = 5;  defaultSlotSetBid[5] = 1500;  1500 + 10% = 1650
104	_, err = c.AuctionBidSimple(101, big.NewInt(1650))
105	assert.Equal(t, errCoordNotReg, err)
106
107	_, err = c.AuctionSetCoordinator(addrForge, "https://foo.bar")
108	assert.Nil(t, err)
109
110	_, err = c.AuctionBidSimple(3, big.NewInt(1))
111	assert.Equal(t, errBidBelowMin, err)
112
113	_, err = c.AuctionBidSimple(3, big.NewInt(1650))
114	assert.Nil(t, err)
115
116	c.CtlSetAddr(addrBidder2)
117	_, err = c.AuctionSetCoordinator(addrForge2, "https://foo2.bar")
118	assert.Nil(t, err)
119
120	_, err = c.AuctionBidSimple(3, big.NewInt(16))
121	assert.Equal(t, errBidBelowMin, err)
122
123	// 1650 + 10% = 1815
124	_, err = c.AuctionBidSimple(3, big.NewInt(1815))
125	assert.Nil(t, err)
126
127	c.CtlMineBlock()
128
129	blockNum, err := c.EthCurrentBlock()
130	require.Nil(t, err)
131
132	auctionEvents, _, err := c.AuctionEventsByBlock(blockNum)
133	require.Nil(t, err)
134	assert.Equal(t, 2, len(auctionEvents.NewBid))
135}
136
137func TestClientRollup(t *testing.T) {
138	token1Addr := ethCommon.HexToAddress("0x6b175474e89094c44da98b954eedeac495271d0f")
139
140	var timer timer
141	clientSetup := NewClientSetupExample()
142	c := NewClient(true, &timer, &ethCommon.Address{}, clientSetup)
143
144	// Add a token
145
146	tx, err := c.RollupAddTokenSimple(token1Addr, clientSetup.RollupVariables.FeeAddToken)
147	require.Nil(t, err)
148	assert.NotNil(t, tx)
149
150	// Add some L1UserTxs
151	// Create Accounts
152
153	const N = 16
154	var keys [N]*keys
155	for i := 0; i < N; i++ {
156		keys[i] = genKeys(int64(i))
157		tx := common.L1Tx{
158			FromIdx:     0,
159			FromEthAddr: keys[i].Addr,
160			FromBJJ:     keys[i].BJJPublicKey,
161			TokenID:     common.TokenID(0),
162			Amount:      big.NewInt(0),
163			LoadAmount:  big.NewInt(10 + int64(i)),
164		}
165		_, err := c.RollupL1UserTxERC20ETH(tx.FromBJJ, int64(tx.FromIdx), tx.LoadAmount,
166			tx.Amount, uint32(tx.TokenID), int64(tx.ToIdx))
167		require.Nil(t, err)
168	}
169	c.CtlMineBlock()
170
171	blockNum, err := c.EthCurrentBlock()
172	require.Nil(t, err)
173	rollupEvents, _, err := c.RollupEventsByBlock(blockNum)
174	require.Nil(t, err)
175	assert.Equal(t, N, len(rollupEvents.L1UserTx))
176	assert.Equal(t, 1, len(rollupEvents.AddToken))
177
178	// Forge a batch
179
180	c.CtlAddBatch(&eth.RollupForgeBatchArgs{
181		NewLastIdx:        0,
182		NewStRoot:         big.NewInt(1),
183		NewExitRoot:       big.NewInt(100),
184		L1CoordinatorTxs:  []common.L1Tx{},
185		L2TxsData:         []common.L2Tx{},
186		FeeIdxCoordinator: []common.Idx{},
187		VerifierIdx:       0,
188		L1Batch:           true,
189	})
190	c.CtlMineBlock()
191
192	blockNumA, err := c.EthCurrentBlock()
193	require.Nil(t, err)
194	rollupEvents, hashA, err := c.RollupEventsByBlock(blockNumA)
195	require.Nil(t, err)
196	assert.Equal(t, 0, len(rollupEvents.L1UserTx))
197	assert.Equal(t, 0, len(rollupEvents.AddToken))
198	assert.Equal(t, 1, len(rollupEvents.ForgeBatch))
199
200	// Simulate reorg discarding last mined block
201
202	c.CtlRollback()
203	c.CtlMineBlock()
204
205	blockNumB, err := c.EthCurrentBlock()
206	require.Nil(t, err)
207	rollupEvents, hashB, err := c.RollupEventsByBlock(blockNumA)
208	require.Nil(t, err)
209	assert.Equal(t, 0, len(rollupEvents.L1UserTx))
210	assert.Equal(t, 0, len(rollupEvents.AddToken))
211	assert.Equal(t, 0, len(rollupEvents.ForgeBatch))
212
213	assert.Equal(t, blockNumA, blockNumB)
214	assert.NotEqual(t, hashA, hashB)
215
216	// Forge again
217	rollupForgeBatchArgs0 := &eth.RollupForgeBatchArgs{
218		NewLastIdx:        0,
219		NewStRoot:         big.NewInt(1),
220		NewExitRoot:       big.NewInt(100),
221		L1CoordinatorTxs:  []common.L1Tx{},
222		L2TxsData:         []common.L2Tx{},
223		FeeIdxCoordinator: []common.Idx{},
224		VerifierIdx:       0,
225		L1Batch:           true,
226	}
227	c.CtlAddBatch(rollupForgeBatchArgs0)
228	c.CtlMineBlock()
229
230	// Retrieve ForgeBatchArguments starting from the events
231
232	blockNum, err = c.EthCurrentBlock()
233	require.Nil(t, err)
234	rollupEvents, _, err = c.RollupEventsByBlock(blockNum)
235	require.Nil(t, err)
236
237	rollupForgeBatchArgs1, sender, err := c.RollupForgeBatchArgs(rollupEvents.ForgeBatch[0].EthTxHash)
238	require.Nil(t, err)
239	assert.Equal(t, *c.addr, *sender)
240	assert.Equal(t, rollupForgeBatchArgs0, rollupForgeBatchArgs1)
241}
242
243type keys struct {
244	BJJSecretKey *babyjub.PrivateKey
245	BJJPublicKey *babyjub.PublicKey
246	Addr         ethCommon.Address
247}
248
249func genKeys(i int64) *keys {
250	i++ // i = 0 doesn't work for the ecdsa key generation
251	var sk babyjub.PrivateKey
252	binary.LittleEndian.PutUint64(sk[:], uint64(i))
253
254	// eth address
255	var key ecdsa.PrivateKey
256	key.D = big.NewInt(i) // only for testing
257	key.PublicKey.X, key.PublicKey.Y = ethCrypto.S256().ScalarBaseMult(key.D.Bytes())
258	key.Curve = ethCrypto.S256()
259	addr := ethCrypto.PubkeyToAddress(key.PublicKey)
260
261	return &keys{
262		BJJSecretKey: &sk,
263		BJJPublicKey: sk.Public(),
264		Addr:         addr,
265	}
266}