Skip to content

Commit

Permalink
Moves ConfidentialInputs into the ConfidentialComputeRequest
Browse files Browse the repository at this point in the history
  • Loading branch information
Ruteri committed Oct 6, 2023
1 parent 309f203 commit 7adc7b1
Show file tree
Hide file tree
Showing 17 changed files with 430 additions and 170 deletions.
94 changes: 69 additions & 25 deletions core/types/confidential.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,28 +6,30 @@ import (
"github.com/ethereum/go-ethereum/common"
)

type ConfidentialComputeRequest struct {
type ConfidentialComputeRecord struct {
Nonce uint64
GasPrice *big.Int
Gas uint64
To *common.Address `rlp:"nil"`
Value *big.Int
Data []byte

ExecutionNode common.Address
ExecutionNode common.Address
ConfidentialInputsHash common.Hash

ChainID *big.Int
V, R, S *big.Int
}

// copy creates a deep copy of the transaction data and initializes all fields.
func (tx *ConfidentialComputeRequest) copy() TxData {
cpy := &ConfidentialComputeRequest{
Nonce: tx.Nonce,
To: copyAddressPtr(tx.To),
Data: common.CopyBytes(tx.Data),
Gas: tx.Gas,
ExecutionNode: tx.ExecutionNode,
func (tx *ConfidentialComputeRecord) copy() TxData {
cpy := &ConfidentialComputeRecord{
Nonce: tx.Nonce,
To: copyAddressPtr(tx.To),
Data: common.CopyBytes(tx.Data),
Gas: tx.Gas,
ExecutionNode: tx.ExecutionNode,
ConfidentialInputsHash: tx.ConfidentialInputsHash,

Value: new(big.Int),
GasPrice: new(big.Int),
Expand Down Expand Up @@ -60,6 +62,48 @@ func (tx *ConfidentialComputeRequest) copy() TxData {
return cpy
}

func (tx *ConfidentialComputeRecord) txType() byte { return ConfidentialComputeRecordTxType }
func (tx *ConfidentialComputeRecord) chainID() *big.Int { return tx.ChainID }
func (tx *ConfidentialComputeRecord) accessList() AccessList { return nil }
func (tx *ConfidentialComputeRecord) data() []byte { return tx.Data }
func (tx *ConfidentialComputeRecord) gas() uint64 { return tx.Gas }
func (tx *ConfidentialComputeRecord) gasPrice() *big.Int { return tx.GasPrice }
func (tx *ConfidentialComputeRecord) gasTipCap() *big.Int { return tx.GasPrice }
func (tx *ConfidentialComputeRecord) gasFeeCap() *big.Int { return tx.GasPrice }
func (tx *ConfidentialComputeRecord) value() *big.Int { return tx.Value }
func (tx *ConfidentialComputeRecord) nonce() uint64 { return tx.Nonce }
func (tx *ConfidentialComputeRecord) to() *common.Address { return tx.To }
func (tx *ConfidentialComputeRecord) blobGas() uint64 { return 0 }
func (tx *ConfidentialComputeRecord) blobGasFeeCap() *big.Int { return nil }
func (tx *ConfidentialComputeRecord) blobHashes() []common.Hash { return nil }

func (tx *ConfidentialComputeRecord) effectiveGasPrice(dst *big.Int, baseFee *big.Int) *big.Int {
return dst.Set(tx.GasPrice)
}

func (tx *ConfidentialComputeRecord) rawSignatureValues() (v, r, s *big.Int) {
return tx.V, tx.R, tx.S
}

func (tx *ConfidentialComputeRecord) setSignatureValues(chainID, v, r, s *big.Int) {
tx.ChainID, tx.V, tx.R, tx.S = chainID, v, r, s
}

type ConfidentialComputeRequest struct {
ConfidentialComputeRecord
ConfidentialInputs []byte
}

// copy creates a deep copy of the transaction data and initializes all fields.
func (tx *ConfidentialComputeRequest) copy() TxData {
cpy := &ConfidentialComputeRequest{
ConfidentialComputeRecord: *(tx.ConfidentialComputeRecord.copy().(*ConfidentialComputeRecord)),
ConfidentialInputs: tx.ConfidentialInputs,
}

return cpy
}

func (tx *ConfidentialComputeRequest) txType() byte { return ConfidentialComputeRequestTxType }
func (tx *ConfidentialComputeRequest) chainID() *big.Int { return tx.ChainID }
func (tx *ConfidentialComputeRequest) accessList() AccessList { return nil }
Expand Down Expand Up @@ -88,9 +132,9 @@ func (tx *ConfidentialComputeRequest) setSignatureValues(chainID, v, r, s *big.I
}

type SuaveTransaction struct {
ExecutionNode common.Address `json:"executionNode" gencodec:"required"`
ConfidentialComputeRequest Transaction `json:"confidentialComputeRequest" gencodec:"required"`
ConfidentialComputeResult []byte `json:"confidentialComputeResult" gencodec:"required"`
ExecutionNode common.Address `json:"executionNode" gencodec:"required"`
ConfidentialComputeRequest ConfidentialComputeRecord `json:"confidentialComputeRequest" gencodec:"required"`
ConfidentialComputeResult []byte `json:"confidentialComputeResult" gencodec:"required"`

// ExecutionNode's signature
ChainID *big.Int
Expand All @@ -103,7 +147,7 @@ type SuaveTransaction struct {
func (tx *SuaveTransaction) copy() TxData {
cpy := &SuaveTransaction{
ExecutionNode: tx.ExecutionNode,
ConfidentialComputeRequest: *NewTx(tx.ConfidentialComputeRequest.inner),
ConfidentialComputeRequest: tx.ConfidentialComputeRequest,
ConfidentialComputeResult: common.CopyBytes(tx.ConfidentialComputeResult),
ChainID: new(big.Int),
V: new(big.Int),
Expand Down Expand Up @@ -140,31 +184,31 @@ func (tx *SuaveTransaction) data() []byte {
// Rest is carried over from wrapped tx
func (tx *SuaveTransaction) chainID() *big.Int { return tx.ChainID }
func (tx *SuaveTransaction) accessList() AccessList {
return tx.ConfidentialComputeRequest.inner.accessList()
return tx.ConfidentialComputeRequest.accessList()
}
func (tx *SuaveTransaction) gas() uint64 { return tx.ConfidentialComputeRequest.inner.gas() }
func (tx *SuaveTransaction) gas() uint64 { return tx.ConfidentialComputeRequest.gas() }
func (tx *SuaveTransaction) gasFeeCap() *big.Int {
return tx.ConfidentialComputeRequest.inner.gasFeeCap()
return tx.ConfidentialComputeRequest.gasFeeCap()
}
func (tx *SuaveTransaction) gasTipCap() *big.Int {
return tx.ConfidentialComputeRequest.inner.gasTipCap()
return tx.ConfidentialComputeRequest.gasTipCap()
}
func (tx *SuaveTransaction) gasPrice() *big.Int {
return tx.ConfidentialComputeRequest.inner.gasFeeCap()
return tx.ConfidentialComputeRequest.gasFeeCap()
}
func (tx *SuaveTransaction) value() *big.Int { return tx.ConfidentialComputeRequest.inner.value() }
func (tx *SuaveTransaction) nonce() uint64 { return tx.ConfidentialComputeRequest.inner.nonce() }
func (tx *SuaveTransaction) to() *common.Address { return tx.ConfidentialComputeRequest.inner.to() }
func (tx *SuaveTransaction) blobGas() uint64 { return tx.ConfidentialComputeRequest.inner.blobGas() }
func (tx *SuaveTransaction) value() *big.Int { return tx.ConfidentialComputeRequest.value() }
func (tx *SuaveTransaction) nonce() uint64 { return tx.ConfidentialComputeRequest.nonce() }
func (tx *SuaveTransaction) to() *common.Address { return tx.ConfidentialComputeRequest.to() }
func (tx *SuaveTransaction) blobGas() uint64 { return tx.ConfidentialComputeRequest.blobGas() }
func (tx *SuaveTransaction) blobGasFeeCap() *big.Int {
return tx.ConfidentialComputeRequest.inner.blobGasFeeCap()
return tx.ConfidentialComputeRequest.blobGasFeeCap()
}
func (tx *SuaveTransaction) blobHashes() []common.Hash {
return tx.ConfidentialComputeRequest.inner.blobHashes()
return tx.ConfidentialComputeRequest.blobHashes()
}

func (tx *SuaveTransaction) effectiveGasPrice(dst *big.Int, baseFee *big.Int) *big.Int {
return tx.ConfidentialComputeRequest.inner.effectiveGasPrice(dst, baseFee)
return tx.ConfidentialComputeRequest.effectiveGasPrice(dst, baseFee)
}

func (tx *SuaveTransaction) rawSignatureValues() (v, r, s *big.Int) {
Expand Down
46 changes: 44 additions & 2 deletions core/types/confidential_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,45 @@ import (
"github.com/stretchr/testify/require"
)

func TestCCRequestToRecord(t *testing.T) {
testKey, err := crypto.HexToECDSA("b71c71a67e1177ad4e901695e1b4b9ee17ae16c6668d313eac2f96dbcda3f291")
require.NoError(t, err)

signer := NewSuaveSigner(new(big.Int))
unsignedTx := NewTx(&ConfidentialComputeRequest{
ConfidentialComputeRecord: ConfidentialComputeRecord{
ExecutionNode: crypto.PubkeyToAddress(testKey.PublicKey),
},
ConfidentialInputs: []byte{0x46},
})
signedTx, err := SignTx(unsignedTx, signer, testKey)
require.NoError(t, err)

recoveredSender, err := signer.Sender(signedTx)
require.NoError(t, err)

require.Equal(t, crypto.PubkeyToAddress(testKey.PublicKey), recoveredSender)

marshalledTxBytes, err := signedTx.MarshalBinary()
require.NoError(t, err)

unmarshalledTx := new(Transaction)
require.NoError(t, unmarshalledTx.UnmarshalBinary(marshalledTxBytes))

recoveredUnmarshalledSender, err := signer.Sender(unmarshalledTx)
require.NoError(t, err)

require.Equal(t, crypto.PubkeyToAddress(testKey.PublicKey), recoveredUnmarshalledSender)

signedRequestInner, ok := CastTxInner[*ConfidentialComputeRequest](unmarshalledTx)
require.True(t, ok)

recoveredRecordSender, err := signer.Sender(NewTx(&signedRequestInner.ConfidentialComputeRecord))
require.NoError(t, err)

require.Equal(t, crypto.PubkeyToAddress(testKey.PublicKey), recoveredRecordSender)
}

func TestCCR(t *testing.T) {
testKey, err := crypto.HexToECDSA("b71c71a67e1177ad4e901695e1b4b9ee17ae16c6668d313eac2f96dbcda3f291")
require.NoError(t, err)
Expand Down Expand Up @@ -40,14 +79,17 @@ func TestSuaveTx(t *testing.T) {

signer := NewSuaveSigner(new(big.Int))

signedCCR, err := SignTx(NewTx(&ConfidentialComputeRequest{
signedCCR, err := SignTx(NewTx(&ConfidentialComputeRecord{
ExecutionNode: crypto.PubkeyToAddress(testKey.PublicKey),
}), signer, testKey)
require.NoError(t, err)

signedInnerCCR, ok := CastTxInner[*ConfidentialComputeRecord](signedCCR)
require.True(t, ok)

unsignedTx := NewTx(&SuaveTransaction{
ExecutionNode: crypto.PubkeyToAddress(testKey.PublicKey),
ConfidentialComputeRequest: *signedCCR,
ConfidentialComputeRequest: *signedInnerCCR,
})
signedTx, err := SignTx(unsignedTx, signer, testKey)
require.NoError(t, err)
Expand Down
5 changes: 3 additions & 2 deletions core/types/transaction.go
Original file line number Diff line number Diff line change
Expand Up @@ -46,8 +46,9 @@ const (
AccessListTxType = 0x01
DynamicFeeTxType = 0x02
BlobTxType = 0x03
ConfidentialComputeRequestTxType = 0x42
SuaveTxType = 0x43
ConfidentialComputeRecordTxType = 0x42
ConfidentialComputeRequestTxType = 0x43
SuaveTxType = 0x50
)

// Transaction is an Ethereum transaction.
Expand Down
94 changes: 91 additions & 3 deletions core/types/transaction_marshalling.go
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,8 @@ type txJSON struct {
AccessList *AccessList `json:"accessList,omitempty"`
BlobVersionedHashes []common.Hash `json:"blobVersionedHashes,omitempty"`
ExecutionNode *common.Address `json:"executionNode,omitempty"`
ConfidentialInputsHash common.Hash `json:"confidentialInputsHash,omitempty"`
ConfidentialInputsHash *common.Hash `json:"confidentialInputsHash,omitempty"`
ConfidentialInputs *hexutil.Bytes `json:"confidentialInputs,omitempty"`
Wrapped *json.RawMessage `json:"wrapped,omitempty"`
ConfidentialComputeResult *hexutil.Bytes `json:"confidentialComputeResult,omitempty"`
V *hexutil.Big `json:"v"`
Expand Down Expand Up @@ -117,8 +118,24 @@ func (tx *Transaction) MarshalJSON() ([]byte, error) {
enc.R = (*hexutil.Big)(itx.R.ToBig())
enc.S = (*hexutil.Big)(itx.S.ToBig())

case *ConfidentialComputeRecord:
enc.ExecutionNode = &itx.ExecutionNode
enc.ConfidentialInputsHash = &itx.ConfidentialInputsHash
enc.Nonce = (*hexutil.Uint64)(&itx.Nonce)
enc.To = tx.To()
enc.Gas = (*hexutil.Uint64)(&itx.Gas)
enc.GasPrice = (*hexutil.Big)(itx.GasPrice)
enc.Value = (*hexutil.Big)(itx.Value)
enc.Input = (*hexutil.Bytes)(&itx.Data)
enc.ChainID = (*hexutil.Big)(itx.ChainID)
enc.V = (*hexutil.Big)(itx.V)
enc.R = (*hexutil.Big)(itx.R)
enc.S = (*hexutil.Big)(itx.S)

case *ConfidentialComputeRequest:
enc.ExecutionNode = &itx.ExecutionNode
enc.ConfidentialInputs = (*hexutil.Bytes)(&itx.ConfidentialInputs)
enc.ConfidentialInputsHash = &itx.ConfidentialInputsHash
enc.Nonce = (*hexutil.Uint64)(&itx.Nonce)
enc.To = tx.To()
enc.Gas = (*hexutil.Uint64)(&itx.Gas)
Expand All @@ -133,7 +150,7 @@ func (tx *Transaction) MarshalJSON() ([]byte, error) {
case *SuaveTransaction:
enc.ExecutionNode = &itx.ExecutionNode

wrapped, err := itx.ConfidentialComputeRequest.MarshalJSON()
wrapped, err := NewTx(&itx.ConfidentialComputeRequest).MarshalJSON()
if err != nil {
return nil, err
}
Expand Down Expand Up @@ -380,6 +397,65 @@ func (tx *Transaction) UnmarshalJSON(input []byte) error {
}
}

case ConfidentialComputeRecordTxType:
var itx ConfidentialComputeRequest
inner = &itx

if dec.ExecutionNode == nil {
return errors.New("missing required field 'executionNode' in transaction")
}
itx.ExecutionNode = *dec.ExecutionNode

if dec.ConfidentialInputsHash != nil {
itx.ConfidentialInputsHash = *dec.ConfidentialInputsHash
}

if dec.Nonce == nil {
return errors.New("missing required field 'nonce' in transaction")
}
itx.Nonce = uint64(*dec.Nonce)
if dec.To != nil {
itx.To = dec.To
}
if dec.Gas == nil {
return errors.New("missing required field 'gas' in transaction")
}
itx.Gas = uint64(*dec.Gas)
if dec.GasPrice == nil {
return errors.New("missing required field 'gasPrice' in transaction")
}
itx.GasPrice = (*big.Int)(dec.GasPrice)
if dec.Value == nil {
return errors.New("missing required field 'value' in transaction")
}
itx.Value = (*big.Int)(dec.Value)
if dec.Input == nil {
return errors.New("missing required field 'input' in transaction")
}
itx.Data = *dec.Input
if dec.ChainID == nil {
return errors.New("missing required field 'chainId' in transaction")
}
itx.ChainID = (*big.Int)(dec.ChainID)
if dec.V == nil {
return errors.New("missing required field 'r' in transaction")
}
itx.V = (*big.Int)(dec.V)
if dec.R == nil {
return errors.New("missing required field 'r' in transaction")
}
itx.R = (*big.Int)(dec.R)
if dec.S == nil {
return errors.New("missing required field 's' in transaction")
}
itx.S = (*big.Int)(dec.S)
withSignature := itx.V.Sign() != 0 || itx.R.Sign() != 0 || itx.S.Sign() != 0
if withSignature {
if err := sanityCheckSignature(itx.V, itx.R, itx.S, false); err != nil {
return err
}
}

case ConfidentialComputeRequestTxType:
var itx ConfidentialComputeRequest
inner = &itx
Expand All @@ -389,6 +465,14 @@ func (tx *Transaction) UnmarshalJSON(input []byte) error {
}
itx.ExecutionNode = *dec.ExecutionNode

if dec.ConfidentialInputsHash != nil {
itx.ConfidentialInputsHash = *dec.ConfidentialInputsHash
}

if dec.ConfidentialInputs != nil {
itx.ConfidentialInputs = *dec.ConfidentialInputs
}

if dec.Nonce == nil {
return errors.New("missing required field 'nonce' in transaction")
}
Expand Down Expand Up @@ -455,7 +539,11 @@ func (tx *Transaction) UnmarshalJSON(input []byte) error {
return err
}

itx.ConfidentialComputeRequest = wrappedTx
ccr, ok := CastTxInner[*ConfidentialComputeRecord](&wrappedTx)
if !ok {
return errors.New("wrapped tx not a ConfidentialComputeRecord")
}
itx.ConfidentialComputeRequest = *ccr

if dec.ConfidentialComputeResult != nil {
itx.ConfidentialComputeResult = ([]byte)(*dec.ConfidentialComputeResult)
Expand Down
Loading

0 comments on commit 7adc7b1

Please sign in to comment.