mirror of https://github.com/poanetwork/quorum.git
Merge pull request #10 from jpmorganchase/jpm-master
Private TX processing and test improvements
This commit is contained in:
commit
a84c31ce76
|
@ -1058,3 +1058,97 @@ func TestCanonicalBlockRetrieval(t *testing.T) {
|
||||||
blockchain.InsertChain(types.Blocks{chain[i]})
|
blockchain.InsertChain(types.Blocks{chain[i]})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type privateTestTx struct {
|
||||||
|
*types.Transaction
|
||||||
|
private bool
|
||||||
|
}
|
||||||
|
|
||||||
|
func (ptx *privateTestTx) IsPrivate() bool { return ptx.private }
|
||||||
|
|
||||||
|
// Tests if the canonical block can be fetched from the database during chain insertion.
|
||||||
|
func TestPrivateTransactions(t *testing.T) {
|
||||||
|
var (
|
||||||
|
db, _ = ethdb.NewMemDatabase()
|
||||||
|
key, _ = crypto.GenerateKey()
|
||||||
|
evmux = &event.TypeMux{}
|
||||||
|
blockchain, _ = NewBlockChain(db, testChainConfig(), FakePow{}, evmux, false)
|
||||||
|
header = &types.Header{}
|
||||||
|
gp = new(GasPool).AddGas(big.NewInt(2000000))
|
||||||
|
err error
|
||||||
|
)
|
||||||
|
publicState, err := state.New(common.Hash{}, db)
|
||||||
|
if err != nil {
|
||||||
|
t.Fatal(err)
|
||||||
|
}
|
||||||
|
privateState, err := state.New(common.Hash{}, db)
|
||||||
|
if err != nil {
|
||||||
|
t.Fatal(err)
|
||||||
|
}
|
||||||
|
prvContractAddr := common.Address{1}
|
||||||
|
pubContractAddr := common.Address{2}
|
||||||
|
|
||||||
|
/* gllc
|
||||||
|
asm {
|
||||||
|
PUSH1 10
|
||||||
|
PUSH1 0
|
||||||
|
SSTORE
|
||||||
|
}
|
||||||
|
*/
|
||||||
|
privateState.SetCode(prvContractAddr, common.Hex2Bytes("600a60005500"))
|
||||||
|
privateState.SetState(prvContractAddr, common.Hash{}, common.Hash{9})
|
||||||
|
publicState.SetCode(pubContractAddr, common.Hex2Bytes("601460005500"))
|
||||||
|
publicState.SetState(pubContractAddr, common.Hash{}, common.Hash{19})
|
||||||
|
|
||||||
|
// Private transaction 1
|
||||||
|
ptx := privateTestTx{private: true}
|
||||||
|
ptx.Transaction, err = types.NewTransaction(0, prvContractAddr, new(big.Int), big.NewInt(1000000), new(big.Int), nil).SignECDSA(key)
|
||||||
|
if err != nil {
|
||||||
|
t.Fatal(err)
|
||||||
|
}
|
||||||
|
_, _, err = ApplyMessage(NewEnv(publicState, privateState, &ChainConfig{}, blockchain, ptx.Transaction, header, vm.Config{}), ptx, gp)
|
||||||
|
if err != nil {
|
||||||
|
t.Fatal(err)
|
||||||
|
}
|
||||||
|
stateEntry := privateState.GetState(prvContractAddr, common.Hash{}).Big()
|
||||||
|
if stateEntry.Cmp(big.NewInt(10)) != 0 {
|
||||||
|
t.Error("expected state to have 10, got", stateEntry)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Public transaction 1
|
||||||
|
ptx = privateTestTx{private: false}
|
||||||
|
ptx.Transaction, err = types.NewTransaction(1, pubContractAddr, new(big.Int), big.NewInt(1000000), new(big.Int), nil).SignECDSA(key)
|
||||||
|
if err != nil {
|
||||||
|
t.Fatal(err)
|
||||||
|
}
|
||||||
|
_, _, err = ApplyMessage(NewEnv(publicState, publicState, &ChainConfig{}, blockchain, ptx.Transaction, header, vm.Config{}), ptx, gp)
|
||||||
|
if err != nil {
|
||||||
|
t.Fatal(err)
|
||||||
|
}
|
||||||
|
stateEntry = publicState.GetState(pubContractAddr, common.Hash{}).Big()
|
||||||
|
if stateEntry.Cmp(big.NewInt(20)) != 0 {
|
||||||
|
t.Error("expected state to have 20, got", stateEntry)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Private transaction 2
|
||||||
|
ptx = privateTestTx{private: true}
|
||||||
|
ptx.Transaction, err = types.NewTransaction(2, prvContractAddr, new(big.Int), big.NewInt(1000000), new(big.Int), nil).SignECDSA(key)
|
||||||
|
if err != nil {
|
||||||
|
t.Fatal(err)
|
||||||
|
}
|
||||||
|
_, _, err = ApplyMessage(NewEnv(publicState, privateState, &ChainConfig{}, blockchain, ptx.Transaction, header, vm.Config{}), ptx, gp)
|
||||||
|
if err != nil {
|
||||||
|
t.Fatal(err)
|
||||||
|
}
|
||||||
|
stateEntry = privateState.GetState(prvContractAddr, common.Hash{}).Big()
|
||||||
|
if stateEntry.Cmp(big.NewInt(10)) != 0 {
|
||||||
|
t.Error("expected state to have 10, got", stateEntry)
|
||||||
|
}
|
||||||
|
|
||||||
|
if publicState.Exist(prvContractAddr) {
|
||||||
|
t.Error("didn't expect private contract address to exist on public state")
|
||||||
|
}
|
||||||
|
if privateState.Exist(pubContractAddr) {
|
||||||
|
t.Error("didn't expect public contract address to exist on private state")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -21,7 +21,6 @@ import (
|
||||||
"math/big"
|
"math/big"
|
||||||
|
|
||||||
"github.com/ethereum/go-ethereum/common"
|
"github.com/ethereum/go-ethereum/common"
|
||||||
"github.com/ethereum/go-ethereum/core/types"
|
|
||||||
"github.com/ethereum/go-ethereum/core/vm"
|
"github.com/ethereum/go-ethereum/core/vm"
|
||||||
"github.com/ethereum/go-ethereum/logger"
|
"github.com/ethereum/go-ethereum/logger"
|
||||||
"github.com/ethereum/go-ethereum/logger/glog"
|
"github.com/ethereum/go-ethereum/logger/glog"
|
||||||
|
@ -77,6 +76,12 @@ type Message interface {
|
||||||
Data() []byte
|
Data() []byte
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// PrivateMessage implements a private message
|
||||||
|
type PrivateMessage interface {
|
||||||
|
Message
|
||||||
|
IsPrivate() bool
|
||||||
|
}
|
||||||
|
|
||||||
func MessageCreatesContract(msg Message) bool {
|
func MessageCreatesContract(msg Message) bool {
|
||||||
return msg.To() == nil
|
return msg.To() == nil
|
||||||
}
|
}
|
||||||
|
@ -159,21 +164,6 @@ func (self *StateTransition) from() (vm.Account, error) {
|
||||||
return self.state.GetAccount(f), nil
|
return self.state.GetAccount(f), nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (self *StateTransition) to() vm.Account {
|
|
||||||
if self.msg == nil {
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
to := self.msg.To()
|
|
||||||
if to == nil {
|
|
||||||
return nil // contract creation
|
|
||||||
}
|
|
||||||
|
|
||||||
if !self.state.Exist(*to) {
|
|
||||||
return self.state.CreateAccount(*to)
|
|
||||||
}
|
|
||||||
return self.state.GetAccount(*to)
|
|
||||||
}
|
|
||||||
|
|
||||||
func (self *StateTransition) useGas(amount *big.Int) error {
|
func (self *StateTransition) useGas(amount *big.Int) error {
|
||||||
if self.gas.Cmp(amount) < 0 {
|
if self.gas.Cmp(amount) < 0 {
|
||||||
return vm.OutOfGasError
|
return vm.OutOfGasError
|
||||||
|
@ -246,7 +236,7 @@ func (self *StateTransition) TransitionDb() (ret []byte, requiredGas, usedGas *b
|
||||||
data []byte
|
data []byte
|
||||||
isPrivate bool
|
isPrivate bool
|
||||||
)
|
)
|
||||||
if tx, ok := msg.(*types.Transaction); ok && tx.IsPrivate() {
|
if msg, ok := msg.(PrivateMessage); ok && msg.IsPrivate() {
|
||||||
isPrivate = true
|
isPrivate = true
|
||||||
data, err = private.P.Receive(self.data)
|
data, err = private.P.Receive(self.data)
|
||||||
// Increment the public account nonce if:
|
// Increment the public account nonce if:
|
||||||
|
@ -257,7 +247,7 @@ func (self *StateTransition) TransitionDb() (ret []byte, requiredGas, usedGas *b
|
||||||
}
|
}
|
||||||
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
glog.V(logger.Debug).Infof("Ignoring private tx %x. Not a participant.", tx.Hash())
|
glog.V(logger.Debug).Infof("Ignoring private tx")
|
||||||
return nil, new(big.Int), new(big.Int), nil
|
return nil, new(big.Int), new(big.Int), nil
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
|
@ -289,7 +279,7 @@ func (self *StateTransition) TransitionDb() (ret []byte, requiredGas, usedGas *b
|
||||||
publicState.SetNonce(sender.Address(), publicState.GetNonce(sender.Address())+1)
|
publicState.SetNonce(sender.Address(), publicState.GetNonce(sender.Address())+1)
|
||||||
}
|
}
|
||||||
|
|
||||||
ret, err = vmenv.Call(sender, self.to().Address(), data, self.gas, self.gasPrice, self.value)
|
ret, err = vmenv.Call(sender, *self.msg.To(), data, self.gas, self.gasPrice, self.value)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
glog.V(logger.Core).Infoln("VM call err:", err)
|
glog.V(logger.Core).Infoln("VM call err:", err)
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue