mirror of
https://github.com/arnaucube/hermez-node.git
synced 2026-02-07 03:16:45 +01:00
Merge pull request #197 from hermeznetwork/feature/transakcio-coordtxs
Add transakcio coordinator tx instruction feature
This commit is contained in:
@@ -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 {
|
||||||
|
|||||||
@@ -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))
|
||||||
|
|||||||
@@ -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 {
|
||||||
if setType != setTypeBlockchain {
|
switch lit {
|
||||||
return c, fmt.Errorf("Unexpected '%s' in a non %s set", lit, setTypeBlockchain)
|
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.TxTypeDeposit
|
} else if setType == setTypePoolL2 {
|
||||||
case "Exit":
|
switch lit {
|
||||||
if setType != setTypeBlockchain {
|
case "PoolTransfer":
|
||||||
return c, fmt.Errorf("Unexpected '%s' in a non %s set", lit, setTypeBlockchain)
|
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.TxTypeExit
|
} else {
|
||||||
case "PoolExit":
|
return c, fmt.Errorf("Invalid set type: '%s'. Valid set types: 'Blockchain', 'PoolL2'", setType)
|
||||||
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)
|
|
||||||
}
|
|
||||||
c.typ = common.TxTypeForceTransfer
|
|
||||||
case "ForceExit":
|
|
||||||
if setType != setTypeBlockchain {
|
|
||||||
return c, fmt.Errorf("Unexpected '%s' in a non %s set", lit, setTypeBlockchain)
|
|
||||||
}
|
|
||||||
c.typ = common.TxTypeForceExit
|
|
||||||
default:
|
|
||||||
return c, fmt.Errorf("Unexpected tx type: %s", lit)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
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 {
|
||||||
|
|||||||
@@ -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, 22, len(instructions.instructions))
|
||||||
assert.Equal(t, 6, len(instructions.accounts))
|
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, txTypeCreateAccountDepositCoordinator, instructions.instructions[5].typ)
|
||||||
assert.Equal(t, "Deposit(1)User0:20", instructions.instructions[11].raw())
|
assert.Equal(t, typeNewBatch, instructions.instructions[9].typ)
|
||||||
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, "Deposit(1)User0:20", instructions.instructions[13].raw())
|
||||||
assert.Equal(t, "Type: Transfer, From: User1, To: User0, Amount: 15, Fee: 1, TokenID: 3\n", instructions.instructions[14].String())
|
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, "Transfer(2)A-B:15(1)", instructions.instructions[10].raw())
|
assert.Equal(t, "Type: Transfer, From: User1, To: User0, Amount: 15, Fee: 1, TokenID: 3\n", instructions.instructions[16].String())
|
||||||
assert.Equal(t, "Type: Transfer, From: A, To: B, Amount: 15, Fee: 1, TokenID: 2\n", instructions.instructions[10].String())
|
assert.Equal(t, "Transfer(2)A-B:15(1)", instructions.instructions[12].raw())
|
||||||
assert.Equal(t, "Exit(1)A:5", instructions.instructions[19].raw())
|
assert.Equal(t, "Type: Transfer, From: A, To: B, Amount: 15, Fee: 1, TokenID: 2\n", instructions.instructions[12].String())
|
||||||
assert.Equal(t, "Type: Exit, From: A, Amount: 5, TokenID: 1\n", instructions.instructions[19].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
|
||||||
|
|||||||
@@ -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
|
||||||
|
|||||||
@@ -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)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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{
|
log.Fatalf("Can not create Transfer for a non existing account. Batch %d, Instruction: %s", currBatchNum, inst)
|
||||||
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++
|
|
||||||
}
|
}
|
||||||
|
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
|
||||||
|
|||||||
@@ -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
|
||||||
|
|||||||
Reference in New Issue
Block a user