Skip to content

Commit

Permalink
Added TxExMsg message type to send derived sender address along with …
Browse files Browse the repository at this point in the history
…transaction itself to avoid doing signature verification. If it comes from non-trusted node, signature verification is enforced.
  • Loading branch information
sadoci committed Sep 23, 2019
1 parent f76d5a5 commit fab71b0
Show file tree
Hide file tree
Showing 4 changed files with 96 additions and 3 deletions.
59 changes: 59 additions & 0 deletions core/types/transaction.go
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,11 @@ type Transaction struct {
from atomic.Value
}

type TransactionEx struct {
Tx *Transaction
From common.Address `json:"from" rlp:"nil"`
}

type txdata struct {
AccountNonce uint64 `json:"nonce" gencodec:"required"`
Price *big.Int `json:"gasPrice" gencodec:"required"`
Expand Down Expand Up @@ -212,6 +217,60 @@ func (tx *Transaction) Size() common.StorageSize {
return common.StorageSize(c)
}

// Convert []*Transaction to []*TransactionEx
func Txs2TxExs(txs []*Transaction) []*TransactionEx {
var out []*TransactionEx
for _, i := range txs {
var from common.Address
if sc := i.from.Load(); sc != nil {
from = sc.(sigCache).from
}
j := &TransactionEx{
Tx: i,
From: from,
}
out = append(out, j)
}
return out
}

// Convert []*TransactionEx to []*Transaction
func TxExs2Txs(signer Signer, txs []*TransactionEx, trustIt bool) []*Transaction {
var out []*Transaction
for _, i := range txs {
if trustIt {
i.Tx.from.Store(sigCache{signer: signer, from: i.From})
}
out = append(out, i.Tx)
}
return out
}

// EncodeRLP implements rlp.Encoder
func (tx *TransactionEx) EncodeRLP(w io.Writer) error {
if err := rlp.Encode(w, &tx.Tx.data); err != nil {
return err
}
var from common.Address
if sc := tx.Tx.from.Load(); sc != nil {
from = sc.(sigCache).from
}
return rlp.Encode(w, &from)
}

// DecodeRLP implements rlp.Decoder
func (tx *TransactionEx) DecodeRLP(s *rlp.Stream) error {
tx.Tx = &Transaction{}
_, size, _ := s.Kind()
err := s.Decode(&tx.Tx.data)
if err != nil {
return err
} else {
tx.Tx.size.Store(common.StorageSize(rlp.ListSize(size)))
}
return s.Decode(&tx.From)
}

// AsMessage returns the transaction as a core.Message.
//
// AsMessage requires a signer to derive the sender.
Expand Down
28 changes: 28 additions & 0 deletions eth/handler.go
Original file line number Diff line number Diff line change
Expand Up @@ -832,6 +832,34 @@ func (pm *ProtocolManager) handleMsg(p *peer) error {
}()
return nil

case p.version >= eth64 && msg.Code == TxExMsg:
// Transactions arrived, make sure we have a valid and fresh chain to handle them
if atomic.LoadUint32(&pm.acceptTxs) == 0 {
break
}
// Transactions can be processed, parse all of them and deliver to the pool
var txexs []*types.TransactionEx
if err := msg.Decode(&txexs); err != nil {
return errResp(ErrDecode, "msg %v: %v", msg, err)
}

// Metadium: it's non-blocking now
go func() error {
signer := types.MakeSigner(pm.chainconfig, pm.blockchain.CurrentBlock().Number())
txs := types.TxExs2Txs(signer, txexs, metaminer.IsPartner(p.ID().String()))
for i, tx := range txs {
// Validate and mark the remote transaction
if tx == nil {
return errResp(ErrDecode, "transaction %d is nil", i)
}
p.MarkTransaction(tx.Hash())
}
//pm.txpool.AddRemotes(txs)
remoteTxCh <- txs
return nil
}()
return nil

// Metadium: leader wants to get left-over transactions if any
case p.version >= eth63 && msg.Code == GetPendingTxsMsg:
if !metaminer.IsPartner(p.ID().String()) {
Expand Down
6 changes: 5 additions & 1 deletion eth/peer.go
Original file line number Diff line number Diff line change
Expand Up @@ -210,7 +210,11 @@ func (p *peer) SendTransactions(txs types.Transactions) error {
for _, tx := range txs {
p.knownTxs.Put(tx.Hash(), true)
}
return p2p.Send(p.rw, TxMsg, txs)
if p.version >= eth64 {
return p2p.Send(p.rw, TxExMsg, types.Txs2TxExs(txs))
} else {
return p2p.Send(p.rw, TxMsg, txs)
}
}

// AsyncSendTransactions queues list of transactions propagation to a remote
Expand Down
6 changes: 4 additions & 2 deletions eth/protocol.go
Original file line number Diff line number Diff line change
Expand Up @@ -32,16 +32,17 @@ import (
const (
eth62 = 62
eth63 = 63
eth64 = 64
)

// ProtocolName is the official short name of the protocol used during capability negotiation.
var ProtocolName = "meta"

// ProtocolVersions are the supported versions of the eth protocol (first is primary).
var ProtocolVersions = []uint{eth63, eth62}
var ProtocolVersions = []uint{eth64, eth63, eth62}

// ProtocolLengths are the number of implemented message corresponding to different protocol versions.
var ProtocolLengths = []uint64{22, 8}
var ProtocolLengths = []uint64{23, 22, 8}

const ProtocolMaxMsgSize = 100 * 1024 * 1024 // Maximum cap on the size of a protocol message

Expand Down Expand Up @@ -69,6 +70,7 @@ const (
StatusExMsg = 0x13
EtcdAddMemberMsg = 0x14
EtcdClusterMsg = 0x15
TxExMsg = 0x16
)

type errCode int
Expand Down

0 comments on commit fab71b0

Please sign in to comment.