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
 20var clientSetup *ClientSetup
 21
 22func init() {
 23	rollupConstants := &eth.RollupConstants{}
 24	rollupVariables := &eth.RollupVariables{
 25		MaxTxVerifiers:     make([]int, 0),
 26		TokenHEZ:           ethCommon.Address{},
 27		GovernanceAddress:  ethCommon.Address{},
 28		SafetyBot:          ethCommon.Address{},
 29		ConsensusContract:  ethCommon.Address{},
 30		WithdrawalContract: ethCommon.Address{},
 31		FeeAddToken:        big.NewInt(1),
 32		ForgeL1Timeout:     16,
 33		FeeL1UserTx:        big.NewInt(2),
 34	}
 35	auctionConstants := &eth.AuctionConstants{}
 36	auctionVariables := &eth.AuctionVariables{
 37		DonationAddress: ethCommon.Address{},
 38		BootCoordinator: ethCommon.Address{},
 39		MinBidEpoch: [6]*big.Int{
 40			big.NewInt(10), big.NewInt(11), big.NewInt(12),
 41			big.NewInt(13), big.NewInt(14), big.NewInt(15)},
 42		ClosedAuctionSlots: 0,
 43		OpenAuctionSlots:   0,
 44		AllocationRatio:    [3]uint8{},
 45		Outbidding:         0,
 46		SlotDeadline:       0,
 47	}
 48	clientSetup = &ClientSetup{
 49		RollupConstants:  rollupConstants,
 50		RollupVariables:  rollupVariables,
 51		AuctionConstants: auctionConstants,
 52		AuctionVariables: auctionVariables,
 53	}
 54}
 55
 56type timer struct {
 57	time int64
 58}
 59
 60func (t *timer) Time() int64 {
 61	currentTime := t.time
 62	t.time++
 63	return currentTime
 64}
 65
 66func TestClientInterface(t *testing.T) {
 67	var c eth.ClientInterface
 68	var timer timer
 69	client := NewClient(true, &timer, clientSetup)
 70	c = client
 71	require.NotNil(t, c)
 72}
 73
 74func TestEthClient(t *testing.T) {
 75	token1Addr := ethCommon.HexToAddress("0x6b175474e89094c44da98b954eedeac495271d0f")
 76
 77	var timer timer
 78	c := NewClient(true, &timer, clientSetup)
 79	blockNum, err := c.EthCurrentBlock()
 80	require.Nil(t, err)
 81	assert.Equal(t, int64(0), blockNum)
 82
 83	block, err := c.EthBlockByNumber(context.TODO(), 0)
 84	require.Nil(t, err)
 85	assert.Equal(t, int64(0), block.EthBlockNum)
 86	assert.Equal(t, time.Unix(0, 0), block.Timestamp)
 87	assert.Equal(t, "0x0000000000000000000000000000000000000000000000000000000000000000", block.Hash.Hex())
 88	assert.Equal(t, int64(0), c.blockNum)
 89
 90	// Mine some empty blocks
 91
 92	c.CtlMineBlock()
 93	assert.Equal(t, int64(1), c.blockNum)
 94	c.CtlMineBlock()
 95	assert.Equal(t, int64(2), c.blockNum)
 96
 97	block, err = c.EthBlockByNumber(context.TODO(), 2)
 98	require.Nil(t, err)
 99	assert.Equal(t, int64(2), block.EthBlockNum)
100	assert.Equal(t, time.Unix(2, 0), block.Timestamp)
101
102	// Add a token
103
104	tx, err := c.RollupAddToken(token1Addr)
105	require.Nil(t, err)
106	assert.NotNil(t, tx)
107
108	// Add some L1UserTxs
109	// Create Accounts
110
111	const N = 16
112	var keys [N]*keys
113	for i := 0; i < N; i++ {
114		keys[i] = genKeys(int64(i))
115		l1UserTx := common.L1Tx{
116			FromIdx:     common.Idx(0),
117			FromEthAddr: keys[i].Addr,
118			FromBJJ:     keys[i].BJJPublicKey,
119			TokenID:     common.TokenID(0),
120			LoadAmount:  big.NewInt(10 + int64(i)),
121		}
122		c.CtlAddL1TxUser(&l1UserTx)
123	}
124	c.CtlMineBlock()
125
126	blockNum, err = c.EthCurrentBlock()
127	require.Nil(t, err)
128	rollupEvents, _, err := c.RollupEventsByBlock(blockNum)
129	require.Nil(t, err)
130	assert.Equal(t, N, len(rollupEvents.L1UserTx))
131	assert.Equal(t, 1, len(rollupEvents.AddToken))
132
133	// Forge a batch
134
135	c.CtlAddBatch(&eth.RollupForgeBatchArgs{
136		NewLastIdx:        0,
137		NewStRoot:         big.NewInt(1),
138		NewExitRoot:       big.NewInt(100),
139		L1CoordinatorTxs:  []*common.L1Tx{},
140		L2Txs:             []*common.L2Tx{},
141		FeeIdxCoordinator: make([]common.Idx, eth.FeeIdxCoordinatorLen),
142		VerifierIdx:       0,
143		L1Batch:           true,
144	})
145	c.CtlMineBlock()
146
147	blockNumA, err := c.EthCurrentBlock()
148	require.Nil(t, err)
149	rollupEvents, hashA, err := c.RollupEventsByBlock(blockNumA)
150	require.Nil(t, err)
151	assert.Equal(t, 0, len(rollupEvents.L1UserTx))
152	assert.Equal(t, 0, len(rollupEvents.AddToken))
153	assert.Equal(t, 1, len(rollupEvents.ForgeBatch))
154
155	// Simulate reorg discarding last mined block
156
157	c.CtlRollback()
158	c.CtlMineBlock()
159
160	blockNumB, err := c.EthCurrentBlock()
161	require.Nil(t, err)
162	rollupEvents, hashB, err := c.RollupEventsByBlock(blockNumA)
163	require.Nil(t, err)
164	assert.Equal(t, 0, len(rollupEvents.L1UserTx))
165	assert.Equal(t, 0, len(rollupEvents.AddToken))
166	assert.Equal(t, 0, len(rollupEvents.ForgeBatch))
167
168	assert.Equal(t, blockNumA, blockNumB)
169	assert.NotEqual(t, hashA, hashB)
170
171	// Forge again
172	rollupForgeBatchArgs0 := &eth.RollupForgeBatchArgs{
173		NewLastIdx:        0,
174		NewStRoot:         big.NewInt(1),
175		NewExitRoot:       big.NewInt(100),
176		L1CoordinatorTxs:  []*common.L1Tx{},
177		L2Txs:             []*common.L2Tx{},
178		FeeIdxCoordinator: make([]common.Idx, eth.FeeIdxCoordinatorLen),
179		VerifierIdx:       0,
180		L1Batch:           true,
181	}
182	c.CtlAddBatch(rollupForgeBatchArgs0)
183	c.CtlMineBlock()
184
185	// Retrieve ForgeBatchArguments starting from the events
186
187	blockNum, err = c.EthCurrentBlock()
188	require.Nil(t, err)
189	rollupEvents, _, err = c.RollupEventsByBlock(blockNum)
190	require.Nil(t, err)
191
192	rollupForgeBatchArgs1, err := c.RollupForgeBatchArgs(rollupEvents.ForgeBatch[0].EthTxHash)
193	require.Nil(t, err)
194	assert.Equal(t, rollupForgeBatchArgs0, rollupForgeBatchArgs1)
195}
196
197type keys struct {
198	BJJSecretKey *babyjub.PrivateKey
199	BJJPublicKey *babyjub.PublicKey
200	Addr         ethCommon.Address
201}
202
203func genKeys(i int64) *keys {
204	i++ // i = 0 doesn't work for the ecdsa key generation
205	var sk babyjub.PrivateKey
206	binary.LittleEndian.PutUint64(sk[:], uint64(i))
207
208	// eth address
209	var key ecdsa.PrivateKey
210	key.D = big.NewInt(i) // only for testing
211	key.PublicKey.X, key.PublicKey.Y = ethCrypto.S256().ScalarBaseMult(key.D.Bytes())
212	key.Curve = ethCrypto.S256()
213	addr := ethCrypto.PubkeyToAddress(key.PublicKey)
214
215	return &keys{
216		BJJSecretKey: &sk,
217		BJJPublicKey: sk.Public(),
218		Addr:         addr,
219	}
220}