arnaucube
arnaucube/hermez-nodePublic Self-hosted repository
hermez-node/test/zkproof/zkproof_test.go
test/zkproof/zkproof_test.goRaw
  1package zkproof
  2
  3import (
  4	"context"
  5	"encoding/hex"
  6	"encoding/json"
  7	"fmt"
  8	"io/ioutil"
  9	"math/big"
 10	"os"
 11	"strconv"
 12	"testing"
 13	"time"
 14
 15	ethCommon "github.com/ethereum/go-ethereum/common"
 16	"github.com/hermeznetwork/hermez-node/common"
 17	"github.com/hermeznetwork/hermez-node/db/statedb"
 18	"github.com/hermeznetwork/hermez-node/prover"
 19	"github.com/hermeznetwork/hermez-node/test/til"
 20	"github.com/hermeznetwork/hermez-node/txprocessor"
 21	"github.com/iden3/go-iden3-crypto/babyjub"
 22	"github.com/stretchr/testify/assert"
 23	"github.com/stretchr/testify/require"
 24)
 25
 26var proofServerURL string
 27
 28const pollInterval = 200 * time.Millisecond
 29
 30func TestMain(m *testing.M) {
 31	exitVal := 0
 32	proofServerURL = os.Getenv("PROOF_SERVER_URL")
 33	if proofServerURL != "" {
 34		exitVal = m.Run()
 35	}
 36	os.Exit(exitVal)
 37}
 38
 39func generateJsUsers(t *testing.T) []til.User {
 40	// same values than in the js test
 41	// skJsHex is equivalent to the 0000...000i js private key in commonjs
 42	skJsHex := []string{"7eb258e61862aae75c6c1d1f7efae5006ffc9e4d5596a6ff95f3df4ea209ea7f", "c005700f76f4b4cec710805c21595688648524df0a9d467afae537b7a7118819", "b373d14c67fb2a517bf4ac831c93341eec8e1b38dbc14e7d725b292a7cf84707", "2064b68d04a7aaae0ac3b36bf6f1850b380f1423be94a506c531940bd4a48b76"}
 43	addrHex := []string{"0x7e5f4552091a69125d5dfcb7b8c2659029395bdf", "0x2b5ad5c4795c026514f8317c7a215e218dccd6cf", "0x6813eb9362372eef6200f3b1dbc3f819671cba69", "0x1eff47bc3a10a45d4b230b5d10e37751fe6aa718"}
 44	var users []til.User
 45	for i := 0; i < len(skJsHex); i++ {
 46		skJs, err := hex.DecodeString(skJsHex[i])
 47		require.NoError(t, err)
 48		var sk babyjub.PrivateKey
 49		copy(sk[:], skJs)
 50		// bjj := sk.Public()
 51		user := til.User{
 52			Name: strconv.Itoa(i),
 53			BJJ:  &sk,
 54			Addr: ethCommon.HexToAddress(addrHex[i]),
 55		}
 56		users = append(users, user)
 57	}
 58	assert.Equal(t, "d746824f7d0ac5044a573f51b278acb56d823bec39551d1d7bf7378b68a1b021", users[0].BJJ.Public().String())
 59	assert.Equal(t, "4d05c307400c65795f02db96b1b81c60386fd53e947d9d3f749f3d99b1853909", users[1].BJJ.Public().String())
 60	assert.Equal(t, "38ffa002724562eb2a952a2503e206248962406cf16392ff32759b6f2a41fe11", users[2].BJJ.Public().String())
 61	assert.Equal(t, "c719e6401190be7fa7fbfcd3448fe2755233c01575341a3b09edadf5454f760b", users[3].BJJ.Public().String())
 62
 63	return users
 64}
 65
 66func signL2Tx(t *testing.T, chainID uint16, user til.User, l2Tx common.PoolL2Tx) common.PoolL2Tx {
 67	toSign, err := l2Tx.HashToSign(chainID)
 68	require.NoError(t, err)
 69	sig := user.BJJ.SignPoseidon(toSign)
 70	l2Tx.Signature = sig.Compress()
 71	return l2Tx
 72}
 73
 74const MaxTx = 376
 75const NLevels = 32
 76const MaxL1Tx = 256
 77const MaxFeeTx = 64
 78const ChainID uint16 = 1
 79
 80func TestTxProcessor(t *testing.T) {
 81	dir, err := ioutil.TempDir("", "tmpdb")
 82	require.NoError(t, err)
 83	defer assert.Nil(t, os.RemoveAll(dir))
 84
 85	sdb, err := statedb.NewStateDB(dir, 128, statedb.TypeBatchBuilder, NLevels)
 86	require.NoError(t, err)
 87
 88	// same values than in the js test
 89	users := generateJsUsers(t)
 90
 91	l1Txs := []common.L1Tx{
 92		{
 93			FromIdx:       0,
 94			DepositAmount: big.NewInt(16000000),
 95			Amount:        big.NewInt(0),
 96			TokenID:       1,
 97			FromBJJ:       users[0].BJJ.Public().Compress(),
 98			FromEthAddr:   users[0].Addr,
 99			ToIdx:         0,
100			Type:          common.TxTypeCreateAccountDeposit,
101			UserOrigin:    true,
102		},
103		{
104			FromIdx:       0,
105			DepositAmount: big.NewInt(16000000),
106			Amount:        big.NewInt(0),
107			TokenID:       1,
108			FromBJJ:       users[1].BJJ.Public().Compress(),
109			FromEthAddr:   users[1].Addr,
110			ToIdx:         0,
111			Type:          common.TxTypeCreateAccountDeposit,
112			UserOrigin:    true,
113		},
114		{
115			FromIdx:       257,
116			DepositAmount: big.NewInt(0),
117			Amount:        big.NewInt(1000),
118			TokenID:       1,
119			FromBJJ:       users[1].BJJ.Public().Compress(),
120			FromEthAddr:   users[1].Addr,
121			ToIdx:         1,
122			Type:          common.TxTypeForceExit,
123			UserOrigin:    true,
124		},
125	}
126	l2Txs := []common.PoolL2Tx{
127		{
128			FromIdx: 256,
129			ToIdx:   257,
130			TokenID: 1,
131			Amount:  big.NewInt(1000),
132			Nonce:   0,
133			Fee:     126,
134			Type:    common.TxTypeTransfer,
135		},
136		{
137			FromIdx: 256,
138			ToIdx:   1,
139			TokenID: 1,
140			Amount:  big.NewInt(1000),
141			Nonce:   1,
142			Fee:     126,
143			Type:    common.TxTypeExit,
144		},
145	}
146
147	l2Txs[0] = signL2Tx(t, ChainID, users[0], l2Txs[0])
148	l2Txs[1] = signL2Tx(t, ChainID, users[0], l2Txs[1])
149
150	config := txprocessor.Config{
151		NLevels:  uint32(NLevels),
152		MaxTx:    MaxTx,
153		MaxL1Tx:  MaxL1Tx,
154		MaxFeeTx: MaxFeeTx,
155		ChainID:  ChainID,
156	}
157	tp := txprocessor.NewTxProcessor(sdb, config)
158
159	// skip first batch to do the test with BatchNum=1
160	_, err = tp.ProcessTxs(nil, nil, nil, nil)
161	require.NoError(t, err)
162
163	coordIdxs := []common.Idx{257}
164	ptOut, err := tp.ProcessTxs(coordIdxs, l1Txs, nil, l2Txs)
165	require.NoError(t, err)
166
167	// Store zkinputs json for debugging purposes
168	zkInputsJSON, err := json.Marshal(ptOut.ZKInputs)
169	require.NoError(t, err)
170	err = ioutil.WriteFile("/tmp/dbgZKInputs.json", zkInputsJSON, 0640) //nolint:gosec
171	require.NoError(t, err)
172
173	proofServerClient := prover.NewProofServerClient(proofServerURL, pollInterval)
174	err = proofServerClient.WaitReady(context.Background())
175	require.NoError(t, err)
176	err = proofServerClient.CalculateProof(context.Background(), ptOut.ZKInputs)
177	require.NoError(t, err)
178	proof, pubInputs, err := proofServerClient.GetProof(context.Background())
179	require.NoError(t, err)
180	fmt.Printf("proof: %#v\n", proof)
181	fmt.Printf("pubInputs: %#v\n", pubInputs)
182}