Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

core, vm, common: define constantinople fork + shift #16045

Merged
merged 5 commits into from
Feb 23, 2018

Conversation

holiman
Copy link
Contributor

@holiman holiman commented Feb 9, 2018

This PR defines Constantinople hard fork in genesis and instruction set. Additionally, it implementes SHR, SHL and SAR, along with testcases defined in the EIP .

Benchmarks:

#go test -bench BenchmarkOp . -run -
goos: linux
goarch: amd64
pkg: github.com/ethereum/go-ethereum/core/vm
BenchmarkOpAdd64-8        	 5000000	       243 ns/op
BenchmarkOpAdd128-8       	 5000000	       243 ns/op
BenchmarkOpAdd256-8       	 5000000	       268 ns/op
BenchmarkOpSub64-8        	 5000000	       270 ns/op
BenchmarkOpSub128-8       	 5000000	       302 ns/op
BenchmarkOpSub256-8       	 5000000	       379 ns/op
BenchmarkOpMul-8          	 3000000	       479 ns/op
BenchmarkOpDiv256-8       	 2000000	       624 ns/op
BenchmarkOpDiv128-8       	 5000000	       316 ns/op
BenchmarkOpDiv64-8        	 5000000	       276 ns/op
BenchmarkOpSdiv-8         	 2000000	      1048 ns/op
BenchmarkOpMod-8          	 2000000	       618 ns/op
BenchmarkOpSmod-8         	 1000000	      1047 ns/op
BenchmarkOpExp-8          	   50000	     35194 ns/op
BenchmarkOpSignExtend-8   	 3000000	       440 ns/op
BenchmarkOpLt-8           	 3000000	       419 ns/op
BenchmarkOpGt-8           	 3000000	       420 ns/op
BenchmarkOpSlt-8          	 2000000	       732 ns/op
BenchmarkOpSgt-8          	 2000000	       746 ns/op
BenchmarkOpEq-8           	 5000000	       399 ns/op
BenchmarkOpAnd-8          	 5000000	       381 ns/op
BenchmarkOpOr-8           	 5000000	       369 ns/op
BenchmarkOpXor-8          	 3000000	       464 ns/op
BenchmarkOpByte-8         	 3000000	       475 ns/op
BenchmarkOpAddmod-8       	 2000000	      1096 ns/op
BenchmarkOpMulmod-8       	 1000000	      1210 ns/op
BenchmarkOpSHL-8          	 2000000	       642 ns/op
BenchmarkOpSHR-8          	 3000000	       412 ns/op
BenchmarkOpSAR-8          	 2000000	       676 ns/op
PASS
ok  	github.com/ethereum/go-ethereum/core/vm	56.064s

The new shifts are defined with gascost GasFastestStep, same as ADD, SUB, GT, LT, SLT, SGT, EQ, ISZERO, AND, XOR, OR, NOT and BYTE.
Selecting only those in the benchmark results, and ordering them by speed, we get:

BenchmarkOpAdd256-8       	 5000000	       268 ns/op
BenchmarkOpOr-8           	 5000000	       369 ns/op
BenchmarkOpSub256-8       	 5000000	       379 ns/op
BenchmarkOpAnd-8          	 5000000	       381 ns/op
BenchmarkOpEq-8           	 5000000	       399 ns/op
BenchmarkOpSHR-8          	 3000000	       412 ns/op
BenchmarkOpLt-8           	 3000000	       419 ns/op
BenchmarkOpGt-8           	 3000000	       420 ns/op
BenchmarkOpXor-8          	 3000000	       464 ns/op
BenchmarkOpByte-8         	 3000000	       475 ns/op
BenchmarkOpSHL-8          	 2000000	       642 ns/op
BenchmarkOpSAR-8          	 2000000	       676 ns/op
BenchmarkOpSlt-8          	 2000000	       732 ns/op
BenchmarkOpSgt-8          	 2000000	       746 ns/op

They weigh in around the average of the other ops (we could probably improve SLT and SGT by not allocating as many bigints.)

This should not go in 1.8.0, but does not need to be "constantinople-complete" to be merged to master: the sooner we get it in the better -- the only prerequisite should be that it will not interfere with pre-constantinople vm runtime. If it panic's when constantinople is enabled, that's fine -- the more testing we get the better, and gives the test-team the possibility to validate their testcases across clients.

@holiman holiman requested a review from karalabe as a code owner February 9, 2018 08:07
@axic
Copy link
Member

axic commented Feb 9, 2018

I wonder why is SHL >50% slower than SHR? Is the underlying Go bignum library external?

@karalabe
Copy link
Member

karalabe commented Feb 9, 2018

@axic SHL does memory allocs as it needs to grow the bignum, and only afterwards is it clipped to 256 bits.

@axic
Copy link
Member

axic commented Feb 9, 2018

Oh, that is a good point. Perhaps even worth noting in the EIP.

Is it possible to have it operate on a fixed 256 bit length?

@holiman
Copy link
Contributor Author

holiman commented Feb 12, 2018

Is it possible to have it operate on a fixed 256 bit length?

It is, but what we really should do is swap out the entire bignums-on-stack implementation with a 256-bit-fixedlength-on-stack. It's a pretty big undertaking (which may be worth doing)

@axic
Copy link
Member

axic commented Feb 12, 2018

Actually isn't this quite a big problem with for example multiplying 0xff..ff with 0xff..ff? Or is it internally implemented using mulmod?

Copy link
Member

@karalabe karalabe left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Generally looks good to me, just disable it on all code paths for now imho. Also pls gofmt.

// byzantium and contantinople instructions.
func NewConstantinopleInstructionSet() [256]operation {
// instructions that can be executed during the byzantium phase.
instructionSet := NewHomesteadInstructionSet()
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

NewHomesteadInstructionSet -> NewByzantiumInstructionSet

params/config.go Outdated

// AllCliqueProtocolChanges contains every protocol change (EIPs) introduced
// and accepted by the Ethereum core developers into the Clique consensus.
//
// This configuration is intentionally not using keyed fields to force anyone
// adding flags to the config to also have to set these fields.
AllCliqueProtocolChanges = &ChainConfig{big.NewInt(1337), big.NewInt(0), nil, false, big.NewInt(0), common.Hash{}, big.NewInt(0), big.NewInt(0), big.NewInt(0), nil, &CliqueConfig{Period: 0, Epoch: 30000}}
AllCliqueProtocolChanges = &ChainConfig{big.NewInt(1337), big.NewInt(0), nil, false, big.NewInt(0), common.Hash{}, big.NewInt(0), big.NewInt(0), big.NewInt(0), big.NewInt(0), nil, &CliqueConfig{Period: 0, Epoch: 30000}}
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't think we should enable it before it's actually accepted. --dev uses these and we don't really want users to start using alpha code.

params/config.go Outdated
@@ -82,16 +82,16 @@ var (
//
// This configuration is intentionally not using keyed fields to force anyone
// adding flags to the config to also have to set these fields.
AllEthashProtocolChanges = &ChainConfig{big.NewInt(1337), big.NewInt(0), nil, false, big.NewInt(0), common.Hash{}, big.NewInt(0), big.NewInt(0), big.NewInt(0), new(EthashConfig), nil}
AllEthashProtocolChanges = &ChainConfig{big.NewInt(1337), big.NewInt(0), nil, false, big.NewInt(0), common.Hash{}, big.NewInt(0), big.NewInt(0), big.NewInt(0), big.NewInt(0), new(EthashConfig), nil}
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't think we should enable it before it's actually accepted. --dev uses these and we don't really want users to start using alpha code.

fmt.Println()
fmt.Printf("Which block should Constantinople come into effect? (default = %v)\n", w.conf.Genesis.Config.ConstantinopleBlock)
w.conf.Genesis.Config.ConstantinopleBlock = w.readDefaultBigInt(w.conf.Genesis.Config.ConstantinopleBlock)

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't think puppeth should offer Constantinople until it's actually finalized. Otherwise people will end up with broken chains.

@holiman
Copy link
Contributor Author

holiman commented Feb 23, 2018

Review concerns addressed, rebased to fix conflicts. PTAL

@@ -63,6 +63,9 @@ const (
XOR
NOT
BYTE
SHL
SHR
SAR
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ah, missed this previously. You'll need to add these opcodes to the opcode -> string map in the same file a few hundred lines below this into opCodeToString.

@holiman
Copy link
Contributor Author

holiman commented Feb 23, 2018

Fixed, ptal

Copy link
Member

@karalabe karalabe left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM

@karalabe karalabe added this to the 1.8.2 milestone Feb 23, 2018
@karalabe karalabe merged commit 44d40ff into ethereum:master Feb 23, 2018
prestonvanloon pushed a commit to prestonvanloon/go-ethereum that referenced this pull request Apr 2, 2018
* core, vm, common: define constantinople fork, start implementation of shift instructions

* vm: more testcases

* vm: add tests for intpool erroneous intpool handling

* core, vm, common: fix constantinople review concerns

* vm: add string<->op definitions for new opcodes
mariameda pushed a commit to NiluPlatform/go-nilu that referenced this pull request Aug 23, 2018
* core, vm, common: define constantinople fork, start implementation of shift instructions

* vm: more testcases

* vm: add tests for intpool erroneous intpool handling

* core, vm, common: fix constantinople review concerns

* vm: add string<->op definitions for new opcodes
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants