From 519d9e320fe9eb95167de9c67af719b492827cbc Mon Sep 17 00:00:00 2001 From: Jonathan Downing Date: Thu, 29 Feb 2024 13:27:22 -0600 Subject: [PATCH] Added Quai ledger scope checks to all EVM state interactions --- common/address.go | 40 ++++++++++++++++++++++++++++---- common/internal_address.go | 5 ++++ common/types.go | 5 ++-- consensus/blake3pow/consensus.go | 22 ++++++++++++++---- consensus/progpow/consensus.go | 22 ++++++++++++++---- core/core.go | 4 ++-- core/evm.go | 6 ++--- core/state/dump.go | 2 +- core/state/statedb.go | 2 +- core/state_transition.go | 15 +++++++----- core/tx_pool.go | 31 ++++++++++++++----------- core/types/transaction_test.go | 6 +++++ core/vm/eips.go | 2 +- core/vm/evm.go | 23 ++++++++++-------- core/vm/gas_table.go | 8 +++---- core/vm/instructions.go | 16 ++++++------- core/vm/logger.go | 2 +- core/vm/operations_acl.go | 6 ++--- core/vm/runtime/runtime.go | 4 ++-- internal/quaiapi/api.go | 21 ++++++++++------- internal/quaiapi/quai_api.go | 8 +++---- quai/api.go | 2 +- 22 files changed, 167 insertions(+), 85 deletions(-) diff --git a/common/address.go b/common/address.go index e2388a4cd6..067561f73b 100644 --- a/common/address.go +++ b/common/address.go @@ -38,23 +38,51 @@ type AddressData interface { setBytes(b []byte) } -var ErrNilInner = errors.New("Address has nil inner") +var ( + ErrNilInner = errors.New("Address has nil inner") + ErrInvalidScope = errors.New("address is not in scope") + ErrQuaiAddress = errors.New("address is in Quai ledger scope and is not in Qi ledger scope") +) func (a Address) InternalAddress() (InternalAddress, error) { if a.inner == nil { return InternalAddress{}, ErrNilInner } internal, ok := a.inner.(*InternalAddress) - if !ok || internal == nil { + if !ok { return InternalAddress{}, ErrInvalidScope } + if internal == nil { + return InternalAddress{}, ErrNilInner + } + return *internal, nil +} + +func (a Address) InternalAndQuaiAddress() (InternalAddress, error) { + if a.inner == nil { + return InternalAddress{}, ErrNilInner + } + if a.IsInQiLedgerScope() { + return InternalAddress{}, MakeErrQiAddress(a.Hex()) + } + internal, ok := a.inner.(*InternalAddress) + if !ok { + return InternalAddress{}, ErrInvalidScope + } + if internal == nil { + return InternalAddress{}, ErrNilInner + } return *internal, nil } func (a Address) IsInQiLedgerScope() bool { - LedgerMask := byte(0b10000000) // The first bit of the second byte is set if the address is in the Qi ledger - return a.Bytes()[1]&LedgerMask == LedgerMask + return a.Bytes()[1] > 127 +} + +func (a Address) IsInQuaiLedgerScope() bool { + // The first bit of the second byte is not set if the address is in the Quai ledger + return a.Bytes()[1] <= 127 } func (a Address) Equal(b Address) bool { @@ -329,3 +357,7 @@ func (a AddressBytes) hex() []byte { hex.Encode(buf[2:], a[:]) return buf[:] } + +func MakeErrQiAddress(addr string) error { + return fmt.Errorf("address %s is in Qi ledger scope and is not in Quai ledger scope", addr) +} diff --git a/common/internal_address.go b/common/internal_address.go index f49395c87b..6e9515a555 100644 --- a/common/internal_address.go +++ b/common/internal_address.go @@ -136,3 +136,8 @@ func (a InternalAddress) Location() *Location { upperNib := (a[0] & 0xF0) >> 4 // Upper 4 bits, shifted right return &Location{upperNib, lowerNib} } + +func (a InternalAddress) IsInQuaiLedgerScope() bool { + // The first bit of the second byte is not set if the address is in the Quai ledger + return a.Bytes()[1] <= 127 +} diff --git a/common/types.go b/common/types.go index 90bf1549d8..6fc69ef25a 100644 --- a/common/types.go +++ b/common/types.go @@ -55,9 +55,8 @@ const ( var ( hashT = reflect.TypeOf(Hash{}) // The zero address (0x0) - ZeroExternal = ExternalAddress{} - Zero = Address{&ZeroExternal} // For utility purposes only. It is out-of-scope for state purposes. - ErrInvalidScope = errors.New("address is not in scope") + ZeroExternal = ExternalAddress{} + Zero = Address{&ZeroExternal} // For utility purposes only. It is out-of-scope for state purposes. ) // Hash represents the 32 byte Keccak256 hash of arbitrary data. diff --git a/consensus/blake3pow/consensus.go b/consensus/blake3pow/consensus.go index 7ffa888390..1092b4aedd 100644 --- a/consensus/blake3pow/consensus.go +++ b/consensus/blake3pow/consensus.go @@ -443,11 +443,16 @@ func (blake3pow *Blake3pow) Finalize(chain consensus.ChainHeaderReader, header * if err != nil { blake3pow.logger.Error("Provided address in genesis block is out of scope") } - state.AddBalance(internal, account.Balance) - state.SetCode(internal, account.Code) - state.SetNonce(internal, account.Nonce) - for key, value := range account.Storage { - state.SetState(internal, key, value) + if addr.IsInQuaiLedgerScope() { + state.AddBalance(internal, account.Balance) + state.SetCode(internal, account.Code) + state.SetNonce(internal, account.Nonce) + for key, value := range account.Storage { + state.SetState(internal, key, value) + } + } else { + blake3pow.logger.WithField("address", addr.String()).Error("Provided address in genesis block alloc is not in the Quai ledger scope") + continue } } } @@ -488,6 +493,13 @@ func accumulateRewards(config *params.ChainConfig, state *state.StateDB, header }).Error("Block has out of scope coinbase, skipping block reward") return } + if !header.Coinbase().IsInQuaiLedgerScope() { + logger.WithFields(log.Fields{ + "Address": header.Coinbase().String(), + "Hash": header.Hash().String(), + }).Debug("Block coinbase is in Qi ledger, skipping Quai block reward") // this log is largely unnecessary + return + } // Accumulate the rewards for the miner and any included uncles reward := new(big.Int).Set(blockReward) diff --git a/consensus/progpow/consensus.go b/consensus/progpow/consensus.go index e6f84f846b..204095ca67 100644 --- a/consensus/progpow/consensus.go +++ b/consensus/progpow/consensus.go @@ -480,11 +480,16 @@ func (progpow *Progpow) Finalize(chain consensus.ChainHeaderReader, header *type if err != nil { progpow.logger.Error("Provided address in genesis block is out of scope") } - state.AddBalance(internal, account.Balance) - state.SetCode(internal, account.Code) - state.SetNonce(internal, account.Nonce) - for key, value := range account.Storage { - state.SetState(internal, key, value) + if addr.IsInQuaiLedgerScope() { + state.AddBalance(internal, account.Balance) + state.SetCode(internal, account.Code) + state.SetNonce(internal, account.Nonce) + for key, value := range account.Storage { + state.SetState(internal, key, value) + } + } else { + progpow.logger.WithField("address", addr.String()).Error("Provided address in genesis block alloc is not in the Quai ledger scope") + continue } } } @@ -522,6 +527,13 @@ func accumulateRewards(config *params.ChainConfig, state *state.StateDB, header logger.WithField("hash", header.Hash().String()).Error("Block has out-of-scope coinbase, skipping block reward") return } + if !header.Coinbase().IsInQuaiLedgerScope() { + logger.WithFields(log.Fields{ + "Address": header.Coinbase().String(), + "Hash": header.Hash().String(), + }).Debug("Block coinbase is in Qi ledger, skipping Quai block reward") // this log is largely unnecessary + return + } // Accumulate the rewards for the miner and any included uncles reward := new(big.Int).Set(blockReward) diff --git a/core/core.go b/core/core.go index cac5c8383e..cbe487ea4a 100644 --- a/core/core.go +++ b/core/core.go @@ -1155,7 +1155,7 @@ func (c *Core) Get(hash common.Hash) *types.Transaction { } func (c *Core) Nonce(addr common.Address) uint64 { - internal, err := addr.InternalAddress() + internal, err := addr.InternalAndQuaiAddress() if err != nil { return 0 } @@ -1171,7 +1171,7 @@ func (c *Core) Content() (map[common.InternalAddress]types.Transactions, map[com } func (c *Core) ContentFrom(addr common.Address) (types.Transactions, types.Transactions) { - internal, err := addr.InternalAddress() + internal, err := addr.InternalAndQuaiAddress() if err != nil { return nil, nil } diff --git a/core/evm.go b/core/evm.go index e0a57fbe24..058cc08e35 100644 --- a/core/evm.go +++ b/core/evm.go @@ -133,7 +133,7 @@ func GetHashFn(ref *types.Header, chain ChainContext) func(n uint64) common.Hash // CanTransfer checks whether there are enough funds in the address' account to make a transfer. // This does not take the necessary gas in to account to make the transfer valid. func CanTransfer(db vm.StateDB, addr common.Address, amount *big.Int) bool { - internalAddr, err := addr.InternalAddress() + internalAddr, err := addr.InternalAndQuaiAddress() if err != nil { return false } @@ -142,11 +142,11 @@ func CanTransfer(db vm.StateDB, addr common.Address, amount *big.Int) bool { // Transfer subtracts amount from sender and adds amount to recipient using the given Db func Transfer(db vm.StateDB, sender, recipient common.Address, amount *big.Int) error { - internalSender, err := sender.InternalAddress() + internalSender, err := sender.InternalAndQuaiAddress() if err != nil { return err } - internalRecipient, err := recipient.InternalAddress() + internalRecipient, err := recipient.InternalAndQuaiAddress() if err != nil { return err } diff --git a/core/state/dump.go b/core/state/dump.go index a7da29855b..962ba02825 100644 --- a/core/state/dump.go +++ b/core/state/dump.go @@ -161,7 +161,7 @@ func (s *StateDB) DumpToCollector(c DumpCollector, conf *DumpConfig) (nextKey [] account.SecureKey = it.Key } addr := common.BytesToAddress(addrBytes, s.nodeLocation) - internal, err := addr.InternalAddress() + internal, err := addr.InternalAndQuaiAddress() if err != nil { continue } diff --git a/core/state/statedb.go b/core/state/statedb.go index a33b39ceed..b52d9ef881 100644 --- a/core/state/statedb.go +++ b/core/state/statedb.go @@ -695,7 +695,7 @@ func (s *StateDB) GetOrNewStateObject(addr common.InternalAddress) *stateObject // createObject creates a new state object. If there is an existing account with // the given address, it is overwritten and returned as the second return value. func (s *StateDB) createObject(addr common.InternalAddress) (newobj, prev *stateObject) { - if !common.IsInChainScope(addr.Bytes(), s.nodeLocation) { + if !common.IsInChainScope(addr.Bytes(), s.nodeLocation) || !addr.IsInQuaiLedgerScope() { s.setError(fmt.Errorf("createObject (%x) error: %v", addr.Bytes(), common.ErrInvalidScope)) return nil, nil } diff --git a/core/state_transition.go b/core/state_transition.go index 039ff91831..1a2dff549a 100644 --- a/core/state_transition.go +++ b/core/state_transition.go @@ -208,7 +208,7 @@ func (st *StateTransition) buyGas() error { balanceCheck = balanceCheck.Mul(balanceCheck, st.gasFeeCap) balanceCheck.Add(balanceCheck, st.value) } - from, err := st.msg.From().InternalAddress() + from, err := st.msg.From().InternalAndQuaiAddress() if err != nil { return err } @@ -238,7 +238,7 @@ func (st *StateTransition) subGasETX() error { } func (st *StateTransition) preCheck() error { - from, err := st.msg.From().InternalAddress() + from, err := st.msg.From().InternalAndQuaiAddress() if err != nil { return err } @@ -352,11 +352,11 @@ func (st *StateTransition) TransitionDb() (*ExecutionResult, error) { contractAddr = &contract } else { // Increment the nonce for the next transaction - addr, err := sender.Address().InternalAddress() + addr, err := sender.Address().InternalAndQuaiAddress() if err != nil { return nil, err } - from, err := msg.From().InternalAddress() + from, err := msg.From().InternalAndQuaiAddress() if err != nil { return nil, err } @@ -375,11 +375,14 @@ func (st *StateTransition) TransitionDb() (*ExecutionResult, error) { st.refundGas(params.RefundQuotient) effectiveTip := cmath.BigMin(st.gasTipCap, new(big.Int).Sub(st.gasFeeCap, st.evm.Context.BaseFee)) + coinbase, err := st.evm.Context.Coinbase.InternalAddress() if err != nil { return nil, err } - st.state.AddBalance(coinbase, new(big.Int).Mul(new(big.Int).SetUint64(st.gasUsed()), effectiveTip)) // todo: etxs no longer pay the miner a fee + if coinbase.IsInQuaiLedgerScope() { + st.state.AddBalance(coinbase, new(big.Int).Mul(new(big.Int).SetUint64(st.gasUsed()), effectiveTip)) // todo: etxs no longer pay the miner a fee + } return &ExecutionResult{ UsedGas: st.gasUsed(), @@ -400,7 +403,7 @@ func (st *StateTransition) refundGas(refundQuotient uint64) { // Return ETH for remaining gas, exchanged at the original rate. remaining := new(big.Int).Mul(new(big.Int).SetUint64(st.gas), st.gasPrice) - from, err := st.msg.From().InternalAddress() + from, err := st.msg.From().InternalAndQuaiAddress() if err != nil { return } diff --git a/core/tx_pool.go b/core/tx_pool.go index c9ceb686c5..ca20111d79 100644 --- a/core/tx_pool.go +++ b/core/tx_pool.go @@ -693,7 +693,7 @@ func (pool *TxPool) validateTx(tx *types.Transaction, local bool) error { addToCache := true if sender := tx.From(); sender != nil { // Check tx cache first var err error - internal, err = sender.InternalAddress() + internal, err = sender.InternalAndQuaiAddress() if err != nil { return err } @@ -706,7 +706,7 @@ func (pool *TxPool) validateTx(tx *types.Transaction, local bool) error { if err != nil { return ErrInvalidSender } - internal, err = from.InternalAddress() + internal, err = from.InternalAndQuaiAddress() if err != nil { return err } @@ -819,7 +819,7 @@ func (pool *TxPool) add(tx *types.Transaction, local bool) (replaced bool, err e if err != nil { return false, err } - internal, err := from.InternalAddress() + internal, err := from.InternalAndQuaiAddress() if err != nil { return false, err } @@ -883,7 +883,7 @@ func (pool *TxPool) enqueueTx(hash common.Hash, tx *types.Transaction, local boo if err != nil { return false, err } - internal, err := from.InternalAddress() + internal, err := from.InternalAndQuaiAddress() if err != nil { return false, err } @@ -1040,12 +1040,17 @@ func (pool *TxPool) addTxs(txs []*types.Transaction, local, sync bool) []error { pool.addUtxoTx(tx) continue } + if tx.To().IsInQiLedgerScope() { + errs[i] = common.MakeErrQiAddress(tx.To().Hex()) + invalidTxMeter.Add(1) + continue + } // Exclude transactions with invalid signatures as soon as // possible and cache senders in transactions before // obtaining lock if sender := tx.From(); sender != nil { var err error - _, err = sender.InternalAddress() + _, err = sender.InternalAndQuaiAddress() if err != nil { errs[i] = err invalidTxMeter.Add(1) @@ -1060,9 +1065,9 @@ func (pool *TxPool) addTxs(txs []*types.Transaction, local, sync bool) []error { invalidTxMeter.Add(1) continue } - _, err = from.InternalAddress() + _, err = from.InternalAndQuaiAddress() if err != nil { - errs[i] = ErrInvalidSender + errs[i] = err invalidTxMeter.Add(1) continue } @@ -1201,7 +1206,7 @@ func (pool *TxPool) Status(hashes []common.Hash) []TxStatus { if err != nil { continue } - internal, err := from.InternalAddress() + internal, err := from.InternalAndQuaiAddress() if err != nil { continue } @@ -1241,7 +1246,7 @@ func (pool *TxPool) removeTx(hash common.Hash, outofbound bool) { if err != nil { return } - internal, err := addr.InternalAddress() + internal, err := addr.InternalAndQuaiAddress() if err != nil { return } @@ -1375,7 +1380,7 @@ func (pool *TxPool) scheduleReorgLoop() { if err != nil { continue } - internal, err := addr.InternalAddress() + internal, err := addr.InternalAndQuaiAddress() if err != nil { pool.logger.WithField("err", err).Debug("Failed to queue transaction") continue @@ -1469,7 +1474,7 @@ func (pool *TxPool) runReorg(done chan struct{}, cancel chan struct{}, reset *tx if err != nil { continue } - internal, err := addr.InternalAddress() + internal, err := addr.InternalAndQuaiAddress() if err != nil { pool.logger.WithField("err", err).Debug("Failed to add transaction event") continue @@ -1994,7 +1999,7 @@ func (as *accountSet) empty() bool { // cannot be derived, this method returns false. func (as *accountSet) containsTx(tx *types.Transaction) bool { if addr, err := types.Sender(as.signer, tx); err == nil { - internal, err := addr.InternalAddress() + internal, err := addr.InternalAndQuaiAddress() if err != nil { return false } @@ -2012,7 +2017,7 @@ func (as *accountSet) add(addr common.InternalAddress) { // addTx adds the sender of tx into the set. func (as *accountSet) addTx(tx *types.Transaction, logger *log.Logger) { if addr, err := types.Sender(as.signer, tx); err == nil { - internal, err := addr.InternalAddress() + internal, err := addr.InternalAndQuaiAddress() if err != nil { logger.WithField("err", err).Debug("Failed to add tx to account set") return diff --git a/core/types/transaction_test.go b/core/types/transaction_test.go index 8ad2decf75..ff7c7f7dfb 100644 --- a/core/types/transaction_test.go +++ b/core/types/transaction_test.go @@ -142,3 +142,9 @@ func TestTransactionHashing(t *testing.T) { require.NotEqual(t, hash, txHash) } + +func TestQiAddressScope(t *testing.T) { + addr := common.HexToAddress("0x001a1C308B372Fe50E7eA2Df8323d57a08a89f83", common.Location{0, 0}) + t.Log(addr.IsInQiLedgerScope()) + t.Log(addr.IsInQuaiLedgerScope()) +} diff --git a/core/vm/eips.go b/core/vm/eips.go index ab5afc4d78..a9ae38c2b8 100644 --- a/core/vm/eips.go +++ b/core/vm/eips.go @@ -21,7 +21,7 @@ import ( ) func opSelfBalance(pc *uint64, interpreter *EVMInterpreter, scope *ScopeContext) ([]byte, error) { - internalAddr, err := scope.Contract.Address().InternalAddress() + internalAddr, err := scope.Contract.Address().InternalAndQuaiAddress() if err != nil { return nil, err } diff --git a/core/vm/evm.go b/core/vm/evm.go index 86982da6a9..c69f39dc5b 100644 --- a/core/vm/evm.go +++ b/core/vm/evm.go @@ -197,7 +197,7 @@ func (evm *EVM) Call(caller ContractRef, addr common.Address, input []byte, gas if evm.TxType == types.InternalToExternalTxType { return evm.CreateETX(addr, caller.Address(), gas, value) } - internalAddr, err := addr.InternalAddress() + internalAddr, err := addr.InternalAndQuaiAddress() if err != nil { // We might want to return zero leftOverGas here, but we're being nice return nil, gas, err @@ -287,7 +287,7 @@ func (evm *EVM) CallCode(caller ContractRef, addr common.Address, input []byte, ret, gas, err = RunPrecompiledContract(p, input, gas) } else { addrCopy := addr - internalAddr, err := addrCopy.InternalAddress() + internalAddr, err := addrCopy.InternalAndQuaiAddress() if err != nil { return nil, gas, err } @@ -327,7 +327,7 @@ func (evm *EVM) DelegateCall(caller ContractRef, addr common.Address, input []by ret, gas, err = RunPrecompiledContract(p, input, gas) } else { addrCopy := addr - internalAddr, err := addrCopy.InternalAddress() + internalAddr, err := addrCopy.InternalAndQuaiAddress() if err != nil { return nil, gas, err } @@ -369,7 +369,7 @@ func (evm *EVM) StaticCall(caller ContractRef, addr common.Address, input []byte if p, isPrecompile, addr := evm.precompile(addr); isPrecompile { ret, gas, err = RunPrecompiledContract(p, input, gas) } else { - internalAddr, err := addr.InternalAddress() + internalAddr, err := addr.InternalAndQuaiAddress() if err != nil { return nil, gas, err } @@ -410,7 +410,7 @@ func (c *codeAndHash) Hash() common.Hash { // create creates a new contract using code as deployment code. func (evm *EVM) create(caller ContractRef, codeAndHash *codeAndHash, gas uint64, value *big.Int, address common.Address) ([]byte, common.Address, uint64, error) { - internalCallerAddr, err := caller.Address().InternalAddress() + internalCallerAddr, err := caller.Address().InternalAndQuaiAddress() if err != nil { return nil, common.Zero, 0, err } @@ -426,7 +426,7 @@ func (evm *EVM) create(caller ContractRef, codeAndHash *codeAndHash, gas uint64, return nil, common.Zero, gas, ErrInsufficientBalance } - internalContractAddr, err := address.InternalAddress() + internalContractAddr, err := address.InternalAndQuaiAddress() if err != nil { return nil, common.Zero, 0, err } @@ -507,7 +507,7 @@ func (evm *EVM) create(caller ContractRef, codeAndHash *codeAndHash, gas uint64, // Create creates a new contract using code as deployment code. func (evm *EVM) Create(caller ContractRef, code []byte, gas uint64, value *big.Int) (ret []byte, contractAddr common.Address, leftOverGas uint64, err error) { - internalAddr, err := caller.Address().InternalAddress() + internalAddr, err := caller.Address().InternalAndQuaiAddress() if err != nil { return nil, common.Zero, 0, err } @@ -515,7 +515,7 @@ func (evm *EVM) Create(caller ContractRef, code []byte, gas uint64, value *big.I nonce := evm.StateDB.GetNonce(internalAddr) contractAddr = crypto.CreateAddress(caller.Address(), nonce, code, evm.chainConfig.Location) - if _, err := contractAddr.InternalAddress(); err == nil { + if _, err := contractAddr.InternalAndQuaiAddress(); err == nil { return evm.create(caller, &codeAndHash{code: code}, gas, value, contractAddr) } @@ -573,7 +573,7 @@ func (evm *EVM) attemptGrindContractCreation(caller ContractRef, nonce uint64, g contractAddr := crypto.CreateAddress2(senderAddress, salt, codeAndHash.Hash().Bytes(), evm.chainConfig.Location) // Check if the generated address is valid. - if _, err := contractAddr.InternalAddress(); err == nil { + if _, err := contractAddr.InternalAndQuaiAddress(); err == nil { return contractAddr, gas, nil } } @@ -597,10 +597,13 @@ func (evm *EVM) CreateETX(toAddr common.Address, fromAddr common.Address, gas ui if common.IsInChainScope(toAddr.Bytes(), evm.chainConfig.Location) { return []byte{}, 0, fmt.Errorf("%x is in chain scope, but CreateETX was called", toAddr) } + if !toAddr.IsInQuaiLedgerScope() { + return []byte{}, 0, fmt.Errorf("%x is not in quai scope, but CreateETX was called", toAddr) + } if gas < params.ETXGas { return []byte{}, 0, fmt.Errorf("CreateETX error: %d is not sufficient gas, required amount: %d", gas, params.ETXGas) } - fromInternal, err := fromAddr.InternalAddress() + fromInternal, err := fromAddr.InternalAndQuaiAddress() if err != nil { return []byte{}, 0, fmt.Errorf("CreateETX error: %s", err.Error()) } diff --git a/core/vm/gas_table.go b/core/vm/gas_table.go index 8e428154a8..7610c8a9e0 100644 --- a/core/vm/gas_table.go +++ b/core/vm/gas_table.go @@ -113,7 +113,7 @@ func gasSStore(evm *EVM, contract *Contract, stack *Stack, mem *Memory, memorySi // Gas sentry honoured, do the actual gas calculation based on the stored value var ( y, x = stack.Back(1), stack.Back(0) - internalContractAddr, err = contract.Address().InternalAddress() + internalContractAddr, err = contract.Address().InternalAndQuaiAddress() ) if err != nil { return 0, err @@ -250,7 +250,7 @@ func gasCall(evm *EVM, contract *Contract, stack *Stack, mem *Memory, memorySize var ( gas uint64 transfersValue = !stack.Back(2).IsZero() - address, err = common.Bytes20ToAddress(stack.Back(1).Bytes20(), evm.chainConfig.Location).InternalAddress() + address, err = common.Bytes20ToAddress(stack.Back(1).Bytes20(), evm.chainConfig.Location).InternalAndQuaiAddress() ) if err != nil { return 0, err @@ -339,12 +339,12 @@ func gasStaticCall(evm *EVM, contract *Contract, stack *Stack, mem *Memory, memo func gasSelfdestruct(evm *EVM, contract *Contract, stack *Stack, mem *Memory, memorySize uint64) (uint64, error) { var gas uint64 - contractAddr, err := contract.Address().InternalAddress() + contractAddr, err := contract.Address().InternalAndQuaiAddress() if err != nil { return 0, err } gas = params.SelfdestructGas - address, err := common.Bytes20ToAddress(stack.Back(0).Bytes20(), evm.chainConfig.Location).InternalAddress() + address, err := common.Bytes20ToAddress(stack.Back(0).Bytes20(), evm.chainConfig.Location).InternalAndQuaiAddress() if err != nil { return 0, err } diff --git a/core/vm/instructions.go b/core/vm/instructions.go index 19a357c61d..4c18d7265c 100644 --- a/core/vm/instructions.go +++ b/core/vm/instructions.go @@ -262,7 +262,7 @@ func opAddress(pc *uint64, interpreter *EVMInterpreter, scope *ScopeContext) ([] func opBalance(pc *uint64, interpreter *EVMInterpreter, scope *ScopeContext) ([]byte, error) { slot := scope.Stack.peek() - address, err := common.Bytes20ToAddress(slot.Bytes20(), interpreter.evm.chainConfig.Location).InternalAddress() + address, err := common.Bytes20ToAddress(slot.Bytes20(), interpreter.evm.chainConfig.Location).InternalAndQuaiAddress() if err != nil { // if an ErrInvalidScope error is returned, the caller (usually interpreter.go/Run) will return the error to Call which will eventually set ReceiptStatusFailed in the tx receipt (state_processor.go/applyTransaction) return nil, err } @@ -392,7 +392,7 @@ func opExtCodeCopy(pc *uint64, interpreter *EVMInterpreter, scope *ScopeContext) if overflow { uint64CodeOffset = 0xffffffffffffffff } - addr, err := common.Bytes20ToAddress(a.Bytes20(), interpreter.evm.chainConfig.Location).InternalAddress() + addr, err := common.Bytes20ToAddress(a.Bytes20(), interpreter.evm.chainConfig.Location).InternalAndQuaiAddress() if err != nil { return nil, err } @@ -437,7 +437,7 @@ func opExtCodeCopy(pc *uint64, interpreter *EVMInterpreter, scope *ScopeContext) // this account should be regarded as a non-existent account and zero should be returned. func opExtCodeHash(pc *uint64, interpreter *EVMInterpreter, scope *ScopeContext) ([]byte, error) { slot := scope.Stack.peek() - address, err := common.Bytes20ToAddress(slot.Bytes20(), interpreter.evm.chainConfig.Location).InternalAddress() + address, err := common.Bytes20ToAddress(slot.Bytes20(), interpreter.evm.chainConfig.Location).InternalAndQuaiAddress() if err != nil { return nil, err } @@ -533,7 +533,7 @@ func opMstore8(pc *uint64, interpreter *EVMInterpreter, scope *ScopeContext) ([] func opSload(pc *uint64, interpreter *EVMInterpreter, scope *ScopeContext) ([]byte, error) { loc := scope.Stack.peek() hash := common.Hash(loc.Bytes32()) - addr, err := scope.Contract.Address().InternalAddress() + addr, err := scope.Contract.Address().InternalAndQuaiAddress() if err != nil { return nil, err } @@ -545,7 +545,7 @@ func opSload(pc *uint64, interpreter *EVMInterpreter, scope *ScopeContext) ([]by func opSstore(pc *uint64, interpreter *EVMInterpreter, scope *ScopeContext) ([]byte, error) { loc := scope.Stack.pop() val := scope.Stack.pop() - addr, err := scope.Contract.Address().InternalAddress() + addr, err := scope.Contract.Address().InternalAndQuaiAddress() if err != nil { return nil, err } @@ -820,11 +820,11 @@ func opStop(pc *uint64, interpreter *EVMInterpreter, scope *ScopeContext) ([]byt func opSuicide(pc *uint64, interpreter *EVMInterpreter, scope *ScopeContext) ([]byte, error) { beneficiary := scope.Stack.pop() - addr, err := scope.Contract.Address().InternalAddress() + addr, err := scope.Contract.Address().InternalAndQuaiAddress() if err != nil { return nil, err } - beneficiaryAddr, err := common.Bytes20ToAddress(beneficiary.Bytes20(), interpreter.evm.chainConfig.Location).InternalAddress() + beneficiaryAddr, err := common.Bytes20ToAddress(beneficiary.Bytes20(), interpreter.evm.chainConfig.Location).InternalAndQuaiAddress() if err != nil { return nil, err } @@ -853,7 +853,7 @@ func opETX(pc *uint64, interpreter *EVMInterpreter, scope *ScopeContext) ([]byte return nil, nil // following opCall protocol } sender := scope.Contract.self.Address() - internalSender, err := sender.InternalAddress() + internalSender, err := sender.InternalAndQuaiAddress() if err != nil { fmt.Printf("%x opETX error: %s\n", scope.Contract.self.Address(), err.Error()) return nil, nil diff --git a/core/vm/logger.go b/core/vm/logger.go index 9c099efff5..a0601348d7 100644 --- a/core/vm/logger.go +++ b/core/vm/logger.go @@ -184,7 +184,7 @@ func (l *StructLogger) CaptureState(env *EVM, pc uint64, op OpCode, gas, cost ui if op == SLOAD && stack.len() >= 1 { var ( address = common.Hash(stack.data[stack.len()-1].Bytes32()) - internalContractAddr, err = contract.Address().InternalAddress() + internalContractAddr, err = contract.Address().InternalAndQuaiAddress() ) if err != nil { fmt.Println("Error in CaptureState: " + err.Error()) diff --git a/core/vm/operations_acl.go b/core/vm/operations_acl.go index d4ac74f590..a196e9cc1f 100644 --- a/core/vm/operations_acl.go +++ b/core/vm/operations_acl.go @@ -35,7 +35,7 @@ func makeGasSStoreFunc(clearingRefund uint64) gasFunc { y, x = stack.Back(1), stack.peek() slot = common.Hash(x.Bytes32()) cost = uint64(0) - internalAddr, err = contract.Address().InternalAddress() + internalAddr, err = contract.Address().InternalAndQuaiAddress() ) if err != nil { return 0, err @@ -200,12 +200,12 @@ func makeSelfdestructGasFn(refundsEnabled bool) gasFunc { var ( gas uint64 address = common.Bytes20ToAddress(stack.peek().Bytes20(), evm.chainConfig.Location) - internalAddress, err = address.InternalAddress() + internalAddress, err = address.InternalAndQuaiAddress() ) if err != nil { return 0, err } - contractAddress, err := contract.Address().InternalAddress() + contractAddress, err := contract.Address().InternalAndQuaiAddress() if err != nil { return 0, err } diff --git a/core/vm/runtime/runtime.go b/core/vm/runtime/runtime.go index 95d1a323b2..3ddb3fff62 100644 --- a/core/vm/runtime/runtime.go +++ b/core/vm/runtime/runtime.go @@ -104,7 +104,7 @@ func Execute(code, input []byte, cfg *Config) ([]byte, *state.StateDB, error) { vmenv = NewEnv(cfg) sender = vm.AccountRef(cfg.Origin) ) - internal, err := address.InternalAddress() + internal, err := address.InternalAndQuaiAddress() if err != nil { return []byte{}, nil, err } @@ -162,7 +162,7 @@ func Call(address common.Address, input []byte, cfg *Config) ([]byte, uint64, er setDefaults(cfg) vmenv := NewEnv(cfg) - _, err := cfg.Origin.InternalAddress() + _, err := cfg.Origin.InternalAndQuaiAddress() if err != nil { return []byte{}, 0, err } diff --git a/internal/quaiapi/api.go b/internal/quaiapi/api.go index ce9cf12168..944f6d9f7c 100644 --- a/internal/quaiapi/api.go +++ b/internal/quaiapi/api.go @@ -245,7 +245,7 @@ func (s *PublicBlockChainAPI) GetBalance(ctx context.Context, address common.Add return nil, err } addr := common.Bytes20ToAddress(address, s.b.NodeLocation()) - internal, err := addr.InternalAddress() + internal, err := addr.InternalAndQuaiAddress() if err != nil { return nil, err } @@ -305,7 +305,7 @@ func (s *PublicBlockChainAPI) GetProof(ctx context.Context, address common.Addre if state == nil || err != nil { return nil, err } - internal, err := address.InternalAddress() + internal, err := address.InternalAndQuaiAddress() if err != nil { return nil, err } @@ -480,7 +480,7 @@ func (s *PublicBlockChainAPI) GetCode(ctx context.Context, address common.Addres if state == nil || err != nil { return nil, err } - internal, err := address.InternalAddress() + internal, err := address.InternalAndQuaiAddress() if err != nil { return nil, err } @@ -503,7 +503,7 @@ func (s *PublicBlockChainAPI) GetStorageAt(ctx context.Context, address common.A if state == nil || err != nil { return nil, err } - internal, err := address.InternalAddress() + internal, err := address.InternalAndQuaiAddress() if err != nil { return nil, err } @@ -538,7 +538,7 @@ func (diff *StateOverride) Apply(state *state.StateDB, nodeLocation common.Locat return nil } for addr, account := range *diff { - internal, err := common.Bytes20ToAddress(addr, nodeLocation).InternalAddress() + internal, err := common.Bytes20ToAddress(addr, nodeLocation).InternalAndQuaiAddress() if err != nil { return err } @@ -611,7 +611,7 @@ func DoCall(ctx context.Context, b Backend, args TransactionArgs, blockNrOrHash defer cancel() if args.Nonce == nil { - internal, err := args.from(b.NodeLocation()).InternalAddress() + internal, err := args.from(b.NodeLocation()).InternalAndQuaiAddress() if err != nil { return nil, err } @@ -756,7 +756,7 @@ func DoEstimateGas(ctx context.Context, b Backend, args TransactionArgs, blockNr if err != nil { return 0, err } - internal, err := args.From.InternalAddress() + internal, err := args.From.InternalAndQuaiAddress() if err != nil { return 0, err } @@ -1382,7 +1382,7 @@ func (s *PublicTransactionPoolAPI) GetTransactionCount(ctx context.Context, addr if state == nil || err != nil { return nil, err } - internal, err := address.InternalAddress() + internal, err := address.InternalAndQuaiAddress() if err != nil { return nil, err } @@ -1562,6 +1562,11 @@ func (s *PublicTransactionPoolAPI) SendRawTransaction(ctx context.Context, input if err != nil { return common.Hash{}, err } + if tx.Type() != types.QiTxType { + if tx.To().IsInQiLedgerScope() { // change after adding Quai->Qi conversion tx type + return common.Hash{}, common.MakeErrQiAddress(tx.To().Hex()) + } + } return SubmitTransaction(ctx, s.b, tx) } diff --git a/internal/quaiapi/quai_api.go b/internal/quaiapi/quai_api.go index af68057151..cf1bd511bc 100644 --- a/internal/quaiapi/quai_api.go +++ b/internal/quaiapi/quai_api.go @@ -137,7 +137,7 @@ func (s *PublicBlockChainQuaiAPI) GetBalance(ctx context.Context, address common return nil, err } addr := common.Bytes20ToAddress(address, s.b.NodeLocation()) - internal, err := addr.InternalAddress() + internal, err := addr.InternalAndQuaiAddress() if err != nil { return nil, err } @@ -180,7 +180,7 @@ func (s *PublicBlockChainQuaiAPI) GetProof(ctx context.Context, address common.A if state == nil || err != nil { return nil, err } - internal, err := address.InternalAddress() + internal, err := address.InternalAndQuaiAddress() if err != nil { return nil, err } @@ -379,7 +379,7 @@ func (s *PublicBlockChainQuaiAPI) GetCode(ctx context.Context, address common.Ad if state == nil || err != nil { return nil, err } - internal, err := address.InternalAddress() + internal, err := address.InternalAndQuaiAddress() if err != nil { return nil, err } @@ -402,7 +402,7 @@ func (s *PublicBlockChainQuaiAPI) GetStorageAt(ctx context.Context, address comm if state == nil || err != nil { return nil, err } - internal, err := address.InternalAddress() + internal, err := address.InternalAndQuaiAddress() if err != nil { return nil, err } diff --git a/quai/api.go b/quai/api.go index e33748855c..9fc74da0d6 100644 --- a/quai/api.go +++ b/quai/api.go @@ -404,7 +404,7 @@ func (api *PrivateDebugAPI) StorageRangeAt(blockHash common.Hash, txIndex int, c if err != nil { return StorageRangeResult{}, err } - internal, err := contractAddress.InternalAddress() + internal, err := contractAddress.InternalAndQuaiAddress() if err != nil { return StorageRangeResult{}, err }