Resolves issues on eth comaptible txns (#3500)

* make eth txn works

* Add forking logic for ethereum compatible txn support
pull/3502/head
Rongjian Lan 4 years ago committed by GitHub
parent 6112100ef5
commit d1f1103b02
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
  1. 7
      cmd/harmony/main.go
  2. 3
      core/state_processor.go
  3. 4
      core/types/eth_transaction.go
  4. 6
      core/types/transaction.go
  5. 3
      core/types/transaction_signing.go
  6. 2
      core/vm/runtime/runtime.go
  7. 286
      internal/params/config.go
  8. 9
      internal/shardchain/shardchains.go
  9. 6
      node/node.go
  10. 1
      node/worker/worker.go
  11. 6
      rpc/pool.go

@ -277,13 +277,14 @@ func setupNodeAndRun(hc harmonyConfig) {
fmt.Fprintf(os.Stderr, "ERROR cannot configure node: %s\n", err)
os.Exit(1)
}
currentNode := setupConsensusAndNode(hc, nodeConfig)
nodeconfig.GetDefaultConfig().ShardID = nodeConfig.ShardID
nodeconfig.GetDefaultConfig().IsOffline = nodeConfig.IsOffline
// Update ethereum compatible chain ids
params.UpdateEthChainIDByShard(nodeConfig.ShardID)
currentNode := setupConsensusAndNode(hc, nodeConfig)
nodeconfig.GetDefaultConfig().ShardID = nodeConfig.ShardID
nodeconfig.GetDefaultConfig().IsOffline = nodeConfig.IsOffline
// Check NTP configuration
accurate, err := ntp.CheckLocalTimeAccurate(nodeConfig.NtpServer)
if !accurate {

@ -189,6 +189,9 @@ func ApplyTransaction(config *params.ChainConfig, bc ChainContext, author *commo
var signer types.Signer
if tx.IsEthCompatible() {
if !config.IsEthCompatible(header.Epoch()) {
return nil, nil, 0, errors.New("ethereum compatible transactions not supported at current epoch")
}
signer = types.NewEIP155Signer(config.EthCompatibleChainID)
} else {
signer = types.MakeSigner(config, header.Epoch())

@ -160,8 +160,8 @@ func (tx *EthTransaction) ToShardID() uint32 {
}
func (tx *EthTransaction) shardID() uint32 {
ethChainID := nodeconfig.GetDefaultConfig().GetNetworkType().ChainConfig().EthCompatibleChainID
return uint32(tx.ChainID().Uint64() - ethChainID.Uint64())
ethChainIDBase := nodeconfig.GetDefaultConfig().GetNetworkType().ChainConfig().EthCompatibleChainID
return uint32(tx.ChainID().Uint64()-ethChainIDBase.Uint64()) + nodeconfig.GetDefaultConfig().ShardID
}
// ChainID returns which chain id this transaction was signed for (if at all)

@ -560,6 +560,9 @@ func NewTransactionsByPriceAndNonce(hmySigner Signer, ethSigner Signer, txs map[
// Initialize a price based heap with the head transactions
heads := make(TxByPrice, 0, len(txs))
for from, accTxs := range txs {
if accTxs.Len() == 0 {
continue
}
heads = append(heads, accTxs[0])
// Ensure the sender address is from the signer
signer := hmySigner
@ -593,6 +596,9 @@ func (t *TransactionsByPriceAndNonce) Peek() *Transaction {
// Shift replaces the current best head with the next one from the same account.
func (t *TransactionsByPriceAndNonce) Shift() {
if len(t.heads) == 0 {
return
}
signer := t.signer
if t.heads[0].IsEthCompatible() {
signer = t.ethSigner

@ -123,8 +123,7 @@ func NewEIP155Signer(chainID *big.Int) EIP155Signer {
// Equal checks if the given EIP155Signer is equal to another Signer.
func (s EIP155Signer) Equal(s2 Signer) bool {
eip155, ok := s2.(EIP155Signer)
ethChainID := nodeconfig.GetDefaultConfig().GetNetworkType().ChainConfig().EthCompatibleChainID
return ok && (eip155.chainID.Cmp(ethChainID) == 0 || eip155.chainID.Cmp(s.chainID) == 0)
return ok && eip155.chainID.Cmp(s.chainID) == 0
}
var big8 = big.NewInt(8)

@ -54,7 +54,7 @@ func setDefaults(cfg *Config) {
if cfg.ChainConfig == nil {
cfg.ChainConfig = &params.ChainConfig{
ChainID: big.NewInt(1),
EthCompatibleChainID: params.EthMainnetChainID,
EthCompatibleChainID: params.EthMainnetShard0ChainID,
CrossTxEpoch: new(big.Int),
CrossLinkEpoch: new(big.Int),
EIP155Epoch: new(big.Int),

@ -18,14 +18,14 @@ var (
TestChainID = big.NewInt(99) // not a real network
AllProtocolChangesChainID = big.NewInt(100) // not a real network
// EthMainnetChainID to be reserved unique chain ID for eth compatible chains.
EthMainnetChainID = big.NewInt(1666600000)
EthTestnetChainID = big.NewInt(1666700000)
EthPangaeaChainID = big.NewInt(1666800000)
EthPartnerChainID = big.NewInt(1666900000)
EthStressnetChainID = big.NewInt(1661000000)
EthTestChainID = big.NewInt(1661100000) // not a real network
EthAllProtocolChangesChainID = big.NewInt(1661200000) // not a real network
// EthMainnetShard0ChainID to be reserved unique chain ID for eth compatible chains.
EthMainnetShard0ChainID = big.NewInt(1666600000)
EthTestnetShard0ChainID = big.NewInt(1666700000)
EthPangaeaShard0ChainID = big.NewInt(1666800000)
EthPartnerShard0ChainID = big.NewInt(1666900000)
EthStressnetShard0ChainID = big.NewInt(1661000000)
EthTestShard0ChainID = big.NewInt(1661100000) // not a real network
EthAllProtocolChangesShard0ChainID = big.NewInt(1661200000) // not a real network
)
// EpochTBD is a large, “not anytime soon” epoch. It used as a placeholder
@ -36,161 +36,177 @@ var once sync.Once
var (
// MainnetChainConfig is the chain parameters to run a node on the main network.
MainnetChainConfig = &ChainConfig{
ChainID: MainnetChainID,
EthCompatibleChainID: EthMainnetChainID,
CrossTxEpoch: big.NewInt(28),
CrossLinkEpoch: big.NewInt(186),
StakingEpoch: big.NewInt(186),
PreStakingEpoch: big.NewInt(185),
QuickUnlockEpoch: big.NewInt(191),
FiveSecondsEpoch: big.NewInt(230),
TwoSecondsEpoch: big.NewInt(366), // Around Tuesday Dec 8th 2020, 8AM PST
SixtyPercentEpoch: big.NewInt(434), // Around Friday Jan 29 2021, 10AM PST
RedelegationEpoch: big.NewInt(290),
EIP155Epoch: big.NewInt(28),
S3Epoch: big.NewInt(28),
IstanbulEpoch: big.NewInt(314),
ReceiptLogEpoch: big.NewInt(101),
ChainID: MainnetChainID,
EthCompatibleChainID: EthMainnetShard0ChainID,
EthCompatibleShard0ChainID: EthMainnetShard0ChainID,
EthCompatibleEpoch: EpochTBD,
CrossTxEpoch: big.NewInt(28),
CrossLinkEpoch: big.NewInt(186),
StakingEpoch: big.NewInt(186),
PreStakingEpoch: big.NewInt(185),
QuickUnlockEpoch: big.NewInt(191),
FiveSecondsEpoch: big.NewInt(230),
TwoSecondsEpoch: big.NewInt(366), // Around Tuesday Dec 8th 2020, 8AM PST
SixtyPercentEpoch: big.NewInt(434), // Around Friday Jan 29 2021, 10AM PST
RedelegationEpoch: big.NewInt(290),
EIP155Epoch: big.NewInt(28),
S3Epoch: big.NewInt(28),
IstanbulEpoch: big.NewInt(314),
ReceiptLogEpoch: big.NewInt(101),
}
// TestnetChainConfig contains the chain parameters to run a node on the harmony test network.
TestnetChainConfig = &ChainConfig{
ChainID: TestnetChainID,
EthCompatibleChainID: EthTestnetChainID,
CrossTxEpoch: big.NewInt(0),
CrossLinkEpoch: big.NewInt(2),
StakingEpoch: big.NewInt(2),
PreStakingEpoch: big.NewInt(1),
QuickUnlockEpoch: big.NewInt(0),
FiveSecondsEpoch: big.NewInt(16500),
TwoSecondsEpoch: big.NewInt(73000),
SixtyPercentEpoch: big.NewInt(73280),
RedelegationEpoch: big.NewInt(36500),
EIP155Epoch: big.NewInt(0),
S3Epoch: big.NewInt(0),
IstanbulEpoch: big.NewInt(43800),
ReceiptLogEpoch: big.NewInt(0),
ChainID: TestnetChainID,
EthCompatibleChainID: EthTestnetShard0ChainID,
EthCompatibleShard0ChainID: EthTestnetShard0ChainID,
EthCompatibleEpoch: EpochTBD,
CrossTxEpoch: big.NewInt(0),
CrossLinkEpoch: big.NewInt(2),
StakingEpoch: big.NewInt(2),
PreStakingEpoch: big.NewInt(1),
QuickUnlockEpoch: big.NewInt(0),
FiveSecondsEpoch: big.NewInt(16500),
TwoSecondsEpoch: big.NewInt(73000),
SixtyPercentEpoch: big.NewInt(73280),
RedelegationEpoch: big.NewInt(36500),
EIP155Epoch: big.NewInt(0),
S3Epoch: big.NewInt(0),
IstanbulEpoch: big.NewInt(43800),
ReceiptLogEpoch: big.NewInt(0),
}
// PangaeaChainConfig contains the chain parameters for the Pangaea network.
// All features except for CrossLink are enabled at launch.
PangaeaChainConfig = &ChainConfig{
ChainID: PangaeaChainID,
EthCompatibleChainID: EthPangaeaChainID,
CrossTxEpoch: big.NewInt(0),
CrossLinkEpoch: big.NewInt(2),
StakingEpoch: big.NewInt(2),
PreStakingEpoch: big.NewInt(1),
QuickUnlockEpoch: big.NewInt(0),
FiveSecondsEpoch: big.NewInt(0),
TwoSecondsEpoch: big.NewInt(0),
SixtyPercentEpoch: big.NewInt(0),
RedelegationEpoch: big.NewInt(0),
EIP155Epoch: big.NewInt(0),
S3Epoch: big.NewInt(0),
IstanbulEpoch: big.NewInt(0),
ReceiptLogEpoch: big.NewInt(0),
ChainID: PangaeaChainID,
EthCompatibleChainID: EthPangaeaShard0ChainID,
EthCompatibleShard0ChainID: EthPangaeaShard0ChainID,
EthCompatibleEpoch: big.NewInt(0),
CrossTxEpoch: big.NewInt(0),
CrossLinkEpoch: big.NewInt(2),
StakingEpoch: big.NewInt(2),
PreStakingEpoch: big.NewInt(1),
QuickUnlockEpoch: big.NewInt(0),
FiveSecondsEpoch: big.NewInt(0),
TwoSecondsEpoch: big.NewInt(0),
SixtyPercentEpoch: big.NewInt(0),
RedelegationEpoch: big.NewInt(0),
EIP155Epoch: big.NewInt(0),
S3Epoch: big.NewInt(0),
IstanbulEpoch: big.NewInt(0),
ReceiptLogEpoch: big.NewInt(0),
}
// PartnerChainConfig contains the chain parameters for the Partner network.
// All features except for CrossLink are enabled at launch.
PartnerChainConfig = &ChainConfig{
ChainID: PartnerChainID,
EthCompatibleChainID: EthPartnerChainID,
CrossTxEpoch: big.NewInt(0),
CrossLinkEpoch: big.NewInt(2),
StakingEpoch: big.NewInt(2),
PreStakingEpoch: big.NewInt(1),
QuickUnlockEpoch: big.NewInt(0),
FiveSecondsEpoch: big.NewInt(0),
TwoSecondsEpoch: big.NewInt(0),
SixtyPercentEpoch: big.NewInt(0),
RedelegationEpoch: big.NewInt(0),
EIP155Epoch: big.NewInt(0),
S3Epoch: big.NewInt(0),
IstanbulEpoch: big.NewInt(0),
ReceiptLogEpoch: big.NewInt(0),
ChainID: PartnerChainID,
EthCompatibleChainID: EthPartnerShard0ChainID,
EthCompatibleShard0ChainID: EthPartnerShard0ChainID,
EthCompatibleEpoch: big.NewInt(0),
CrossTxEpoch: big.NewInt(0),
CrossLinkEpoch: big.NewInt(2),
StakingEpoch: big.NewInt(2),
PreStakingEpoch: big.NewInt(1),
QuickUnlockEpoch: big.NewInt(0),
FiveSecondsEpoch: big.NewInt(0),
TwoSecondsEpoch: big.NewInt(0),
SixtyPercentEpoch: big.NewInt(0),
RedelegationEpoch: big.NewInt(0),
EIP155Epoch: big.NewInt(0),
S3Epoch: big.NewInt(0),
IstanbulEpoch: big.NewInt(0),
ReceiptLogEpoch: big.NewInt(0),
}
// StressnetChainConfig contains the chain parameters for the Stress test network.
// All features except for CrossLink are enabled at launch.
StressnetChainConfig = &ChainConfig{
ChainID: StressnetChainID,
EthCompatibleChainID: EthStressnetChainID,
CrossTxEpoch: big.NewInt(0),
CrossLinkEpoch: big.NewInt(2),
StakingEpoch: big.NewInt(2),
PreStakingEpoch: big.NewInt(1),
QuickUnlockEpoch: big.NewInt(0),
FiveSecondsEpoch: big.NewInt(0),
TwoSecondsEpoch: big.NewInt(0),
SixtyPercentEpoch: EpochTBD, // Never enable it for STN as STN has no external validator setup
RedelegationEpoch: big.NewInt(0),
EIP155Epoch: big.NewInt(0),
S3Epoch: big.NewInt(0),
IstanbulEpoch: big.NewInt(0),
ReceiptLogEpoch: big.NewInt(0),
ChainID: StressnetChainID,
EthCompatibleChainID: EthStressnetShard0ChainID,
EthCompatibleShard0ChainID: EthStressnetShard0ChainID,
EthCompatibleEpoch: big.NewInt(0),
CrossTxEpoch: big.NewInt(0),
CrossLinkEpoch: big.NewInt(2),
StakingEpoch: big.NewInt(2),
PreStakingEpoch: big.NewInt(1),
QuickUnlockEpoch: big.NewInt(0),
FiveSecondsEpoch: big.NewInt(0),
TwoSecondsEpoch: big.NewInt(0),
SixtyPercentEpoch: EpochTBD, // Never enable it for STN as STN has no external validator setup
RedelegationEpoch: big.NewInt(0),
EIP155Epoch: big.NewInt(0),
S3Epoch: big.NewInt(0),
IstanbulEpoch: big.NewInt(0),
ReceiptLogEpoch: big.NewInt(0),
}
// LocalnetChainConfig contains the chain parameters to run for local development.
LocalnetChainConfig = &ChainConfig{
ChainID: TestnetChainID,
EthCompatibleChainID: EthTestnetChainID,
CrossTxEpoch: big.NewInt(0),
CrossLinkEpoch: big.NewInt(2),
StakingEpoch: big.NewInt(2),
PreStakingEpoch: big.NewInt(0),
QuickUnlockEpoch: big.NewInt(0),
FiveSecondsEpoch: big.NewInt(0),
TwoSecondsEpoch: big.NewInt(3),
SixtyPercentEpoch: EpochTBD, // Never enable it for localnet as localnet has no external validator setup
RedelegationEpoch: big.NewInt(0),
EIP155Epoch: big.NewInt(0),
S3Epoch: big.NewInt(0),
IstanbulEpoch: big.NewInt(0),
ReceiptLogEpoch: big.NewInt(0),
ChainID: TestnetChainID,
EthCompatibleChainID: EthTestnetShard0ChainID,
EthCompatibleShard0ChainID: EthTestnetShard0ChainID,
EthCompatibleEpoch: big.NewInt(0),
CrossTxEpoch: big.NewInt(0),
CrossLinkEpoch: big.NewInt(2),
StakingEpoch: big.NewInt(2),
PreStakingEpoch: big.NewInt(0),
QuickUnlockEpoch: big.NewInt(0),
FiveSecondsEpoch: big.NewInt(0),
TwoSecondsEpoch: big.NewInt(3),
SixtyPercentEpoch: EpochTBD, // Never enable it for localnet as localnet has no external validator setup
RedelegationEpoch: big.NewInt(0),
EIP155Epoch: big.NewInt(0),
S3Epoch: big.NewInt(0),
IstanbulEpoch: big.NewInt(0),
ReceiptLogEpoch: big.NewInt(0),
}
// AllProtocolChanges ...
// This configuration is intentionally not using keyed fields to force anyone
// adding flags to the config to also have to set these fields.
AllProtocolChanges = &ChainConfig{
AllProtocolChangesChainID, // ChainID
EthAllProtocolChangesChainID, // EthCompatibleChainID
big.NewInt(0), // CrossTxEpoch
big.NewInt(0), // CrossLinkEpoch
big.NewInt(0), // StakingEpoch
big.NewInt(0), // PreStakingEpoch
big.NewInt(0), // QuickUnlockEpoch
big.NewInt(0), // FiveSecondsEpoch
big.NewInt(0), // TwoSecondsEpoch
big.NewInt(0), // SixtyPercentEpoch
big.NewInt(0), // RedelegationEpoch
big.NewInt(0), // EIP155Epoch
big.NewInt(0), // S3Epoch
big.NewInt(0), // IstanbulEpoch
big.NewInt(0), // ReceiptLogEpoch
AllProtocolChangesChainID, // ChainID
EthAllProtocolChangesShard0ChainID, // EthCompatibleChainID
EthAllProtocolChangesShard0ChainID, // EthCompatibleShard0ChainID
big.NewInt(0), // EthCompatibleEpoch
big.NewInt(0), // CrossTxEpoch
big.NewInt(0), // CrossLinkEpoch
big.NewInt(0), // StakingEpoch
big.NewInt(0), // PreStakingEpoch
big.NewInt(0), // QuickUnlockEpoch
big.NewInt(0), // FiveSecondsEpoch
big.NewInt(0), // TwoSecondsEpoch
big.NewInt(0), // SixtyPercentEpoch
big.NewInt(0), // RedelegationEpoch
big.NewInt(0), // EIP155Epoch
big.NewInt(0), // S3Epoch
big.NewInt(0), // IstanbulEpoch
big.NewInt(0), // ReceiptLogEpoch
}
// TestChainConfig ...
// This configuration is intentionally not using keyed fields to force anyone
// adding flags to the config to also have to set these fields.
TestChainConfig = &ChainConfig{
TestChainID, // ChainID
EthTestChainID, // EthCompatibleChainID
big.NewInt(0), // CrossTxEpoch
big.NewInt(0), // CrossLinkEpoch
big.NewInt(0), // StakingEpoch
big.NewInt(0), // PreStakingEpoch
big.NewInt(0), // QuickUnlockEpoch
big.NewInt(0), // FiveSecondsEpoch
big.NewInt(0), // TwoSecondsEpoch
big.NewInt(0), // SixtyPercentEpoch
big.NewInt(0), // RedelegationEpoch
big.NewInt(0), // EIP155Epoch
big.NewInt(0), // S3Epoch
big.NewInt(0), // IstanbulEpoch
big.NewInt(0), // ReceiptLogEpoch
TestChainID, // ChainID
EthTestShard0ChainID, // EthCompatibleChainID
EthTestShard0ChainID, // EthCompatibleShard0ChainID
big.NewInt(0), // EthCompatibleEpoch
big.NewInt(0), // CrossTxEpoch
big.NewInt(0), // CrossLinkEpoch
big.NewInt(0), // StakingEpoch
big.NewInt(0), // PreStakingEpoch
big.NewInt(0), // QuickUnlockEpoch
big.NewInt(0), // FiveSecondsEpoch
big.NewInt(0), // TwoSecondsEpoch
big.NewInt(0), // SixtyPercentEpoch
big.NewInt(0), // RedelegationEpoch
big.NewInt(0), // EIP155Epoch
big.NewInt(0), // S3Epoch
big.NewInt(0), // IstanbulEpoch
big.NewInt(0), // ReceiptLogEpoch
}
// TestRules ...
@ -221,6 +237,13 @@ type ChainConfig struct {
// EthCompatibleChainID identifies the chain id used for ethereum compatible transactions
EthCompatibleChainID *big.Int `json:"eth-compatible-chain-id"`
// EthCompatibleShard0ChainID identifies the shard 0 chain id used for ethereum compatible transactions
EthCompatibleShard0ChainID *big.Int `json:"eth-compatible-shard-0-chain-id"`
// EthCompatibleEpoch is the epoch where ethereum-compatible transaction starts being
// processed.
EthCompatibleEpoch *big.Int `json:"eth-compatible-epoch,omitempty"`
// CrossTxEpoch is the epoch where cross-shard transaction starts being
// processed.
CrossTxEpoch *big.Int `json:"cross-tx-epoch,omitempty"`
@ -304,6 +327,11 @@ func (c *ChainConfig) HasCrossTxFields(epoch *big.Int) bool {
return isForked(c.CrossTxEpoch, epoch)
}
// IsEthCompatible determines whether it is ethereum compatible epoch
func (c *ChainConfig) IsEthCompatible(epoch *big.Int) bool {
return isForked(c.EthCompatibleEpoch, epoch)
}
// IsStaking determines whether it is staking epoch
func (c *ChainConfig) IsStaking(epoch *big.Int) bool {
return isForked(c.StakingEpoch, epoch)
@ -375,7 +403,7 @@ func UpdateEthChainIDByShard(shardID uint32) {
// IsEthCompatible returns whether the chainID is for ethereum compatible txn or not
func IsEthCompatible(chainID *big.Int) bool {
return chainID.Cmp(EthMainnetChainID) >= 0
return chainID.Cmp(EthMainnetShard0ChainID) >= 0
}
// GasTable returns the gas table corresponding to the current phase (homestead or homestead reprice).

@ -1,8 +1,11 @@
package shardchain
import (
"math/big"
"sync"
"github.com/harmony-one/harmony/shard"
"github.com/ethereum/go-ethereum/common"
"github.com/ethereum/go-ethereum/ethdb"
"github.com/harmony-one/harmony/consensus/engine"
@ -96,6 +99,12 @@ func (sc *CollectionImpl) ShardChain(shardID uint32) (*core.BlockChain, error) {
Msg("disable cache, running in archival mode")
}
chainConfig := *sc.chainConfig
if shardID == shard.BeaconChainShardID {
// For beacon chain inside a shard chain, need to reset the eth chainID to shard 0's eth chainID in the config
chainConfig.EthCompatibleChainID = big.NewInt(chainConfig.EthCompatibleShard0ChainID.Int64())
}
bc, err := core.NewBlockChain(
db, cacheConfig, sc.chainConfig, sc.engine, vm.Config{}, nil,
)

@ -193,6 +193,10 @@ func (node *Node) addPendingTransactions(newTxs types.Transactions) []error {
errs = append(errs, errors.WithMessage(errInvalidEpoch, "cross-shard tx not accepted yet"))
continue
}
if tx.IsEthCompatible() && !node.Blockchain().Config().IsEthCompatible(node.Blockchain().CurrentBlock().Epoch()) {
errs = append(errs, errors.WithMessage(errInvalidEpoch, "ethereum tx not accepted yet"))
continue
}
poolTxs = append(poolTxs, tx)
}
errs = append(errs, node.TxPool.AddRemotes(poolTxs)...)
@ -279,7 +283,7 @@ func (node *Node) AddPendingTransaction(newTx *types.Transaction) error {
}
return err
}
return errors.New("shard do not match")
return errors.Errorf("shard do not match, txShard: %d, nodeShard: %d", newTx.ShardID(), node.NodeConfig.ShardID)
}
// AddPendingReceipts adds one receipt message to pending list.

@ -140,6 +140,7 @@ func (w *Worker) CommitTransactions(
// HARMONY TXNS
normalTxns := types.NewTransactionsByPriceAndNonce(w.current.signer, w.current.ethSigner, pendingNormal)
w.CommitSortedTransactions(normalTxns, coinbase)
// STAKING - only beaconchain process staking transaction

@ -78,6 +78,11 @@ func (s *PublicPoolService) SendRawTransaction(
// Log submission
if tx.To() == nil {
signer := types.MakeSigner(s.hmy.ChainConfig(), s.hmy.CurrentBlock().Epoch())
ethSigner := types.NewEIP155Signer(s.hmy.ChainConfig().EthCompatibleChainID)
if tx.IsEthCompatible() {
signer = ethSigner
}
from, err := types.Sender(signer, tx)
if err != nil {
return common.Hash{}, err
@ -91,6 +96,7 @@ func (s *PublicPoolService) SendRawTransaction(
utils.Logger().Info().
Str("fullhash", tx.Hash().Hex()).
Str("recipient", tx.To().Hex()).
Interface("tx", tx).
Msg("Submitted transaction")
}

Loading…
Cancel
Save