Skip to content

Commit

Permalink
Optimize judge for address (fix#378) (#392)
Browse files Browse the repository at this point in the history
* Optimize judge for address (fix#378)

* Adapt some previous function call
  • Loading branch information
zhugelianglongming committed Dec 6, 2022
1 parent 817bb6f commit 5a3396e
Show file tree
Hide file tree
Showing 12 changed files with 361 additions and 167 deletions.
25 changes: 17 additions & 8 deletions bcs/contract/evm/address.go
Original file line number Diff line number Diff line change
Expand Up @@ -99,19 +99,28 @@ func EVMAddressToContractAccountWithoutPrefixAndSuffix(evmAddr crypto.Address) (
return contractNameStrWithPrefix[4:], nil
}

// determine whether it is a contract account
// Deprecating, use IsContractAccount instead
func DetermineContractAccount(account string) bool {
if utils.IsAccount(account) != 1 {
return false
}
return strings.Index(account, "@") != -1
return IsContractAccount(account)
}

// determine whether it is a contract name
// IsContractAccount returns true for a contract account
func IsContractAccount(account string) bool {
return utils.IsAccount(account) && strings.Contains(account, "@")
}

// Deprecating
// if error of incorrect name is needed, use `contract.ValidContractName`
// otherwise, use IsContractName
func DetermineContractName(contractName string) error {
return contract.ValidContractName(contractName)
}

// IsContractName determine whether it is a contract name
func IsContractName(contractName string) bool {
return contract.ValidContractName(contractName) == nil
}

// determine whether it is a contract name
func DetermineContractNameFromEVM(evmAddr crypto.Address) (string, error) {
var addr string
Expand Down Expand Up @@ -162,10 +171,10 @@ func DetermineXchainAddress(xAddr string) (string, string, error) {
var addr crypto.Address
var addrType string
var err error
if DetermineContractAccount(xAddr) {
if IsContractAccount(xAddr) {
addr, err = ContractAccountToEVMAddress(xAddr)
addrType = contractAccountType
} else if DetermineContractName(xAddr) == nil {
} else if IsContractName(xAddr) {
addr, err = ContractNameToEVMAddress(xAddr)
addrType = contractNameType
} else {
Expand Down
108 changes: 54 additions & 54 deletions bcs/contract/evm/creator.go
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ type evmCreator struct {
vm *evm.EVM
}

func newEvmCreator(config *bridge.InstanceCreatorConfig) (bridge.InstanceCreator, error) {
func newEvmCreator(_ *bridge.InstanceCreatorConfig) (bridge.InstanceCreator, error) {
opt := evm.Options{}
vm := evm.New(opt)
return &evmCreator{
Expand All @@ -53,7 +53,7 @@ func (e *evmCreator) CreateInstance(ctx *bridge.Context, cp bridge.ContractCodeP
}, nil
}

func (e *evmCreator) RemoveCache(name string) {
func (e *evmCreator) RemoveCache(_ string) {
}

type evmInstance struct {
Expand All @@ -68,50 +68,50 @@ type evmInstance struct {
fromCache bool
}

func (e *evmInstance) Exec() error {
func (i *evmInstance) Exec() error {
var err error

// 获取合约的 code。
if e.fromCache {
e.code, err = e.cp.GetContractCodeFromCache(e.ctx.ContractName)
if i.fromCache {
i.code, err = i.cp.GetContractCodeFromCache(i.ctx.ContractName)
if err != nil {
return err
}
} else {
e.code, err = e.cp.GetContractCode(e.ctx.ContractName)
i.code, err = i.cp.GetContractCode(i.ctx.ContractName)
if err != nil {
return err
}
}

// 部署合约或者调用合约时参数未使用 abi 编码时需要获取到合约的 abi。执行结果也需要使用 abi 解析。
if e.fromCache {
e.abi, err = e.cp.GetContractAbiFromCache(e.ctx.ContractName)
if i.fromCache {
i.abi, err = i.cp.GetContractAbiFromCache(i.ctx.ContractName)
if err != nil {
return err
}
} else {
e.abi, err = e.cp.GetContractAbi(e.ctx.ContractName)
i.abi, err = i.cp.GetContractAbi(i.ctx.ContractName)
if err != nil {
return err
}
}

if e.ctx.Method == initializeMethod {
return e.deployContract()
if i.ctx.Method == initializeMethod {
return i.deployContract()
}

var caller crypto.Address
if DetermineContractAccount(e.state.ctx.Initiator) {
caller, err = ContractAccountToEVMAddress(e.state.ctx.Initiator)
if IsContractAccount(i.state.ctx.Initiator) {
caller, err = ContractAccountToEVMAddress(i.state.ctx.Initiator)
} else {
caller, err = XchainToEVMAddress(e.state.ctx.Initiator)
caller, err = XchainToEVMAddress(i.state.ctx.Initiator)
}
if err != nil {
return err
}

callee, err := ContractNameToEVMAddress(e.ctx.ContractName)
callee, err := ContractNameToEVMAddress(i.ctx.ContractName)
if err != nil {
return err
}
Expand All @@ -121,20 +121,20 @@ func (e *evmInstance) Exec() error {
// 如果客户端已经将参数进行了 abi 编码,那么此处不需要再进行编码,而且返回的结果也不需要 abi 解码。否则此处需要将参数 abi 编码同时将结果 abi 解码。
needDecodeResp := false
input := []byte{}
jsonEncoded, ok := e.ctx.Args[evmParamJSONEncoded]
jsonEncoded, ok := i.ctx.Args[evmParamJSONEncoded]
if !ok || string(jsonEncoded) != "true" {
input = e.ctx.Args[evmInput]
input = i.ctx.Args[evmInput]
} else {
needDecodeResp = true
if input, err = e.encodeInvokeInput(); err != nil {
if input, err = i.encodeInvokeInput(); err != nil {
return err
}
}

value := big.NewInt(0)
ok = false
if e.ctx.TransferAmount != "" {
value, ok = new(big.Int).SetString(e.ctx.TransferAmount, 0)
if i.ctx.TransferAmount != "" {
value, ok = new(big.Int).SetString(i.ctx.TransferAmount, 0)
if !ok {
return fmt.Errorf("get evm value error")
}
Expand All @@ -147,60 +147,60 @@ func (e *evmInstance) Exec() error {
Value: value,
Gas: &gas,
}
out, err := e.vm.Execute(e.state, e.blockState, e, params, e.code)
out, err := i.vm.Execute(i.state, i.blockState, i, params, i.code)
if err != nil {
return err
}

if needDecodeResp {
// 执行结果根据 abi 解码,返回 json 格式的数组。
out, err = decodeRespWithAbiForEVM(string(e.abi), e.ctx.Method, out)
out, err = decodeRespWithAbiForEVM(string(i.abi), i.ctx.Method, out)
if err != nil {
return err
}
}

e.gasUsed = uint64(contract.MaxLimits.Cpu) - *params.Gas
i.gasUsed = uint64(contract.MaxLimits.Cpu) - *params.Gas

e.ctx.Output = &pb.Response{
i.ctx.Output = &pb.Response{
Status: 200,
Body: out,
}
return nil
}

func (e *evmInstance) ResourceUsed() contract.Limits {
func (i *evmInstance) ResourceUsed() contract.Limits {
return contract.Limits{
Cpu: int64(e.gasUsed),
Cpu: int64(i.gasUsed),
}
}

func (e *evmInstance) Release() {
func (i *evmInstance) Release() {
}

func (e *evmInstance) Abort(msg string) {
func (i *evmInstance) Abort(msg string) {
}

func (e *evmInstance) Call(call *exec.CallEvent, exception *errors.Exception) error {
func (i *evmInstance) Call(call *exec.CallEvent, exception *errors.Exception) error {
return nil
}

func (e *evmInstance) Log(log *exec.LogEvent) error {
func (i *evmInstance) Log(log *exec.LogEvent) error {
contractName, _, err := DetermineEVMAddress(log.Address)
if err != nil {
return err
}

contractAbiByte, err := e.cp.GetContractAbi(contractName)
contractAbiByte, err := i.cp.GetContractAbi(contractName)
if err != nil {
return err
}
event, err := unpackEventFromAbi(contractAbiByte, contractName, log)
if err != nil {
return err
}
e.ctx.Events = append(e.ctx.Events, event)
e.ctx.State.AddEvent(event)
i.ctx.Events = append(i.ctx.Events, event)
i.ctx.State.AddEvent(event)
return nil
}

Expand Down Expand Up @@ -239,33 +239,33 @@ func unpackEventFromAbi(abiByte []byte, contractName string, log *exec.LogEvent)
return event, nil
}

func (e *evmInstance) deployContract() error {
func (i *evmInstance) deployContract() error {
var caller crypto.Address
var err error
if DetermineContractAccount(e.state.ctx.Initiator) {
caller, err = ContractAccountToEVMAddress(e.state.ctx.Initiator)
if IsContractAccount(i.state.ctx.Initiator) {
caller, err = ContractAccountToEVMAddress(i.state.ctx.Initiator)
} else {
caller, err = XchainToEVMAddress(e.state.ctx.Initiator)
caller, err = XchainToEVMAddress(i.state.ctx.Initiator)
}
if err != nil {
return err
}

callee, err := ContractNameToEVMAddress(e.ctx.ContractName)
callee, err := ContractNameToEVMAddress(i.ctx.ContractName)
if err != nil {
return err
}

gas := uint64(contract.MaxLimits.Cpu)

input := []byte{}
jsonEncoded, ok := e.ctx.Args[evmParamJSONEncoded]
jsonEncoded, ok := i.ctx.Args[evmParamJSONEncoded]
if !ok || string(jsonEncoded) != "true" {
// 客户端传来的参数是已经 abi 编码的。
input = e.code
input = i.code
} else {
// 客户端未将参数编码。
if input, err = e.encodeDeployInput(); err != nil {
if input, err = i.encodeDeployInput(); err != nil {
return err
}
}
Expand All @@ -279,20 +279,20 @@ func (e *evmInstance) deployContract() error {
Value: big.NewInt(0),
Gas: &gas,
}
contractCode, err := e.vm.Execute(e.state, e.blockState, e, params, input)
contractCode, err := i.vm.Execute(i.state, i.blockState, i, params, input)
if err != nil {
return err
}

key := evmCodeKey(e.ctx.ContractName)
err = e.ctx.State.Put("contract", key, contractCode)
key := evmCodeKey(i.ctx.ContractName)
err = i.ctx.State.Put("contract", key, contractCode)
if err != nil {
return err
}

e.gasUsed = uint64(contract.MaxLimits.Cpu) - *params.Gas
i.gasUsed = uint64(contract.MaxLimits.Cpu) - *params.Gas

e.ctx.Output = &pb.Response{
i.ctx.Output = &pb.Response{
Status: 200,
}
return nil
Expand Down Expand Up @@ -339,9 +339,9 @@ func decodeRespWithAbiForEVM(abiData, funcName string, resp []byte) ([]byte, err
return out, nil
}

func (e *evmInstance) encodeDeployInput() ([]byte, error) {
func (i *evmInstance) encodeDeployInput() ([]byte, error) {
// 客户端如果未将参数进行 abi 编码,那么通过 input 获取的是参数 json 序列化的结果。
argsBytes, ok := e.ctx.Args[evmInput]
argsBytes, ok := i.ctx.Args[evmInput]
if !ok {
return nil, fmt.Errorf("missing emvInput")
}
Expand All @@ -352,7 +352,7 @@ func (e *evmInstance) encodeDeployInput() ([]byte, error) {
return nil, err
}

enc, err := xabi.New(e.abi)
enc, err := xabi.New(i.abi)
if err != nil {
return nil, err
}
Expand All @@ -362,7 +362,7 @@ func (e *evmInstance) encodeDeployInput() ([]byte, error) {
return nil, err
}

evmCode := string(e.code) + hex.EncodeToString(input)
evmCode := string(i.code) + hex.EncodeToString(input)
codeBuf, err := hex.DecodeString(evmCode)
if err != nil {
return nil, err
Expand All @@ -371,8 +371,8 @@ func (e *evmInstance) encodeDeployInput() ([]byte, error) {
return codeBuf, nil
}

func (e *evmInstance) encodeInvokeInput() ([]byte, error) {
argsBytes, ok := e.ctx.Args[evmInput]
func (i *evmInstance) encodeInvokeInput() ([]byte, error) {
argsBytes, ok := i.ctx.Args[evmInput]
if !ok {
return nil, nil
}
Expand All @@ -382,12 +382,12 @@ func (e *evmInstance) encodeInvokeInput() ([]byte, error) {
return nil, err
}

enc, err := xabi.New(e.abi)
enc, err := xabi.New(i.abi)
if err != nil {
return nil, err
}

input, err := enc.Encode(e.ctx.Method, args)
input, err := enc.Encode(i.ctx.Method, args)
if err != nil {
return nil, err
}
Expand Down
Loading

0 comments on commit 5a3396e

Please sign in to comment.