mirror of https://github.com/poanetwork/quorum.git
added unit tests and comments
This commit is contained in:
parent
bacd5dc3c9
commit
74337c7167
|
@ -188,6 +188,12 @@ func (st *StateTransition) preCheck() error {
|
|||
// TransitionDb will transition the state by applying the current message and
|
||||
// returning the result including the used gas. It returns an error if failed.
|
||||
// An error indicates a consensus issue.
|
||||
//
|
||||
// Quorum:
|
||||
// 1. Intrinsic gas is calculated based on the encrypted payload hash
|
||||
// and NOT the actual private payload
|
||||
// 2. For private transactions, we only deduct intrinsic gas from the gas pool
|
||||
// regardless the current node is party to the transaction or not
|
||||
func (st *StateTransition) TransitionDb() (ret []byte, usedGas uint64, failed bool, err error) {
|
||||
if err = st.preCheck(); err != nil {
|
||||
return
|
||||
|
@ -231,7 +237,7 @@ func (st *StateTransition) TransitionDb() (ret []byte, usedGas uint64, failed bo
|
|||
|
||||
var (
|
||||
leftoverGas uint64
|
||||
evm = st.evm
|
||||
evm = st.evm
|
||||
// vm errors do not effect consensus and are therefor
|
||||
// not assigned to err, except for insufficient balance
|
||||
// error.
|
||||
|
@ -255,6 +261,7 @@ func (st *StateTransition) TransitionDb() (ret []byte, usedGas uint64, failed bo
|
|||
//if input is empty for the smart contract call, return
|
||||
if len(data) == 0 && isPrivate {
|
||||
st.refundGas()
|
||||
st.state.AddBalance(st.evm.Coinbase, new(big.Int).Mul(new(big.Int).SetUint64(st.gasUsed()), st.gasPrice))
|
||||
return nil, 0, false, nil
|
||||
}
|
||||
|
||||
|
|
|
@ -0,0 +1,115 @@
|
|||
package core
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"math/big"
|
||||
"testing"
|
||||
|
||||
"github.com/ethereum/go-ethereum/private"
|
||||
|
||||
"github.com/ethereum/go-ethereum/common"
|
||||
"github.com/ethereum/go-ethereum/core/state"
|
||||
"github.com/ethereum/go-ethereum/core/vm"
|
||||
"github.com/ethereum/go-ethereum/ethdb"
|
||||
"github.com/ethereum/go-ethereum/params"
|
||||
|
||||
testifyassert "github.com/stretchr/testify/assert"
|
||||
)
|
||||
|
||||
func verifyGasPoolCalculation(t *testing.T, pm private.PrivateTransactionManager) {
|
||||
assert := testifyassert.New(t)
|
||||
saved := private.P
|
||||
defer func() {
|
||||
private.P = saved
|
||||
}()
|
||||
private.P = pm
|
||||
|
||||
txGasLimit := uint64(100000)
|
||||
gasPool := new(GasPool).AddGas(200000)
|
||||
// this payload would give us 25288 intrinsic gas
|
||||
arbitraryEncryptedPayload := "4ab80888354582b92ab442a317828386e4bf21ea4a38d1a9183fbb715f199475269d7686939017f4a6b28310d5003ebd8e012eade530b79e157657ce8dd9692a"
|
||||
expectedGasPool := new(GasPool).AddGas(174712) // only intrinsic gas is deducted
|
||||
|
||||
db := ethdb.NewMemDatabase()
|
||||
privateState, _ := state.New(common.Hash{}, state.NewDatabase(db))
|
||||
publicState, _ := state.New(common.Hash{}, state.NewDatabase(db))
|
||||
msg := privateCallMsg{
|
||||
callmsg: callmsg{
|
||||
addr: common.Address{2},
|
||||
to: &common.Address{},
|
||||
value: new(big.Int),
|
||||
gas: txGasLimit,
|
||||
gasPrice: big.NewInt(0),
|
||||
data: common.Hex2Bytes(arbitraryEncryptedPayload),
|
||||
},
|
||||
}
|
||||
ctx := NewEVMContext(msg, &dualStateTestHeader, nil, &common.Address{})
|
||||
evm := vm.NewEVM(ctx, publicState, privateState, params.QuorumTestChainConfig, vm.Config{})
|
||||
arbitraryBalance := big.NewInt(100000000)
|
||||
publicState.SetBalance(evm.Coinbase, arbitraryBalance)
|
||||
publicState.SetBalance(msg.From(), arbitraryBalance)
|
||||
|
||||
testObject := NewStateTransition(evm, msg, gasPool)
|
||||
|
||||
_, _, failed, err := testObject.TransitionDb()
|
||||
|
||||
assert.NoError(err)
|
||||
assert.False(failed)
|
||||
|
||||
assert.Equal(new(big.Int).SetUint64(expectedGasPool.Gas()), new(big.Int).SetUint64(gasPool.Gas()), "gas pool must be calculated correctly")
|
||||
assert.Equal(arbitraryBalance, publicState.GetBalance(evm.Coinbase), "balance must not be changed")
|
||||
assert.Equal(arbitraryBalance, publicState.GetBalance(msg.From()), "balance must not be changed")
|
||||
}
|
||||
|
||||
func TestStateTransition_TransitionDb_GasPoolCalculation_whenNonPartyNodeProcessingPrivateTransactions(t *testing.T) {
|
||||
stubPTM := &StubPrivateTransactionManager{
|
||||
responses: map[string][]interface{}{
|
||||
"Receive": {
|
||||
[]byte{},
|
||||
nil,
|
||||
},
|
||||
},
|
||||
}
|
||||
verifyGasPoolCalculation(t, stubPTM)
|
||||
}
|
||||
|
||||
func TestStateTransition_TransitionDb_GasPoolCalculation_whenPartyNodeProcessingPrivateTransactions(t *testing.T) {
|
||||
stubPTM := &StubPrivateTransactionManager{
|
||||
responses: map[string][]interface{}{
|
||||
"Receive": {
|
||||
common.Hex2Bytes("600a6000526001601ff300"),
|
||||
nil,
|
||||
},
|
||||
},
|
||||
}
|
||||
verifyGasPoolCalculation(t, stubPTM)
|
||||
}
|
||||
|
||||
type privateCallMsg struct {
|
||||
callmsg
|
||||
}
|
||||
|
||||
func (pm privateCallMsg) IsPrivate() bool { return true }
|
||||
|
||||
type StubPrivateTransactionManager struct {
|
||||
responses map[string][]interface{}
|
||||
}
|
||||
|
||||
func (spm *StubPrivateTransactionManager) Send(data []byte, from string, to []string) ([]byte, error) {
|
||||
return nil, fmt.Errorf("to be implemented")
|
||||
}
|
||||
|
||||
func (spm *StubPrivateTransactionManager) SendSignedTx(data []byte, to []string) ([]byte, error) {
|
||||
return nil, fmt.Errorf("to be implemented")
|
||||
}
|
||||
|
||||
func (spm *StubPrivateTransactionManager) Receive(data []byte) ([]byte, error) {
|
||||
res := spm.responses["Receive"]
|
||||
if err, ok := res[1].(error); ok {
|
||||
return nil, err
|
||||
}
|
||||
if ret, ok := res[0].([]byte); ok {
|
||||
return ret, nil
|
||||
}
|
||||
return nil, nil
|
||||
}
|
Loading…
Reference in New Issue