[core] fix: block multiple cx xfers per tx

pull/4165/head
MaxMustermann2 3 years ago
parent 96e075beb5
commit c9768c9d4e
No known key found for this signature in database
GPG Key ID: 4F4AB9DB6FF24C94
  1. 26
      core/vm/contracts_write.go
  2. 3
      core/vm/contracts_write_test.go

@ -283,16 +283,22 @@ func (c *crossShardXferPrecompile) RunWriteCapable(
// now do the actual transfer
// step 1 -> remove funds from the precompile address
evm.Transfer(evm.StateDB, contract.Address(), toAddress, value, types.SubtractionOnly)
// step 2 -> make a cross link
// note that the transaction hash is added by state_processor.go to this receipt
// and that the receiving shard does not care about the `From` but we use the original
// instead of the precompile address for consistency
evm.CXReceipt = &types.CXReceipt{
From: fromAddress,
To: &toAddress,
ShardID: fromShardID,
ToShardID: toShardID,
Amount: value,
// make sure that cxreceipt is already nil to prevent multiple calls to the precompile
// in the same transaction
if evm.CXReceipt == nil {
// step 2 -> make a cross link
// note that the transaction hash is added by state_processor.go to this receipt
// and that the receiving shard does not care about the `From` but we use the original
// instead of the precompile address for consistency
evm.CXReceipt = &types.CXReceipt{
From: fromAddress,
To: &toAddress,
ShardID: fromShardID,
ToShardID: toShardID,
Amount: value,
}
} else {
return nil, errors.New("cannot call cross shard precompile again in same tx")
}
return nil, nil
}

@ -3,7 +3,6 @@ package vm
import (
"bytes"
"errors"
"fmt"
"math/big"
"testing"
@ -66,7 +65,7 @@ func CalculateMigrationGasFn() CalculateMigrationGasFunc {
}
func testWriteCapablePrecompile(test writeCapablePrecompileTest, t *testing.T, env *EVM, p WriteCapablePrecompiledContract) {
t.Run(fmt.Sprintf("%s", test.name), func(t *testing.T) {
t.Run(test.name, func(t *testing.T) {
contract := NewContract(AccountRef(common.HexToAddress("1337")), AccountRef(common.HexToAddress("1338")), test.value, 0)
gas, err := p.RequiredGas(env, contract, test.input)
if err != nil {

Loading…
Cancel
Save