-
Notifications
You must be signed in to change notification settings - Fork 199
/
changeOwnerAddress.go
90 lines (76 loc) · 2.6 KB
/
changeOwnerAddress.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
package builtInFunctions
import (
"bytes"
"fmt"
"sync"
"github.com/ElrondNetwork/elrond-go/core/check"
"github.com/ElrondNetwork/elrond-go/core/vmcommon"
"github.com/ElrondNetwork/elrond-go/data/state"
"github.com/ElrondNetwork/elrond-go/process"
)
var _ process.BuiltinFunction = (*changeOwnerAddress)(nil)
type changeOwnerAddress struct {
gasCost uint64
mutExecution sync.RWMutex
}
// NewChangeOwnerAddressFunc create a new change owner built in function
func NewChangeOwnerAddressFunc(gasCost uint64) *changeOwnerAddress {
return &changeOwnerAddress{gasCost: gasCost}
}
// SetNewGasConfig is called whenever gas cost is changed
func (c *changeOwnerAddress) SetNewGasConfig(gasCost *process.GasCost) {
c.mutExecution.Lock()
c.gasCost = gasCost.BuiltInCost.ChangeOwnerAddress
c.mutExecution.Unlock()
}
// ProcessBuiltinFunction processes simple protocol built-in function
func (c *changeOwnerAddress) ProcessBuiltinFunction(
acntSnd, acntDst state.UserAccountHandler,
vmInput *vmcommon.ContractCallInput,
) (*vmcommon.VMOutput, error) {
c.mutExecution.RLock()
defer c.mutExecution.RUnlock()
if vmInput == nil {
return nil, process.ErrNilVmInput
}
if len(vmInput.Arguments) == 0 {
return nil, process.ErrInvalidArguments
}
if vmInput.CallValue.Cmp(zero) != 0 {
return nil, process.ErrBuiltInFunctionCalledWithValue
}
if len(vmInput.Arguments[0]) != len(vmInput.CallerAddr) {
return nil, process.ErrInvalidAddressLength
}
if vmInput.GasProvided < c.gasCost {
return nil, process.ErrNotEnoughGas
}
gasRemaining := computeGasRemaining(acntSnd, vmInput.GasProvided, c.gasCost)
if check.IfNil(acntDst) {
// cross-shard call, in sender shard only the gas is taken out
return &vmcommon.VMOutput{ReturnCode: vmcommon.Ok, GasRemaining: gasRemaining}, nil
}
if !bytes.Equal(vmInput.CallerAddr, acntDst.GetOwnerAddress()) {
return nil, fmt.Errorf("%w not the owner of the account", process.ErrOperationNotPermitted)
}
err := acntDst.ChangeOwnerAddress(vmInput.CallerAddr, vmInput.Arguments[0])
if err != nil {
return nil, err
}
return &vmcommon.VMOutput{GasRemaining: gasRemaining, ReturnCode: vmcommon.Ok}, nil
}
func computeGasRemaining(snd state.UserAccountHandler, gasProvided uint64, gasToUse uint64) uint64 {
if gasProvided < gasToUse {
return 0
}
// in case of built in functions - gas is consumed in sender shard, returned already in sender shard
// thus we must return with 0 here
if check.IfNil(snd) {
return 0
}
return gasProvided - gasToUse
}
// IsInterfaceNil returns true if underlying object in nil
func (c *changeOwnerAddress) IsInterfaceNil() bool {
return c == nil
}