mirror of
https://github.com/arnaucube/hermez-node.git
synced 2026-02-07 03:16:45 +01:00
Merge pull request #437 from hermeznetwork/feature/ethprivkey
Load ethereum private key
This commit is contained in:
@@ -38,7 +38,8 @@ TokenHEZ = "0x5D94e3e7aeC542aB0F9129B9a7BAdeb5B3Ca0f77"
|
||||
TokenHEZName = "Hermez Network Token"
|
||||
|
||||
[Coordinator]
|
||||
ForgerAddress = "0x6BB84Cc84D4A34467aD12a2039A312f7029e2071"
|
||||
# ForgerAddress = "0x05c23b938a85ab26A36E6314a0D02080E9ca6BeD" # Non-Boot Coordinator
|
||||
ForgerAddress = "0xb4124ceb3451635dacedd11767f004d8a28c6ee7" # Boot Coordinator
|
||||
ConfirmBlocks = 10
|
||||
L1BatchTimeoutPerc = 0.6
|
||||
ProofServerPollInterval = "1s"
|
||||
@@ -60,7 +61,7 @@ Path = "/tmp/iden3-test/hermez/txselector"
|
||||
Path = "/tmp/iden3-test/hermez/batchbuilder"
|
||||
|
||||
[[Coordinator.ServerProofs]]
|
||||
URL = "http://localhost:3000"
|
||||
URL = "http://localhost:3000/api"
|
||||
|
||||
[Coordinator.EthClient]
|
||||
CallGasLimit = 300000
|
||||
@@ -73,8 +74,13 @@ CheckLoopInterval = "500ms"
|
||||
Attempts = 8
|
||||
AttemptsDelay = "200ms"
|
||||
|
||||
[Coordinator.EthClient.Keystore]
|
||||
Path = "/tmp/iden3-test/hermez/ethkeystore"
|
||||
Password = "yourpasswordhere"
|
||||
|
||||
[Coordinator.API]
|
||||
Coordinator = true
|
||||
|
||||
[Coordinator.Debug]
|
||||
BatchPath = "/tmp/iden3-test/hermez/batchesdebug"
|
||||
LightScrypt = true
|
||||
|
||||
7
cli/node/load-sk-example.sh
Executable file
7
cli/node/load-sk-example.sh
Executable file
@@ -0,0 +1,7 @@
|
||||
#!/bin/sh
|
||||
|
||||
# Non-Boot Coordinator
|
||||
go run . --mode coord --cfg cfg.buidler.toml importkey --privatekey 0x30f5fddb34cd4166adb2c6003fa6b18f380fd2341376be42cf1c7937004ac7a3
|
||||
|
||||
# Boot Coordinator
|
||||
go run . --mode coord --cfg cfg.buidler.toml importkey --privatekey 0xa8a54b2d8197bc0b19bb8a084031be71835580a01e70a45a13babd16c9bc1563
|
||||
@@ -4,7 +4,10 @@ import (
|
||||
"fmt"
|
||||
"os"
|
||||
"os/signal"
|
||||
"strings"
|
||||
|
||||
ethKeystore "github.com/ethereum/go-ethereum/accounts/keystore"
|
||||
"github.com/ethereum/go-ethereum/crypto"
|
||||
"github.com/hermeznetwork/hermez-node/config"
|
||||
"github.com/hermeznetwork/hermez-node/log"
|
||||
"github.com/hermeznetwork/hermez-node/node"
|
||||
@@ -15,19 +18,42 @@ import (
|
||||
const (
|
||||
flagCfg = "cfg"
|
||||
flagMode = "mode"
|
||||
flagSK = "privatekey"
|
||||
modeSync = "sync"
|
||||
modeCoord = "coord"
|
||||
)
|
||||
|
||||
func cmdInit(c *cli.Context) error {
|
||||
log.Info("Init")
|
||||
cfg, err := parseCli(c)
|
||||
func cmdImportKey(c *cli.Context) error {
|
||||
_cfg, err := parseCli(c)
|
||||
if err != nil {
|
||||
return tracerr.Wrap(fmt.Errorf("error parsing flags and config: %w", err))
|
||||
}
|
||||
if _cfg.mode != node.ModeCoordinator {
|
||||
return tracerr.Wrap(fmt.Errorf("importkey must use mode coordinator"))
|
||||
}
|
||||
cfg := _cfg.node
|
||||
|
||||
scryptN := ethKeystore.StandardScryptN
|
||||
scryptP := ethKeystore.StandardScryptP
|
||||
if cfg.Coordinator.Debug.LightScrypt {
|
||||
scryptN = ethKeystore.LightScryptN
|
||||
scryptP = ethKeystore.LightScryptP
|
||||
}
|
||||
keyStore := ethKeystore.NewKeyStore(cfg.Coordinator.EthClient.Keystore.Path,
|
||||
scryptN, scryptP)
|
||||
hexKey := c.String(flagSK)
|
||||
hexKey = strings.TrimPrefix(hexKey, "0x")
|
||||
sk, err := crypto.HexToECDSA(hexKey)
|
||||
if err != nil {
|
||||
return tracerr.Wrap(err)
|
||||
}
|
||||
fmt.Println("TODO", cfg)
|
||||
acc, err := keyStore.ImportECDSA(sk, cfg.Coordinator.EthClient.Keystore.Password)
|
||||
if err != nil {
|
||||
return tracerr.Wrap(err)
|
||||
}
|
||||
log.Infow("Imported private key", "addr", acc.Address.Hex())
|
||||
return nil
|
||||
}
|
||||
|
||||
func cmdRun(c *cli.Context) error {
|
||||
cfg, err := parseCli(c)
|
||||
@@ -122,10 +148,16 @@ func main() {
|
||||
|
||||
app.Commands = []*cli.Command{
|
||||
{
|
||||
Name: "init",
|
||||
Name: "importkey",
|
||||
Aliases: []string{},
|
||||
Usage: "Initialize the hermez-node",
|
||||
Action: cmdInit,
|
||||
Usage: "Import ethereum private key",
|
||||
Action: cmdImportKey,
|
||||
Flags: []cli.Flag{
|
||||
&cli.StringFlag{
|
||||
Name: flagSK,
|
||||
Usage: "ethereum `PRIVATE_KEY` in hex",
|
||||
Required: true,
|
||||
}},
|
||||
},
|
||||
{
|
||||
Name: "run",
|
||||
|
||||
@@ -83,6 +83,10 @@ type Coordinator struct {
|
||||
// AttemptsDelay is delay between attempts do do an eth client
|
||||
// RPC call
|
||||
AttemptsDelay Duration `validate:"required"`
|
||||
Keystore struct {
|
||||
Path string `validate:"required"`
|
||||
Password string `validate:"required"`
|
||||
} `validate:"required"`
|
||||
} `validate:"required"`
|
||||
API struct {
|
||||
Coordinator bool
|
||||
@@ -91,6 +95,9 @@ type Coordinator struct {
|
||||
// BatchPath if set, specifies the path where batchInfo is stored
|
||||
// in JSON in every step/update of the pipeline
|
||||
BatchPath string
|
||||
// LightScrypt if set, uses light parameters for the ethereum
|
||||
// keystore encryption algorithm.
|
||||
LightScrypt bool
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -4,6 +4,7 @@ import (
|
||||
"context"
|
||||
"fmt"
|
||||
"math/big"
|
||||
"os"
|
||||
"strings"
|
||||
"sync"
|
||||
"time"
|
||||
@@ -111,6 +112,12 @@ func NewCoordinator(cfg Config,
|
||||
cfg.EthClientAttempts))
|
||||
}
|
||||
|
||||
if cfg.DebugBatchPath != "" {
|
||||
if err := os.MkdirAll(cfg.DebugBatchPath, 0744); err != nil {
|
||||
return nil, tracerr.Wrap(err)
|
||||
}
|
||||
}
|
||||
|
||||
purger := Purger{
|
||||
cfg: cfg.Purger,
|
||||
lastPurgeBlock: 0,
|
||||
@@ -147,9 +154,10 @@ func NewCoordinator(cfg Config,
|
||||
return &c, nil
|
||||
}
|
||||
|
||||
func (c *Coordinator) newPipeline(ctx context.Context) (*Pipeline, error) {
|
||||
func (c *Coordinator) newPipeline(ctx context.Context,
|
||||
stats *synchronizer.Stats) (*Pipeline, error) {
|
||||
return NewPipeline(ctx, c.cfg, c.historyDB, c.l2DB, c.txSelector,
|
||||
c.batchBuilder, c.purger, c.txManager, c.provers, &c.consts)
|
||||
c.batchBuilder, c.purger, c.txManager, c.provers, stats, &c.consts)
|
||||
}
|
||||
|
||||
// MsgSyncBlock indicates an update to the Synchronizer stats
|
||||
@@ -226,7 +234,7 @@ func (c *Coordinator) syncStats(ctx context.Context, stats *synchronizer.Stats)
|
||||
stats.Eth.LastBlock.Num, "batch", stats.Sync.LastBatch)
|
||||
batchNum := common.BatchNum(stats.Sync.LastBatch)
|
||||
var err error
|
||||
if c.pipeline, err = c.newPipeline(ctx); err != nil {
|
||||
if c.pipeline, err = c.newPipeline(ctx, stats); err != nil {
|
||||
return tracerr.Wrap(err)
|
||||
}
|
||||
if err := c.pipeline.Start(batchNum, stats.Sync.LastForgeL1TxsNum,
|
||||
@@ -295,22 +303,16 @@ func (c *Coordinator) handleStopPipeline(ctx context.Context, reason string) err
|
||||
func (c *Coordinator) handleMsg(ctx context.Context, msg interface{}) error {
|
||||
switch msg := msg.(type) {
|
||||
case MsgSyncBlock:
|
||||
if err := c.handleMsgSyncBlock(ctx, &msg); common.IsErrDone(err) {
|
||||
return nil
|
||||
} else if err != nil {
|
||||
if err := c.handleMsgSyncBlock(ctx, &msg); err != nil {
|
||||
return tracerr.Wrap(fmt.Errorf("Coordinator.handleMsgSyncBlock error: %w", err))
|
||||
}
|
||||
case MsgSyncReorg:
|
||||
if err := c.handleReorg(ctx, &msg.Stats); common.IsErrDone(err) {
|
||||
return nil
|
||||
} else if err != nil {
|
||||
if err := c.handleReorg(ctx, &msg.Stats); err != nil {
|
||||
return tracerr.Wrap(fmt.Errorf("Coordinator.handleReorg error: %w", err))
|
||||
}
|
||||
case MsgStopPipeline:
|
||||
log.Infow("Coordinator received MsgStopPipeline", "reason", msg.Reason)
|
||||
if err := c.handleStopPipeline(ctx, msg.Reason); common.IsErrDone(err) {
|
||||
return nil
|
||||
} else if err != nil {
|
||||
if err := c.handleStopPipeline(ctx, msg.Reason); err != nil {
|
||||
return tracerr.Wrap(fmt.Errorf("Coordinator.handleStopPipeline: %w", err))
|
||||
}
|
||||
default:
|
||||
@@ -341,7 +343,9 @@ func (c *Coordinator) Start() {
|
||||
c.wg.Done()
|
||||
return
|
||||
case msg := <-c.msgCh:
|
||||
if err := c.handleMsg(c.ctx, msg); err != nil {
|
||||
if err := c.handleMsg(c.ctx, msg); c.ctx.Err() != nil {
|
||||
continue
|
||||
} else if err != nil {
|
||||
log.Errorw("Coordinator.handleMsg", "err", err)
|
||||
waitDuration = time.Duration(c.cfg.SyncRetryInterval)
|
||||
continue
|
||||
@@ -352,7 +356,9 @@ func (c *Coordinator) Start() {
|
||||
waitDuration = time.Duration(longWaitDuration)
|
||||
continue
|
||||
}
|
||||
if err := c.syncStats(c.ctx, c.stats); err != nil {
|
||||
if err := c.syncStats(c.ctx, c.stats); c.ctx.Err() != nil {
|
||||
continue
|
||||
} else if err != nil {
|
||||
log.Errorw("Coordinator.syncStats", "err", err)
|
||||
waitDuration = time.Duration(c.cfg.SyncRetryInterval)
|
||||
continue
|
||||
@@ -456,7 +462,8 @@ func (t *TxManager) rollupForgeBatch(ctx context.Context, batchInfo *BatchInfo)
|
||||
return tracerr.Wrap(err)
|
||||
}
|
||||
log.Errorw("TxManager ethClient.RollupForgeBatch",
|
||||
"attempt", attempt, "err", err, "block", t.lastBlock)
|
||||
"attempt", attempt, "err", err, "block", t.lastBlock,
|
||||
"batchNum", batchInfo.BatchNum)
|
||||
} else {
|
||||
break
|
||||
}
|
||||
@@ -484,6 +491,9 @@ func (t *TxManager) ethTransactionReceipt(ctx context.Context, batchInfo *BatchI
|
||||
var err error
|
||||
for attempt := 0; attempt < t.cfg.EthClientAttempts; attempt++ {
|
||||
receipt, err = t.ethClient.EthTransactionReceipt(ctx, txHash)
|
||||
if ctx.Err() != nil {
|
||||
continue
|
||||
}
|
||||
if err != nil {
|
||||
log.Errorw("TxManager ethClient.EthTransactionReceipt",
|
||||
"attempt", attempt, "err", err)
|
||||
@@ -621,6 +631,7 @@ func NewPipeline(ctx context.Context,
|
||||
purger *Purger,
|
||||
txManager *TxManager,
|
||||
provers []prover.Client,
|
||||
stats *synchronizer.Stats,
|
||||
scConsts *synchronizer.SCConsts,
|
||||
) (*Pipeline, error) {
|
||||
proversPool := NewProversPool(len(provers))
|
||||
@@ -647,6 +658,7 @@ func NewPipeline(ctx context.Context,
|
||||
purger: purger,
|
||||
txManager: txManager,
|
||||
consts: *scConsts,
|
||||
stats: *stats,
|
||||
statsCh: make(chan synchronizer.Stats, queueLen),
|
||||
}, nil
|
||||
}
|
||||
@@ -697,7 +709,7 @@ func (p *Pipeline) Start(batchNum common.BatchNum, lastForgeL1TxsNum int64,
|
||||
for {
|
||||
select {
|
||||
case <-p.ctx.Done():
|
||||
log.Debug("Pipeline forgeBatch loop done")
|
||||
log.Info("Pipeline forgeBatch loop done")
|
||||
p.wg.Done()
|
||||
return
|
||||
case syncStats := <-p.statsCh:
|
||||
@@ -705,7 +717,7 @@ func (p *Pipeline) Start(batchNum common.BatchNum, lastForgeL1TxsNum int64,
|
||||
default:
|
||||
batchNum = p.batchNum + 1
|
||||
batchInfo, err := p.forgeBatch(p.ctx, batchNum, selectionConfig)
|
||||
if common.IsErrDone(err) {
|
||||
if p.ctx.Err() != nil {
|
||||
continue
|
||||
} else if err != nil {
|
||||
log.Errorw("forgeBatch", "err", err)
|
||||
@@ -713,14 +725,16 @@ func (p *Pipeline) Start(batchNum common.BatchNum, lastForgeL1TxsNum int64,
|
||||
}
|
||||
// 6. Wait for an available server proof (blocking call)
|
||||
serverProof, err := p.proversPool.Get(p.ctx)
|
||||
if common.IsErrDone(err) {
|
||||
if p.ctx.Err() != nil {
|
||||
continue
|
||||
} else if err != nil {
|
||||
log.Errorw("proversPool.Get", "err", err)
|
||||
continue
|
||||
}
|
||||
batchInfo.ServerProof = serverProof
|
||||
if err := p.sendServerProof(p.ctx, batchInfo); err != nil {
|
||||
if err := p.sendServerProof(p.ctx, batchInfo); p.ctx.Err() != nil {
|
||||
continue
|
||||
} else if err != nil {
|
||||
log.Errorw("sendServerProof", "err", err)
|
||||
batchInfo.ServerProof = nil
|
||||
p.proversPool.Add(serverProof)
|
||||
@@ -737,17 +751,17 @@ func (p *Pipeline) Start(batchNum common.BatchNum, lastForgeL1TxsNum int64,
|
||||
for {
|
||||
select {
|
||||
case <-p.ctx.Done():
|
||||
log.Debug("Pipeline waitServerProofSendEth loop done")
|
||||
log.Info("Pipeline waitServerProofSendEth loop done")
|
||||
p.wg.Done()
|
||||
return
|
||||
case batchInfo := <-batchChSentServerProof:
|
||||
err := p.waitServerProof(p.ctx, batchInfo)
|
||||
if common.IsErrDone(err) {
|
||||
continue
|
||||
}
|
||||
// We are done with this serverProof, add it back to the pool
|
||||
p.proversPool.Add(batchInfo.ServerProof)
|
||||
batchInfo.ServerProof = nil
|
||||
if p.ctx.Err() != nil {
|
||||
continue
|
||||
}
|
||||
if err != nil {
|
||||
log.Errorw("waitServerProof", "err", err)
|
||||
continue
|
||||
@@ -765,7 +779,7 @@ func (p *Pipeline) Stop(ctx context.Context) {
|
||||
log.Fatal("Pipeline already stopped")
|
||||
}
|
||||
p.started = false
|
||||
log.Debug("Stopping Pipeline...")
|
||||
log.Info("Stopping Pipeline...")
|
||||
p.cancel()
|
||||
p.wg.Wait()
|
||||
for _, prover := range p.provers {
|
||||
@@ -899,7 +913,7 @@ func (p *Pipeline) waitServerProof(ctx context.Context, batchInfo *BatchInfo) er
|
||||
}
|
||||
batchInfo.Proof = proof
|
||||
batchInfo.PublicInputs = pubInputs
|
||||
batchInfo.ForgeBatchArgs = p.prepareForgeBatchArgs(batchInfo)
|
||||
batchInfo.ForgeBatchArgs = prepareForgeBatchArgs(batchInfo)
|
||||
batchInfo.TxStatus = TxStatusPending
|
||||
p.cfg.debugBatchStore(batchInfo)
|
||||
return nil
|
||||
@@ -921,7 +935,7 @@ func (p *Pipeline) shouldL1L2Batch() bool {
|
||||
return false
|
||||
}
|
||||
|
||||
func (p *Pipeline) prepareForgeBatchArgs(batchInfo *BatchInfo) *eth.RollupForgeBatchArgs {
|
||||
func prepareForgeBatchArgs(batchInfo *BatchInfo) *eth.RollupForgeBatchArgs {
|
||||
proof := batchInfo.Proof
|
||||
zki := batchInfo.ZKInputs
|
||||
return ð.RollupForgeBatchArgs{
|
||||
|
||||
@@ -10,7 +10,10 @@ import (
|
||||
"testing"
|
||||
"time"
|
||||
|
||||
ethKeystore "github.com/ethereum/go-ethereum/accounts/keystore"
|
||||
ethCommon "github.com/ethereum/go-ethereum/common"
|
||||
"github.com/ethereum/go-ethereum/crypto"
|
||||
"github.com/ethereum/go-ethereum/ethclient"
|
||||
"github.com/hermeznetwork/hermez-node/batchbuilder"
|
||||
"github.com/hermeznetwork/hermez-node/common"
|
||||
dbUtils "github.com/hermeznetwork/hermez-node/db"
|
||||
@@ -26,6 +29,7 @@ import (
|
||||
"github.com/hermeznetwork/hermez-node/txprocessor"
|
||||
"github.com/hermeznetwork/hermez-node/txselector"
|
||||
"github.com/hermeznetwork/tracerr"
|
||||
"github.com/iden3/go-merkletree"
|
||||
"github.com/iden3/go-merkletree/db/pebble"
|
||||
"github.com/stretchr/testify/assert"
|
||||
"github.com/stretchr/testify/require"
|
||||
@@ -428,8 +432,9 @@ func TestPipelineShouldL1L2Batch(t *testing.T) {
|
||||
ctx := context.Background()
|
||||
ethClient := test.NewClient(true, &timer, &bidder, ethClientSetup)
|
||||
modules := newTestModules(t)
|
||||
var stats synchronizer.Stats
|
||||
coord := newTestCoordinator(t, forger, ethClient, ethClientSetup, modules)
|
||||
pipeline, err := coord.newPipeline(ctx)
|
||||
pipeline, err := coord.newPipeline(ctx, &stats)
|
||||
require.NoError(t, err)
|
||||
pipeline.vars = coord.vars
|
||||
|
||||
@@ -439,8 +444,6 @@ func TestPipelineShouldL1L2Batch(t *testing.T) {
|
||||
l1BatchTimeoutPerc := pipeline.cfg.L1BatchTimeoutPerc
|
||||
l1BatchTimeout := ethClientSetup.RollupVariables.ForgeL1L2BatchTimeout
|
||||
|
||||
var stats synchronizer.Stats
|
||||
|
||||
startBlock := int64(100)
|
||||
|
||||
//
|
||||
@@ -576,11 +579,6 @@ func TestPipeline1(t *testing.T) {
|
||||
modules := newTestModules(t)
|
||||
coord := newTestCoordinator(t, forger, ethClient, ethClientSetup, modules)
|
||||
sync := newTestSynchronizer(t, ethClient, ethClientSetup, modules)
|
||||
pipeline, err := coord.newPipeline(ctx)
|
||||
require.NoError(t, err)
|
||||
|
||||
require.NotNil(t, sync)
|
||||
require.NotNil(t, pipeline)
|
||||
|
||||
// preload the synchronier (via the test ethClient) some tokens and
|
||||
// users with positive balances
|
||||
@@ -589,6 +587,9 @@ func TestPipeline1(t *testing.T) {
|
||||
batchNum := common.BatchNum(syncStats.Sync.LastBatch)
|
||||
syncSCVars := sync.SCVars()
|
||||
|
||||
pipeline, err := coord.newPipeline(ctx, syncStats)
|
||||
require.NoError(t, err)
|
||||
|
||||
// Insert some l2txs in the Pool
|
||||
setPool := `
|
||||
Type: PoolL2
|
||||
@@ -713,6 +714,80 @@ func TestCoordinatorStress(t *testing.T) {
|
||||
coord.Stop()
|
||||
}
|
||||
|
||||
func TestRollupForgeBatch(t *testing.T) {
|
||||
if os.Getenv("TEST_ROLLUP_FORGE_BATCH") == "" {
|
||||
return
|
||||
}
|
||||
const web3URL = "http://localhost:8545"
|
||||
const password = "test"
|
||||
addr := ethCommon.HexToAddress("0xb4124ceb3451635dacedd11767f004d8a28c6ee7")
|
||||
sk, err := crypto.HexToECDSA(
|
||||
"a8a54b2d8197bc0b19bb8a084031be71835580a01e70a45a13babd16c9bc1563")
|
||||
require.NoError(t, err)
|
||||
rollupAddr := ethCommon.HexToAddress("0x8EEaea23686c319133a7cC110b840d1591d9AeE0")
|
||||
pathKeystore, err := ioutil.TempDir("", "tmpKeystore")
|
||||
require.NoError(t, err)
|
||||
deleteme = append(deleteme, pathKeystore)
|
||||
ctx := context.Background()
|
||||
batchInfo := &BatchInfo{}
|
||||
proofClient := &prover.MockClient{}
|
||||
chainID := uint16(0)
|
||||
|
||||
ethClient, err := ethclient.Dial(web3URL)
|
||||
require.NoError(t, err)
|
||||
ethCfg := eth.EthereumConfig{
|
||||
CallGasLimit: 300000,
|
||||
DeployGasLimit: 1000000,
|
||||
GasPriceDiv: 100,
|
||||
ReceiptTimeout: 60 * time.Second,
|
||||
IntervalReceiptLoop: 500 * time.Millisecond,
|
||||
}
|
||||
scryptN := ethKeystore.LightScryptN
|
||||
scryptP := ethKeystore.LightScryptP
|
||||
keyStore := ethKeystore.NewKeyStore(pathKeystore,
|
||||
scryptN, scryptP)
|
||||
account, err := keyStore.ImportECDSA(sk, password)
|
||||
require.NoError(t, err)
|
||||
require.Equal(t, account.Address, addr)
|
||||
err = keyStore.Unlock(account, password)
|
||||
require.NoError(t, err)
|
||||
|
||||
client, err := eth.NewClient(ethClient, &account, keyStore, ð.ClientConfig{
|
||||
Ethereum: ethCfg,
|
||||
Rollup: eth.RollupConfig{
|
||||
Address: rollupAddr,
|
||||
},
|
||||
Auction: eth.AuctionConfig{
|
||||
Address: ethCommon.Address{},
|
||||
TokenHEZ: eth.TokenConfig{
|
||||
Address: ethCommon.Address{},
|
||||
Name: "HEZ",
|
||||
},
|
||||
},
|
||||
WDelayer: eth.WDelayerConfig{
|
||||
Address: ethCommon.Address{},
|
||||
},
|
||||
})
|
||||
require.NoError(t, err)
|
||||
|
||||
zkInputs := common.NewZKInputs(chainID, 100, 24, 512, 32, big.NewInt(1))
|
||||
zkInputs.Metadata.NewStateRootRaw = &merkletree.Hash{1}
|
||||
zkInputs.Metadata.NewExitRootRaw = &merkletree.Hash{2}
|
||||
batchInfo.ZKInputs = zkInputs
|
||||
err = proofClient.CalculateProof(ctx, batchInfo.ZKInputs)
|
||||
require.NoError(t, err)
|
||||
|
||||
proof, pubInputs, err := proofClient.GetProof(ctx)
|
||||
require.NoError(t, err)
|
||||
batchInfo.Proof = proof
|
||||
batchInfo.PublicInputs = pubInputs
|
||||
|
||||
batchInfo.ForgeBatchArgs = prepareForgeBatchArgs(batchInfo)
|
||||
_, err = client.RollupForgeBatch(batchInfo.ForgeBatchArgs)
|
||||
require.NoError(t, err)
|
||||
batchInfo.Proof = proof
|
||||
}
|
||||
|
||||
// TODO: Test Reorg
|
||||
// TODO: Test Pipeline
|
||||
// TODO: Test TxMonitor
|
||||
|
||||
@@ -112,6 +112,10 @@ func TestNewStateDBIntermediateState(t *testing.T) {
|
||||
sdb, err = NewStateDB(dir, 128, TypeTxSelector, 0)
|
||||
assert.NoError(t, err)
|
||||
|
||||
bn, err = sdb.db.GetCurrentBatch()
|
||||
assert.NoError(t, err)
|
||||
assert.Equal(t, common.BatchNum(1), bn)
|
||||
|
||||
v, err = sdb.db.DB().Get(k0)
|
||||
assert.NoError(t, err)
|
||||
assert.Equal(t, v0, v)
|
||||
|
||||
@@ -65,7 +65,10 @@ type ClientConfig struct {
|
||||
|
||||
// NewClient creates a new Client to interact with Ethereum and the Hermez smart contracts.
|
||||
func NewClient(client *ethclient.Client, account *accounts.Account, ks *ethKeystore.KeyStore, cfg *ClientConfig) (*Client, error) {
|
||||
ethereumClient := NewEthereumClient(client, account, ks, &cfg.Ethereum)
|
||||
ethereumClient, err := NewEthereumClient(client, account, ks, &cfg.Ethereum)
|
||||
if err != nil {
|
||||
return nil, tracerr.Wrap(err)
|
||||
}
|
||||
auctionClient, err := NewAuctionClient(ethereumClient, cfg.Auction.Address, cfg.Auction.TokenHEZ)
|
||||
if err != nil {
|
||||
return nil, tracerr.Wrap(err)
|
||||
|
||||
@@ -73,6 +73,7 @@ type EthereumConfig struct {
|
||||
// EthereumClient is an ethereum client to call Smart Contract methods and check blockchain information.
|
||||
type EthereumClient struct {
|
||||
client *ethclient.Client
|
||||
chainID *big.Int
|
||||
account *accounts.Account
|
||||
ks *ethKeystore.KeyStore
|
||||
ReceiptTimeout time.Duration
|
||||
@@ -82,7 +83,7 @@ type EthereumClient struct {
|
||||
|
||||
// NewEthereumClient creates a EthereumClient instance. The account is not mandatory (it can
|
||||
// be nil). If the account is nil, CallAuth will fail with ErrAccountNil.
|
||||
func NewEthereumClient(client *ethclient.Client, account *accounts.Account, ks *ethKeystore.KeyStore, config *EthereumConfig) *EthereumClient {
|
||||
func NewEthereumClient(client *ethclient.Client, account *accounts.Account, ks *ethKeystore.KeyStore, config *EthereumConfig) (*EthereumClient, error) {
|
||||
if config == nil {
|
||||
config = &EthereumConfig{
|
||||
CallGasLimit: defaultCallGasLimit,
|
||||
@@ -92,7 +93,7 @@ func NewEthereumClient(client *ethclient.Client, account *accounts.Account, ks *
|
||||
IntervalReceiptLoop: defaultIntervalReceiptLoop,
|
||||
}
|
||||
}
|
||||
return &EthereumClient{
|
||||
c := &EthereumClient{
|
||||
client: client,
|
||||
account: account,
|
||||
ks: ks,
|
||||
@@ -100,6 +101,12 @@ func NewEthereumClient(client *ethclient.Client, account *accounts.Account, ks *
|
||||
config: config,
|
||||
opts: newCallOpts(),
|
||||
}
|
||||
chainID, err := c.EthChainID()
|
||||
if err != nil {
|
||||
return nil, tracerr.Wrap(err)
|
||||
}
|
||||
c.chainID = chainID
|
||||
return c, nil
|
||||
}
|
||||
|
||||
// EthChainID returns the ChainID of the ethereum network
|
||||
@@ -147,8 +154,7 @@ func (c *EthereumClient) CallAuth(gasLimit uint64,
|
||||
gasPrice.Add(gasPrice, inc)
|
||||
log.Debugw("Transaction metadata", "gasPrice", gasPrice)
|
||||
|
||||
// TODO: Set the correct chainID
|
||||
auth, err := bind.NewKeyStoreTransactorWithChainID(c.ks, *c.account, big.NewInt(0))
|
||||
auth, err := bind.NewKeyStoreTransactorWithChainID(c.ks, *c.account, c.chainID)
|
||||
if err != nil {
|
||||
return nil, tracerr.Wrap(err)
|
||||
}
|
||||
|
||||
@@ -11,7 +11,8 @@ import (
|
||||
func TestEthERC20(t *testing.T) {
|
||||
ethClient, err := ethclient.Dial(ethClientDialURL)
|
||||
require.Nil(t, err)
|
||||
client := NewEthereumClient(ethClient, auxAccount, ks, nil)
|
||||
client, err := NewEthereumClient(ethClient, auxAccount, ks, nil)
|
||||
require.Nil(t, err)
|
||||
|
||||
consts, err := client.EthERC20Consts(tokenHEZAddressConst)
|
||||
require.Nil(t, err)
|
||||
|
||||
@@ -164,7 +164,10 @@ func TestMain(m *testing.M) {
|
||||
}
|
||||
|
||||
// Controllable Governance Address
|
||||
ethereumClientGov := NewEthereumClient(ethClient, governanceAccount, ks, nil)
|
||||
ethereumClientGov, err := NewEthereumClient(ethClient, governanceAccount, ks, nil)
|
||||
if err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
auctionClient, err = NewAuctionClient(ethereumClientGov, auctionAddressConst, tokenHEZ)
|
||||
if err != nil {
|
||||
log.Fatal(err)
|
||||
@@ -186,10 +189,22 @@ func TestMain(m *testing.M) {
|
||||
log.Fatal(err)
|
||||
}
|
||||
|
||||
ethereumClientEmergencyCouncil = NewEthereumClient(ethClient, emergencyCouncilAccount, ks, nil)
|
||||
ethereumClientAux = NewEthereumClient(ethClient, auxAccount, ks, nil)
|
||||
ethereumClientAux2 = NewEthereumClient(ethClient, aux2Account, ks, nil)
|
||||
ethereumClientHermez = NewEthereumClient(ethClient, hermezRollupTestAccount, ks, nil)
|
||||
ethereumClientEmergencyCouncil, err = NewEthereumClient(ethClient, emergencyCouncilAccount, ks, nil)
|
||||
if err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
ethereumClientAux, err = NewEthereumClient(ethClient, auxAccount, ks, nil)
|
||||
if err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
ethereumClientAux2, err = NewEthereumClient(ethClient, aux2Account, ks, nil)
|
||||
if err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
ethereumClientHermez, err = NewEthereumClient(ethClient, hermezRollupTestAccount, ks, nil)
|
||||
if err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
|
||||
exitVal = m.Run()
|
||||
}
|
||||
|
||||
29
node/node.go
29
node/node.go
@@ -7,6 +7,8 @@ import (
|
||||
"sync"
|
||||
"time"
|
||||
|
||||
"github.com/ethereum/go-ethereum/accounts"
|
||||
ethKeystore "github.com/ethereum/go-ethereum/accounts/keystore"
|
||||
ethCommon "github.com/ethereum/go-ethereum/common"
|
||||
"github.com/ethereum/go-ethereum/ethclient"
|
||||
"github.com/gin-contrib/cors"
|
||||
@@ -87,6 +89,8 @@ func NewNode(mode Mode, cfg *config.Node) (*Node, error) {
|
||||
return nil, tracerr.Wrap(err)
|
||||
}
|
||||
var ethCfg eth.EthereumConfig
|
||||
var account *accounts.Account
|
||||
var keyStore *ethKeystore.KeyStore
|
||||
if mode == ModeCoordinator {
|
||||
ethCfg = eth.EthereumConfig{
|
||||
CallGasLimit: cfg.Coordinator.EthClient.CallGasLimit,
|
||||
@@ -95,8 +99,31 @@ func NewNode(mode Mode, cfg *config.Node) (*Node, error) {
|
||||
ReceiptTimeout: cfg.Coordinator.EthClient.ReceiptTimeout.Duration,
|
||||
IntervalReceiptLoop: cfg.Coordinator.EthClient.ReceiptLoopInterval.Duration,
|
||||
}
|
||||
|
||||
scryptN := ethKeystore.StandardScryptN
|
||||
scryptP := ethKeystore.StandardScryptP
|
||||
if cfg.Coordinator.Debug.LightScrypt {
|
||||
scryptN = ethKeystore.LightScryptN
|
||||
scryptP = ethKeystore.LightScryptP
|
||||
}
|
||||
client, err := eth.NewClient(ethClient, nil, nil, ð.ClientConfig{
|
||||
keyStore = ethKeystore.NewKeyStore(cfg.Coordinator.EthClient.Keystore.Path,
|
||||
scryptN, scryptP)
|
||||
if !keyStore.HasAddress(cfg.Coordinator.ForgerAddress) {
|
||||
return nil, tracerr.Wrap(fmt.Errorf(
|
||||
"ethereum keystore doesn't have the key for address %v",
|
||||
cfg.Coordinator.ForgerAddress))
|
||||
}
|
||||
account = &accounts.Account{
|
||||
Address: cfg.Coordinator.ForgerAddress,
|
||||
}
|
||||
if err := keyStore.Unlock(*account,
|
||||
cfg.Coordinator.EthClient.Keystore.Password); err != nil {
|
||||
return nil, tracerr.Wrap(err)
|
||||
}
|
||||
log.Infow("Forger ethereum account unlocked in the keystore",
|
||||
"addr", cfg.Coordinator.ForgerAddress)
|
||||
}
|
||||
client, err := eth.NewClient(ethClient, account, keyStore, ð.ClientConfig{
|
||||
Ethereum: ethCfg,
|
||||
Rollup: eth.RollupConfig{
|
||||
Address: cfg.SmartContracts.Rollup,
|
||||
|
||||
Reference in New Issue
Block a user