diff --git a/accounts/abi/bind/backends/simulated.go b/accounts/abi/bind/backends/simulated.go index 0f69b68890..7f27fe57c3 100644 --- a/accounts/abi/bind/backends/simulated.go +++ b/accounts/abi/bind/backends/simulated.go @@ -544,7 +544,7 @@ func (fb *filterBackend) ServiceFilter(ctx context.Context, ms *bloombits.Matche panic("not supported") } -func (fb *filterBackend) AccountExtraDataStateReaderByNumber(context.Context, rpc.BlockNumber) (vm.AccountExtraDataStateReader, error) { +func (fb *filterBackend) AccountExtraDataStateGetterByNumber(context.Context, rpc.BlockNumber) (vm.AccountExtraDataStateGetter, error) { panic("not supported") } diff --git a/common/slice.go b/common/slice.go new file mode 100644 index 0000000000..5bcf76ee91 --- /dev/null +++ b/common/slice.go @@ -0,0 +1,54 @@ +// Copyright 2014 The go-ethereum Authors +// This file is part of the go-ethereum library. +// +// The go-ethereum library is free software: you can redistribute it and/or modify +// it under the terms of the GNU Lesser General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// The go-ethereum library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public License +// along with the go-ethereum library. If not, see . + +package common + +// ContainsAll returns true if all elements in the target are in the source, +// false otherwise. +func ContainsAll(source, target []string) bool { + mark := make(map[string]bool, len(source)) + for _, str := range source { + mark[str] = true + } + for _, str := range target { + if _, found := mark[str]; !found { + return false + } + } + return true +} + +// ContainsAll returns true if all elements in the target are NOT in the source, +// false otherwise. +func NotContainsAll(source, target []string) bool { + return !ContainsAll(source, target) +} + +// AppendSkipDuplicates appends source with elements with a condition +// that those elemments must NOT already exist in the source +func AppendSkipDuplicates(slice []string, elems ... string) (result []string) { + mark := make(map[string]bool, len(slice)) + for _, val := range slice { + mark[val] = true + } + result = slice + for _, val := range elems { + if _, ok := mark[val]; !ok { + result = append(result, val) + } + } + return result +} diff --git a/common/slice_test.go b/common/slice_test.go new file mode 100644 index 0000000000..88a63e7819 --- /dev/null +++ b/common/slice_test.go @@ -0,0 +1,93 @@ +// Copyright 2014 The go-ethereum Authors +// This file is part of the go-ethereum library. +// +// The go-ethereum library is free software: you can redistribute it and/or modify +// it under the terms of the GNU Lesser General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// The go-ethereum library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public License +// along with the go-ethereum library. If not, see . + +package common + +import ( + "testing" + + "github.com/stretchr/testify/assert" +) + +func TestContainsAll_whenTypical(t *testing.T) { + source := []string{"1", "2"} + target := []string{"1", "2"} + + assert.True(t, ContainsAll(source, target)) +} + +func TestContainsAll_whenNot(t *testing.T) { + source := []string{"1", "2"} + target := []string{"3", "4"} + + assert.False(t, ContainsAll(source, target)) +} + +func TestContainsAll_whenTargetIsSubset(t *testing.T) { + source := []string{"1", "2"} + target := []string{"1"} + + assert.True(t, ContainsAll(source, target)) +} + +func TestContainsAll_whenTargetIsSuperSet(t *testing.T) { + source := []string{"2"} + target := []string{"1", "2"} + + assert.False(t, ContainsAll(source, target)) +} + +func TestContainsAll_whenSourceIsEmpty(t *testing.T) { + var source []string + target := []string{"1", "2"} + + assert.False(t, ContainsAll(source, target)) +} + +func TestContainsAll_whenSourceIsNil(t *testing.T) { + target := []string{"1", "2"} + + assert.False(t, ContainsAll(nil, target)) +} + +func TestContainsAll_whenTargetIsEmpty(t *testing.T) { + source := []string{"1", "2"} + + assert.True(t, ContainsAll(source, []string{})) +} + +func TestContainsAll_whenTargetIsNil(t *testing.T) { + source := []string{"1", "2"} + + assert.True(t, ContainsAll(source, nil)) +} + +func TestAppendSkipDuplicates_whenTypical(t *testing.T) { + source := []string{"1", "2"} + additional := []string{"1", "3"} + + assert.Equal(t, []string{"1", "2", "3"}, AppendSkipDuplicates(source, additional...)) +} + +func TestAppendSkipDuplicates_whenSourceIsNil(t *testing.T) { + additional := []string{"1", "3"} + + assert.Equal(t, []string{"1", "3"}, AppendSkipDuplicates(nil, additional...)) +} + +func TestAppendSkipDuplicates_whenElementIsNil(t *testing.T) { + assert.Equal(t, []string{"1", "3"}, AppendSkipDuplicates([]string{"1", "3"}, nil...)) +} diff --git a/core/rawdb/database_quorum.go b/core/rawdb/database_quorum.go index 965eb88a19..4d5f169839 100644 --- a/core/rawdb/database_quorum.go +++ b/core/rawdb/database_quorum.go @@ -89,11 +89,11 @@ func GetPrivateBlockBloom(db ethdb.Database, number uint64) (bloom types.Bloom) // AccountExtraDataLinker maintains mapping between root hash of the state trie // and root hash of state.AccountExtraData trie type AccountExtraDataLinker interface { - // Find returns the root hash of the state.AccountExtraData trie from + // GetAccountExtraDataRoot returns the root hash of the state.AccountExtraData trie from // the given root hash of the state trie. // // It returns an empty hash if not found. - Find(stateRoot common.Hash) common.Hash + GetAccountExtraDataRoot(stateRoot common.Hash) common.Hash // Link saves the mapping between root hash of the state trie and // root hash of state.AccountExtraData trie to the persistent storage. // Don't write the mapping if extraDataRoot is an emptyRoot @@ -112,7 +112,7 @@ func NewAccountExtraDataLinker(db ethdb.Database) AccountExtraDataLinker { } } -func (pml *ethdbAccountExtraDataLinker) Find(stateRoot common.Hash) common.Hash { +func (pml *ethdbAccountExtraDataLinker) GetAccountExtraDataRoot(stateRoot common.Hash) common.Hash { return GetAccountExtraDataRoot(pml.db, stateRoot) } diff --git a/core/rawdb/database_quorum_test.go b/core/rawdb/database_quorum_test.go index 3e35f986da..b44c7f56f8 100644 --- a/core/rawdb/database_quorum_test.go +++ b/core/rawdb/database_quorum_test.go @@ -132,7 +132,7 @@ func TestAccountExtraDataLinker_whenFinding(t *testing.T) { pml := NewAccountExtraDataLinker(db) - pmrRetrieved := pml.Find(psr) + pmrRetrieved := pml.GetAccountExtraDataRoot(psr) if pmrRetrieved != pmr { t.Fatal("the mapping should have been retrieved") @@ -145,7 +145,7 @@ func TestAccountExtraDataLinker_whenNotFound(t *testing.T) { pml := NewAccountExtraDataLinker(db) - pmrRetrieved := pml.Find(psr) + pmrRetrieved := pml.GetAccountExtraDataRoot(psr) if !common.EmptyHash(pmrRetrieved) { t.Fatal("the retrieved privacy metadata root should be the empty hash") diff --git a/core/state/statedb.go b/core/state/statedb.go index 43bedbfd13..b8fb985f2a 100644 --- a/core/state/statedb.go +++ b/core/state/statedb.go @@ -114,7 +114,7 @@ func New(root common.Hash, db Database) (*StateDB, error) { } // Quorum - Privacy Enhancements - retrieve the privacy metadata root corresponding to the account state root - extraDataRoot := db.AccountExtraDataLinker().Find(root) + extraDataRoot := db.AccountExtraDataLinker().GetAccountExtraDataRoot(root) log.Debug("Account Extra Data root", "hash", extraDataRoot) accountExtraDataTrie, err := db.OpenTrie(extraDataRoot) if err != nil { @@ -253,7 +253,7 @@ func (self *StateDB) GetNonce(addr common.Address) uint64 { return 0 } -func (self *StateDB) ReadPrivacyMetadata(addr common.Address) (*PrivacyMetadata, error) { +func (self *StateDB) GetPrivacyMetadata(addr common.Address) (*PrivacyMetadata, error) { stateObject := self.getStateObject(addr) if stateObject != nil { return stateObject.PrivacyMetadata() @@ -269,7 +269,7 @@ func (self *StateDB) GetCommittedStatePrivacyMetadata(addr common.Address) (*Pri return nil, nil } -func (self *StateDB) ReadManagedParties(addr common.Address) ([]string, error) { +func (self *StateDB) GetManagedParties(addr common.Address) ([]string, error) { stateObject := self.getStateObject(addr) if stateObject != nil { return stateObject.ManagedParties() @@ -437,14 +437,14 @@ func (self *StateDB) SetNonce(addr common.Address, nonce uint64) { } } -func (self *StateDB) WritePrivacyMetadata(addr common.Address, metadata *PrivacyMetadata) { +func (self *StateDB) SetPrivacyMetadata(addr common.Address, metadata *PrivacyMetadata) { stateObject := self.GetOrNewStateObject(addr) if stateObject != nil { stateObject.SetStatePrivacyMetadata(metadata) } } -func (self *StateDB) WriteManagedParties(addr common.Address, managedParties []string) { +func (self *StateDB) SetManagedParties(addr common.Address, managedParties []string) { stateObject := self.GetOrNewStateObject(addr) if stateObject != nil && len(managedParties) > 0 { stateObject.SetManagedParties(managedParties) diff --git a/core/state/statedb_test.go b/core/state/statedb_test.go index 2b6ab9f65e..cac1d90610 100644 --- a/core/state/statedb_test.go +++ b/core/state/statedb_test.go @@ -326,7 +326,7 @@ func newTestAction(addr common.Address, r *rand.Rand) testAction { args: make([]int64, 2), }, { - name: "WritePrivacyMetadata", + name: "SetPrivacyMetadata", fn: func(a testAction, s *StateDB) { privFlag := engine.PrivacyFlagType((uint64(a.args[0])%2)*2 + 1) // the only possible values should be 1 and 3 @@ -334,7 +334,7 @@ func newTestAction(addr common.Address, r *rand.Rand) testAction { binary.BigEndian.PutUint64(b, uint64(a.args[1])) hash := common.BytesToEncryptedPayloadHash(b) - s.WritePrivacyMetadata(addr, &PrivacyMetadata{ + s.SetPrivacyMetadata(addr, &PrivacyMetadata{ CreationTxHash: hash, PrivacyFlag: privFlag, }) @@ -482,9 +482,9 @@ func (test *snapshotTest) checkEqual(state, checkstate *StateDB) error { checkeq("GetCode", state.GetCode(addr), checkstate.GetCode(addr)) checkeq("GetCodeHash", state.GetCodeHash(addr), checkstate.GetCodeHash(addr)) checkeq("GetCodeSize", state.GetCodeSize(addr), checkstate.GetCodeSize(addr)) - statePM, _ := state.ReadPrivacyMetadata(addr) - checkStatePM, _ := checkstate.ReadPrivacyMetadata(addr) - checkeq("ReadPrivacyMetadata", statePM, checkStatePM) + statePM, _ := state.GetPrivacyMetadata(addr) + checkStatePM, _ := checkstate.GetPrivacyMetadata(addr) + checkeq("GetPrivacyMetadata", statePM, checkStatePM) // Check storage. if obj := state.getStateObject(addr); obj != nil { state.ForEachStorage(addr, func(key, value common.Hash) bool { @@ -744,7 +744,7 @@ func TestPrivacyMetadataIsSavedOnStateDbCommit(t *testing.T) { state.CreateAccount(addr) state.SetNonce(addr, uint64(1)) - state.WritePrivacyMetadata(addr, &PrivacyMetadata{ + state.SetPrivacyMetadata(addr, &PrivacyMetadata{ PrivacyFlag: engine.PrivacyFlagPartyProtection, CreationTxHash: common.EncryptedPayloadHash{1}, }) @@ -771,7 +771,7 @@ func TestPrivacyMetadataIsUpdatedOnAccountReCreateWithDifferentPrivacyMetadata(t state.CreateAccount(addr) state.SetNonce(addr, uint64(1)) - state.WritePrivacyMetadata(addr, &PrivacyMetadata{ + state.SetPrivacyMetadata(addr, &PrivacyMetadata{ PrivacyFlag: engine.PrivacyFlagPartyProtection, CreationTxHash: common.EncryptedPayloadHash{1}, }) @@ -784,7 +784,7 @@ func TestPrivacyMetadataIsUpdatedOnAccountReCreateWithDifferentPrivacyMetadata(t state.CreateAccount(addr) state.SetNonce(addr, uint64(1)) - state.WritePrivacyMetadata(addr, &PrivacyMetadata{ + state.SetPrivacyMetadata(addr, &PrivacyMetadata{ PrivacyFlag: engine.PrivacyFlagStateValidation, CreationTxHash: common.EncryptedPayloadHash{1}, }) @@ -808,7 +808,7 @@ func TestPrivacyMetadataIsRemovedOnAccountSuicide(t *testing.T) { state.CreateAccount(addr) state.SetNonce(addr, uint64(1)) - state.WritePrivacyMetadata(addr, &PrivacyMetadata{ + state.SetPrivacyMetadata(addr, &PrivacyMetadata{ PrivacyFlag: engine.PrivacyFlagPartyProtection, CreationTxHash: common.EncryptedPayloadHash{1}, }) @@ -837,7 +837,7 @@ func TestPrivacyMetadataChangesAreRolledBackOnRevert(t *testing.T) { state.CreateAccount(addr) state.SetNonce(addr, uint64(1)) - state.WritePrivacyMetadata(addr, &PrivacyMetadata{ + state.SetPrivacyMetadata(addr, &PrivacyMetadata{ PrivacyFlag: engine.PrivacyFlagPartyProtection, CreationTxHash: common.BytesToEncryptedPayloadHash([]byte("one")), }) @@ -849,7 +849,7 @@ func TestPrivacyMetadataChangesAreRolledBackOnRevert(t *testing.T) { } // update privacy metadata - state.WritePrivacyMetadata(addr, &PrivacyMetadata{ + state.SetPrivacyMetadata(addr, &PrivacyMetadata{ PrivacyFlag: engine.PrivacyFlagStateValidation, CreationTxHash: common.BytesToEncryptedPayloadHash([]byte("two")), }) @@ -857,18 +857,18 @@ func TestPrivacyMetadataChangesAreRolledBackOnRevert(t *testing.T) { // record the snapshot snapshot := state.Snapshot() - privMetaData, _ = state.ReadPrivacyMetadata(addr) + privMetaData, _ = state.GetPrivacyMetadata(addr) if privMetaData.CreationTxHash != common.BytesToEncryptedPayloadHash([]byte("two")) { t.Errorf("current privacy metadata creation tx hash does not match the expected value") } // update the metadata - state.WritePrivacyMetadata(addr, &PrivacyMetadata{ + state.SetPrivacyMetadata(addr, &PrivacyMetadata{ PrivacyFlag: engine.PrivacyFlagStateValidation, CreationTxHash: common.BytesToEncryptedPayloadHash([]byte("three")), }) - privMetaData, _ = state.ReadPrivacyMetadata(addr) + privMetaData, _ = state.GetPrivacyMetadata(addr) if privMetaData.CreationTxHash != common.BytesToEncryptedPayloadHash([]byte("three")) { t.Errorf("current privacy metadata creation tx hash does not match the expected value") } @@ -876,7 +876,7 @@ func TestPrivacyMetadataChangesAreRolledBackOnRevert(t *testing.T) { // revert to snapshot state.RevertToSnapshot(snapshot) - privMetaData, _ = state.ReadPrivacyMetadata(addr) + privMetaData, _ = state.GetPrivacyMetadata(addr) if privMetaData.CreationTxHash != common.BytesToEncryptedPayloadHash([]byte("two")) { t.Errorf("current privacy metadata creation tx hash does not match the expected value") } diff --git a/core/state_transition.go b/core/state_transition.go index ca922d14fe..5248ad6e6d 100644 --- a/core/state_transition.go +++ b/core/state_transition.go @@ -318,13 +318,13 @@ func (st *StateTransition) TransitionDb() (ret []byte, usedGas uint64, failed bo if msg, ok := msg.(PrivateMessage); ok && isQuorum && st.evm.SupportsMultitenancy && msg.IsPrivate() { if len(managedPartiesInTx) > 0 { for _, address := range evm.AffectedContracts() { - managedPartiesInContract, err := st.evm.StateDB.ReadManagedParties(address) + managedPartiesInContract, err := st.evm.StateDB.GetManagedParties(address) if err != nil { return nil, 0, true, err } // managed parties for public transactions is empty so nothing to check there if len(managedPartiesInContract) > 0 { - if !containsAll(managedPartiesInContract, managedPartiesInTx) { + if common.NotContainsAll(managedPartiesInContract, managedPartiesInTx) { log.Debug("Managed parties check has failed for contract", "addr", address, "EPH", pmh.eph.TerminalString(), "contractMP", managedPartiesInContract, "txMP", managedPartiesInTx) st.evm.RevertToSnapshot(snapshot) @@ -356,7 +356,7 @@ func (st *StateTransition) TransitionDb() (ret []byte, usedGas uint64, failed bo "address", strings.ToLower(address.Hex()), "isPrivate", isPrivate, "parties", managedPartiesInTx) - st.evm.StateDB.WriteManagedParties(address, managedPartiesInTx) + st.evm.StateDB.SetManagedParties(address, managedPartiesInTx) } } @@ -366,22 +366,6 @@ func (st *StateTransition) TransitionDb() (ret []byte, usedGas uint64, failed bo return ret, st.gasUsed(), vmerr != nil, err } -func containsAll(source, target []string) bool { - for _, str := range target { - found := false - for _, sourceStr := range source { - if sourceStr == str { - found = true - break - } - } - if !found { - return false - } - } - return true -} - func (st *StateTransition) refundGas() { // Apply refund counter, capped to half of the used gas. refund := st.gasUsed() / 2 @@ -415,7 +399,7 @@ func (st *StateTransition) RevertToSnapshot(snapshot int) { st.evm.StateDB.RevertToSnapshot(snapshot) } func (st *StateTransition) GetStatePrivacyMetadata(addr common.Address) (*state.PrivacyMetadata, error) { - return st.evm.StateDB.ReadPrivacyMetadata(addr) + return st.evm.StateDB.GetPrivacyMetadata(addr) } func (st *StateTransition) CalculateMerkleRoot() (common.Hash, error) { return st.evm.CalculateMerkleRoot() diff --git a/core/state_transition_pmh.go b/core/state_transition_pmh.go index 5c2c750785..f97d4d7a3e 100644 --- a/core/state_transition_pmh.go +++ b/core/state_transition_pmh.go @@ -86,7 +86,7 @@ func (pmh *privateMessageHandler) verify(vmerr error) (bool, error) { log.Trace("Verify hashes of affected contracts", "expectedHashes", pmh.receivedPrivacyMetadata.ACHashes, "numberOfAffectedAddresses", len(actualACAddresses)) privacyFlag := pmh.receivedPrivacyMetadata.PrivacyFlag for _, addr := range actualACAddresses { - // ReadPrivacyMetadata is invoked on the privateState (as the tx is private) and it returns: + // GetPrivacyMetadata is invoked on the privateState (as the tx is private) and it returns: // 1. public contacts: privacyMetadata = nil, err = nil // 2. private contracts of type: // 2.1. StandardPrivate: privacyMetadata = nil, err = "The provided contract does not have privacy metadata" diff --git a/core/vm/evm.go b/core/vm/evm.go index d2c7ed845a..243ff9c5a8 100644 --- a/core/vm/evm.go +++ b/core/vm/evm.go @@ -242,11 +242,25 @@ const ( type AffectedMode byte const ( + // ModeUnknown indicates an auxiliary mode used during initialization of an affected contract ModeUnknown AffectedMode = iota - ModeRead AffectedMode = iota - ModeWrite = ModeRead << 1 + // ModeRead indicates that state has not been modified as the result of contract code execution + ModeRead AffectedMode = iota + // ModeWrite indicates that state has been modified as the result of contract code execution + ModeWrite = ModeRead << 1 ) +func ModeOf(isWrite bool) AffectedMode { + if isWrite { + return ModeWrite + } + return ModeRead +} + +func (mode AffectedMode) IsAuthorized(actualMode AffectedMode) bool { + return mode&actualMode != actualMode +} + // NewEVM returns a new EVM. The returned EVM is not thread safe and should // only ever be used *once*. func NewEVM(ctx Context, statedb, privateState StateDB, chainConfig *params.ChainConfig, vmConfig Config) *EVM { @@ -563,12 +577,12 @@ func (evm *EVM) create(caller ContractRef, codeAndHash *codeAndHash, gas uint64, } // Create a new account on the state snapshot := evm.StateDB.Snapshot() - evm.StateDB.CreateAccount(address) if evm.SupportsMultitenancy && evm.AuthorizeCreateFunc != nil { if authorized := evm.AuthorizeCreateFunc(); !authorized { return nil, common.Address{}, gas, multitenancy.ErrNotAuthorized } } + evm.StateDB.CreateAccount(address) evm.affectedContracts[address] = newAffectedType(Creation, ModeWrite|ModeRead) if evm.chainRules.IsEIP158 { evm.StateDB.SetNonce(address, 1) @@ -577,7 +591,7 @@ func (evm *EVM) create(caller ContractRef, codeAndHash *codeAndHash, gas uint64, // for calls (reading contract state) or finding the affected contracts there is no transaction if evm.currentTx.PrivacyMetadata().PrivacyFlag.IsNotStandardPrivate() { pm := state.NewStatePrivacyMetadata(common.BytesToEncryptedPayloadHash(evm.currentTx.Data()), evm.currentTx.PrivacyMetadata().PrivacyFlag) - evm.StateDB.WritePrivacyMetadata(address, pm) + evm.StateDB.SetPrivacyMetadata(address, pm) log.Trace("Set Privacy Metadata", "key", address, "privacyMetadata", pm) } } @@ -784,6 +798,17 @@ func (evm *EVM) popAddress() { evm.addressStack = evm.addressStack[:l-1] } +// Quorum +// +// peekAddress retrieves the affected contract address from the top of the stack +func (evm *EVM) peekAddress() common.Address { + l := len(evm.addressStack) + if l == 0 { + return common.Address{} + } + return evm.addressStack[l-1] +} + // Quorum // // captureOperationMode stores the type of operation being applied on the current @@ -791,19 +816,15 @@ func (evm *EVM) popAddress() { // For multitenancy, it checks if the mode is allowed. Also it bubbles up the last error // captured. This helps to avoid "evm: execution revert" generic error func (evm *EVM) captureOperationMode(isWriteOperation bool) error { - l := len(evm.addressStack) - if l == 0 { + currentAddress := evm.peekAddress() + if (currentAddress == common.Address{}) { return nil } - currentAddress := evm.addressStack[l-1] - actualMode := ModeRead - if isWriteOperation { - actualMode = ModeWrite - } + actualMode := ModeOf(isWriteOperation) if t, ok := evm.affectedContracts[currentAddress]; ok { // perform multitenancy check if evm.enforceMultitenancyCheck() { - if t.mode&actualMode != actualMode { + if t.mode.IsAuthorized(actualMode) { log.Trace("Multitenancy check for captureOperationMode()", "address", currentAddress.Hex(), "actual", actualMode, "expect", t.mode) evm.lastError = multitenancy.ErrNotAuthorized } diff --git a/core/vm/interface.go b/core/vm/interface.go index f24dcd3601..af0c373fbe 100644 --- a/core/vm/interface.go +++ b/core/vm/interface.go @@ -26,21 +26,21 @@ import ( "github.com/ethereum/go-ethereum/core/types" ) -type AccountExtraDataStateReader interface { +type AccountExtraDataStateGetter interface { // Return nil for public contract - ReadPrivacyMetadata(addr common.Address) (*state.PrivacyMetadata, error) - ReadManagedParties(addr common.Address) ([]string, error) + GetPrivacyMetadata(addr common.Address) (*state.PrivacyMetadata, error) + GetManagedParties(addr common.Address) ([]string, error) } -type AccountExtraDataStateWriter interface { - WritePrivacyMetadata(addr common.Address, pm *state.PrivacyMetadata) - WriteManagedParties(addr common.Address, managedParties []string) +type AccountExtraDataStateSetter interface { + SetPrivacyMetadata(addr common.Address, pm *state.PrivacyMetadata) + SetManagedParties(addr common.Address, managedParties []string) } // Quorum uses a cut-down StateDB, MinimalApiState. We leave the methods in StateDB commented out so they'll produce a // conflict when upstream changes. type MinimalApiState interface { - AccountExtraDataStateReader + AccountExtraDataStateGetter GetBalance(addr common.Address) *big.Int SetBalance(addr common.Address, balance *big.Int) @@ -65,7 +65,7 @@ type MinimalApiState interface { // StateDB is an EVM database for full state querying. type StateDB interface { MinimalApiState - AccountExtraDataStateWriter + AccountExtraDataStateSetter CreateAccount(common.Address) diff --git a/core/vm/mock_interface.go b/core/vm/mock_interface.go index b8d59c32cc..5060315167 100644 --- a/core/vm/mock_interface.go +++ b/core/vm/mock_interface.go @@ -14,104 +14,104 @@ import ( gomock "github.com/golang/mock/gomock" ) -// MockAccountExtraDataStateReader is a mock of AccountExtraDataStateReader interface. -type MockAccountExtraDataStateReader struct { +// MockAccountExtraDataStateGetter is a mock of AccountExtraDataStateGetter interface. +type MockAccountExtraDataStateGetter struct { ctrl *gomock.Controller - recorder *MockAccountExtraDataStateReaderMockRecorder + recorder *MockAccountExtraDataStateGetterMockRecorder } -// MockAccountExtraDataStateReaderMockRecorder is the mock recorder for MockAccountExtraDataStateReader. -type MockAccountExtraDataStateReaderMockRecorder struct { - mock *MockAccountExtraDataStateReader +// MockAccountExtraDataStateGetterMockRecorder is the mock recorder for MockAccountExtraDataStateGetter. +type MockAccountExtraDataStateGetterMockRecorder struct { + mock *MockAccountExtraDataStateGetter } -// NewMockAccountExtraDataStateReader creates a new mock instance. -func NewMockAccountExtraDataStateReader(ctrl *gomock.Controller) *MockAccountExtraDataStateReader { - mock := &MockAccountExtraDataStateReader{ctrl: ctrl} - mock.recorder = &MockAccountExtraDataStateReaderMockRecorder{mock} +// NewMockAccountExtraDataStateGetter creates a new mock instance. +func NewMockAccountExtraDataStateGetter(ctrl *gomock.Controller) *MockAccountExtraDataStateGetter { + mock := &MockAccountExtraDataStateGetter{ctrl: ctrl} + mock.recorder = &MockAccountExtraDataStateGetterMockRecorder{mock} return mock } // EXPECT returns an object that allows the caller to indicate expected use. -func (m *MockAccountExtraDataStateReader) EXPECT() *MockAccountExtraDataStateReaderMockRecorder { +func (m *MockAccountExtraDataStateGetter) EXPECT() *MockAccountExtraDataStateGetterMockRecorder { return m.recorder } -// ReadPrivacyMetadata mocks base method. -func (m *MockAccountExtraDataStateReader) ReadPrivacyMetadata(addr common.Address) (*state.PrivacyMetadata, error) { +// GetPrivacyMetadata mocks base method. +func (m *MockAccountExtraDataStateGetter) GetPrivacyMetadata(addr common.Address) (*state.PrivacyMetadata, error) { m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "ReadPrivacyMetadata", addr) + ret := m.ctrl.Call(m, "GetPrivacyMetadata", addr) ret0, _ := ret[0].(*state.PrivacyMetadata) ret1, _ := ret[1].(error) return ret0, ret1 } -// ReadPrivacyMetadata indicates an expected call of ReadPrivacyMetadata. -func (mr *MockAccountExtraDataStateReaderMockRecorder) ReadPrivacyMetadata(addr interface{}) *gomock.Call { +// GetPrivacyMetadata indicates an expected call of GetPrivacyMetadata. +func (mr *MockAccountExtraDataStateGetterMockRecorder) GetPrivacyMetadata(addr interface{}) *gomock.Call { mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ReadPrivacyMetadata", reflect.TypeOf((*MockAccountExtraDataStateReader)(nil).ReadPrivacyMetadata), addr) + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetPrivacyMetadata", reflect.TypeOf((*MockAccountExtraDataStateGetter)(nil).GetPrivacyMetadata), addr) } -// ReadManagedParties mocks base method. -func (m *MockAccountExtraDataStateReader) ReadManagedParties(addr common.Address) ([]string, error) { +// GetManagedParties mocks base method. +func (m *MockAccountExtraDataStateGetter) GetManagedParties(addr common.Address) ([]string, error) { m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "ReadManagedParties", addr) + ret := m.ctrl.Call(m, "GetManagedParties", addr) ret0, _ := ret[0].([]string) ret1, _ := ret[1].(error) return ret0, ret1 } -// ReadManagedParties indicates an expected call of ReadManagedParties. -func (mr *MockAccountExtraDataStateReaderMockRecorder) ReadManagedParties(addr interface{}) *gomock.Call { +// GetManagedParties indicates an expected call of GetManagedParties. +func (mr *MockAccountExtraDataStateGetterMockRecorder) GetManagedParties(addr interface{}) *gomock.Call { mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ReadManagedParties", reflect.TypeOf((*MockAccountExtraDataStateReader)(nil).ReadManagedParties), addr) + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetManagedParties", reflect.TypeOf((*MockAccountExtraDataStateGetter)(nil).GetManagedParties), addr) } -// MockAccountExtraDataStateWriter is a mock of AccountExtraDataStateWriter interface. -type MockAccountExtraDataStateWriter struct { +// MockAccountExtraDataStateSetter is a mock of AccountExtraDataStateSetter interface. +type MockAccountExtraDataStateSetter struct { ctrl *gomock.Controller - recorder *MockAccountExtraDataStateWriterMockRecorder + recorder *MockAccountExtraDataStateSetterMockRecorder } -// MockAccountExtraDataStateWriterMockRecorder is the mock recorder for MockAccountExtraDataStateWriter. -type MockAccountExtraDataStateWriterMockRecorder struct { - mock *MockAccountExtraDataStateWriter +// MockAccountExtraDataStateSetterMockRecorder is the mock recorder for MockAccountExtraDataStateSetter. +type MockAccountExtraDataStateSetterMockRecorder struct { + mock *MockAccountExtraDataStateSetter } -// NewMockAccountExtraDataStateWriter creates a new mock instance. -func NewMockAccountExtraDataStateWriter(ctrl *gomock.Controller) *MockAccountExtraDataStateWriter { - mock := &MockAccountExtraDataStateWriter{ctrl: ctrl} - mock.recorder = &MockAccountExtraDataStateWriterMockRecorder{mock} +// NewMockAccountExtraDataStateSetter creates a new mock instance. +func NewMockAccountExtraDataStateSetter(ctrl *gomock.Controller) *MockAccountExtraDataStateSetter { + mock := &MockAccountExtraDataStateSetter{ctrl: ctrl} + mock.recorder = &MockAccountExtraDataStateSetterMockRecorder{mock} return mock } // EXPECT returns an object that allows the caller to indicate expected use. -func (m *MockAccountExtraDataStateWriter) EXPECT() *MockAccountExtraDataStateWriterMockRecorder { +func (m *MockAccountExtraDataStateSetter) EXPECT() *MockAccountExtraDataStateSetterMockRecorder { return m.recorder } -// WritePrivacyMetadata mocks base method. -func (m *MockAccountExtraDataStateWriter) WritePrivacyMetadata(addr common.Address, pm *state.PrivacyMetadata) { +// SetPrivacyMetadata mocks base method. +func (m *MockAccountExtraDataStateSetter) SetPrivacyMetadata(addr common.Address, pm *state.PrivacyMetadata) { m.ctrl.T.Helper() - m.ctrl.Call(m, "WritePrivacyMetadata", addr, pm) + m.ctrl.Call(m, "SetPrivacyMetadata", addr, pm) } -// WritePrivacyMetadata indicates an expected call of WritePrivacyMetadata. -func (mr *MockAccountExtraDataStateWriterMockRecorder) WritePrivacyMetadata(addr, pm interface{}) *gomock.Call { +// SetPrivacyMetadata indicates an expected call of SetPrivacyMetadata. +func (mr *MockAccountExtraDataStateSetterMockRecorder) SetPrivacyMetadata(addr, pm interface{}) *gomock.Call { mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "WritePrivacyMetadata", reflect.TypeOf((*MockAccountExtraDataStateWriter)(nil).WritePrivacyMetadata), addr, pm) + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "SetPrivacyMetadata", reflect.TypeOf((*MockAccountExtraDataStateSetter)(nil).SetPrivacyMetadata), addr, pm) } -// WriteManagedParties mocks base method. -func (m *MockAccountExtraDataStateWriter) WriteManagedParties(addr common.Address, managedParties []string) { +// SetManagedParties mocks base method. +func (m *MockAccountExtraDataStateSetter) SetManagedParties(addr common.Address, managedParties []string) { m.ctrl.T.Helper() - m.ctrl.Call(m, "WriteManagedParties", addr, managedParties) + m.ctrl.Call(m, "SetManagedParties", addr, managedParties) } -// WriteManagedParties indicates an expected call of WriteManagedParties. -func (mr *MockAccountExtraDataStateWriterMockRecorder) WriteManagedParties(addr, managedParties interface{}) *gomock.Call { +// SetManagedParties indicates an expected call of SetManagedParties. +func (mr *MockAccountExtraDataStateSetterMockRecorder) SetManagedParties(addr, managedParties interface{}) *gomock.Call { mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "WriteManagedParties", reflect.TypeOf((*MockAccountExtraDataStateWriter)(nil).WriteManagedParties), addr, managedParties) + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "SetManagedParties", reflect.TypeOf((*MockAccountExtraDataStateSetter)(nil).SetManagedParties), addr, managedParties) } // MockMinimalApiState is a mock of MinimalApiState interface. @@ -137,34 +137,34 @@ func (m *MockMinimalApiState) EXPECT() *MockMinimalApiStateMockRecorder { return m.recorder } -// ReadPrivacyMetadata mocks base method. -func (m *MockMinimalApiState) ReadPrivacyMetadata(addr common.Address) (*state.PrivacyMetadata, error) { +// GetPrivacyMetadata mocks base method. +func (m *MockMinimalApiState) GetPrivacyMetadata(addr common.Address) (*state.PrivacyMetadata, error) { m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "ReadPrivacyMetadata", addr) + ret := m.ctrl.Call(m, "GetPrivacyMetadata", addr) ret0, _ := ret[0].(*state.PrivacyMetadata) ret1, _ := ret[1].(error) return ret0, ret1 } -// ReadPrivacyMetadata indicates an expected call of ReadPrivacyMetadata. -func (mr *MockMinimalApiStateMockRecorder) ReadPrivacyMetadata(addr interface{}) *gomock.Call { +// GetPrivacyMetadata indicates an expected call of GetPrivacyMetadata. +func (mr *MockMinimalApiStateMockRecorder) GetPrivacyMetadata(addr interface{}) *gomock.Call { mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ReadPrivacyMetadata", reflect.TypeOf((*MockMinimalApiState)(nil).ReadPrivacyMetadata), addr) + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetPrivacyMetadata", reflect.TypeOf((*MockMinimalApiState)(nil).GetPrivacyMetadata), addr) } -// ReadManagedParties mocks base method. -func (m *MockMinimalApiState) ReadManagedParties(addr common.Address) ([]string, error) { +// GetManagedParties mocks base method. +func (m *MockMinimalApiState) GetManagedParties(addr common.Address) ([]string, error) { m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "ReadManagedParties", addr) + ret := m.ctrl.Call(m, "GetManagedParties", addr) ret0, _ := ret[0].([]string) ret1, _ := ret[1].(error) return ret0, ret1 } -// ReadManagedParties indicates an expected call of ReadManagedParties. -func (mr *MockMinimalApiStateMockRecorder) ReadManagedParties(addr interface{}) *gomock.Call { +// GetManagedParties indicates an expected call of GetManagedParties. +func (mr *MockMinimalApiStateMockRecorder) GetManagedParties(addr interface{}) *gomock.Call { mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ReadManagedParties", reflect.TypeOf((*MockMinimalApiState)(nil).ReadManagedParties), addr) + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetManagedParties", reflect.TypeOf((*MockMinimalApiState)(nil).GetManagedParties), addr) } // GetBalance mocks base method. @@ -393,34 +393,34 @@ func (m *MockStateDB) EXPECT() *MockStateDBMockRecorder { return m.recorder } -// ReadPrivacyMetadata mocks base method. -func (m *MockStateDB) ReadPrivacyMetadata(addr common.Address) (*state.PrivacyMetadata, error) { +// GetPrivacyMetadata mocks base method. +func (m *MockStateDB) GetPrivacyMetadata(addr common.Address) (*state.PrivacyMetadata, error) { m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "ReadPrivacyMetadata", addr) + ret := m.ctrl.Call(m, "GetPrivacyMetadata", addr) ret0, _ := ret[0].(*state.PrivacyMetadata) ret1, _ := ret[1].(error) return ret0, ret1 } -// ReadPrivacyMetadata indicates an expected call of ReadPrivacyMetadata. -func (mr *MockStateDBMockRecorder) ReadPrivacyMetadata(addr interface{}) *gomock.Call { +// GetPrivacyMetadata indicates an expected call of GetPrivacyMetadata. +func (mr *MockStateDBMockRecorder) GetPrivacyMetadata(addr interface{}) *gomock.Call { mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ReadPrivacyMetadata", reflect.TypeOf((*MockStateDB)(nil).ReadPrivacyMetadata), addr) + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetPrivacyMetadata", reflect.TypeOf((*MockStateDB)(nil).GetPrivacyMetadata), addr) } -// ReadManagedParties mocks base method. -func (m *MockStateDB) ReadManagedParties(addr common.Address) ([]string, error) { +// GetManagedParties mocks base method. +func (m *MockStateDB) GetManagedParties(addr common.Address) ([]string, error) { m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "ReadManagedParties", addr) + ret := m.ctrl.Call(m, "GetManagedParties", addr) ret0, _ := ret[0].([]string) ret1, _ := ret[1].(error) return ret0, ret1 } -// ReadManagedParties indicates an expected call of ReadManagedParties. -func (mr *MockStateDBMockRecorder) ReadManagedParties(addr interface{}) *gomock.Call { +// GetManagedParties indicates an expected call of GetManagedParties. +func (mr *MockStateDBMockRecorder) GetManagedParties(addr interface{}) *gomock.Call { mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ReadManagedParties", reflect.TypeOf((*MockStateDB)(nil).ReadManagedParties), addr) + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetManagedParties", reflect.TypeOf((*MockStateDB)(nil).GetManagedParties), addr) } // GetBalance mocks base method. @@ -626,28 +626,28 @@ func (mr *MockStateDBMockRecorder) SetStorage(addr, storage interface{}) *gomock return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "SetStorage", reflect.TypeOf((*MockStateDB)(nil).SetStorage), addr, storage) } -// WritePrivacyMetadata mocks base method. -func (m *MockStateDB) WritePrivacyMetadata(addr common.Address, pm *state.PrivacyMetadata) { +// SetPrivacyMetadata mocks base method. +func (m *MockStateDB) SetPrivacyMetadata(addr common.Address, pm *state.PrivacyMetadata) { m.ctrl.T.Helper() - m.ctrl.Call(m, "WritePrivacyMetadata", addr, pm) + m.ctrl.Call(m, "SetPrivacyMetadata", addr, pm) } -// WritePrivacyMetadata indicates an expected call of WritePrivacyMetadata. -func (mr *MockStateDBMockRecorder) WritePrivacyMetadata(addr, pm interface{}) *gomock.Call { +// SetPrivacyMetadata indicates an expected call of SetPrivacyMetadata. +func (mr *MockStateDBMockRecorder) SetPrivacyMetadata(addr, pm interface{}) *gomock.Call { mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "WritePrivacyMetadata", reflect.TypeOf((*MockStateDB)(nil).WritePrivacyMetadata), addr, pm) + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "SetPrivacyMetadata", reflect.TypeOf((*MockStateDB)(nil).SetPrivacyMetadata), addr, pm) } -// WriteManagedParties mocks base method. -func (m *MockStateDB) WriteManagedParties(addr common.Address, managedParties []string) { +// SetManagedParties mocks base method. +func (m *MockStateDB) SetManagedParties(addr common.Address, managedParties []string) { m.ctrl.T.Helper() - m.ctrl.Call(m, "WriteManagedParties", addr, managedParties) + m.ctrl.Call(m, "SetManagedParties", addr, managedParties) } -// WriteManagedParties indicates an expected call of WriteManagedParties. -func (mr *MockStateDBMockRecorder) WriteManagedParties(addr, managedParties interface{}) *gomock.Call { +// SetManagedParties indicates an expected call of SetManagedParties. +func (mr *MockStateDBMockRecorder) SetManagedParties(addr, managedParties interface{}) *gomock.Call { mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "WriteManagedParties", reflect.TypeOf((*MockStateDB)(nil).WriteManagedParties), addr, managedParties) + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "SetManagedParties", reflect.TypeOf((*MockStateDB)(nil).SetManagedParties), addr, managedParties) } // CreateAccount mocks base method. diff --git a/core/vm/runtime/evm_privacy_test.go b/core/vm/runtime/evm_privacy_test.go index 884261ba69..2f54e2b1ef 100644 --- a/core/vm/runtime/evm_privacy_test.go +++ b/core/vm/runtime/evm_privacy_test.go @@ -103,7 +103,7 @@ func TestPrivacyEnhancements_CreateC1(t *testing.T) { var getPrivacyMetadataFunc func(common.Address) (*state.PrivacyMetadata, error) cfg.onAfterEVM = func(evm *vm.EVM) { affectedContracts = evm.AffectedContracts() - getPrivacyMetadataFunc = evm.StateDB.ReadPrivacyMetadata + getPrivacyMetadataFunc = evm.StateDB.GetPrivacyMetadata } stubPrivateTx = newTypicalPrivateTx(cfg) stubPrivateTx.SetTxPrivacyMetadata(&types.PrivacyMetadata{ @@ -173,7 +173,7 @@ func TestPrivacyEnhancements_CreateC1_StandardPrivate(t *testing.T) { var getPrivacyMetadataFunc func(common.Address) (*state.PrivacyMetadata, error) cfg.onAfterEVM = func(evm *vm.EVM) { affectedContracts = evm.AffectedContracts() - getPrivacyMetadataFunc = evm.StateDB.ReadPrivacyMetadata + getPrivacyMetadataFunc = evm.StateDB.GetPrivacyMetadata } stubPrivateTx = newTypicalPrivateTx(cfg) stubPrivateTx.SetTxPrivacyMetadata(&types.PrivacyMetadata{ diff --git a/eth/api_backend.go b/eth/api_backend.go index 94fb139aaf..b51c782677 100644 --- a/eth/api_backend.go +++ b/eth/api_backend.go @@ -372,13 +372,13 @@ func (b *EthAPIBackend) SupportsMultitenancy(rpcCtx context.Context) (*proto.Pre return nil, false } -func (b *EthAPIBackend) AccountExtraDataStateReaderByNumber(ctx context.Context, number rpc.BlockNumber) (vm.AccountExtraDataStateReader, error) { +func (b *EthAPIBackend) AccountExtraDataStateGetterByNumber(ctx context.Context, number rpc.BlockNumber) (vm.AccountExtraDataStateGetter, error) { s, _, err := b.StateAndHeaderByNumber(ctx, number) return s, err } func (b *EthAPIBackend) IsAuthorized(ctx context.Context, authToken *proto.PreAuthenticatedAuthenticationToken, attributes ...*multitenancy.ContractSecurityAttribute) (bool, error) { - auth, err := b.eth.contractAccessDecisionManager.IsAuthorized(ctx, authToken, attributes...) + auth, err := b.eth.contractAccessManager.IsAuthorized(ctx, authToken, attributes...) if err != nil { log.Error("failed to perform authorization check", "err", err, "granted", string(authToken.RawToken), "ask", attributes) return false, err @@ -459,16 +459,16 @@ func (s EthAPIState) GetNonce(addr common.Address) uint64 { return s.state.GetNonce(addr) } -func (s EthAPIState) ReadPrivacyMetadata(addr common.Address) (*state.PrivacyMetadata, error) { +func (s EthAPIState) GetPrivacyMetadata(addr common.Address) (*state.PrivacyMetadata, error) { if s.privateState.Exist(addr) { - return s.privateState.ReadPrivacyMetadata(addr) + return s.privateState.GetPrivacyMetadata(addr) } return nil, fmt.Errorf("%x: %w", addr, common.ErrNotPrivateContract) } -func (s EthAPIState) ReadManagedParties(addr common.Address) ([]string, error) { +func (s EthAPIState) GetManagedParties(addr common.Address) ([]string, error) { if s.privateState.Exist(addr) { - return s.privateState.ReadManagedParties(addr) + return s.privateState.GetManagedParties(addr) } return nil, fmt.Errorf("%x: %w", addr, common.ErrNotPrivateContract) } diff --git a/eth/backend.go b/eth/backend.go index fa29abae3f..2557606416 100644 --- a/eth/backend.go +++ b/eth/backend.go @@ -101,8 +101,8 @@ type Ethereum struct { lock sync.RWMutex // Protects the variadic fields (e.g. gas price and etherbase) // Quorum - Multitenancy - // contractAccessDecisionManager is set after node starts instead in New() - contractAccessDecisionManager multitenancy.ContractAccessDecisionManager + // contractAccessManager is set after node starts instead in New() + contractAccessManager multitenancy.ContractAccessDecisionManager } func (s *Ethereum) AddLesServer(ls LesServer) { @@ -122,7 +122,7 @@ func (s *Ethereum) SetContractBackend(backend bind.ContractBackend) { // // Set the decision manager for multitenancy support func (s *Ethereum) SetContractAccessDecisionManager(dm multitenancy.ContractAccessDecisionManager) { - s.contractAccessDecisionManager = dm + s.contractAccessManager = dm } // New creates a new Ethereum object (including the diff --git a/eth/filters/api.go b/eth/filters/api.go index a92bc3795d..75b8174da3 100644 --- a/eth/filters/api.go +++ b/eth/filters/api.go @@ -597,21 +597,18 @@ func (api *PublicFilterAPI) filterUnAuthorized(ctx context.Context, logs []*type if authToken, ok := api.backend.SupportsMultitenancy(ctx); ok { filteredLogs := make([]*types.Log, 0) for _, l := range logs { - attributes := make([]*multitenancy.ContractSecurityAttribute, 0) - contractAddress := l.Address - extraDataReader, err := api.backend.AccountExtraDataStateReaderByNumber(ctx, rpc.BlockNumber(l.BlockNumber)) + extraDataReader, err := api.backend.AccountExtraDataStateGetterByNumber(ctx, rpc.BlockNumber(l.BlockNumber)) if err != nil { return nil, fmt.Errorf("no account extra data reader at block %v: %w", l.BlockNumber, err) } - managedParties, err := extraDataReader.ReadManagedParties(contractAddress) attrBuilder := multitenancy.NewContractSecurityAttributeBuilder().Read().Private() + managedParties, err := extraDataReader.GetManagedParties(l.Address) if errors.Is(err, common.ErrNotPrivateContract) { attrBuilder.Public() } else if err != nil { - return nil, fmt.Errorf("contract %s not found in the index due to %s", contractAddress.Hex(), err.Error()) + return nil, fmt.Errorf("contract %s not found in the index due to %s", l.Address.Hex(), err.Error()) } - attributes = append(attributes, attrBuilder.Parties(managedParties).Build()) - if ok, _ := api.backend.IsAuthorized(ctx, authToken, attributes...); ok { + if ok, _ := api.backend.IsAuthorized(ctx, authToken, attrBuilder.Parties(managedParties).Build()); ok { filteredLogs = append(filteredLogs, l) } } diff --git a/eth/filters/filter.go b/eth/filters/filter.go index d3cb76755b..c703fd8b9c 100644 --- a/eth/filters/filter.go +++ b/eth/filters/filter.go @@ -34,7 +34,7 @@ import ( ) type Backend interface { - multitenancy.OperationalSupport + multitenancy.AccessDecisionManager ChainDb() ethdb.Database EventMux() *event.TypeMux @@ -51,8 +51,8 @@ type Backend interface { BloomStatus() (uint64, uint64) ServiceFilter(ctx context.Context, session *bloombits.MatcherSession) - // AccountExtraDataStateReaderByNumber returns state reader at a given block height - AccountExtraDataStateReaderByNumber(ctx context.Context, number rpc.BlockNumber) (vm.AccountExtraDataStateReader, error) + // AccountExtraDataStateGetterByNumber returns state getter at a given block height + AccountExtraDataStateGetterByNumber(ctx context.Context, number rpc.BlockNumber) (vm.AccountExtraDataStateGetter, error) } // Filter can be used to retrieve and filter logs. diff --git a/eth/filters/filter_system_test.go b/eth/filters/filter_system_test.go index e91f9d68aa..44bc75ed9e 100644 --- a/eth/filters/filter_system_test.go +++ b/eth/filters/filter_system_test.go @@ -158,7 +158,7 @@ func (b *testBackend) SupportsMultitenancy(rpcCtx context.Context) (*proto.PreAu return nil, false } -func (b *testBackend) AccountExtraDataStateReaderByNumber(context.Context, rpc.BlockNumber) (vm.AccountExtraDataStateReader, error) { +func (b *testBackend) AccountExtraDataStateGetterByNumber(context.Context, rpc.BlockNumber) (vm.AccountExtraDataStateGetter, error) { return nil, nil } diff --git a/extension/api.go b/extension/api.go index e362309dfc..e197f85639 100644 --- a/extension/api.go +++ b/extension/api.go @@ -112,19 +112,15 @@ func (api *PrivateExtensionAPI) doMultiTenantChecks(ctx context.Context, address return errors.New("You must specify 'privateFrom' when running in a multitenant node") } // check whether the user has access to txa.PrivateFrom and the txa.From eth account - attributes := make([]*multitenancy.ContractSecurityAttribute, 0) - attributes = append(attributes, - multitenancy.NewContractSecurityAttributeBuilder().FromEOA(txa.From).Private().Create().PrivateFrom(txa.PrivateFrom).Build(), - multitenancy.NewContractSecurityAttributeBuilder().FromEOA(txa.From).Private().Write().Party(txa.PrivateFrom).Build(), - multitenancy.NewContractSecurityAttributeBuilder().FromEOA(txa.From).Private().Read().Party(txa.PrivateFrom).Build()) + attributes := multitenancy.FullAccessContractSecurityAttributes(txa.From, txa.PrivateFrom) chainAccessor := api.privacyService.stateFetcher.chainAccessor currentBlock := chainAccessor.CurrentBlock().Number().Int64() - extraDataReader, err := apiHelper.AccountExtraDataStateReaderByNumber(ctx, rpc.BlockNumber(currentBlock)) + extraDataReader, err := apiHelper.AccountExtraDataStateGetterByNumber(ctx, rpc.BlockNumber(currentBlock)) if err != nil { return fmt.Errorf("no account extra data reader at block %v: %w", currentBlock, err) } - managedParties, err := extraDataReader.ReadManagedParties(address) + managedParties, err := extraDataReader.GetManagedParties(address) if err != nil { return err } @@ -363,18 +359,16 @@ func (api *PrivateExtensionAPI) GetExtensionStatus(ctx context.Context, extensio apiHelper := api.privacyService.apiBackendHelper if authToken, ok := apiHelper.SupportsMultitenancy(ctx); ok { currentBlock := apiHelper.CurrentBlock().Number().Int64() - extraDataReader, err := apiHelper.AccountExtraDataStateReaderByNumber(ctx, rpc.BlockNumber(currentBlock)) + extraDataReader, err := apiHelper.AccountExtraDataStateGetterByNumber(ctx, rpc.BlockNumber(currentBlock)) if err != nil { return "", fmt.Errorf("no account extra data reader at block %v: %w", currentBlock, err) } - managedParties, err := extraDataReader.ReadManagedParties(extensionContract) + managedParties, err := extraDataReader.GetManagedParties(extensionContract) if err != nil { return "", err } - attributes := []*multitenancy.ContractSecurityAttribute{ - multitenancy.NewContractSecurityAttributeBuilder().Private().Read().Parties(managedParties).Build(), - } - if authorized, _ := apiHelper.IsAuthorized(ctx, authToken, attributes...); !authorized { + if authorized, _ := apiHelper.IsAuthorized(ctx, authToken, + multitenancy.NewContractSecurityAttributeBuilder().Private().Read().Parties(managedParties).Build()); !authorized { return "", multitenancy.ErrNotAuthorized } } diff --git a/extension/privacyExtension/state_set_utilities.go b/extension/privacyExtension/state_set_utilities.go index b187955cfd..1d6143735b 100644 --- a/extension/privacyExtension/state_set_utilities.go +++ b/extension/privacyExtension/state_set_utilities.go @@ -3,14 +3,13 @@ package privacyExtension import ( "math/big" - "github.com/ethereum/go-ethereum/private" - "github.com/ethereum/go-ethereum/private/engine" - "github.com/ethereum/go-ethereum/common" "github.com/ethereum/go-ethereum/core/state" "github.com/ethereum/go-ethereum/core/types" extension "github.com/ethereum/go-ethereum/extension/extensionContracts" "github.com/ethereum/go-ethereum/log" + "github.com/ethereum/go-ethereum/private" + "github.com/ethereum/go-ethereum/private/engine" ) func setState(privateState *state.StateDB, accounts map[string]extension.AccountWithMetadata, privacyMetaData *state.PrivacyMetadata, managedParties []string) bool { @@ -32,10 +31,10 @@ func setState(privateState *state.StateDB, accounts map[string]extension.Account privateState.SetState(contractAddress, keyStore, common.HexToHash(valueStore)) } if privacyMetaData.PrivacyFlag != engine.PrivacyFlagStandardPrivate { - privateState.WritePrivacyMetadata(contractAddress, privacyMetaData) + privateState.SetPrivacyMetadata(contractAddress, privacyMetaData) } if managedParties != nil { - privateState.WriteManagedParties(contractAddress, managedParties) + privateState.SetManagedParties(contractAddress, managedParties) } } return true @@ -43,7 +42,7 @@ func setState(privateState *state.StateDB, accounts map[string]extension.Account // updates the privacy metadata func setPrivacyMetadata(privateState *state.StateDB, address common.Address, hash string) { - privacyMetaData, err := privateState.ReadPrivacyMetadata(address) + privacyMetaData, err := privateState.GetPrivacyMetadata(address) if err != nil || privacyMetaData.PrivacyFlag.IsStandardPrivate() { return } @@ -54,11 +53,11 @@ func setPrivacyMetadata(privateState *state.StateDB, address common.Address, has return } pm := state.NewStatePrivacyMetadata(ptmHash, privacyMetaData.PrivacyFlag) - privateState.WritePrivacyMetadata(address, pm) + privateState.SetPrivacyMetadata(address, pm) } func setManagedParties(ptm private.PrivateTransactionManager, privateState *state.StateDB, address common.Address, hash string) { - existingManagedParties, err := privateState.ReadManagedParties(address) + existingManagedParties, err := privateState.GetManagedParties(address) if err != nil { return } @@ -70,27 +69,8 @@ func setManagedParties(ptm private.PrivateTransactionManager, privateState *stat } _, managedParties, _, _, err := ptm.Receive(ptmHash) - newManagedParties := appendSkipDuplicates(existingManagedParties, managedParties) - privateState.WriteManagedParties(address, newManagedParties) -} - -func appendSkipDuplicates(list1 []string, list2 []string) (result []string) { - result = list1 - for _, val := range list2 { - if !sliceContains(list1, val) { - result = append(result, val) - } - } - return result -} - -func sliceContains(list []string, item string) bool { - for _, val := range list { - if val == item { - return true - } - } - return false + newManagedParties := common.AppendSkipDuplicates(existingManagedParties, managedParties...) + privateState.SetManagedParties(address, newManagedParties) } func logContainsExtensionTopic(receivedLog *types.Log) bool { diff --git a/extension/privacyExtension/state_set_utilities_test.go b/extension/privacyExtension/state_set_utilities_test.go index 8d3dd42ee9..94af7852d9 100644 --- a/extension/privacyExtension/state_set_utilities_test.go +++ b/extension/privacyExtension/state_set_utilities_test.go @@ -125,13 +125,13 @@ func Test_setPrivacyMetadata(t *testing.T) { setPrivacyMetadata(statedb, address, base64.StdEncoding.EncodeToString(arbitraryBytes1)) // we don't save PrivacyMetadata if it's standardprivate - privacyMetaData, err := statedb.ReadPrivacyMetadata(address) + privacyMetaData, err := statedb.GetPrivacyMetadata(address) assert.Error(t, err, common.ErrNoAccountExtraData) privacyMetaData = &state.PrivacyMetadata{CreationTxHash: hash, PrivacyFlag: engine.PrivacyFlagPartyProtection} - statedb.WritePrivacyMetadata(address, privacyMetaData) + statedb.SetPrivacyMetadata(address, privacyMetaData) - privacyMetaData, err = statedb.ReadPrivacyMetadata(address) + privacyMetaData, err = statedb.GetPrivacyMetadata(address) if err != nil { t.Errorf("expected error to be nil, got err %s", err) } @@ -142,7 +142,7 @@ func Test_setPrivacyMetadata(t *testing.T) { newHash := common.BytesToEncryptedPayloadHash(arbitraryBytes2) setPrivacyMetadata(statedb, address, base64.StdEncoding.EncodeToString(arbitraryBytes2)) - privacyMetaData, err = statedb.ReadPrivacyMetadata(address) + privacyMetaData, err = statedb.GetPrivacyMetadata(address) if err != nil { t.Errorf("expected error to be nil, got err %s", err) } diff --git a/extension/state_fetcher.go b/extension/state_fetcher.go index 6a53e3eaed..ab243c918b 100644 --- a/extension/state_fetcher.go +++ b/extension/state_fetcher.go @@ -26,8 +26,8 @@ type ChainAccessor interface { // Only extract required methods from ethService.APIBackend type APIBackendHelper interface { - multitenancy.OperationalSupport - AccountExtraDataStateReaderByNumber(ctx context.Context, number rpc.BlockNumber) (vm.AccountExtraDataStateReader, error) + multitenancy.AccessDecisionManager + AccountExtraDataStateGetterByNumber(ctx context.Context, number rpc.BlockNumber) (vm.AccountExtraDataStateGetter, error) CurrentBlock() *types.Block } @@ -96,7 +96,7 @@ func (fetcher *StateFetcher) GetPrivacyMetaData(blockHash common.Hash, address c return nil, err } - privacyMetaData, err := privateState.ReadPrivacyMetadata(address) + privacyMetaData, err := privateState.GetPrivacyMetadata(address) if err != nil { return nil, err } diff --git a/internal/ethapi/api.go b/internal/ethapi/api.go index 341537f24f..19675fa2a3 100644 --- a/internal/ethapi/api.go +++ b/internal/ethapi/api.go @@ -29,8 +29,6 @@ import ( "sync" "time" - "github.com/jpmorganchase/quorum-security-plugin-sdk-go/proto" - "github.com/davecgh/go-spew/spew" "github.com/ethereum/go-ethereum/accounts" "github.com/ethereum/go-ethereum/accounts/keystore" @@ -55,6 +53,7 @@ import ( "github.com/ethereum/go-ethereum/private/engine" "github.com/ethereum/go-ethereum/rlp" "github.com/ethereum/go-ethereum/rpc" + "github.com/jpmorganchase/quorum-security-plugin-sdk-go/proto" "github.com/tyler-smith/go-bip39" ) @@ -958,11 +957,11 @@ func DoCall(ctx context.Context, b Backend, args CallArgs, blockNrOrHash rpc.Blo readSecAttr = multitenancy.NewContractSecurityAttributeBuilder().FromEOA(addr).ToEOA(*msg.To()).Public().Read().Build() } else { currentBlock := b.CurrentBlock().Number().Int64() - extraDataReader, err := b.AccountExtraDataStateReaderByNumber(ctx, rpc.BlockNumber(currentBlock)) + extraDataReader, err := b.AccountExtraDataStateGetterByNumber(ctx, rpc.BlockNumber(currentBlock)) if err != nil { return false, false, fmt.Errorf("no account extra data reader at block %v: %w", currentBlock, err) } - managedParties, err := extraDataReader.ReadManagedParties(contractAddress) + managedParties, err := extraDataReader.GetManagedParties(contractAddress) isPrivate := true if errors.Is(err, common.ErrNotPrivateContract) { isPrivate = false @@ -972,6 +971,7 @@ func DoCall(ctx context.Context, b Backend, args CallArgs, blockNrOrHash rpc.Blo readSecAttr = multitenancy.NewContractSecurityAttributeBuilder().FromEOA(addr).PrivateIf(isPrivate).PartiesOnlyIf(isPrivate, managedParties).Read().Build() } authorizedRead, _ := b.IsAuthorized(ctx, authToken, readSecAttr) + log.Trace("Authorized Message Call", "read", authorizedRead, "address", contractAddress.Hex(), "securityAttribute", readSecAttr) return authorizedRead, false, nil } enrichedCtx = context.WithValue(enrichedCtx, multitenancy.CtxKeyAuthorizeMessageCallFunc, authorizeMessageCallFunc) @@ -1423,7 +1423,7 @@ func (s *PublicTransactionPoolAPI) GetContractPrivacyMetadata(ctx context.Contex if state == nil || err != nil { return nil, err } - return state.ReadPrivacyMetadata(address) + return state.GetPrivacyMetadata(address) } // /Quorum @@ -1513,14 +1513,14 @@ func (s *PublicTransactionPoolAPI) GetTransactionReceipt(ctx context.Context, ha fields["contractAddress"] = receipt.ContractAddress } if authToken, ok := s.b.SupportsMultitenancy(ctx); ok { - extraDataReader, err := s.b.AccountExtraDataStateReaderByNumber(ctx, rpc.BlockNumber(blockNumber)) + extraDataReader, err := s.b.AccountExtraDataStateGetterByNumber(ctx, rpc.BlockNumber(blockNumber)) if err != nil { return nil, fmt.Errorf("no account extra data reader at block %v: %w", blockNumber, err) } filteredLogs := make([]*types.Log, 0) for _, l := range receipt.Logs { - ok, err := s.hasAccessToContract(ctx, authToken, extraDataReader, l.Address) + ok, err := s.isContractAuthorized(ctx, authToken, extraDataReader, l.Address) if err != nil { return nil, err } @@ -1535,18 +1535,16 @@ func (s *PublicTransactionPoolAPI) GetTransactionReceipt(ctx context.Context, ha return fields, nil } -func (s *PublicTransactionPoolAPI) hasAccessToContract(ctx context.Context, authToken *proto.PreAuthenticatedAuthenticationToken, extraDataReader vm.AccountExtraDataStateReader, addr common.Address) (bool, error) { - attributes := make([]*multitenancy.ContractSecurityAttribute, 0) +func (s *PublicTransactionPoolAPI) isContractAuthorized(ctx context.Context, authToken *proto.PreAuthenticatedAuthenticationToken, extraDataReader vm.AccountExtraDataStateGetter, addr common.Address) (bool, error) { attrBuilder := multitenancy.NewContractSecurityAttributeBuilder().Read().Private() - managedParties, err := extraDataReader.ReadManagedParties(addr) + managedParties, err := extraDataReader.GetManagedParties(addr) if errors.Is(err, common.ErrNotPrivateContract) { attrBuilder.Public() } else if err != nil { return false, fmt.Errorf("contract %s not found in the index due to %s", addr.Hex(), err.Error()) } - attributes = append(attributes, attrBuilder.Parties(managedParties).Build()) - ok, _ := s.b.IsAuthorized(ctx, authToken, attributes...) + ok, _ := s.b.IsAuthorized(ctx, authToken, attrBuilder.Parties(managedParties).Build()) return ok, nil } @@ -1769,16 +1767,12 @@ func performMultitenancyChecks(ctx context.Context, authToken *proto.PreAuthenti // user must be entitled for all actions // READ and WRITE actions are taking Parties into consideration so // we need to populate it with privateFrom - if authorized, _ := b.IsAuthorized(ctx, authToken, - multitenancy.NewContractSecurityAttributeBuilder().FromEOA(fromEOA).Private().Create().PrivateFrom(privateArgs.PrivateFrom).Build(), - multitenancy.NewContractSecurityAttributeBuilder().FromEOA(fromEOA).Private().Write().Party(privateArgs.PrivateFrom).Build(), - multitenancy.NewContractSecurityAttributeBuilder().FromEOA(fromEOA).Private().Read().Party(privateArgs.PrivateFrom).Build(), - ); !authorized { + if authorized, _ := b.IsAuthorized(ctx, authToken, multitenancy.FullAccessContractSecurityAttributes(fromEOA, privateArgs.PrivateFrom)...); !authorized { return multitenancy.ErrNotAuthorized } } currentBlock := b.CurrentBlock().Number().Int64() - extraDataReader, err := b.AccountExtraDataStateReaderByNumber(ctx, rpc.BlockNumber(currentBlock)) + extraDataReader, err := b.AccountExtraDataStateGetterByNumber(ctx, rpc.BlockNumber(currentBlock)) if err != nil { return fmt.Errorf("no account extra data reader at block %v: %w", currentBlock, err) } @@ -1786,11 +1780,12 @@ func performMultitenancyChecks(ctx context.Context, authToken *proto.PreAuthenti createContractSA := multitenancy.NewContractSecurityAttributeBuilder(). FromEOA(fromEOA).PrivateIf(tx.IsPrivate()).Create().PrivateFromOnlyIf(tx.IsPrivate(), privateArgs.PrivateFrom).Build() authorizedCreate, _ := b.IsAuthorized(ctx, authToken, createContractSA) + log.Debug("Authorized Contract Creation", "create", authorizedCreate, "securityAttribute", createContractSA) var authorizeCreateFunc multitenancy.AuthorizeCreateFunc = func() bool { return authorizedCreate } var authorizeMessageCallFunc multitenancy.AuthorizeMessageCallFunc = func(contractAddress common.Address) (bool, bool, error) { - managedParties, err := extraDataReader.ReadManagedParties(contractAddress) + managedParties, err := extraDataReader.GetManagedParties(contractAddress) isPrivate := true if errors.Is(err, common.ErrNotPrivateContract) { isPrivate = false @@ -1799,9 +1794,10 @@ func performMultitenancyChecks(ctx context.Context, authToken *proto.PreAuthenti } readSecAttr := multitenancy.NewContractSecurityAttributeBuilder().FromEOA(fromEOA).PrivateIf(isPrivate).PartiesOnlyIf(isPrivate, managedParties).Read().Build() authorizedRead, _ := b.IsAuthorized(ctx, authToken, readSecAttr) + log.Trace("Authorized Message Call", "read", authorizedRead, "address", contractAddress.Hex(), "securityAttribute", readSecAttr) writeSecAttr := multitenancy.NewContractSecurityAttributeBuilder().FromEOA(fromEOA).PrivateIf(isPrivate).PartiesOnlyIf(isPrivate, managedParties).Write().Build() authorizedWrite, _ := b.IsAuthorized(ctx, authToken, writeSecAttr) - log.Trace("Authorized Message Call", "read", authorizedRead, "write", authorizedWrite, "address", contractAddress.Hex()) + log.Trace("Authorized Message Call", "write", authorizedWrite, "address", contractAddress.Hex(), "securityAttribute", writeSecAttr) return authorizedRead, authorizedWrite, nil } enrichedCtx := ctx @@ -2601,12 +2597,12 @@ func simulateExecutionForPE(ctx context.Context, b Backend, from common.Address, privacyFlag := privateTxArgs.PrivacyFlag log.Trace("after simulation run", "numberOfAffectedContracts", len(addresses), "privacyFlag", privacyFlag) for _, addr := range addresses { - // ReadPrivacyMetadata is invoked directly on the privateState (as the tx is private) and it returns: + // GetPrivacyMetadata is invoked directly on the privateState (as the tx is private) and it returns: // 1. public contacts: privacyMetadata = nil, err = nil // 2. private contracts of type: // 2.1. StandardPrivate: privacyMetadata = nil, err = "The provided contract does not have privacy metadata" // 2.2. PartyProtection/PSV: privacyMetadata = , err = nil - privacyMetadata, err := evm.StateDB.ReadPrivacyMetadata(addr) + privacyMetadata, err := evm.StateDB.GetPrivacyMetadata(addr) log.Debug("Found affected contract", "address", addr.Hex(), "privacyMetadata", privacyMetadata) //privacyMetadata not found=non-party, or another db error if err != nil && privacyFlag.IsNotStandardPrivate() { diff --git a/internal/ethapi/api_test.go b/internal/ethapi/api_test.go index 06eef1ea21..9dcc84f8c0 100644 --- a/internal/ethapi/api_test.go +++ b/internal/ethapi/api_test.go @@ -199,7 +199,7 @@ func TestSimulateExecution_whenPartyProtectionMessageCall(t *testing.T) { privateTxArgs.PrivacyFlag = engine.PrivacyFlagPartyProtection privateStateDB.SetCode(arbitrarySimpleStorageContractAddress, hexutil.MustDecode("0x608060405234801561001057600080fd5b506040516020806101618339810180604052602081101561003057600080fd5b81019080805190602001909291905050508060008190555050610109806100586000396000f3fe6080604052600436106049576000357c0100000000000000000000000000000000000000000000000000000000900463ffffffff16806360fe47b114604e5780636d4ce63c146099575b600080fd5b348015605957600080fd5b50608360048036036020811015606e57600080fd5b810190808035906020019092919050505060c1565b6040518082815260200191505060405180910390f35b34801560a457600080fd5b5060ab60d4565b6040518082815260200191505060405180910390f35b6000816000819055506000549050919050565b6000805490509056fea165627a7a723058203624ca2e3479d3fa5a12d97cf3dae0d9a6de3a3b8a53c8605b9cd398d9766b9f00290000000000000000000000000000000000000000000000000000000000000001")) - privateStateDB.WritePrivacyMetadata(arbitrarySimpleStorageContractAddress, &state.PrivacyMetadata{ + privateStateDB.SetPrivacyMetadata(arbitrarySimpleStorageContractAddress, &state.PrivacyMetadata{ PrivacyFlag: privateTxArgs.PrivacyFlag, CreationTxHash: arbitrarySimpleStorageContractEncryptedPayloadHash, }) @@ -241,7 +241,7 @@ func TestSimulateExecution_whenStateValidationMessageCall(t *testing.T) { privateTxArgs.PrivacyFlag = engine.PrivacyFlagStateValidation privateStateDB.SetCode(arbitrarySimpleStorageContractAddress, hexutil.MustDecode("0x608060405234801561001057600080fd5b506040516020806101618339810180604052602081101561003057600080fd5b81019080805190602001909291905050508060008190555050610109806100586000396000f3fe6080604052600436106049576000357c0100000000000000000000000000000000000000000000000000000000900463ffffffff16806360fe47b114604e5780636d4ce63c146099575b600080fd5b348015605957600080fd5b50608360048036036020811015606e57600080fd5b810190808035906020019092919050505060c1565b6040518082815260200191505060405180910390f35b34801560a457600080fd5b5060ab60d4565b6040518082815260200191505060405180910390f35b6000816000819055506000549050919050565b6000805490509056fea165627a7a723058203624ca2e3479d3fa5a12d97cf3dae0d9a6de3a3b8a53c8605b9cd398d9766b9f00290000000000000000000000000000000000000000000000000000000000000001")) - privateStateDB.WritePrivacyMetadata(arbitrarySimpleStorageContractAddress, &state.PrivacyMetadata{ + privateStateDB.SetPrivacyMetadata(arbitrarySimpleStorageContractAddress, &state.PrivacyMetadata{ PrivacyFlag: privateTxArgs.PrivacyFlag, CreationTxHash: arbitrarySimpleStorageContractEncryptedPayloadHash, }) @@ -282,7 +282,7 @@ func TestSimulateExecution_StandardPrivateFlagCallingPartyProtectionContract_Err privateTxArgs.PrivacyFlag = engine.PrivacyFlagStandardPrivate privateStateDB.SetCode(arbitrarySimpleStorageContractAddress, hexutil.MustDecode("0x608060405234801561001057600080fd5b506040516020806101618339810180604052602081101561003057600080fd5b81019080805190602001909291905050508060008190555050610109806100586000396000f3fe6080604052600436106049576000357c0100000000000000000000000000000000000000000000000000000000900463ffffffff16806360fe47b114604e5780636d4ce63c146099575b600080fd5b348015605957600080fd5b50608360048036036020811015606e57600080fd5b810190808035906020019092919050505060c1565b6040518082815260200191505060405180910390f35b34801560a457600080fd5b5060ab60d4565b6040518082815260200191505060405180910390f35b6000816000819055506000549050919050565b6000805490509056fea165627a7a723058203624ca2e3479d3fa5a12d97cf3dae0d9a6de3a3b8a53c8605b9cd398d9766b9f00290000000000000000000000000000000000000000000000000000000000000001")) - privateStateDB.WritePrivacyMetadata(arbitrarySimpleStorageContractAddress, &state.PrivacyMetadata{ + privateStateDB.SetPrivacyMetadata(arbitrarySimpleStorageContractAddress, &state.PrivacyMetadata{ PrivacyFlag: engine.PrivacyFlagPartyProtection, CreationTxHash: arbitrarySimpleStorageContractEncryptedPayloadHash, }) @@ -300,7 +300,7 @@ func TestSimulateExecution_StandardPrivateFlagCallingStateValidationContract_Err privateTxArgs.PrivacyFlag = engine.PrivacyFlagStandardPrivate privateStateDB.SetCode(arbitrarySimpleStorageContractAddress, hexutil.MustDecode("0x608060405234801561001057600080fd5b506040516020806101618339810180604052602081101561003057600080fd5b81019080805190602001909291905050508060008190555050610109806100586000396000f3fe6080604052600436106049576000357c0100000000000000000000000000000000000000000000000000000000900463ffffffff16806360fe47b114604e5780636d4ce63c146099575b600080fd5b348015605957600080fd5b50608360048036036020811015606e57600080fd5b810190808035906020019092919050505060c1565b6040518082815260200191505060405180910390f35b34801560a457600080fd5b5060ab60d4565b6040518082815260200191505060405180910390f35b6000816000819055506000549050919050565b6000805490509056fea165627a7a723058203624ca2e3479d3fa5a12d97cf3dae0d9a6de3a3b8a53c8605b9cd398d9766b9f00290000000000000000000000000000000000000000000000000000000000000001")) - privateStateDB.WritePrivacyMetadata(arbitrarySimpleStorageContractAddress, &state.PrivacyMetadata{ + privateStateDB.SetPrivacyMetadata(arbitrarySimpleStorageContractAddress, &state.PrivacyMetadata{ PrivacyFlag: engine.PrivacyFlagStateValidation, CreationTxHash: arbitrarySimpleStorageContractEncryptedPayloadHash, }) @@ -320,7 +320,7 @@ func TestSimulateExecution_PartyProtectionFlagCallingStateValidationContract_Err privateTxArgs.PrivacyFlag = engine.PrivacyFlagPartyProtection privateStateDB.SetCode(arbitrarySimpleStorageContractAddress, hexutil.MustDecode("0x608060405234801561001057600080fd5b506040516020806101618339810180604052602081101561003057600080fd5b81019080805190602001909291905050508060008190555050610109806100586000396000f3fe6080604052600436106049576000357c0100000000000000000000000000000000000000000000000000000000900463ffffffff16806360fe47b114604e5780636d4ce63c146099575b600080fd5b348015605957600080fd5b50608360048036036020811015606e57600080fd5b810190808035906020019092919050505060c1565b6040518082815260200191505060405180910390f35b34801560a457600080fd5b5060ab60d4565b6040518082815260200191505060405180910390f35b6000816000819055506000549050919050565b6000805490509056fea165627a7a723058203624ca2e3479d3fa5a12d97cf3dae0d9a6de3a3b8a53c8605b9cd398d9766b9f00290000000000000000000000000000000000000000000000000000000000000001")) - privateStateDB.WritePrivacyMetadata(arbitrarySimpleStorageContractAddress, &state.PrivacyMetadata{ + privateStateDB.SetPrivacyMetadata(arbitrarySimpleStorageContractAddress, &state.PrivacyMetadata{ PrivacyFlag: engine.PrivacyFlagStateValidation, CreationTxHash: arbitrarySimpleStorageContractEncryptedPayloadHash, }) @@ -340,7 +340,7 @@ func TestSimulateExecution_StateValidationFlagCallingPartyProtectionContract_Err privateTxArgs.PrivacyFlag = engine.PrivacyFlagStateValidation privateStateDB.SetCode(arbitrarySimpleStorageContractAddress, hexutil.MustDecode("0x608060405234801561001057600080fd5b506040516020806101618339810180604052602081101561003057600080fd5b81019080805190602001909291905050508060008190555050610109806100586000396000f3fe6080604052600436106049576000357c0100000000000000000000000000000000000000000000000000000000900463ffffffff16806360fe47b114604e5780636d4ce63c146099575b600080fd5b348015605957600080fd5b50608360048036036020811015606e57600080fd5b810190808035906020019092919050505060c1565b6040518082815260200191505060405180910390f35b34801560a457600080fd5b5060ab60d4565b6040518082815260200191505060405180910390f35b6000816000819055506000549050919050565b6000805490509056fea165627a7a723058203624ca2e3479d3fa5a12d97cf3dae0d9a6de3a3b8a53c8605b9cd398d9766b9f00290000000000000000000000000000000000000000000000000000000000000001")) - privateStateDB.WritePrivacyMetadata(arbitrarySimpleStorageContractAddress, &state.PrivacyMetadata{ + privateStateDB.SetPrivacyMetadata(arbitrarySimpleStorageContractAddress, &state.PrivacyMetadata{ PrivacyFlag: engine.PrivacyFlagPartyProtection, CreationTxHash: arbitrarySimpleStorageContractEncryptedPayloadHash, }) @@ -468,15 +468,15 @@ func copyTransaction(tx *types.Transaction) *types.Transaction { type StubBackend struct { getEVMCalled bool - mockAccountExtraDataStateReader *vm.MockAccountExtraDataStateReader + mockAccountExtraDataStateGetter *vm.MockAccountExtraDataStateGetter } func (sb *StubBackend) SupportsMultitenancy(rpcCtx context.Context) (*proto.PreAuthenticatedAuthenticationToken, bool) { panic("implement me") } -func (sb *StubBackend) AccountExtraDataStateReaderByNumber(context.Context, rpc.BlockNumber) (vm.AccountExtraDataStateReader, error) { - return sb.mockAccountExtraDataStateReader, nil +func (sb *StubBackend) AccountExtraDataStateGetterByNumber(context.Context, rpc.BlockNumber) (vm.AccountExtraDataStateGetter, error) { + return sb.mockAccountExtraDataStateGetter, nil } func (sb *StubBackend) IsAuthorized(ctx context.Context, authToken *proto.PreAuthenticatedAuthenticationToken, attributes ...*multitenancy.ContractSecurityAttribute) (bool, error) { @@ -680,11 +680,11 @@ func (StubMinimalApiState) SetCode(common.Address, []byte) { panic("implement me") } -func (StubMinimalApiState) ReadPrivacyMetadata(addr common.Address) (*state.PrivacyMetadata, error) { +func (StubMinimalApiState) GetPrivacyMetadata(addr common.Address) (*state.PrivacyMetadata, error) { panic("implement me") } -func (StubMinimalApiState) ReadManagedParties(addr common.Address) ([]string, error) { +func (StubMinimalApiState) GetManagedParties(addr common.Address) ([]string, error) { panic("implement me") } diff --git a/internal/ethapi/backend.go b/internal/ethapi/backend.go index 8650e274c6..6096ebd391 100644 --- a/internal/ethapi/backend.go +++ b/internal/ethapi/backend.go @@ -39,7 +39,7 @@ import ( // Backend interface provides the common API services (that are provided by // both full and light clients) with access to necessary functions. type Backend interface { - multitenancy.OperationalSupport + multitenancy.AccessDecisionManager // General Ethereum API Downloader() *downloader.Downloader ProtocolVersion() int @@ -88,8 +88,8 @@ type Backend interface { ChainConfig() *params.ChainConfig CurrentBlock() *types.Block - // AccountExtraDataStateReaderByNumber returns state reader at a given block - AccountExtraDataStateReaderByNumber(ctx context.Context, number rpc.BlockNumber) (vm.AccountExtraDataStateReader, error) + // AccountExtraDataStateGetterByNumber returns state getter at a given block height + AccountExtraDataStateGetterByNumber(ctx context.Context, number rpc.BlockNumber) (vm.AccountExtraDataStateGetter, error) } func GetAPIs(apiBackend Backend) []rpc.API { diff --git a/les/api_backend.go b/les/api_backend.go index 91dd80efe7..a20812ec2c 100644 --- a/les/api_backend.go +++ b/les/api_backend.go @@ -291,7 +291,7 @@ func (b *LesApiBackend) SupportsMultitenancy(rpcCtx context.Context) (*proto.Pre return nil, false } -func (b *LesApiBackend) AccountExtraDataStateReaderByNumber(ctx context.Context, number rpc.BlockNumber) (vm.AccountExtraDataStateReader, error) { +func (b *LesApiBackend) AccountExtraDataStateGetterByNumber(ctx context.Context, number rpc.BlockNumber) (vm.AccountExtraDataStateGetter, error) { s, _, err := b.StateAndHeaderByNumber(ctx, number) return s, err } diff --git a/light/trie.go b/light/trie.go index 58d26e7d45..3a5e6e1b0a 100644 --- a/light/trie.go +++ b/light/trie.go @@ -98,7 +98,7 @@ func newAccountExtraDataLinkerStub() rawdb.AccountExtraDataLinker { return &stubAccountExtraDataLinker{} } -func (pml *stubAccountExtraDataLinker) Find(_ common.Hash) common.Hash { +func (pml *stubAccountExtraDataLinker) GetAccountExtraDataRoot(_ common.Hash) common.Hash { return common.Hash{} } diff --git a/multitenancy/types.go b/multitenancy/types.go index 0b57189a69..a3e5642583 100644 --- a/multitenancy/types.go +++ b/multitenancy/types.go @@ -39,7 +39,8 @@ type ContextAware interface { SupportsMultitenancy(ctx context.Context) (*proto.PreAuthenticatedAuthenticationToken, bool) } -type OperationalSupport interface { +// AccessDecisionManager specifies APIs to be implemented to provide multitenancy capability +type AccessDecisionManager interface { ContextAware ContractAccessDecisionManager } @@ -186,3 +187,14 @@ func (csab *ContractSecurityAttributeBuilder) Party(tmPubKey string) *ContractSe func (csab *ContractSecurityAttributeBuilder) Build() *ContractSecurityAttribute { return &csab.secAttr } + +// FullAccessContractSecurityAttributes returns a list of contract security attributes. +// The attributes are used to verify ownership of a TM key which is going to be used +// to send a private transaction. +func FullAccessContractSecurityAttributes(fromEOA common.Address, privateFrom string) []*ContractSecurityAttribute { + return []*ContractSecurityAttribute{ + NewContractSecurityAttributeBuilder().FromEOA(fromEOA).Private().Create().PrivateFrom(privateFrom).Build(), + NewContractSecurityAttributeBuilder().FromEOA(fromEOA).Private().Write().Party(privateFrom).Build(), + NewContractSecurityAttributeBuilder().FromEOA(fromEOA).Private().Read().Party(privateFrom).Build(), + } +}