arnaucube
arnaucube/hermez-nodePublic Self-hosted repository
hermez-node/test/transakcio/txs_test.go
test/transakcio/txs_test.goRaw
  1package transakcio
  2
  3import (
  4	"math/big"
  5	"testing"
  6
  7	"github.com/hermeznetwork/hermez-node/common"
  8	"github.com/stretchr/testify/assert"
  9	"github.com/stretchr/testify/require"
 10)
 11
 12func TestGenerateBlocks(t *testing.T) {
 13	set := `
 14		Type: Blockchain
 15		RegisterToken(1)
 16		RegisterToken(2)
 17		RegisterToken(3)
 18	
 19		CreateAccountDeposit(1) A: 10
 20		CreateAccountDeposit(2) A: 20
 21		CreateAccountDeposit(1) B: 5
 22		CreateAccountDeposit(1) C: 5
 23		CreateAccountDepositTransfer(1) D-A: 15, 10 (3)
 24
 25		Transfer(1) A-B: 6 (1)
 26		Transfer(1) B-D: 3 (1)
 27		Transfer(1) A-D: 1 (1)
 28
 29		// set new batch
 30		> batch
 31		CreateAccountDepositCoordinator(1) E
 32		CreateAccountDepositCoordinator(2) B
 33
 34		DepositTransfer(1) A-B: 15, 10 (1)
 35		Transfer(1) C-A : 3 (1)
 36		Transfer(2) A-B: 15 (1)
 37		Transfer(1) A-E: 1 (1)
 38
 39		CreateAccountDeposit(1) User0: 20
 40		CreateAccountDeposit(3) User1: 20
 41		CreateAccountDepositCoordinator(1) User1
 42		CreateAccountDepositCoordinator(3) User0
 43		Transfer(1) User0-User1: 15 (1)
 44		Transfer(3) User1-User0: 15 (1)
 45		Transfer(1) A-C: 1 (1)
 46
 47		> batch
 48
 49		Transfer(1) User1-User0: 1 (1)
 50
 51		> block
 52
 53		// Exits
 54		Transfer(1) A-B: 1 (1)
 55		Exit(1) A: 5
 56	`
 57	tc := NewTestContext()
 58	blocks, err := tc.GenerateBlocks(set)
 59	require.Nil(t, err)
 60	assert.Equal(t, 2, len(blocks))
 61	assert.Equal(t, 3, len(blocks[0].Batches))
 62	assert.Equal(t, 1, len(blocks[1].Batches))
 63	assert.Equal(t, 5, len(blocks[0].Batches[0].L1UserTxs))
 64	assert.Equal(t, 4, len(blocks[0].Batches[1].L1CoordinatorTxs))
 65	assert.Equal(t, 0, len(blocks[1].Batches[0].L1UserTxs))
 66
 67	// Check expected values generated by each line
 68	// #0: Deposit(1) A: 10
 69	tc.checkL1TxParams(t, blocks[0].Batches[0].L1UserTxs[0], common.TxTypeCreateAccountDeposit, 1, "A", "", big.NewInt(10), nil)
 70	// #1: Deposit(2) A: 20
 71	tc.checkL1TxParams(t, blocks[0].Batches[0].L1UserTxs[1], common.TxTypeCreateAccountDeposit, 2, "A", "", big.NewInt(20), nil)
 72	// #2: Deposit(1) A: 20
 73	tc.checkL1TxParams(t, blocks[0].Batches[0].L1UserTxs[2], common.TxTypeCreateAccountDeposit, 1, "B", "", big.NewInt(5), nil)
 74	// #3: CreateAccountDeposit(1) C: 5
 75	tc.checkL1TxParams(t, blocks[0].Batches[0].L1UserTxs[3], common.TxTypeCreateAccountDeposit, 1, "C", "", big.NewInt(5), nil)
 76	// #4: CreateAccountDepositTransfer(1) D-A: 15, 10 (3)
 77	tc.checkL1TxParams(t, blocks[0].Batches[0].L1UserTxs[4], common.TxTypeCreateAccountDepositTransfer, 1, "D", "A", big.NewInt(15), big.NewInt(10))
 78	// #5: Transfer(1) A-B: 6 (1)
 79	tc.checkL2TxParams(t, blocks[0].Batches[0].L2Txs[0], common.TxTypeTransfer, 1, "A", "B", big.NewInt(6), common.BatchNum(0), common.Nonce(1))
 80	// #6: Transfer(1) B-D: 3 (1)
 81	tc.checkL2TxParams(t, blocks[0].Batches[0].L2Txs[1], common.TxTypeTransfer, 1, "B", "D", big.NewInt(3), common.BatchNum(0), common.Nonce(1))
 82	// #7: Transfer(1) A-D: 1 (1)
 83	tc.checkL2TxParams(t, blocks[0].Batches[0].L2Txs[2], common.TxTypeTransfer, 1, "A", "D", big.NewInt(1), common.BatchNum(0), common.Nonce(2))
 84	// change of Batch
 85	// #8: DepositTransfer(1) A-B: 15, 10 (1)
 86	tc.checkL1TxParams(t, blocks[0].Batches[1].L1UserTxs[0], common.TxTypeDepositTransfer, 1, "A", "B", big.NewInt(15), big.NewInt(10))
 87	// #9: Deposit(1) User0: 20
 88	tc.checkL1TxParams(t, blocks[0].Batches[1].L1UserTxs[0], common.TxTypeDepositTransfer, 1, "A", "B", big.NewInt(15), big.NewInt(10))
 89	// #10: Transfer(1) C-A : 3 (1)
 90	tc.checkL2TxParams(t, blocks[0].Batches[1].L2Txs[0], common.TxTypeTransfer, 1, "C", "A", big.NewInt(3), common.BatchNum(1), common.Nonce(1))
 91	// #11: Transfer(2) A-B: 15 (1)
 92	tc.checkL2TxParams(t, blocks[0].Batches[1].L2Txs[1], common.TxTypeTransfer, 2, "A", "B", big.NewInt(15), common.BatchNum(1), common.Nonce(1))
 93	// #12: Deposit(1) User0: 20
 94	tc.checkL1TxParams(t, blocks[0].Batches[1].L1UserTxs[1], common.TxTypeCreateAccountDeposit, 1, "User0", "", big.NewInt(20), nil)
 95	// #13: Deposit(3) User1: 20
 96	tc.checkL1TxParams(t, blocks[0].Batches[1].L1UserTxs[2], common.TxTypeCreateAccountDeposit, 3, "User1", "", big.NewInt(20), nil)
 97	// #14: Transfer(1) User0-User1: 15 (1)
 98	tc.checkL2TxParams(t, blocks[0].Batches[1].L2Txs[3], common.TxTypeTransfer, 1, "User0", "User1", big.NewInt(15), common.BatchNum(1), common.Nonce(1))
 99	// #15: Transfer(3) User1-User0: 15 (1)
100	tc.checkL2TxParams(t, blocks[0].Batches[1].L2Txs[4], common.TxTypeTransfer, 3, "User1", "User0", big.NewInt(15), common.BatchNum(1), common.Nonce(1))
101	// #16: Transfer(1) A-C: 1 (1)
102	tc.checkL2TxParams(t, blocks[0].Batches[1].L2Txs[5], common.TxTypeTransfer, 1, "A", "C", big.NewInt(1), common.BatchNum(1), common.Nonce(4))
103	// change of Batch
104	// #17: Transfer(1) User1-User0: 1 (1)
105	tc.checkL2TxParams(t, blocks[0].Batches[2].L2Txs[0], common.TxTypeTransfer, 1, "User1", "User0", big.NewInt(1), common.BatchNum(2), common.Nonce(1))
106	// change of Block (implies also a change of batch)
107	// #18: Transfer(1) A-B: 1 (1)
108	tc.checkL2TxParams(t, blocks[1].Batches[0].L2Txs[0], common.TxTypeTransfer, 1, "A", "B", big.NewInt(1), common.BatchNum(3), common.Nonce(5))
109}
110
111func (tc *TestContext) checkL1TxParams(t *testing.T, tx common.L1Tx, typ common.TxType, tokenID common.TokenID, from, to string, loadAmount, amount *big.Int) {
112	assert.Equal(t, typ, tx.Type)
113	if tx.FromIdx != common.Idx(0) {
114		assert.Equal(t, tc.Users[from].Accounts[tokenID].Idx, tx.FromIdx)
115	}
116	assert.Equal(t, tc.Users[from].Addr.Hex(), tx.FromEthAddr.Hex())
117	assert.Equal(t, tc.Users[from].BJJ.Public(), tx.FromBJJ)
118	if tx.ToIdx != common.Idx(0) {
119		assert.Equal(t, tc.Users[to].Accounts[tokenID].Idx, tx.ToIdx)
120	}
121	if loadAmount != nil {
122		assert.Equal(t, loadAmount, tx.LoadAmount)
123	}
124	if amount != nil {
125		assert.Equal(t, amount, tx.Amount)
126	}
127}
128func (tc *TestContext) checkL2TxParams(t *testing.T, tx common.L2Tx, typ common.TxType, tokenID common.TokenID, from, to string, amount *big.Int, batchNum common.BatchNum, nonce common.Nonce) {
129	assert.Equal(t, typ, tx.Type)
130	assert.Equal(t, tc.Users[from].Accounts[tokenID].Idx, tx.FromIdx)
131	if tx.Type != common.TxTypeExit {
132		assert.Equal(t, tc.Users[to].Accounts[tokenID].Idx, tx.ToIdx)
133	}
134	if amount != nil {
135		assert.Equal(t, amount, tx.Amount)
136	}
137	assert.Equal(t, batchNum, tx.BatchNum)
138	assert.Equal(t, nonce, tx.Nonce)
139}
140
141func TestGeneratePoolL2Txs(t *testing.T) {
142	set := `
143		Type: Blockchain
144		RegisterToken(1)
145		RegisterToken(2)
146		RegisterToken(3)
147	
148		CreateAccountDeposit(1) A: 10
149		CreateAccountDeposit(2) A: 20
150		CreateAccountDeposit(1) B: 5
151		CreateAccountDeposit(1) C: 5
152		CreateAccountDeposit(1) User0: 5
153		CreateAccountDeposit(1) User1: 0
154		CreateAccountDeposit(3) User0: 0
155		CreateAccountDeposit(3) User1: 5
156		CreateAccountDeposit(2) B: 5
157		CreateAccountDeposit(2) D: 0
158	`
159	tc := NewTestContext()
160	_, err := tc.GenerateBlocks(set)
161	require.Nil(t, err)
162	set = `
163		Type: PoolL2
164		PoolTransfer(1) A-B: 6 (1)
165		PoolTransfer(1) B-C: 3 (1)
166		PoolTransfer(1) C-A: 3 (1)
167		PoolTransfer(1) A-B: 1 (1)
168		PoolTransfer(2) A-B: 15 (1)
169		PoolTransfer(1) User0-User1: 15 (1)
170		PoolTransfer(3) User1-User0: 15 (1)
171		PoolTransfer(2) B-D: 3 (1)
172		PoolExit(1) A: 3
173	`
174	poolL2Txs, err := tc.GeneratePoolL2Txs(set)
175	require.Nil(t, err)
176	assert.Equal(t, 9, len(poolL2Txs))
177	assert.Equal(t, common.TxTypeTransfer, poolL2Txs[0].Type)
178	assert.Equal(t, common.TxTypeExit, poolL2Txs[8].Type)
179	assert.Equal(t, tc.Users["B"].Addr.Hex(), poolL2Txs[0].ToEthAddr.Hex())
180	assert.Equal(t, tc.Users["B"].BJJ.Public().String(), poolL2Txs[0].ToBJJ.String())
181	assert.Equal(t, tc.Users["User1"].Addr.Hex(), poolL2Txs[5].ToEthAddr.Hex())
182	assert.Equal(t, tc.Users["User1"].BJJ.Public().String(), poolL2Txs[5].ToBJJ.String())
183
184	assert.Equal(t, common.Nonce(1), poolL2Txs[0].Nonce)
185	assert.Equal(t, common.Nonce(2), poolL2Txs[3].Nonce)
186	assert.Equal(t, common.Nonce(3), poolL2Txs[8].Nonce)
187
188	// load another set in the same TestContext
189	set = `
190		Type: PoolL2
191		PoolTransfer(1) A-B: 6 (1)
192		PoolTransfer(1) B-C: 3 (1)
193		PoolTransfer(1) A-C: 3 (1)
194	`
195	poolL2Txs, err = tc.GeneratePoolL2Txs(set)
196	require.Nil(t, err)
197	assert.Equal(t, common.Nonce(4), poolL2Txs[0].Nonce)
198	assert.Equal(t, common.Nonce(2), poolL2Txs[1].Nonce)
199	assert.Equal(t, common.Nonce(5), poolL2Txs[2].Nonce)
200}
201
202func TestGenerateErrors(t *testing.T) {
203	// unregistered token
204	set := `Type: Blockchain
205		CreateAccountDeposit(1) A: 5
206		`
207	tc := NewTestContext()
208	_, err := tc.GenerateBlocks(set)
209	assert.Equal(t, "Can not process CreateAccountDeposit: TokenID 1 not registered, last registered TokenID: 0", err.Error())
210
211	// ensure RegisterToken sequentiality and not using 0
212	set = `
213		Type: Blockchain
214		RegisterToken(0)
215	`
216	tc = NewTestContext()
217	_, err = tc.GenerateBlocks(set)
218	require.Equal(t, "RegisterToken can not register TokenID 0", err.Error())
219
220	set = `
221		Type: Blockchain
222		RegisterToken(2)
223	`
224	tc = NewTestContext()
225	_, err = tc.GenerateBlocks(set)
226	require.Equal(t, "RegisterToken TokenID should be sequential, expected TokenID: 1, defined TokenID: 2", err.Error())
227
228	set = `
229		Type: Blockchain
230		RegisterToken(1)
231		RegisterToken(2)
232		RegisterToken(3)
233		RegisterToken(5)
234	`
235	tc = NewTestContext()
236	_, err = tc.GenerateBlocks(set)
237	require.Equal(t, "RegisterToken TokenID should be sequential, expected TokenID: 4, defined TokenID: 5", err.Error())
238}