arnaucube
arnaucube/hermez-nodePublic Self-hosted repository
hermez-node/test/txs.go
test/txs.goRaw
  1package test
  2
  3import (
  4	"crypto/ecdsa"
  5	"math/big"
  6	"strconv"
  7	"testing"
  8	"time"
  9
 10	ethCommon "github.com/ethereum/go-ethereum/common"
 11	ethCrypto "github.com/ethereum/go-ethereum/crypto"
 12	"github.com/hermeznetwork/hermez-node/common"
 13	"github.com/iden3/go-iden3-crypto/babyjub"
 14)
 15
 16type Account struct {
 17	BJJ   *babyjub.PrivateKey
 18	Addr  ethCommon.Address
 19	Idx   common.Idx
 20	Nonce common.Nonce
 21}
 22
 23// GenerateKeys generates BabyJubJub & Address keys for the given list of
 24// account names in a deterministic way. This means, that for the same given
 25// 'accNames' the keys will be always the same.
 26func GenerateKeys(t *testing.T, accNames []string) map[string]*Account {
 27	acc := make(map[string]*Account)
 28	for i := 1; i < len(accNames)+1; i++ {
 29		// babyjubjub key
 30		var sk babyjub.PrivateKey
 31		copy(sk[:], []byte(strconv.Itoa(i))) // only for testing
 32
 33		// eth address
 34		var key ecdsa.PrivateKey
 35		key.D = big.NewInt(int64(i)) // only for testing
 36		key.PublicKey.X, key.PublicKey.Y = ethCrypto.S256().ScalarBaseMult(key.D.Bytes())
 37		key.Curve = ethCrypto.S256()
 38		addr := ethCrypto.PubkeyToAddress(key.PublicKey)
 39
 40		a := Account{
 41			BJJ:   &sk,
 42			Addr:  addr,
 43			Nonce: 0,
 44		}
 45		acc[accNames[i-1]] = &a
 46	}
 47	return acc
 48}
 49
 50// GenerateTestTxs generates L1Tx & PoolL2Tx in a deterministic way for the
 51// given Instructions.
 52func GenerateTestTxs(t *testing.T, instructions Instructions) ([]*common.L1Tx, []*common.PoolL2Tx) {
 53	accounts := GenerateKeys(t, instructions.Accounts)
 54
 55	// debug
 56	// fmt.Println("accounts:")
 57	// for n, a := range accounts {
 58	//         fmt.Printf("	%s: bjj:%s - addr:%s\n", n, a.BJJ.Public().String()[:10], a.Addr.Hex()[:10])
 59	// }
 60
 61	var l1txs []*common.L1Tx
 62	var l2txs []*common.PoolL2Tx
 63	idx := 1
 64	for _, inst := range instructions.Instructions {
 65		switch inst.Type {
 66		case common.TxTypeCreateAccountDeposit:
 67			tx := common.L1Tx{
 68				// TxID
 69				FromEthAddr: accounts[idxTokenIDToString(inst.From, inst.TokenID)].Addr,
 70				FromBJJ:     accounts[idxTokenIDToString(inst.From, inst.TokenID)].BJJ.Public(),
 71				TokenID:     inst.TokenID,
 72				LoadAmount:  big.NewInt(int64(inst.Amount)),
 73				Type:        common.TxTypeCreateAccountDeposit,
 74			}
 75			l1txs = append(l1txs, &tx)
 76			if accounts[idxTokenIDToString(inst.From, inst.TokenID)].Idx == common.Idx(0) { // if account.Idx is not set yet, set it and increment idx
 77				accounts[idxTokenIDToString(inst.From, inst.TokenID)].Idx = common.Idx(idx)
 78				idx++
 79			}
 80		case common.TxTypeTransfer:
 81			tx := common.PoolL2Tx{
 82				// TxID: nil,
 83				FromIdx:   accounts[idxTokenIDToString(inst.From, inst.TokenID)].Idx,
 84				ToIdx:     accounts[idxTokenIDToString(inst.To, inst.TokenID)].Idx,
 85				ToEthAddr: accounts[idxTokenIDToString(inst.To, inst.TokenID)].Addr,
 86				ToBJJ:     accounts[idxTokenIDToString(inst.To, inst.TokenID)].BJJ.Public(),
 87				TokenID:   inst.TokenID,
 88				Amount:    big.NewInt(int64(inst.Amount)),
 89				Fee:       common.FeeSelector(inst.Fee),
 90				Nonce:     accounts[idxTokenIDToString(inst.From, inst.TokenID)].Nonce,
 91				State:     common.PoolL2TxStatePending,
 92				Timestamp: time.Now(),
 93				BatchNum:  0,
 94				Type:      common.TxTypeTransfer,
 95			}
 96			// TODO once signature function is ready, perform
 97			// signature and set it to tx.Signature
 98
 99			accounts[idxTokenIDToString(inst.From, inst.TokenID)].Nonce++
100			l2txs = append(l2txs, &tx)
101		default:
102			continue
103		}
104
105	}
106
107	return l1txs, l2txs
108}