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
 58func (bb *BatchBuilder) BuildBatch(configBatch ConfigBatch, l1usertxs, l1coordinatortxs []common.L1Tx, l2txs []common.L2Tx, tokenIDs []common.TokenID) (*common.ZKInputs, error) {
 59
 60	for _, tx := range l1usertxs {
 61		bb.processL1Tx(tx)
 62	}
 63	for _, tx := range l1coordinatortxs {
 64		bb.processL1Tx(tx)
 65	}
 66	for _, tx := range l2txs {
 67		switch tx.Type {
 68		case common.TxTypeTransfer:
 69			// go to the MT leaf of sender and receiver, and update
 70			// balance & nonce
 71			bb.applyTransfer(tx.Tx)
 72		case common.TxTypeExit:
 73			// execute exit flow
 74		default:
 75		}
 76
 77	}
 78
 79	return nil, nil
 80}
 81
 82func (bb *BatchBuilder) processL1Tx(tx common.L1Tx) error {
 83	switch tx.Type {
 84	case common.TxTypeForceTransfer, common.TxTypeTransfer:
 85		// go to the MT leaf of sender and receiver, and update balance
 86		// & nonce
 87		bb.applyTransfer(tx.Tx)
 88	case common.TxTypeCreateAccountDeposit:
 89		// add new leaf to the MT, update balance of the MT leaf
 90		bb.applyCreateLeaf(tx)
 91	case common.TxTypeDeposit:
 92		// update balance of the MT leaf
 93		bb.applyDeposit(tx)
 94	case common.TxTypeDepositAndTransfer:
 95		// update balance in MT leaf, update balance & nonce of sender
 96		// & receiver
 97		bb.applyDeposit(tx) // this after v0, can be done by bb.applyDepositAndTransfer in a single step
 98		bb.applyTransfer(tx.Tx)
 99	case common.TxTypeCreateAccountDepositAndTransfer:
100		// add new leaf to the merkletree, update balance in MT leaf,
101		// update balance & nonce of sender & receiver
102		bb.applyCreateLeaf(tx)
103		bb.applyTransfer(tx.Tx)
104	case common.TxTypeExit:
105		// execute exit flow
106	default:
107	}
108
109	return nil
110}
111
112// applyCreateLeaf creates a new leaf in the leaf of the depositer, it stores
113// the deposit value
114func (bb *BatchBuilder) applyCreateLeaf(tx common.L1Tx) error {
115	k := big.NewInt(int64(bb.idx + 1))
116
117	leaf := common.Leaf{
118		TokenID: tx.TokenID,
119		Nonce:   0, // TODO check always that a new leaf is created nonce is at 0
120		Balance: tx.LoadAmount,
121		Ax:      tx.FromBJJ.X,
122		Ay:      tx.FromBJJ.Y,
123		EthAddr: tx.FromEthAddr,
124	}
125
126	v, err := leaf.Value()
127	if err != nil {
128		return err
129	}
130
131	// store at the DB the key: v, and value: leaf.Bytes()
132	dbTx, err := bb.mt.DB().NewTx()
133	if err != nil {
134		return err
135	}
136	leafBytes := leaf.Bytes()
137	dbTx.Put(v.Bytes(), leafBytes[:])
138
139	// Add k & v into the MT
140	err = bb.mt.Add(k, v)
141	if err != nil {
142		return err
143	}
144
145	// if everything is fine, increment idx
146	bb.idx = bb.idx + 1
147	return nil
148}
149
150// applyDeposit updates the balance in the leaf of the depositer
151func (bb *BatchBuilder) applyDeposit(tx common.L1Tx) error {
152
153	return nil
154}
155
156// applyTransfer updates the balance & nonce in the leaf of the sender, and the
157// balance in the leaf of the receiver
158func (bb *BatchBuilder) applyTransfer(tx common.Tx) error {
159
160	return nil
161}