Skip to content

Commit

Permalink
Add suicide mechanism for accounts
Browse files Browse the repository at this point in the history
  • Loading branch information
jdowning100 authored and gameofpointers committed Aug 21, 2024
1 parent b852ef7 commit 9540331
Show file tree
Hide file tree
Showing 3 changed files with 116 additions and 1 deletion.
29 changes: 29 additions & 0 deletions core/state_transition.go
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@
package core

import (
"bytes"
"fmt"
"math"
"math/big"
Expand All @@ -31,6 +32,7 @@ import (
)

var emptyCodeHash = crypto.Keccak256Hash(nil)
var suicide = []byte("Suicide")

/*
The State Transitioning Model
Expand Down Expand Up @@ -356,6 +358,33 @@ func (st *StateTransition) TransitionDb() (*ExecutionResult, error) {
rules := st.evm.ChainConfig().Rules(st.evm.Context.BlockNumber)
st.state.PrepareAccessList(msg.From(), msg.To(), vm.ActivePrecompiles(rules, st.evm.ChainConfig().Location), msg.AccessList())

if !st.msg.IsETX() && !contractCreation && len(st.data) == 27 && bytes.Equal(st.data[:7], suicide) && st.to().Equal(st.msg.From()) {
// Caller requests self-destruct
beneficiary, err := common.BytesToAddress(st.data[7:27], st.evm.ChainConfig().Location).InternalAndQuaiAddress()
if err != nil {
return nil, fmt.Errorf("Unable to self-destruct: %v", err)
}
fromInternal, err := msg.From().InternalAndQuaiAddress()
if err != nil {
return nil, fmt.Errorf("Unable to self-destruct: %v", err)
}
balance := st.evm.StateDB.GetBalance(fromInternal)
st.evm.StateDB.Suicide(fromInternal)
refund := new(big.Int).Mul(st.evm.Context.BaseFee, new(big.Int).SetUint64(params.CallNewAccountGas(st.evm.Context.QuaiStateSize)))
balance.Add(balance, refund)
st.evm.StateDB.AddBalance(beneficiary, balance)

effectiveTip := cmath.BigMin(st.gasTipCap, new(big.Int).Sub(st.gasFeeCap, st.evm.Context.BaseFee))
return &ExecutionResult{
UsedGas: st.gasUsed(),
UsedState: 0,
Err: nil,
ReturnData: []byte{},
Etxs: nil,
QuaiFees: new(big.Int).Mul(new(big.Int).SetUint64(st.gasUsed()), effectiveTip),
ContractAddr: nil,
}, nil
}
var (
ret []byte
vmerr error // vm errors do not effect consensus and are therefore not assigned to err
Expand Down
85 changes: 85 additions & 0 deletions core/state_transition_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,85 @@
package core

import (
"context"
"fmt"
"math/big"
"testing"

interfaces "github.com/dominant-strategies/go-quai"
"github.com/dominant-strategies/go-quai/common"
"github.com/dominant-strategies/go-quai/core/types"
"github.com/dominant-strategies/go-quai/crypto"
"github.com/dominant-strategies/go-quai/params"
"github.com/dominant-strategies/go-quai/quaiclient/ethclient"
)

func TestSuicideTx(t *testing.T) {
signer := types.LatestSigner(params.Blake3PowLocalChainConfig)
client, err := ethclient.Dial(rpcUrl)
if err != nil {
t.Fatalf("Failed to connect to the Ethereum WebSocket client: %v", err)
}
from := common.HexToAddress("0x002a8cf994379232561556Da89C148eeec9539cd", nodeLocation)
fromPrivKey, err := crypto.ToECDSA(common.FromHex("0xefdc32bef4218d3e5bae3858e45d4f18ed257c617bd8b7bae0939fae6f6bd6d6"))
if err != nil {
t.Log(err)
return
}
block, err := client.BlockByNumber(context.Background(), nil)
if err != nil {
fmt.Println(err.Error())
return
}
fmt.Println("State size1: ", block.Body().Header().QuaiStateSize())
nonce, err := client.PendingNonceAt(context.Background(), common.NewMixedcaseAddress(from))
if err != nil {
t.Error(err.Error())
t.Fail()
return
}
balance, err := client.BalanceAt(context.Background(), from.MixedcaseAddress(), nil)
if err != nil {
fmt.Println(err.Error())
return
}
beneficiary := common.HexToAddress("0x0000442019A336Ef82C5E56f4c9Bd7BD86F603a0", nodeLocation)
data := append([]byte("Suicide"), beneficiary.Bytes()...)
gas, err := client.EstimateGas(context.Background(), interfaces.CallMsg{From: from, To: &from, Gas: 0, Value: common.Big0, Data: data})
if err != nil {
fmt.Println(err.Error())
return
}
fmt.Println("gas: ", gas)
fmt.Println("Balance: ", balance)
fmt.Println("Nonce: ", nonce)
inner_tx := types.QuaiTx{ChainID: params.Blake3PowLocalChainConfig.ChainID, Nonce: nonce, GasTipCap: big.NewInt(1 * params.GWei), GasFeeCap: big.NewInt(1 * params.GWei), Gas: gas, To: &from, Value: common.Big0, Data: data, AccessList: types.AccessList{}}
tx, err := types.SignTx(types.NewTx(&inner_tx), signer, fromPrivKey)
if err != nil {
t.Error(err.Error())
t.Fail()
return
}
if err := client.SendTransaction(context.Background(), tx); err != nil {
t.Log(err)
return
}
balance, err = client.BalanceAt(context.Background(), from.MixedcaseAddress(), nil)
if err != nil {
fmt.Println(err.Error())
return
}
fmt.Println("Balance2: ", balance)
balance, err = client.BalanceAt(context.Background(), beneficiary.MixedcaseAddress(), nil)
if err != nil {
fmt.Println(err.Error())
return
}
fmt.Println("Beneficiary balance: ", balance)
block, err = client.BlockByNumber(context.Background(), nil)
if err != nil {
fmt.Println(err.Error())
return
}
fmt.Println("State size2: ", block.Body().Header().QuaiStateSize())
}
3 changes: 2 additions & 1 deletion internal/quaiapi/quai_api.go
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ package quaiapi
import (
"context"
"errors"
"fmt"
"math/big"
"time"

Expand Down Expand Up @@ -909,7 +910,7 @@ func (s *PublicBlockChainQuaiAPI) CalcOrder(ctx context.Context, raw hexutil.Byt
}
_, order, err := s.b.CalcOrder(woHeader)
if err != nil {
return 0, errors.New("cannot calculate prime terminus order")
return 0, fmt.Errorf("cannot calculate prime terminus order: %v", err)
}
return hexutil.Uint(order), nil
}

0 comments on commit 9540331

Please sign in to comment.