Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
29 commits
Select commit Hold shift + click to select a range
8d4516f
Added an empty InvokeExpressionTransaction
esuwu Dec 13, 2021
1b844ed
Added invoke expression tx, added some methods and diff
esuwu Dec 19, 2021
7d367b8
Added test
esuwu Dec 21, 2021
31be4eb
Added methods for tx, added checker and fee counter
esuwu Dec 23, 2021
2e2fdc5
Fixd transaction type in protobuf converters
esuwu Dec 23, 2021
2fd94b3
Added invocation set
esuwu Dec 24, 2021
0303c57
Merge branch 'master' into invoke-expression-tx
esuwu Dec 24, 2021
5efbde1
Added verify function for tx
esuwu Dec 24, 2021
c2b2234
Added base64 type
esuwu Dec 26, 2021
25d9c0c
Added fee validation and protobuf version for tx
esuwu Dec 27, 2021
fc22146
Added sponsorship handling
esuwu Dec 29, 2021
3bf2f6b
Merged from master
esuwu Dec 29, 2021
b13594c
Moved invocation set
esuwu Dec 29, 2021
cb18254
Moved invocation set
esuwu Jan 14, 2022
45ada7c
Merge branch 'invoke-expression-tx' of github.com:wavesplatform/gowav…
esuwu Jan 14, 2022
9a380cb
Fix formatting issues
alexeykiselev Jan 14, 2022
6d24ed0
Merge branch 'master' into invoke-expression-tx
alexeykiselev Jan 14, 2022
fbbabe0
Merge branch 'master' into invoke-expression-tx
alexeykiselev Jan 18, 2022
5ff9344
Better height logging. Better formatting.
alexeykiselev Jan 19, 2022
cc3b313
Merge branch 'master' into invoke-expression-tx
alexeykiselev Jan 19, 2022
ae6d7af
Merge branch 'master' into invoke-expression-tx
alexeykiselev Jan 20, 2022
4d2f21c
Merge branch 'master' into invoke-expression-tx
nickeskov Jan 20, 2022
07d5ad2
Added ethereum invoke expression kind
esuwu Jan 24, 2022
175c947
Added transaction object set
esuwu Jan 25, 2022
7b41b57
Merged from master
esuwu Jan 28, 2022
df14c5e
Added diff creation
esuwu Jan 28, 2022
db9cf6f
Eth invoke and ethereum tx refactoring (#657)
esuwu Feb 7, 2022
7a86bca
Merge branch 'master' into eth-invoke-expression-tx
nickeskov Feb 7, 2022
2278dd8
Merge branch 'master' into eth-invoke-expression-tx
nickeskov Feb 8, 2022
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 1 addition & 5 deletions pkg/metamask/service.go
Original file line number Diff line number Diff line change
Expand Up @@ -143,10 +143,6 @@ func (s RPCService) Eth_EstimateGas(req estimateGasRequest) (string, error) {
value = new(big.Int)
data []byte
)
if req.To == nil {
zap.S().Debug("Eth_EstimateGas: trying estimate gas for set dApp transaction")
return "", errors.New("gas estimation for set dApp transaction is not permitted")
}
if req.Value != nil {
var _, ok = value.SetString(strings.TrimPrefix(*req.Value, "0x"), 16)
if !ok {
Expand All @@ -163,7 +159,7 @@ func (s RPCService) Eth_EstimateGas(req estimateGasRequest) (string, error) {
}
}

txKind, err := state.GuessEthereumTransactionKind(data)
txKind, err := state.GuessEthereumTransactionKind(data, req.To)
if err != nil {
return "", errors.Errorf("failed to guess ethereum tx kind, %v", err)
}
Expand Down
33 changes: 31 additions & 2 deletions pkg/proto/eth_transaction.go
Original file line number Diff line number Diff line change
Expand Up @@ -129,10 +129,13 @@ func (tx *EthereumTransferAssetsErc20TxKind) String() string {

type EthereumInvokeScriptTxKind struct {
decodedData ethabi.DecodedCallData
TxID *crypto.Digest
From WavesAddress
To WavesAddress
}

func NewEthereumInvokeScriptTxKind(decodedData ethabi.DecodedCallData) *EthereumInvokeScriptTxKind {
return &EthereumInvokeScriptTxKind{decodedData: decodedData}
func NewEthereumInvokeScriptTxKind(decodedData ethabi.DecodedCallData, txID *crypto.Digest, from WavesAddress, to WavesAddress) *EthereumInvokeScriptTxKind {
return &EthereumInvokeScriptTxKind{decodedData: decodedData, TxID: txID, From: from, To: to}
}

func (tx *EthereumInvokeScriptTxKind) DecodedData() *ethabi.DecodedCallData {
Expand All @@ -143,6 +146,32 @@ func (tx *EthereumInvokeScriptTxKind) String() string {
return "EthereumInvokeScriptTxKind"
}

func (tx *EthereumInvokeScriptTxKind) markerInvokeScriptTx() {

}

type EthereumInvokeExpressionTxKind struct {
Expression string
TxID *crypto.Digest
From WavesAddress
}

func NewEthereumInvokeExpressionTxKind(expression string, txID *crypto.Digest, from WavesAddress) *EthereumInvokeExpressionTxKind {
return &EthereumInvokeExpressionTxKind{Expression: expression, TxID: txID, From: from}
}

func (tx *EthereumInvokeExpressionTxKind) DecodedData() *ethabi.DecodedCallData {
return nil
}

func (tx *EthereumInvokeExpressionTxKind) String() string {
return "EthereumInvokeExpressionTxKind"
}

func (tx *EthereumInvokeExpressionTxKind) markerInvokeExpressionTx() {

}

type EthereumTransaction struct {
inner EthereumTxData
innerBinarySize int
Expand Down
41 changes: 41 additions & 0 deletions pkg/proto/invoke_union.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
package proto

import "github.com/wavesplatform/gowaves/pkg/crypto"

type InvokeTxUnion interface {
TxID() crypto.Digest
}

type InvokeScriptSubTransaction interface {
markerInvokeScriptTx()
}

type InvokeExpressionSubTransaction interface {
markerInvokeExpressionTx()
}

type InvokeScriptTxUnion struct {
SubTx InvokeScriptSubTransaction
txID crypto.Digest
}

func NewInvokeScriptTxUnion(subTransaction InvokeScriptSubTransaction, id crypto.Digest) *InvokeScriptTxUnion {
return &InvokeScriptTxUnion{SubTx: subTransaction, txID: id}
}

func (invScript InvokeScriptTxUnion) TxID() crypto.Digest {
return invScript.txID
}

type InvokeExpressionTxUnion struct {
SubTx InvokeExpressionSubTransaction
txID crypto.Digest
}

func NewInvokeExpressionTxUnion(subTransaction InvokeExpressionSubTransaction, id crypto.Digest) *InvokeExpressionTxUnion {
return &InvokeExpressionTxUnion{SubTx: subTransaction, txID: id}
}

func (invExp InvokeExpressionTxUnion) TxID() crypto.Digest {
return invExp.txID
}
1 change: 0 additions & 1 deletion pkg/proto/transactions.go
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,6 @@ const (
UpdateAssetInfoTransaction // 17 - UpdateAssetInfoTransaction
InvokeExpressionTransaction // 18 - InvokeExpressionTransaction
EthereumMetamaskTransaction // 19 - EthereumMetamaskTransaction is a transaction which is received from metamask

)

// TxFailureReason indicates Transactions failure reasons.
Expand Down
7 changes: 7 additions & 0 deletions pkg/proto/transactions_with_proofs.go
Original file line number Diff line number Diff line change
Expand Up @@ -4758,6 +4758,9 @@ func (tx *InvokeScriptWithProofs) ToProtobufSigned(scheme Scheme) (*g.SignedTran
}, nil
}

func (tx *InvokeScriptWithProofs) markerInvokeScriptTx() {
}

type UpdateAssetInfoWithProofs struct {
Type TransactionType `json:"type"`
Version byte `json:"version,omitempty"`
Expand Down Expand Up @@ -5136,3 +5139,7 @@ func (tx *InvokeExpressionTransactionWithProofs) ToProtobufSigned(scheme Scheme)
Proofs: tx.Proofs.Bytes(),
}, nil
}

func (tx *InvokeExpressionTransactionWithProofs) markerInvokeExpressionTx() {

}
41 changes: 17 additions & 24 deletions pkg/ride/converters.go
Original file line number Diff line number Diff line change
Expand Up @@ -886,7 +886,7 @@ func invokeScriptWithProofsToObject(scheme byte, tx *proto.InvokeScriptWithProof
return r, nil
}

// TODO think of reusing "InvokeScripTToObject" function. Also should we fill "payments" and "function name" fields"?
// TODO think of reusing "InvokeScripTToObject" function.TestEthereumInvokeWithoutPaymentsAndArguments
func invokeExpressionWithProofsToObject(scheme byte, tx *proto.InvokeExpressionTransactionWithProofs) (rideObject, error) {
sender, err := proto.NewAddressFromPublicKey(scheme, tx.SenderPK)
if err != nil {
Expand Down Expand Up @@ -982,13 +982,16 @@ func ethereumTransactionToObject(scheme proto.Scheme, tx *proto.EthereumTransact
r["bodyBytes"] = rideBytes(nil)
r["proofs"] = proofs(proto.NewProofs())

r["version"] = rideInt(tx.GetVersion())
r["id"] = rideBytes(tx.ID.Bytes())
r["sender"] = rideAddress(sender)
r["senderPublicKey"] = rideBytes(callerPK)
r["feeAssetId"] = optionalAsset(proto.NewOptionalAssetWaves())
r["timestamp"] = rideInt(tx.GetTimestamp())
r["fee"] = rideInt(tx.GetFee())
switch kind := tx.TxKind.(type) {
case *proto.EthereumTransferWavesTxKind:
r[instanceFieldName] = rideString("TransferTransaction")
r["version"] = rideInt(tx.GetVersion())
r["id"] = rideBytes(tx.ID.Bytes())
r["sender"] = rideAddress(sender)
r["senderPublicKey"] = rideBytes(callerPK)
r["recipient"] = rideRecipient(proto.NewRecipientFromAddress(*to))
r["assetId"] = optionalAsset(proto.NewOptionalAssetWaves())
res := new(big.Int).Div(tx.Value(), big.NewInt(int64(proto.DiffEthWaves)))
Expand All @@ -999,36 +1002,21 @@ func ethereumTransactionToObject(scheme proto.Scheme, tx *proto.EthereumTransact
}
amount := res.Int64()
r["amount"] = rideInt(amount)
r["fee"] = rideInt(tx.GetFee())
r["feeAssetId"] = optionalAsset(proto.NewOptionalAssetWaves())
r["attachment"] = rideBytes(nil)
r["timestamp"] = rideInt(tx.GetTimestamp())

case *proto.EthereumTransferAssetsErc20TxKind:
r[instanceFieldName] = rideString("TransferTransaction")
r["version"] = rideInt(tx.GetVersion())
r["id"] = rideBytes(tx.ID.Bytes())
r["sender"] = rideAddress(sender)
r["senderPublicKey"] = rideBytes(callerPK)

recipientAddr, err := proto.EthereumAddress(kind.Arguments.Recipient).ToWavesAddress(scheme)
if err != nil {
return nil, errors.Wrap(err, "failed to convert ethereum ERC20 transfer recipient to WavesAddress")
}
r["recipient"] = rideRecipient(proto.NewRecipientFromAddress(recipientAddr))
r["assetId"] = optionalAsset(kind.Asset)
r["amount"] = rideInt(kind.Arguments.Amount)
r["fee"] = rideInt(tx.GetFee())
r["feeAssetId"] = optionalAsset(proto.NewOptionalAssetWaves())
r["attachment"] = rideBytes(nil)
r["timestamp"] = rideInt(tx.GetTimestamp())

case *proto.EthereumInvokeScriptTxKind:
r[instanceFieldName] = rideString("InvokeScriptTransaction")
r["version"] = rideInt(tx.GetVersion())
r["id"] = rideBytes(tx.ID.Bytes())
r["sender"] = rideAddress(sender)
r["senderPublicKey"] = rideBytes(callerPK)
r["dApp"] = rideRecipient(proto.NewRecipientFromAddress(*to))

var scriptPayments []proto.ScriptPayment
Expand Down Expand Up @@ -1059,7 +1047,6 @@ func ethereumTransactionToObject(scheme proto.Scheme, tx *proto.EthereumTransact
r["payment"] = rideUnit{}
r["payments"] = make(rideList, 0)
}
r["feeAssetId"] = optionalAsset(proto.NewOptionalAssetWaves())
r["function"] = rideString(tx.TxKind.DecodedData().Name)
arguments, err := ConvertDecodedEthereumArgumentsToProtoArguments(tx.TxKind.DecodedData().Inputs)
if err != nil {
Expand All @@ -1074,9 +1061,14 @@ func ethereumTransactionToObject(scheme proto.Scheme, tx *proto.EthereumTransact
args[i] = a
}
r["args"] = args
r["fee"] = rideInt(tx.GetFee())
r["timestamp"] = rideInt(tx.GetTimestamp())

case *proto.EthereumInvokeExpressionTxKind:
r := make(rideObject)
r[instanceFieldName] = rideString("InvokeExpressionTransaction")
r["dApp"] = rideRecipient(proto.NewRecipientFromAddress(sender))
r["payment"] = rideUnit{}
r["payments"] = make(rideList, 0)
r["function"] = rideString("default")
r["args"] = rideList{}
default:
return nil, errors.New("unknown ethereum transaction kind")
}
Expand Down Expand Up @@ -1189,6 +1181,7 @@ func invocationToObject(rideVersion int, scheme byte, tx proto.Transaction) (rid
ID = *transaction.ID
FeeAsset = transaction.FeeAsset
Fee = transaction.Fee

switch rideVersion {
case 1, 2, 3:
r["payment"] = rideUnit{}
Expand Down
8 changes: 6 additions & 2 deletions pkg/ride/environment.go
Original file line number Diff line number Diff line change
Expand Up @@ -1365,8 +1365,12 @@ func (e *EvaluationEnvironment) SetInvoke(tx proto.Transaction, v int) error {
return nil
}

func (e *EvaluationEnvironment) SetEthereumInvoke(tx *proto.EthereumTransaction, v int, payments []proto.ScriptPayment) error {
obj, err := ethereumInvocationToObject(v, e.sch, tx, payments)
func (e *EvaluationEnvironment) SetEthereumInvoke(tx proto.Transaction, v int, payments []proto.ScriptPayment) error {
ethTx, ok := tx.(*proto.EthereumTransaction)
if !ok {
return errors.New("failed to transform interface to ethereum transaction")
}
obj, err := ethereumInvocationToObject(v, e.sch, ethTx, payments)
if err != nil {
return err
}
Expand Down
35 changes: 18 additions & 17 deletions pkg/state/appender.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,6 @@ import (

"github.com/mr-tron/base58/base58"
"github.com/pkg/errors"
"github.com/wavesplatform/gowaves/pkg/crypto"
"github.com/wavesplatform/gowaves/pkg/errs"
"github.com/wavesplatform/gowaves/pkg/proto"
"github.com/wavesplatform/gowaves/pkg/settings"
Expand Down Expand Up @@ -212,9 +211,9 @@ func (a *txAppender) checkTxFees(tx proto.Transaction, info *fallibleValidationP
if err != nil {
return err
}
// TODO handle ethereum invoke expression tx
// ethereum InvokeScript and InvokeExpression
case proto.EthereumMetamaskTransaction:
feeChanges, err = a.txHandler.td.createFeeDiffEthereumInvokeScriptWithProofs(tx, differInfo)
feeChanges, err = a.txHandler.td.createFeeDiffEthereumInvokeWithProofs(tx, differInfo)
if err != nil {
return err
}
Expand Down Expand Up @@ -497,9 +496,7 @@ func (a *txAppender) appendTx(tx proto.Transaction, params *appendTxParams) erro
ethTx.TxKind.String(), ethTx.ID.String(), params.checkerInfo.height+1, err,
)
}
// In UTX balances are always validated.
needToValidateBalanceDiff = params.validatingUtx
case *proto.EthereumInvokeScriptTxKind:
case *proto.EthereumInvokeScriptTxKind, *proto.EthereumInvokeExpressionTxKind:
fallibleInfo := &fallibleValidationParams{
appendTxParams: params,
senderScripted: accountHasVerifierScript,
Expand All @@ -512,7 +509,10 @@ func (a *txAppender) appendTx(tx proto.Transaction, params *appendTxParams) erro
ethTx.TxKind.String(), ethTx.ID.String(), params.checkerInfo.height+1, err,
)
}

}
// In UTX balances are always validated.
needToValidateBalanceDiff = params.validatingUtx
default:
applicationRes, err = a.handleDefaultTransaction(tx, params, accountHasVerifierScript)
if err != nil {
Expand Down Expand Up @@ -646,27 +646,28 @@ type applicationResult struct {
}

func (a *txAppender) handleInvoke(tx proto.Transaction, info *fallibleValidationParams) (*applicationResult, error) {
var ID crypto.Digest
var invokeUnion proto.InvokeTxUnion
switch t := tx.(type) {
case *proto.InvokeScriptWithProofs:
ID = *t.ID
invokeUnion = proto.NewInvokeScriptTxUnion(t, *t.ID)
case *proto.InvokeExpressionTransactionWithProofs:
ID = *t.ID
case *proto.EthereumTransaction:
// TODO: handle ethereum invoke expression tx
switch t.TxKind.(type) {
invokeUnion = proto.NewInvokeExpressionTxUnion(t, *t.ID)
case *proto.EthereumTransaction: // ethereum InvokeExpression and InvokeScript
switch kind := t.TxKind.(type) {
case *proto.EthereumInvokeScriptTxKind:
ID = *t.ID
invokeUnion = proto.NewInvokeScriptTxUnion(kind, *t.ID)
case *proto.EthereumInvokeExpressionTxKind:
invokeUnion = proto.NewInvokeExpressionTxUnion(kind, *t.ID)
default:
return nil, errors.Errorf("unexpected ethereum tx kind (%T)", tx)
return nil, errors.Errorf("failed to handle invoke: wrong type of ethereum transactiion (%T)", tx)
}
ID = *t.ID
default:
return nil, errors.Errorf("failed to handle invoke: wrong type of transaction (%T)", tx)
}
res, err := a.ia.applyInvokeScript(tx, info)

res, err := a.ia.applyInvokeScript(tx, invokeUnion, info)
if err != nil {
zap.S().Debugf("failed to apply InvokeScript transaction %s to state: %v", ID.String(), err)
zap.S().Debugf("failed to apply InvokeScript transaction %s to state: %v", invokeUnion.TxID().String(), err)
return nil, err
}
return res, nil
Expand Down
2 changes: 1 addition & 1 deletion pkg/state/block_differ.go
Original file line number Diff line number Diff line change
Expand Up @@ -125,7 +125,7 @@ func (d *blockDiffer) createFailedTransactionDiff(tx proto.Transaction, block *p
return txBalanceChanges{}, err
}
case proto.EthereumMetamaskTransaction:
txChanges, err = d.handler.td.createFeeDiffEthereumInvokeScriptWithProofs(tx, differInfo)
txChanges, err = d.handler.td.createFeeDiffEthereumInvokeWithProofs(tx, differInfo)
if err != nil {
return txBalanceChanges{}, err
}
Expand Down
Loading