Skip to content

Commit 6231a0a

Browse files
fix: add readonly arg with delegate call enabled (#5)
* refactor!: Remove readonly parameter in RunPrecompiledContract and bring the implementation closer to standard geth For tag v1.10.28-nibiru * refactor!: Sync behavior closer to upstream geth * fix: add readonly arg with delegate call enabled v1.10.29-nibiru * chore: linter
1 parent b8129ee commit 6231a0a

File tree

9 files changed

+63
-41
lines changed

9 files changed

+63
-41
lines changed

cmd/evm/t8n_test.go

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -369,7 +369,7 @@ func TestT9n(t *testing.T) {
369369
ok, err := cmpJson(have, want)
370370
switch {
371371
case err != nil:
372-
t.Logf(string(have))
372+
t.Log(string(have))
373373
t.Fatalf("test %d, json parsing failed: %v", i, err)
374374
case !ok:
375375
t.Fatalf("test %d: output wrong, have \n%v\nwant\n%v\n", i, string(have), string(want))
@@ -488,7 +488,7 @@ func TestB11r(t *testing.T) {
488488
ok, err := cmpJson(have, want)
489489
switch {
490490
case err != nil:
491-
t.Logf(string(have))
491+
t.Log(string(have))
492492
t.Fatalf("test %d, json parsing failed: %v", i, err)
493493
case !ok:
494494
t.Fatalf("test %d: output wrong, have \n%v\nwant\n%v\n", i, string(have), string(want))

core/rawdb/accessors_chain_test.go

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -391,7 +391,7 @@ func TestBlockReceiptStorage(t *testing.T) {
391391
t.Fatalf("no receipts returned")
392392
} else {
393393
if err := checkReceiptsRLP(rs, receipts); err != nil {
394-
t.Fatalf(err.Error())
394+
t.Fatal(err.Error())
395395
}
396396
}
397397
// Delete the body and ensure that the receipts are no longer returned (metadata can't be recomputed)
@@ -401,7 +401,7 @@ func TestBlockReceiptStorage(t *testing.T) {
401401
}
402402
// Ensure that receipts without metadata can be returned without the block body too
403403
if err := checkReceiptsRLP(ReadRawReceipts(db, hash, 0), receipts); err != nil {
404-
t.Fatalf(err.Error())
404+
t.Fatal(err.Error())
405405
}
406406
// Sanity check that body alone without the receipt is a full purge
407407
WriteBody(db, hash, 0, body)

core/vm/contract.go

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -108,6 +108,10 @@ func (c Contract) IsPrecompile() bool {
108108
}
109109

110110
func (c *Contract) validJumpdest(dest *uint256.Int) bool {
111+
if c.isPrecompile {
112+
return false
113+
}
114+
111115
udest, overflow := dest.Uint64WithOverflow()
112116
// PC cannot go beyond len(code) and certainly can't be bigger than 63bits.
113117
// Don't bother checking for JUMPDEST in that case.
@@ -124,6 +128,10 @@ func (c *Contract) validJumpdest(dest *uint256.Int) bool {
124128
// isCode returns true if the provided PC location is an actual opcode, as
125129
// opposed to a data-segment following a PUSHN operation.
126130
func (c *Contract) isCode(udest uint64) bool {
131+
if c.isPrecompile {
132+
return false
133+
}
134+
127135
// Do we already have an analysis laying around?
128136
if c.analysis != nil {
129137
return c.analysis.codeSegment(udest)
@@ -157,6 +165,10 @@ func (c *Contract) isCode(udest uint64) bool {
157165
// AsDelegate sets the contract to be a delegate call and returns the current
158166
// contract (for chaining calls)
159167
func (c *Contract) AsDelegate() *Contract {
168+
if c.isPrecompile {
169+
return c
170+
}
171+
// NOTE: caller must, at all times be a contract. It should never happen
160172
// that caller is something other than a Contract.
161173
parent := c.caller.(*Contract)
162174
c.CallerAddress = parent.CallerAddress
@@ -204,6 +216,10 @@ func (c *Contract) Value() *big.Int {
204216
// SetCallCode sets the code of the contract and address of the backing data
205217
// object
206218
func (c *Contract) SetCallCode(addr *common.Address, hash common.Hash, code []byte) {
219+
if c.isPrecompile {
220+
return
221+
}
222+
207223
c.Code = code
208224
c.CodeHash = hash
209225
c.CodeAddr = addr
@@ -212,6 +228,10 @@ func (c *Contract) SetCallCode(addr *common.Address, hash common.Hash, code []by
212228
// SetCodeOptionalHash can be used to provide code, but it's optional to provide hash.
213229
// In case hash is not provided, the jumpdest analysis will not be saved to the parent context
214230
func (c *Contract) SetCodeOptionalHash(addr *common.Address, codeAndHash *codeAndHash) {
231+
if c.isPrecompile {
232+
return
233+
}
234+
215235
c.Code = codeAndHash.code
216236
c.CodeHash = codeAndHash.hash
217237
c.CodeAddr = addr

core/vm/contracts.go

Lines changed: 24 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -42,7 +42,7 @@ type PrecompiledContract interface {
4242
// RequiredPrice calculates the contract gas used
4343
RequiredGas(input []byte) uint64
4444
// Run runs the precompiled contract
45-
Run(evm *EVM, contract *Contract) ([]byte, error)
45+
Run(evm *EVM, contract *Contract, readonly bool) ([]byte, error)
4646
}
4747

4848
// PrecompiledContractsHomestead contains the default set of pre-compiled Ethereum
@@ -264,6 +264,7 @@ func (evm *EVM) RunPrecompiledContract(
264264
input []byte,
265265
suppliedGas uint64,
266266
value *big.Int,
267+
readOnly bool,
267268
) (ret []byte, remainingGas uint64, err error) {
268269
addrCopy := p.Address()
269270
inputCopy := make([]byte, len(input))
@@ -277,7 +278,7 @@ func (evm *EVM) RunPrecompiledContract(
277278
return nil, contract.Gas, ErrOutOfGas
278279
}
279280

280-
output, err := p.Run(evm, contract)
281+
output, err := p.Run(evm, contract, readOnly)
281282
return output, contract.Gas, err
282283
}
283284

@@ -294,7 +295,7 @@ func (c *ecrecover) RequiredGas(input []byte) uint64 {
294295
return params.EcrecoverGas
295296
}
296297

297-
func (c *ecrecover) Run(evm *EVM, contract *Contract) ([]byte, error) {
298+
func (c *ecrecover) Run(evm *EVM, contract *Contract, readonly bool) ([]byte, error) {
298299
const ecRecoverInputLength = 128
299300

300301
contract.Input = common.RightPadBytes(contract.Input, ecRecoverInputLength)
@@ -342,7 +343,7 @@ func (c *sha256hash) RequiredGas(input []byte) uint64 {
342343
return uint64(len(input)+31)/32*params.Sha256PerWordGas + params.Sha256BaseGas
343344
}
344345

345-
func (c *sha256hash) Run(evm *EVM, contract *Contract) ([]byte, error) {
346+
func (c *sha256hash) Run(evm *EVM, contract *Contract, readonly bool) ([]byte, error) {
346347
h := sha256.Sum256(contract.Input)
347348
return h[:], nil
348349
}
@@ -364,7 +365,7 @@ func (c *ripemd160hash) RequiredGas(input []byte) uint64 {
364365
return uint64(len(input)+31)/32*params.Ripemd160PerWordGas + params.Ripemd160BaseGas
365366
}
366367

367-
func (c *ripemd160hash) Run(evm *EVM, contract *Contract) ([]byte, error) {
368+
func (c *ripemd160hash) Run(evm *EVM, contract *Contract, readonly bool) ([]byte, error) {
368369
ripemd := ripemd160.New()
369370
ripemd.Write(contract.Input)
370371
return common.LeftPadBytes(ripemd.Sum(nil), 32), nil
@@ -387,7 +388,7 @@ func (c *dataCopy) RequiredGas(input []byte) uint64 {
387388
return uint64(len(input)+31)/32*params.IdentityPerWordGas + params.IdentityBaseGas
388389
}
389390

390-
func (c *dataCopy) Run(evm *EVM, contract *Contract) ([]byte, error) {
391+
func (c *dataCopy) Run(evm *EVM, contract *Contract, readonly bool) ([]byte, error) {
391392
return common.CopyBytes(contract.Input), nil
392393
}
393394

@@ -521,7 +522,7 @@ func (c *bigModExp) RequiredGas(input []byte) uint64 {
521522
return gas.Uint64()
522523
}
523524

524-
func (c *bigModExp) Run(evm *EVM, contract *Contract) ([]byte, error) {
525+
func (c *bigModExp) Run(evm *EVM, contract *Contract, readonly bool) ([]byte, error) {
525526
var (
526527
baseLen = new(big.Int).SetBytes(getData(contract.Input, 0, 32)).Uint64()
527528
expLen = new(big.Int).SetBytes(getData(contract.Input, 32, 32)).Uint64()
@@ -600,7 +601,7 @@ func (c *bn256AddIstanbul) RequiredGas(input []byte) uint64 {
600601
return params.Bn256AddGasIstanbul
601602
}
602603

603-
func (c *bn256AddIstanbul) Run(evm *EVM, contract *Contract) ([]byte, error) {
604+
func (c *bn256AddIstanbul) Run(evm *EVM, contract *Contract, readonly bool) ([]byte, error) {
604605
return runBn256Add(contract.Input)
605606
}
606607

@@ -619,7 +620,7 @@ func (c *bn256AddByzantium) RequiredGas(input []byte) uint64 {
619620
return params.Bn256AddGasByzantium
620621
}
621622

622-
func (c *bn256AddByzantium) Run(evm *EVM, contract *Contract) ([]byte, error) {
623+
func (c *bn256AddByzantium) Run(evm *EVM, contract *Contract, readonly bool) ([]byte, error) {
623624
return runBn256Add(contract.Input)
624625
}
625626

@@ -650,7 +651,7 @@ func (c *bn256ScalarMulIstanbul) RequiredGas(input []byte) uint64 {
650651
return params.Bn256ScalarMulGasIstanbul
651652
}
652653

653-
func (c *bn256ScalarMulIstanbul) Run(evm *EVM, contract *Contract) ([]byte, error) {
654+
func (c *bn256ScalarMulIstanbul) Run(evm *EVM, contract *Contract, readonly bool) ([]byte, error) {
654655
return runBn256ScalarMul(contract.Input)
655656
}
656657

@@ -669,7 +670,7 @@ func (c *bn256ScalarMulByzantium) RequiredGas(input []byte) uint64 {
669670
return params.Bn256ScalarMulGasByzantium
670671
}
671672

672-
func (c *bn256ScalarMulByzantium) Run(evm *EVM, contract *Contract) ([]byte, error) {
673+
func (c *bn256ScalarMulByzantium) Run(evm *EVM, contract *Contract, readonly bool) ([]byte, error) {
673674
return runBn256ScalarMul(contract.Input)
674675
}
675676

@@ -730,7 +731,7 @@ func (c *bn256PairingIstanbul) RequiredGas(input []byte) uint64 {
730731
return params.Bn256PairingBaseGasIstanbul + uint64(len(input)/192)*params.Bn256PairingPerPointGasIstanbul
731732
}
732733

733-
func (c *bn256PairingIstanbul) Run(evm *EVM, contract *Contract) ([]byte, error) {
734+
func (c *bn256PairingIstanbul) Run(evm *EVM, contract *Contract, readonly bool) ([]byte, error) {
734735
return runBn256Pairing(contract.Input)
735736
}
736737

@@ -749,7 +750,7 @@ func (c *bn256PairingByzantium) RequiredGas(input []byte) uint64 {
749750
return params.Bn256PairingBaseGasByzantium + uint64(len(input)/192)*params.Bn256PairingPerPointGasByzantium
750751
}
751752

752-
func (c *bn256PairingByzantium) Run(evm *EVM, contract *Contract) ([]byte, error) {
753+
func (c *bn256PairingByzantium) Run(evm *EVM, contract *Contract, readonly bool) ([]byte, error) {
753754
return runBn256Pairing(contract.Input)
754755
}
755756

@@ -781,7 +782,7 @@ var (
781782
errBlake2FInvalidFinalFlag = errors.New("invalid final flag")
782783
)
783784

784-
func (c *blake2F) Run(evm *EVM, contract *Contract) ([]byte, error) {
785+
func (c *blake2F) Run(evm *EVM, contract *Contract, readonly bool) ([]byte, error) {
785786
// Make sure the input is valid (correct length and final flag)
786787
if len(contract.Input) != blake2FInputLength {
787788
return nil, errBlake2FInvalidInputLength
@@ -841,7 +842,7 @@ func (c *bls12381G1Add) RequiredGas(input []byte) uint64 {
841842
return params.Bls12381G1AddGas
842843
}
843844

844-
func (c *bls12381G1Add) Run(evm *EVM, contract *Contract) ([]byte, error) {
845+
func (c *bls12381G1Add) Run(evm *EVM, contract *Contract, readonly bool) ([]byte, error) {
845846
// Implements EIP-2537 G1Add precompile.
846847
// > G1 addition call expects `256` bytes as an input that is interpreted as byte concatenation of two G1 points (`128` bytes each).
847848
// > Output is an encoding of addition operation result - single G1 point (`128` bytes).
@@ -885,7 +886,7 @@ func (c *bls12381G1Mul) RequiredGas(input []byte) uint64 {
885886
return params.Bls12381G1MulGas
886887
}
887888

888-
func (c *bls12381G1Mul) Run(evm *EVM, contract *Contract) ([]byte, error) {
889+
func (c *bls12381G1Mul) Run(evm *EVM, contract *Contract, readonly bool) ([]byte, error) {
889890
// Implements EIP-2537 G1Mul precompile.
890891
// > G1 multiplication call expects `160` bytes as an input that is interpreted as byte concatenation of encoding of G1 point (`128` bytes) and encoding of a scalar value (`32` bytes).
891892
// > Output is an encoding of multiplication operation result - single G1 point (`128` bytes).
@@ -941,7 +942,7 @@ func (c *bls12381G1MultiExp) RequiredGas(input []byte) uint64 {
941942
return (uint64(k) * params.Bls12381G1MulGas * discount) / 1000
942943
}
943944

944-
func (c *bls12381G1MultiExp) Run(evm *EVM, contract *Contract) ([]byte, error) {
945+
func (c *bls12381G1MultiExp) Run(evm *EVM, contract *Contract, readonly bool) ([]byte, error) {
945946
// Implements EIP-2537 G1MultiExp precompile.
946947
// G1 multiplication call expects `160*k` bytes as an input that is interpreted as byte concatenation of `k` slices each of them being a byte concatenation of encoding of G1 point (`128` bytes) and encoding of a scalar value (`32` bytes).
947948
// Output is an encoding of multiexponentiation operation result - single G1 point (`128` bytes).
@@ -990,7 +991,7 @@ func (c *bls12381G2Add) RequiredGas(input []byte) uint64 {
990991
return params.Bls12381G2AddGas
991992
}
992993

993-
func (c *bls12381G2Add) Run(evm *EVM, contract *Contract) ([]byte, error) {
994+
func (c *bls12381G2Add) Run(evm *EVM, contract *Contract, readonly bool) ([]byte, error) {
994995
// Implements EIP-2537 G2Add precompile.
995996
// > G2 addition call expects `512` bytes as an input that is interpreted as byte concatenation of two G2 points (`256` bytes each).
996997
// > Output is an encoding of addition operation result - single G2 point (`256` bytes).
@@ -1034,7 +1035,7 @@ func (c *bls12381G2Mul) RequiredGas(input []byte) uint64 {
10341035
return params.Bls12381G2MulGas
10351036
}
10361037

1037-
func (c *bls12381G2Mul) Run(evm *EVM, contract *Contract) ([]byte, error) {
1038+
func (c *bls12381G2Mul) Run(evm *EVM, contract *Contract, readonly bool) ([]byte, error) {
10381039
// Implements EIP-2537 G2MUL precompile logic.
10391040
// > G2 multiplication call expects `288` bytes as an input that is interpreted as byte concatenation of encoding of G2 point (`256` bytes) and encoding of a scalar value (`32` bytes).
10401041
// > Output is an encoding of multiplication operation result - single G2 point (`256` bytes).
@@ -1090,7 +1091,7 @@ func (c *bls12381G2MultiExp) RequiredGas(input []byte) uint64 {
10901091
return (uint64(k) * params.Bls12381G2MulGas * discount) / 1000
10911092
}
10921093

1093-
func (c *bls12381G2MultiExp) Run(evm *EVM, contract *Contract) ([]byte, error) {
1094+
func (c *bls12381G2MultiExp) Run(evm *EVM, contract *Contract, readonly bool) ([]byte, error) {
10941095
// Implements EIP-2537 G2MultiExp precompile logic
10951096
// > G2 multiplication call expects `288*k` bytes as an input that is interpreted as byte concatenation of `k` slices each of them being a byte concatenation of encoding of G2 point (`256` bytes) and encoding of a scalar value (`32` bytes).
10961097
// > Output is an encoding of multiexponentiation operation result - single G2 point (`256` bytes).
@@ -1139,7 +1140,7 @@ func (c *bls12381Pairing) RequiredGas(input []byte) uint64 {
11391140
return params.Bls12381PairingBaseGas + uint64(len(input)/384)*params.Bls12381PairingPerPairGas
11401141
}
11411142

1142-
func (c *bls12381Pairing) Run(evm *EVM, contract *Contract) ([]byte, error) {
1143+
func (c *bls12381Pairing) Run(evm *EVM, contract *Contract, readonly bool) ([]byte, error) {
11431144
// Implements EIP-2537 Pairing precompile logic.
11441145
// > Pairing call expects `384*k` bytes as an inputs that is interpreted as byte concatenation of `k` slices. Each slice has the following structure:
11451146
// > - `128` bytes of G1 point encoding
@@ -1224,7 +1225,7 @@ func (c *bls12381MapG1) RequiredGas(input []byte) uint64 {
12241225
return params.Bls12381MapG1Gas
12251226
}
12261227

1227-
func (c *bls12381MapG1) Run(evm *EVM, contract *Contract) ([]byte, error) {
1228+
func (c *bls12381MapG1) Run(evm *EVM, contract *Contract, readonly bool) ([]byte, error) {
12281229
// Implements EIP-2537 Map_To_G1 precompile.
12291230
// > Field-to-curve call expects `64` bytes an an input that is interpreted as a an element of the base field.
12301231
// > Output of this call is `128` bytes and is G1 point following respective encoding rules.
@@ -1265,7 +1266,7 @@ func (c *bls12381MapG2) RequiredGas(input []byte) uint64 {
12651266
return params.Bls12381MapG2Gas
12661267
}
12671268

1268-
func (c *bls12381MapG2) Run(evm *EVM, contract *Contract) ([]byte, error) {
1269+
func (c *bls12381MapG2) Run(evm *EVM, contract *Contract, readonly bool) ([]byte, error) {
12691270
// Implements EIP-2537 Map_FP2_TO_G2 precompile logic.
12701271
// > Field-to-curve call expects `128` bytes an an input that is interpreted as a an element of the quadratic extension field.
12711272
// > Output of this call is `256` bytes and is G2 point following respective encoding rules.

core/vm/contracts_test.go

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -98,7 +98,7 @@ func testPrecompiled(addr string, test precompiledTest, t *testing.T) {
9898
gas := p.RequiredGas(in)
9999
t.Run(fmt.Sprintf("%s-Gas=%d", test.Name, gas), func(t *testing.T) {
100100
if res, _, err := new(EVM).RunPrecompiledContract(
101-
p, AccountRef(common.Address{}), in, gas, new(big.Int),
101+
p, AccountRef(common.Address{}), in, gas, new(big.Int), false,
102102
); err != nil {
103103
t.Error(err)
104104
} else if common.Bytes2Hex(res) != test.Expected {
@@ -122,7 +122,7 @@ func testPrecompiledOOG(addr string, test precompiledTest, t *testing.T) {
122122

123123
t.Run(fmt.Sprintf("%s-Gas=%d", test.Name, gas), func(t *testing.T) {
124124
_, _, err := new(EVM).RunPrecompiledContract(
125-
p, AccountRef(common.Address{}), in, gas, new(big.Int),
125+
p, AccountRef(common.Address{}), in, gas, new(big.Int), false,
126126
)
127127
if err.Error() != "out of gas" {
128128
t.Errorf("Expected error [out of gas], got [%v]", err)
@@ -141,7 +141,7 @@ func testPrecompiledFailure(addr string, test precompiledFailureTest, t *testing
141141
gas := p.RequiredGas(in)
142142
t.Run(test.Name, func(t *testing.T) {
143143
_, _, err := new(EVM).RunPrecompiledContract(
144-
p, AccountRef(common.Address{}), in, gas, new(big.Int),
144+
p, AccountRef(common.Address{}), in, gas, new(big.Int), false,
145145
)
146146
if err.Error() != test.ExpectedError {
147147
t.Errorf("Expected error [%v], got [%v]", test.ExpectedError, err)
@@ -175,7 +175,7 @@ func benchmarkPrecompiled(addr string, test precompiledTest, bench *testing.B) {
175175
for i := 0; i < bench.N; i++ {
176176
copy(data, in)
177177
res, _, err = new(EVM).RunPrecompiledContract(
178-
p, AccountRef(common.Address{}), in, reqGas, new(big.Int),
178+
p, AccountRef(common.Address{}), in, reqGas, new(big.Int), false,
179179
)
180180
}
181181
bench.StopTimer()

core/vm/evm.go

Lines changed: 8 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -210,7 +210,7 @@ func (evm *EVM) Call(caller ContractRef, addr common.Address, input []byte, gas
210210

211211
// It is allowed to call precompiles, even via call -- as opposed to callcode, staticcall and delegatecall it can also modify state
212212
if isPrecompile {
213-
ret, gas, err = evm.RunPrecompiledContract(p, caller, input, gas, value)
213+
ret, gas, err = evm.RunPrecompiledContract(p, caller, input, gas, value, false)
214214
} else {
215215
// Initialise a new contract and set the code that is to be used by the EVM.
216216
// The contract is a scoped environment for this execution context only.
@@ -273,13 +273,15 @@ func (evm *EVM) CallCode(caller ContractRef, addr common.Address, input []byte,
273273

274274
// It is allowed to call precompiles, even via callcode
275275
if p, isPrecompile := evm.Precompile(addr); isPrecompile {
276-
ret, gas, err = evm.RunPrecompiledContract(p, caller, input, gas, value)
276+
ret, gas, err = evm.RunPrecompiledContract(p, caller, input, gas, value, false)
277277
} else {
278278
addrCopy := addr
279279
// Initialise a new contract and set the code that is to be used by the EVM.
280280
// The contract is a scoped environment for this execution context only.
281281
contract := NewContract(caller, AccountRef(caller.Address()), value, gas)
282-
contract.SetCallCode(&addrCopy, evm.StateDB.GetCodeHash(addrCopy), evm.StateDB.GetCode(addrCopy))
282+
contract.SetCallCode(
283+
&addrCopy, evm.StateDB.GetCodeHash(addrCopy), evm.StateDB.GetCode(addrCopy),
284+
)
283285
ret, err = evm.interpreter.Run(contract, input, false)
284286
gas = contract.Gas
285287
}
@@ -314,7 +316,7 @@ func (evm *EVM) DelegateCall(caller ContractRef, addr common.Address, input []by
314316

315317
// It is allowed to call precompiles, even via delegatecall
316318
if p, isPrecompile := evm.Precompile(addr); isPrecompile {
317-
ret, gas, err = evm.RunPrecompiledContract(p, caller, input, gas, nil)
319+
ret, gas, err = evm.RunPrecompiledContract(p, caller, input, gas, nil, false)
318320
} else {
319321
addrCopy := addr
320322
// Initialise a new contract and make initialise the delegate values
@@ -363,7 +365,8 @@ func (evm *EVM) StaticCall(caller ContractRef, addr common.Address, input []byte
363365
}
364366

365367
if p, isPrecompile := evm.Precompile(addr); isPrecompile {
366-
ret, gas, err = evm.RunPrecompiledContract(p, caller, input, gas, new(big.Int))
368+
// Note: delegate call is not allowed to modify state on precompiles
369+
ret, gas, err = evm.RunPrecompiledContract(p, caller, input, gas, new(big.Int), true)
367370
} else {
368371
// At this point, we use a copy of address. If we don't, the go compiler will
369372
// leak the 'contract' to the outer scope, and make allocation for 'contract'

eth/tracers/logger/logger.go

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -172,9 +172,7 @@ func (l *StructLogger) CaptureState(pc uint64, op vm.OpCode, gas, cost uint64, s
172172
var stck []uint256.Int
173173
if !l.cfg.DisableStack {
174174
stck = make([]uint256.Int, len(stack.Data))
175-
for i, item := range stack.Data {
176-
stck[i] = item
177-
}
175+
copy(stck, stack.Data)
178176
}
179177
stackData := stack.Data
180178
stackLen := len(stackData)

0 commit comments

Comments
 (0)