Avoid using pointers in common

This commit is contained in:
Arnau B
2020-10-07 18:43:48 +02:00
parent 5ec18f0378
commit 5097939b12
30 changed files with 673 additions and 564 deletions

View File

@@ -21,7 +21,6 @@ type Batch struct {
ExitRoot Hash `meddler:"exit_root"`
ForgeL1TxsNum *int64 `meddler:"forge_l1_txs_num"` // optional, Only when the batch forges L1 txs. Identifier that corresponds to the group of L1 txs forged in the current batch.
SlotNum SlotNum `meddler:"slot_num"` // Slot in which the batch is forged
TotalFeesUSD *float64 `meddler:"total_fees_usd"`
}
// BatchNum identifies a batch

View File

@@ -31,7 +31,7 @@ type L1Tx struct {
ToForgeL1TxsNum *int64 // toForgeL1TxsNum in which the tx was forged / will be forged
Position int
UserOrigin bool // true if the tx was originated by a user, false if it was aoriginated by a coordinator. Note that this differ from the spec for implementation simplification purpposes
FromIdx *Idx // FromIdx is used by L1Tx/Deposit to indicate the Idx receiver of the L1Tx.LoadAmount (deposit)
FromIdx Idx // FromIdx is used by L1Tx/Deposit to indicate the Idx receiver of the L1Tx.LoadAmount (deposit)
FromEthAddr ethCommon.Address
FromBJJ *babyjub.PublicKey
ToIdx Idx // ToIdx is ignored in L1Tx/Deposit, but used in the L1Tx/DepositAndTransfer
@@ -41,8 +41,6 @@ type L1Tx struct {
EthBlockNum int64 // Ethereum Block Number in which this L1Tx was added to the queue
Type TxType
BatchNum *BatchNum
USD *float64
LoadAmountUSD *float64
}
// NewL1Tx returns the given L1Tx with the TxId & Type parameters calculated
@@ -50,7 +48,7 @@ type L1Tx struct {
func NewL1Tx(l1Tx *L1Tx) (*L1Tx, error) {
// calculate TxType
var txType TxType
if l1Tx.FromIdx == nil {
if l1Tx.FromIdx == 0 {
if l1Tx.ToIdx == Idx(0) {
txType = TxTypeCreateAccountDeposit
} else if l1Tx.ToIdx >= IdxUserThreshold {
@@ -58,7 +56,7 @@ func NewL1Tx(l1Tx *L1Tx) (*L1Tx, error) {
} else {
return l1Tx, fmt.Errorf("Can not determine type of L1Tx, invalid ToIdx value: %d", l1Tx.ToIdx)
}
} else if *l1Tx.FromIdx >= IdxUserThreshold {
} else if l1Tx.FromIdx >= IdxUserThreshold {
if l1Tx.ToIdx == Idx(0) {
txType = TxTypeDeposit
} else if l1Tx.ToIdx == Idx(1) {
@@ -123,28 +121,22 @@ func (tx *L1Tx) Tx() *Tx {
amountFloat, _ := f.Float64()
userOrigin := new(bool)
*userOrigin = tx.UserOrigin
fromEthAddr := new(ethCommon.Address)
*fromEthAddr = tx.FromEthAddr
toIdx := new(Idx)
*toIdx = tx.ToIdx
genericTx := &Tx{
IsL1: true,
TxID: tx.TxID,
Type: tx.Type,
Position: tx.Position,
FromIdx: tx.FromIdx,
ToIdx: toIdx,
ToIdx: tx.ToIdx,
Amount: tx.Amount,
AmountFloat: amountFloat,
TokenID: tx.TokenID,
ToForgeL1TxsNum: tx.ToForgeL1TxsNum,
UserOrigin: userOrigin,
FromEthAddr: fromEthAddr,
FromEthAddr: tx.FromEthAddr,
FromBJJ: tx.FromBJJ,
LoadAmount: tx.LoadAmount,
EthBlockNum: tx.EthBlockNum,
USD: tx.USD,
LoadAmountUSD: tx.LoadAmountUSD,
}
if tx.LoadAmount != nil {
lf := new(big.Float).SetInt(tx.LoadAmount)
@@ -219,10 +211,7 @@ func L1TxFromBytes(b []byte) (*L1Tx, error) {
if err != nil {
return nil, err
}
if fromIdx != 0 {
tx.FromIdx = new(Idx)
*tx.FromIdx = fromIdx
}
tx.FromIdx = fromIdx
tx.LoadAmount = Float16FromBytes(b[58:60]).BigInt()
tx.Amount = Float16FromBytes(b[60:62]).BigInt()
tx.TokenID, err = TokenIDFromBytes(b[62:66])

View File

@@ -17,7 +17,6 @@ import (
func TestNewL1UserTx(t *testing.T) {
toForge := int64(123456)
fromIdx := Idx(300)
l1Tx := &L1Tx{
ToForgeL1TxsNum: &toForge,
Position: 71,
@@ -26,7 +25,7 @@ func TestNewL1UserTx(t *testing.T) {
TokenID: 5,
Amount: big.NewInt(1),
LoadAmount: big.NewInt(2),
FromIdx: &fromIdx,
FromIdx: Idx(300),
}
l1Tx, err := NewL1Tx(l1Tx)
assert.Nil(t, err)
@@ -34,7 +33,6 @@ func TestNewL1UserTx(t *testing.T) {
}
func TestNewL1CoordinatorTx(t *testing.T) {
fromIdx := Idx(300)
batchNum := BatchNum(51966)
l1Tx := &L1Tx{
Position: 88,
@@ -43,7 +41,7 @@ func TestNewL1CoordinatorTx(t *testing.T) {
TokenID: 5,
Amount: big.NewInt(1),
LoadAmount: big.NewInt(2),
FromIdx: &fromIdx,
FromIdx: Idx(300),
BatchNum: &batchNum,
}
l1Tx, err := NewL1Tx(l1Tx)
@@ -59,14 +57,12 @@ func TestL1TxByteParsers(t *testing.T) {
pk, err := pkComp.Decompress()
require.Nil(t, err)
fromIdx := new(Idx)
*fromIdx = 2
l1Tx := &L1Tx{
ToIdx: 3,
TokenID: 5,
Amount: big.NewInt(1),
LoadAmount: big.NewInt(2),
FromIdx: fromIdx,
FromIdx: 2,
FromBJJ: pk,
FromEthAddr: ethCommon.HexToAddress("0xc58d29fA6e86E4FAe04DDcEd660d45BCf3Cb2370"),
}

View File

@@ -14,9 +14,7 @@ type L2Tx struct {
FromIdx Idx
ToIdx Idx
Amount *big.Int
USD *float64
Fee FeeSelector
FeeUSD *float64
Nonce Nonce
Type TxType
EthBlockNum int64 // Ethereum Block Number in which this L2Tx was added to the queue
@@ -60,32 +58,23 @@ func NewL2Tx(l2Tx *L2Tx) (*L2Tx, error) {
// Tx returns a *Tx from the L2Tx
func (tx *L2Tx) Tx() *Tx {
f := new(big.Float).SetInt(tx.Amount)
amountFloat, _ := f.Float64()
batchNum := new(BatchNum)
*batchNum = tx.BatchNum
fee := new(FeeSelector)
*fee = tx.Fee
nonce := new(Nonce)
*nonce = tx.Nonce
fromIdx := new(Idx)
*fromIdx = tx.FromIdx
toIdx := new(Idx)
*toIdx = tx.ToIdx
return &Tx{
IsL1: false,
TxID: tx.TxID,
Type: tx.Type,
Position: tx.Position,
FromIdx: fromIdx,
ToIdx: toIdx,
FromIdx: tx.FromIdx,
ToIdx: tx.ToIdx,
Amount: tx.Amount,
USD: tx.USD,
AmountFloat: amountFloat,
BatchNum: batchNum,
EthBlockNum: tx.EthBlockNum,
Fee: fee,
FeeUSD: tx.FeeUSD,
Nonce: nonce,
}
}
@@ -93,19 +82,14 @@ func (tx *L2Tx) Tx() *Tx {
// PoolL2Tx returns the data structure of PoolL2Tx with the parameters of a
// L2Tx filled
func (tx *L2Tx) PoolL2Tx() *PoolL2Tx {
batchNum := new(BatchNum)
*batchNum = tx.BatchNum
toIdx := new(Idx)
*toIdx = tx.ToIdx
return &PoolL2Tx{
TxID: tx.TxID,
BatchNum: batchNum,
FromIdx: tx.FromIdx,
ToIdx: toIdx,
Amount: tx.Amount,
Fee: tx.Fee,
Nonce: tx.Nonce,
Type: tx.Type,
TxID: tx.TxID,
FromIdx: tx.FromIdx,
ToIdx: tx.ToIdx,
Amount: tx.Amount,
Fee: tx.Fee,
Nonce: tx.Nonce,
Type: tx.Type,
}
}

View File

@@ -1,7 +1,6 @@
package common
import (
"errors"
"fmt"
"math/big"
"time"
@@ -18,32 +17,29 @@ type PoolL2Tx struct {
// TxID (12 bytes) for L2Tx is:
// bytes: | 1 | 6 | 5 |
// values: | type | FromIdx | Nonce |
TxID TxID `meddler:"tx_id"`
FromIdx Idx `meddler:"from_idx"` // FromIdx is used by L1Tx/Deposit to indicate the Idx receiver of the L1Tx.LoadAmount (deposit)
ToIdx *Idx `meddler:"to_idx"` // ToIdx is ignored in L1Tx/Deposit, but used in the L1Tx/DepositAndTransfer
ToEthAddr *ethCommon.Address `meddler:"to_eth_addr"`
ToBJJ *babyjub.PublicKey `meddler:"to_bjj"` // TODO: stop using json, use scanner/valuer
TokenID TokenID `meddler:"token_id"`
Amount *big.Int `meddler:"amount,bigint"` // TODO: change to float16
AmountFloat float64 `meddler:"amount_f"` // TODO: change to float16
USD *float64 `meddler:"value_usd"` // TODO: change to float16
Fee FeeSelector `meddler:"fee"`
Nonce Nonce `meddler:"nonce"` // effective 40 bits used
State PoolL2TxState `meddler:"state"`
Signature *babyjub.Signature `meddler:"signature"` // tx signature
Timestamp time.Time `meddler:"timestamp,utctime"` // time when added to the tx pool
TxID TxID `meddler:"tx_id"`
FromIdx Idx `meddler:"from_idx"`
ToIdx Idx `meddler:"to_idx,zeroisnull"`
ToEthAddr ethCommon.Address `meddler:"to_eth_addr"`
ToBJJ *babyjub.PublicKey `meddler:"to_bjj"`
TokenID TokenID `meddler:"token_id"`
Amount *big.Int `meddler:"amount,bigint"` // TODO: change to float16
Fee FeeSelector `meddler:"fee"`
Nonce Nonce `meddler:"nonce"` // effective 40 bits used
State PoolL2TxState `meddler:"state"`
Signature *babyjub.Signature `meddler:"signature"` // tx signature
Timestamp time.Time `meddler:"timestamp,utctime"` // time when added to the tx pool
// Stored in DB: optional fileds, may be uninitialized
BatchNum *BatchNum `meddler:"batch_num"` // batchNum in which this tx was forged. Presence indicates "forged" state.
RqFromIdx *Idx `meddler:"rq_from_idx"` // FromIdx is used by L1Tx/Deposit to indicate the Idx receiver of the L1Tx.LoadAmount (deposit)
RqToIdx *Idx `meddler:"rq_to_idx"` // FromIdx is used by L1Tx/Deposit to indicate the Idx receiver of the L1Tx.LoadAmount (deposit)
RqToEthAddr *ethCommon.Address `meddler:"rq_to_eth_addr"`
RqFromIdx Idx `meddler:"rq_from_idx,zeroisnull"` // FromIdx is used by L1Tx/Deposit to indicate the Idx receiver of the L1Tx.LoadAmount (deposit)
RqToIdx Idx `meddler:"rq_to_idx,zeroisnull"` // FromIdx is used by L1Tx/Deposit to indicate the Idx receiver of the L1Tx.LoadAmount (deposit)
RqToEthAddr ethCommon.Address `meddler:"rq_to_eth_addr"`
RqToBJJ *babyjub.PublicKey `meddler:"rq_to_bjj"` // TODO: stop using json, use scanner/valuer
RqTokenID *TokenID `meddler:"rq_token_id"`
RqTokenID TokenID `meddler:"rq_token_id,zeroisnull"`
RqAmount *big.Int `meddler:"rq_amount,bigintnull"` // TODO: change to float16
RqFee *FeeSelector `meddler:"rq_fee"`
RqNonce *uint64 `meddler:"rq_nonce"` // effective 48 bits used
AbsoluteFee *float64 `meddler:"fee_usd"`
AbsoluteFeeUpdate *time.Time `meddler:"usd_update,utctime"`
RqFee FeeSelector `meddler:"rq_fee,zeroisnull"`
RqNonce uint64 `meddler:"rq_nonce,zeroisnull"` // effective 48 bits used
AbsoluteFee float64 `meddler:"fee_usd,zeroisnull"`
AbsoluteFeeUpdate time.Time `meddler:"usd_update,utctimez"`
Type TxType `meddler:"tx_type"`
// Extra metadata, may be uninitialized
RqTxCompressedData []byte `meddler:"-"` // 253 bits, optional for atomic txs
@@ -54,11 +50,11 @@ type PoolL2Tx struct {
func NewPoolL2Tx(poolL2Tx *PoolL2Tx) (*PoolL2Tx, error) {
// calculate TxType
var txType TxType
if poolL2Tx.ToIdx == nil || *poolL2Tx.ToIdx == Idx(0) {
if poolL2Tx.ToIdx == Idx(0) {
txType = TxTypeTransfer
} else if *poolL2Tx.ToIdx == Idx(1) {
} else if poolL2Tx.ToIdx == Idx(1) {
txType = TxTypeExit
} else if *poolL2Tx.ToIdx >= IdxUserThreshold {
} else if poolL2Tx.ToIdx >= IdxUserThreshold {
txType = TxTypeTransfer
} else {
return poolL2Tx, fmt.Errorf("Can not determine type of PoolL2Tx, invalid ToIdx value: %d", poolL2Tx.ToIdx)
@@ -189,14 +185,8 @@ func (tx *PoolL2Tx) HashToSign() (*big.Int, error) {
if err != nil {
return nil, err
}
toEthAddr := big.NewInt(0)
if tx.ToEthAddr != nil {
toEthAddr = EthAddrToBigInt(*tx.ToEthAddr)
}
rqToEthAddr := big.NewInt(0)
if tx.RqToEthAddr != nil {
rqToEthAddr = EthAddrToBigInt(*tx.RqToEthAddr)
}
toEthAddr := EthAddrToBigInt(tx.ToEthAddr)
rqToEthAddr := EthAddrToBigInt(tx.RqToEthAddr)
toBJJAy := tx.ToBJJ.Y
rqTxCompressedDataV2, err := tx.TxCompressedDataV2()
if err != nil {
@@ -217,31 +207,22 @@ func (tx *PoolL2Tx) VerifySignature(pk *babyjub.PublicKey) bool {
// L2Tx returns a *L2Tx from the PoolL2Tx
func (tx *PoolL2Tx) L2Tx() (*L2Tx, error) {
if tx.ToIdx == nil || tx.BatchNum == nil {
return nil, errors.New("PoolL2Tx must have ToIdx != nil and BatchNum != nil in order to be able to transform to Tx")
}
return &L2Tx{
TxID: tx.TxID,
BatchNum: *tx.BatchNum,
FromIdx: tx.FromIdx,
ToIdx: *tx.ToIdx,
Amount: tx.Amount,
Fee: tx.Fee,
Nonce: tx.Nonce,
Type: tx.Type,
TxID: tx.TxID,
FromIdx: tx.FromIdx,
ToIdx: tx.ToIdx,
Amount: tx.Amount,
Fee: tx.Fee,
Nonce: tx.Nonce,
Type: tx.Type,
}, nil
}
// Tx returns a *Tx from the PoolL2Tx
func (tx *PoolL2Tx) Tx() (*Tx, error) {
if tx.ToIdx == nil {
return nil, errors.New("PoolL2Tx must have ToIdx != nil in order to be able to transform to Tx")
}
fromIdx := new(Idx)
*fromIdx = tx.FromIdx
return &Tx{
TxID: tx.TxID,
FromIdx: fromIdx,
FromIdx: tx.FromIdx,
ToIdx: tx.ToIdx,
Amount: tx.Amount,
Nonce: &tx.Nonce,

View File

@@ -11,11 +11,9 @@ import (
)
func TestNewPoolL2Tx(t *testing.T) {
toIdx := new(Idx)
*toIdx = 300
poolL2Tx := &PoolL2Tx{
FromIdx: 87654,
ToIdx: toIdx,
ToIdx: 300,
Amount: big.NewInt(4),
TokenID: 5,
Nonce: 144,
@@ -29,11 +27,9 @@ func TestTxCompressedData(t *testing.T) {
var sk babyjub.PrivateKey
_, err := hex.Decode(sk[:], []byte("0001020304050607080900010203040506070809000102030405060708090001"))
assert.Nil(t, err)
toIdx := new(Idx)
*toIdx = 3
tx := PoolL2Tx{
FromIdx: 2,
ToIdx: toIdx,
ToIdx: 3,
Amount: big.NewInt(4),
TokenID: 5,
Nonce: 6,
@@ -48,10 +44,9 @@ func TestTxCompressedData(t *testing.T) {
assert.True(t, ok)
assert.Equal(t, expected.Bytes(), txCompressedData.Bytes())
assert.Equal(t, "10000000000060000000500040000000000030000000000020001c60be60f", hex.EncodeToString(txCompressedData.Bytes())[1:])
*toIdx = 8
tx = PoolL2Tx{
FromIdx: 7,
ToIdx: toIdx,
ToIdx: 8,
Amount: big.NewInt(9),
TokenID: 10,
Nonce: 11,
@@ -73,17 +68,14 @@ func TestHashToSign(t *testing.T) {
var sk babyjub.PrivateKey
_, err := hex.Decode(sk[:], []byte("0001020304050607080900010203040506070809000102030405060708090001"))
assert.Nil(t, err)
ethAddr := ethCommon.HexToAddress("0xc58d29fA6e86E4FAe04DDcEd660d45BCf3Cb2370")
toIdx := new(Idx)
*toIdx = 3
tx := PoolL2Tx{
FromIdx: 2,
ToIdx: toIdx,
ToIdx: 3,
Amount: big.NewInt(4),
TokenID: 5,
Nonce: 6,
ToBJJ: sk.Public(),
RqToEthAddr: &ethAddr,
RqToEthAddr: ethCommon.HexToAddress("0xc58d29fA6e86E4FAe04DDcEd660d45BCf3Cb2370"),
RqToBJJ: sk.Public(),
}
toSign, err := tx.HashToSign()
@@ -95,17 +87,14 @@ func TestVerifyTxSignature(t *testing.T) {
var sk babyjub.PrivateKey
_, err := hex.Decode(sk[:], []byte("0001020304050607080900010203040506070809000102030405060708090001"))
assert.Nil(t, err)
ethAddr := ethCommon.HexToAddress("0xc58d29fA6e86E4FAe04DDcEd660d45BCf3Cb2370")
toIdx := new(Idx)
*toIdx = 3
tx := PoolL2Tx{
FromIdx: 2,
ToIdx: toIdx,
ToIdx: 3,
Amount: big.NewInt(4),
TokenID: 5,
Nonce: 6,
ToBJJ: sk.Public(),
RqToEthAddr: &ethAddr,
RqToEthAddr: ethCommon.HexToAddress("0xc58d29fA6e86E4FAe04DDcEd660d45BCf3Cb2370"),
RqToBJJ: sk.Public(),
}
toSign, err := tx.HashToSign()

View File

@@ -20,8 +20,6 @@ type Token struct {
Name string `json:"name" meddler:"name"`
Symbol string `json:"symbol" meddler:"symbol"`
Decimals uint64 `json:"decimals" meddler:"decimals"`
USD *float64 `json:"USD" meddler:"usd"`
USDUpdate *time.Time `json:"fiatUpdate" meddler:"usd_update,utctime"`
}
// TokenInfo provides the price of the token in USD

View File

@@ -3,7 +3,6 @@ package common
import (
"database/sql/driver"
"encoding/hex"
"errors"
"fmt"
"math/big"
@@ -84,14 +83,15 @@ const (
)
// Tx is a struct used by the TxSelector & BatchBuilder as a generic type generated from L1Tx & PoolL2Tx
// TODO: this should be changed for "mini Tx"
type Tx struct {
// Generic
IsL1 bool `meddler:"is_l1"`
TxID TxID `meddler:"id"`
Type TxType `meddler:"type"`
Position int `meddler:"position"`
FromIdx *Idx `meddler:"from_idx"`
ToIdx *Idx `meddler:"to_idx"`
FromIdx Idx `meddler:"from_idx"`
ToIdx Idx `meddler:"to_idx"`
Amount *big.Int `meddler:"amount,bigint"`
AmountFloat float64 `meddler:"amount_f"`
TokenID TokenID `meddler:"token_id"`
@@ -101,7 +101,7 @@ type Tx struct {
// L1
ToForgeL1TxsNum *int64 `meddler:"to_forge_l1_txs_num"` // toForgeL1TxsNum in which the tx was forged / will be forged
UserOrigin *bool `meddler:"user_origin"` // true if the tx was originated by a user, false if it was aoriginated by a coordinator. Note that this differ from the spec for implementation simplification purpposes
FromEthAddr *ethCommon.Address `meddler:"from_eth_addr"`
FromEthAddr ethCommon.Address `meddler:"from_eth_addr"`
FromBJJ *babyjub.PublicKey `meddler:"from_bjj"`
LoadAmount *big.Int `meddler:"load_amount,bigintnull"`
LoadAmountFloat *float64 `meddler:"load_amount_f"`
@@ -114,18 +114,15 @@ type Tx struct {
// L1Tx returns a *L1Tx from the Tx
func (tx *Tx) L1Tx() (*L1Tx, error) {
if tx.UserOrigin == nil || tx.FromEthAddr == nil {
return nil, errors.New("Tx must have UserOrigin != nil and FromEthAddr != nil in order to be able to transform to L1Tx")
}
return &L1Tx{
TxID: tx.TxID,
ToForgeL1TxsNum: tx.ToForgeL1TxsNum,
Position: tx.Position,
UserOrigin: *tx.UserOrigin,
FromIdx: tx.FromIdx,
FromEthAddr: *tx.FromEthAddr,
FromEthAddr: tx.FromEthAddr,
FromBJJ: tx.FromBJJ,
ToIdx: *tx.ToIdx,
ToIdx: tx.ToIdx,
TokenID: tx.TokenID,
Amount: tx.Amount,
LoadAmount: tx.LoadAmount,