mirror of
https://github.com/arnaucube/hermez-node.git
synced 2026-02-07 03:16:45 +01:00
Merge pull request #416 from hermeznetwork/feature/update-accountcreationauth
Update AccountCreationAuth & fix auth.HashToSign
This commit is contained in:
@@ -21,7 +21,7 @@ func (a *API) postAccountCreationAuth(c *gin.Context) {
|
|||||||
}
|
}
|
||||||
// API to common + verify signature
|
// API to common + verify signature
|
||||||
commonAuth := accountCreationAuthAPIToCommon(&apiAuth)
|
commonAuth := accountCreationAuthAPIToCommon(&apiAuth)
|
||||||
if !commonAuth.VerifySignature() {
|
if !commonAuth.VerifySignature(a.chainID, a.hermezAddress) {
|
||||||
retBadReq(errors.New("invalid signature"), c)
|
retBadReq(errors.New("invalid signature"), c)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -4,6 +4,7 @@ import (
|
|||||||
"errors"
|
"errors"
|
||||||
"sync"
|
"sync"
|
||||||
|
|
||||||
|
ethCommon "github.com/ethereum/go-ethereum/common"
|
||||||
"github.com/gin-gonic/gin"
|
"github.com/gin-gonic/gin"
|
||||||
"github.com/hermeznetwork/hermez-node/common"
|
"github.com/hermeznetwork/hermez-node/common"
|
||||||
"github.com/hermeznetwork/hermez-node/db/historydb"
|
"github.com/hermeznetwork/hermez-node/db/historydb"
|
||||||
@@ -37,6 +38,7 @@ type API struct {
|
|||||||
l2 *l2db.L2DB
|
l2 *l2db.L2DB
|
||||||
status Status
|
status Status
|
||||||
chainID uint16
|
chainID uint16
|
||||||
|
hermezAddress ethCommon.Address
|
||||||
}
|
}
|
||||||
|
|
||||||
// NewAPI sets the endpoints and the appropriate handlers, but doesn't start the server
|
// NewAPI sets the endpoints and the appropriate handlers, but doesn't start the server
|
||||||
@@ -47,7 +49,6 @@ func NewAPI(
|
|||||||
sdb *statedb.StateDB,
|
sdb *statedb.StateDB,
|
||||||
l2db *l2db.L2DB,
|
l2db *l2db.L2DB,
|
||||||
config *Config,
|
config *Config,
|
||||||
chainID uint16,
|
|
||||||
) (*API, error) {
|
) (*API, error) {
|
||||||
// Check input
|
// Check input
|
||||||
// TODO: is stateDB only needed for explorer endpoints or for both?
|
// TODO: is stateDB only needed for explorer endpoints or for both?
|
||||||
@@ -68,7 +69,8 @@ func NewAPI(
|
|||||||
s: sdb,
|
s: sdb,
|
||||||
l2: l2db,
|
l2: l2db,
|
||||||
status: Status{},
|
status: Status{},
|
||||||
chainID: chainID,
|
chainID: config.ChainID,
|
||||||
|
hermezAddress: config.HermezAddress,
|
||||||
}
|
}
|
||||||
|
|
||||||
// Add coordinator endpoints
|
// Add coordinator endpoints
|
||||||
|
|||||||
@@ -221,7 +221,7 @@ func TestMain(m *testing.M) {
|
|||||||
test.WipeDB(l2DB.DB()) // this will clean HistoryDB and L2DB
|
test.WipeDB(l2DB.DB()) // this will clean HistoryDB and L2DB
|
||||||
|
|
||||||
// Config (smart contract constants)
|
// Config (smart contract constants)
|
||||||
_config := getConfigTest()
|
_config := getConfigTest(chainID)
|
||||||
config = configAPI{
|
config = configAPI{
|
||||||
RollupConstants: *newRollupConstants(_config.RollupConstants),
|
RollupConstants: *newRollupConstants(_config.RollupConstants),
|
||||||
AuctionConstants: _config.AuctionConstants,
|
AuctionConstants: _config.AuctionConstants,
|
||||||
@@ -238,7 +238,6 @@ func TestMain(m *testing.M) {
|
|||||||
sdb,
|
sdb,
|
||||||
l2DB,
|
l2DB,
|
||||||
&_config,
|
&_config,
|
||||||
chainID,
|
|
||||||
)
|
)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
panic(err)
|
panic(err)
|
||||||
@@ -423,7 +422,7 @@ func TestMain(m *testing.M) {
|
|||||||
exits: testExits,
|
exits: testExits,
|
||||||
poolTxsToSend: poolTxsToSend,
|
poolTxsToSend: poolTxsToSend,
|
||||||
poolTxsToReceive: poolTxsToReceive,
|
poolTxsToReceive: poolTxsToReceive,
|
||||||
auths: genTestAuths(test.GenAuths(5)),
|
auths: genTestAuths(test.GenAuths(5, _config.ChainID, _config.HermezAddress)),
|
||||||
router: router,
|
router: router,
|
||||||
bids: testBids,
|
bids: testBids,
|
||||||
slots: api.genTestSlots(
|
slots: api.genTestSlots(
|
||||||
|
|||||||
@@ -4,6 +4,7 @@ import (
|
|||||||
"math/big"
|
"math/big"
|
||||||
"net/http"
|
"net/http"
|
||||||
|
|
||||||
|
ethCommon "github.com/ethereum/go-ethereum/common"
|
||||||
"github.com/gin-gonic/gin"
|
"github.com/gin-gonic/gin"
|
||||||
"github.com/hermeznetwork/hermez-node/common"
|
"github.com/hermeznetwork/hermez-node/common"
|
||||||
)
|
)
|
||||||
@@ -51,6 +52,8 @@ type Config struct {
|
|||||||
RollupConstants common.RollupConstants
|
RollupConstants common.RollupConstants
|
||||||
AuctionConstants common.AuctionConstants
|
AuctionConstants common.AuctionConstants
|
||||||
WDelayerConstants common.WDelayerConstants
|
WDelayerConstants common.WDelayerConstants
|
||||||
|
ChainID uint16
|
||||||
|
HermezAddress ethCommon.Address
|
||||||
}
|
}
|
||||||
|
|
||||||
type configAPI struct {
|
type configAPI struct {
|
||||||
|
|||||||
@@ -9,7 +9,7 @@ import (
|
|||||||
"github.com/stretchr/testify/assert"
|
"github.com/stretchr/testify/assert"
|
||||||
)
|
)
|
||||||
|
|
||||||
func getConfigTest() Config {
|
func getConfigTest(chainID uint16) Config {
|
||||||
var config Config
|
var config Config
|
||||||
|
|
||||||
var rollupPublicConstants common.RollupConstants
|
var rollupPublicConstants common.RollupConstants
|
||||||
@@ -40,6 +40,9 @@ func getConfigTest() Config {
|
|||||||
config.AuctionConstants = auctionConstants
|
config.AuctionConstants = auctionConstants
|
||||||
config.WDelayerConstants = wdelayerConstants
|
config.WDelayerConstants = wdelayerConstants
|
||||||
|
|
||||||
|
config.ChainID = chainID
|
||||||
|
config.HermezAddress = ethCommon.HexToAddress("0xc344E203a046Da13b0B4467EB7B3629D0C99F6E6")
|
||||||
|
|
||||||
return config
|
return config
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1,15 +1,20 @@
|
|||||||
package common
|
package common
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"encoding/binary"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
ethCommon "github.com/ethereum/go-ethereum/common"
|
ethCommon "github.com/ethereum/go-ethereum/common"
|
||||||
ethCrypto "github.com/ethereum/go-ethereum/crypto"
|
ethCrypto "github.com/ethereum/go-ethereum/crypto"
|
||||||
"github.com/hermeznetwork/tracerr"
|
|
||||||
"github.com/iden3/go-iden3-crypto/babyjub"
|
"github.com/iden3/go-iden3-crypto/babyjub"
|
||||||
)
|
)
|
||||||
|
|
||||||
// AccountCreationAuth authorizations sent by users to the L2DB, to be used for account creations when necessary
|
// AccountCreationAuthMsg is the message that is signed to authorize an account
|
||||||
|
// creation
|
||||||
|
const AccountCreationAuthMsg = "I authorize this babyjubjub key for hermez rollup account creation"
|
||||||
|
|
||||||
|
// AccountCreationAuth authorizations sent by users to the L2DB, to be used for
|
||||||
|
// account creations when necessary
|
||||||
type AccountCreationAuth struct {
|
type AccountCreationAuth struct {
|
||||||
EthAddr ethCommon.Address `meddler:"eth_addr"`
|
EthAddr ethCommon.Address `meddler:"eth_addr"`
|
||||||
BJJ babyjub.PublicKeyComp `meddler:"bjj"`
|
BJJ babyjub.PublicKeyComp `meddler:"bjj"`
|
||||||
@@ -18,21 +23,21 @@ type AccountCreationAuth struct {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// HashToSign builds the hash to be signed using BJJ pub key and the constant message
|
// HashToSign builds the hash to be signed using BJJ pub key and the constant message
|
||||||
func (a *AccountCreationAuth) HashToSign() ([]byte, error) {
|
func (a *AccountCreationAuth) HashToSign(chainID uint16,
|
||||||
|
hermezContractAddr ethCommon.Address) ([]byte, error) {
|
||||||
// Calculate message to be signed
|
// Calculate message to be signed
|
||||||
const msg = "I authorize this babyjubjub key for hermez rollup account creation"
|
var chainIDBytes [2]byte
|
||||||
comp, err := a.BJJ.MarshalText()
|
binary.BigEndian.PutUint16(chainIDBytes[:], chainID)
|
||||||
if err != nil {
|
// to hash: [AccountCreationAuthMsg | compressedBJJ | chainID | hermezContractAddr]
|
||||||
return nil, tracerr.Wrap(err)
|
return ethCrypto.Keccak256Hash([]byte(AccountCreationAuthMsg), a.BJJ[:], chainIDBytes[:],
|
||||||
}
|
hermezContractAddr[:]).Bytes(), nil
|
||||||
// Hash message (msg || compressed-bjj)
|
|
||||||
return ethCrypto.Keccak256Hash([]byte(msg), comp).Bytes(), nil
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// VerifySignature ensures that the Signature is done with the specified EthAddr
|
// VerifySignature ensures that the Signature is done with the specified EthAddr
|
||||||
func (a *AccountCreationAuth) VerifySignature() bool {
|
func (a *AccountCreationAuth) VerifySignature(chainID uint16,
|
||||||
|
hermezContractAddr ethCommon.Address) bool {
|
||||||
// Calculate hash to be signed
|
// Calculate hash to be signed
|
||||||
msg, err := a.HashToSign()
|
msg, err := a.HashToSign(chainID, hermezContractAddr)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
|||||||
41
common/accountcreationauths_test.go
Normal file
41
common/accountcreationauths_test.go
Normal file
@@ -0,0 +1,41 @@
|
|||||||
|
package common
|
||||||
|
|
||||||
|
import (
|
||||||
|
"encoding/hex"
|
||||||
|
"testing"
|
||||||
|
|
||||||
|
ethCommon "github.com/ethereum/go-ethereum/common"
|
||||||
|
ethCrypto "github.com/ethereum/go-ethereum/crypto"
|
||||||
|
"github.com/iden3/go-iden3-crypto/babyjub"
|
||||||
|
"github.com/stretchr/testify/assert"
|
||||||
|
"github.com/stretchr/testify/require"
|
||||||
|
)
|
||||||
|
|
||||||
|
func TestAccountCreationAuth(t *testing.T) {
|
||||||
|
// Ethereum key
|
||||||
|
ethSk, err := ethCrypto.HexToECDSA("fad9c8855b740a0b7ed4c221dbad0f33a83a49cad6b3fe8d5817ac83d38b6a19")
|
||||||
|
require.NoError(t, err)
|
||||||
|
ethAddr := ethCrypto.PubkeyToAddress(ethSk.PublicKey)
|
||||||
|
|
||||||
|
// BabyJubJub key
|
||||||
|
var sk babyjub.PrivateKey
|
||||||
|
_, err = hex.Decode(sk[:], []byte("0001020304050607080900010203040506070809000102030405060708090001"))
|
||||||
|
assert.NoError(t, err)
|
||||||
|
|
||||||
|
chainID := uint16(0)
|
||||||
|
hermezContractAddr := ethCommon.HexToAddress("0xc344E203a046Da13b0B4467EB7B3629D0C99F6E6")
|
||||||
|
a := AccountCreationAuth{
|
||||||
|
EthAddr: ethAddr,
|
||||||
|
BJJ: sk.Public().Compress(),
|
||||||
|
}
|
||||||
|
msg, err := a.HashToSign(chainID, hermezContractAddr)
|
||||||
|
assert.NoError(t, err)
|
||||||
|
assert.Equal(t, "cb5a7e44329ff430c81fec49fb2ac6741f02d5ec96cbcb618a6991f0a9c80ffd", hex.EncodeToString(msg))
|
||||||
|
|
||||||
|
// sign AccountCreationAuth with eth key
|
||||||
|
sig, err := ethCrypto.Sign(msg, ethSk)
|
||||||
|
assert.NoError(t, err)
|
||||||
|
a.Signature = sig
|
||||||
|
|
||||||
|
assert.True(t, a.VerifySignature(chainID, hermezContractAddr))
|
||||||
|
}
|
||||||
@@ -611,8 +611,10 @@ func TestPurge(t *testing.T) {
|
|||||||
func TestAuth(t *testing.T) {
|
func TestAuth(t *testing.T) {
|
||||||
test.WipeDB(l2DB.DB())
|
test.WipeDB(l2DB.DB())
|
||||||
const nAuths = 5
|
const nAuths = 5
|
||||||
|
chainID := uint16(0)
|
||||||
|
hermezContractAddr := ethCommon.HexToAddress("0xc344E203a046Da13b0B4467EB7B3629D0C99F6E6")
|
||||||
// Generate authorizations
|
// Generate authorizations
|
||||||
auths := test.GenAuths(nAuths)
|
auths := test.GenAuths(nAuths, chainID, hermezContractAddr)
|
||||||
for i := 0; i < len(auths); i++ {
|
for i := 0; i < len(auths); i++ {
|
||||||
// Add to the DB
|
// Add to the DB
|
||||||
err := l2DB.AddAccountCreationAuth(auths[i])
|
err := l2DB.AddAccountCreationAuth(auths[i])
|
||||||
|
|||||||
@@ -245,8 +245,9 @@ func NewNode(mode Mode, cfg *config.Node) (*Node, error) {
|
|||||||
RollupConstants: scConsts.Rollup,
|
RollupConstants: scConsts.Rollup,
|
||||||
AuctionConstants: scConsts.Auction,
|
AuctionConstants: scConsts.Auction,
|
||||||
WDelayerConstants: scConsts.WDelayer,
|
WDelayerConstants: scConsts.WDelayer,
|
||||||
|
ChainID: chainIDU16,
|
||||||
|
HermezAddress: cfg.SmartContracts.Rollup,
|
||||||
},
|
},
|
||||||
chainIDU16,
|
|
||||||
)
|
)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, tracerr.Wrap(err)
|
return nil, tracerr.Wrap(err)
|
||||||
@@ -301,7 +302,6 @@ func NewNodeAPI(
|
|||||||
sdb *statedb.StateDB,
|
sdb *statedb.StateDB,
|
||||||
l2db *l2db.L2DB,
|
l2db *l2db.L2DB,
|
||||||
config *api.Config,
|
config *api.Config,
|
||||||
chainID uint16,
|
|
||||||
) (*NodeAPI, error) {
|
) (*NodeAPI, error) {
|
||||||
engine := gin.Default()
|
engine := gin.Default()
|
||||||
engine.NoRoute(handleNoRoute)
|
engine.NoRoute(handleNoRoute)
|
||||||
@@ -313,7 +313,6 @@ func NewNodeAPI(
|
|||||||
sdb,
|
sdb,
|
||||||
l2db,
|
l2db,
|
||||||
config,
|
config,
|
||||||
chainID,
|
|
||||||
)
|
)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, tracerr.Wrap(err)
|
return nil, tracerr.Wrap(err)
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
package test
|
package test
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
ethCommon "github.com/ethereum/go-ethereum/common"
|
||||||
ethCrypto "github.com/ethereum/go-ethereum/crypto"
|
ethCrypto "github.com/ethereum/go-ethereum/crypto"
|
||||||
"github.com/hermeznetwork/hermez-node/common"
|
"github.com/hermeznetwork/hermez-node/common"
|
||||||
"github.com/iden3/go-iden3-crypto/babyjub"
|
"github.com/iden3/go-iden3-crypto/babyjub"
|
||||||
@@ -66,7 +67,7 @@ func GenPoolTxs(n int, tokens []common.Token) []*common.PoolL2Tx {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// GenAuths generates account creation authorizations
|
// GenAuths generates account creation authorizations
|
||||||
func GenAuths(nAuths int) []*common.AccountCreationAuth {
|
func GenAuths(nAuths int, chainID uint16, hermezContractAddr ethCommon.Address) []*common.AccountCreationAuth {
|
||||||
auths := []*common.AccountCreationAuth{}
|
auths := []*common.AccountCreationAuth{}
|
||||||
for i := 0; i < nAuths; i++ {
|
for i := 0; i < nAuths; i++ {
|
||||||
// Generate keys
|
// Generate keys
|
||||||
@@ -81,7 +82,7 @@ func GenAuths(nAuths int) []*common.AccountCreationAuth {
|
|||||||
BJJ: bjjPrivK.Public().Compress(),
|
BJJ: bjjPrivK.Public().Compress(),
|
||||||
}
|
}
|
||||||
// Sign
|
// Sign
|
||||||
h, err := auth.HashToSign()
|
h, err := auth.HashToSign(chainID, hermezContractAddr)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
panic(err)
|
panic(err)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -3,13 +3,17 @@ package test
|
|||||||
import (
|
import (
|
||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
|
ethCommon "github.com/ethereum/go-ethereum/common"
|
||||||
"github.com/stretchr/testify/assert"
|
"github.com/stretchr/testify/assert"
|
||||||
)
|
)
|
||||||
|
|
||||||
func TestGenAuths(t *testing.T) {
|
func TestGenAuths(t *testing.T) {
|
||||||
|
chainID := uint16(0)
|
||||||
|
hermezContractAddr := ethCommon.HexToAddress("0xc344E203a046Da13b0B4467EB7B3629D0C99F6E6")
|
||||||
|
|
||||||
const nAuths = 5
|
const nAuths = 5
|
||||||
auths := GenAuths(nAuths)
|
auths := GenAuths(nAuths, chainID, hermezContractAddr)
|
||||||
for _, auth := range auths {
|
for _, auth := range auths {
|
||||||
assert.True(t, auth.VerifySignature())
|
assert.True(t, auth.VerifySignature(chainID, hermezContractAddr))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user