arnaucube
arnaucube/hermez-nodePublic Self-hosted repository
Merge pull request #436 from hermeznetwork/feature/exit-proof-siblings

Update ExitProofs-Siblings padding
a_bennassar arnaubennassar5@gmail.com
Wed, 30 Dec 2020 11:13:22 +0100
commit

c2dd982d26d8034278acbc8a17362842ddb391d2

parent

88f924e9dd54ec2aefc00387c7c4198030c79339

6 files changed, 81 insertions(+), 5 deletions(-)

jump to
M common/utils.go → common/utils.go

@@ -1,12 +1,14 @@

package common import ( + "bytes" "encoding/hex" "math/big" ethCommon "github.com/ethereum/go-ethereum/common" "github.com/hermeznetwork/tracerr" "github.com/iden3/go-iden3-crypto/babyjub" + "github.com/iden3/go-merkletree" ) // SwapEndianness swaps the order of the bytes in the slice.

@@ -42,3 +44,21 @@ // CopyBigInt returns a copy of the big int

func CopyBigInt(a *big.Int) *big.Int { return new(big.Int).SetBytes(a.Bytes()) } + +// RmEndingZeroes is used to convert the Siblings from a CircomProof into +// Siblings of a merkletree Proof compatible with the js version. This method +// should be used only if it exist an already generated CircomProof compatible +// with circom circuits and a CircomProof compatible with SmartContracts is +// needed. If the proof is not generated yet, this method should not be needed +// and should be used mt.GenerateSCVerifierProof to directly generate the +// CircomProof for the SmartContracts. +func RmEndingZeroes(siblings []*merkletree.Hash) []*merkletree.Hash { + pos := 0 + for i := len(siblings) - 1; i >= 0; i-- { + if !bytes.Equal(siblings[i].Bytes(), merkletree.HashZero.Bytes()) { + pos = i + 1 + break + } + } + return siblings[:pos] +}
M common/utils_test.go → common/utils_test.go

@@ -4,7 +4,9 @@ import (

"encoding/hex" "testing" + "github.com/iden3/go-merkletree" "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" ) func TestBJJFromStringWithChecksum(t *testing.T) {

@@ -22,3 +24,52 @@ // expected values computed with js implementation

assert.Equal(t, "2492816973395423007340226948038371729989170225696553239457870892535792679622", pk.X.String()) assert.Equal(t, "15238403086306505038849621710779816852318505119327426213168494964113886299863", pk.Y.String()) } + +func TestRmEndingZeroes(t *testing.T) { + s0, err := merkletree.NewHashFromHex("0x0000000000000000000000000000000000000000000000000000000000000000") + require.NoError(t, err) + s1, err := merkletree.NewHashFromHex("0x0000000000000000000000000000000000000000000000000000000000000001") + require.NoError(t, err) + s2, err := merkletree.NewHashFromHex("0x0000000000000000000000000000000000000000000000000000000000000002") + require.NoError(t, err) + + // expect cropped last zeroes + circomSiblings := []*merkletree.Hash{s0, s1, s0, s1, s1, s1, s2, s0, s0, s0, s0} + siblings := RmEndingZeroes(circomSiblings) + expected := []*merkletree.Hash{s0, s1, s0, s1, s1, s1, s2} + assert.Equal(t, expected, siblings) + + // expect empty array when input is an empty array + siblings = RmEndingZeroes([]*merkletree.Hash{}) + assert.Equal(t, []*merkletree.Hash{}, siblings) + // expect nil when input is nil + siblings = RmEndingZeroes(nil) + assert.Nil(t, siblings) + + // cases when inputs are [x], [x,0], [0,x] + circomSiblings = []*merkletree.Hash{s1} + siblings = RmEndingZeroes(circomSiblings) + assert.Equal(t, []*merkletree.Hash{s1}, siblings) + circomSiblings = []*merkletree.Hash{s1, s0} + siblings = RmEndingZeroes(circomSiblings) + assert.Equal(t, []*merkletree.Hash{s1}, siblings) + circomSiblings = []*merkletree.Hash{s0, s1} + siblings = RmEndingZeroes(circomSiblings) + assert.Equal(t, []*merkletree.Hash{s0, s1}, siblings) + + // expect empty array when input is all zeroes + circomSiblings = []*merkletree.Hash{s0} + siblings = RmEndingZeroes(circomSiblings) + assert.Equal(t, []*merkletree.Hash{}, siblings) + circomSiblings = []*merkletree.Hash{s0, s0} + siblings = RmEndingZeroes(circomSiblings) + assert.Equal(t, []*merkletree.Hash{}, siblings) + circomSiblings = []*merkletree.Hash{s0, s0, s0, s0, s0} + siblings = RmEndingZeroes(circomSiblings) + assert.Equal(t, []*merkletree.Hash{}, siblings) + + // expect input equal to output when last element!=0 + circomSiblings = []*merkletree.Hash{s0, s1, s0, s1, s1, s1, s2, s0, s0, s0, s0, s2} + siblings = RmEndingZeroes(circomSiblings) + assert.Equal(t, circomSiblings, siblings) +}
M db/statedb/statedb.go → db/statedb/statedb.go

@@ -328,7 +328,11 @@ func (s *StateDB) MTGetProof(idx common.Idx) (*merkletree.CircomVerifierProof, error) {

if s.MT == nil { return nil, tracerr.Wrap(ErrStateDBWithoutMT) } - return s.MT.GenerateCircomVerifierProof(idx.BigInt(), s.MT.Root()) + p, err := s.MT.GenerateSCVerifierProof(idx.BigInt(), s.MT.Root()) + if err != nil { + return nil, tracerr.Wrap(err) + } + return p, nil } // MTGetRoot returns the current root of the underlying Merkle Tree
M go.mod → go.mod

@@ -13,7 +13,7 @@ github.com/gin-gonic/gin v1.5.0

github.com/gobuffalo/packr/v2 v2.8.1 github.com/hermeznetwork/tracerr v0.3.1-0.20201126162137-de9930d0cf29 github.com/iden3/go-iden3-crypto v0.0.6-0.20201221160344-58e589b6eb4c - github.com/iden3/go-merkletree v0.0.0-20201218120219-8f3905f15f89 + github.com/iden3/go-merkletree v0.0.0-20201230093451-4280a9914f51 github.com/jinzhu/copier v0.0.0-20190924061706-b57f9002281a github.com/jmoiron/sqlx v1.2.1-0.20200615141059-0794cb1f47ee github.com/joho/godotenv v1.3.0
M go.sum → go.sum

@@ -309,8 +309,8 @@ github.com/huin/goutil v0.0.0-20170803182201-1ca381bf3150/go.mod h1:PpLOETDnJ0o3iZrZfqZzyLl6l7F3c6L1oWn7OICBi6o=

github.com/iden3/go-iden3-crypto v0.0.6-0.20201218111145-a2015adb2f1b/go.mod h1:oBgthFLboAWi9feaBUFy7OxEcyn9vA1khHSL/WwWFyg= github.com/iden3/go-iden3-crypto v0.0.6-0.20201221160344-58e589b6eb4c h1:D2u8FFYey6iFXLsqqJZ8R7ch8gZum+/b98whvoSDbyg= github.com/iden3/go-iden3-crypto v0.0.6-0.20201221160344-58e589b6eb4c/go.mod h1:oBgthFLboAWi9feaBUFy7OxEcyn9vA1khHSL/WwWFyg= -github.com/iden3/go-merkletree v0.0.0-20201218120219-8f3905f15f89 h1:t7tnOTCtw12Rniyk98Hi4gOp0h5JPdzbNcLWCFNj98o= -github.com/iden3/go-merkletree v0.0.0-20201218120219-8f3905f15f89/go.mod h1:MCXbnyoFRwt+7aYHtzVSB3sZZcHLjDf7VZZ2Zqrhqrc= +github.com/iden3/go-merkletree v0.0.0-20201230093451-4280a9914f51 h1:EqkLnC+JlOdX3hQnjq0u2JKcMMmmaQcpmG1udG6BTXw= +github.com/iden3/go-merkletree v0.0.0-20201230093451-4280a9914f51/go.mod h1:MCXbnyoFRwt+7aYHtzVSB3sZZcHLjDf7VZZ2Zqrhqrc= github.com/inconshreveable/mousetrap v1.0.0/go.mod h1:PxqpIevigyE2G7u3NXJIT2ANytuPF1OarO4DADm73n8= github.com/influxdata/influxdb v1.2.3-0.20180221223340-01288bdb0883/go.mod h1:qZna6X/4elxqT3yI9iZYdZrWWdeFOOprn86kgg4+IzY= github.com/influxdata/influxdb1-client v0.0.0-20190809212627-fc22c7df067e/go.mod h1:qj24IKcXYK6Iy9ceXlo3Tc+vtHo9lIhSX5JddghvEPo=
M txprocessor/txprocessor.go → txprocessor/txprocessor.go

@@ -372,10 +372,11 @@ exitIdx := exits[i].idx

exitAccount := exits[i].acc // 0. generate MerkleProof - p, err := exitTree.GenerateCircomVerifierProof(exitIdx.BigInt(), nil) + p, err := exitTree.GenerateSCVerifierProof(exitIdx.BigInt(), nil) if err != nil { return nil, tracerr.Wrap(err) } + // 1. generate common.ExitInfo ei := common.ExitInfo{ AccountIdx: exitIdx,