mirror of
https://github.com/arnaucube/hermez-node.git
synced 2026-02-07 11:26:44 +01:00
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
This commit is contained in:
@@ -33,25 +33,12 @@ func NewBigIntStr(bigInt *big.Int) *BigIntStr {
|
|||||||
|
|
||||||
// Scan implements Scanner for database/sql
|
// Scan implements Scanner for database/sql
|
||||||
func (b *BigIntStr) Scan(src interface{}) error {
|
func (b *BigIntStr) Scan(src interface{}) error {
|
||||||
// decode base64 src
|
srcBytes, ok := src.([]byte)
|
||||||
var decoded []byte
|
if !ok {
|
||||||
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
|
|
||||||
return fmt.Errorf("can't scan %T into apitypes.BigIntStr", src)
|
return fmt.Errorf("can't scan %T into apitypes.BigIntStr", src)
|
||||||
}
|
}
|
||||||
if err != nil {
|
// bytes to *big.Int
|
||||||
return err
|
bigInt := new(big.Int).SetBytes(srcBytes)
|
||||||
}
|
|
||||||
// decoded bytes to *big.Int
|
|
||||||
bigInt := &big.Int{}
|
|
||||||
bigInt = bigInt.SetBytes(decoded)
|
|
||||||
// *big.Int to BigIntStr
|
// *big.Int to BigIntStr
|
||||||
bigIntStr := NewBigIntStr(bigInt)
|
bigIntStr := NewBigIntStr(bigInt)
|
||||||
if bigIntStr == nil {
|
if bigIntStr == nil {
|
||||||
@@ -64,13 +51,12 @@ func (b *BigIntStr) Scan(src interface{}) error {
|
|||||||
// Value implements valuer for database/sql
|
// Value implements valuer for database/sql
|
||||||
func (b BigIntStr) Value() (driver.Value, error) {
|
func (b BigIntStr) Value() (driver.Value, error) {
|
||||||
// string to *big.Int
|
// string to *big.Int
|
||||||
bigInt := &big.Int{}
|
bigInt, ok := new(big.Int).SetString(string(b), 10)
|
||||||
bigInt, ok := bigInt.SetString(string(b), 10)
|
|
||||||
if !ok || bigInt == nil {
|
if !ok || bigInt == nil {
|
||||||
return nil, errors.New("invalid representation of a *big.Int")
|
return nil, errors.New("invalid representation of a *big.Int")
|
||||||
}
|
}
|
||||||
// *big.Int to base64
|
// *big.Int to bytes
|
||||||
return base64.StdEncoding.EncodeToString(bigInt.Bytes()), nil
|
return bigInt.Bytes(), nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// StrBigInt is used to unmarshal BigIntStr directly into an alias of big.Int
|
// StrBigInt is used to unmarshal BigIntStr directly into an alias of big.Int
|
||||||
|
|||||||
@@ -526,7 +526,7 @@ FOR EACH ROW EXECUTE PROCEDURE forge_l1_user_txs();
|
|||||||
CREATE TABLE rollup_vars (
|
CREATE TABLE rollup_vars (
|
||||||
eth_block_num BIGINT PRIMARY KEY REFERENCES block (eth_block_num) ON DELETE CASCADE,
|
eth_block_num BIGINT PRIMARY KEY REFERENCES block (eth_block_num) ON DELETE CASCADE,
|
||||||
fee_add_token BYTEA NOT NULL,
|
fee_add_token BYTEA NOT NULL,
|
||||||
forge_l1_timeout BYTEA NOT NULL,
|
forge_l1_timeout BIGINT NOT NULL,
|
||||||
withdrawal_delay BIGINT NOT NULL,
|
withdrawal_delay BIGINT NOT NULL,
|
||||||
buckets BYTEA
|
buckets BYTEA
|
||||||
);
|
);
|
||||||
|
|||||||
35
db/utils.go
35
db/utils.go
@@ -1,7 +1,6 @@
|
|||||||
package db
|
package db
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"encoding/base64"
|
|
||||||
"fmt"
|
"fmt"
|
||||||
"math/big"
|
"math/big"
|
||||||
"reflect"
|
"reflect"
|
||||||
@@ -95,14 +94,8 @@ func (b BigIntMeddler) PostRead(fieldPtr, scanTarget interface{}) error {
|
|||||||
if ptr == nil {
|
if ptr == nil {
|
||||||
return fmt.Errorf("BigIntMeddler.PostRead: nil pointer")
|
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 := fieldPtr.(**big.Int)
|
||||||
*field = new(big.Int).SetBytes(data)
|
*field = new(big.Int).SetBytes([]byte(*ptr))
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -110,9 +103,7 @@ func (b BigIntMeddler) PostRead(fieldPtr, scanTarget interface{}) error {
|
|||||||
func (b BigIntMeddler) PreWrite(fieldPtr interface{}) (saveValue interface{}, err error) {
|
func (b BigIntMeddler) PreWrite(fieldPtr interface{}) (saveValue interface{}, err error) {
|
||||||
field := fieldPtr.(*big.Int)
|
field := fieldPtr.(*big.Int)
|
||||||
|
|
||||||
str := base64.StdEncoding.EncodeToString(field.Bytes())
|
return field.Bytes(), nil
|
||||||
|
|
||||||
return str, nil
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// BigIntNullMeddler encodes or decodes the field value to or from JSON
|
// BigIntNullMeddler encodes or decodes the field value to or from JSON
|
||||||
@@ -125,23 +116,19 @@ func (b BigIntNullMeddler) PreRead(fieldAddr interface{}) (scanTarget interface{
|
|||||||
|
|
||||||
// PostRead is called after a Scan operation for fields that have the BigIntNullMeddler
|
// PostRead is called after a Scan operation for fields that have the BigIntNullMeddler
|
||||||
func (b BigIntNullMeddler) PostRead(fieldPtr, scanTarget interface{}) error {
|
func (b BigIntNullMeddler) PostRead(fieldPtr, scanTarget interface{}) error {
|
||||||
sv := reflect.ValueOf(scanTarget)
|
field := fieldPtr.(**big.Int)
|
||||||
if sv.Elem().IsNil() {
|
ptrPtr := scanTarget.(*interface{})
|
||||||
|
if *ptrPtr == nil {
|
||||||
// null column, so set target to be zero value
|
// null column, so set target to be zero value
|
||||||
fv := reflect.ValueOf(fieldPtr)
|
*field = nil
|
||||||
fv.Elem().Set(reflect.Zero(fv.Elem().Type()))
|
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
// not null
|
// not null
|
||||||
encoded := new([]byte)
|
ptr := (*ptrPtr).([]byte)
|
||||||
refEnc := reflect.ValueOf(encoded)
|
if ptr == nil {
|
||||||
refEnc.Elem().Set(sv.Elem().Elem())
|
return fmt.Errorf("BigIntMeddler.PostRead: nil pointer")
|
||||||
data, err := base64.StdEncoding.DecodeString(string(*encoded))
|
|
||||||
if err != nil {
|
|
||||||
return fmt.Errorf("big.Int decode error: %v", err)
|
|
||||||
}
|
}
|
||||||
field := fieldPtr.(**big.Int)
|
*field = new(big.Int).SetBytes(ptr)
|
||||||
*field = new(big.Int).SetBytes(data)
|
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -151,7 +138,7 @@ func (b BigIntNullMeddler) PreWrite(fieldPtr interface{}) (saveValue interface{}
|
|||||||
if field == nil {
|
if field == nil {
|
||||||
return nil, nil
|
return nil, nil
|
||||||
}
|
}
|
||||||
return base64.StdEncoding.EncodeToString(field.Bytes()), nil
|
return field.Bytes(), nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// SliceToSlicePtrs converts any []Foo to []*Foo
|
// SliceToSlicePtrs converts any []Foo to []*Foo
|
||||||
|
|||||||
Reference in New Issue
Block a user