Skip to content
Merged
Show file tree
Hide file tree
Changes from 21 commits
Commits
Show all changes
24 commits
Select commit Hold shift + click to select a range
3917e7b
Transaction background indexing/unindexing + improved chain initiatio…
error2215 Jun 29, 2022
4180502
core/rawdb: Stop freezer process as part of freezer.Close()
error2215 Jun 29, 2022
da9e4e2
PR#20302, PR#21010, PR#20758, PR#21212, PR#20837, PR#20808, PR#20692,…
error2215 Jul 1, 2022
ac2dc6f
define and test chain reparation cornercases
error2215 Jul 4, 2022
b482bbb
fix KnownDNSNetwork
error2215 Jul 4, 2022
1a51a2f
final fixes
error2215 Jul 4, 2022
9d6c1ea
remove verbosity in test
error2215 Jul 5, 2022
57739c1
test timeouts 20m
error2215 Jul 6, 2022
7691d3f
accounts/abi: implement new fallback functions #20764
error2215 Jul 6, 2022
b041414
accounts/abi: Prevent recalculation of internal fields #20895
error2215 Jul 6, 2022
192ea43
fix test
error2215 Jul 6, 2022
659ead9
improve EstimateEnergy API #20830
error2215 Jul 8, 2022
c1a7675
ignore long-running tests
error2215 Jul 8, 2022
e98e59a
ignore long-running tests
error2215 Jul 8, 2022
0acea1f
Merge remote-tracking branch 'origin/develop' into feature/chain_repa…
error2215 Jul 8, 2022
2dd7920
go mod tidy (add uint256 package)
error2215 Jul 13, 2022
7b5bb00
merge
error2215 Jul 13, 2022
9877d66
cmd/сvm: add state transition tool for testing #20958
error2215 Jul 13, 2022
1f47e54
core/vm: use a callcontext struct #20761
error2215 Jul 13, 2022
c5ede52
EIP-2315: JUMPSUB for the CVM #20619
error2215 Jul 13, 2022
1c10376
core/vm: less allocations for various call variants #21222
error2215 Jul 13, 2022
2989599
merge develop
error2215 Jul 22, 2022
f7fc4ef
merge develop
Jul 25, 2022
5d83a76
Merge remote-tracking branch 'origin/develop' into feature/less_alloc…
Jul 25, 2022
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
147 changes: 110 additions & 37 deletions accounts/abi/abi.go
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,9 @@ package abi
import (
"bytes"
"encoding/json"
"errors"
"fmt"
"github.com/core-coin/go-core/crypto"
"io"

"github.com/core-coin/go-core/common"
Expand All @@ -32,6 +34,12 @@ type ABI struct {
Constructor Method
Methods map[string]Method
Events map[string]Event

// Additional "special" functions introduced in ylem v0.6.0.
// It's separated from the original default fallback. Each contract
// can only define one fallback and receive function.
Fallback Method // Note it's also used to represent legacy fallback before v0.6.0
Receive Method
}

// JSON returns a parsed ABI interface and error if it failed.
Expand Down Expand Up @@ -70,7 +78,7 @@ func (abi ABI) Pack(name string, args ...interface{}) ([]byte, error) {
return nil, err
}
// Pack up the method ID too if not a constructor and return
return append(method.ID(), arguments...), nil
return append(method.ID, arguments...), nil
}

// Unpack output in v according to the abi specification
Expand Down Expand Up @@ -108,13 +116,22 @@ func (abi ABI) UnpackIntoMap(v map[string]interface{}, name string, data []byte)
// UnmarshalJSON implements json.Unmarshaler interface
func (abi *ABI) UnmarshalJSON(data []byte) error {
var fields []struct {
Type string
Name string
Constant bool
Type string
Name string
Inputs []Argument
Outputs []Argument

// Status indicator which can be: "pure", "view",
// "nonpayable" or "payable".
StateMutability string
Anonymous bool
Inputs []Argument
Outputs []Argument

// Deprecated Status indicators, but removed in v0.6.0.
Constant bool // True if function is either pure or view
Payable bool // True if function is payable

// Event relevant indicator represents the event is
// declared as anonymous.
Anonymous bool
}
if err := json.Unmarshal(data, &fields); err != nil {
return err
Expand All @@ -124,52 +141,76 @@ func (abi *ABI) UnmarshalJSON(data []byte) error {
for _, field := range fields {
switch field.Type {
case "constructor":
abi.Constructor = Method{
Inputs: field.Inputs,
abi.Constructor = NewMethod("", "", Constructor, field.StateMutability, field.Constant, field.Payable, field.Inputs, nil)
case "function":
name := abi.overloadedMethodName(field.Name)
abi.Methods[name] = NewMethod(name, field.Name, Function, field.StateMutability, field.Constant, field.Payable, field.Inputs, field.Outputs)
case "fallback":
// New introduced function type in v0.6.0, check more detail
// here https://solidity.readthedocs.io/en/v0.6.0/contracts.html#fallback-function
if abi.HasFallback() {
return errors.New("only single fallback is allowed")
}
// empty defaults to function according to the abi spec
case "function", "":
name := field.Name
_, ok := abi.Methods[name]
for idx := 0; ok; idx++ {
name = fmt.Sprintf("%s%d", field.Name, idx)
_, ok = abi.Methods[name]
abi.Fallback = NewMethod("", "", Fallback, field.StateMutability, field.Constant, field.Payable, nil, nil)
case "receive":
// New introduced function type in v0.6.0, check more detail
// here https://solidity.readthedocs.io/en/v0.6.0/contracts.html#fallback-function
if abi.HasReceive() {
return errors.New("only single receive is allowed")
}
isConst := field.Constant || field.StateMutability == "pure" || field.StateMutability == "view"
abi.Methods[name] = Method{
Name: name,
RawName: field.Name,
Const: isConst,
Inputs: field.Inputs,
Outputs: field.Outputs,
if field.StateMutability != "payable" {
return errors.New("the statemutability of receive can only be payable")
}
abi.Receive = NewMethod("", "", Receive, field.StateMutability, field.Constant, field.Payable, nil, nil)
case "event":
name := field.Name
_, ok := abi.Events[name]
for idx := 0; ok; idx++ {
name = fmt.Sprintf("%s%d", field.Name, idx)
_, ok = abi.Events[name]
}
abi.Events[name] = Event{
Name: name,
RawName: field.Name,
Anonymous: field.Anonymous,
Inputs: field.Inputs,
}
name := abi.overloadedEventName(field.Name)
abi.Events[name] = NewEvent(name, field.Name, field.Anonymous, field.Inputs)
default:
return fmt.Errorf("abi: could not recognize type %v of field %v", field.Type, field.Name)
}
}

return nil
}

// overloadedMethodName returns the next available name for a given function.
// Needed since ylem allows for function overload.
//
// e.g. if the abi contains Methods send, send1
// overloadedMethodName would return send2 for input send.
func (abi *ABI) overloadedMethodName(rawName string) string {
name := rawName
_, ok := abi.Methods[name]
for idx := 0; ok; idx++ {
name = fmt.Sprintf("%s%d", rawName, idx)
_, ok = abi.Methods[name]
}
return name
}

// overloadedEventName returns the next available name for a given event.
// Needed since ylem allows for event overload.
//
// e.g. if the abi contains events received, received1
// overloadedEventName would return received2 for input received.
func (abi *ABI) overloadedEventName(rawName string) string {
name := rawName
_, ok := abi.Events[name]
for idx := 0; ok; idx++ {
name = fmt.Sprintf("%s%d", rawName, idx)
_, ok = abi.Events[name]
}
return name
}

// MethodById looks up a method by the 4-byte id
// returns nil if none found
func (abi *ABI) MethodById(sigdata []byte) (*Method, error) {
if len(sigdata) < 4 {
return nil, fmt.Errorf("data too short (%d bytes) for abi method lookup", len(sigdata))
}
for _, method := range abi.Methods {
if bytes.Equal(method.ID(), sigdata[:4]) {
if bytes.Equal(method.ID, sigdata[:4]) {
return &method, nil
}
}
Expand All @@ -180,9 +221,41 @@ func (abi *ABI) MethodById(sigdata []byte) (*Method, error) {
// ABI and returns nil if none found.
func (abi *ABI) EventByID(topic common.Hash) (*Event, error) {
for _, event := range abi.Events {
if bytes.Equal(event.ID().Bytes(), topic.Bytes()) {
if bytes.Equal(event.ID.Bytes(), topic.Bytes()) {
return &event, nil
}
}
return nil, fmt.Errorf("no event with id: %#x", topic.Hex())
}

// HasFallback returns an indicator whether a fallback function is included.
func (abi *ABI) HasFallback() bool {
return abi.Fallback.Type == Fallback
}

// HasReceive returns an indicator whether a receive function is included.
func (abi *ABI) HasReceive() bool {
return abi.Receive.Type == Receive
}

// revertSelector is a special function selector for revert reason unpacking.
var revertSelector = crypto.SHA3([]byte("Error(string)"))[:4]

// UnpackRevert resolves the abi-encoded revert reason. According to the solidity
// spec https://solidity.readthedocs.io/en/latest/control-structures.html#revert,
// the provided revert reason is abi-encoded as if it were a call to a function
// `Error(string)`. So it's a special tool for it.
func UnpackRevert(data []byte) (string, error) {
if len(data) < 4 {
return "", errors.New("invalid data for unpacking")
}
if !bytes.Equal(data[:4], revertSelector) {
return "", errors.New("invalid data for unpacking")
}
var reason string
typ, _ := NewType("string", "", nil)
if err := (Arguments{{Type: typ}}).Unpack(&reason, data[4:]); err != nil {
return "", err
}
return reason, nil
}
Loading