Tx submission epoch checks (#3421)

* [node] Add Cx epoch check

* Report invalid epoch for staking tx

Signed-off-by: Daniel Van Der Maden <dvandermaden0@berkeley.edu>

* [rosetta] Add Cx epoch check in Metadata request

Signed-off-by: Daniel Van Der Maden <dvandermaden0@berkeley.edu>

* [node] Fix lint

Signed-off-by: Daniel Van Der Maden <dvandermaden0@berkeley.edu>
pull/3425/head
Daniel Van Der Maden 4 years ago committed by GitHub
parent 13051c4cf8
commit 2ead9d7d33
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
  1. 52
      node/node.go
  2. 14
      rosetta/services/construction_check.go

@ -204,10 +204,16 @@ func (node *Node) tryBroadcastStaking(stakingTx *staking.StakingTransaction) {
// Add new transactions to the pending transaction list. // Add new transactions to the pending transaction list.
func (node *Node) addPendingTransactions(newTxs types.Transactions) []error { func (node *Node) addPendingTransactions(newTxs types.Transactions) []error {
poolTxs := types.PoolTransactions{} poolTxs := types.PoolTransactions{}
errs := []error{}
acceptCx := node.Blockchain().Config().AcceptsCrossTx(node.Blockchain().CurrentHeader().Epoch())
for _, tx := range newTxs { for _, tx := range newTxs {
if tx.ShardID() != tx.ToShardID() && !acceptCx {
errs = append(errs, errors.WithMessage(errInvalidEpoch, "cross-shard tx not accepted yet"))
continue
}
poolTxs = append(poolTxs, tx) poolTxs = append(poolTxs, tx)
} }
errs := node.TxPool.AddRemotes(poolTxs) errs = append(errs, node.TxPool.AddRemotes(poolTxs)...)
pendingCount, queueCount := node.TxPool.Stats() pendingCount, queueCount := node.TxPool.Stats()
utils.Logger().Info(). utils.Logger().Info().
@ -221,22 +227,28 @@ func (node *Node) addPendingTransactions(newTxs types.Transactions) []error {
// Add new staking transactions to the pending staking transaction list. // Add new staking transactions to the pending staking transaction list.
func (node *Node) addPendingStakingTransactions(newStakingTxs staking.StakingTransactions) []error { func (node *Node) addPendingStakingTransactions(newStakingTxs staking.StakingTransactions) []error {
if node.NodeConfig.ShardID == shard.BeaconChainShardID && if node.NodeConfig.ShardID == shard.BeaconChainShardID {
node.Blockchain().Config().IsPreStaking(node.Blockchain().CurrentHeader().Epoch()) { if node.Blockchain().Config().IsPreStaking(node.Blockchain().CurrentHeader().Epoch()) {
poolTxs := types.PoolTransactions{} poolTxs := types.PoolTransactions{}
for _, tx := range newStakingTxs { for _, tx := range newStakingTxs {
poolTxs = append(poolTxs, tx) poolTxs = append(poolTxs, tx)
}
errs := node.TxPool.AddRemotes(poolTxs)
pendingCount, queueCount := node.TxPool.Stats()
utils.Logger().Info().
Int("length of newStakingTxs", len(poolTxs)).
Int("totalPending", pendingCount).
Int("totalQueued", queueCount).
Msg("Got more staking transactions")
return errs
} }
errs := node.TxPool.AddRemotes(poolTxs) return []error{
pendingCount, queueCount := node.TxPool.Stats() errors.WithMessage(errInvalidEpoch, "staking txs not accepted yet"),
utils.Logger().Info(). }
Int("length of newStakingTxs", len(poolTxs)). }
Int("totalPending", pendingCount). return []error{
Int("totalQueued", queueCount). errors.WithMessage(errInvalidShard, fmt.Sprintf("txs only valid on shard %v", shard.BeaconChainShardID)),
Msg("Got more staking transactions")
return errs
} }
return make([]error, len(newStakingTxs))
} }
// AddPendingStakingTransaction staking transactions // AddPendingStakingTransaction staking transactions
@ -248,13 +260,17 @@ func (node *Node) AddPendingStakingTransaction(
var err error var err error
for i := range errs { for i := range errs {
if errs[i] != nil { if errs[i] != nil {
utils.Logger().Info().Err(errs[i]).Msg("[AddPendingStakingTransaction] Failed adding new staking transaction") utils.Logger().Info().
Err(errs[i]).
Msg("[AddPendingStakingTransaction] Failed adding new staking transaction")
err = errs[i] err = errs[i]
break break
} }
} }
if err == nil || node.BroadcastInvalidTx { if err == nil || node.BroadcastInvalidTx {
utils.Logger().Info().Str("Hash", newStakingTx.Hash().Hex()).Msg("Broadcasting Staking Tx") utils.Logger().Info().
Str("Hash", newStakingTx.Hash().Hex()).
Msg("Broadcasting Staking Tx")
node.tryBroadcastStaking(newStakingTx) node.tryBroadcastStaking(newStakingTx)
} }
return err return err
@ -361,6 +377,8 @@ var (
errWrongShardID = errors.New("wrong shard id") errWrongShardID = errors.New("wrong shard id")
errInvalidNodeMsg = errors.New("invalid node message") errInvalidNodeMsg = errors.New("invalid node message")
errIgnoreBeaconMsg = errors.New("ignore beacon sync block") errIgnoreBeaconMsg = errors.New("ignore beacon sync block")
errInvalidEpoch = errors.New("invalid epoch for transaction")
errInvalidShard = errors.New("invalid shard")
) )
// validateNodeMessage validate node message // validateNodeMessage validate node message

@ -172,6 +172,20 @@ func (s *ConstructAPI) ConstructionMetadata(
}) })
} }
currBlock, err := s.hmy.BlockByNumber(ctx, ethRpc.LatestBlockNumber)
if err != nil {
return nil, common.NewError(common.CatchAllError, map[string]interface{}{
"message": err.Error(),
})
}
if options.OperationType == common.NativeCrossShardTransferOperation &&
!s.hmy.BlockChain.Config().AcceptsCrossTx(currBlock.Epoch()) {
return nil, common.NewError(common.InvalidTransactionConstructionError, map[string]interface{}{
"message": "cross-shard transaction is not accepted yet",
})
}
data := hexutil.Bytes{} data := hexutil.Bytes{}
if options.TransactionMetadata.Data != nil { if options.TransactionMetadata.Data != nil {
var err error var err error

Loading…
Cancel
Save