mirror of
https://github.com/arnaucube/hermez-node.git
synced 2026-02-07 11:26:44 +01:00
- KVDB/StateDB
- Pass config parameters in a Config type instead of using many
arguments in constructor.
- Add new parameter `NoLast` which disables having an opened DB with a
checkpoint to the last batchNum for thread-safe reads. Last will be
disabled in the StateDB used by the TxSelector and BatchBuilder.
- Add new parameter `NoGapsCheck` which skips checking gaps in the list
of checkpoints and returning errors if there are gaps. Gaps check
will be disabled in the StateDB used by the TxSelector and
BatchBuilder, because we expect to have gaps when there are multiple
coordinators forging (slots not forged by our coordinator will leave
gaps).
297 lines
9.4 KiB
Go
297 lines
9.4 KiB
Go
package zkproof
|
|
|
|
import (
|
|
"context"
|
|
"encoding/json"
|
|
"fmt"
|
|
"io/ioutil"
|
|
"os"
|
|
"testing"
|
|
"time"
|
|
|
|
"github.com/hermeznetwork/hermez-node/common"
|
|
"github.com/hermeznetwork/hermez-node/db/statedb"
|
|
"github.com/hermeznetwork/hermez-node/log"
|
|
"github.com/hermeznetwork/hermez-node/prover"
|
|
"github.com/hermeznetwork/hermez-node/test/til"
|
|
"github.com/hermeznetwork/hermez-node/test/txsets"
|
|
"github.com/hermeznetwork/hermez-node/txprocessor"
|
|
"github.com/stretchr/testify/assert"
|
|
"github.com/stretchr/testify/require"
|
|
)
|
|
|
|
var proofServerURL string
|
|
|
|
const pollInterval = 200 * time.Millisecond
|
|
|
|
func TestMain(m *testing.M) {
|
|
exitVal := 0
|
|
proofServerURL = os.Getenv("PROOF_SERVER_URL")
|
|
exitVal = m.Run()
|
|
os.Exit(exitVal)
|
|
}
|
|
|
|
const MaxTx = 376
|
|
const NLevels = 32
|
|
const MaxL1Tx = 256
|
|
const MaxFeeTx = 64
|
|
const ChainID uint16 = 1
|
|
|
|
var txprocConfig = txprocessor.Config{
|
|
NLevels: uint32(NLevels),
|
|
MaxTx: MaxTx,
|
|
MaxL1Tx: MaxL1Tx,
|
|
MaxFeeTx: MaxFeeTx,
|
|
ChainID: ChainID,
|
|
}
|
|
|
|
func initStateDB(t *testing.T, typ statedb.TypeStateDB) *statedb.StateDB {
|
|
dir, err := ioutil.TempDir("", "tmpdb")
|
|
require.NoError(t, err)
|
|
defer assert.Nil(t, os.RemoveAll(dir))
|
|
|
|
sdb, err := statedb.NewStateDB(statedb.Config{Path: dir, Keep: 128, Type: typ, NLevels: NLevels})
|
|
require.NoError(t, err)
|
|
return sdb
|
|
}
|
|
|
|
func sendProofAndCheckResp(t *testing.T, zki *common.ZKInputs) {
|
|
if proofServerURL == "" {
|
|
log.Debug("No PROOF_SERVER_URL defined, not using ProofServer")
|
|
return
|
|
}
|
|
|
|
// Store zkinputs json for debugging purposes
|
|
zkInputsJSON, err := json.Marshal(zki)
|
|
require.NoError(t, err)
|
|
err = ioutil.WriteFile("/tmp/dbgZKInputs.json", zkInputsJSON, 0640) //nolint:gosec
|
|
require.NoError(t, err)
|
|
|
|
proofServerClient := prover.NewProofServerClient(proofServerURL, pollInterval)
|
|
err = proofServerClient.WaitReady(context.Background())
|
|
require.NoError(t, err)
|
|
err = proofServerClient.CalculateProof(context.Background(), zki)
|
|
require.NoError(t, err)
|
|
proof, pubInputs, err := proofServerClient.GetProof(context.Background())
|
|
require.NoError(t, err)
|
|
fmt.Printf("proof: %#v\n", proof)
|
|
fmt.Printf("pubInputs: %#v\n", pubInputs)
|
|
}
|
|
|
|
func TestZKInputsEmpty(t *testing.T) {
|
|
sdb := initStateDB(t, statedb.TypeBatchBuilder)
|
|
|
|
tp := txprocessor.NewTxProcessor(sdb, txprocConfig)
|
|
|
|
coordIdxs := []common.Idx{}
|
|
l1UserTxs := []common.L1Tx{}
|
|
l1CoordTxs := []common.L1Tx{}
|
|
l2Txs := []common.PoolL2Tx{}
|
|
ptOut, err := tp.ProcessTxs(coordIdxs, l1UserTxs, l1CoordTxs, l2Txs)
|
|
require.NoError(t, err)
|
|
|
|
sendProofAndCheckResp(t, ptOut.ZKInputs) // test empty batch ZKInputs
|
|
|
|
_, coordIdxs, l1UserTxs, l1CoordTxs, l2Txs = txsets.GenerateTxsZKInputs0(t, ChainID)
|
|
|
|
_, err = tp.ProcessTxs(coordIdxs, l1UserTxs, l1CoordTxs, l2Txs)
|
|
require.NoError(t, err)
|
|
|
|
coordIdxs = []common.Idx{}
|
|
l1UserTxs = []common.L1Tx{}
|
|
l1CoordTxs = []common.L1Tx{}
|
|
l2Txs = []common.PoolL2Tx{}
|
|
ptOut, err = tp.ProcessTxs(coordIdxs, l1UserTxs, l1CoordTxs, l2Txs)
|
|
require.NoError(t, err)
|
|
sendProofAndCheckResp(t, ptOut.ZKInputs) // test empty batch ZKInputs after a non-empty batch
|
|
}
|
|
|
|
func TestZKInputs0(t *testing.T) {
|
|
sdb := initStateDB(t, statedb.TypeBatchBuilder)
|
|
|
|
_, coordIdxs, l1UserTxs, l1CoordTxs, l2Txs := txsets.GenerateTxsZKInputs0(t, ChainID)
|
|
|
|
tp := txprocessor.NewTxProcessor(sdb, txprocConfig)
|
|
ptOut, err := tp.ProcessTxs(coordIdxs, l1UserTxs, l1CoordTxs, l2Txs)
|
|
require.NoError(t, err)
|
|
|
|
sendProofAndCheckResp(t, ptOut.ZKInputs)
|
|
}
|
|
func TestZKInputs1(t *testing.T) {
|
|
sdb := initStateDB(t, statedb.TypeBatchBuilder)
|
|
|
|
_, coordIdxs, l1UserTxs, l1CoordTxs, l2Txs := txsets.GenerateTxsZKInputs1(t, ChainID)
|
|
|
|
tp := txprocessor.NewTxProcessor(sdb, txprocConfig)
|
|
ptOut, err := tp.ProcessTxs(coordIdxs, l1UserTxs, l1CoordTxs, l2Txs)
|
|
require.NoError(t, err)
|
|
|
|
sendProofAndCheckResp(t, ptOut.ZKInputs)
|
|
}
|
|
func TestZKInputs2(t *testing.T) {
|
|
sdb := initStateDB(t, statedb.TypeBatchBuilder)
|
|
|
|
_, coordIdxs, l1UserTxs, l1CoordTxs, l2Txs := txsets.GenerateTxsZKInputs2(t, ChainID)
|
|
|
|
tp := txprocessor.NewTxProcessor(sdb, txprocConfig)
|
|
ptOut, err := tp.ProcessTxs(coordIdxs, l1UserTxs, l1CoordTxs, l2Txs)
|
|
require.NoError(t, err)
|
|
|
|
sendProofAndCheckResp(t, ptOut.ZKInputs)
|
|
}
|
|
func TestZKInputs3(t *testing.T) {
|
|
sdb := initStateDB(t, statedb.TypeBatchBuilder)
|
|
|
|
_, coordIdxs, l1UserTxs, l1CoordTxs, l2Txs := txsets.GenerateTxsZKInputs3(t, ChainID)
|
|
|
|
tp := txprocessor.NewTxProcessor(sdb, txprocConfig)
|
|
ptOut, err := tp.ProcessTxs(coordIdxs, l1UserTxs, l1CoordTxs, l2Txs)
|
|
require.NoError(t, err)
|
|
|
|
sendProofAndCheckResp(t, ptOut.ZKInputs)
|
|
}
|
|
func TestZKInputs4(t *testing.T) {
|
|
sdb := initStateDB(t, statedb.TypeBatchBuilder)
|
|
|
|
_, coordIdxs, l1UserTxs, l1CoordTxs, l2Txs := txsets.GenerateTxsZKInputs4(t, ChainID)
|
|
|
|
tp := txprocessor.NewTxProcessor(sdb, txprocConfig)
|
|
ptOut, err := tp.ProcessTxs(coordIdxs, l1UserTxs, l1CoordTxs, l2Txs)
|
|
require.NoError(t, err)
|
|
|
|
sendProofAndCheckResp(t, ptOut.ZKInputs)
|
|
}
|
|
|
|
func TestZKInputs5(t *testing.T) {
|
|
sdb := initStateDB(t, statedb.TypeBatchBuilder)
|
|
|
|
_, coordIdxs, l1UserTxs, l1CoordTxs, l2Txs := txsets.GenerateTxsZKInputs5(t, ChainID)
|
|
|
|
tp := txprocessor.NewTxProcessor(sdb, txprocConfig)
|
|
ptOut, err := tp.ProcessTxs(coordIdxs, l1UserTxs, l1CoordTxs, l2Txs)
|
|
require.NoError(t, err)
|
|
|
|
sendProofAndCheckResp(t, ptOut.ZKInputs)
|
|
}
|
|
|
|
func TestZKInputs6(t *testing.T) {
|
|
sdb := initStateDB(t, statedb.TypeBatchBuilder)
|
|
|
|
tc := til.NewContext(ChainID, common.RollupConstMaxL1UserTx)
|
|
blocks, err := tc.GenerateBlocks(txsets.SetBlockchainMinimumFlow0)
|
|
require.NoError(t, err)
|
|
|
|
// restart nonces of TilContext, as will be set by generating directly
|
|
// the PoolL2Txs for each specific batch with tc.GeneratePoolL2Txs
|
|
tc.RestartNonces()
|
|
|
|
tp := txprocessor.NewTxProcessor(sdb, txprocConfig)
|
|
// batch1
|
|
ptOut, err := tp.ProcessTxs(nil, nil, blocks[0].Rollup.Batches[0].L1CoordinatorTxs, nil)
|
|
require.NoError(t, err)
|
|
|
|
sendProofAndCheckResp(t, ptOut.ZKInputs)
|
|
|
|
// batch2
|
|
l1UserTxs := []common.L1Tx{}
|
|
l2Txs := common.L2TxsToPoolL2Txs(blocks[0].Rollup.Batches[1].L2Txs)
|
|
ptOut, err = tp.ProcessTxs(nil, l1UserTxs, blocks[0].Rollup.Batches[1].L1CoordinatorTxs, l2Txs)
|
|
require.NoError(t, err)
|
|
|
|
sendProofAndCheckResp(t, ptOut.ZKInputs)
|
|
|
|
// batch3
|
|
l1UserTxs = til.L1TxsToCommonL1Txs(tc.Queues[*blocks[0].Rollup.Batches[2].Batch.ForgeL1TxsNum])
|
|
l2Txs = common.L2TxsToPoolL2Txs(blocks[0].Rollup.Batches[2].L2Txs)
|
|
ptOut, err = tp.ProcessTxs(nil, l1UserTxs, blocks[0].Rollup.Batches[2].L1CoordinatorTxs, l2Txs)
|
|
require.NoError(t, err)
|
|
|
|
sendProofAndCheckResp(t, ptOut.ZKInputs)
|
|
|
|
// batch4
|
|
l1UserTxs = til.L1TxsToCommonL1Txs(tc.Queues[*blocks[0].Rollup.Batches[3].Batch.ForgeL1TxsNum])
|
|
l2Txs = common.L2TxsToPoolL2Txs(blocks[0].Rollup.Batches[3].L2Txs)
|
|
ptOut, err = tp.ProcessTxs(nil, l1UserTxs, blocks[0].Rollup.Batches[3].L1CoordinatorTxs, l2Txs)
|
|
require.NoError(t, err)
|
|
|
|
sendProofAndCheckResp(t, ptOut.ZKInputs)
|
|
|
|
// batch5
|
|
l1UserTxs = til.L1TxsToCommonL1Txs(tc.Queues[*blocks[0].Rollup.Batches[4].Batch.ForgeL1TxsNum])
|
|
l2Txs = common.L2TxsToPoolL2Txs(blocks[0].Rollup.Batches[4].L2Txs)
|
|
ptOut, err = tp.ProcessTxs(nil, l1UserTxs, blocks[0].Rollup.Batches[4].L1CoordinatorTxs, l2Txs)
|
|
require.NoError(t, err)
|
|
|
|
sendProofAndCheckResp(t, ptOut.ZKInputs)
|
|
|
|
// batch6
|
|
l1UserTxs = til.L1TxsToCommonL1Txs(tc.Queues[*blocks[0].Rollup.Batches[5].Batch.ForgeL1TxsNum])
|
|
l2Txs = common.L2TxsToPoolL2Txs(blocks[0].Rollup.Batches[5].L2Txs)
|
|
ptOut, err = tp.ProcessTxs(nil, l1UserTxs, blocks[0].Rollup.Batches[5].L1CoordinatorTxs, l2Txs)
|
|
require.NoError(t, err)
|
|
|
|
sendProofAndCheckResp(t, ptOut.ZKInputs)
|
|
|
|
// batch7
|
|
// simulate the PoolL2Txs of the batch7
|
|
batchPoolL2 := `
|
|
Type: PoolL2
|
|
PoolTransferToEthAddr(1) A-B: 200 (126)
|
|
PoolTransferToEthAddr(0) B-C: 100 (126)`
|
|
poolL2Txs, err := tc.GeneratePoolL2Txs(batchPoolL2)
|
|
require.NoError(t, err)
|
|
|
|
// Coordinator Idx where to send the fees
|
|
coordIdxs := []common.Idx{261, 262}
|
|
l1UserTxs = til.L1TxsToCommonL1Txs(tc.Queues[*blocks[0].Rollup.Batches[6].Batch.ForgeL1TxsNum])
|
|
l2Txs = poolL2Txs
|
|
ptOut, err = tp.ProcessTxs(coordIdxs, l1UserTxs, blocks[0].Rollup.Batches[6].L1CoordinatorTxs, l2Txs)
|
|
require.NoError(t, err)
|
|
|
|
sendProofAndCheckResp(t, ptOut.ZKInputs)
|
|
|
|
// batch8
|
|
// simulate the PoolL2Txs of the batch8
|
|
batchPoolL2 = `
|
|
Type: PoolL2
|
|
PoolTransfer(0) A-B: 100 (126)
|
|
PoolTransfer(0) C-A: 50 (126)
|
|
PoolTransfer(1) B-C: 100 (126)
|
|
PoolExit(0) A: 100 (126)`
|
|
poolL2Txs, err = tc.GeneratePoolL2Txs(batchPoolL2)
|
|
require.NoError(t, err)
|
|
|
|
l1UserTxs = til.L1TxsToCommonL1Txs(tc.Queues[*blocks[0].Rollup.Batches[7].Batch.ForgeL1TxsNum])
|
|
l2Txs = poolL2Txs
|
|
ptOut, err = tp.ProcessTxs(coordIdxs, l1UserTxs, blocks[0].Rollup.Batches[7].L1CoordinatorTxs, l2Txs)
|
|
require.NoError(t, err)
|
|
|
|
sendProofAndCheckResp(t, ptOut.ZKInputs)
|
|
|
|
// batch9
|
|
// simulate the PoolL2Txs of the batch9
|
|
batchPoolL2 = `
|
|
Type: PoolL2
|
|
PoolTransfer(0) D-A: 300 (126)
|
|
PoolTransfer(0) B-D: 100 (126)`
|
|
poolL2Txs, err = tc.GeneratePoolL2Txs(batchPoolL2)
|
|
require.NoError(t, err)
|
|
|
|
l1UserTxs = til.L1TxsToCommonL1Txs(tc.Queues[*blocks[1].Rollup.Batches[0].Batch.ForgeL1TxsNum])
|
|
l2Txs = poolL2Txs
|
|
coordIdxs = []common.Idx{262}
|
|
ptOut, err = tp.ProcessTxs(coordIdxs, l1UserTxs, blocks[1].Rollup.Batches[0].L1CoordinatorTxs, l2Txs)
|
|
require.NoError(t, err)
|
|
|
|
sendProofAndCheckResp(t, ptOut.ZKInputs)
|
|
|
|
// batch10
|
|
l1UserTxs = til.L1TxsToCommonL1Txs(tc.Queues[*blocks[1].Rollup.Batches[1].Batch.ForgeL1TxsNum])
|
|
l2Txs = []common.PoolL2Tx{}
|
|
coordIdxs = []common.Idx{}
|
|
ptOut, err = tp.ProcessTxs(coordIdxs, l1UserTxs, blocks[1].Rollup.Batches[1].L1CoordinatorTxs, l2Txs)
|
|
require.NoError(t, err)
|
|
|
|
sendProofAndCheckResp(t, ptOut.ZKInputs)
|
|
}
|