arnaucube
arnaucube/hermez-nodePublic Self-hosted repository
hermez-node/batchbuilder/batchbuilder.go
batchbuilder/batchbuilder.goRaw
  1package batchbuilder
  2
  3import (
  4	"math/big"
  5
  6	ethCommon "github.com/ethereum/go-ethereum/common"
  7	"github.com/hermeznetwork/hermez-node/common"
  8	"github.com/iden3/go-merkletree"
  9	"github.com/iden3/go-merkletree/db"
 10	"github.com/iden3/go-merkletree/db/memory"
 11)
 12
 13type ConfigCircuit struct {
 14	TxsMax       uint64
 15	L1TxsMax     uint64
 16	SMTLevelsMax uint64
 17}
 18
 19type BatchBuilder struct {
 20	StateDB        db.Storage // where the MTs will be stored by the Synchronizer
 21	idx            uint64
 22	mt             *merkletree.MerkleTree
 23	configCircuits []ConfigCircuit
 24}
 25
 26type ConfigBatch struct {
 27	CoordinatorAddress ethCommon.Address
 28}
 29
 30// NewBatchBuilder constructs a new BatchBuilder, and executes the bb.Reset
 31// method
 32func NewBatchBuilder(stateDB db.Storage, configCircuits []ConfigCircuit, batchNum int, idx, nLevels uint64) (*BatchBuilder, error) {
 33	localMt, err := merkletree.NewMerkleTree(memory.NewMemoryStorage(), int(nLevels))
 34	if err != nil {
 35		return nil, err
 36	}
 37	bb := BatchBuilder{
 38		StateDB:        stateDB,
 39		idx:            idx,
 40		mt:             localMt,
 41		configCircuits: configCircuits,
 42	}
 43
 44	bb.Reset(batchNum, idx, true)
 45
 46	return &bb, nil
 47}
 48
 49// Reset tells the BatchBuilder to reset it's internal state to the required
 50// `batchNum`.  If `fromSynchronizer` is true, the BatchBuilder must take a
 51// copy of the rollup state from the Synchronizer at that `batchNum`, otherwise
 52// it can just roll back the internal copy.
 53func (bb *BatchBuilder) Reset(batchNum int, idx uint64, fromSynchronizer bool) error {
 54
 55	return nil
 56}
 57
 58type ZKInputs struct{} // TMP
 59
 60func (bb *BatchBuilder) BuildBatch(configBatch ConfigBatch, l1usertxs, l1coordinatortxs []common.L1Tx, l2txs []common.L2Tx, tokenIDs []common.TokenID) (*ZKInputs, error) {
 61
 62	for _, tx := range l1usertxs {
 63		bb.processL1Tx(tx)
 64	}
 65	for _, tx := range l1coordinatortxs {
 66		bb.processL1Tx(tx)
 67	}
 68	for _, tx := range l2txs {
 69		switch tx.Type {
 70		case common.TxTypeTransfer:
 71			// go to the MT leaf of sender and receiver, and update
 72			// balance & nonce
 73			bb.applyTransfer(tx.Tx)
 74		case common.TxTypeExit:
 75			// execute exit flow
 76		default:
 77		}
 78
 79	}
 80
 81	return nil, nil
 82}
 83
 84func (bb *BatchBuilder) processL1Tx(tx common.L1Tx) error {
 85	switch tx.Type {
 86	case common.TxTypeForceTransfer, common.TxTypeTransfer:
 87		// go to the MT leaf of sender and receiver, and update balance
 88		// & nonce
 89		bb.applyTransfer(tx.Tx)
 90	case common.TxTypeCreateAccountDeposit:
 91		// add new leaf to the MT, update balance of the MT leaf
 92		bb.applyCreateLeaf(tx)
 93	case common.TxTypeDeposit:
 94		// update balance of the MT leaf
 95		bb.applyDeposit(tx)
 96	case common.TxTypeDepositAndTransfer:
 97		// update balance in MT leaf, update balance & nonce of sender
 98		// & receiver
 99		bb.applyDeposit(tx) // this after v0, can be done by bb.applyDepositAndTransfer in a single step
100		bb.applyTransfer(tx.Tx)
101	case common.TxTypeCreateAccountDepositAndTransfer:
102		// add new leaf to the merkletree, update balance in MT leaf,
103		// update balance & nonce of sender & receiver
104		bb.applyCreateLeaf(tx)
105		bb.applyTransfer(tx.Tx)
106	case common.TxTypeExit:
107		// execute exit flow
108	default:
109	}
110
111	return nil
112}
113
114// applyCreateLeaf creates a new leaf in the leaf of the depositer, it stores
115// the deposit value
116func (bb *BatchBuilder) applyCreateLeaf(tx common.L1Tx) error {
117	k := big.NewInt(int64(bb.idx + 1))
118
119	leaf := common.Leaf{
120		TokenID: tx.TokenID,
121		Nonce:   0, // TODO check always that a new leaf is created nonce is at 0
122		Balance: tx.LoadAmount,
123		Ax:      tx.FromBJJ.X,
124		Ay:      tx.FromBJJ.Y,
125		EthAddr: tx.FromEthAddr,
126	}
127
128	v, err := leaf.HashValue()
129	if err != nil {
130		return err
131	}
132
133	// store at the DB the key: v, and value: leaf.Bytes()
134	dbTx, err := bb.mt.DB().NewTx()
135	if err != nil {
136		return err
137	}
138	leafBytes, err := leaf.Bytes()
139	if err != nil {
140		return err
141	}
142	dbTx.Put(v.Bytes(), leafBytes[:])
143
144	// Add k & v into the MT
145	err = bb.mt.Add(k, v)
146	if err != nil {
147		return err
148	}
149
150	// if everything is fine, increment idx
151	bb.idx = bb.idx + 1
152	return nil
153}
154
155// applyDeposit updates the balance in the leaf of the depositer
156func (bb *BatchBuilder) applyDeposit(tx common.L1Tx) error {
157
158	return nil
159}
160
161// applyTransfer updates the balance & nonce in the leaf of the sender, and the
162// balance in the leaf of the receiver
163func (bb *BatchBuilder) applyTransfer(tx common.Tx) error {
164
165	return nil
166}