From dd1901709c4574894849f6d8b54ab870d94e60cc Mon Sep 17 00:00:00 2001 From: arnaucube Date: Mon, 3 Aug 2020 12:53:36 +0200 Subject: [PATCH 1/6] Add common/Leaf struct & parsers (bigint & byte arrays) --- common/leaf_test.go | 69 +++++++++++++++++++++++---------------------- 1 file changed, 35 insertions(+), 34 deletions(-) diff --git a/common/leaf_test.go b/common/leaf_test.go index 2f67a10..1e27e35 100644 --- a/common/leaf_test.go +++ b/common/leaf_test.go @@ -7,6 +7,7 @@ import ( "testing" ethCommon "github.com/ethereum/go-ethereum/common" + ethCrypto "github.com/ethereum/go-ethereum/crypto" cryptoConstants "github.com/iden3/go-iden3-crypto/constants" cryptoUtils "github.com/iden3/go-iden3-crypto/utils" "github.com/stretchr/testify/assert" @@ -45,40 +46,40 @@ func TestLeaf(t *testing.T) { assert.Equal(t, l1, l2) } -// func TestLeafLoop(t *testing.T) { -// // check that for different Address there is no problem -// for i := 0; i < 256; i++ { -// key, err := ethCrypto.GenerateKey() -// assert.Nil(t, err) -// address := ethCrypto.PubkeyToAddress(key.PublicKey) -// -// leaf := &Leaf{ -// TokenID: TokenID(i), -// Nonce: uint64(i), -// Balance: big.NewInt(1000), -// Ax: big.NewInt(9876), -// Ay: big.NewInt(6789), -// EthAddr: address, -// } -// b, err := leaf.Bytes() -// assert.Nil(t, err) -// l1, err := LeafFromBytes(b) -// assert.Nil(t, err) -// assert.Equal(t, leaf, l1) -// -// e, err := leaf.BigInts() -// assert.Nil(t, err) -// assert.True(t, cryptoUtils.CheckBigIntInField(e[0])) -// assert.True(t, cryptoUtils.CheckBigIntInField(e[1])) -// assert.True(t, cryptoUtils.CheckBigIntInField(e[2])) -// assert.True(t, cryptoUtils.CheckBigIntInField(e[3])) -// assert.True(t, cryptoUtils.CheckBigIntInField(e[4])) -// -// l2, err := LeafFromBigInts(e) -// assert.Nil(t, err) -// assert.Equal(t, leaf, l2) -// } -// } +func TestLeafLoop(t *testing.T) { + // check that for different Address there is no problem + for i := 0; i < 256; i++ { + key, err := ethCrypto.GenerateKey() + assert.Nil(t, err) + address := ethCrypto.PubkeyToAddress(key.PublicKey) + + leaf := &Leaf{ + TokenID: TokenID(i), + Nonce: uint64(i), + Balance: big.NewInt(1000), + Ax: big.NewInt(9876), + Ay: big.NewInt(6789), + EthAddr: address, + } + b, err := leaf.Bytes() + assert.Nil(t, err) + l1, err := LeafFromBytes(b) + assert.Nil(t, err) + assert.Equal(t, leaf, l1) + + e, err := leaf.BigInts() + assert.Nil(t, err) + assert.True(t, cryptoUtils.CheckBigIntInField(e[0])) + assert.True(t, cryptoUtils.CheckBigIntInField(e[1])) + assert.True(t, cryptoUtils.CheckBigIntInField(e[2])) + assert.True(t, cryptoUtils.CheckBigIntInField(e[3])) + assert.True(t, cryptoUtils.CheckBigIntInField(e[4])) + + l2, err := LeafFromBigInts(e) + assert.Nil(t, err) + assert.Equal(t, leaf, l2) + } +} func TestLeafErrNotInFF(t *testing.T) { z := big.NewInt(0) From f3cfba1bbeff307cffdae7dbb7d5cc9d6e95fd51 Mon Sep 17 00:00:00 2001 From: arnaucube Date: Mon, 3 Aug 2020 18:24:51 +0200 Subject: [PATCH 2/6] Add initial structure of BatchBuilder --- batchbuilder/batchbuilder.go | 161 ++++++++++++++++++++++++++++++ batchbuilder/batchbuilder_test.go | 18 ++++ common/leaf.go | 11 ++ go.mod | 1 + go.sum | 2 + 5 files changed, 193 insertions(+) create mode 100644 batchbuilder/batchbuilder.go create mode 100644 batchbuilder/batchbuilder_test.go diff --git a/batchbuilder/batchbuilder.go b/batchbuilder/batchbuilder.go new file mode 100644 index 0000000..26b4e41 --- /dev/null +++ b/batchbuilder/batchbuilder.go @@ -0,0 +1,161 @@ +package batchbuilder + +import ( + "math/big" + + ethCommon "github.com/ethereum/go-ethereum/common" + "github.com/hermeznetwork/hermez-node/common" + "github.com/iden3/go-merkletree" + "github.com/iden3/go-merkletree/db" + "github.com/iden3/go-merkletree/db/memory" +) + +type ConfigCircuit struct { + TxsMax uint64 + L1TxsMax uint64 + SMTLevelsMax uint64 +} + +type BatchBuilder struct { + StateDB db.Storage // where the MTs will be stored by the Synchronizer + idx uint64 + mt *merkletree.MerkleTree + configCircuits []ConfigCircuit +} + +type ConfigBatch struct { + CoordinatorAddress ethCommon.Address +} + +// NewBatchBuilder constructs a new BatchBuilder, and executes the bb.Reset +// method +func NewBatchBuilder(stateDB db.Storage, configCircuits []ConfigCircuit, batchNum int, idx, nLevels uint64) (*BatchBuilder, error) { + localMt, err := merkletree.NewMerkleTree(memory.NewMemoryStorage(), int(nLevels)) + if err != nil { + return nil, err + } + bb := BatchBuilder{ + StateDB: stateDB, + idx: idx, + mt: localMt, + configCircuits: configCircuits, + } + + bb.Reset(batchNum, idx, true) + + return &bb, nil +} + +// Reset tells the BatchBuilder to reset it's internal state to the required +// `batchNum`. If `fromSynchronizer` is true, the BatchBuilder must take a +// copy of the rollup state from the Synchronizer at that `batchNum`, otherwise +// it can just roll back the internal copy. +func (bb *BatchBuilder) Reset(batchNum int, idx uint64, fromSynchronizer bool) error { + + return nil +} + +func (bb *BatchBuilder) BuildBatch(configBatch ConfigBatch, l1usertxs, l1coordinatortxs []common.L1Tx, l2txs []common.L2Tx, tokenIDs []common.TokenID) (*common.ZKInputs, error) { + + for _, tx := range l1usertxs { + bb.processL1Tx(tx) + } + for _, tx := range l1coordinatortxs { + bb.processL1Tx(tx) + } + for _, tx := range l2txs { + switch tx.Type { + case common.TxTypeTransfer: + // go to the MT leaf of sender and receiver, and update + // balance & nonce + bb.applyTransfer(tx.Tx) + case common.TxTypeExit: + // execute exit flow + default: + } + + } + + return nil, nil +} + +func (bb *BatchBuilder) processL1Tx(tx common.L1Tx) error { + switch tx.Type { + case common.TxTypeForceTransfer, common.TxTypeTransfer: + // go to the MT leaf of sender and receiver, and update balance + // & nonce + bb.applyTransfer(tx.Tx) + case common.TxTypeCreateAccountDeposit: + // add new leaf to the MT, update balance of the MT leaf + bb.applyCreateLeaf(tx) + case common.TxTypeDeposit: + // update balance of the MT leaf + bb.applyDeposit(tx) + case common.TxTypeDepositAndTransfer: + // update balance in MT leaf, update balance & nonce of sender + // & receiver + bb.applyDeposit(tx) // this after v0, can be done by bb.applyDepositAndTransfer in a single step + bb.applyTransfer(tx.Tx) + case common.TxTypeCreateAccountDepositAndTransfer: + // add new leaf to the merkletree, update balance in MT leaf, + // update balance & nonce of sender & receiver + bb.applyCreateLeaf(tx) + bb.applyTransfer(tx.Tx) + case common.TxTypeExit: + // execute exit flow + default: + } + + return nil +} + +// applyCreateLeaf creates a new leaf in the leaf of the depositer, it stores +// the deposit value +func (bb *BatchBuilder) applyCreateLeaf(tx common.L1Tx) error { + k := big.NewInt(int64(bb.idx + 1)) + + leaf := common.Leaf{ + TokenID: tx.TokenID, + Nonce: 0, // TODO check always that a new leaf is created nonce is at 0 + Balance: tx.LoadAmount, + Ax: tx.FromBJJ.X, + Ay: tx.FromBJJ.Y, + EthAddr: tx.FromEthAddr, + } + + v, err := leaf.Value() + if err != nil { + return err + } + + // store at the DB the key: v, and value: leaf.Bytes() + dbTx, err := bb.mt.DB().NewTx() + if err != nil { + return err + } + leafBytes := leaf.Bytes() + dbTx.Put(v.Bytes(), leafBytes[:]) + + // Add k & v into the MT + err = bb.mt.Add(k, v) + if err != nil { + return err + } + + // if everything is fine, increment idx + bb.idx = bb.idx + 1 + return nil +} + +// applyDeposit updates the balance in the leaf of the depositer +func (bb *BatchBuilder) applyDeposit(tx common.L1Tx) error { + + return nil +} + +// applyTransfer updates the balance & nonce in the leaf of the sender, and the +// balance in the leaf of the receiver +func (bb *BatchBuilder) applyTransfer(tx common.Tx) error { + + return nil +} diff --git a/batchbuilder/batchbuilder_test.go b/batchbuilder/batchbuilder_test.go new file mode 100644 index 0000000..b8fd379 --- /dev/null +++ b/batchbuilder/batchbuilder_test.go @@ -0,0 +1,18 @@ +package batchbuilder + +import ( + "fmt" + "testing" + + "github.com/iden3/go-merkletree/db/memory" + "github.com/stretchr/testify/assert" +) + +func TestBatchBuilder(t *testing.T) { + + stateDB := memory.NewMemoryStorage() + + bb, err := NewBatchBuilder(stateDB, nil, 0, 0, 32) + assert.Nil(t, err) + fmt.Println(bb) +} diff --git a/common/leaf.go b/common/leaf.go index 9cb4e73..7bf60d6 100644 --- a/common/leaf.go +++ b/common/leaf.go @@ -8,6 +8,7 @@ import ( "math/big" eth "github.com/ethereum/go-ethereum/common" + "github.com/iden3/go-iden3-crypto/poseidon" cryptoUtils "github.com/iden3/go-iden3-crypto/utils" ) @@ -65,6 +66,16 @@ func (l *Leaf) BigInts() ([5]*big.Int, error) { return e, nil } +// Value returns the value of the Leaf, which is the Poseidon hash of its *big.Int representation +func (l *Leaf) Value() (*big.Int, error) { + toHash := [poseidon.T]*big.Int{} + lBI := l.BigInts() + copy(toHash[:], lBI[:]) + + v, err := poseidon.Hash(toHash) + return v, err +} + // LeafFromBigInts returns a Leaf from a [5]*big.Int func LeafFromBigInts(e [5]*big.Int) (*Leaf, error) { if !cryptoUtils.CheckBigIntArrayInField(e[:]) { diff --git a/go.mod b/go.mod index 1425a09..584e13f 100644 --- a/go.mod +++ b/go.mod @@ -3,6 +3,7 @@ module github.com/hermeznetwork/hermez-node go 1.14 require ( + github.com/dghubble/sling v1.3.0 github.com/ethereum/go-ethereum v1.9.17 github.com/iden3/go-iden3-crypto v0.0.6-0.20200723082457-29a66457f0bf github.com/iden3/go-merkletree v0.0.0-20200723202738-75e24244a1e3 diff --git a/go.sum b/go.sum index 76132c8..977471c 100644 --- a/go.sum +++ b/go.sum @@ -62,6 +62,7 @@ github.com/deckarep/golang-set v0.0.0-20180603214616-504e848d77ea/go.mod h1:93vs github.com/deckarep/golang-set v1.7.1/go.mod h1:93vsz/8Wt4joVM7c2AVqh+YRMiUSc14yDtF28KmMOgQ= github.com/denisenkom/go-mssqldb v0.0.0-20191124224453-732737034ffd h1:83Wprp6ROGeiHFAP8WJdI2RoxALQYgdllERc3N5N2DM= github.com/denisenkom/go-mssqldb v0.0.0-20191124224453-732737034ffd/go.mod h1:xbL0rPBG9cCiLr28tMa8zpbdarY27NDyej4t/EjAShU= +github.com/dghubble/sling v1.3.0 h1:pZHjCJq4zJvc6qVQ5wN1jo5oNZlNE0+8T/h0XeXBUKU= github.com/dghubble/sling v1.3.0/go.mod h1:XXShWaBWKzNLhu2OxikSNFrlsvowtz4kyRuXUG7oQKY= github.com/dgrijalva/jwt-go v3.2.0+incompatible/go.mod h1:E3ru+11k8xSBh+hMPgOLZmtrrCbhqsmaPHjLKYnJCaQ= github.com/dgryski/go-sip13 v0.0.0-20181026042036-e10d5fee7954/go.mod h1:vAd38F8PWV+bWy6jNmig1y/TA+kYO4g3RSRF0IAv0no= @@ -111,6 +112,7 @@ github.com/golang/snappy v0.0.1/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEW github.com/golang/snappy v0.0.2-0.20200707131729-196ae77b8a26/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q= github.com/google/go-cmp v0.3.0/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU= github.com/google/go-cmp v0.3.1/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU= +github.com/google/go-querystring v1.0.0 h1:Xkwi/a1rcvNg1PPYe5vI8GbeBY/jrVuDX5ASuANWTrk= github.com/google/go-querystring v1.0.0/go.mod h1:odCYkC5MyYFN7vkCjXpyrEuKhc/BUO6wN/zVPAxq5ck= github.com/google/uuid v1.0.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= github.com/gorilla/websocket v1.4.1-0.20190629185528-ae1634f6a989/go.mod h1:E7qHFY5m1UJ88s3WnNqhKjPHQ0heANvMoAMk2YaljkQ= From 37cefb00579402b2217f3b57f200ef4b7c4cd44a Mon Sep 17 00:00:00 2001 From: arnaucube Date: Tue, 4 Aug 2020 17:53:19 +0200 Subject: [PATCH 3/6] Add common> Idx parsers --- batchbuilder/batchbuilder.go | 11 ++++++++--- common/leaf.go | 9 ++++++--- common/tx.go | 28 ++++++++++++++++++++++++++-- common/tx_test.go | 23 +++++++++++++++++++++++ 4 files changed, 63 insertions(+), 8 deletions(-) create mode 100644 common/tx_test.go diff --git a/batchbuilder/batchbuilder.go b/batchbuilder/batchbuilder.go index 26b4e41..1f37124 100644 --- a/batchbuilder/batchbuilder.go +++ b/batchbuilder/batchbuilder.go @@ -55,7 +55,9 @@ func (bb *BatchBuilder) Reset(batchNum int, idx uint64, fromSynchronizer bool) e return nil } -func (bb *BatchBuilder) BuildBatch(configBatch ConfigBatch, l1usertxs, l1coordinatortxs []common.L1Tx, l2txs []common.L2Tx, tokenIDs []common.TokenID) (*common.ZKInputs, error) { +type ZKInputs struct{} // TMP + +func (bb *BatchBuilder) BuildBatch(configBatch ConfigBatch, l1usertxs, l1coordinatortxs []common.L1Tx, l2txs []common.L2Tx, tokenIDs []common.TokenID) (*ZKInputs, error) { for _, tx := range l1usertxs { bb.processL1Tx(tx) @@ -123,7 +125,7 @@ func (bb *BatchBuilder) applyCreateLeaf(tx common.L1Tx) error { EthAddr: tx.FromEthAddr, } - v, err := leaf.Value() + v, err := leaf.HashValue() if err != nil { return err } @@ -133,7 +135,10 @@ func (bb *BatchBuilder) applyCreateLeaf(tx common.L1Tx) error { if err != nil { return err } - leafBytes := leaf.Bytes() + leafBytes, err := leaf.Bytes() + if err != nil { + return err + } dbTx.Put(v.Bytes(), leafBytes[:]) // Add k & v into the MT diff --git a/common/leaf.go b/common/leaf.go index 7bf60d6..b880ad5 100644 --- a/common/leaf.go +++ b/common/leaf.go @@ -66,10 +66,13 @@ func (l *Leaf) BigInts() ([5]*big.Int, error) { return e, nil } -// Value returns the value of the Leaf, which is the Poseidon hash of its *big.Int representation -func (l *Leaf) Value() (*big.Int, error) { +// HashValue returns the value of the Leaf, which is the Poseidon hash of its *big.Int representation +func (l *Leaf) HashValue() (*big.Int, error) { toHash := [poseidon.T]*big.Int{} - lBI := l.BigInts() + lBI, err := l.BigInts() + if err != nil { + return nil, err + } copy(toHash[:], lBI[:]) v, err := poseidon.Hash(toHash) diff --git a/common/tx.go b/common/tx.go index 58b2e20..393b9ef 100644 --- a/common/tx.go +++ b/common/tx.go @@ -1,14 +1,38 @@ package common import ( + "encoding/binary" "math/big" ) +// Idx represents the account Index in the MerkleTree +type Idx uint32 + +// Bytes returns a byte array representing the Idx +func (idx Idx) Bytes() []byte { + var b [4]byte + binary.LittleEndian.PutUint32(b[:], uint32(idx)) + return b[:] +} + +// BigInt returns a *big.Int representing the Idx +func (idx Idx) BigInt() *big.Int { + return big.NewInt(int64(idx)) +} + +// IdxFromBigInt converts a *big.Int to Idx type +func IdxFromBigInt(b *big.Int) (Idx, error) { + if b.Int64() > 4294967295 { // 2**32-1 + return 0, ErrNumOverflow + } + return Idx(uint32(b.Int64())), nil +} + // Tx is a struct that represents a Hermez network transaction type Tx struct { TxID TxID - FromIdx uint32 - ToIdx uint32 + FromIdx Idx // FromIdx is used by L1Tx/Deposit to indicate the Idx receiver of the L1Tx.LoadAmount (deposit) + ToIdx Idx // ToIdx is ignored in L1Tx/Deposit, but used in the L1Tx/DepositAndTransfer TokenID TokenID Amount *big.Int Nonce uint64 // effective 48 bits used diff --git a/common/tx_test.go b/common/tx_test.go new file mode 100644 index 0000000..4851e5d --- /dev/null +++ b/common/tx_test.go @@ -0,0 +1,23 @@ +package common + +import ( + "math/big" + "testing" + + "github.com/stretchr/testify/assert" +) + +func TestIdx(t *testing.T) { + i := Idx(100) + assert.Equal(t, big.NewInt(100), i.BigInt()) + + i = Idx(uint32(4294967295)) + assert.Equal(t, "4294967295", i.BigInt().String()) + + b := big.NewInt(4294967296) + i, err := IdxFromBigInt(b) + assert.NotNil(t, err) + assert.Equal(t, ErrNumOverflow, err) + assert.Equal(t, Idx(0), i) + +} From bcd9f96e1b3d8bdadcd13a3d119d82ea71bca45d Mon Sep 17 00:00:00 2001 From: arnaucube Date: Tue, 4 Aug 2020 18:42:20 +0200 Subject: [PATCH 4/6] Add batchbuilder applyCreateLeaf, applyDeposit, applyTransfer --- batchbuilder/batchbuilder.go | 124 ++++++++++++++++++++++-------- batchbuilder/batchbuilder_test.go | 13 +++- batchbuilder/state.go | 85 ++++++++++++++++++++ common/zk.go | 56 ++++++++++++++ 4 files changed, 245 insertions(+), 33 deletions(-) create mode 100644 batchbuilder/state.go create mode 100644 common/zk.go diff --git a/batchbuilder/batchbuilder.go b/batchbuilder/batchbuilder.go index 1f37124..c4bbb57 100644 --- a/batchbuilder/batchbuilder.go +++ b/batchbuilder/batchbuilder.go @@ -1,8 +1,6 @@ package batchbuilder import ( - "math/big" - ethCommon "github.com/ethereum/go-ethereum/common" "github.com/hermeznetwork/hermez-node/common" "github.com/iden3/go-merkletree" @@ -41,9 +39,8 @@ func NewBatchBuilder(stateDB db.Storage, configCircuits []ConfigCircuit, batchNu configCircuits: configCircuits, } - bb.Reset(batchNum, idx, true) - - return &bb, nil + err = bb.Reset(batchNum, idx, true) + return &bb, err } // Reset tells the BatchBuilder to reset it's internal state to the required @@ -55,27 +52,32 @@ func (bb *BatchBuilder) Reset(batchNum int, idx uint64, fromSynchronizer bool) e return nil } -type ZKInputs struct{} // TMP - -func (bb *BatchBuilder) BuildBatch(configBatch ConfigBatch, l1usertxs, l1coordinatortxs []common.L1Tx, l2txs []common.L2Tx, tokenIDs []common.TokenID) (*ZKInputs, error) { - +func (bb *BatchBuilder) BuildBatch(configBatch ConfigBatch, l1usertxs, l1coordinatortxs []common.L1Tx, l2txs []common.L2Tx, tokenIDs []common.TokenID) (*common.ZKInputs, error) { for _, tx := range l1usertxs { - bb.processL1Tx(tx) + err := bb.processL1Tx(tx) + if err != nil { + return nil, err + } } for _, tx := range l1coordinatortxs { - bb.processL1Tx(tx) + err := bb.processL1Tx(tx) + if err != nil { + return nil, err + } } for _, tx := range l2txs { switch tx.Type { case common.TxTypeTransfer: // go to the MT leaf of sender and receiver, and update // balance & nonce - bb.applyTransfer(tx.Tx) + err := bb.applyTransfer(tx.Tx) + if err != nil { + return nil, err + } case common.TxTypeExit: // execute exit flow default: } - } return nil, nil @@ -86,23 +88,40 @@ func (bb *BatchBuilder) processL1Tx(tx common.L1Tx) error { case common.TxTypeForceTransfer, common.TxTypeTransfer: // go to the MT leaf of sender and receiver, and update balance // & nonce - bb.applyTransfer(tx.Tx) + err := bb.applyTransfer(tx.Tx) + if err != nil { + return err + } case common.TxTypeCreateAccountDeposit: // add new leaf to the MT, update balance of the MT leaf - bb.applyCreateLeaf(tx) + err := bb.applyCreateLeaf(tx) + if err != nil { + return err + } case common.TxTypeDeposit: // update balance of the MT leaf - bb.applyDeposit(tx) + err := bb.applyDeposit(tx, false) + if err != nil { + return err + } case common.TxTypeDepositAndTransfer: // update balance in MT leaf, update balance & nonce of sender // & receiver - bb.applyDeposit(tx) // this after v0, can be done by bb.applyDepositAndTransfer in a single step - bb.applyTransfer(tx.Tx) + err := bb.applyDeposit(tx, true) + if err != nil { + return err + } case common.TxTypeCreateAccountDepositAndTransfer: // add new leaf to the merkletree, update balance in MT leaf, // update balance & nonce of sender & receiver - bb.applyCreateLeaf(tx) - bb.applyTransfer(tx.Tx) + err := bb.applyCreateLeaf(tx) + if err != nil { + return err + } + err = bb.applyTransfer(tx.Tx) + if err != nil { + return err + } case common.TxTypeExit: // execute exit flow default: @@ -114,11 +133,9 @@ func (bb *BatchBuilder) processL1Tx(tx common.L1Tx) error { // applyCreateLeaf creates a new leaf in the leaf of the depositer, it stores // the deposit value func (bb *BatchBuilder) applyCreateLeaf(tx common.L1Tx) error { - k := big.NewInt(int64(bb.idx + 1)) - leaf := common.Leaf{ TokenID: tx.TokenID, - Nonce: 0, // TODO check always that a new leaf is created nonce is at 0 + Nonce: 0, // TODO check w spec: always that a new leaf is created nonce is at 0 Balance: tx.LoadAmount, Ax: tx.FromBJJ.X, Ay: tx.FromBJJ.Y, @@ -129,38 +146,81 @@ func (bb *BatchBuilder) applyCreateLeaf(tx common.L1Tx) error { if err != nil { return err } - - // store at the DB the key: v, and value: leaf.Bytes() dbTx, err := bb.mt.DB().NewTx() if err != nil { return err } + + err = bb.CreateBalance(dbTx, common.Idx(bb.idx+1), leaf) + if err != nil { + return err + } leafBytes, err := leaf.Bytes() if err != nil { return err } dbTx.Put(v.Bytes(), leafBytes[:]) - // Add k & v into the MT - err = bb.mt.Add(k, v) - if err != nil { + // if everything is fine, do dbTx & increment idx + if err := dbTx.Commit(); err != nil { return err } - - // if everything is fine, increment idx bb.idx = bb.idx + 1 return nil } -// applyDeposit updates the balance in the leaf of the depositer -func (bb *BatchBuilder) applyDeposit(tx common.L1Tx) error { +// applyDeposit updates the balance in the leaf of the depositer, if andTransfer parameter is set to true, the method will also apply the Transfer of the L1Tx/DepositAndTransfer +func (bb *BatchBuilder) applyDeposit(tx common.L1Tx, andTransfer bool) error { + dbTx, err := bb.mt.DB().NewTx() + if err != nil { + return err + } + + // deposit + err = bb.UpdateBalance(dbTx, tx.FromIdx, tx.LoadAmount, false) + if err != nil { + return err + } + + // in case that the tx is a L1Tx>DepositAndTransfer + if andTransfer { + // transact + err = bb.UpdateBalance(dbTx, tx.FromIdx, tx.Tx.Amount, true) + if err != nil { + return err + } + err = bb.UpdateBalance(dbTx, tx.ToIdx, tx.Tx.Amount, false) + if err != nil { + return err + } + } + if err := dbTx.Commit(); err != nil { + return err + } return nil } // applyTransfer updates the balance & nonce in the leaf of the sender, and the // balance in the leaf of the receiver func (bb *BatchBuilder) applyTransfer(tx common.Tx) error { + dbTx, err := bb.mt.DB().NewTx() + if err != nil { + return err + } + + // transact + err = bb.UpdateBalance(dbTx, tx.FromIdx, tx.Amount, true) + if err != nil { + return err + } + err = bb.UpdateBalance(dbTx, tx.ToIdx, tx.Amount, false) + if err != nil { + return err + } + if err := dbTx.Commit(); err != nil { + return err + } return nil } diff --git a/batchbuilder/batchbuilder_test.go b/batchbuilder/batchbuilder_test.go index b8fd379..4ed5134 100644 --- a/batchbuilder/batchbuilder_test.go +++ b/batchbuilder/batchbuilder_test.go @@ -8,8 +8,19 @@ import ( "github.com/stretchr/testify/assert" ) -func TestBatchBuilder(t *testing.T) { +// func genTxs(n int) common.Tx { +// return common.Tx{} +// } +// func genL1Txs(n int) []common.L1Tx { +// +// return nil +// } +// func genL2Txs(n int) []common.L2Tx { +// +// return nil +// } +func TestBatchBuilder(t *testing.T) { stateDB := memory.NewMemoryStorage() bb, err := NewBatchBuilder(stateDB, nil, 0, 0, 32) diff --git a/batchbuilder/state.go b/batchbuilder/state.go new file mode 100644 index 0000000..bd2c2ef --- /dev/null +++ b/batchbuilder/state.go @@ -0,0 +1,85 @@ +package batchbuilder + +import ( + "math/big" + + "github.com/hermeznetwork/hermez-node/common" + "github.com/iden3/go-merkletree/db" +) + +// TODO move this file into StateDB, which Synchronizer will use in the disk DB, and BatchBuilder will use with the MemoryDB + +// GetBalance returns the balance for a given Idx from the DB +func (bb *BatchBuilder) GetBalance(tx db.Tx, idx common.Idx) (*common.Leaf, error) { + idxBytes := idx.Bytes() + vBytes, err := tx.Get(idxBytes[:]) + if err != nil { + return nil, err + } + var b [32 * 5]byte + copy(b[:], vBytes) + leaf, err := common.LeafFromBytes(b) + if err != nil { + return nil, err + } + return leaf, nil +} + +// CreateBalance stores the Leaf into the Idx position in the MerkleTree, also adds db entry for the Leaf value +func (bb *BatchBuilder) CreateBalance(tx db.Tx, idx common.Idx, leaf common.Leaf) error { + // store at the DB the key: v, and value: leaf.Bytes() + v, err := leaf.HashValue() + if err != nil { + return err + } + leafBytes, err := leaf.Bytes() + if err != nil { + return err + } + + // store the Leaf value + tx.Put(v.Bytes(), leafBytes[:]) + // Add k & v into the MT + err = bb.mt.Add(idx.BigInt(), v) + if err != nil { + return err + } + + return nil +} + +// UpdateBalance updates the balance of the leaf of a given Idx. +// If sending==true: will substract the amount, if sending==false will add the ammount +func (bb *BatchBuilder) UpdateBalance(tx db.Tx, idx common.Idx, amount *big.Int, sending bool) error { + leaf, err := bb.GetBalance(tx, idx) + if err != nil { + return err + } + + // TODO add checks that the numbers are correct and there is no missing value neither impossible values + if sending { + leaf.Balance = new(big.Int).Sub(leaf.Balance, amount) + } else { + leaf.Balance = new(big.Int).Add(leaf.Balance, amount) + } + + // store at the DB the key: v, and value: leaf.Bytes() + v, err := leaf.HashValue() + if err != nil { + return err + } + leafBytes, err := leaf.Bytes() + if err != nil { + return err + } + + // store the Leaf value + tx.Put(v.Bytes(), leafBytes[:]) + // Add k & v into the MT + err = bb.mt.Update(idx.BigInt(), v) + if err != nil { + return err + } + + return nil +} diff --git a/common/zk.go b/common/zk.go new file mode 100644 index 0000000..8392ca9 --- /dev/null +++ b/common/zk.go @@ -0,0 +1,56 @@ +package common + +import ( + "math/big" +) + +type ZKInputs struct { + InitialIdx uint64 + OldStRoot Hash + FeePlanCoins *big.Int + FeeTotals *big.Int + PubEthAddress *big.Int + + ImStateRoot []Hash + ImExitRoot []Hash + + ImOnChainHash []Hash + ImOnChain []*big.Int + TxData []*big.Int + + FromIdx []uint64 + ToIdX []uint64 + ToAx []*big.Int + ToAy []*big.Int + ToEthAddr []*big.Int + FromEthAddr []*big.Int + FromAx []*big.Int + FromAy []*big.Int + + RqTxData []*big.Int + LoadAmount []*big.Int + + S []*big.Int + R8x []*big.Int + R8y []*big.Int + + Ax1 []*big.Int + Ay1 []*big.Int + Amount1 []*big.Int + Nonce1 []*big.Int + EthAddr1 []*big.Int + Siblings1 [][]*big.Int + IsOld01 []*big.Int `json:"isOld0_1"` + OldKey1 []*big.Int + OldValue1 []*big.Int + + Ax2 []*big.Int + Ay2 []*big.Int + Amount2 []*big.Int + Nonce2 []*big.Int + EthAddr2 []*big.Int + Siblings2 [][]*big.Int + IsOld02 []*big.Int `json:"isOld0_2"` + OldKey2 []*big.Int + OldValue2 []*big.Int +} From 16555b51e338ea4313345284414786d4d5640e7e Mon Sep 17 00:00:00 2001 From: arnaucube Date: Wed, 5 Aug 2020 16:06:31 +0200 Subject: [PATCH 5/6] Update Leaf to new spec (Sign+Ay) --- batchbuilder/batchbuilder.go | 9 +++- batchbuilder/state.go | 4 +- common/leaf.go | 45 +++++++++--------- common/leaf_test.go | 91 +++++++++++++++++------------------- 4 files changed, 74 insertions(+), 75 deletions(-) diff --git a/batchbuilder/batchbuilder.go b/batchbuilder/batchbuilder.go index c4bbb57..23be0ea 100644 --- a/batchbuilder/batchbuilder.go +++ b/batchbuilder/batchbuilder.go @@ -3,17 +3,20 @@ package batchbuilder import ( ethCommon "github.com/ethereum/go-ethereum/common" "github.com/hermeznetwork/hermez-node/common" + "github.com/iden3/go-iden3-crypto/babyjub" "github.com/iden3/go-merkletree" "github.com/iden3/go-merkletree/db" "github.com/iden3/go-merkletree/db/memory" ) +// ConfigCircuit contains the circuit configuration type ConfigCircuit struct { TxsMax uint64 L1TxsMax uint64 SMTLevelsMax uint64 } +// BatchBuilder implements the batch builder type, which contains the functionallities type BatchBuilder struct { StateDB db.Storage // where the MTs will be stored by the Synchronizer idx uint64 @@ -21,6 +24,7 @@ type BatchBuilder struct { configCircuits []ConfigCircuit } +// ConfigBatch contains the batch configuration type ConfigBatch struct { CoordinatorAddress ethCommon.Address } @@ -48,10 +52,11 @@ func NewBatchBuilder(stateDB db.Storage, configCircuits []ConfigCircuit, batchNu // copy of the rollup state from the Synchronizer at that `batchNum`, otherwise // it can just roll back the internal copy. func (bb *BatchBuilder) Reset(batchNum int, idx uint64, fromSynchronizer bool) error { - + // TODO return nil } +// BuildBatch takes the transactions and returns the common.ZKInputs of the next batch func (bb *BatchBuilder) BuildBatch(configBatch ConfigBatch, l1usertxs, l1coordinatortxs []common.L1Tx, l2txs []common.L2Tx, tokenIDs []common.TokenID) (*common.ZKInputs, error) { for _, tx := range l1usertxs { err := bb.processL1Tx(tx) @@ -137,7 +142,7 @@ func (bb *BatchBuilder) applyCreateLeaf(tx common.L1Tx) error { TokenID: tx.TokenID, Nonce: 0, // TODO check w spec: always that a new leaf is created nonce is at 0 Balance: tx.LoadAmount, - Ax: tx.FromBJJ.X, + Sign: babyjub.PointCoordSign(tx.FromBJJ.X), Ay: tx.FromBJJ.Y, EthAddr: tx.FromEthAddr, } diff --git a/batchbuilder/state.go b/batchbuilder/state.go index bd2c2ef..be6ca63 100644 --- a/batchbuilder/state.go +++ b/batchbuilder/state.go @@ -7,7 +7,7 @@ import ( "github.com/iden3/go-merkletree/db" ) -// TODO move this file into StateDB, which Synchronizer will use in the disk DB, and BatchBuilder will use with the MemoryDB +// TODO next iteration move the methods of this file into StateDB, which Synchronizer will use in the disk DB, and BatchBuilder will use with the MemoryDB // GetBalance returns the balance for a given Idx from the DB func (bb *BatchBuilder) GetBalance(tx db.Tx, idx common.Idx) (*common.Leaf, error) { @@ -16,7 +16,7 @@ func (bb *BatchBuilder) GetBalance(tx db.Tx, idx common.Idx) (*common.Leaf, erro if err != nil { return nil, err } - var b [32 * 5]byte + var b [32 * common.NLEAFELEMS]byte copy(b[:], vBytes) leaf, err := common.LeafFromBytes(b) if err != nil { diff --git a/common/leaf.go b/common/leaf.go index b880ad5..87b5445 100644 --- a/common/leaf.go +++ b/common/leaf.go @@ -12,19 +12,21 @@ import ( cryptoUtils "github.com/iden3/go-iden3-crypto/utils" ) +const NLEAFELEMS = 4 + // Leaf is the data structure stored in the Leaf of the MerkleTree type Leaf struct { TokenID TokenID Nonce uint64 // max of 40 bits used Balance *big.Int // max of 192 bits used - Ax *big.Int + Sign bool Ay *big.Int EthAddr eth.Address } // Bytes returns the bytes representing the Leaf, in a way that each BigInt is represented by 32 bytes, in spite of the BigInt could be represented in less bytes (due a small big.Int), so in this way each BigInt is always 32 bytes and can be automatically parsed from a byte array. -func (l *Leaf) Bytes() ([32 * 5]byte, error) { - var b [32 * 5]byte +func (l *Leaf) Bytes() ([32 * NLEAFELEMS]byte, error) { + var b [32 * NLEAFELEMS]byte if l.Nonce >= uint64(math.Pow(2, 40)) { return b, fmt.Errorf("%s Nonce", ErrNumOverflow) @@ -40,17 +42,19 @@ func (l *Leaf) Bytes() ([32 * 5]byte, error) { copy(b[0:4], tokenIDBytes[:]) copy(b[4:9], nonceBytes[:]) + if l.Sign { + b[10] = 1 + } copy(b[32:64], SwapEndianness(l.Balance.Bytes())) // SwapEndianness, as big.Int uses BigEndian - copy(b[64:96], SwapEndianness(l.Ax.Bytes())) - copy(b[96:128], SwapEndianness(l.Ay.Bytes())) - copy(b[128:148], l.EthAddr.Bytes()) + copy(b[64:96], SwapEndianness(l.Ay.Bytes())) + copy(b[96:116], l.EthAddr.Bytes()) return b, nil } // BigInts returns the [5]*big.Int, where each *big.Int is inside the Finite Field -func (l *Leaf) BigInts() ([5]*big.Int, error) { - e := [5]*big.Int{} +func (l *Leaf) BigInts() ([NLEAFELEMS]*big.Int, error) { + e := [NLEAFELEMS]*big.Int{} b, err := l.Bytes() if err != nil { @@ -61,7 +65,6 @@ func (l *Leaf) BigInts() ([5]*big.Int, error) { e[1] = new(big.Int).SetBytes(SwapEndianness(b[32:64])) e[2] = new(big.Int).SetBytes(SwapEndianness(b[64:96])) e[3] = new(big.Int).SetBytes(SwapEndianness(b[96:128])) - e[4] = new(big.Int).SetBytes(SwapEndianness(b[128:160])) return e, nil } @@ -80,41 +83,39 @@ func (l *Leaf) HashValue() (*big.Int, error) { } // LeafFromBigInts returns a Leaf from a [5]*big.Int -func LeafFromBigInts(e [5]*big.Int) (*Leaf, error) { +func LeafFromBigInts(e [NLEAFELEMS]*big.Int) (*Leaf, error) { if !cryptoUtils.CheckBigIntArrayInField(e[:]) { return nil, ErrNotInFF } - var b [32 * 5]byte + var b [32 * NLEAFELEMS]byte copy(b[0:32], SwapEndianness(e[0].Bytes())) // SwapEndianness, as big.Int uses BigEndian copy(b[32:64], SwapEndianness(e[1].Bytes())) copy(b[64:96], SwapEndianness(e[2].Bytes())) copy(b[96:128], SwapEndianness(e[3].Bytes())) - copy(b[128:160], SwapEndianness(e[4].Bytes())) return LeafFromBytes(b) } // LeafFromBytes returns a Leaf from a byte array -func LeafFromBytes(b [32 * 5]byte) (*Leaf, error) { +func LeafFromBytes(b [32 * NLEAFELEMS]byte) (*Leaf, error) { tokenID := binary.LittleEndian.Uint32(b[0:4]) - nonce := binary.LittleEndian.Uint64(b[4:12]) - if !bytes.Equal(b[9:12], []byte{0, 0, 0}) { // alternatively: if nonce >= uint64(math.Pow(2, 40)) { + var nonceBytes [8]byte + copy(nonceBytes[:], b[4:9]) + nonce := binary.LittleEndian.Uint64(nonceBytes[:]) + if nonce >= uint64(math.Pow(2, 40)) { return nil, fmt.Errorf("%s Nonce", ErrNumOverflow) } + sign := b[10] == 1 balance := new(big.Int).SetBytes(SwapEndianness(b[32:56])) // b[32:56], as Balance is 192 bits (24 bytes) if !bytes.Equal(b[56:64], []byte{0, 0, 0, 0, 0, 0, 0, 0}) { return nil, fmt.Errorf("%s Balance", ErrNumOverflow) } - ax := new(big.Int).SetBytes(SwapEndianness(b[64:96])) // SwapEndianness, as big.Int uses BigEndian - ay := new(big.Int).SetBytes(SwapEndianness(b[96:128])) - ethAddr := eth.BytesToAddress(b[128:148]) + ay := new(big.Int).SetBytes(SwapEndianness(b[64:96])) + ethAddr := eth.BytesToAddress(b[96:116]) if !cryptoUtils.CheckBigIntInField(balance) { return nil, ErrNotInFF } - if !cryptoUtils.CheckBigIntInField(ax) { - return nil, ErrNotInFF - } if !cryptoUtils.CheckBigIntInField(ay) { return nil, ErrNotInFF } @@ -123,7 +124,7 @@ func LeafFromBytes(b [32 * 5]byte) (*Leaf, error) { TokenID: TokenID(tokenID), Nonce: nonce, Balance: balance, - Ax: ax, + Sign: sign, Ay: ay, EthAddr: ethAddr, } diff --git a/common/leaf_test.go b/common/leaf_test.go index 1e27e35..d51b1ab 100644 --- a/common/leaf_test.go +++ b/common/leaf_test.go @@ -7,7 +7,6 @@ import ( "testing" ethCommon "github.com/ethereum/go-ethereum/common" - ethCrypto "github.com/ethereum/go-ethereum/crypto" cryptoConstants "github.com/iden3/go-iden3-crypto/constants" cryptoUtils "github.com/iden3/go-iden3-crypto/utils" "github.com/stretchr/testify/assert" @@ -18,12 +17,13 @@ func TestLeaf(t *testing.T) { TokenID: TokenID(1), Nonce: uint64(1234), Balance: big.NewInt(1000), - Ax: big.NewInt(9876), + Sign: true, Ay: big.NewInt(6789), EthAddr: ethCommon.HexToAddress("0xc58d29fA6e86E4FAe04DDcEd660d45BCf3Cb2370"), } b, err := leaf.Bytes() assert.Nil(t, err) + assert.Equal(t, byte(1), b[10]) l1, err := LeafFromBytes(b) assert.Nil(t, err) assert.Equal(t, leaf, l1) @@ -34,11 +34,10 @@ func TestLeaf(t *testing.T) { assert.True(t, cryptoUtils.CheckBigIntInField(e[1])) assert.True(t, cryptoUtils.CheckBigIntInField(e[2])) assert.True(t, cryptoUtils.CheckBigIntInField(e[3])) - assert.True(t, cryptoUtils.CheckBigIntInField(e[4])) assert.Equal(t, "1000", e[1].String()) - assert.Equal(t, "9876", e[2].String()) - assert.Equal(t, "6789", e[3].String()) + assert.Equal(t, "6789", e[2].String()) + assert.Equal(t, new(big.Int).SetBytes(SwapEndianness(leaf.EthAddr.Bytes())).String(), e[3].String()) l2, err := LeafFromBigInts(e) assert.Nil(t, err) @@ -46,60 +45,59 @@ func TestLeaf(t *testing.T) { assert.Equal(t, l1, l2) } -func TestLeafLoop(t *testing.T) { - // check that for different Address there is no problem - for i := 0; i < 256; i++ { - key, err := ethCrypto.GenerateKey() - assert.Nil(t, err) - address := ethCrypto.PubkeyToAddress(key.PublicKey) - - leaf := &Leaf{ - TokenID: TokenID(i), - Nonce: uint64(i), - Balance: big.NewInt(1000), - Ax: big.NewInt(9876), - Ay: big.NewInt(6789), - EthAddr: address, - } - b, err := leaf.Bytes() - assert.Nil(t, err) - l1, err := LeafFromBytes(b) - assert.Nil(t, err) - assert.Equal(t, leaf, l1) - - e, err := leaf.BigInts() - assert.Nil(t, err) - assert.True(t, cryptoUtils.CheckBigIntInField(e[0])) - assert.True(t, cryptoUtils.CheckBigIntInField(e[1])) - assert.True(t, cryptoUtils.CheckBigIntInField(e[2])) - assert.True(t, cryptoUtils.CheckBigIntInField(e[3])) - assert.True(t, cryptoUtils.CheckBigIntInField(e[4])) - - l2, err := LeafFromBigInts(e) - assert.Nil(t, err) - assert.Equal(t, leaf, l2) - } -} +// func TestLeafLoop(t *testing.T) { +// // check that for different Address there is no problem +// for i := 0; i < 256; i++ { +// key, err := ethCrypto.GenerateKey() +// assert.Nil(t, err) +// address := ethCrypto.PubkeyToAddress(key.PublicKey) +// +// leaf := &Leaf{ +// TokenID: TokenID(i), +// Nonce: uint64(i), +// Balance: big.NewInt(1000), +// Sign: true, +// Ay: big.NewInt(6789), +// EthAddr: address, +// } +// b, err := leaf.Bytes() +// assert.Nil(t, err) +// l1, err := LeafFromBytes(b) +// assert.Nil(t, err) +// assert.Equal(t, leaf, l1) +// +// e, err := leaf.BigInts() +// assert.Nil(t, err) +// assert.True(t, cryptoUtils.CheckBigIntInField(e[0])) +// assert.True(t, cryptoUtils.CheckBigIntInField(e[1])) +// assert.True(t, cryptoUtils.CheckBigIntInField(e[2])) +// assert.True(t, cryptoUtils.CheckBigIntInField(e[3])) +// +// l2, err := LeafFromBigInts(e) +// assert.Nil(t, err) +// assert.Equal(t, leaf, l2) +// } +// } func TestLeafErrNotInFF(t *testing.T) { z := big.NewInt(0) // Q-1 should not give error r := new(big.Int).Sub(cryptoConstants.Q, big.NewInt(1)) - e := [5]*big.Int{z, z, r, r, r} + e := [NLEAFELEMS]*big.Int{z, z, r, r} _, err := LeafFromBigInts(e) assert.Nil(t, err) // Q should give error r = cryptoConstants.Q - e = [5]*big.Int{z, z, r, r, r} + e = [NLEAFELEMS]*big.Int{z, z, r, r} _, err = LeafFromBigInts(e) assert.NotNil(t, err) assert.Equal(t, ErrNotInFF, err) // Q+1 should give error r = new(big.Int).Add(cryptoConstants.Q, big.NewInt(1)) - e = [5]*big.Int{z, z, r, r, r} + e = [NLEAFELEMS]*big.Int{z, z, r, r} _, err = LeafFromBigInts(e) assert.NotNil(t, err) assert.Equal(t, ErrNotInFF, err) @@ -111,7 +109,7 @@ func TestLeafErrNumOverflowNonce(t *testing.T) { TokenID: TokenID(1), Nonce: uint64(math.Pow(2, 40) - 1), Balance: big.NewInt(1000), - Ax: big.NewInt(9876), + Sign: true, Ay: big.NewInt(6789), EthAddr: ethCommon.HexToAddress("0xc58d29fA6e86E4FAe04DDcEd660d45BCf3Cb2370"), } @@ -126,11 +124,6 @@ func TestLeafErrNumOverflowNonce(t *testing.T) { _, err = LeafFromBytes(b) assert.Nil(t, err) - - b[9] = 1 - _, err = LeafFromBytes(b) - assert.NotNil(t, err) - assert.Equal(t, fmt.Errorf("%s Nonce", ErrNumOverflow), err) } func TestLeafErrNumOverflowBalance(t *testing.T) { @@ -139,7 +132,7 @@ func TestLeafErrNumOverflowBalance(t *testing.T) { TokenID: TokenID(1), Nonce: uint64(math.Pow(2, 40) - 1), Balance: new(big.Int).Sub(new(big.Int).Exp(big.NewInt(2), big.NewInt(192), nil), big.NewInt(1)), - Ax: big.NewInt(9876), + Sign: true, Ay: big.NewInt(6789), EthAddr: ethCommon.HexToAddress("0xc58d29fA6e86E4FAe04DDcEd660d45BCf3Cb2370"), } From 2109d9f1cf27cd4b60990c1da47f5b825dde8192 Mon Sep 17 00:00:00 2001 From: arnau <17317030+arnaucube@users.noreply.github.com> Date: Thu, 6 Aug 2020 12:47:32 +0200 Subject: [PATCH 6/6] Apply suggestions from code review Co-authored-by: Eduard S. --- common/leaf.go | 6 +----- common/tx.go | 2 +- 2 files changed, 2 insertions(+), 6 deletions(-) diff --git a/common/leaf.go b/common/leaf.go index 87b5445..156c750 100644 --- a/common/leaf.go +++ b/common/leaf.go @@ -4,7 +4,6 @@ import ( "bytes" "encoding/binary" "fmt" - "math" "math/big" eth "github.com/ethereum/go-ethereum/common" @@ -28,7 +27,7 @@ type Leaf struct { func (l *Leaf) Bytes() ([32 * NLEAFELEMS]byte, error) { var b [32 * NLEAFELEMS]byte - if l.Nonce >= uint64(math.Pow(2, 40)) { + if l.Nonce > 0xffffffffff { return b, fmt.Errorf("%s Nonce", ErrNumOverflow) } if len(l.Balance.Bytes()) > 24 { @@ -102,9 +101,6 @@ func LeafFromBytes(b [32 * NLEAFELEMS]byte) (*Leaf, error) { var nonceBytes [8]byte copy(nonceBytes[:], b[4:9]) nonce := binary.LittleEndian.Uint64(nonceBytes[:]) - if nonce >= uint64(math.Pow(2, 40)) { - return nil, fmt.Errorf("%s Nonce", ErrNumOverflow) - } sign := b[10] == 1 balance := new(big.Int).SetBytes(SwapEndianness(b[32:56])) // b[32:56], as Balance is 192 bits (24 bytes) if !bytes.Equal(b[56:64], []byte{0, 0, 0, 0, 0, 0, 0, 0}) { diff --git a/common/tx.go b/common/tx.go index 393b9ef..3f2156f 100644 --- a/common/tx.go +++ b/common/tx.go @@ -22,7 +22,7 @@ func (idx Idx) BigInt() *big.Int { // IdxFromBigInt converts a *big.Int to Idx type func IdxFromBigInt(b *big.Int) (Idx, error) { - if b.Int64() > 4294967295 { // 2**32-1 + if b.Int64() > 0xffffffff { // 2**32-1 return 0, ErrNumOverflow } return Idx(uint32(b.Int64())), nil