From bee4ad3002471519d876aa5442cb11523d8af619 Mon Sep 17 00:00:00 2001 From: chao Date: Wed, 7 Aug 2019 14:18:10 -0700 Subject: [PATCH] modify transaction structure and method for cross shard tx --- core/types/gen_tx_json.go | 44 ++++++++++++++++++++++----------------- core/types/transaction.go | 35 ++++++++++++++++++++++++++++++- 2 files changed, 59 insertions(+), 20 deletions(-) diff --git a/core/types/gen_tx_json.go b/core/types/gen_tx_json.go index c5744571a..a2979e8f1 100644 --- a/core/types/gen_tx_json.go +++ b/core/types/gen_tx_json.go @@ -16,13 +16,14 @@ var _ = (*txdataMarshaling)(nil) // MarshalJSON marshals as JSON. func (t txdata) MarshalJSON() ([]byte, error) { type txdata struct { - AccountNonce hexutil.Uint64 `json:"nonce" gencodec:"required"` - ShardID uint32 `json:"shardID" gencodec:"required"` - Price *hexutil.Big `json:"gasPrice" gencodec:"required"` - GasLimit hexutil.Uint64 `json:"gas" gencodec:"required"` - Recipient *common.Address `json:"to" rlp:"nil"` - Amount *hexutil.Big `json:"value" gencodec:"required"` - Payload hexutil.Bytes `json:"input" gencodec:"required"` + AccountNonce hexutil.Uint64 `json:"nonce" gencodec:"required"` + Price *hexutil.Big `json:"gasPrice" gencodec:"required"` + GasLimit hexutil.Uint64 `json:"gas" gencodec:"required"` + ShardID uint32 `json:"shardID" gencodec:"required"` + ToShardID uint32 `json:"toShardID"` + Recipient *common.Address `json:"to" rlp:"nil"` + Amount *hexutil.Big `json:"value" gencodec:"required"` + Payload hexutil.Bytes `json:"input" gencodec:"required"` V *hexutil.Big `json:"v" gencodec:"required"` R *hexutil.Big `json:"r" gencodec:"required"` S *hexutil.Big `json:"s" gencodec:"required"` @@ -30,9 +31,10 @@ func (t txdata) MarshalJSON() ([]byte, error) { } var enc txdata enc.AccountNonce = hexutil.Uint64(t.AccountNonce) - enc.ShardID = t.ShardID enc.Price = (*hexutil.Big)(t.Price) enc.GasLimit = hexutil.Uint64(t.GasLimit) + enc.ShardID = t.ShardID + enc.ToShardID = t.ToShardID enc.Recipient = t.Recipient enc.Amount = (*hexutil.Big)(t.Amount) enc.Payload = t.Payload @@ -46,13 +48,14 @@ func (t txdata) MarshalJSON() ([]byte, error) { // UnmarshalJSON unmarshals from JSON. func (t *txdata) UnmarshalJSON(input []byte) error { type txdata struct { - AccountNonce *hexutil.Uint64 `json:"nonce" gencodec:"required"` - ShardID *uint32 `json:"shardID" gencodec:"required"` - Price *hexutil.Big `json:"gasPrice" gencodec:"required"` - GasLimit *hexutil.Uint64 `json:"gas" gencodec:"required"` - Recipient *common.Address `json:"to" rlp:"nil"` - Amount *hexutil.Big `json:"value" gencodec:"required"` - Payload *hexutil.Bytes `json:"input" gencodec:"required"` + AccountNonce *hexutil.Uint64 `json:"nonce" gencodec:"required"` + Price *hexutil.Big `json:"gasPrice" gencodec:"required"` + GasLimit *hexutil.Uint64 `json:"gas" gencodec:"required"` + ShardID *uint32 `json:"shardID" gencodec:"required"` + ToShardID *uint32 `json:"toShardID"` + Recipient *common.Address `json:"to" rlp:"nil"` + Amount *hexutil.Big `json:"value" gencodec:"required"` + Payload *hexutil.Bytes `json:"input" gencodec:"required"` V *hexutil.Big `json:"v" gencodec:"required"` R *hexutil.Big `json:"r" gencodec:"required"` S *hexutil.Big `json:"s" gencodec:"required"` @@ -66,10 +69,6 @@ func (t *txdata) UnmarshalJSON(input []byte) error { return errors.New("missing required field 'nonce' for txdata") } t.AccountNonce = uint64(*dec.AccountNonce) - if dec.ShardID == nil { - return errors.New("missing required field 'shardID' for txdata") - } - t.ShardID = *dec.ShardID if dec.Price == nil { return errors.New("missing required field 'gasPrice' for txdata") } @@ -78,6 +77,13 @@ func (t *txdata) UnmarshalJSON(input []byte) error { return errors.New("missing required field 'gas' for txdata") } t.GasLimit = uint64(*dec.GasLimit) + if dec.ShardID == nil { + return errors.New("missing required field 'shardID' for txdata") + } + t.ShardID = *dec.ShardID + if dec.ToShardID != nil { + t.ToShardID = *dec.ToShardID + } if dec.Recipient != nil { t.Recipient = dec.Recipient } diff --git a/core/types/transaction.go b/core/types/transaction.go index 12ae4a06e..7efce4a9e 100644 --- a/core/types/transaction.go +++ b/core/types/transaction.go @@ -50,7 +50,7 @@ type txdata struct { Price *big.Int `json:"gasPrice" gencodec:"required"` GasLimit uint64 `json:"gas" gencodec:"required"` ShardID uint32 `json:"shardID" gencodec:"required"` - ToShardID uint32 `json:"toShardID" gencodec:"required"` + ToShardID uint32 `json:"toShardID"` Recipient *common.Address `json:"to" rlp:"nil"` // nil means contract creation Amount *big.Int `json:"value" gencodec:"required"` Payload []byte `json:"input" gencodec:"required"` @@ -111,6 +111,34 @@ func newTransaction(nonce uint64, to *common.Address, shardID uint32, amount *bi return &Transaction{data: d} } +// create new cross-shard transaction +func newCrossShardTransaction(nonce uint64, to *common.Address, shardID uint32, toShardID uint32, amount *big.Int, gasLimit uint64, gasPrice *big.Int, data []byte) *Transaction { + if len(data) > 0 { + data = common.CopyBytes(data) + } + d := txdata{ + AccountNonce: nonce, + Recipient: to, + ShardID: shardID, + ToShardID: toShardID, + Payload: data, + Amount: new(big.Int), + GasLimit: gasLimit, + Price: new(big.Int), + V: new(big.Int), + R: new(big.Int), + S: new(big.Int), + } + if amount != nil { + d.Amount.Set(amount) + } + if gasPrice != nil { + d.Price.Set(gasPrice) + } + + return &Transaction{data: d} +} + // ChainID returns which chain id this transaction was signed for (if at all) func (tx *Transaction) ChainID() *big.Int { return deriveChainID(tx.data.V) @@ -121,6 +149,11 @@ func (tx *Transaction) ShardID() uint32 { return tx.data.ShardID } +// ToShardID returns the destination shard id this transaction is going to +func (tx *Transaction) ToShardID() uint32 { + return tx.data.ToShardID +} + // Protected returns whether the transaction is protected from replay protection. func (tx *Transaction) Protected() bool { return isProtectedV(tx.data.V)