Skip to content

Commit

Permalink
Pass signer key to rootchain.SendTxn function
Browse files Browse the repository at this point in the history
  • Loading branch information
Stefan-Ethernal committed Nov 23, 2022
1 parent 593d3f7 commit ce656f0
Show file tree
Hide file tree
Showing 9 changed files with 63 additions and 38 deletions.
4 changes: 2 additions & 2 deletions command/rootchain/emit/emit.go
Original file line number Diff line number Diff line change
Expand Up @@ -76,7 +76,7 @@ func runCommand(cmd *cobra.Command, _ []string) {
return
}

pendingNonce, err := helper.GetPendingNonce(helper.GetDefAccount())
pendingNonce, err := helper.GetPendingNonce(helper.GetRootchainAdminAddr())
if err != nil {
outputter.SetError(fmt.Errorf("could not get pending nonce: %w", err))

Expand All @@ -100,7 +100,7 @@ func runCommand(cmd *cobra.Command, _ []string) {
return fmt.Errorf("failed to create tx input: %w", err)
}

if _, err = helper.SendTxn(pendingNonce+walletIndex, txn); err != nil {
if _, err = helper.SendTxn(pendingNonce+walletIndex, txn, helper.GetRootchainAdminKey()); err != nil {
return fmt.Errorf("sending transaction to wallet: %s with amount: %s, failed with error: %w", wallet, amount, err)
}

Expand Down
16 changes: 10 additions & 6 deletions command/rootchain/helper/txn.go
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ const (
var (
// use a deterministic wallet/private key so that the address of the deployed contracts
// are deterministic
defKey *wallet.Key
rootchainAdminKey *wallet.Key

jrpcClientLock sync.Mutex
jsonRPCClient *jsonrpc.Client
Expand All @@ -34,19 +34,23 @@ func init() {
panic(err)
}

defKey, err = wallet.NewWalletFromPrivKey(dec)
rootchainAdminKey, err = wallet.NewWalletFromPrivKey(dec)
if err != nil {
panic(err)
}
}

func GetDefAccount() types.Address {
return types.BytesToAddress(defKey.Address().Bytes())
func GetRootchainAdminAddr() types.Address {
return types.Address(rootchainAdminKey.Address())
}

func GetRootchainAdminKey() ethgo.Key {
return rootchainAdminKey
}

// SendTxn function sends transaction to the rootchain
// blocks until receipt hash is returned
func SendTxn(nonce uint64, txn *ethgo.Transaction) (*ethgo.Receipt, error) {
func SendTxn(nonce uint64, txn *ethgo.Transaction, key ethgo.Key) (*ethgo.Receipt, error) {
provider, err := getJSONRPCClient()
if err != nil {
return nil, err
Expand All @@ -62,7 +66,7 @@ func SendTxn(nonce uint64, txn *ethgo.Transaction) (*ethgo.Receipt, error) {
}

signer := wallet.NewEIP155Signer(chainID.Uint64())
if txn, err = signer.SignTx(txn, defKey); err != nil {
if txn, err = signer.SignTx(txn, key); err != nil {
return nil, err
}

Expand Down
8 changes: 4 additions & 4 deletions command/rootchain/initcontracts/init_contracts.go
Original file line number Diff line number Diff line change
Expand Up @@ -116,7 +116,7 @@ func runCommand(cmd *cobra.Command, _ []string) {
func deployContracts(outputter command.OutputFormatter) error {
// if the bridge contract is not created, we have to deploy all the contracts
// fund account
if _, err := helper.FundAccount(helper.GetDefAccount()); err != nil {
if _, err := helper.FundAccount(helper.GetRootchainAdminAddr()); err != nil {
return err
}

Expand Down Expand Up @@ -147,7 +147,7 @@ func deployContracts(outputter command.OutputFormatter) error {
},
}

pendingNonce, err := helper.GetPendingNonce(helper.GetDefAccount())
pendingNonce, err := helper.GetPendingNonce(helper.GetRootchainAdminAddr())
if err != nil {
return err
}
Expand All @@ -163,7 +163,7 @@ func deployContracts(outputter command.OutputFormatter) error {
Input: bytecode,
}

receipt, err := helper.SendTxn(pendingNonce+uint64(i), txn)
receipt, err := helper.SendTxn(pendingNonce+uint64(i), txn, helper.GetRootchainAdminKey())
if err != nil {
return err
}
Expand Down Expand Up @@ -211,7 +211,7 @@ func initializeCheckpointManager(nonce uint64) error {
Input: initCheckpointInput,
}

receipt, err := helper.SendTxn(nonce, txn)
receipt, err := helper.SendTxn(nonce, txn, helper.GetRootchainAdminKey())
if err != nil {
return fmt.Errorf("failed to send transaction to CheckpointManager. error: %w", err)
}
Expand Down
34 changes: 19 additions & 15 deletions consensus/polybft/checkpoint_manager.go
Original file line number Diff line number Diff line change
Expand Up @@ -34,8 +34,10 @@ var (

// checkpointManager encapsulates logic for checkpoint data submission
type checkpointManager struct {
// sender address
sender types.Address
// signer is the identity of the node submitting a checkpoint
signer ethgo.Key
// signerAddress is the address of the node submitting a checkpoint
signerAddress types.Address
// blockchain is abstraction for blockchain
blockchain blockchainBackend
// consensusBackend is abstraction for polybft consensus specific functions
Expand All @@ -51,15 +53,16 @@ type checkpointManager struct {
}

// newCheckpointManager creates a new instance of checkpointManager
func newCheckpointManager(sender types.Address, checkpointOffset uint64, interactor rootchainInteractor,
func newCheckpointManager(signer ethgo.Key, checkpointOffset uint64, interactor rootchainInteractor,
blockchain blockchainBackend, backend polybftBackend) *checkpointManager {
r := interactor
if interactor == nil {
r = &defaultRootchainInteractor{}
}

return &checkpointManager{
sender: sender,
signer: signer,
signerAddress: types.Address(signer.Address()),
blockchain: blockchain,
consensusBackend: backend,
rootchain: r,
Expand All @@ -74,7 +77,10 @@ func (c checkpointManager) getLatestCheckpointBlock() (uint64, error) {
return 0, fmt.Errorf("failed to encode currentCheckpointId function parameters: %w", err)
}

latestCheckpointBlockRaw, err := c.rootchain.Call(c.sender, helper.CheckpointManagerAddress, checkpointIDMethodEncoded)
latestCheckpointBlockRaw, err := c.rootchain.Call(
c.signerAddress,
helper.CheckpointManagerAddress,
checkpointIDMethodEncoded)
if err != nil {
return 0, fmt.Errorf("failed to invoke currentCheckpointId function on the rootchain: %w", err)
}
Expand All @@ -99,17 +105,16 @@ func (c checkpointManager) submitCheckpoint(latestHeader types.Header, isEndOfEp
return err
}

nonce, err := c.rootchain.GetPendingNonce(c.sender)
nonce, err := c.rootchain.GetPendingNonce(c.signerAddress)
if err != nil {
return err
}

checkpointManagerAddr := ethgo.Address(helper.CheckpointManagerAddress)
txn := &ethgo.Transaction{
To: &checkpointManagerAddr,
From: ethgo.Address(c.sender),
From: ethgo.Address(c.signerAddress),
}

initialBlockNumber := lastCheckpointBlockNumber + 1

var (
Expand Down Expand Up @@ -153,8 +158,7 @@ func (c checkpointManager) submitCheckpoint(latestHeader types.Header, isEndOfEp
continue
}

err = c.encodeAndSendCheckpoint(nonce, txn, *parentHeader, *parentExtra, true)
if err != nil {
if err = c.encodeAndSendCheckpoint(nonce, txn, *parentHeader, *parentExtra, true); err != nil {
return err
}
nonce++
Expand All @@ -166,7 +170,7 @@ func (c checkpointManager) submitCheckpoint(latestHeader types.Header, isEndOfEp
return err
}

return c.encodeAndSendCheckpoint(nonce+1, txn, latestHeader, *extra, isEndOfEpoch)
return c.encodeAndSendCheckpoint(nonce, txn, latestHeader, *extra, isEndOfEpoch)
}

// encodeAndSendCheckpoint encodes checkpoint data for the given block and
Expand All @@ -193,7 +197,7 @@ func (c *checkpointManager) encodeAndSendCheckpoint(nonce uint64, txn *ethgo.Tra

c.logger.Info("sending checkpoint tx...", "nonce", nonce)

receipt, err := c.rootchain.SendTransaction(nonce, txn)
receipt, err := c.rootchain.SendTransaction(nonce, txn, c.signer)
if err != nil {
return err
}
Expand Down Expand Up @@ -251,7 +255,7 @@ var _ rootchainInteractor = (*defaultRootchainInteractor)(nil)

type rootchainInteractor interface {
Call(from types.Address, to types.Address, input []byte) (string, error)
SendTransaction(nonce uint64, transaction *ethgo.Transaction) (*ethgo.Receipt, error)
SendTransaction(nonce uint64, transaction *ethgo.Transaction, signer ethgo.Key) (*ethgo.Receipt, error)
GetPendingNonce(address types.Address) (uint64, error)
}

Expand All @@ -263,8 +267,8 @@ func (d *defaultRootchainInteractor) Call(from types.Address, to types.Address,
}

func (d *defaultRootchainInteractor) SendTransaction(nonce uint64,
transaction *ethgo.Transaction) (*ethgo.Receipt, error) {
return helper.SendTxn(nonce, transaction)
transaction *ethgo.Transaction, signer ethgo.Key) (*ethgo.Receipt, error) {
return helper.SendTxn(nonce, transaction, signer)
}

func (d *defaultRootchainInteractor) GetPendingNonce(address types.Address) (uint64, error) {
Expand Down
19 changes: 11 additions & 8 deletions consensus/polybft/checkpoint_manager_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -13,14 +13,16 @@ import (
"github.com/0xPolygon/polygon-edge/consensus/ibft/signer"
"github.com/0xPolygon/polygon-edge/consensus/polybft/bitmap"
bls "github.com/0xPolygon/polygon-edge/consensus/polybft/signer"
"github.com/0xPolygon/polygon-edge/consensus/polybft/wallet"
"github.com/0xPolygon/polygon-edge/types"
)

func TestCheckpointManager_submitCheckpoint(t *testing.T) {
t.Skip("FIX ME")
t.Parallel()

validators := newTestValidators(5).getPublicIdentities()
validators := newTestValidators(5)
validatorsMetadata := validators.getPublicIdentities()
rootchainMock := new(dummyRootchainInteractor)
rootchainMock.On("Call", mock.Anything, mock.Anything, mock.Anything).
Return("1", error(nil)).
Expand All @@ -40,7 +42,7 @@ func TestCheckpointManager_submitCheckpoint(t *testing.T) {
EpochNumber: 4,
EventRoot: types.BytesToHash(generateRandomBytes(t)),
}
extra := createTestExtraObject(validators, validators, 3, 3, 3)
extra := createTestExtraObject(validatorsMetadata, validatorsMetadata, 3, 3, 3)
extra.Checkpoint = checkpoint

latestCheckpointHeader := &types.Header{
Expand All @@ -57,9 +59,9 @@ func TestCheckpointManager_submitCheckpoint(t *testing.T) {
checkpoint3 := checkpoint.Copy()
checkpoint3.EpochNumber = 3

extra = createTestExtraObject(validators, validators, 4, 4, 4)
extra = createTestExtraObject(validatorsMetadata, validatorsMetadata, 4, 4, 4)
extra.Checkpoint = checkpoint1
extra3 := createTestExtraObject(validators, validators, 4, 4, 4)
extra3 := createTestExtraObject(validatorsMetadata, validatorsMetadata, 4, 4, 4)
extra3.Checkpoint = checkpoint3

headersMap := &testHeadersMap{}
Expand Down Expand Up @@ -87,8 +89,9 @@ func TestCheckpointManager_submitCheckpoint(t *testing.T) {
blockchainMock := new(blockchainMock)
blockchainMock.On("GetHeaderByNumber", mock.Anything).Return(headersMap.getHeader)

validatorAcc := validators.getValidator("A")
c := &checkpointManager{
sender: types.StringToAddress("2"),
signer: wallet.NewEcdsaSigner(validatorAcc.Key()),
rootchain: rootchainMock,
consensusBackend: backendMock,
blockchain: blockchainMock,
Expand Down Expand Up @@ -237,7 +240,7 @@ func TestCheckpointManager_isCheckpointBlock(t *testing.T) {
t.Run(c.name, func(t *testing.T) {
t.Parallel()

checkpointMgr := newCheckpointManager(types.ZeroAddress, c.checkpointsOffset, nil, nil, nil)
checkpointMgr := newCheckpointManager(nil, c.checkpointsOffset, nil, nil, nil)
require.Equal(t, c.isCheckpointBlock, checkpointMgr.isCheckpointBlock(c.blockNumber))
})
}
Expand All @@ -255,8 +258,8 @@ func (d dummyRootchainInteractor) Call(from types.Address, to types.Address, inp
return args.String(0), args.Error(1)
}

func (d dummyRootchainInteractor) SendTransaction(nonce uint64, transaction *ethgo.Transaction) (*ethgo.Receipt, error) {
args := d.Called(nonce, transaction)
func (d dummyRootchainInteractor) SendTransaction(nonce uint64, transaction *ethgo.Transaction, signer ethgo.Key) (*ethgo.Receipt, error) {
args := d.Called(nonce, transaction, signer)

return args.Get(0).(*ethgo.Receipt), args.Error(1) //nolint:forcetypeassert
}
Expand Down
2 changes: 1 addition & 1 deletion consensus/polybft/consensus_runtime.go
Original file line number Diff line number Diff line change
Expand Up @@ -134,7 +134,7 @@ func newConsensusRuntime(log hcf.Logger, config *runtimeConfig) *consensusRuntim

if runtime.IsBridgeEnabled() {
runtime.checkpointManager = newCheckpointManager(
types.Address(config.Key.Address()),
wallet.NewEcdsaSigner(config.Key),
defaultCheckpointsOffset,
&defaultRootchainInteractor{},
config.blockchain,
Expand Down
3 changes: 2 additions & 1 deletion consensus/polybft/consensus_runtime_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -1603,13 +1603,14 @@ func TestConsensusRuntime_FSM_EndOfEpoch_OnBlockInserted(t *testing.T) {
txPool: txPool,
}

signer := validatorAccounts.getValidator("A").Key()
runtime := &consensusRuntime{
logger: hclog.NewNullLogger(),
state: state,
epoch: metadata,
config: config,
lastBuiltBlock: lastBuiltBlock,
checkpointManager: newCheckpointManager(types.StringToAddress("3"), 5, nil, nil, nil),
checkpointManager: newCheckpointManager(wallet.NewEcdsaSigner(signer), 5, nil, nil, nil),
}

err = runtime.FSM()
Expand Down
2 changes: 1 addition & 1 deletion consensus/polybft/polybft.go
Original file line number Diff line number Diff line change
Expand Up @@ -134,7 +134,7 @@ func GenesisPostHookFactory(config *chain.Chain, engineName string) func(txn *st
}

input, err = initNativeTokenMethod.Encode(
[]interface{}{helper.GetDefAccount(), nativeTokenName, nativeTokenSymbol})
[]interface{}{helper.GetRootchainAdminAddr(), nativeTokenName, nativeTokenSymbol})
if err != nil {
return err
}
Expand Down
13 changes: 13 additions & 0 deletions consensus/polybft/wallet/key.go
Original file line number Diff line number Diff line change
Expand Up @@ -60,3 +60,16 @@ func RecoverAddressFromSignature(sig, msg []byte) (types.Address, error) {

return crypto.PubKeyToAddress(pub), nil
}

// ECDSASigner implements ethgo.Key interface and it is used for signing using provided ECDSA key
type ECDSASigner struct {
*Key
}

func NewEcdsaSigner(ecdsaKey *Key) *ECDSASigner {
return &ECDSASigner{Key: ecdsaKey}
}

func (k *ECDSASigner) Sign(b []byte) ([]byte, error) {
return k.raw.Ecdsa.Sign(b)
}

0 comments on commit ce656f0

Please sign in to comment.