Skip to content

Commit d79c2a5

Browse files
authored
Merge pull request #623 from iotaledger/txbuilder-clone
improve cloning in transaction builder
2 parents a8a3ad4 + 75f5a8b commit d79c2a5

File tree

3 files changed

+93
-5
lines changed

3 files changed

+93
-5
lines changed

packages/vm/core/evm/evmtest/contractInstance.go

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -124,6 +124,10 @@ func (e *EVMContractInstance) estimateGas(opts []ethCallOptions, fnName string,
124124
return tx.Gas(), nil
125125
}
126126

127+
func (e *EVMContractInstance) MakeCallFn(opts []ethCallOptions, fnName string, args ...interface{}) (*types.Transaction, error) {
128+
return e.buildEthTx(opts, fnName, args...)
129+
}
130+
127131
func (e *EVMContractInstance) CallFn(opts []ethCallOptions, fnName string, args ...interface{}) (CallFnResult, error) {
128132
e.chain.t.Logf("callFn: %s %+v", fnName, args)
129133

packages/vm/core/evm/evmtest/evm_test.go

Lines changed: 82 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2061,3 +2061,85 @@ func TestEVMEventOnFailedL1Deposit(t *testing.T) {
20612061
// logs := env.LastBlockEVMLogs()
20622062
// require.Len(t, logs, 0)
20632063
}
2064+
2065+
func TestEVM_WithdrawWithFailedTxAfter(t *testing.T) {
2066+
env := InitEVM(t)
2067+
2068+
env.Chain.DepositAssetsToL2(isc.NewAssets(1*isc.Million), env.Chain.ChainAdmin)
2069+
2070+
ethKey, senderEthAddress := env.Chain.NewEthereumAccountWithL2Funds()
2071+
senderAgentID := isc.NewEthereumAddressAgentID(senderEthAddress)
2072+
2073+
_, receiver := env.solo.NewKeyPair()
2074+
2075+
l1Balance := env.Chain.Env.L1BaseTokens(receiver)
2076+
l2Balance := env.Chain.L2BaseTokens(senderAgentID)
2077+
const tokensWithdrawn = 10_000
2078+
2079+
value := util.BaseTokensDecimalsToEthereumDecimals(tokensWithdrawn, parameters.BaseTokenDecimals)
2080+
tx, err := env.ISCMagicSandbox(ethKey).MakeCallFn(
2081+
[]ethCallOptions{{sender: ethKey, value: value, gasLimit: 100_000}},
2082+
"transferToL1",
2083+
receiver,
2084+
iscmagic.WrapISCAssets(isc.NewEmptyAssets()),
2085+
)
2086+
require.NoError(t, err)
2087+
withdrawRequest, err := isc.NewEVMOffLedgerTxRequest(env.Chain.ChainID, tx)
2088+
require.NoError(t, err)
2089+
2090+
failingRequest := solo.NewCallParams(accounts.FuncWithdraw.Message()).
2091+
AddAllowance(isc.NewAssets(env.Chain.L2BaseTokens(env.Chain.AdminAgentID())*2)).
2092+
WithMaxAffordableGasBudget().NewRequestOffLedger(env.Chain, env.Chain.ChainAdmin)
2093+
2094+
// run both requests in a single block:
2095+
_, res := env.Chain.RunOffLedgerRequests([]isc.Request{withdrawRequest, failingRequest})
2096+
2097+
require.Len(t, res, 2)
2098+
require.Nil(t, res[0].Receipt.Error)
2099+
require.NotNil(t, res[1].Receipt.Error)
2100+
2101+
gasFee := env.Chain.GetRequestReceiptsForBlock(env.Chain.LatestBlockIndex())[0].GasFeeCharged
2102+
require.EqualValues(t, l2Balance-tokensWithdrawn-gasFee, env.Chain.L2BaseTokens(senderAgentID))
2103+
require.EqualValues(t, l1Balance+tokensWithdrawn, env.Chain.Env.L1BaseTokens(receiver))
2104+
}
2105+
2106+
func TestEVM_WithdrawWithFailedTxBefore(t *testing.T) {
2107+
env := InitEVM(t)
2108+
2109+
env.Chain.DepositAssetsToL2(isc.NewAssets(1*isc.Million), env.Chain.ChainAdmin)
2110+
2111+
ethKey, senderEthAddress := env.Chain.NewEthereumAccountWithL2Funds()
2112+
senderAgentID := isc.NewEthereumAddressAgentID(senderEthAddress)
2113+
2114+
_, receiver := env.solo.NewKeyPair()
2115+
2116+
l1Balance := env.Chain.Env.L1BaseTokens(receiver)
2117+
l2Balance := env.Chain.L2BaseTokens(senderAgentID)
2118+
const tokensWithdrawn = 10_000
2119+
2120+
value := util.BaseTokensDecimalsToEthereumDecimals(tokensWithdrawn, parameters.BaseTokenDecimals)
2121+
tx, err := env.ISCMagicSandbox(ethKey).MakeCallFn(
2122+
[]ethCallOptions{{sender: ethKey, value: value, gasLimit: 100_000}},
2123+
"transferToL1",
2124+
receiver,
2125+
iscmagic.WrapISCAssets(isc.NewEmptyAssets()),
2126+
)
2127+
require.NoError(t, err)
2128+
withdrawRequest, err := isc.NewEVMOffLedgerTxRequest(env.Chain.ChainID, tx)
2129+
require.NoError(t, err)
2130+
2131+
failingRequest := solo.NewCallParams(accounts.FuncWithdraw.Message()).
2132+
AddAllowance(isc.NewAssets(env.Chain.L2BaseTokens(env.Chain.AdminAgentID())*2)).
2133+
WithMaxAffordableGasBudget().NewRequestOffLedger(env.Chain, env.Chain.ChainAdmin)
2134+
2135+
// run both requests in a single block:
2136+
_, res := env.Chain.RunOffLedgerRequests([]isc.Request{failingRequest, withdrawRequest})
2137+
2138+
require.Len(t, res, 2)
2139+
require.NotNil(t, res[0].Receipt.Error)
2140+
require.Nil(t, res[1].Receipt.Error)
2141+
2142+
gasFee := env.Chain.GetRequestReceiptsForBlock(env.Chain.LatestBlockIndex())[1].GasFeeCharged
2143+
require.EqualValues(t, l2Balance-tokensWithdrawn-gasFee, env.Chain.L2BaseTokens(senderAgentID))
2144+
require.EqualValues(t, l1Balance+tokensWithdrawn, env.Chain.Env.L1BaseTokens(receiver))
2145+
}

packages/vm/vmtxbuilder/txbuilder.go

Lines changed: 7 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -52,11 +52,13 @@ func NewAnchorTransactionBuilder(
5252

5353
func (txb *AnchorTransactionBuilder) Clone() TransactionBuilder {
5454
return &AnchorTransactionBuilder{
55-
anchor: txb.anchor,
56-
iscPackage: txb.iscPackage,
57-
consumed: slices.Clone(txb.consumed),
58-
ptb: txb.ptb.Clone(),
59-
ownerAddr: txb.ownerAddr,
55+
anchor: txb.anchor,
56+
iscPackage: txb.iscPackage,
57+
consumed: slices.Clone(txb.consumed),
58+
ptb: txb.ptb.Clone(),
59+
ownerAddr: txb.ownerAddr,
60+
sent: slices.Clone(txb.sent),
61+
rotateToAddr: txb.rotateToAddr,
6062
}
6163
}
6264

0 commit comments

Comments
 (0)