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
|
||||
commonAuth := accountCreationAuthAPIToCommon(&apiAuth)
|
||||
if !commonAuth.VerifySignature() {
|
||||
if !commonAuth.VerifySignature(a.chainID, a.hermezAddress) {
|
||||
retBadReq(errors.New("invalid signature"), c)
|
||||
return
|
||||
}
|
||||
|
||||
24
api/api.go
24
api/api.go
@@ -4,6 +4,7 @@ import (
|
||||
"errors"
|
||||
"sync"
|
||||
|
||||
ethCommon "github.com/ethereum/go-ethereum/common"
|
||||
"github.com/gin-gonic/gin"
|
||||
"github.com/hermeznetwork/hermez-node/common"
|
||||
"github.com/hermeznetwork/hermez-node/db/historydb"
|
||||
@@ -31,12 +32,13 @@ type Status struct {
|
||||
|
||||
// API serves HTTP requests to allow external interaction with the Hermez node
|
||||
type API struct {
|
||||
h *historydb.HistoryDB
|
||||
cg *configAPI
|
||||
s *statedb.StateDB
|
||||
l2 *l2db.L2DB
|
||||
status Status
|
||||
chainID uint16
|
||||
h *historydb.HistoryDB
|
||||
cg *configAPI
|
||||
s *statedb.StateDB
|
||||
l2 *l2db.L2DB
|
||||
status Status
|
||||
chainID uint16
|
||||
hermezAddress ethCommon.Address
|
||||
}
|
||||
|
||||
// NewAPI sets the endpoints and the appropriate handlers, but doesn't start the server
|
||||
@@ -47,7 +49,6 @@ func NewAPI(
|
||||
sdb *statedb.StateDB,
|
||||
l2db *l2db.L2DB,
|
||||
config *Config,
|
||||
chainID uint16,
|
||||
) (*API, error) {
|
||||
// Check input
|
||||
// TODO: is stateDB only needed for explorer endpoints or for both?
|
||||
@@ -65,10 +66,11 @@ func NewAPI(
|
||||
AuctionConstants: config.AuctionConstants,
|
||||
WDelayerConstants: config.WDelayerConstants,
|
||||
},
|
||||
s: sdb,
|
||||
l2: l2db,
|
||||
status: Status{},
|
||||
chainID: chainID,
|
||||
s: sdb,
|
||||
l2: l2db,
|
||||
status: Status{},
|
||||
chainID: config.ChainID,
|
||||
hermezAddress: config.HermezAddress,
|
||||
}
|
||||
|
||||
// Add coordinator endpoints
|
||||
|
||||
@@ -221,7 +221,7 @@ func TestMain(m *testing.M) {
|
||||
test.WipeDB(l2DB.DB()) // this will clean HistoryDB and L2DB
|
||||
|
||||
// Config (smart contract constants)
|
||||
_config := getConfigTest()
|
||||
_config := getConfigTest(chainID)
|
||||
config = configAPI{
|
||||
RollupConstants: *newRollupConstants(_config.RollupConstants),
|
||||
AuctionConstants: _config.AuctionConstants,
|
||||
@@ -238,7 +238,6 @@ func TestMain(m *testing.M) {
|
||||
sdb,
|
||||
l2DB,
|
||||
&_config,
|
||||
chainID,
|
||||
)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
@@ -423,7 +422,7 @@ func TestMain(m *testing.M) {
|
||||
exits: testExits,
|
||||
poolTxsToSend: poolTxsToSend,
|
||||
poolTxsToReceive: poolTxsToReceive,
|
||||
auths: genTestAuths(test.GenAuths(5)),
|
||||
auths: genTestAuths(test.GenAuths(5, _config.ChainID, _config.HermezAddress)),
|
||||
router: router,
|
||||
bids: testBids,
|
||||
slots: api.genTestSlots(
|
||||
|
||||
@@ -4,6 +4,7 @@ import (
|
||||
"math/big"
|
||||
"net/http"
|
||||
|
||||
ethCommon "github.com/ethereum/go-ethereum/common"
|
||||
"github.com/gin-gonic/gin"
|
||||
"github.com/hermeznetwork/hermez-node/common"
|
||||
)
|
||||
@@ -51,6 +52,8 @@ type Config struct {
|
||||
RollupConstants common.RollupConstants
|
||||
AuctionConstants common.AuctionConstants
|
||||
WDelayerConstants common.WDelayerConstants
|
||||
ChainID uint16
|
||||
HermezAddress ethCommon.Address
|
||||
}
|
||||
|
||||
type configAPI struct {
|
||||
|
||||
@@ -9,7 +9,7 @@ import (
|
||||
"github.com/stretchr/testify/assert"
|
||||
)
|
||||
|
||||
func getConfigTest() Config {
|
||||
func getConfigTest(chainID uint16) Config {
|
||||
var config Config
|
||||
|
||||
var rollupPublicConstants common.RollupConstants
|
||||
@@ -40,6 +40,9 @@ func getConfigTest() Config {
|
||||
config.AuctionConstants = auctionConstants
|
||||
config.WDelayerConstants = wdelayerConstants
|
||||
|
||||
config.ChainID = chainID
|
||||
config.HermezAddress = ethCommon.HexToAddress("0xc344E203a046Da13b0B4467EB7B3629D0C99F6E6")
|
||||
|
||||
return config
|
||||
}
|
||||
|
||||
|
||||
@@ -1,15 +1,20 @@
|
||||
package common
|
||||
|
||||
import (
|
||||
"encoding/binary"
|
||||
"time"
|
||||
|
||||
ethCommon "github.com/ethereum/go-ethereum/common"
|
||||
ethCrypto "github.com/ethereum/go-ethereum/crypto"
|
||||
"github.com/hermeznetwork/tracerr"
|
||||
"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 {
|
||||
EthAddr ethCommon.Address `meddler:"eth_addr"`
|
||||
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
|
||||
func (a *AccountCreationAuth) HashToSign() ([]byte, error) {
|
||||
func (a *AccountCreationAuth) HashToSign(chainID uint16,
|
||||
hermezContractAddr ethCommon.Address) ([]byte, error) {
|
||||
// Calculate message to be signed
|
||||
const msg = "I authorize this babyjubjub key for hermez rollup account creation"
|
||||
comp, err := a.BJJ.MarshalText()
|
||||
if err != nil {
|
||||
return nil, tracerr.Wrap(err)
|
||||
}
|
||||
// Hash message (msg || compressed-bjj)
|
||||
return ethCrypto.Keccak256Hash([]byte(msg), comp).Bytes(), nil
|
||||
var chainIDBytes [2]byte
|
||||
binary.BigEndian.PutUint16(chainIDBytes[:], chainID)
|
||||
// to hash: [AccountCreationAuthMsg | compressedBJJ | chainID | hermezContractAddr]
|
||||
return ethCrypto.Keccak256Hash([]byte(AccountCreationAuthMsg), a.BJJ[:], chainIDBytes[:],
|
||||
hermezContractAddr[:]).Bytes(), nil
|
||||
}
|
||||
|
||||
// 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
|
||||
msg, err := a.HashToSign()
|
||||
msg, err := a.HashToSign(chainID, hermezContractAddr)
|
||||
if err != nil {
|
||||
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) {
|
||||
test.WipeDB(l2DB.DB())
|
||||
const nAuths = 5
|
||||
chainID := uint16(0)
|
||||
hermezContractAddr := ethCommon.HexToAddress("0xc344E203a046Da13b0B4467EB7B3629D0C99F6E6")
|
||||
// Generate authorizations
|
||||
auths := test.GenAuths(nAuths)
|
||||
auths := test.GenAuths(nAuths, chainID, hermezContractAddr)
|
||||
for i := 0; i < len(auths); i++ {
|
||||
// Add to the DB
|
||||
err := l2DB.AddAccountCreationAuth(auths[i])
|
||||
|
||||
@@ -245,8 +245,9 @@ func NewNode(mode Mode, cfg *config.Node) (*Node, error) {
|
||||
RollupConstants: scConsts.Rollup,
|
||||
AuctionConstants: scConsts.Auction,
|
||||
WDelayerConstants: scConsts.WDelayer,
|
||||
ChainID: chainIDU16,
|
||||
HermezAddress: cfg.SmartContracts.Rollup,
|
||||
},
|
||||
chainIDU16,
|
||||
)
|
||||
if err != nil {
|
||||
return nil, tracerr.Wrap(err)
|
||||
@@ -301,7 +302,6 @@ func NewNodeAPI(
|
||||
sdb *statedb.StateDB,
|
||||
l2db *l2db.L2DB,
|
||||
config *api.Config,
|
||||
chainID uint16,
|
||||
) (*NodeAPI, error) {
|
||||
engine := gin.Default()
|
||||
engine.NoRoute(handleNoRoute)
|
||||
@@ -313,7 +313,6 @@ func NewNodeAPI(
|
||||
sdb,
|
||||
l2db,
|
||||
config,
|
||||
chainID,
|
||||
)
|
||||
if err != nil {
|
||||
return nil, tracerr.Wrap(err)
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
package test
|
||||
|
||||
import (
|
||||
ethCommon "github.com/ethereum/go-ethereum/common"
|
||||
ethCrypto "github.com/ethereum/go-ethereum/crypto"
|
||||
"github.com/hermeznetwork/hermez-node/common"
|
||||
"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
|
||||
func GenAuths(nAuths int) []*common.AccountCreationAuth {
|
||||
func GenAuths(nAuths int, chainID uint16, hermezContractAddr ethCommon.Address) []*common.AccountCreationAuth {
|
||||
auths := []*common.AccountCreationAuth{}
|
||||
for i := 0; i < nAuths; i++ {
|
||||
// Generate keys
|
||||
@@ -81,7 +82,7 @@ func GenAuths(nAuths int) []*common.AccountCreationAuth {
|
||||
BJJ: bjjPrivK.Public().Compress(),
|
||||
}
|
||||
// Sign
|
||||
h, err := auth.HashToSign()
|
||||
h, err := auth.HashToSign(chainID, hermezContractAddr)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
|
||||
@@ -3,13 +3,17 @@ package test
|
||||
import (
|
||||
"testing"
|
||||
|
||||
ethCommon "github.com/ethereum/go-ethereum/common"
|
||||
"github.com/stretchr/testify/assert"
|
||||
)
|
||||
|
||||
func TestGenAuths(t *testing.T) {
|
||||
chainID := uint16(0)
|
||||
hermezContractAddr := ethCommon.HexToAddress("0xc344E203a046Da13b0B4467EB7B3629D0C99F6E6")
|
||||
|
||||
const nAuths = 5
|
||||
auths := GenAuths(nAuths)
|
||||
auths := GenAuths(nAuths, chainID, hermezContractAddr)
|
||||
for _, auth := range auths {
|
||||
assert.True(t, auth.VerifySignature())
|
||||
assert.True(t, auth.VerifySignature(chainID, hermezContractAddr))
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user