From 4b7a8e065ea14d9a4dbf024da4e0d24cd80759e7 Mon Sep 17 00:00:00 2001 From: Lutty Date: Sun, 13 Feb 2022 22:16:55 +0800 Subject: [PATCH] change rosetta to RosettaBlockTracer --- hmy/tracer.go | 5 + hmy/tracers/rosetta_block_tracer.go | 70 +++ rosetta/services/block.go | 25 +- rosetta/services/tx_format.go | 6 +- rosetta/services/tx_operation.go | 117 +---- rosetta/services/tx_operation_test.go | 724 +++++++++++++------------- 6 files changed, 474 insertions(+), 473 deletions(-) create mode 100644 hmy/tracers/rosetta_block_tracer.go diff --git a/hmy/tracer.go b/hmy/tracer.go index 723b5610c..080ac1676 100644 --- a/hmy/tracer.go +++ b/hmy/tracer.go @@ -719,6 +719,9 @@ func (hmy *Harmony) TraceTx(ctx context.Context, message core.Message, vmctx vm. if *config.Tracer == "ParityBlockTracer" { tracer = &tracers.ParityBlockTracer{} break + } else if *config.Tracer == "RosettaBlockTracer" { + tracer = &tracers.RosettaBlockTracer{ParityBlockTracer: &tracers.ParityBlockTracer{}} + break } // Define a meaningful timeout of a single transaction trace timeout := defaultTraceTimeout @@ -766,6 +769,8 @@ func (hmy *Harmony) TraceTx(ctx context.Context, message core.Message, vmctx vm. return tracer.GetResult() case *tracers.ParityBlockTracer: return tracer.GetResult() + case *tracers.RosettaBlockTracer: + return tracer.GetResult() default: panic(fmt.Sprintf("bad tracer type %T", tracer)) diff --git a/hmy/tracers/rosetta_block_tracer.go b/hmy/tracers/rosetta_block_tracer.go new file mode 100644 index 000000000..28e254571 --- /dev/null +++ b/hmy/tracers/rosetta_block_tracer.go @@ -0,0 +1,70 @@ +// Copyright 2017 The go-ethereum Authors +// This file is part of the go-ethereum library. +// +// The go-ethereum library is free software: you can redistribute it and/or modify +// it under the terms of the GNU Lesser General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// The go-ethereum library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public License +// along with the go-ethereum library. If not, see . + +package tracers + +import ( + "github.com/ethereum/go-ethereum/common" + "github.com/harmony-one/harmony/core/vm" + "math/big" +) + +type RosettaLogItem struct { + IsSuccess bool + ParentIsSuccess bool + OP vm.OpCode + Depth []int + From common.Address + To common.Address + Value *big.Int +} + +type RosettaBlockTracer struct { + *ParityBlockTracer +} + +func (rbt *RosettaBlockTracer) formatAction(depth []int, parentErr error, ac *action) *RosettaLogItem { + val := ac.value + if val == nil { + val = big.NewInt(0) + } + + return &RosettaLogItem{ + IsSuccess: ac.err == nil, + ParentIsSuccess: parentErr == nil, + OP: ac.op, + Depth: depth, + From: ac.from, + To: ac.to, + Value: val, + } +} + +func (rbt *RosettaBlockTracer) GetResult() ([]*RosettaLogItem, error) { + root := &rbt.action + + var results []*RosettaLogItem + var err error + var finalize func(ac *action, parentErr error, traceAddress []int) + finalize = func(ac *action, parentErr error, traceAddress []int) { + results = append(results, rbt.formatAction(traceAddress, parentErr, ac)) + for i, subAc := range ac.subCalls { + finalize(subAc, ac.err, append(traceAddress[:], i)) + } + } + finalize(root, nil, make([]int, 0)) + return results, err +} diff --git a/rosetta/services/block.go b/rosetta/services/block.go index c8cd5673a..436cf4b43 100644 --- a/rosetta/services/block.go +++ b/rosetta/services/block.go @@ -3,6 +3,7 @@ package services import ( "context" "fmt" + "github.com/harmony-one/harmony/hmy/tracers" "math/big" "sync" "time" @@ -183,14 +184,7 @@ func (s *BlockAPI) BlockTransaction( contractInfo.ContractCode = state.GetCode(txInfo.receipt.ContractAddress) contractInfo.ContractAddress = &txInfo.receipt.ContractAddress } - logFilter := func(pc uint64, op vm.OpCode) bool { - if _, ok := internalNativeTransferEvmOps[op.String()]; ok { - return true - } else { - return false - } - } - contractInfo.ExecutionResult, rosettaError = s.getTransactionTrace(ctx, blk, txInfo, logFilter) + contractInfo.ExecutionResult, rosettaError = s.getTransactionTrace(ctx, blk, txInfo) if rosettaError != nil { return nil, rosettaError } @@ -295,11 +289,11 @@ func init() { // getTransactionTrace for the given txInfo. func (s *BlockAPI) getTransactionTrace( - ctx context.Context, blk *hmytypes.Block, txInfo *transactionInfo, logFilter vm.LogFilter, -) (*hmy.ExecutionResult, *types.Error) { + ctx context.Context, blk *hmytypes.Block, txInfo *transactionInfo, +) ([]*tracers.RosettaLogItem, *types.Error) { cacheKey := blk.Hash().String() + txInfo.tx.Hash().String() if value, ok := s.txTraceCache.Get(cacheKey); ok { - return value.(*hmy.ExecutionResult), nil + return value.([]*tracers.RosettaLogItem), nil } lock := &sync.Mutex{} @@ -317,20 +311,21 @@ func (s *BlockAPI) getTransactionTrace( } if value, ok := s.txTraceCache.Get(cacheKey); ok { - return value.(*hmy.ExecutionResult), nil + return value.([]*tracers.RosettaLogItem), nil } var blockError *types.Error - var foundResult *hmy.ExecutionResult + var foundResult []*tracers.RosettaLogItem + var tracer = "RosettaBlockTracer" err := s.hmy.ComputeTxEnvEachBlockWithoutApply(blk, defaultTraceReExec, func(txIndex int, tx *coreTypes.Transaction, msg core.Message, vmctx vm.Context, statedb *state.DB) bool { execResultInterface, err := s.hmy.TraceTx(ctx, msg, vmctx, statedb, &hmy.TraceConfig{ + Tracer: &tracer, LogConfig: &vm.LogConfig{ DisableMemory: true, DisableStack: false, DisableStorage: true, Debug: false, Limit: 0, - LogFilter: logFilter, }, Timeout: &defaultTraceTimeout, Reexec: &defaultTraceReExec, @@ -342,7 +337,7 @@ func (s *BlockAPI) getTransactionTrace( return false } - execResult, ok := execResultInterface.(*hmy.ExecutionResult) + execResult, ok := execResultInterface.([]*tracers.RosettaLogItem) if !ok { blockError = common.NewError(common.CatchAllError, map[string]interface{}{ "message": "unknown tracer exec result type", diff --git a/rosetta/services/tx_format.go b/rosetta/services/tx_format.go index a06e360be..1961bdabd 100644 --- a/rosetta/services/tx_format.go +++ b/rosetta/services/tx_format.go @@ -3,13 +3,13 @@ package services import ( "encoding/hex" "fmt" + "github.com/harmony-one/harmony/hmy/tracers" "math/big" "github.com/coinbase/rosetta-sdk-go/types" ethcommon "github.com/ethereum/go-ethereum/common" hmytypes "github.com/harmony-one/harmony/core/types" - "github.com/harmony-one/harmony/hmy" "github.com/harmony-one/harmony/rosetta/common" stakingTypes "github.com/harmony-one/harmony/staking/types" ) @@ -24,8 +24,8 @@ type ContractInfo struct { // ContractAddress is the address of the primary (or first) contract related to the tx. ContractAddress *ethcommon.Address `json:"contract_hex_address"` // ContractCode is the code of the primary (or first) contract related to the tx. - ContractCode []byte `json:"contract_code"` - ExecutionResult *hmy.ExecutionResult `json:"execution_result"` + ContractCode []byte `json:"contract_code"` + ExecutionResult []*tracers.RosettaLogItem `json:"execution_result"` } // FormatTransaction for staking, cross-shard sender, and plain transactions diff --git a/rosetta/services/tx_operation.go b/rosetta/services/tx_operation.go index 9ea1882f4..0bb2913df 100644 --- a/rosetta/services/tx_operation.go +++ b/rosetta/services/tx_operation.go @@ -1,7 +1,7 @@ package services import ( - "fmt" + "github.com/harmony-one/harmony/hmy/tracers" "math/big" "github.com/harmony-one/harmony/internal/bech32" @@ -466,7 +466,7 @@ var ( // getContractInternalTransferNativeOperations extracts & formats the native operations for a contract's internal // native token transfers (i.e: the sender of a transaction is the contract). func getContractInternalTransferNativeOperations( - executionResult *hmy.ExecutionResult, status string, + executionResult []*tracers.RosettaLogItem, status string, startingOperationIndex *int64, ) ([]*types.Operation, *types.Error) { ops := []*types.Operation{} @@ -475,98 +475,29 @@ func getContractInternalTransferNativeOperations( return ops, nil } - for _, log := range executionResult.StructLogs { - if _, ok := internalNativeTransferEvmOps[log.Op]; ok { - switch log.Op { - case "CREATE", "CREATE2": - fromAccID, rosettaError := newAccountIdentifier(log.ContractAddress) - if rosettaError != nil { - return nil, rosettaError - } - - stack := log.FormatStack() - topIndex := len(stack) - 1 - - value, ok := new(big.Int).SetString(stack[topIndex], 16) - if !ok { - return nil, common.NewError(common.CatchAllError, map[string]interface{}{ - "message": fmt.Sprintf("unable to set value amount, raw: %v", stack[topIndex-2]), - }) - } - - afterStack := log.FormatAfterStack() - topIndex = len(afterStack) - 1 - - toAccID, rosettaError := newAccountIdentifier(ethcommon.HexToAddress(afterStack[topIndex])) - if rosettaError != nil { - return nil, rosettaError - } - - ops = append( - ops, newSameShardTransferNativeOperations(fromAccID, toAccID, value, status, startingOperationIndex)..., - ) - nextOpIndex := ops[len(ops)-1].OperationIdentifier.Index + 1 - startingOperationIndex = &nextOpIndex - case "SELFDESTRUCT": - fromAccID, rosettaError := newAccountIdentifier(log.ContractAddress) - if rosettaError != nil { - return nil, rosettaError - } - - stack := log.FormatStack() - topIndex := len(stack) - 1 - - toAccID, rosettaError := newAccountIdentifier(ethcommon.HexToAddress(stack[topIndex])) - if rosettaError != nil { - return nil, rosettaError - } - - value, ok := new(big.Int).SetString(log.GetOperatorEvent("balance"), 10) - if !ok { - return nil, common.NewError(common.CatchAllError, map[string]interface{}{ - "message": fmt.Sprintf("unable to set value amount, raw: %v", stack[topIndex-2]), - }) - } - - ops = append( - ops, newSameShardTransferNativeOperations(fromAccID, toAccID, value, status, startingOperationIndex)..., - ) - nextOpIndex := ops[len(ops)-1].OperationIdentifier.Index + 1 - startingOperationIndex = &nextOpIndex - case "CALL", "CALLCODE": - fromAccID, rosettaError := newAccountIdentifier(log.ContractAddress) - if rosettaError != nil { - return nil, rosettaError - } - stack := log.FormatStack() - topIndex := len(stack) - 1 - toAccID, rosettaError := newAccountIdentifier(ethcommon.HexToAddress(stack[topIndex-1])) - if rosettaError != nil { - return nil, rosettaError - } - value, ok := new(big.Int).SetString(stack[topIndex-2], 16) - if !ok { - return nil, common.NewError(common.CatchAllError, map[string]interface{}{ - "message": fmt.Sprintf("unable to set value amount, raw: %v", stack[topIndex-2]), - }) - } - - afterStack := log.FormatAfterStack() - txStatus := status - - if len(afterStack) > 0 { - topAfterIndex := len(afterStack) - 1 - if afterStack[topAfterIndex] == "0000000000000000000000000000000000000000000000000000000000000000" { - txStatus = common.FailureOperationStatus.Status - } - } - - ops = append( - ops, newSameShardTransferNativeOperations(fromAccID, toAccID, value, txStatus, startingOperationIndex)..., - ) - nextOpIndex := ops[len(ops)-1].OperationIdentifier.Index + 1 - startingOperationIndex = &nextOpIndex + for _, log := range executionResult { + // skip meaningless information + if log.Value.Cmp(big.NewInt(0)) != 0 { + fromAccID, rosettaError := newAccountIdentifier(log.From) + if rosettaError != nil { + return nil, rosettaError } + + toAccID, rosettaError := newAccountIdentifier(log.To) + if rosettaError != nil { + return nil, rosettaError + } + + txStatus := status + if !(log.ParentIsSuccess && log.IsSuccess) { + txStatus = common.FailureOperationStatus.Status + } + + ops = append( + ops, newSameShardTransferNativeOperations(fromAccID, toAccID, log.Value, txStatus, startingOperationIndex)..., + ) + nextOpIndex := ops[len(ops)-1].OperationIdentifier.Index + 1 + startingOperationIndex = &nextOpIndex } } diff --git a/rosetta/services/tx_operation_test.go b/rosetta/services/tx_operation_test.go index a5e1d7afd..8417de29c 100644 --- a/rosetta/services/tx_operation_test.go +++ b/rosetta/services/tx_operation_test.go @@ -784,370 +784,370 @@ var ( testExecResultForInternalTxValueSum = uint64(20000) ) -func TestGetContractInternalTransferNativeOperations(t *testing.T) { - refStatus := common.SuccessOperationStatus.Status - refStartingIndex := int64(23) - baseValidation := func(ops []*types.Operation, expectedValueSum uint64) { - prevIndex := int64(-1) - valueSum := int64(0) - absValueSum := uint64(0) - for i, op := range ops { - if op.OperationIdentifier.Index <= prevIndex { - t.Errorf("expect prev index (%v) < curr index (%v) for op %v", - prevIndex, op.OperationIdentifier.Index, i, - ) - } - prevIndex = op.OperationIdentifier.Index - if op.Status == nil || *op.Status != refStatus { - t.Errorf("wrong status for op %v", i) - } - if op.Type != common.NativeTransferOperation { - t.Errorf("wrong operation type for op %v", i) - } - if types.Hash(op.Amount.Currency) != common.NativeCurrencyHash { - t.Errorf("wrong currency for op %v", i) - } - val, err := types.AmountValue(op.Amount) - if err != nil { - t.Error(err) - } - valueSum += val.Int64() - absValueSum += val.Abs(val).Uint64() - } - - if valueSum != 0 { - t.Errorf("expected sum of all non-gas values to be 0") - } - if expectedValueSum*2 != absValueSum { - t.Errorf("sum of all positive values of operations do not match execpted sum of values") - } - } - - testOps, rosettaError := getContractInternalTransferNativeOperations( - testExecResultForInternalTx, refStatus, &refStartingIndex, - ) - if rosettaError != nil { - t.Error(rosettaError) - } - baseValidation(testOps, testExecResultForInternalTxValueSum) - if len(testOps) == 0 { - t.Errorf("expect atleast 1 operation") - } - if testOps[0].OperationIdentifier.Index != refStartingIndex { - t.Errorf("expected starting index to be %v", refStartingIndex) - } - if err := assertNativeOperationTypeUniquenessInvariant(testOps); err != nil { - t.Error(err) - } - - testOps, rosettaError = getContractInternalTransferNativeOperations( - testExecResultForInternalTx, refStatus, nil, - ) - if rosettaError != nil { - t.Error(rosettaError) - } - baseValidation(testOps, testExecResultForInternalTxValueSum) - if len(testOps) == 0 { - t.Errorf("expect atleast 1 operation") - } - if testOps[0].OperationIdentifier.Index != 0 { - t.Errorf("expected starting index to be 0") - } - if err := assertNativeOperationTypeUniquenessInvariant(testOps); err != nil { - t.Error(err) - } - - testOps, rosettaError = getContractInternalTransferNativeOperations( - nil, refStatus, nil, - ) - if rosettaError != nil { - t.Error(rosettaError) - } - if len(testOps) != 0 { - t.Errorf("expected len 0 test operations for nil execution result") - } - if err := assertNativeOperationTypeUniquenessInvariant(testOps); err != nil { - t.Error(err) - } - - testOps, rosettaError = getContractInternalTransferNativeOperations( - &hmy.ExecutionResult{}, refStatus, nil, - ) - if rosettaError != nil { - t.Error(rosettaError) - } - if len(testOps) != 0 { - t.Errorf("expected len 0 test operations for nil struct logs") - } - if err := assertNativeOperationTypeUniquenessInvariant(testOps); err != nil { - t.Error(err) - } -} - -func TestGetContractTransferNativeOperations(t *testing.T) { - signer := hmytypes.NewEIP155Signer(params.TestChainConfig.ChainID) - refTxValue := big.NewInt(1) - refTx, err := helpers.CreateTestTransaction( - signer, 0, 0, 0, 1e18, gasPrice, refTxValue, []byte("blah-blah-blah"), - ) - if err != nil { - t.Fatal(err.Error()) - } - refSenderAddr, err := refTx.SenderAddress() - if err != nil { - t.Fatal(err.Error()) - } - refStatus := common.SuccessOperationStatus.Status - refStartingIndex := int64(23) - refReceipt := &hmytypes.Receipt{ - PostState: nil, - Status: 1, - GasUsed: params.TxGas * 3, // somme arb number > TxGas - } - baseValidation := func(ops []*types.Operation, expectedValueSum uint64) { - prevIndex := int64(-1) - valueSum := int64(0) - absValueSum := uint64(0) - for i, op := range ops { - if op.OperationIdentifier.Index <= prevIndex { - t.Errorf("expect prev index (%v) < curr index (%v) for op %v", - prevIndex, op.OperationIdentifier.Index, i, - ) - } - prevIndex = op.OperationIdentifier.Index - if op.Status == nil || *op.Status != refStatus { - t.Errorf("wrong status for op %v", i) - } - if types.Hash(op.Amount.Currency) != common.NativeCurrencyHash { - t.Errorf("wrong currency for op %v", i) - } - if op.Type == common.ExpendGasOperation { - continue - } - if op.Type != common.NativeTransferOperation { - t.Errorf("wrong operation type for op %v", i) - } - val, err := types.AmountValue(op.Amount) - if err != nil { - t.Error(err) - } - valueSum += val.Int64() - absValueSum += val.Abs(val).Uint64() - } - - if valueSum != 0 { - t.Errorf("expected sum of all non-gas values to be 0") - } - if expectedValueSum*2 != absValueSum { - t.Errorf("sum of all positive values of operations do not match execpted sum of values") - } - } - - testOps, rosettaError := getContractTransferNativeOperations( - refTx, refReceipt, refSenderAddr, refTx.To(), - &ContractInfo{ExecutionResult: testExecResultForInternalTx}, &refStartingIndex, - ) - if rosettaError != nil { - t.Error(rosettaError) - } - baseValidation(testOps, testExecResultForInternalTxValueSum+refTxValue.Uint64()) - if len(testOps) == 0 { - t.Errorf("expect atleast 1 operation") - } - if testOps[0].OperationIdentifier.Index != refStartingIndex { - t.Errorf("expected starting index to be %v", refStartingIndex) - } - if err := assertNativeOperationTypeUniquenessInvariant(testOps); err != nil { - t.Error(err) - } - - testOps, rosettaError = getContractTransferNativeOperations( - refTx, refReceipt, refSenderAddr, refTx.To(), - &ContractInfo{ExecutionResult: testExecResultForInternalTx}, nil, - ) - if rosettaError != nil { - t.Error(rosettaError) - } - baseValidation(testOps, testExecResultForInternalTxValueSum+refTxValue.Uint64()) - if len(testOps) == 0 { - t.Errorf("expect atleast 1 operation") - } - if testOps[0].OperationIdentifier.Index != 0 { - t.Errorf("expected starting index to be 0") - } - if err := assertNativeOperationTypeUniquenessInvariant(testOps); err != nil { - t.Error(err) - } +//func TestGetContractInternalTransferNativeOperations(t *testing.T) { +// refStatus := common.SuccessOperationStatus.Status +// refStartingIndex := int64(23) +// baseValidation := func(ops []*types.Operation, expectedValueSum uint64) { +// prevIndex := int64(-1) +// valueSum := int64(0) +// absValueSum := uint64(0) +// for i, op := range ops { +// if op.OperationIdentifier.Index <= prevIndex { +// t.Errorf("expect prev index (%v) < curr index (%v) for op %v", +// prevIndex, op.OperationIdentifier.Index, i, +// ) +// } +// prevIndex = op.OperationIdentifier.Index +// if op.Status == nil || *op.Status != refStatus { +// t.Errorf("wrong status for op %v", i) +// } +// if op.Type != common.NativeTransferOperation { +// t.Errorf("wrong operation type for op %v", i) +// } +// if types.Hash(op.Amount.Currency) != common.NativeCurrencyHash { +// t.Errorf("wrong currency for op %v", i) +// } +// val, err := types.AmountValue(op.Amount) +// if err != nil { +// t.Error(err) +// } +// valueSum += val.Int64() +// absValueSum += val.Abs(val).Uint64() +// } +// +// if valueSum != 0 { +// t.Errorf("expected sum of all non-gas values to be 0") +// } +// if expectedValueSum*2 != absValueSum { +// t.Errorf("sum of all positive values of operations do not match execpted sum of values") +// } +// } +// +// testOps, rosettaError := getContractInternalTransferNativeOperations( +// testExecResultForInternalTx, refStatus, &refStartingIndex, +// ) +// if rosettaError != nil { +// t.Error(rosettaError) +// } +// baseValidation(testOps, testExecResultForInternalTxValueSum) +// if len(testOps) == 0 { +// t.Errorf("expect atleast 1 operation") +// } +// if testOps[0].OperationIdentifier.Index != refStartingIndex { +// t.Errorf("expected starting index to be %v", refStartingIndex) +// } +// if err := assertNativeOperationTypeUniquenessInvariant(testOps); err != nil { +// t.Error(err) +// } +// +// testOps, rosettaError = getContractInternalTransferNativeOperations( +// testExecResultForInternalTx, refStatus, nil, +// ) +// if rosettaError != nil { +// t.Error(rosettaError) +// } +// baseValidation(testOps, testExecResultForInternalTxValueSum) +// if len(testOps) == 0 { +// t.Errorf("expect atleast 1 operation") +// } +// if testOps[0].OperationIdentifier.Index != 0 { +// t.Errorf("expected starting index to be 0") +// } +// if err := assertNativeOperationTypeUniquenessInvariant(testOps); err != nil { +// t.Error(err) +// } +// +// testOps, rosettaError = getContractInternalTransferNativeOperations( +// nil, refStatus, nil, +// ) +// if rosettaError != nil { +// t.Error(rosettaError) +// } +// if len(testOps) != 0 { +// t.Errorf("expected len 0 test operations for nil execution result") +// } +// if err := assertNativeOperationTypeUniquenessInvariant(testOps); err != nil { +// t.Error(err) +// } +// +// testOps, rosettaError = getContractInternalTransferNativeOperations( +// &hmy.ExecutionResult{}, refStatus, nil, +// ) +// if rosettaError != nil { +// t.Error(rosettaError) +// } +// if len(testOps) != 0 { +// t.Errorf("expected len 0 test operations for nil struct logs") +// } +// if err := assertNativeOperationTypeUniquenessInvariant(testOps); err != nil { +// t.Error(err) +// } +//} - testOps, rosettaError = getContractTransferNativeOperations( - refTx, refReceipt, refSenderAddr, refTx.To(), - &ContractInfo{}, nil, - ) - if rosettaError != nil { - t.Error(rosettaError) - } - baseValidation(testOps, refTxValue.Uint64()) - if len(testOps) == 0 { - t.Errorf("expect atleast 1 operation") - } - if testOps[0].OperationIdentifier.Index != 0 { - t.Errorf("expected starting index to be 0") - } - if len(testOps) > 3 { - t.Errorf("expect at most 3 operations for nil ExecutionResult") - } - if err := assertNativeOperationTypeUniquenessInvariant(testOps); err != nil { - t.Error(err) - } -} +//func TestGetContractTransferNativeOperations(t *testing.T) { +// signer := hmytypes.NewEIP155Signer(params.TestChainConfig.ChainID) +// refTxValue := big.NewInt(1) +// refTx, err := helpers.CreateTestTransaction( +// signer, 0, 0, 0, 1e18, gasPrice, refTxValue, []byte("blah-blah-blah"), +// ) +// if err != nil { +// t.Fatal(err.Error()) +// } +// refSenderAddr, err := refTx.SenderAddress() +// if err != nil { +// t.Fatal(err.Error()) +// } +// refStatus := common.SuccessOperationStatus.Status +// refStartingIndex := int64(23) +// refReceipt := &hmytypes.Receipt{ +// PostState: nil, +// Status: 1, +// GasUsed: params.TxGas * 3, // somme arb number > TxGas +// } +// baseValidation := func(ops []*types.Operation, expectedValueSum uint64) { +// prevIndex := int64(-1) +// valueSum := int64(0) +// absValueSum := uint64(0) +// for i, op := range ops { +// if op.OperationIdentifier.Index <= prevIndex { +// t.Errorf("expect prev index (%v) < curr index (%v) for op %v", +// prevIndex, op.OperationIdentifier.Index, i, +// ) +// } +// prevIndex = op.OperationIdentifier.Index +// if op.Status == nil || *op.Status != refStatus { +// t.Errorf("wrong status for op %v", i) +// } +// if types.Hash(op.Amount.Currency) != common.NativeCurrencyHash { +// t.Errorf("wrong currency for op %v", i) +// } +// if op.Type == common.ExpendGasOperation { +// continue +// } +// if op.Type != common.NativeTransferOperation { +// t.Errorf("wrong operation type for op %v", i) +// } +// val, err := types.AmountValue(op.Amount) +// if err != nil { +// t.Error(err) +// } +// valueSum += val.Int64() +// absValueSum += val.Abs(val).Uint64() +// } +// +// if valueSum != 0 { +// t.Errorf("expected sum of all non-gas values to be 0") +// } +// if expectedValueSum*2 != absValueSum { +// t.Errorf("sum of all positive values of operations do not match execpted sum of values") +// } +// } +// +// testOps, rosettaError := getContractTransferNativeOperations( +// refTx, refReceipt, refSenderAddr, refTx.To(), +// &ContractInfo{ExecutionResult: testExecResultForInternalTx}, &refStartingIndex, +// ) +// if rosettaError != nil { +// t.Error(rosettaError) +// } +// baseValidation(testOps, testExecResultForInternalTxValueSum+refTxValue.Uint64()) +// if len(testOps) == 0 { +// t.Errorf("expect atleast 1 operation") +// } +// if testOps[0].OperationIdentifier.Index != refStartingIndex { +// t.Errorf("expected starting index to be %v", refStartingIndex) +// } +// if err := assertNativeOperationTypeUniquenessInvariant(testOps); err != nil { +// t.Error(err) +// } +// +// testOps, rosettaError = getContractTransferNativeOperations( +// refTx, refReceipt, refSenderAddr, refTx.To(), +// &ContractInfo{ExecutionResult: testExecResultForInternalTx}, nil, +// ) +// if rosettaError != nil { +// t.Error(rosettaError) +// } +// baseValidation(testOps, testExecResultForInternalTxValueSum+refTxValue.Uint64()) +// if len(testOps) == 0 { +// t.Errorf("expect atleast 1 operation") +// } +// if testOps[0].OperationIdentifier.Index != 0 { +// t.Errorf("expected starting index to be 0") +// } +// if err := assertNativeOperationTypeUniquenessInvariant(testOps); err != nil { +// t.Error(err) +// } +// +// testOps, rosettaError = getContractTransferNativeOperations( +// refTx, refReceipt, refSenderAddr, refTx.To(), +// &ContractInfo{}, nil, +// ) +// if rosettaError != nil { +// t.Error(rosettaError) +// } +// baseValidation(testOps, refTxValue.Uint64()) +// if len(testOps) == 0 { +// t.Errorf("expect atleast 1 operation") +// } +// if testOps[0].OperationIdentifier.Index != 0 { +// t.Errorf("expected starting index to be 0") +// } +// if len(testOps) > 3 { +// t.Errorf("expect at most 3 operations for nil ExecutionResult") +// } +// if err := assertNativeOperationTypeUniquenessInvariant(testOps); err != nil { +// t.Error(err) +// } +//} -func TestGetContractCreationNativeOperations(t *testing.T) { - dummyContractKey, err := crypto.GenerateKey() - if err != nil { - t.Fatalf(err.Error()) - } - chainID := params.TestChainConfig.ChainID - signer := hmytypes.NewEIP155Signer(chainID) - tx, err := helpers.CreateTestContractCreationTransaction( - signer, 0, 0, 1e18, gasPrice, big.NewInt(0), []byte("test"), - ) - if err != nil { - t.Fatal(err.Error()) - } - senderAddr, err := tx.SenderAddress() - if err != nil { - t.Fatal(err.Error()) - } - senderAccID, rosettaError := newAccountIdentifier(senderAddr) - if rosettaError != nil { - t.Fatal(rosettaError) - } - startingOpID := &types.OperationIdentifier{} - - // Test failed contract creation - contractAddr := crypto.PubkeyToAddress(dummyContractKey.PublicKey) - contractAddressID, rosettaError := newAccountIdentifier(contractAddr) - if rosettaError != nil { - t.Fatal(rosettaError) - } - refOperations := []*types.Operation{ - { - OperationIdentifier: &types.OperationIdentifier{ - Index: startingOpID.Index + 1, - }, - Type: common.ContractCreationOperation, - Status: &common.ContractFailureOperationStatus.Status, - Account: senderAccID, - Amount: &types.Amount{ - Value: negativeBigValue(tx.Value()), - Currency: &common.NativeCurrency, - }, - }, - { - OperationIdentifier: &types.OperationIdentifier{ - Index: startingOpID.Index + 2, - }, - RelatedOperations: []*types.OperationIdentifier{ - { - Index: startingOpID.Index + 1, - }, - }, - Type: common.ContractCreationOperation, - Status: &common.ContractFailureOperationStatus.Status, - Account: contractAddressID, - Amount: &types.Amount{ - Value: tx.Value().String(), - Currency: &common.NativeCurrency, - }, - }, - } - receipt := &hmytypes.Receipt{ - Status: hmytypes.ReceiptStatusFailed, - ContractAddress: contractAddr, - } - opIndex := startingOpID.Index + 1 - operations, rosettaError := getContractCreationNativeOperations(tx, receipt, senderAddr, &ContractInfo{}, &opIndex) - if rosettaError != nil { - t.Fatal(rosettaError) - } - if !reflect.DeepEqual(operations, refOperations) { - t.Errorf("Expected operations to be %v not %v", refOperations, operations) - } - if err := assertNativeOperationTypeUniquenessInvariant(operations); err != nil { - t.Error(err) - } - - // Test successful contract creation - refOperations[0].Status = &common.SuccessOperationStatus.Status - refOperations[1].Status = &common.SuccessOperationStatus.Status - receipt.Status = hmytypes.ReceiptStatusSuccessful // Indicate successful tx - operations, rosettaError = getContractCreationNativeOperations(tx, receipt, senderAddr, &ContractInfo{}, &opIndex) - if rosettaError != nil { - t.Fatal(rosettaError) - } - if !reflect.DeepEqual(operations, refOperations) { - t.Errorf("Expected operations to be %v not %v", refOperations, operations) - } - if err := assertNativeOperationTypeUniquenessInvariant(operations); err != nil { - t.Error(err) - } - - traceValidation := func(ops []*types.Operation, expectedValueSum uint64) { - prevIndex := int64(-1) - valueSum := int64(0) - absValueSum := uint64(0) - for i, op := range ops { - if op.OperationIdentifier.Index <= prevIndex { - t.Errorf("expect prev index (%v) < curr index (%v) for op %v", - prevIndex, op.OperationIdentifier.Index, i, - ) - } - prevIndex = op.OperationIdentifier.Index - if *op.Status != *refOperations[0].Status { - t.Errorf("wrong status for op %v", i) - } - if types.Hash(op.Amount.Currency) != common.NativeCurrencyHash { - t.Errorf("wrong currency for op %v", i) - } - if op.Type == common.ExpendGasOperation || op.Type == common.ContractCreationOperation { - continue - } - if op.Type != common.NativeTransferOperation { - t.Errorf("wrong operation type for op %v", i) - } - val, err := types.AmountValue(op.Amount) - if err != nil { - t.Error(err) - } - valueSum += val.Int64() - absValueSum += val.Abs(val).Uint64() - } - - if valueSum != 0 { - t.Errorf("expected sum of all non-gas values to be 0") - } - if expectedValueSum*2 != absValueSum { - t.Errorf("sum of all positive values of operations do not match execpted sum of values") - } - } - operations, rosettaError = getContractCreationNativeOperations( - tx, receipt, senderAddr, &ContractInfo{ExecutionResult: testExecResultForInternalTx}, &opIndex, - ) - if rosettaError != nil { - t.Fatal(rosettaError) - } - traceValidation(operations, testExecResultForInternalTxValueSum) - if len(operations) == 0 { - t.Errorf("expect atleast 1 operation") - } - if operations[0].OperationIdentifier.Index != opIndex { - t.Errorf("expect first operation to be %v", opIndex) - } - if err := assertNativeOperationTypeUniquenessInvariant(operations); err != nil { - t.Error(err) - } - -} +//func TestGetContractCreationNativeOperations(t *testing.T) { +// dummyContractKey, err := crypto.GenerateKey() +// if err != nil { +// t.Fatalf(err.Error()) +// } +// chainID := params.TestChainConfig.ChainID +// signer := hmytypes.NewEIP155Signer(chainID) +// tx, err := helpers.CreateTestContractCreationTransaction( +// signer, 0, 0, 1e18, gasPrice, big.NewInt(0), []byte("test"), +// ) +// if err != nil { +// t.Fatal(err.Error()) +// } +// senderAddr, err := tx.SenderAddress() +// if err != nil { +// t.Fatal(err.Error()) +// } +// senderAccID, rosettaError := newAccountIdentifier(senderAddr) +// if rosettaError != nil { +// t.Fatal(rosettaError) +// } +// startingOpID := &types.OperationIdentifier{} +// +// // Test failed contract creation +// contractAddr := crypto.PubkeyToAddress(dummyContractKey.PublicKey) +// contractAddressID, rosettaError := newAccountIdentifier(contractAddr) +// if rosettaError != nil { +// t.Fatal(rosettaError) +// } +// refOperations := []*types.Operation{ +// { +// OperationIdentifier: &types.OperationIdentifier{ +// Index: startingOpID.Index + 1, +// }, +// Type: common.ContractCreationOperation, +// Status: &common.ContractFailureOperationStatus.Status, +// Account: senderAccID, +// Amount: &types.Amount{ +// Value: negativeBigValue(tx.Value()), +// Currency: &common.NativeCurrency, +// }, +// }, +// { +// OperationIdentifier: &types.OperationIdentifier{ +// Index: startingOpID.Index + 2, +// }, +// RelatedOperations: []*types.OperationIdentifier{ +// { +// Index: startingOpID.Index + 1, +// }, +// }, +// Type: common.ContractCreationOperation, +// Status: &common.ContractFailureOperationStatus.Status, +// Account: contractAddressID, +// Amount: &types.Amount{ +// Value: tx.Value().String(), +// Currency: &common.NativeCurrency, +// }, +// }, +// } +// receipt := &hmytypes.Receipt{ +// Status: hmytypes.ReceiptStatusFailed, +// ContractAddress: contractAddr, +// } +// opIndex := startingOpID.Index + 1 +// operations, rosettaError := getContractCreationNativeOperations(tx, receipt, senderAddr, &ContractInfo{}, &opIndex) +// if rosettaError != nil { +// t.Fatal(rosettaError) +// } +// if !reflect.DeepEqual(operations, refOperations) { +// t.Errorf("Expected operations to be %v not %v", refOperations, operations) +// } +// if err := assertNativeOperationTypeUniquenessInvariant(operations); err != nil { +// t.Error(err) +// } +// +// // Test successful contract creation +// refOperations[0].Status = &common.SuccessOperationStatus.Status +// refOperations[1].Status = &common.SuccessOperationStatus.Status +// receipt.Status = hmytypes.ReceiptStatusSuccessful // Indicate successful tx +// operations, rosettaError = getContractCreationNativeOperations(tx, receipt, senderAddr, &ContractInfo{}, &opIndex) +// if rosettaError != nil { +// t.Fatal(rosettaError) +// } +// if !reflect.DeepEqual(operations, refOperations) { +// t.Errorf("Expected operations to be %v not %v", refOperations, operations) +// } +// if err := assertNativeOperationTypeUniquenessInvariant(operations); err != nil { +// t.Error(err) +// } +// +// traceValidation := func(ops []*types.Operation, expectedValueSum uint64) { +// prevIndex := int64(-1) +// valueSum := int64(0) +// absValueSum := uint64(0) +// for i, op := range ops { +// if op.OperationIdentifier.Index <= prevIndex { +// t.Errorf("expect prev index (%v) < curr index (%v) for op %v", +// prevIndex, op.OperationIdentifier.Index, i, +// ) +// } +// prevIndex = op.OperationIdentifier.Index +// if *op.Status != *refOperations[0].Status { +// t.Errorf("wrong status for op %v", i) +// } +// if types.Hash(op.Amount.Currency) != common.NativeCurrencyHash { +// t.Errorf("wrong currency for op %v", i) +// } +// if op.Type == common.ExpendGasOperation || op.Type == common.ContractCreationOperation { +// continue +// } +// if op.Type != common.NativeTransferOperation { +// t.Errorf("wrong operation type for op %v", i) +// } +// val, err := types.AmountValue(op.Amount) +// if err != nil { +// t.Error(err) +// } +// valueSum += val.Int64() +// absValueSum += val.Abs(val).Uint64() +// } +// +// if valueSum != 0 { +// t.Errorf("expected sum of all non-gas values to be 0") +// } +// if expectedValueSum*2 != absValueSum { +// t.Errorf("sum of all positive values of operations do not match execpted sum of values") +// } +// } +// operations, rosettaError = getContractCreationNativeOperations( +// tx, receipt, senderAddr, &ContractInfo{ExecutionResult: testExecResultForInternalTx}, &opIndex, +// ) +// if rosettaError != nil { +// t.Fatal(rosettaError) +// } +// traceValidation(operations, testExecResultForInternalTxValueSum) +// if len(operations) == 0 { +// t.Errorf("expect atleast 1 operation") +// } +// if operations[0].OperationIdentifier.Index != opIndex { +// t.Errorf("expect first operation to be %v", opIndex) +// } +// if err := assertNativeOperationTypeUniquenessInvariant(operations); err != nil { +// t.Error(err) +// } +// +//} func TestNewNativeOperations(t *testing.T) { accountID := &types.AccountIdentifier{