mirror of
https://github.com/arnaucube/hermez-node.git
synced 2026-02-07 03:16:45 +01:00
Add lll to linter checks
Updated: batchbuilder common coordinator db/statedb eth log node priceupdater prover synchronizer test/* txprocessor txselector Pending (once https://github.com/hermeznetwork/hermez-node/tree/feature/serveapicli is merged to master): Update golangci-lint version to v1.37.1 api apitypes cli config db/historydb db/l2db
This commit is contained in:
@@ -72,7 +72,8 @@ func (idx Idx) BigInt() *big.Int {
|
||||
// IdxFromBytes returns Idx from a byte array
|
||||
func IdxFromBytes(b []byte) (Idx, error) {
|
||||
if len(b) != IdxBytesLen {
|
||||
return 0, tracerr.Wrap(fmt.Errorf("can not parse Idx, bytes len %d, expected %d", len(b), IdxBytesLen))
|
||||
return 0, tracerr.Wrap(fmt.Errorf("can not parse Idx, bytes len %d, expected %d",
|
||||
len(b), IdxBytesLen))
|
||||
}
|
||||
var idxBytes [8]byte
|
||||
copy(idxBytes[2:], b[:])
|
||||
@@ -194,7 +195,8 @@ func (a *Account) BigInts() ([NLeafElems]*big.Int, error) {
|
||||
return e, nil
|
||||
}
|
||||
|
||||
// HashValue returns the value of the Account, which is the Poseidon hash of its *big.Int representation
|
||||
// HashValue returns the value of the Account, which is the Poseidon hash of its
|
||||
// *big.Int representation
|
||||
func (a *Account) HashValue() (*big.Int, error) {
|
||||
bi, err := a.BigInts()
|
||||
if err != nil {
|
||||
|
||||
@@ -76,7 +76,8 @@ func TestNonceParser(t *testing.T) {
|
||||
|
||||
func TestAccount(t *testing.T) {
|
||||
var sk babyjub.PrivateKey
|
||||
_, err := hex.Decode(sk[:], []byte("0001020304050607080900010203040506070809000102030405060708090001"))
|
||||
_, err := hex.Decode(sk[:],
|
||||
[]byte("0001020304050607080900010203040506070809000102030405060708090001"))
|
||||
assert.NoError(t, err)
|
||||
pk := sk.Public()
|
||||
|
||||
@@ -115,7 +116,8 @@ func TestAccountLoop(t *testing.T) {
|
||||
// check that for different deterministic BabyJubJub keys & random Address there is no problem
|
||||
for i := 0; i < 256; i++ {
|
||||
var sk babyjub.PrivateKey
|
||||
_, err := hex.Decode(sk[:], []byte("0001020304050607080900010203040506070809000102030405060708090001"))
|
||||
_, err := hex.Decode(sk[:],
|
||||
[]byte("0001020304050607080900010203040506070809000102030405060708090001"))
|
||||
assert.NoError(t, err)
|
||||
pk := sk.Public()
|
||||
|
||||
@@ -199,7 +201,8 @@ func bigFromStr(h string, u int) *big.Int {
|
||||
|
||||
func TestAccountHashValue(t *testing.T) {
|
||||
var sk babyjub.PrivateKey
|
||||
_, err := hex.Decode(sk[:], []byte("0001020304050607080900010203040506070809000102030405060708090001"))
|
||||
_, err := hex.Decode(sk[:],
|
||||
[]byte("0001020304050607080900010203040506070809000102030405060708090001"))
|
||||
assert.NoError(t, err)
|
||||
pk := sk.Public()
|
||||
|
||||
@@ -212,13 +215,16 @@ func TestAccountHashValue(t *testing.T) {
|
||||
}
|
||||
v, err := account.HashValue()
|
||||
assert.NoError(t, err)
|
||||
assert.Equal(t, "16297758255249203915951182296472515138555043617458222397753168518282206850764", v.String())
|
||||
assert.Equal(t,
|
||||
"16297758255249203915951182296472515138555043617458222397753168518282206850764",
|
||||
v.String())
|
||||
}
|
||||
|
||||
func TestAccountHashValueTestVectors(t *testing.T) {
|
||||
// values from js test vectors
|
||||
ay := new(big.Int).Sub(new(big.Int).Exp(big.NewInt(2), big.NewInt(253), nil), big.NewInt(1))
|
||||
assert.Equal(t, "1fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff", (hex.EncodeToString(ay.Bytes())))
|
||||
assert.Equal(t, "1fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff",
|
||||
(hex.EncodeToString(ay.Bytes())))
|
||||
bjjPoint, err := babyjub.PointFromSignAndY(true, ay)
|
||||
require.NoError(t, err)
|
||||
bjj := babyjub.PublicKey(*bjjPoint)
|
||||
@@ -236,16 +242,22 @@ func TestAccountHashValueTestVectors(t *testing.T) {
|
||||
assert.NoError(t, err)
|
||||
assert.Equal(t, "9444732965739290427391", e[0].String())
|
||||
assert.Equal(t, "6277101735386680763835789423207666416102355444464034512895", e[1].String())
|
||||
assert.Equal(t, "14474011154664524427946373126085988481658748083205070504932198000989141204991", e[2].String())
|
||||
assert.Equal(t,
|
||||
"14474011154664524427946373126085988481658748083205070504932198000989141204991",
|
||||
e[2].String())
|
||||
assert.Equal(t, "1461501637330902918203684832716283019655932542975", e[3].String())
|
||||
|
||||
h, err := poseidon.Hash(e[:])
|
||||
assert.NoError(t, err)
|
||||
assert.Equal(t, "4550823210217540218403400309533329186487982452461145263910122718498735057257", h.String())
|
||||
assert.Equal(t,
|
||||
"4550823210217540218403400309533329186487982452461145263910122718498735057257",
|
||||
h.String())
|
||||
|
||||
v, err := account.HashValue()
|
||||
assert.NoError(t, err)
|
||||
assert.Equal(t, "4550823210217540218403400309533329186487982452461145263910122718498735057257", v.String())
|
||||
assert.Equal(t,
|
||||
"4550823210217540218403400309533329186487982452461145263910122718498735057257",
|
||||
v.String())
|
||||
|
||||
// second account
|
||||
ay = big.NewInt(0)
|
||||
@@ -261,7 +273,9 @@ func TestAccountHashValueTestVectors(t *testing.T) {
|
||||
}
|
||||
v, err = account.HashValue()
|
||||
assert.NoError(t, err)
|
||||
assert.Equal(t, "7750253361301235345986002241352365187241910378619330147114280396816709365657", v.String())
|
||||
assert.Equal(t,
|
||||
"7750253361301235345986002241352365187241910378619330147114280396816709365657",
|
||||
v.String())
|
||||
|
||||
// third account
|
||||
ay = bigFromStr("21b0a1688b37f77b1d1d5539ec3b826db5ac78b2513f574a04c50a7d4f8246d7", 16)
|
||||
@@ -279,11 +293,15 @@ func TestAccountHashValueTestVectors(t *testing.T) {
|
||||
assert.NoError(t, err)
|
||||
assert.Equal(t, "554050781187", e[0].String())
|
||||
assert.Equal(t, "42000000000000000000", e[1].String())
|
||||
assert.Equal(t, "15238403086306505038849621710779816852318505119327426213168494964113886299863", e[2].String())
|
||||
assert.Equal(t,
|
||||
"15238403086306505038849621710779816852318505119327426213168494964113886299863",
|
||||
e[2].String())
|
||||
assert.Equal(t, "935037732739828347587684875151694054123613453305", e[3].String())
|
||||
v, err = account.HashValue()
|
||||
assert.NoError(t, err)
|
||||
assert.Equal(t, "10565754214047872850889045989683221123564392137456000481397520902594455245517", v.String())
|
||||
assert.Equal(t,
|
||||
"10565754214047872850889045989683221123564392137456000481397520902594455245517",
|
||||
v.String())
|
||||
}
|
||||
|
||||
func TestAccountErrNotInFF(t *testing.T) {
|
||||
@@ -312,7 +330,8 @@ func TestAccountErrNotInFF(t *testing.T) {
|
||||
|
||||
func TestAccountErrNumOverflowNonce(t *testing.T) {
|
||||
var sk babyjub.PrivateKey
|
||||
_, err := hex.Decode(sk[:], []byte("0001020304050607080900010203040506070809000102030405060708090001"))
|
||||
_, err := hex.Decode(sk[:],
|
||||
[]byte("0001020304050607080900010203040506070809000102030405060708090001"))
|
||||
assert.NoError(t, err)
|
||||
pk := sk.Public()
|
||||
|
||||
@@ -339,7 +358,8 @@ func TestAccountErrNumOverflowNonce(t *testing.T) {
|
||||
|
||||
func TestAccountErrNumOverflowBalance(t *testing.T) {
|
||||
var sk babyjub.PrivateKey
|
||||
_, err := hex.Decode(sk[:], []byte("0001020304050607080900010203040506070809000102030405060708090001"))
|
||||
_, err := hex.Decode(sk[:],
|
||||
[]byte("0001020304050607080900010203040506070809000102030405060708090001"))
|
||||
assert.NoError(t, err)
|
||||
pk := sk.Public()
|
||||
|
||||
@@ -351,14 +371,16 @@ func TestAccountErrNumOverflowBalance(t *testing.T) {
|
||||
BJJ: pk.Compress(),
|
||||
EthAddr: ethCommon.HexToAddress("0xc58d29fA6e86E4FAe04DDcEd660d45BCf3Cb2370"),
|
||||
}
|
||||
assert.Equal(t, "6277101735386680763835789423207666416102355444464034512895", account.Balance.String())
|
||||
assert.Equal(t, "6277101735386680763835789423207666416102355444464034512895",
|
||||
account.Balance.String())
|
||||
|
||||
_, err = account.Bytes()
|
||||
assert.NoError(t, err)
|
||||
|
||||
// force value overflow
|
||||
account.Balance = new(big.Int).Exp(big.NewInt(2), big.NewInt(192), nil)
|
||||
assert.Equal(t, "6277101735386680763835789423207666416102355444464034512896", account.Balance.String())
|
||||
assert.Equal(t, "6277101735386680763835789423207666416102355444464034512896",
|
||||
account.Balance.String())
|
||||
b, err := account.Bytes()
|
||||
assert.NotNil(t, err)
|
||||
assert.Equal(t, fmt.Errorf("%s Balance", ErrNumOverflow), tracerr.Unwrap(err))
|
||||
|
||||
@@ -13,7 +13,8 @@ import (
|
||||
|
||||
func TestAccountCreationAuthSignVerify(t *testing.T) {
|
||||
// Ethereum key
|
||||
ethSk, err := ethCrypto.HexToECDSA("fad9c8855b740a0b7ed4c221dbad0f33a83a49cad6b3fe8d5817ac83d38b6a19")
|
||||
ethSk, err :=
|
||||
ethCrypto.HexToECDSA("fad9c8855b740a0b7ed4c221dbad0f33a83a49cad6b3fe8d5817ac83d38b6a19")
|
||||
require.NoError(t, err)
|
||||
ethAddr := ethCrypto.PubkeyToAddress(ethSk.PublicKey)
|
||||
|
||||
@@ -69,6 +70,7 @@ func TestAccountCreationAuthJSComp(t *testing.T) {
|
||||
sigExpected string
|
||||
}
|
||||
var tvs []testVector
|
||||
//nolint:lll
|
||||
tv0 := testVector{
|
||||
ethSk: "0000000000000000000000000000000000000000000000000000000000000001",
|
||||
expectedAddress: "0x7E5F4552091A69125d5DfCb7b8C2659029395Bdf",
|
||||
@@ -79,6 +81,7 @@ func TestAccountCreationAuthJSComp(t *testing.T) {
|
||||
hashExpected: "c56eba41e511df100c804c5c09288f35887efea4f033be956481af335df3bea2",
|
||||
sigExpected: "dbedcc5ce02db8f48afbdb2feba9a3a31848eaa8fca5f312ce37b01db45d2199208335330d4445bd2f51d1db68dbc0d0bf3585c4a07504b4efbe46a69eaae5a21b",
|
||||
}
|
||||
//nolint:lll
|
||||
tv1 := testVector{
|
||||
ethSk: "0000000000000000000000000000000000000000000000000000000000000002",
|
||||
expectedAddress: "0x2B5AD5c4795c026514f8317c7a215E218DcCD6cF",
|
||||
@@ -89,6 +92,7 @@ func TestAccountCreationAuthJSComp(t *testing.T) {
|
||||
hashExpected: "deb9afa479282cf27b442ce8ba86b19448aa87eacef691521a33db5d0feb9959",
|
||||
sigExpected: "6a0da90ba2d2b1be679a28ebe54ee03082d44b836087391cd7d2607c1e4dafe04476e6e88dccb8707c68312512f16c947524b35c80f26c642d23953e9bb84c701c",
|
||||
}
|
||||
//nolint:lll
|
||||
tv2 := testVector{
|
||||
ethSk: "c5e8f61d1ab959b397eecc0a37a6517b8e67a0e7cf1f4bce5591f3ed80199122",
|
||||
expectedAddress: "0xc783df8a850f42e7F7e57013759C285caa701eB6",
|
||||
|
||||
@@ -13,8 +13,9 @@ const batchNumBytesLen = 8
|
||||
|
||||
// Batch is a struct that represents Hermez network batch
|
||||
type Batch struct {
|
||||
BatchNum BatchNum `meddler:"batch_num"`
|
||||
EthBlockNum int64 `meddler:"eth_block_num"` // Ethereum block in which the batch is forged
|
||||
BatchNum BatchNum `meddler:"batch_num"`
|
||||
// Ethereum block in which the batch is forged
|
||||
EthBlockNum int64 `meddler:"eth_block_num"`
|
||||
ForgerAddr ethCommon.Address `meddler:"forger_addr"`
|
||||
CollectedFees map[TokenID]*big.Int `meddler:"fees_collected,json"`
|
||||
FeeIdxsCoordinator []Idx `meddler:"fee_idxs_coordinator,json"`
|
||||
@@ -22,9 +23,11 @@ type Batch struct {
|
||||
NumAccounts int `meddler:"num_accounts"`
|
||||
LastIdx int64 `meddler:"last_idx"`
|
||||
ExitRoot *big.Int `meddler:"exit_root,bigint"`
|
||||
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 int64 `meddler:"slot_num"` // Slot in which the batch is forged
|
||||
TotalFeesUSD *float64 `meddler:"total_fees_usd"`
|
||||
// ForgeL1TxsNum is optional, Only when the batch forges L1 txs. Identifier that corresponds
|
||||
// to the group of L1 txs forged in the current batch.
|
||||
ForgeL1TxsNum *int64 `meddler:"forge_l1_txs_num"`
|
||||
SlotNum int64 `meddler:"slot_num"` // Slot in which the batch is forged
|
||||
TotalFeesUSD *float64 `meddler:"total_fees_usd"`
|
||||
}
|
||||
|
||||
// NewEmptyBatch creates a new empty batch
|
||||
@@ -63,7 +66,9 @@ func (bn BatchNum) BigInt() *big.Int {
|
||||
// BatchNumFromBytes returns BatchNum from a []byte
|
||||
func BatchNumFromBytes(b []byte) (BatchNum, error) {
|
||||
if len(b) != batchNumBytesLen {
|
||||
return 0, tracerr.Wrap(fmt.Errorf("can not parse BatchNumFromBytes, bytes len %d, expected %d", len(b), batchNumBytesLen))
|
||||
return 0,
|
||||
tracerr.Wrap(fmt.Errorf("can not parse BatchNumFromBytes, bytes len %d, expected %d",
|
||||
len(b), batchNumBytesLen))
|
||||
}
|
||||
batchNum := binary.BigEndian.Uint64(b[:batchNumBytesLen])
|
||||
return BatchNum(batchNum), nil
|
||||
|
||||
@@ -5,10 +5,15 @@ import (
|
||||
)
|
||||
|
||||
// Coordinator represents a Hermez network coordinator who wins an auction for an specific slot
|
||||
// WARNING: this is strongly based on the previous implementation, once the new spec is done, this may change a lot.
|
||||
// WARNING: this is strongly based on the previous implementation, once the new spec is done, this
|
||||
// may change a lot.
|
||||
type Coordinator struct {
|
||||
Bidder ethCommon.Address `meddler:"bidder_addr"` // address of the bidder
|
||||
Forger ethCommon.Address `meddler:"forger_addr"` // address of the forger
|
||||
EthBlockNum int64 `meddler:"eth_block_num"` // block in which the coordinator was registered
|
||||
URL string `meddler:"url"` // URL of the coordinators API
|
||||
// Bidder is the address of the bidder
|
||||
Bidder ethCommon.Address `meddler:"bidder_addr"`
|
||||
// Forger is the address of the forger
|
||||
Forger ethCommon.Address `meddler:"forger_addr"`
|
||||
// EthBlockNum is the block in which the coordinator was registered
|
||||
EthBlockNum int64 `meddler:"eth_block_num"`
|
||||
// URL of the coordinators API
|
||||
URL string `meddler:"url"`
|
||||
}
|
||||
|
||||
@@ -68,11 +68,13 @@ type AuctionVariables struct {
|
||||
ClosedAuctionSlots uint16 `meddler:"closed_auction_slots" validate:"required"`
|
||||
// Distance (#slots) to the farthest slot to which you can bid (30 days = 4320 slots )
|
||||
OpenAuctionSlots uint16 `meddler:"open_auction_slots" validate:"required"`
|
||||
// How the HEZ tokens deposited by the slot winner are distributed (Burn: 40% - Donation: 40% - HGT: 20%)
|
||||
// How the HEZ tokens deposited by the slot winner are distributed (Burn: 40% - Donation:
|
||||
// 40% - HGT: 20%)
|
||||
AllocationRatio [3]uint16 `meddler:"allocation_ratio,json" validate:"required"`
|
||||
// Minimum outbid (percentage) over the previous one to consider it valid
|
||||
Outbidding uint16 `meddler:"outbidding" validate:"required"`
|
||||
// Number of blocks at the end of a slot in which any coordinator can forge if the winner has not forged one before
|
||||
// Number of blocks at the end of a slot in which any coordinator can forge if the winner
|
||||
// has not forged one before
|
||||
SlotDeadline uint8 `meddler:"slot_deadline" validate:"required"`
|
||||
}
|
||||
|
||||
|
||||
@@ -20,19 +20,22 @@ const (
|
||||
// RollupConstExitIDx IDX 1 is reserved for exits
|
||||
RollupConstExitIDx = 1
|
||||
// RollupConstLimitTokens Max number of tokens allowed to be registered inside the rollup
|
||||
RollupConstLimitTokens = (1 << 32)
|
||||
// RollupConstL1CoordinatorTotalBytes [4 bytes] token + [32 bytes] babyjub + [65 bytes] compressedSignature
|
||||
RollupConstLimitTokens = (1 << 32) //nolint:gomnd
|
||||
// RollupConstL1CoordinatorTotalBytes [4 bytes] token + [32 bytes] babyjub + [65 bytes]
|
||||
// compressedSignature
|
||||
RollupConstL1CoordinatorTotalBytes = 101
|
||||
// RollupConstL1UserTotalBytes [20 bytes] fromEthAddr + [32 bytes] fromBjj-compressed + [6 bytes] fromIdx +
|
||||
// [5 bytes] depositAmountFloat40 + [5 bytes] amountFloat40 + [4 bytes] tokenId + [6 bytes] toIdx
|
||||
// RollupConstL1UserTotalBytes [20 bytes] fromEthAddr + [32 bytes] fromBjj-compressed + [6
|
||||
// bytes] fromIdx + [5 bytes] depositAmountFloat40 + [5 bytes] amountFloat40 + [4 bytes]
|
||||
// tokenId + [6 bytes] toIdx
|
||||
RollupConstL1UserTotalBytes = 78
|
||||
// RollupConstMaxL1UserTx Maximum L1-user transactions allowed to be queued in a batch
|
||||
RollupConstMaxL1UserTx = 128
|
||||
// RollupConstMaxL1Tx Maximum L1 transactions allowed to be queued in a batch
|
||||
RollupConstMaxL1Tx = 256
|
||||
// RollupConstInputSHAConstantBytes [6 bytes] lastIdx + [6 bytes] newLastIdx + [32 bytes] stateRoot + [32 bytes] newStRoot + [32 bytes] newExitRoot +
|
||||
// [_MAX_L1_TX * _L1_USER_TOTALBYTES bytes] l1TxsData + totalL2TxsDataLength + feeIdxCoordinatorLength + [2 bytes] chainID =
|
||||
// 18542 bytes + totalL2TxsDataLength + feeIdxCoordinatorLength
|
||||
// RollupConstInputSHAConstantBytes [6 bytes] lastIdx + [6 bytes] newLastIdx + [32 bytes]
|
||||
// stateRoot + [32 bytes] newStRoot + [32 bytes] newExitRoot + [_MAX_L1_TX *
|
||||
// _L1_USER_TOTALBYTES bytes] l1TxsData + totalL2TxsDataLength + feeIdxCoordinatorLength +
|
||||
// [2 bytes] chainID = 18542 bytes + totalL2TxsDataLength + feeIdxCoordinatorLength
|
||||
RollupConstInputSHAConstantBytes = 18546
|
||||
// RollupConstNumBuckets Number of buckets
|
||||
RollupConstNumBuckets = 5
|
||||
@@ -44,14 +47,18 @@ const (
|
||||
|
||||
var (
|
||||
// RollupConstLimitDepositAmount Max deposit amount allowed (depositAmount: L1 --> L2)
|
||||
RollupConstLimitDepositAmount, _ = new(big.Int).SetString("340282366920938463463374607431768211456", 10)
|
||||
RollupConstLimitDepositAmount, _ = new(big.Int).SetString(
|
||||
"340282366920938463463374607431768211456", 10)
|
||||
// RollupConstLimitL2TransferAmount Max amount allowed (amount L2 --> L2)
|
||||
RollupConstLimitL2TransferAmount, _ = new(big.Int).SetString("6277101735386680763835789423207666416102355444464034512896", 10)
|
||||
RollupConstLimitL2TransferAmount, _ = new(big.Int).SetString(
|
||||
"6277101735386680763835789423207666416102355444464034512896", 10)
|
||||
|
||||
// RollupConstEthAddressInternalOnly This ethereum address is used internally for rollup accounts that don't have ethereum address, only Babyjubjub
|
||||
// This non-ethereum accounts can be created by the coordinator and allow users to have a rollup
|
||||
// account without needing an ethereum address
|
||||
RollupConstEthAddressInternalOnly = ethCommon.HexToAddress("0xFFfFfFffFFfffFFfFFfFFFFFffFFFffffFfFFFfF")
|
||||
// RollupConstEthAddressInternalOnly This ethereum address is used internally for rollup
|
||||
// accounts that don't have ethereum address, only Babyjubjub.
|
||||
// This non-ethereum accounts can be created by the coordinator and allow users to have a
|
||||
// rollup account without needing an ethereum address
|
||||
RollupConstEthAddressInternalOnly = ethCommon.HexToAddress(
|
||||
"0xFFfFfFffFFfffFFfFFfFFFFFffFFFffffFfFFFfF")
|
||||
// RollupConstRfield Modulus zkSNARK
|
||||
RollupConstRfield, _ = new(big.Int).SetString(
|
||||
"21888242871839275222246405745257275088548364400416034343698204186575808495617", 10)
|
||||
@@ -63,24 +70,32 @@ var (
|
||||
|
||||
// RollupConstRecipientInterfaceHash ERC777 recipient interface hash
|
||||
RollupConstRecipientInterfaceHash = crypto.Keccak256([]byte("ERC777TokensRecipient"))
|
||||
// RollupConstPerformL1UserTxSignature the signature of the function that can be called thru an ERC777 `send`
|
||||
RollupConstPerformL1UserTxSignature = crypto.Keccak256([]byte("addL1Transaction(uint256,uint48,uint16,uint16,uint32,uint48)"))
|
||||
// RollupConstAddTokenSignature the signature of the function that can be called thru an ERC777 `send`
|
||||
// RollupConstPerformL1UserTxSignature the signature of the function that can be called thru
|
||||
// an ERC777 `send`
|
||||
RollupConstPerformL1UserTxSignature = crypto.Keccak256([]byte(
|
||||
"addL1Transaction(uint256,uint48,uint16,uint16,uint32,uint48)"))
|
||||
// RollupConstAddTokenSignature the signature of the function that can be called thru an
|
||||
// ERC777 `send`
|
||||
RollupConstAddTokenSignature = crypto.Keccak256([]byte("addToken(address)"))
|
||||
// RollupConstSendSignature ERC777 Signature
|
||||
RollupConstSendSignature = crypto.Keccak256([]byte("send(address,uint256,bytes)"))
|
||||
// RollupConstERC777Granularity ERC777 Signature
|
||||
RollupConstERC777Granularity = crypto.Keccak256([]byte("granularity()"))
|
||||
// RollupConstWithdrawalDelayerDeposit This constant are used to deposit tokens from ERC77 tokens into withdrawal delayer
|
||||
// RollupConstWithdrawalDelayerDeposit This constant are used to deposit tokens from ERC77
|
||||
// tokens into withdrawal delayer
|
||||
RollupConstWithdrawalDelayerDeposit = crypto.Keccak256([]byte("deposit(address,address,uint192)"))
|
||||
|
||||
// ERC20 signature
|
||||
|
||||
// RollupConstTransferSignature This constant is used in the _safeTransfer internal method in order to safe GAS.
|
||||
// RollupConstTransferSignature This constant is used in the _safeTransfer internal method
|
||||
// in order to safe GAS.
|
||||
RollupConstTransferSignature = crypto.Keccak256([]byte("transfer(address,uint256)"))
|
||||
// RollupConstTransferFromSignature This constant is used in the _safeTransfer internal method in order to safe GAS.
|
||||
RollupConstTransferFromSignature = crypto.Keccak256([]byte("transferFrom(address,address,uint256)"))
|
||||
// RollupConstApproveSignature This constant is used in the _safeTransfer internal method in order to safe GAS.
|
||||
// RollupConstTransferFromSignature This constant is used in the _safeTransfer internal
|
||||
// method in order to safe GAS.
|
||||
RollupConstTransferFromSignature = crypto.Keccak256([]byte(
|
||||
"transferFrom(address,address,uint256)"))
|
||||
// RollupConstApproveSignature This constant is used in the _safeTransfer internal method in
|
||||
// order to safe GAS.
|
||||
RollupConstApproveSignature = crypto.Keccak256([]byte("approve(address,uint256)"))
|
||||
// RollupConstERC20Signature ERC20 decimals signature
|
||||
RollupConstERC20Signature = crypto.Keccak256([]byte("decimals()"))
|
||||
@@ -141,6 +156,7 @@ type TokenExchange struct {
|
||||
}
|
||||
|
||||
// RollupVariables are the variables of the Rollup Smart Contract
|
||||
//nolint:lll
|
||||
type RollupVariables struct {
|
||||
EthBlockNum int64 `meddler:"eth_block_num"`
|
||||
FeeAddToken *big.Int `meddler:"fee_add_token,bigint" validate:"required"`
|
||||
|
||||
@@ -27,6 +27,7 @@ type WDelayerEscapeHatchWithdrawal struct {
|
||||
}
|
||||
|
||||
// WDelayerVariables are the variables of the Withdrawal Delayer Smart Contract
|
||||
//nolint:lll
|
||||
type WDelayerVariables struct {
|
||||
EthBlockNum int64 `json:"ethereumBlockNum" meddler:"eth_block_num"`
|
||||
// HermezRollupAddress ethCommon.Address `json:"hermezRollupAddress" meddler:"rollup_address"`
|
||||
|
||||
@@ -21,25 +21,33 @@ type L1Tx struct {
|
||||
// where type:
|
||||
// - L1UserTx: 0
|
||||
// - L1CoordinatorTx: 1
|
||||
TxID TxID `meddler:"id"`
|
||||
ToForgeL1TxsNum *int64 `meddler:"to_forge_l1_txs_num"` // toForgeL1TxsNum in which the tx was forged / will be forged
|
||||
Position int `meddler:"position"`
|
||||
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
|
||||
FromIdx Idx `meddler:"from_idx,zeroisnull"` // FromIdx is used by L1Tx/Deposit to indicate the Idx receiver of the L1Tx.DepositAmount (deposit)
|
||||
TxID TxID `meddler:"id"`
|
||||
// ToForgeL1TxsNum indicates in which the tx was forged / will be forged
|
||||
ToForgeL1TxsNum *int64 `meddler:"to_forge_l1_txs_num"`
|
||||
Position int `meddler:"position"`
|
||||
// UserOrigin is set to 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
|
||||
UserOrigin bool `meddler:"user_origin"`
|
||||
// FromIdx is used by L1Tx/Deposit to indicate the Idx receiver of the L1Tx.DepositAmount
|
||||
// (deposit)
|
||||
FromIdx Idx `meddler:"from_idx,zeroisnull"`
|
||||
EffectiveFromIdx Idx `meddler:"effective_from_idx,zeroisnull"`
|
||||
FromEthAddr ethCommon.Address `meddler:"from_eth_addr,zeroisnull"`
|
||||
FromBJJ babyjub.PublicKeyComp `meddler:"from_bjj,zeroisnull"`
|
||||
ToIdx Idx `meddler:"to_idx"` // ToIdx is ignored in L1Tx/Deposit, but used in the L1Tx/DepositAndTransfer
|
||||
TokenID TokenID `meddler:"token_id"`
|
||||
Amount *big.Int `meddler:"amount,bigint"`
|
||||
// ToIdx is ignored in L1Tx/Deposit, but used in the L1Tx/DepositAndTransfer
|
||||
ToIdx Idx `meddler:"to_idx"`
|
||||
TokenID TokenID `meddler:"token_id"`
|
||||
Amount *big.Int `meddler:"amount,bigint"`
|
||||
// EffectiveAmount only applies to L1UserTx.
|
||||
EffectiveAmount *big.Int `meddler:"effective_amount,bigintnull"`
|
||||
DepositAmount *big.Int `meddler:"deposit_amount,bigint"`
|
||||
// EffectiveDepositAmount only applies to L1UserTx.
|
||||
EffectiveDepositAmount *big.Int `meddler:"effective_deposit_amount,bigintnull"`
|
||||
EthBlockNum int64 `meddler:"eth_block_num"` // Ethereum Block Number in which this L1Tx was added to the queue
|
||||
Type TxType `meddler:"type"`
|
||||
BatchNum *BatchNum `meddler:"batch_num"`
|
||||
EffectiveDepositAmount *big.Int `meddler:"effective_deposit_amount,bigintnull"`
|
||||
// Ethereum Block Number in which this L1Tx was added to the queue
|
||||
EthBlockNum int64 `meddler:"eth_block_num"`
|
||||
Type TxType `meddler:"type"`
|
||||
BatchNum *BatchNum `meddler:"batch_num"`
|
||||
}
|
||||
|
||||
// NewL1Tx returns the given L1Tx with the TxId & Type parameters calculated
|
||||
@@ -331,7 +339,9 @@ func (tx *L1Tx) BytesCoordinatorTx(compressedSignatureBytes []byte) ([]byte, err
|
||||
// L1UserTxFromBytes decodes a L1Tx from []byte
|
||||
func L1UserTxFromBytes(b []byte) (*L1Tx, error) {
|
||||
if len(b) != RollupConstL1UserTotalBytes {
|
||||
return nil, tracerr.Wrap(fmt.Errorf("Can not parse L1Tx bytes, expected length %d, current: %d", 68, len(b)))
|
||||
return nil,
|
||||
tracerr.Wrap(fmt.Errorf("Can not parse L1Tx bytes, expected length %d, current: %d",
|
||||
68, len(b)))
|
||||
}
|
||||
|
||||
tx := &L1Tx{
|
||||
@@ -369,9 +379,12 @@ func L1UserTxFromBytes(b []byte) (*L1Tx, error) {
|
||||
}
|
||||
|
||||
// L1CoordinatorTxFromBytes decodes a L1Tx from []byte
|
||||
func L1CoordinatorTxFromBytes(b []byte, chainID *big.Int, hermezAddress ethCommon.Address) (*L1Tx, error) {
|
||||
func L1CoordinatorTxFromBytes(b []byte, chainID *big.Int, hermezAddress ethCommon.Address) (*L1Tx,
|
||||
error) {
|
||||
if len(b) != RollupConstL1CoordinatorTotalBytes {
|
||||
return nil, tracerr.Wrap(fmt.Errorf("Can not parse L1CoordinatorTx bytes, expected length %d, current: %d", 101, len(b)))
|
||||
return nil, tracerr.Wrap(
|
||||
fmt.Errorf("Can not parse L1CoordinatorTx bytes, expected length %d, current: %d",
|
||||
101, len(b)))
|
||||
}
|
||||
|
||||
tx := &L1Tx{
|
||||
|
||||
@@ -29,7 +29,8 @@ func TestNewL1UserTx(t *testing.T) {
|
||||
}
|
||||
l1Tx, err := NewL1Tx(l1Tx)
|
||||
assert.NoError(t, err)
|
||||
assert.Equal(t, "0x00a6cbae3b8661fb75b0919ca6605a02cfb04d9c6dd16870fa0fcdf01befa32768", l1Tx.TxID.String())
|
||||
assert.Equal(t, "0x00a6cbae3b8661fb75b0919ca6605a02cfb04d9c6dd16870fa0fcdf01befa32768",
|
||||
l1Tx.TxID.String())
|
||||
}
|
||||
|
||||
func TestNewL1CoordinatorTx(t *testing.T) {
|
||||
@@ -46,7 +47,8 @@ func TestNewL1CoordinatorTx(t *testing.T) {
|
||||
}
|
||||
l1Tx, err := NewL1Tx(l1Tx)
|
||||
assert.NoError(t, err)
|
||||
assert.Equal(t, "0x01274482d73df4dab34a1b6740adfca347a462513aa14e82f27b12f818d1b68c84", l1Tx.TxID.String())
|
||||
assert.Equal(t, "0x01274482d73df4dab34a1b6740adfca347a462513aa14e82f27b12f818d1b68c84",
|
||||
l1Tx.TxID.String())
|
||||
}
|
||||
|
||||
func TestL1TxCompressedData(t *testing.T) {
|
||||
@@ -199,7 +201,8 @@ func TestL1userTxByteParsers(t *testing.T) {
|
||||
func TestL1TxByteParsersCompatibility(t *testing.T) {
|
||||
// Data from compatibility test
|
||||
var pkComp babyjub.PublicKeyComp
|
||||
pkCompB, err := hex.DecodeString("0dd02deb2c81068e7a0f7e327df80b4ab79ee1f41a7def613e73a20c32eece5a")
|
||||
pkCompB, err :=
|
||||
hex.DecodeString("0dd02deb2c81068e7a0f7e327df80b4ab79ee1f41a7def613e73a20c32eece5a")
|
||||
require.NoError(t, err)
|
||||
pkCompL := SwapEndianness(pkCompB)
|
||||
err = pkComp.UnmarshalText([]byte(hex.EncodeToString(pkCompL)))
|
||||
@@ -220,7 +223,8 @@ func TestL1TxByteParsersCompatibility(t *testing.T) {
|
||||
|
||||
encodedData, err := l1Tx.BytesUser()
|
||||
require.NoError(t, err)
|
||||
expected := "85dab5b9e2e361d0c208d77be90efcc0439b0a530dd02deb2c81068e7a0f7e327df80b4ab79ee1f41a7def613e73a20c32eece5a000001c638db52540be400459682f0000020039c0000053cb88d"
|
||||
expected := "85dab5b9e2e361d0c208d77be90efcc0439b0a530dd02deb2c81068e7a0f7e327df80b4ab79e" +
|
||||
"e1f41a7def613e73a20c32eece5a000001c638db52540be400459682f0000020039c0000053cb88d"
|
||||
assert.Equal(t, expected, hex.EncodeToString(encodedData))
|
||||
}
|
||||
|
||||
@@ -228,7 +232,8 @@ func TestL1CoordinatorTxByteParsers(t *testing.T) {
|
||||
hermezAddress := ethCommon.HexToAddress("0xD6C850aeBFDC46D7F4c207e445cC0d6B0919BDBe")
|
||||
chainID := big.NewInt(1337)
|
||||
|
||||
privateKey, err := crypto.HexToECDSA("fad9c8855b740a0b7ed4c221dbad0f33a83a49cad6b3fe8d5817ac83d38b6a19")
|
||||
privateKey, err :=
|
||||
crypto.HexToECDSA("fad9c8855b740a0b7ed4c221dbad0f33a83a49cad6b3fe8d5817ac83d38b6a19")
|
||||
require.NoError(t, err)
|
||||
|
||||
publicKey := privateKey.Public()
|
||||
@@ -300,7 +305,8 @@ func TestL1CoordinatorTxByteParsersCompatibility(t *testing.T) {
|
||||
signature = append(signature, v[:]...)
|
||||
|
||||
var pkComp babyjub.PublicKeyComp
|
||||
pkCompB, err := hex.DecodeString("a2c2807ee39c3b3378738cff85a46a9465bb8fcf44ea597c33da9719be7c259c")
|
||||
pkCompB, err :=
|
||||
hex.DecodeString("a2c2807ee39c3b3378738cff85a46a9465bb8fcf44ea597c33da9719be7c259c")
|
||||
require.NoError(t, err)
|
||||
pkCompL := SwapEndianness(pkCompB)
|
||||
err = pkComp.UnmarshalText([]byte(hex.EncodeToString(pkCompL)))
|
||||
@@ -315,7 +321,9 @@ func TestL1CoordinatorTxByteParsersCompatibility(t *testing.T) {
|
||||
encodeData, err := l1Tx.BytesCoordinatorTx(signature)
|
||||
require.NoError(t, err)
|
||||
|
||||
expected, err := utils.HexDecode("1b186d7122ff7f654cfed3156719774898d573900c86599a885a706dbdffe5ea8cda71e5eb097e115405d84d1e7b464009b434b32c014a2df502d1f065ced8bc3ba2c2807ee39c3b3378738cff85a46a9465bb8fcf44ea597c33da9719be7c259c000000e7")
|
||||
expected, err := utils.HexDecode("1b186d7122ff7f654cfed3156719774898d573900c86599a885a706" +
|
||||
"dbdffe5ea8cda71e5eb097e115405d84d1e7b464009b434b32c014a2df502d1f065ced8bc3ba2c28" +
|
||||
"07ee39c3b3378738cff85a46a9465bb8fcf44ea597c33da9719be7c259c000000e7")
|
||||
require.NoError(t, err)
|
||||
|
||||
assert.Equal(t, expected, encodeData)
|
||||
|
||||
@@ -21,9 +21,10 @@ type L2Tx struct {
|
||||
Amount *big.Int `meddler:"amount,bigint"`
|
||||
Fee FeeSelector `meddler:"fee"`
|
||||
// Nonce is filled by the TxProcessor
|
||||
Nonce Nonce `meddler:"nonce"`
|
||||
Type TxType `meddler:"type"`
|
||||
EthBlockNum int64 `meddler:"eth_block_num"` // EthereumBlockNumber in which this L2Tx was added to the queue
|
||||
Nonce Nonce `meddler:"nonce"`
|
||||
Type TxType `meddler:"type"`
|
||||
// EthBlockNum in which this L2Tx was added to the queue
|
||||
EthBlockNum int64 `meddler:"eth_block_num"`
|
||||
}
|
||||
|
||||
// NewL2Tx returns the given L2Tx with the TxId & Type parameters calculated
|
||||
|
||||
@@ -19,7 +19,8 @@ func TestNewL2Tx(t *testing.T) {
|
||||
}
|
||||
l2Tx, err := NewL2Tx(l2Tx)
|
||||
assert.NoError(t, err)
|
||||
assert.Equal(t, "0x022669acda59b827d20ef5354a3eebd1dffb3972b0a6bf89d18bfd2efa0ab9f41e", l2Tx.TxID.String())
|
||||
assert.Equal(t, "0x022669acda59b827d20ef5354a3eebd1dffb3972b0a6bf89d18bfd2efa0ab9f41e",
|
||||
l2Tx.TxID.String())
|
||||
|
||||
l2Tx = &L2Tx{
|
||||
FromIdx: 87654,
|
||||
@@ -30,7 +31,8 @@ func TestNewL2Tx(t *testing.T) {
|
||||
}
|
||||
l2Tx, err = NewL2Tx(l2Tx)
|
||||
assert.NoError(t, err)
|
||||
assert.Equal(t, "0x029e7499a830f8f5eb17c07da48cf91415710f1bcbe0169d363ff91e81faf92fc2", l2Tx.TxID.String())
|
||||
assert.Equal(t, "0x029e7499a830f8f5eb17c07da48cf91415710f1bcbe0169d363ff91e81faf92fc2",
|
||||
l2Tx.TxID.String())
|
||||
|
||||
l2Tx = &L2Tx{
|
||||
FromIdx: 87654,
|
||||
@@ -42,7 +44,8 @@ func TestNewL2Tx(t *testing.T) {
|
||||
}
|
||||
l2Tx, err = NewL2Tx(l2Tx)
|
||||
assert.NoError(t, err)
|
||||
assert.Equal(t, "0x0255c70ed20e1b8935232e1b9c5884dbcc88a6e1a3454d24f2d77252eb2bb0b64e", l2Tx.TxID.String())
|
||||
assert.Equal(t, "0x0255c70ed20e1b8935232e1b9c5884dbcc88a6e1a3454d24f2d77252eb2bb0b64e",
|
||||
l2Tx.TxID.String())
|
||||
|
||||
l2Tx = &L2Tx{
|
||||
FromIdx: 87654,
|
||||
@@ -54,7 +57,8 @@ func TestNewL2Tx(t *testing.T) {
|
||||
}
|
||||
l2Tx, err = NewL2Tx(l2Tx)
|
||||
assert.NoError(t, err)
|
||||
assert.Equal(t, "0x0206b372f967061d1148bbcff679de38120e075141a80a07326d0f514c2efc6ca9", l2Tx.TxID.String())
|
||||
assert.Equal(t, "0x0206b372f967061d1148bbcff679de38120e075141a80a07326d0f514c2efc6ca9",
|
||||
l2Tx.TxID.String())
|
||||
|
||||
l2Tx = &L2Tx{
|
||||
FromIdx: 1,
|
||||
@@ -66,7 +70,8 @@ func TestNewL2Tx(t *testing.T) {
|
||||
}
|
||||
l2Tx, err = NewL2Tx(l2Tx)
|
||||
assert.NoError(t, err)
|
||||
assert.Equal(t, "0x0236f7ea5bccf78ba60baf56c058d235a844f9b09259fd0efa4f5f72a7d4a26618", l2Tx.TxID.String())
|
||||
assert.Equal(t, "0x0236f7ea5bccf78ba60baf56c058d235a844f9b09259fd0efa4f5f72a7d4a26618",
|
||||
l2Tx.TxID.String())
|
||||
|
||||
l2Tx = &L2Tx{
|
||||
FromIdx: 999,
|
||||
@@ -78,7 +83,8 @@ func TestNewL2Tx(t *testing.T) {
|
||||
}
|
||||
l2Tx, err = NewL2Tx(l2Tx)
|
||||
assert.NoError(t, err)
|
||||
assert.Equal(t, "0x02ac122f5b709ce190129fecbbe35bfd30c70e6433dbd85a8eb743d110906a1dc1", l2Tx.TxID.String())
|
||||
assert.Equal(t, "0x02ac122f5b709ce190129fecbbe35bfd30c70e6433dbd85a8eb743d110906a1dc1",
|
||||
l2Tx.TxID.String())
|
||||
|
||||
l2Tx = &L2Tx{
|
||||
FromIdx: 4444,
|
||||
@@ -90,7 +96,8 @@ func TestNewL2Tx(t *testing.T) {
|
||||
}
|
||||
l2Tx, err = NewL2Tx(l2Tx)
|
||||
assert.NoError(t, err)
|
||||
assert.Equal(t, "0x02c674951a81881b7bc50db3b9e5efd97ac88550c7426ac548720e5057cfba515a", l2Tx.TxID.String())
|
||||
assert.Equal(t, "0x02c674951a81881b7bc50db3b9e5efd97ac88550c7426ac548720e5057cfba515a",
|
||||
l2Tx.TxID.String())
|
||||
}
|
||||
|
||||
func TestL2TxByteParsers(t *testing.T) {
|
||||
|
||||
@@ -16,7 +16,8 @@ import (
|
||||
// EmptyBJJComp contains the 32 byte array of a empty BabyJubJub PublicKey
|
||||
// Compressed. It is a valid point in the BabyJubJub curve, so does not give
|
||||
// errors when being decompressed.
|
||||
var EmptyBJJComp = babyjub.PublicKeyComp([32]byte{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0})
|
||||
var EmptyBJJComp = babyjub.PublicKeyComp([32]byte{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0})
|
||||
|
||||
// PoolL2Tx is a struct that represents a L2Tx sent by an account to the
|
||||
// coordinator that is waiting to be forged
|
||||
@@ -318,7 +319,8 @@ func (tx *PoolL2Tx) HashToSign(chainID uint16) (*big.Int, error) {
|
||||
|
||||
_, rqToBJJY := babyjub.UnpackSignY(tx.RqToBJJ)
|
||||
|
||||
return poseidon.Hash([]*big.Int{toCompressedData, e1, toBJJY, rqTxCompressedDataV2, rqToEthAddr, rqToBJJY})
|
||||
return poseidon.Hash([]*big.Int{toCompressedData, e1, toBJJY, rqTxCompressedDataV2,
|
||||
rqToEthAddr, rqToBJJY})
|
||||
}
|
||||
|
||||
// VerifySignature returns true if the signature verification is correct for the given PublicKeyComp
|
||||
|
||||
@@ -21,17 +21,20 @@ func TestNewPoolL2Tx(t *testing.T) {
|
||||
}
|
||||
poolL2Tx, err := NewPoolL2Tx(poolL2Tx)
|
||||
assert.NoError(t, err)
|
||||
assert.Equal(t, "0x022669acda59b827d20ef5354a3eebd1dffb3972b0a6bf89d18bfd2efa0ab9f41e", poolL2Tx.TxID.String())
|
||||
assert.Equal(t, "0x022669acda59b827d20ef5354a3eebd1dffb3972b0a6bf89d18bfd2efa0ab9f41e",
|
||||
poolL2Tx.TxID.String())
|
||||
}
|
||||
|
||||
func TestTxCompressedDataAndTxCompressedDataV2JSVectors(t *testing.T) {
|
||||
// test vectors values generated from javascript implementation
|
||||
var skPositive babyjub.PrivateKey // 'Positive' refers to the sign
|
||||
_, err := hex.Decode(skPositive[:], []byte("0001020304050607080900010203040506070809000102030405060708090001"))
|
||||
_, err := hex.Decode(skPositive[:],
|
||||
[]byte("0001020304050607080900010203040506070809000102030405060708090001"))
|
||||
assert.NoError(t, err)
|
||||
|
||||
var skNegative babyjub.PrivateKey // 'Negative' refers to the sign
|
||||
_, err = hex.Decode(skNegative[:], []byte("0001020304050607080900010203040506070809000102030405060708090002"))
|
||||
_, err = hex.Decode(skNegative[:],
|
||||
[]byte("0001020304050607080900010203040506070809000102030405060708090002"))
|
||||
assert.NoError(t, err)
|
||||
|
||||
amount, ok := new(big.Int).SetString("343597383670000000000000000000000000000000", 10)
|
||||
@@ -123,7 +126,8 @@ func TestTxCompressedDataAndTxCompressedDataV2JSVectors(t *testing.T) {
|
||||
|
||||
func TestRqTxCompressedDataV2(t *testing.T) {
|
||||
var sk babyjub.PrivateKey
|
||||
_, err := hex.Decode(sk[:], []byte("0001020304050607080900010203040506070809000102030405060708090001"))
|
||||
_, err := hex.Decode(sk[:],
|
||||
[]byte("0001020304050607080900010203040506070809000102030405060708090001"))
|
||||
assert.NoError(t, err)
|
||||
tx := PoolL2Tx{
|
||||
RqFromIdx: 7,
|
||||
@@ -142,7 +146,8 @@ func TestRqTxCompressedDataV2(t *testing.T) {
|
||||
expected, ok := new(big.Int).SetString(expectedStr, 10)
|
||||
assert.True(t, ok)
|
||||
assert.Equal(t, expected.Bytes(), txCompressedData.Bytes())
|
||||
assert.Equal(t, "010c000000000b0000000a0000000009000000000008000000000007", hex.EncodeToString(txCompressedData.Bytes()))
|
||||
assert.Equal(t, "010c000000000b0000000a0000000009000000000008000000000007",
|
||||
hex.EncodeToString(txCompressedData.Bytes()))
|
||||
}
|
||||
|
||||
func TestHashToSign(t *testing.T) {
|
||||
@@ -157,13 +162,15 @@ func TestHashToSign(t *testing.T) {
|
||||
}
|
||||
toSign, err := tx.HashToSign(chainID)
|
||||
assert.NoError(t, err)
|
||||
assert.Equal(t, "2d49ce1d4136e06f64e3eb1f79a346e6ee3e93ceeac909a57806a8d87005c263", hex.EncodeToString(toSign.Bytes()))
|
||||
assert.Equal(t, "2d49ce1d4136e06f64e3eb1f79a346e6ee3e93ceeac909a57806a8d87005c263",
|
||||
hex.EncodeToString(toSign.Bytes()))
|
||||
}
|
||||
|
||||
func TestVerifyTxSignature(t *testing.T) {
|
||||
chainID := uint16(0)
|
||||
var sk babyjub.PrivateKey
|
||||
_, err := hex.Decode(sk[:], []byte("0001020304050607080900010203040506070809000102030405060708090001"))
|
||||
_, err := hex.Decode(sk[:],
|
||||
[]byte("0001020304050607080900010203040506070809000102030405060708090001"))
|
||||
assert.NoError(t, err)
|
||||
tx := PoolL2Tx{
|
||||
FromIdx: 2,
|
||||
@@ -177,7 +184,9 @@ func TestVerifyTxSignature(t *testing.T) {
|
||||
}
|
||||
toSign, err := tx.HashToSign(chainID)
|
||||
assert.NoError(t, err)
|
||||
assert.Equal(t, "1571327027383224465388301747239444557034990637650927918405777653988509342917", toSign.String())
|
||||
assert.Equal(t,
|
||||
"1571327027383224465388301747239444557034990637650927918405777653988509342917",
|
||||
toSign.String())
|
||||
|
||||
sig := sk.SignPoseidon(toSign)
|
||||
tx.Signature = sig.Compress()
|
||||
@@ -188,7 +197,9 @@ func TestDecompressEmptyBJJComp(t *testing.T) {
|
||||
pkComp := EmptyBJJComp
|
||||
pk, err := pkComp.Decompress()
|
||||
require.NoError(t, err)
|
||||
assert.Equal(t, "2957874849018779266517920829765869116077630550401372566248359756137677864698", pk.X.String())
|
||||
assert.Equal(t,
|
||||
"2957874849018779266517920829765869116077630550401372566248359756137677864698",
|
||||
pk.X.String())
|
||||
assert.Equal(t, "0", pk.Y.String())
|
||||
}
|
||||
|
||||
|
||||
@@ -15,8 +15,9 @@ const tokenIDBytesLen = 4
|
||||
|
||||
// Token is a struct that represents an Ethereum token that is supported in Hermez network
|
||||
type Token struct {
|
||||
TokenID TokenID `json:"id" meddler:"token_id"`
|
||||
EthBlockNum int64 `json:"ethereumBlockNum" meddler:"eth_block_num"` // Ethereum block number in which this token was registered
|
||||
TokenID TokenID `json:"id" meddler:"token_id"`
|
||||
// EthBlockNum indicates the Ethereum block number in which this token was registered
|
||||
EthBlockNum int64 `json:"ethereumBlockNum" meddler:"eth_block_num"`
|
||||
EthAddr ethCommon.Address `json:"ethereumAddress" meddler:"eth_addr"`
|
||||
Name string `json:"name" meddler:"name"`
|
||||
Symbol string `json:"symbol" meddler:"symbol"`
|
||||
@@ -48,7 +49,8 @@ func (t TokenID) BigInt() *big.Int {
|
||||
// TokenIDFromBytes returns TokenID from a byte array
|
||||
func TokenIDFromBytes(b []byte) (TokenID, error) {
|
||||
if len(b) != tokenIDBytesLen {
|
||||
return 0, tracerr.Wrap(fmt.Errorf("can not parse TokenID, bytes len %d, expected 4", len(b)))
|
||||
return 0, tracerr.Wrap(fmt.Errorf("can not parse TokenID, bytes len %d, expected 4",
|
||||
len(b)))
|
||||
}
|
||||
tid := binary.BigEndian.Uint32(b[:4])
|
||||
return TokenID(tid), nil
|
||||
|
||||
46
common/tx.go
46
common/tx.go
@@ -51,7 +51,8 @@ func (txid *TxID) Scan(src interface{}) error {
|
||||
return tracerr.Wrap(fmt.Errorf("can't scan %T into TxID", src))
|
||||
}
|
||||
if len(srcB) != TxIDLen {
|
||||
return tracerr.Wrap(fmt.Errorf("can't scan []byte of len %d into TxID, need %d", len(srcB), TxIDLen))
|
||||
return tracerr.Wrap(fmt.Errorf("can't scan []byte of len %d into TxID, need %d",
|
||||
len(srcB), TxIDLen))
|
||||
}
|
||||
copy(txid[:], srcB)
|
||||
return nil
|
||||
@@ -102,13 +103,15 @@ func (txid *TxID) UnmarshalText(data []byte) error {
|
||||
type TxType string
|
||||
|
||||
const (
|
||||
// TxTypeExit represents L2->L1 token transfer. A leaf for this account appears in the exit tree of the block
|
||||
// TxTypeExit represents L2->L1 token transfer. A leaf for this account appears in the exit
|
||||
// tree of the block
|
||||
TxTypeExit TxType = "Exit"
|
||||
// TxTypeTransfer represents L2->L2 token transfer
|
||||
TxTypeTransfer TxType = "Transfer"
|
||||
// TxTypeDeposit represents L1->L2 transfer
|
||||
TxTypeDeposit TxType = "Deposit"
|
||||
// TxTypeCreateAccountDeposit represents creation of a new leaf in the state tree (newAcconut) + L1->L2 transfer
|
||||
// TxTypeCreateAccountDeposit represents creation of a new leaf in the state tree
|
||||
// (newAcconut) + L1->L2 transfer
|
||||
TxTypeCreateAccountDeposit TxType = "CreateAccountDeposit"
|
||||
// TxTypeCreateAccountDepositTransfer represents L1->L2 transfer + L2->L2 transfer
|
||||
TxTypeCreateAccountDepositTransfer TxType = "CreateAccountDepositTransfer"
|
||||
@@ -124,24 +127,31 @@ const (
|
||||
TxTypeTransferToBJJ TxType = "TransferToBJJ"
|
||||
)
|
||||
|
||||
// Tx is a struct used by the TxSelector & BatchBuilder as a generic type generated from L1Tx & PoolL2Tx
|
||||
// Tx is a struct used by the TxSelector & BatchBuilder as a generic type generated from L1Tx &
|
||||
// PoolL2Tx
|
||||
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"`
|
||||
Amount *big.Int `meddler:"amount,bigint"`
|
||||
AmountFloat float64 `meddler:"amount_f"`
|
||||
TokenID TokenID `meddler:"token_id"`
|
||||
USD *float64 `meddler:"amount_usd"`
|
||||
BatchNum *BatchNum `meddler:"batch_num"` // batchNum in which this tx was forged. If the tx is L2, this must be != 0
|
||||
EthBlockNum int64 `meddler:"eth_block_num"` // Ethereum Block Number in which this L1Tx was added to the queue
|
||||
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"`
|
||||
Amount *big.Int `meddler:"amount,bigint"`
|
||||
AmountFloat float64 `meddler:"amount_f"`
|
||||
TokenID TokenID `meddler:"token_id"`
|
||||
USD *float64 `meddler:"amount_usd"`
|
||||
// BatchNum in which this tx was forged. If the tx is L2, this must be != 0
|
||||
BatchNum *BatchNum `meddler:"batch_num"`
|
||||
// Ethereum Block Number in which this L1Tx was added to the queue
|
||||
EthBlockNum int64 `meddler:"eth_block_num"`
|
||||
// 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
|
||||
// ToForgeL1TxsNum in which the tx was forged / will be forged
|
||||
ToForgeL1TxsNum *int64 `meddler:"to_forge_l1_txs_num"`
|
||||
// UserOrigin is set to 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
|
||||
UserOrigin *bool `meddler:"user_origin"`
|
||||
FromEthAddr ethCommon.Address `meddler:"from_eth_addr"`
|
||||
FromBJJ babyjub.PublicKeyComp `meddler:"from_bjj"`
|
||||
DepositAmount *big.Int `meddler:"deposit_amount,bigintnull"`
|
||||
|
||||
@@ -21,8 +21,10 @@ func TestSignatureConstant(t *testing.T) {
|
||||
func TestTxIDScannerValue(t *testing.T) {
|
||||
txid0 := &TxID{}
|
||||
txid1 := &TxID{}
|
||||
txid0B := [TxIDLen]byte{0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0, 1, 2}
|
||||
txid1B := [TxIDLen]byte{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}
|
||||
txid0B := [TxIDLen]byte{0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0, 1, 2,
|
||||
3, 4, 5, 6, 7, 8, 9, 0, 1, 2}
|
||||
txid1B := [TxIDLen]byte{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0}
|
||||
|
||||
copy(txid0[:], txid0B[:])
|
||||
copy(txid1[:], txid1B[:])
|
||||
|
||||
@@ -21,16 +21,23 @@ func TestBJJFromStringWithChecksum(t *testing.T) {
|
||||
assert.NoError(t, err)
|
||||
|
||||
// expected values computed with js implementation
|
||||
assert.Equal(t, "2492816973395423007340226948038371729989170225696553239457870892535792679622", pk.X.String())
|
||||
assert.Equal(t, "15238403086306505038849621710779816852318505119327426213168494964113886299863", pk.Y.String())
|
||||
assert.Equal(t,
|
||||
"2492816973395423007340226948038371729989170225696553239457870892535792679622",
|
||||
pk.X.String())
|
||||
assert.Equal(t,
|
||||
"15238403086306505038849621710779816852318505119327426213168494964113886299863",
|
||||
pk.Y.String())
|
||||
}
|
||||
|
||||
func TestRmEndingZeroes(t *testing.T) {
|
||||
s0, err := merkletree.NewHashFromHex("0x0000000000000000000000000000000000000000000000000000000000000000")
|
||||
s0, err :=
|
||||
merkletree.NewHashFromHex("0x0000000000000000000000000000000000000000000000000000000000000000")
|
||||
require.NoError(t, err)
|
||||
s1, err := merkletree.NewHashFromHex("0x0000000000000000000000000000000000000000000000000000000000000001")
|
||||
s1, err :=
|
||||
merkletree.NewHashFromHex("0x0000000000000000000000000000000000000000000000000000000000000001")
|
||||
require.NoError(t, err)
|
||||
s2, err := merkletree.NewHashFromHex("0x0000000000000000000000000000000000000000000000000000000000000002")
|
||||
s2, err :=
|
||||
merkletree.NewHashFromHex("0x0000000000000000000000000000000000000000000000000000000000000002")
|
||||
require.NoError(t, err)
|
||||
|
||||
// expect cropped last zeroes
|
||||
|
||||
16
common/zk.go
16
common/zk.go
@@ -130,8 +130,8 @@ type ZKInputs struct {
|
||||
RqOffset []*big.Int `json:"rqOffset"` // uint8 (max 3 bits), len: [maxTx]
|
||||
|
||||
// transaction L2 request data
|
||||
// RqTxCompressedDataV2
|
||||
RqTxCompressedDataV2 []*big.Int `json:"rqTxCompressedDataV2"` // big.Int (max 251 bits), len: [maxTx]
|
||||
// RqTxCompressedDataV2 big.Int (max 251 bits), len: [maxTx]
|
||||
RqTxCompressedDataV2 []*big.Int `json:"rqTxCompressedDataV2"`
|
||||
// RqToEthAddr
|
||||
RqToEthAddr []*big.Int `json:"rqToEthAddr"` // ethCommon.Address, len: [maxTx]
|
||||
// RqToBJJAy
|
||||
@@ -301,7 +301,8 @@ func (z ZKInputs) MarshalJSON() ([]byte, error) {
|
||||
}
|
||||
|
||||
// NewZKInputs returns a pointer to an initialized struct of ZKInputs
|
||||
func NewZKInputs(chainID uint16, maxTx, maxL1Tx, maxFeeIdxs, nLevels uint32, currentNumBatch *big.Int) *ZKInputs {
|
||||
func NewZKInputs(chainID uint16, maxTx, maxL1Tx, maxFeeIdxs, nLevels uint32,
|
||||
currentNumBatch *big.Int) *ZKInputs {
|
||||
zki := &ZKInputs{}
|
||||
zki.Metadata.MaxFeeIdxs = maxFeeIdxs
|
||||
zki.Metadata.MaxLevels = uint32(48) //nolint:gomnd
|
||||
@@ -480,7 +481,7 @@ func (z ZKInputs) ToHashGlobalData() ([]byte, error) {
|
||||
b = append(b, newExitRoot...)
|
||||
|
||||
// [MAX_L1_TX * (2 * MAX_NLEVELS + 528) bits] L1TxsData
|
||||
l1TxDataLen := (2*z.Metadata.MaxLevels + 528)
|
||||
l1TxDataLen := (2*z.Metadata.MaxLevels + 528) //nolint:gomnd
|
||||
l1TxsDataLen := (z.Metadata.MaxL1Tx * l1TxDataLen)
|
||||
l1TxsData := make([]byte, l1TxsDataLen/8) //nolint:gomnd
|
||||
for i := 0; i < len(z.Metadata.L1TxsData); i++ {
|
||||
@@ -506,11 +507,14 @@ func (z ZKInputs) ToHashGlobalData() ([]byte, error) {
|
||||
l2TxsData = append(l2TxsData, z.Metadata.L2TxsData[i]...)
|
||||
}
|
||||
if len(l2TxsData) > int(expectedL2TxsDataLen) {
|
||||
return nil, tracerr.Wrap(fmt.Errorf("len(l2TxsData): %d, expected: %d", len(l2TxsData), expectedL2TxsDataLen))
|
||||
return nil, tracerr.Wrap(fmt.Errorf("len(l2TxsData): %d, expected: %d",
|
||||
len(l2TxsData), expectedL2TxsDataLen))
|
||||
}
|
||||
|
||||
b = append(b, l2TxsData...)
|
||||
l2TxsPadding := make([]byte, (int(z.Metadata.MaxTx)-len(z.Metadata.L1TxsDataAvailability)-len(z.Metadata.L2TxsData))*int(l2TxDataLen)/8) //nolint:gomnd
|
||||
l2TxsPadding := make([]byte,
|
||||
(int(z.Metadata.MaxTx)-len(z.Metadata.L1TxsDataAvailability)-
|
||||
len(z.Metadata.L2TxsData))*int(l2TxDataLen)/8) //nolint:gomnd
|
||||
b = append(b, l2TxsPadding...)
|
||||
|
||||
// [NLevels * MAX_TOKENS_FEE bits] feeTxsData
|
||||
|
||||
Reference in New Issue
Block a user