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}