Browse Source

Add transakcio coordinator tx instruction feature

Transakcio:
- Transaction generation to fail when Transfer to an account that don't exist (not created yet)
- Add CreateAccountDepositCoordinator instruction feature
- Updated lang.go instruction type parser approach for more simplicity of code
- Remove `*testing.T` from transactions generation methods, use `log.Fatal` instead
feature/sql-semaphore1
arnaucube 3 years ago
parent
commit
17ff917a20
8 changed files with 116 additions and 108 deletions
  1. +13
    -1
      db/statedb/txprocessors.go
  2. +4
    -4
      db/statedb/txprocessors_test.go
  3. +45
    -55
      test/transakcio/lang.go
  4. +16
    -13
      test/transakcio/lang_test.go
  5. +5
    -0
      test/transakcio/sets.go
  6. +1
    -1
      test/transakcio/sets_test.go
  7. +20
    -28
      test/transakcio/txs.go
  8. +12
    -6
      test/transakcio/txs_test.go

+ 13
- 1
db/statedb/txprocessors.go

@ -248,12 +248,14 @@ func (s *StateDB) processL1Tx(exitTree *merkletree.MerkleTree, tx *common.L1Tx)
// & nonce // & nonce
err := s.applyTransfer(tx.Tx(), 0) // 0 for the parameter toIdx, as at L1Tx ToIdx can only be 0 in the Deposit type case. err := s.applyTransfer(tx.Tx(), 0) // 0 for the parameter toIdx, as at L1Tx ToIdx can only be 0 in the Deposit type case.
if err != nil { if err != nil {
log.Error(err)
return nil, nil, false, err return nil, nil, false, err
} }
case common.TxTypeCreateAccountDeposit: case common.TxTypeCreateAccountDeposit:
// add new account to the MT, update balance of the MT account // add new account to the MT, update balance of the MT account
err := s.applyCreateAccount(tx) err := s.applyCreateAccount(tx)
if err != nil { if err != nil {
log.Error(err)
return nil, nil, false, err return nil, nil, false, err
} }
// TODO applyCreateAccount will return the created account, // TODO applyCreateAccount will return the created account,
@ -268,6 +270,7 @@ func (s *StateDB) processL1Tx(exitTree *merkletree.MerkleTree, tx *common.L1Tx)
// update balance of the MT account // update balance of the MT account
err := s.applyDeposit(tx, false) err := s.applyDeposit(tx, false)
if err != nil { if err != nil {
log.Error(err)
return nil, nil, false, err return nil, nil, false, err
} }
case common.TxTypeDepositTransfer: case common.TxTypeDepositTransfer:
@ -275,6 +278,7 @@ func (s *StateDB) processL1Tx(exitTree *merkletree.MerkleTree, tx *common.L1Tx)
// & receiver // & receiver
err := s.applyDeposit(tx, true) err := s.applyDeposit(tx, true)
if err != nil { if err != nil {
log.Error(err)
return nil, nil, false, err return nil, nil, false, err
} }
case common.TxTypeCreateAccountDepositTransfer: case common.TxTypeCreateAccountDepositTransfer:
@ -282,6 +286,7 @@ func (s *StateDB) processL1Tx(exitTree *merkletree.MerkleTree, tx *common.L1Tx)
// update balance & nonce of sender & receiver // update balance & nonce of sender & receiver
err := s.applyCreateAccountDepositTransfer(tx) err := s.applyCreateAccountDepositTransfer(tx)
if err != nil { if err != nil {
log.Error(err)
return nil, nil, false, err return nil, nil, false, err
} }
@ -293,6 +298,7 @@ func (s *StateDB) processL1Tx(exitTree *merkletree.MerkleTree, tx *common.L1Tx)
// execute exit flow // execute exit flow
exitAccount, newExit, err := s.applyExit(exitTree, tx.Tx()) exitAccount, newExit, err := s.applyExit(exitTree, tx.Tx())
if err != nil { if err != nil {
log.Error(err)
return nil, nil, false, err return nil, nil, false, err
} }
return &tx.FromIdx, exitAccount, newExit, nil return &tx.FromIdx, exitAccount, newExit, nil
@ -356,6 +362,7 @@ func (s *StateDB) processL2Tx(exitTree *merkletree.MerkleTree, tx *common.PoolL2
// as type==TypeSynchronizer, always tx.ToIdx!=0 // as type==TypeSynchronizer, always tx.ToIdx!=0
acc, err := s.GetAccount(tx.FromIdx) acc, err := s.GetAccount(tx.FromIdx)
if err != nil { if err != nil {
log.Error(err)
return nil, nil, false, err return nil, nil, false, err
} }
tx.Nonce = acc.Nonce tx.Nonce = acc.Nonce
@ -371,12 +378,14 @@ func (s *StateDB) processL2Tx(exitTree *merkletree.MerkleTree, tx *common.PoolL2
// balance & nonce // balance & nonce
err = s.applyTransfer(tx.Tx(), tx.AuxToIdx) err = s.applyTransfer(tx.Tx(), tx.AuxToIdx)
if err != nil { if err != nil {
log.Error(err)
return nil, nil, false, err return nil, nil, false, err
} }
case common.TxTypeExit: case common.TxTypeExit:
// execute exit flow // execute exit flow
exitAccount, newExit, err := s.applyExit(exitTree, tx.Tx()) exitAccount, newExit, err := s.applyExit(exitTree, tx.Tx())
if err != nil { if err != nil {
log.Error(err)
return nil, nil, false, err return nil, nil, false, err
} }
return &tx.FromIdx, exitAccount, newExit, nil return &tx.FromIdx, exitAccount, newExit, nil
@ -493,16 +502,18 @@ func (s *StateDB) applyDeposit(tx *common.L1Tx, transfer bool) error {
// the receiver. This parameter is used when the tx.ToIdx is not specified and // the receiver. This parameter is used when the tx.ToIdx is not specified and
// the real ToIdx is found trhrough the ToEthAddr or ToBJJ. // the real ToIdx is found trhrough the ToEthAddr or ToBJJ.
func (s *StateDB) applyTransfer(tx common.Tx, auxToIdx common.Idx) error { func (s *StateDB) applyTransfer(tx common.Tx, auxToIdx common.Idx) error {
if auxToIdx == 0 {
if auxToIdx == common.Idx(0) {
auxToIdx = tx.ToIdx auxToIdx = tx.ToIdx
} }
// get sender and receiver accounts from localStateDB // get sender and receiver accounts from localStateDB
accSender, err := s.GetAccount(tx.FromIdx) accSender, err := s.GetAccount(tx.FromIdx)
if err != nil { if err != nil {
log.Error(err)
return err return err
} }
accReceiver, err := s.GetAccount(auxToIdx) accReceiver, err := s.GetAccount(auxToIdx)
if err != nil { if err != nil {
log.Error(err)
return err return err
} }
@ -517,6 +528,7 @@ func (s *StateDB) applyTransfer(tx common.Tx, auxToIdx common.Idx) error {
// update sender account in localStateDB // update sender account in localStateDB
pSender, err := s.UpdateAccount(tx.FromIdx, accSender) pSender, err := s.UpdateAccount(tx.FromIdx, accSender)
if err != nil { if err != nil {
log.Error(err)
return err return err
} }
if s.zki != nil { if s.zki != nil {

+ 4
- 4
db/statedb/txprocessors_test.go

@ -21,7 +21,7 @@ func TestProcessTxsSynchronizer(t *testing.T) {
assert.Nil(t, err) assert.Nil(t, err)
// generate test transactions from test.SetTest0 code // generate test transactions from test.SetTest0 code
tc := transakcio.NewTestContext(t)
tc := transakcio.NewTestContext()
blocks := tc.GenerateBlocks(transakcio.SetBlockchain0) blocks := tc.GenerateBlocks(transakcio.SetBlockchain0)
assert.Equal(t, 29, len(blocks[0].Batches[0].L1UserTxs)) assert.Equal(t, 29, len(blocks[0].Batches[0].L1UserTxs))
@ -31,7 +31,7 @@ func TestProcessTxsSynchronizer(t *testing.T) {
assert.Equal(t, 1, len(blocks[0].Batches[1].L1CoordinatorTxs)) assert.Equal(t, 1, len(blocks[0].Batches[1].L1CoordinatorTxs))
assert.Equal(t, 59, len(blocks[0].Batches[1].L2Txs)) assert.Equal(t, 59, len(blocks[0].Batches[1].L2Txs))
assert.Equal(t, 9, len(blocks[0].Batches[2].L1UserTxs)) assert.Equal(t, 9, len(blocks[0].Batches[2].L1UserTxs))
assert.Equal(t, 0, len(blocks[0].Batches[2].L1CoordinatorTxs))
assert.Equal(t, 1, len(blocks[0].Batches[2].L1CoordinatorTxs))
assert.Equal(t, 8, len(blocks[0].Batches[2].L2Txs)) assert.Equal(t, 8, len(blocks[0].Batches[2].L2Txs))
// use first batch // use first batch
@ -76,7 +76,7 @@ func TestProcessTxsBatchBuilder(t *testing.T) {
assert.Nil(t, err) assert.Nil(t, err)
// generate test transactions from test.SetTest0 code // generate test transactions from test.SetTest0 code
tc := transakcio.NewTestContext(t)
tc := transakcio.NewTestContext()
blocks := tc.GenerateBlocks(transakcio.SetBlockchain0) blocks := tc.GenerateBlocks(transakcio.SetBlockchain0)
assert.Equal(t, 29, len(blocks[0].Batches[0].L1UserTxs)) assert.Equal(t, 29, len(blocks[0].Batches[0].L1UserTxs))
@ -125,7 +125,7 @@ func TestZKInputsGeneration(t *testing.T) {
assert.Nil(t, err) assert.Nil(t, err)
// generate test transactions from test.SetTest0 code // generate test transactions from test.SetTest0 code
tc := transakcio.NewTestContext(t)
tc := transakcio.NewTestContext()
blocks := tc.GenerateBlocks(transakcio.SetBlockchain0) blocks := tc.GenerateBlocks(transakcio.SetBlockchain0)
assert.Equal(t, 29, len(blocks[0].Batches[0].L1UserTxs)) assert.Equal(t, 29, len(blocks[0].Batches[0].L1UserTxs))
assert.Equal(t, 0, len(blocks[0].Batches[0].L1CoordinatorTxs)) assert.Equal(t, 0, len(blocks[0].Batches[0].L1CoordinatorTxs))

+ 45
- 55
test/transakcio/lang.go

@ -35,6 +35,8 @@ var typeNewBatch common.TxType = "TxTypeNewBatch"
// common.TxType of a new ethereum block // common.TxType of a new ethereum block
var typeNewBlock common.TxType = "TxTypeNewBlock" var typeNewBlock common.TxType = "TxTypeNewBlock"
var txTypeCreateAccountDepositCoordinator common.TxType = "TypeCreateAccountDepositCoordinator"
//nolint //nolint
const ( const (
ILLEGAL token = iota ILLEGAL token = iota
@ -297,63 +299,46 @@ func (p *parser) parseLine(setType setType) (*instruction, error) {
return c, fmt.Errorf("Set type not defined") return c, fmt.Errorf("Set type not defined")
} }
transferring := false transferring := false
switch lit {
case "Deposit":
if setType != setTypeBlockchain {
return c, fmt.Errorf("Unexpected '%s' in a non %s set", lit, setTypeBlockchain)
}
c.typ = common.TxTypeDeposit
case "Exit":
if setType != setTypeBlockchain {
return c, fmt.Errorf("Unexpected '%s' in a non %s set", lit, setTypeBlockchain)
}
c.typ = common.TxTypeExit
case "PoolExit":
if setType != setTypePoolL2 {
return c, fmt.Errorf("Unexpected '%s' in a non %s set", lit, setTypePoolL2)
}
c.typ = common.TxTypeExit
case "Transfer":
if setType != setTypeBlockchain {
return c, fmt.Errorf("Unexpected '%s' in a non %s set", lit, setTypeBlockchain)
}
c.typ = common.TxTypeTransfer
transferring = true
case "PoolTransfer":
if setType != setTypePoolL2 {
return c, fmt.Errorf("Unexpected '%s' in a non %s set", lit, setTypePoolL2)
}
c.typ = common.TxTypeTransfer
transferring = true
case "CreateAccountDeposit":
if setType != setTypeBlockchain {
return c, fmt.Errorf("Unexpected '%s' in a non %s set", lit, setTypeBlockchain)
}
c.typ = common.TxTypeCreateAccountDeposit
case "CreateAccountDepositTransfer":
if setType != setTypeBlockchain {
return c, fmt.Errorf("Unexpected '%s' in a non %s set", lit, setTypeBlockchain)
}
c.typ = common.TxTypeCreateAccountDepositTransfer
transferring = true
case "DepositTransfer":
if setType != setTypeBlockchain {
return c, fmt.Errorf("Unexpected '%s' in a non %s set", lit, setTypeBlockchain)
}
c.typ = common.TxTypeDepositTransfer
transferring = true
case "ForceTransfer":
if setType != setTypeBlockchain {
return c, fmt.Errorf("Unexpected '%s' in a non %s set", lit, setTypeBlockchain)
if setType == setTypeBlockchain {
switch lit {
case "Deposit":
c.typ = common.TxTypeDeposit
case "Exit":
c.typ = common.TxTypeExit
case "Transfer":
c.typ = common.TxTypeTransfer
transferring = true
case "CreateAccountDeposit":
c.typ = common.TxTypeCreateAccountDeposit
case "CreateAccountDepositTransfer":
c.typ = common.TxTypeCreateAccountDepositTransfer
transferring = true
case "CreateAccountDepositCoordinator":
c.typ = txTypeCreateAccountDepositCoordinator
// transferring is false, as the Coordinator tx transfer will be 0
case "DepositTransfer":
c.typ = common.TxTypeDepositTransfer
transferring = true
case "ForceTransfer":
c.typ = common.TxTypeForceTransfer
case "ForceExit":
c.typ = common.TxTypeForceExit
default:
return c, fmt.Errorf("Unexpected Blockchain tx type: %s", lit)
} }
c.typ = common.TxTypeForceTransfer
case "ForceExit":
if setType != setTypeBlockchain {
return c, fmt.Errorf("Unexpected '%s' in a non %s set", lit, setTypeBlockchain)
} else if setType == setTypePoolL2 {
switch lit {
case "PoolTransfer":
c.typ = common.TxTypeTransfer
transferring = true
case "PoolExit":
c.typ = common.TxTypeExit
default:
return c, fmt.Errorf("Unexpected PoolL2 tx type: %s", lit)
} }
c.typ = common.TxTypeForceExit
default:
return c, fmt.Errorf("Unexpected tx type: %s", lit)
} else {
return c, fmt.Errorf("Invalid set type: '%s'. Valid set types: 'Blockchain', 'PoolL2'", setType)
} }
if err := p.expectChar(c, "("); err != nil { if err := p.expectChar(c, "("); err != nil {
@ -374,6 +359,11 @@ func (p *parser) parseLine(setType setType) (*instruction, error) {
_, lit = p.scanIgnoreWhitespace() _, lit = p.scanIgnoreWhitespace()
c.literal += lit c.literal += lit
c.from = lit c.from = lit
if c.typ == txTypeCreateAccountDepositCoordinator {
line, _ := p.s.r.ReadString('\n')
c.literal += line
return c, nil
}
_, lit = p.scanIgnoreWhitespace() _, lit = p.scanIgnoreWhitespace()
c.literal += lit c.literal += lit
if transferring { if transferring {

+ 16
- 13
test/transakcio/lang_test.go

@ -20,10 +20,12 @@ func TestParseBlockchainTxs(t *testing.T) {
Deposit(1) B: 5 Deposit(1) B: 5
CreateAccountDeposit(1) C: 5 CreateAccountDeposit(1) C: 5
CreateAccountDepositTransfer(1) D-A: 15, 10 (3) CreateAccountDepositTransfer(1) D-A: 15, 10 (3)
CreateAccountDepositCoordinator(1) E
// L2 transactions // L2 transactions
Transfer(1) A-B: 6 (1) Transfer(1) A-B: 6 (1)
Transfer(1) B-D: 3 (1) Transfer(1) B-D: 3 (1)
Transfer(1) A-E: 1 (1)
// set new batch // set new batch
> batch > batch
@ -51,8 +53,8 @@ func TestParseBlockchainTxs(t *testing.T) {
parser := newParser(strings.NewReader(s)) parser := newParser(strings.NewReader(s))
instructions, err := parser.parse() instructions, err := parser.parse()
require.Nil(t, err) require.Nil(t, err)
assert.Equal(t, 20, len(instructions.instructions))
assert.Equal(t, 6, len(instructions.accounts))
assert.Equal(t, 22, len(instructions.instructions))
assert.Equal(t, 7, len(instructions.accounts))
assert.Equal(t, 3, len(instructions.tokenIDs)) assert.Equal(t, 3, len(instructions.tokenIDs))
if debug { if debug {
@ -62,14 +64,15 @@ func TestParseBlockchainTxs(t *testing.T) {
} }
} }
assert.Equal(t, typeNewBatch, instructions.instructions[7].typ)
assert.Equal(t, "Deposit(1)User0:20", instructions.instructions[11].raw())
assert.Equal(t, "Type: DepositTransfer, From: A, To: B, LoadAmount: 15, Amount: 10, Fee: 1, TokenID: 1\n", instructions.instructions[8].String())
assert.Equal(t, "Type: Transfer, From: User1, To: User0, Amount: 15, Fee: 1, TokenID: 3\n", instructions.instructions[14].String())
assert.Equal(t, "Transfer(2)A-B:15(1)", instructions.instructions[10].raw())
assert.Equal(t, "Type: Transfer, From: A, To: B, Amount: 15, Fee: 1, TokenID: 2\n", instructions.instructions[10].String())
assert.Equal(t, "Exit(1)A:5", instructions.instructions[19].raw())
assert.Equal(t, "Type: Exit, From: A, Amount: 5, TokenID: 1\n", instructions.instructions[19].String())
assert.Equal(t, txTypeCreateAccountDepositCoordinator, instructions.instructions[5].typ)
assert.Equal(t, typeNewBatch, instructions.instructions[9].typ)
assert.Equal(t, "Deposit(1)User0:20", instructions.instructions[13].raw())
assert.Equal(t, "Type: DepositTransfer, From: A, To: B, LoadAmount: 15, Amount: 10, Fee: 1, TokenID: 1\n", instructions.instructions[10].String())
assert.Equal(t, "Type: Transfer, From: User1, To: User0, Amount: 15, Fee: 1, TokenID: 3\n", instructions.instructions[16].String())
assert.Equal(t, "Transfer(2)A-B:15(1)", instructions.instructions[12].raw())
assert.Equal(t, "Type: Transfer, From: A, To: B, Amount: 15, Fee: 1, TokenID: 2\n", instructions.instructions[12].String())
assert.Equal(t, "Exit(1)A:5", instructions.instructions[21].raw())
assert.Equal(t, "Type: Exit, From: A, Amount: 5, TokenID: 1\n", instructions.instructions[21].String())
} }
func TestParsePoolTxs(t *testing.T) { func TestParsePoolTxs(t *testing.T) {
@ -118,7 +121,7 @@ func TestParseErrors(t *testing.T) {
` `
parser = newParser(strings.NewReader(s)) parser = newParser(strings.NewReader(s))
_, err = parser.parse() _, err = parser.parse()
assert.Equal(t, "error parsing line 2: 20, err: Unexpected tx type: 20", err.Error())
assert.Equal(t, "error parsing line 2: 20, err: Unexpected Blockchain tx type: 20", err.Error())
s = ` s = `
Type: Blockchain Type: Blockchain
@ -159,14 +162,14 @@ func TestParseErrors(t *testing.T) {
` `
parser = newParser(strings.NewReader(s)) parser = newParser(strings.NewReader(s))
_, err = parser.parse() _, err = parser.parse()
assert.Equal(t, "error parsing line 1: Transfer, err: Unexpected 'Transfer' in a non Blockchain set", err.Error())
assert.Equal(t, "error parsing line 1: Transfer, err: Unexpected PoolL2 tx type: Transfer", err.Error())
s = ` s = `
Type: Blockchain Type: Blockchain
PoolTransfer(1) A-B: 10 (1) PoolTransfer(1) A-B: 10 (1)
` `
parser = newParser(strings.NewReader(s)) parser = newParser(strings.NewReader(s))
_, err = parser.parse() _, err = parser.parse()
assert.Equal(t, "error parsing line 1: PoolTransfer, err: Unexpected 'PoolTransfer' in a non PoolL2 set", err.Error())
assert.Equal(t, "error parsing line 1: PoolTransfer, err: Unexpected Blockchain tx type: PoolTransfer", err.Error())
s = ` s = `
Type: Blockchain Type: Blockchain

+ 5
- 0
test/transakcio/sets.go

@ -64,6 +64,8 @@ Transfer(1) H-K: 3 (1)
> batch > batch
// A (3) still does not exist, coordinator should create new L1Tx to create the account // A (3) still does not exist, coordinator should create new L1Tx to create the account
CreateAccountDepositCoordinator(3) A
Transfer(3) B-A: 5 (1) Transfer(3) B-A: 5 (1)
Transfer(2) A-B: 5 (1) Transfer(2) A-B: 5 (1)
Transfer(1) I-K: 3 (1) Transfer(1) I-K: 3 (1)
@ -144,6 +146,9 @@ Transfer(1) C-O: 5 (1)
Transfer(1) H-O: 5 (1) Transfer(1) H-O: 5 (1)
Transfer(1) I-H: 5 (1) Transfer(1) I-H: 5 (1)
Exit(1) A: 5 Exit(1) A: 5
// create CoordinatorTx CreateAccount for D, TokenId 2, used at SetPool0 for 'PoolTransfer(2) B-D: 3 (1)'
CreateAccountDepositCoordinator(2) D
` `
// SetPool0 contains a set of transactions from the PoolL2 // SetPool0 contains a set of transactions from the PoolL2

+ 1
- 1
test/transakcio/sets_test.go

@ -15,7 +15,7 @@ func TestCompileSets(t *testing.T) {
_, err = parser.parse() _, err = parser.parse()
assert.Nil(t, err) assert.Nil(t, err)
tc := NewTestContext(t)
tc := NewTestContext()
_ = tc.GenerateBlocks(SetBlockchain0) _ = tc.GenerateBlocks(SetBlockchain0)
_ = tc.GenerateBlocks(SetPool0) _ = tc.GenerateBlocks(SetPool0)
} }

+ 20
- 28
test/transakcio/txs.go

@ -5,7 +5,6 @@ import (
"math/big" "math/big"
"strconv" "strconv"
"strings" "strings"
"testing"
"time" "time"
ethCommon "github.com/ethereum/go-ethereum/common" ethCommon "github.com/ethereum/go-ethereum/common"
@ -13,12 +12,10 @@ import (
"github.com/hermeznetwork/hermez-node/common" "github.com/hermeznetwork/hermez-node/common"
"github.com/hermeznetwork/hermez-node/log" "github.com/hermeznetwork/hermez-node/log"
"github.com/iden3/go-iden3-crypto/babyjub" "github.com/iden3/go-iden3-crypto/babyjub"
"github.com/stretchr/testify/require"
) )
// TestContext contains the data of the test // TestContext contains the data of the test
type TestContext struct { type TestContext struct {
t *testing.T
Instructions []instruction Instructions []instruction
accountsNames []string accountsNames []string
Users map[string]*User Users map[string]*User
@ -27,9 +24,8 @@ type TestContext struct {
} }
// NewTestContext returns a new TestContext // NewTestContext returns a new TestContext
func NewTestContext(t *testing.T) *TestContext {
func NewTestContext() *TestContext {
return &TestContext{ return &TestContext{
t: t,
Users: make(map[string]*User), Users: make(map[string]*User),
l1CreatedAccounts: make(map[string]*Account), l1CreatedAccounts: make(map[string]*Account),
} }
@ -74,7 +70,9 @@ type BatchData struct {
func (tc *TestContext) GenerateBlocks(set string) []BlockData { func (tc *TestContext) GenerateBlocks(set string) []BlockData {
parser := newParser(strings.NewReader(set)) parser := newParser(strings.NewReader(set))
parsedSet, err := parser.parse() parsedSet, err := parser.parse()
require.Nil(tc.t, err)
if err != nil {
log.Fatal(err)
}
tc.Instructions = parsedSet.instructions tc.Instructions = parsedSet.instructions
tc.accountsNames = parsedSet.accounts tc.accountsNames = parsedSet.accounts
@ -89,7 +87,7 @@ func (tc *TestContext) GenerateBlocks(set string) []BlockData {
idx := 256 idx := 256
for _, inst := range parsedSet.instructions { for _, inst := range parsedSet.instructions {
switch inst.typ { switch inst.typ {
case common.TxTypeCreateAccountDeposit, common.TxTypeCreateAccountDepositTransfer:
case common.TxTypeCreateAccountDeposit, common.TxTypeCreateAccountDepositTransfer, txTypeCreateAccountDepositCoordinator:
tx := common.L1Tx{ tx := common.L1Tx{
// TxID // TxID
FromEthAddr: tc.Users[inst.from].Addr, FromEthAddr: tc.Users[inst.from].Addr,
@ -110,7 +108,12 @@ func (tc *TestContext) GenerateBlocks(set string) []BlockData {
if inst.typ == common.TxTypeCreateAccountDepositTransfer { if inst.typ == common.TxTypeCreateAccountDepositTransfer {
tx.Amount = big.NewInt(int64(inst.amount)) tx.Amount = big.NewInt(int64(inst.amount))
} }
currBatch.L1UserTxs = append(currBatch.L1UserTxs, tx)
if inst.typ == txTypeCreateAccountDepositCoordinator {
tx.Type = common.TxTypeCreateAccountDeposit // as txTypeCreateAccountDepositCoordinator is not valid oustide Transakcio package
currBatch.L1CoordinatorTxs = append(currBatch.L1CoordinatorTxs, tx)
} else {
currBatch.L1UserTxs = append(currBatch.L1UserTxs, tx)
}
case common.TxTypeDeposit, common.TxTypeDepositTransfer: case common.TxTypeDeposit, common.TxTypeDepositTransfer:
if tc.Users[inst.from].Accounts[inst.tokenID] == nil { if tc.Users[inst.from].Accounts[inst.tokenID] == nil {
log.Fatalf("Deposit at User %s for TokenID %d while account not created yet", inst.from, inst.tokenID) log.Fatalf("Deposit at User %s for TokenID %d while account not created yet", inst.from, inst.tokenID)
@ -150,24 +153,11 @@ func (tc *TestContext) GenerateBlocks(set string) []BlockData {
if tc.Users[inst.from].Accounts[inst.tokenID] == nil { if tc.Users[inst.from].Accounts[inst.tokenID] == nil {
log.Fatalf("Transfer from User %s for TokenID %d while account not created yet", inst.from, inst.tokenID) log.Fatalf("Transfer from User %s for TokenID %d while account not created yet", inst.from, inst.tokenID)
} }
tc.Users[inst.from].Accounts[inst.tokenID].Nonce++
// if account of receiver does not exist, create a new CoordinatorL1Tx creating the account // if account of receiver does not exist, create a new CoordinatorL1Tx creating the account
if _, ok := tc.l1CreatedAccounts[idxTokenIDToString(inst.to, inst.tokenID)]; !ok { if _, ok := tc.l1CreatedAccounts[idxTokenIDToString(inst.to, inst.tokenID)]; !ok {
tx := common.L1Tx{
FromEthAddr: tc.Users[inst.to].Addr,
FromBJJ: tc.Users[inst.to].BJJ.Public(),
TokenID: inst.tokenID,
LoadAmount: big.NewInt(int64(inst.amount)),
Type: common.TxTypeCreateAccountDeposit,
}
tc.Users[inst.to].Accounts[inst.tokenID] = &Account{
Idx: common.Idx(idx),
Nonce: common.Nonce(0),
}
tc.l1CreatedAccounts[idxTokenIDToString(inst.to, inst.tokenID)] = tc.Users[inst.to].Accounts[inst.tokenID]
currBatch.L1CoordinatorTxs = append(currBatch.L1CoordinatorTxs, tx)
idx++
log.Fatalf("Can not create Transfer for a non existing account. Batch %d, Instruction: %s", currBatchNum, inst)
} }
tc.Users[inst.from].Accounts[inst.tokenID].Nonce++
tx := common.L2Tx{ tx := common.L2Tx{
FromIdx: tc.Users[inst.from].Accounts[inst.tokenID].Idx, FromIdx: tc.Users[inst.from].Accounts[inst.tokenID].Idx,
ToIdx: tc.Users[inst.to].Accounts[inst.tokenID].Idx, ToIdx: tc.Users[inst.to].Accounts[inst.tokenID].Idx,
@ -178,7 +168,7 @@ func (tc *TestContext) GenerateBlocks(set string) []BlockData {
} }
nTx, err := common.NewPoolL2Tx(tx.PoolL2Tx()) nTx, err := common.NewPoolL2Tx(tx.PoolL2Tx())
if err != nil { if err != nil {
panic(err)
log.Fatal(err)
} }
tx = nTx.L2Tx() tx = nTx.L2Tx()
tx.BatchNum = common.BatchNum(currBatchNum) // when converted to PoolL2Tx BatchNum parameter is lost tx.BatchNum = common.BatchNum(currBatchNum) // when converted to PoolL2Tx BatchNum parameter is lost
@ -195,7 +185,7 @@ func (tc *TestContext) GenerateBlocks(set string) []BlockData {
} }
nTx, err := common.NewPoolL2Tx(tx.PoolL2Tx()) nTx, err := common.NewPoolL2Tx(tx.PoolL2Tx())
if err != nil { if err != nil {
panic(err)
log.Fatal(err)
} }
tx = nTx.L2Tx() tx = nTx.L2Tx()
currBatch.L2Txs = append(currBatch.L2Txs, tx) currBatch.L2Txs = append(currBatch.L2Txs, tx)
@ -233,7 +223,9 @@ func (tc *TestContext) GenerateBlocks(set string) []BlockData {
func (tc *TestContext) GeneratePoolL2Txs(set string) []common.PoolL2Tx { func (tc *TestContext) GeneratePoolL2Txs(set string) []common.PoolL2Tx {
parser := newParser(strings.NewReader(set)) parser := newParser(strings.NewReader(set))
parsedSet, err := parser.parse() parsedSet, err := parser.parse()
require.Nil(tc.t, err)
if err != nil {
log.Fatal(err)
}
tc.Instructions = parsedSet.instructions tc.Instructions = parsedSet.instructions
tc.accountsNames = parsedSet.accounts tc.accountsNames = parsedSet.accounts
@ -271,13 +263,13 @@ func (tc *TestContext) GeneratePoolL2Txs(set string) []common.PoolL2Tx {
} }
nTx, err := common.NewPoolL2Tx(&tx) nTx, err := common.NewPoolL2Tx(&tx)
if err != nil { if err != nil {
panic(err)
log.Fatal(err)
} }
tx = *nTx tx = *nTx
// perform signature and set it to tx.Signature // perform signature and set it to tx.Signature
toSign, err := tx.HashToSign() toSign, err := tx.HashToSign()
if err != nil { if err != nil {
panic(err)
log.Fatal(err)
} }
sig := tc.Users[inst.to].BJJ.SignPoseidon(toSign) sig := tc.Users[inst.to].BJJ.SignPoseidon(toSign)
tx.Signature = sig tx.Signature = sig

+ 12
- 6
test/transakcio/txs_test.go

@ -24,13 +24,18 @@ func TestGenerateBlocks(t *testing.T) {
// set new batch // set new batch
> batch > batch
CreateAccountDepositCoordinator(1) E
CreateAccountDepositCoordinator(2) B
DepositTransfer(1) A-B: 15, 10 (1) DepositTransfer(1) A-B: 15, 10 (1)
Transfer(1) C-A : 3 (1) Transfer(1) C-A : 3 (1)
Transfer(2) A-B: 15 (1) Transfer(2) A-B: 15 (1)
Transfer(1) A-E: 1 (1)
CreateAccountDeposit(1) User0: 20 CreateAccountDeposit(1) User0: 20
CreateAccountDeposit(3) User1: 20 CreateAccountDeposit(3) User1: 20
CreateAccountDepositCoordinator(1) User1
CreateAccountDepositCoordinator(3) User0
Transfer(1) User0-User1: 15 (1) Transfer(1) User0-User1: 15 (1)
Transfer(3) User1-User0: 15 (1) Transfer(3) User1-User0: 15 (1)
Transfer(1) A-C: 1 (1) Transfer(1) A-C: 1 (1)
@ -45,12 +50,13 @@ func TestGenerateBlocks(t *testing.T) {
Transfer(1) A-B: 1 (1) Transfer(1) A-B: 1 (1)
Exit(1) A: 5 Exit(1) A: 5
` `
tc := NewTestContext(t)
tc := NewTestContext()
blocks := tc.GenerateBlocks(set) blocks := tc.GenerateBlocks(set)
assert.Equal(t, 2, len(blocks)) assert.Equal(t, 2, len(blocks))
assert.Equal(t, 3, len(blocks[0].Batches)) assert.Equal(t, 3, len(blocks[0].Batches))
assert.Equal(t, 1, len(blocks[1].Batches)) assert.Equal(t, 1, len(blocks[1].Batches))
assert.Equal(t, 5, len(blocks[0].Batches[0].L1UserTxs)) assert.Equal(t, 5, len(blocks[0].Batches[0].L1UserTxs))
assert.Equal(t, 4, len(blocks[0].Batches[1].L1CoordinatorTxs))
assert.Equal(t, 0, len(blocks[1].Batches[0].L1UserTxs)) assert.Equal(t, 0, len(blocks[1].Batches[0].L1UserTxs))
// Check expected values generated by each line // Check expected values generated by each line
@ -84,17 +90,17 @@ func TestGenerateBlocks(t *testing.T) {
// #13: Deposit(3) User1: 20 // #13: Deposit(3) User1: 20
tc.checkL1TxParams(t, blocks[0].Batches[1].L1UserTxs[2], common.TxTypeCreateAccountDeposit, 3, "User1", "", big.NewInt(20), nil) tc.checkL1TxParams(t, blocks[0].Batches[1].L1UserTxs[2], common.TxTypeCreateAccountDeposit, 3, "User1", "", big.NewInt(20), nil)
// #14: Transfer(1) User0-User1: 15 (1) // #14: Transfer(1) User0-User1: 15 (1)
tc.checkL2TxParams(t, blocks[0].Batches[1].L2Txs[2], common.TxTypeTransfer, 1, "User0", "User1", big.NewInt(15), common.BatchNum(1), common.Nonce(1))
tc.checkL2TxParams(t, blocks[0].Batches[1].L2Txs[3], common.TxTypeTransfer, 1, "User0", "User1", big.NewInt(15), common.BatchNum(1), common.Nonce(1))
// #15: Transfer(3) User1-User0: 15 (1) // #15: Transfer(3) User1-User0: 15 (1)
tc.checkL2TxParams(t, blocks[0].Batches[1].L2Txs[3], common.TxTypeTransfer, 3, "User1", "User0", big.NewInt(15), common.BatchNum(1), common.Nonce(1))
tc.checkL2TxParams(t, blocks[0].Batches[1].L2Txs[4], common.TxTypeTransfer, 3, "User1", "User0", big.NewInt(15), common.BatchNum(1), common.Nonce(1))
// #16: Transfer(1) A-C: 1 (1) // #16: Transfer(1) A-C: 1 (1)
tc.checkL2TxParams(t, blocks[0].Batches[1].L2Txs[4], common.TxTypeTransfer, 1, "A", "C", big.NewInt(1), common.BatchNum(1), common.Nonce(3))
tc.checkL2TxParams(t, blocks[0].Batches[1].L2Txs[5], common.TxTypeTransfer, 1, "A", "C", big.NewInt(1), common.BatchNum(1), common.Nonce(4))
// change of Batch // change of Batch
// #17: Transfer(1) User1-User0: 1 (1) // #17: Transfer(1) User1-User0: 1 (1)
tc.checkL2TxParams(t, blocks[0].Batches[2].L2Txs[0], common.TxTypeTransfer, 1, "User1", "User0", big.NewInt(1), common.BatchNum(2), common.Nonce(1)) tc.checkL2TxParams(t, blocks[0].Batches[2].L2Txs[0], common.TxTypeTransfer, 1, "User1", "User0", big.NewInt(1), common.BatchNum(2), common.Nonce(1))
// change of Block (implies also a change of batch) // change of Block (implies also a change of batch)
// #18: Transfer(1) A-B: 1 (1) // #18: Transfer(1) A-B: 1 (1)
tc.checkL2TxParams(t, blocks[1].Batches[0].L2Txs[0], common.TxTypeTransfer, 1, "A", "B", big.NewInt(1), common.BatchNum(3), common.Nonce(4))
tc.checkL2TxParams(t, blocks[1].Batches[0].L2Txs[0], common.TxTypeTransfer, 1, "A", "B", big.NewInt(1), common.BatchNum(3), common.Nonce(5))
} }
func (tc *TestContext) checkL1TxParams(t *testing.T, tx common.L1Tx, typ common.TxType, tokenID common.TokenID, from, to string, loadAmount, amount *big.Int) { func (tc *TestContext) checkL1TxParams(t *testing.T, tx common.L1Tx, typ common.TxType, tokenID common.TokenID, from, to string, loadAmount, amount *big.Int) {
@ -142,7 +148,7 @@ func TestGeneratePoolL2Txs(t *testing.T) {
CreateAccountDeposit(2) B: 5 CreateAccountDeposit(2) B: 5
CreateAccountDeposit(2) D: 0 CreateAccountDeposit(2) D: 0
` `
tc := NewTestContext(t)
tc := NewTestContext()
_ = tc.GenerateBlocks(set) _ = tc.GenerateBlocks(set)
set = ` set = `
Type: PoolL2 Type: PoolL2

Loading…
Cancel
Save