arnaucube
arnaucube/hermez-nodePublic Self-hosted repository
Update SQL types, improve SQL *big.Int

- In SQL Tables, set rollup_vars.forge_l1_timeout to BIGINT (instead of BYTEA)
- In "bigint" encoding/decoding used with meddler, store the *big.Int as raw
  bytes, instead of base64 to be more space efficient
Eduard S eduard@iden3.io
Wed, 18 Nov 2020 12:54:45 +0100
commit

738fa0ac30ac1185a56b941565a09803a314642d

parent

0e7d3e72fd29f673b3312644a56495e1c5c03121

3 files changed, 19 insertions(+), 46 deletions(-)

jump to
M apitypes/apitypes.go → apitypes/apitypes.go

@@ -33,25 +33,12 @@ }

// Scan implements Scanner for database/sql func (b *BigIntStr) Scan(src interface{}) error { - // decode base64 src - var decoded []byte - var err error - if srcStr, ok := src.(string); ok { - // src is a string - decoded, err = base64.StdEncoding.DecodeString(srcStr) - } else if srcBytes, ok := src.([]byte); ok { - // src is []byte - decoded, err = base64.StdEncoding.DecodeString(string(srcBytes)) - } else { - // unexpected src + srcBytes, ok := src.([]byte) + if !ok { return fmt.Errorf("can't scan %T into apitypes.BigIntStr", src) } - if err != nil { - return err - } - // decoded bytes to *big.Int - bigInt := &big.Int{} - bigInt = bigInt.SetBytes(decoded) + // bytes to *big.Int + bigInt := new(big.Int).SetBytes(srcBytes) // *big.Int to BigIntStr bigIntStr := NewBigIntStr(bigInt) if bigIntStr == nil {

@@ -64,13 +51,12 @@

// Value implements valuer for database/sql func (b BigIntStr) Value() (driver.Value, error) { // string to *big.Int - bigInt := &big.Int{} - bigInt, ok := bigInt.SetString(string(b), 10) + bigInt, ok := new(big.Int).SetString(string(b), 10) if !ok || bigInt == nil { return nil, errors.New("invalid representation of a *big.Int") } - // *big.Int to base64 - return base64.StdEncoding.EncodeToString(bigInt.Bytes()), nil + // *big.Int to bytes + return bigInt.Bytes(), nil } // StrBigInt is used to unmarshal BigIntStr directly into an alias of big.Int
M db/migrations/0001.sql → db/migrations/0001.sql

@@ -526,7 +526,7 @@

CREATE TABLE rollup_vars ( eth_block_num BIGINT PRIMARY KEY REFERENCES block (eth_block_num) ON DELETE CASCADE, fee_add_token BYTEA NOT NULL, - forge_l1_timeout BYTEA NOT NULL, + forge_l1_timeout BIGINT NOT NULL, withdrawal_delay BIGINT NOT NULL, buckets BYTEA );
M db/utils.go → db/utils.go

@@ -1,7 +1,6 @@

package db import ( - "encoding/base64" "fmt" "math/big" "reflect"

@@ -95,14 +94,8 @@ ptr := scanTarget.(*string)

if ptr == nil { return fmt.Errorf("BigIntMeddler.PostRead: nil pointer") } - - data, err := base64.StdEncoding.DecodeString(*ptr) - if err != nil { - return fmt.Errorf("big.Int decode error: %v", err) - } field := fieldPtr.(**big.Int) - *field = new(big.Int).SetBytes(data) - + *field = new(big.Int).SetBytes([]byte(*ptr)) return nil }

@@ -110,9 +103,7 @@ // PreWrite is called before an Insert or Update operation for fields that have the BigIntMeddler

func (b BigIntMeddler) PreWrite(fieldPtr interface{}) (saveValue interface{}, err error) { field := fieldPtr.(*big.Int) - str := base64.StdEncoding.EncodeToString(field.Bytes()) - - return str, nil + return field.Bytes(), nil } // BigIntNullMeddler encodes or decodes the field value to or from JSON

@@ -125,23 +116,19 @@ }

// PostRead is called after a Scan operation for fields that have the BigIntNullMeddler func (b BigIntNullMeddler) PostRead(fieldPtr, scanTarget interface{}) error { - sv := reflect.ValueOf(scanTarget) - if sv.Elem().IsNil() { + field := fieldPtr.(**big.Int) + ptrPtr := scanTarget.(*interface{}) + if *ptrPtr == nil { // null column, so set target to be zero value - fv := reflect.ValueOf(fieldPtr) - fv.Elem().Set(reflect.Zero(fv.Elem().Type())) + *field = nil return nil } // not null - encoded := new([]byte) - refEnc := reflect.ValueOf(encoded) - refEnc.Elem().Set(sv.Elem().Elem()) - data, err := base64.StdEncoding.DecodeString(string(*encoded)) - if err != nil { - return fmt.Errorf("big.Int decode error: %v", err) + ptr := (*ptrPtr).([]byte) + if ptr == nil { + return fmt.Errorf("BigIntMeddler.PostRead: nil pointer") } - field := fieldPtr.(**big.Int) - *field = new(big.Int).SetBytes(data) + *field = new(big.Int).SetBytes(ptr) return nil }

@@ -151,7 +138,7 @@ field := fieldPtr.(*big.Int)

if field == nil { return nil, nil } - return base64.StdEncoding.EncodeToString(field.Bytes()), nil + return field.Bytes(), nil } // SliceToSlicePtrs converts any []Foo to []*Foo