Resolve harmony-one/bounties#77: Staking precompiles (#3906)
* Resolve harmony-one/bounties#77: Staking precompiles
Create write capable precompiles that can perform staking transactions
Add hard fork logic (EpochTBD) for these precompiles
Tests for new code with at least 80% unit test coverage
Staking library + tests in MaxMustermann2/harmony-staking-precompiles
* Fix small typo in comment
* Run goimports on files to fix Travis
* Do not activate staking precompile on shard 0
* Cascade readOnly to WriteCapableContract
* No overlap in readOnly + writeCapable precompiles
* Use function selector instead of directive
From Solidity, use abi.encodeWithSelector and match it against the
exact ABI of the functions. This allows us to remove the need for
a directive (32) being encoded, and thus saves 28 bytes of data.
* Do not allow contracts to become validators
As discussed with Jacky on #3906
* Merge harmony-one/harmony/main properly this time
* Run goimports
* Update gas calculation for staking precompile
Please see comment in core/vm/contracts_write.go RequiredGas
* Do not allow contract to become validator (2/2)
* Cache StakeMsgs from precompiled transactions
Add the StakeMsgs to ProcessorResult and cascade them in insertChain
* Remove ContractCode fields from validators
Since smart contracts can no longer beecome validators,
this field is superfluous. Remove it from the Wrapper
structure, and do not assign it a value when creating
a validator. Build and goimports checked
* Update comments in response to feedback
(1) Comments to start with function names
(2) Comments for public variables
(3) Comment to match function name RunPrecompiledContract
(4) Clarify that CreateValidatorFunc + EditValidatorFunc are still used
* Fix Travis build by reverting rosetta change
* Add revert capability to 3 staking tx types
- Delegate
- Undelegate
- CollectRewards
* Fix build: Update evm_test for ValidatorWrapper
* Merge main into harmony-staking-precompiles
* Add gas for precompile calls and allow EOA usage
- Each time the precompile is called, charge the base gas fee plus data
cost (if data can be parsed successfully). A gas fee is added to
prevent benevolent contract deployers from subsidizing the staking
transactions for EOAs through repeated assembly `delegatecall`.
- Allow EOAs to use the staking precompile directly. Some changes to
the Solidity library are associated with this change.
- Remove bytes from parsing address, since the ABI unpacks it into an
address format correctly.
- Add or update tests. Test coverage report to be attached to the PR
shortly.
* Run goimports
* Check read only and write capable for overlap
* Handle precompile stakeMsgs for block proposer
The staking precompile generates staking messages which are cascaded to
the block via the EVM in `state_processor.go`. This change cascades them
in `worker.go` to allow block proposers and block verifiers to keep the
same state.
* Run goimports for cf2dfac4081444e36a120c9432f4e..
* Update staking precompile epoch to 2 for localnet
Bring it in line with staking epoch. Change effects all configurations
except mainnet and testnet. `goimports` included.
* Add read only precompile to fetch the epoch num
* Move epoch precompile to 250
* precompiles: left pad the returned epoch number
* chainConfig: check epochs for precompiles
panic if staking precompile epoch < pre staking epoch
* Add staking migration precompile
- Lives at address 251
- Migrates delegations + pending undelegations from address A to B
- Useful if address A is hacked
- Charges gas of 21k + cost of bytes for two addresses
- Does not remove existing delegations, just sets them to zero.
Replicates current undelegate setup
- Unit tests and `goimports` included. Integration test following
shortly in MaxMustermann2/harmony-staking-precompiles
* Migration precompile: merge into staking
Merge the two precompiles into one, add gas calculation for migration
precompile. Move epoch precompile to 251 as a result. When migrating,
add undelegations to `To`'s existing undelegations, if any match the
epoch.
* Add migration gas test, remove panic, add check
In response to review comments, add tests for migration gas wherein
there are 0/1/2 delegations to migrate. Add the index out of bound check
to migration gas calculator and remove panics. Lastly, re-sort
migrated undelegations if no existing undelegation in the same epoch was
found on `To`.
* Move undelegations sorting to end of loop
3 years ago
|
|
|
package vm
|
|
|
|
|
|
|
|
import (
|
|
|
|
"errors"
|
|
|
|
"math/big"
|
|
|
|
"strings"
|
|
|
|
|
Resolve harmony-one/bounties#77: Staking precompiles (#3906)
* Resolve harmony-one/bounties#77: Staking precompiles
Create write capable precompiles that can perform staking transactions
Add hard fork logic (EpochTBD) for these precompiles
Tests for new code with at least 80% unit test coverage
Staking library + tests in MaxMustermann2/harmony-staking-precompiles
* Fix small typo in comment
* Run goimports on files to fix Travis
* Do not activate staking precompile on shard 0
* Cascade readOnly to WriteCapableContract
* No overlap in readOnly + writeCapable precompiles
* Use function selector instead of directive
From Solidity, use abi.encodeWithSelector and match it against the
exact ABI of the functions. This allows us to remove the need for
a directive (32) being encoded, and thus saves 28 bytes of data.
* Do not allow contracts to become validators
As discussed with Jacky on #3906
* Merge harmony-one/harmony/main properly this time
* Run goimports
* Update gas calculation for staking precompile
Please see comment in core/vm/contracts_write.go RequiredGas
* Do not allow contract to become validator (2/2)
* Cache StakeMsgs from precompiled transactions
Add the StakeMsgs to ProcessorResult and cascade them in insertChain
* Remove ContractCode fields from validators
Since smart contracts can no longer beecome validators,
this field is superfluous. Remove it from the Wrapper
structure, and do not assign it a value when creating
a validator. Build and goimports checked
* Update comments in response to feedback
(1) Comments to start with function names
(2) Comments for public variables
(3) Comment to match function name RunPrecompiledContract
(4) Clarify that CreateValidatorFunc + EditValidatorFunc are still used
* Fix Travis build by reverting rosetta change
* Add revert capability to 3 staking tx types
- Delegate
- Undelegate
- CollectRewards
* Fix build: Update evm_test for ValidatorWrapper
* Merge main into harmony-staking-precompiles
* Add gas for precompile calls and allow EOA usage
- Each time the precompile is called, charge the base gas fee plus data
cost (if data can be parsed successfully). A gas fee is added to
prevent benevolent contract deployers from subsidizing the staking
transactions for EOAs through repeated assembly `delegatecall`.
- Allow EOAs to use the staking precompile directly. Some changes to
the Solidity library are associated with this change.
- Remove bytes from parsing address, since the ABI unpacks it into an
address format correctly.
- Add or update tests. Test coverage report to be attached to the PR
shortly.
* Run goimports
* Check read only and write capable for overlap
* Handle precompile stakeMsgs for block proposer
The staking precompile generates staking messages which are cascaded to
the block via the EVM in `state_processor.go`. This change cascades them
in `worker.go` to allow block proposers and block verifiers to keep the
same state.
* Run goimports for cf2dfac4081444e36a120c9432f4e..
* Update staking precompile epoch to 2 for localnet
Bring it in line with staking epoch. Change effects all configurations
except mainnet and testnet. `goimports` included.
* Add read only precompile to fetch the epoch num
* Move epoch precompile to 250
* precompiles: left pad the returned epoch number
* chainConfig: check epochs for precompiles
panic if staking precompile epoch < pre staking epoch
* Add staking migration precompile
- Lives at address 251
- Migrates delegations + pending undelegations from address A to B
- Useful if address A is hacked
- Charges gas of 21k + cost of bytes for two addresses
- Does not remove existing delegations, just sets them to zero.
Replicates current undelegate setup
- Unit tests and `goimports` included. Integration test following
shortly in MaxMustermann2/harmony-staking-precompiles
* Migration precompile: merge into staking
Merge the two precompiles into one, add gas calculation for migration
precompile. Move epoch precompile to 251 as a result. When migrating,
add undelegations to `To`'s existing undelegations, if any match the
epoch.
* Add migration gas test, remove panic, add check
In response to review comments, add tests for migration gas wherein
there are 0/1/2 delegations to migrate. Add the index out of bound check
to migration gas calculator and remove panics. Lastly, re-sort
migrated undelegations if no existing undelegation in the same epoch was
found on `To`.
* Move undelegations sorting to end of loop
3 years ago
|
|
|
"github.com/ethereum/go-ethereum/common"
|
|
|
|
"github.com/ethereum/go-ethereum/rlp"
|
|
|
|
"github.com/harmony-one/harmony/accounts/abi"
|
|
|
|
"github.com/harmony-one/harmony/core/types"
|
Resolve harmony-one/bounties#77: Staking precompiles (#3906)
* Resolve harmony-one/bounties#77: Staking precompiles
Create write capable precompiles that can perform staking transactions
Add hard fork logic (EpochTBD) for these precompiles
Tests for new code with at least 80% unit test coverage
Staking library + tests in MaxMustermann2/harmony-staking-precompiles
* Fix small typo in comment
* Run goimports on files to fix Travis
* Do not activate staking precompile on shard 0
* Cascade readOnly to WriteCapableContract
* No overlap in readOnly + writeCapable precompiles
* Use function selector instead of directive
From Solidity, use abi.encodeWithSelector and match it against the
exact ABI of the functions. This allows us to remove the need for
a directive (32) being encoded, and thus saves 28 bytes of data.
* Do not allow contracts to become validators
As discussed with Jacky on #3906
* Merge harmony-one/harmony/main properly this time
* Run goimports
* Update gas calculation for staking precompile
Please see comment in core/vm/contracts_write.go RequiredGas
* Do not allow contract to become validator (2/2)
* Cache StakeMsgs from precompiled transactions
Add the StakeMsgs to ProcessorResult and cascade them in insertChain
* Remove ContractCode fields from validators
Since smart contracts can no longer beecome validators,
this field is superfluous. Remove it from the Wrapper
structure, and do not assign it a value when creating
a validator. Build and goimports checked
* Update comments in response to feedback
(1) Comments to start with function names
(2) Comments for public variables
(3) Comment to match function name RunPrecompiledContract
(4) Clarify that CreateValidatorFunc + EditValidatorFunc are still used
* Fix Travis build by reverting rosetta change
* Add revert capability to 3 staking tx types
- Delegate
- Undelegate
- CollectRewards
* Fix build: Update evm_test for ValidatorWrapper
* Merge main into harmony-staking-precompiles
* Add gas for precompile calls and allow EOA usage
- Each time the precompile is called, charge the base gas fee plus data
cost (if data can be parsed successfully). A gas fee is added to
prevent benevolent contract deployers from subsidizing the staking
transactions for EOAs through repeated assembly `delegatecall`.
- Allow EOAs to use the staking precompile directly. Some changes to
the Solidity library are associated with this change.
- Remove bytes from parsing address, since the ABI unpacks it into an
address format correctly.
- Add or update tests. Test coverage report to be attached to the PR
shortly.
* Run goimports
* Check read only and write capable for overlap
* Handle precompile stakeMsgs for block proposer
The staking precompile generates staking messages which are cascaded to
the block via the EVM in `state_processor.go`. This change cascades them
in `worker.go` to allow block proposers and block verifiers to keep the
same state.
* Run goimports for cf2dfac4081444e36a120c9432f4e..
* Update staking precompile epoch to 2 for localnet
Bring it in line with staking epoch. Change effects all configurations
except mainnet and testnet. `goimports` included.
* Add read only precompile to fetch the epoch num
* Move epoch precompile to 250
* precompiles: left pad the returned epoch number
* chainConfig: check epochs for precompiles
panic if staking precompile epoch < pre staking epoch
* Add staking migration precompile
- Lives at address 251
- Migrates delegations + pending undelegations from address A to B
- Useful if address A is hacked
- Charges gas of 21k + cost of bytes for two addresses
- Does not remove existing delegations, just sets them to zero.
Replicates current undelegate setup
- Unit tests and `goimports` included. Integration test following
shortly in MaxMustermann2/harmony-staking-precompiles
* Migration precompile: merge into staking
Merge the two precompiles into one, add gas calculation for migration
precompile. Move epoch precompile to 251 as a result. When migrating,
add undelegations to `To`'s existing undelegations, if any match the
epoch.
* Add migration gas test, remove panic, add check
In response to review comments, add tests for migration gas wherein
there are 0/1/2 delegations to migrate. Add the index out of bound check
to migration gas calculator and remove panics. Lastly, re-sort
migrated undelegations if no existing undelegation in the same epoch was
found on `To`.
* Move undelegations sorting to end of loop
3 years ago
|
|
|
"github.com/harmony-one/harmony/shard"
|
|
|
|
"github.com/harmony-one/harmony/staking"
|
|
|
|
stakingTypes "github.com/harmony-one/harmony/staking/types"
|
|
|
|
)
|
|
|
|
|
|
|
|
// WriteCapablePrecompiledContractsStaking lists out the write capable precompiled contracts
|
|
|
|
// which are available after the StakingPrecompileEpoch
|
|
|
|
// for now, we have only one contract at 252 or 0xfc - which is the staking precompile
|
|
|
|
var WriteCapablePrecompiledContractsStaking = map[common.Address]WriteCapablePrecompiledContract{
|
|
|
|
common.BytesToAddress([]byte{252}): &stakingPrecompile{},
|
|
|
|
}
|
|
|
|
|
|
|
|
// WriteCapablePrecompiledContractsCrossXfer lists out the write capable precompiled contracts
|
|
|
|
// which are available after the CrossShardXferPrecompileEpoch
|
|
|
|
// It includes the staking precompile and the cross-shard transfer precompile
|
|
|
|
var WriteCapablePrecompiledContractsCrossXfer = map[common.Address]WriteCapablePrecompiledContract{
|
|
|
|
// reserve 250 for read only staking precompile and 251 for epoch
|
|
|
|
common.BytesToAddress([]byte{249}): &crossShardXferPrecompile{},
|
|
|
|
common.BytesToAddress([]byte{252}): &stakingPrecompile{},
|
|
|
|
}
|
|
|
|
|
Resolve harmony-one/bounties#77: Staking precompiles (#3906)
* Resolve harmony-one/bounties#77: Staking precompiles
Create write capable precompiles that can perform staking transactions
Add hard fork logic (EpochTBD) for these precompiles
Tests for new code with at least 80% unit test coverage
Staking library + tests in MaxMustermann2/harmony-staking-precompiles
* Fix small typo in comment
* Run goimports on files to fix Travis
* Do not activate staking precompile on shard 0
* Cascade readOnly to WriteCapableContract
* No overlap in readOnly + writeCapable precompiles
* Use function selector instead of directive
From Solidity, use abi.encodeWithSelector and match it against the
exact ABI of the functions. This allows us to remove the need for
a directive (32) being encoded, and thus saves 28 bytes of data.
* Do not allow contracts to become validators
As discussed with Jacky on #3906
* Merge harmony-one/harmony/main properly this time
* Run goimports
* Update gas calculation for staking precompile
Please see comment in core/vm/contracts_write.go RequiredGas
* Do not allow contract to become validator (2/2)
* Cache StakeMsgs from precompiled transactions
Add the StakeMsgs to ProcessorResult and cascade them in insertChain
* Remove ContractCode fields from validators
Since smart contracts can no longer beecome validators,
this field is superfluous. Remove it from the Wrapper
structure, and do not assign it a value when creating
a validator. Build and goimports checked
* Update comments in response to feedback
(1) Comments to start with function names
(2) Comments for public variables
(3) Comment to match function name RunPrecompiledContract
(4) Clarify that CreateValidatorFunc + EditValidatorFunc are still used
* Fix Travis build by reverting rosetta change
* Add revert capability to 3 staking tx types
- Delegate
- Undelegate
- CollectRewards
* Fix build: Update evm_test for ValidatorWrapper
* Merge main into harmony-staking-precompiles
* Add gas for precompile calls and allow EOA usage
- Each time the precompile is called, charge the base gas fee plus data
cost (if data can be parsed successfully). A gas fee is added to
prevent benevolent contract deployers from subsidizing the staking
transactions for EOAs through repeated assembly `delegatecall`.
- Allow EOAs to use the staking precompile directly. Some changes to
the Solidity library are associated with this change.
- Remove bytes from parsing address, since the ABI unpacks it into an
address format correctly.
- Add or update tests. Test coverage report to be attached to the PR
shortly.
* Run goimports
* Check read only and write capable for overlap
* Handle precompile stakeMsgs for block proposer
The staking precompile generates staking messages which are cascaded to
the block via the EVM in `state_processor.go`. This change cascades them
in `worker.go` to allow block proposers and block verifiers to keep the
same state.
* Run goimports for cf2dfac4081444e36a120c9432f4e..
* Update staking precompile epoch to 2 for localnet
Bring it in line with staking epoch. Change effects all configurations
except mainnet and testnet. `goimports` included.
* Add read only precompile to fetch the epoch num
* Move epoch precompile to 250
* precompiles: left pad the returned epoch number
* chainConfig: check epochs for precompiles
panic if staking precompile epoch < pre staking epoch
* Add staking migration precompile
- Lives at address 251
- Migrates delegations + pending undelegations from address A to B
- Useful if address A is hacked
- Charges gas of 21k + cost of bytes for two addresses
- Does not remove existing delegations, just sets them to zero.
Replicates current undelegate setup
- Unit tests and `goimports` included. Integration test following
shortly in MaxMustermann2/harmony-staking-precompiles
* Migration precompile: merge into staking
Merge the two precompiles into one, add gas calculation for migration
precompile. Move epoch precompile to 251 as a result. When migrating,
add undelegations to `To`'s existing undelegations, if any match the
epoch.
* Add migration gas test, remove panic, add check
In response to review comments, add tests for migration gas wherein
there are 0/1/2 delegations to migrate. Add the index out of bound check
to migration gas calculator and remove panics. Lastly, re-sort
migrated undelegations if no existing undelegation in the same epoch was
found on `To`.
* Move undelegations sorting to end of loop
3 years ago
|
|
|
// WriteCapablePrecompiledContract represents the interface for Native Go contracts
|
|
|
|
// which are available as a precompile in the EVM
|
|
|
|
// As with (read-only) PrecompiledContracts, these need a RequiredGas function
|
|
|
|
// Note that these contracts have the capability to alter the state
|
|
|
|
// while those in contracts.go do not
|
|
|
|
type WriteCapablePrecompiledContract interface {
|
|
|
|
// RequiredGas calculates the contract gas use
|
|
|
|
RequiredGas(evm *EVM, contract *Contract, input []byte) (uint64, error)
|
|
|
|
// use a different name from read-only contracts to be safe
|
|
|
|
RunWriteCapable(evm *EVM, contract *Contract, input []byte) ([]byte, error)
|
Resolve harmony-one/bounties#77: Staking precompiles (#3906)
* Resolve harmony-one/bounties#77: Staking precompiles
Create write capable precompiles that can perform staking transactions
Add hard fork logic (EpochTBD) for these precompiles
Tests for new code with at least 80% unit test coverage
Staking library + tests in MaxMustermann2/harmony-staking-precompiles
* Fix small typo in comment
* Run goimports on files to fix Travis
* Do not activate staking precompile on shard 0
* Cascade readOnly to WriteCapableContract
* No overlap in readOnly + writeCapable precompiles
* Use function selector instead of directive
From Solidity, use abi.encodeWithSelector and match it against the
exact ABI of the functions. This allows us to remove the need for
a directive (32) being encoded, and thus saves 28 bytes of data.
* Do not allow contracts to become validators
As discussed with Jacky on #3906
* Merge harmony-one/harmony/main properly this time
* Run goimports
* Update gas calculation for staking precompile
Please see comment in core/vm/contracts_write.go RequiredGas
* Do not allow contract to become validator (2/2)
* Cache StakeMsgs from precompiled transactions
Add the StakeMsgs to ProcessorResult and cascade them in insertChain
* Remove ContractCode fields from validators
Since smart contracts can no longer beecome validators,
this field is superfluous. Remove it from the Wrapper
structure, and do not assign it a value when creating
a validator. Build and goimports checked
* Update comments in response to feedback
(1) Comments to start with function names
(2) Comments for public variables
(3) Comment to match function name RunPrecompiledContract
(4) Clarify that CreateValidatorFunc + EditValidatorFunc are still used
* Fix Travis build by reverting rosetta change
* Add revert capability to 3 staking tx types
- Delegate
- Undelegate
- CollectRewards
* Fix build: Update evm_test for ValidatorWrapper
* Merge main into harmony-staking-precompiles
* Add gas for precompile calls and allow EOA usage
- Each time the precompile is called, charge the base gas fee plus data
cost (if data can be parsed successfully). A gas fee is added to
prevent benevolent contract deployers from subsidizing the staking
transactions for EOAs through repeated assembly `delegatecall`.
- Allow EOAs to use the staking precompile directly. Some changes to
the Solidity library are associated with this change.
- Remove bytes from parsing address, since the ABI unpacks it into an
address format correctly.
- Add or update tests. Test coverage report to be attached to the PR
shortly.
* Run goimports
* Check read only and write capable for overlap
* Handle precompile stakeMsgs for block proposer
The staking precompile generates staking messages which are cascaded to
the block via the EVM in `state_processor.go`. This change cascades them
in `worker.go` to allow block proposers and block verifiers to keep the
same state.
* Run goimports for cf2dfac4081444e36a120c9432f4e..
* Update staking precompile epoch to 2 for localnet
Bring it in line with staking epoch. Change effects all configurations
except mainnet and testnet. `goimports` included.
* Add read only precompile to fetch the epoch num
* Move epoch precompile to 250
* precompiles: left pad the returned epoch number
* chainConfig: check epochs for precompiles
panic if staking precompile epoch < pre staking epoch
* Add staking migration precompile
- Lives at address 251
- Migrates delegations + pending undelegations from address A to B
- Useful if address A is hacked
- Charges gas of 21k + cost of bytes for two addresses
- Does not remove existing delegations, just sets them to zero.
Replicates current undelegate setup
- Unit tests and `goimports` included. Integration test following
shortly in MaxMustermann2/harmony-staking-precompiles
* Migration precompile: merge into staking
Merge the two precompiles into one, add gas calculation for migration
precompile. Move epoch precompile to 251 as a result. When migrating,
add undelegations to `To`'s existing undelegations, if any match the
epoch.
* Add migration gas test, remove panic, add check
In response to review comments, add tests for migration gas wherein
there are 0/1/2 delegations to migrate. Add the index out of bound check
to migration gas calculator and remove panics. Lastly, re-sort
migrated undelegations if no existing undelegation in the same epoch was
found on `To`.
* Move undelegations sorting to end of loop
3 years ago
|
|
|
}
|
|
|
|
|
|
|
|
// RunWriteCapablePrecompiledContract runs and evaluates the output of a write capable precompiled contract.
|
|
|
|
func RunWriteCapablePrecompiledContract(
|
|
|
|
p WriteCapablePrecompiledContract,
|
|
|
|
evm *EVM,
|
|
|
|
contract *Contract,
|
|
|
|
input []byte,
|
|
|
|
readOnly bool,
|
|
|
|
) ([]byte, error) {
|
|
|
|
// immediately error out if readOnly
|
|
|
|
if readOnly {
|
|
|
|
return nil, errWriteProtection
|
|
|
|
}
|
|
|
|
gas, err := p.RequiredGas(evm, contract, input)
|
|
|
|
if err != nil {
|
|
|
|
return nil, err
|
|
|
|
}
|
|
|
|
if !contract.UseGas(gas) {
|
|
|
|
return nil, ErrOutOfGas
|
|
|
|
}
|
|
|
|
return p.RunWriteCapable(evm, contract, input)
|
Resolve harmony-one/bounties#77: Staking precompiles (#3906)
* Resolve harmony-one/bounties#77: Staking precompiles
Create write capable precompiles that can perform staking transactions
Add hard fork logic (EpochTBD) for these precompiles
Tests for new code with at least 80% unit test coverage
Staking library + tests in MaxMustermann2/harmony-staking-precompiles
* Fix small typo in comment
* Run goimports on files to fix Travis
* Do not activate staking precompile on shard 0
* Cascade readOnly to WriteCapableContract
* No overlap in readOnly + writeCapable precompiles
* Use function selector instead of directive
From Solidity, use abi.encodeWithSelector and match it against the
exact ABI of the functions. This allows us to remove the need for
a directive (32) being encoded, and thus saves 28 bytes of data.
* Do not allow contracts to become validators
As discussed with Jacky on #3906
* Merge harmony-one/harmony/main properly this time
* Run goimports
* Update gas calculation for staking precompile
Please see comment in core/vm/contracts_write.go RequiredGas
* Do not allow contract to become validator (2/2)
* Cache StakeMsgs from precompiled transactions
Add the StakeMsgs to ProcessorResult and cascade them in insertChain
* Remove ContractCode fields from validators
Since smart contracts can no longer beecome validators,
this field is superfluous. Remove it from the Wrapper
structure, and do not assign it a value when creating
a validator. Build and goimports checked
* Update comments in response to feedback
(1) Comments to start with function names
(2) Comments for public variables
(3) Comment to match function name RunPrecompiledContract
(4) Clarify that CreateValidatorFunc + EditValidatorFunc are still used
* Fix Travis build by reverting rosetta change
* Add revert capability to 3 staking tx types
- Delegate
- Undelegate
- CollectRewards
* Fix build: Update evm_test for ValidatorWrapper
* Merge main into harmony-staking-precompiles
* Add gas for precompile calls and allow EOA usage
- Each time the precompile is called, charge the base gas fee plus data
cost (if data can be parsed successfully). A gas fee is added to
prevent benevolent contract deployers from subsidizing the staking
transactions for EOAs through repeated assembly `delegatecall`.
- Allow EOAs to use the staking precompile directly. Some changes to
the Solidity library are associated with this change.
- Remove bytes from parsing address, since the ABI unpacks it into an
address format correctly.
- Add or update tests. Test coverage report to be attached to the PR
shortly.
* Run goimports
* Check read only and write capable for overlap
* Handle precompile stakeMsgs for block proposer
The staking precompile generates staking messages which are cascaded to
the block via the EVM in `state_processor.go`. This change cascades them
in `worker.go` to allow block proposers and block verifiers to keep the
same state.
* Run goimports for cf2dfac4081444e36a120c9432f4e..
* Update staking precompile epoch to 2 for localnet
Bring it in line with staking epoch. Change effects all configurations
except mainnet and testnet. `goimports` included.
* Add read only precompile to fetch the epoch num
* Move epoch precompile to 250
* precompiles: left pad the returned epoch number
* chainConfig: check epochs for precompiles
panic if staking precompile epoch < pre staking epoch
* Add staking migration precompile
- Lives at address 251
- Migrates delegations + pending undelegations from address A to B
- Useful if address A is hacked
- Charges gas of 21k + cost of bytes for two addresses
- Does not remove existing delegations, just sets them to zero.
Replicates current undelegate setup
- Unit tests and `goimports` included. Integration test following
shortly in MaxMustermann2/harmony-staking-precompiles
* Migration precompile: merge into staking
Merge the two precompiles into one, add gas calculation for migration
precompile. Move epoch precompile to 251 as a result. When migrating,
add undelegations to `To`'s existing undelegations, if any match the
epoch.
* Add migration gas test, remove panic, add check
In response to review comments, add tests for migration gas wherein
there are 0/1/2 delegations to migrate. Add the index out of bound check
to migration gas calculator and remove panics. Lastly, re-sort
migrated undelegations if no existing undelegation in the same epoch was
found on `To`.
* Move undelegations sorting to end of loop
3 years ago
|
|
|
}
|
|
|
|
|
|
|
|
type stakingPrecompile struct{}
|
|
|
|
|
|
|
|
// RequiredGas returns the gas required to execute the pre-compiled contract.
|
|
|
|
//
|
|
|
|
// This method does not require any overflow checking as the input size gas costs
|
|
|
|
// required for anything significant is so high it's impossible to pay for.
|
|
|
|
func (c *stakingPrecompile) RequiredGas(
|
|
|
|
evm *EVM,
|
|
|
|
contract *Contract,
|
|
|
|
input []byte,
|
|
|
|
) (uint64, error) {
|
|
|
|
// if invalid data or invalid shard
|
|
|
|
// set payload to blank and charge minimum gas
|
|
|
|
var payload []byte = make([]byte, 0)
|
|
|
|
// availability of staking and precompile has already been checked
|
|
|
|
if evm.Context.ShardID == shard.BeaconChainShardID {
|
|
|
|
// check that input is well formed
|
|
|
|
// meaning all the expected parameters are available
|
|
|
|
// and that we are only trying to perform staking tx
|
|
|
|
// on behalf of the correct entity
|
|
|
|
stakeMsg, err := staking.ParseStakeMsg(contract.Caller(), input)
|
|
|
|
if err == nil {
|
|
|
|
// otherwise charge similar to a regular staking tx
|
|
|
|
if migrationMsg, ok := stakeMsg.(*stakingTypes.MigrationMsg); ok {
|
|
|
|
// charge per delegation to migrate
|
|
|
|
return evm.CalculateMigrationGas(evm.StateDB,
|
|
|
|
migrationMsg,
|
|
|
|
evm.ChainConfig().IsS3(evm.EpochNumber),
|
|
|
|
evm.ChainConfig().IsIstanbul(evm.EpochNumber),
|
|
|
|
)
|
|
|
|
} else if encoded, err := rlp.EncodeToBytes(stakeMsg); err == nil {
|
|
|
|
payload = encoded
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
if gas, err := IntrinsicGas(
|
|
|
|
payload,
|
|
|
|
false, // contractCreation
|
|
|
|
evm.ChainConfig().IsS3(evm.EpochNumber), // homestead
|
|
|
|
evm.ChainConfig().IsIstanbul(evm.EpochNumber), // istanbul
|
|
|
|
false, // isValidatorCreation
|
|
|
|
); err != nil {
|
|
|
|
return 0, err // ErrOutOfGas occurs when gas payable > uint64
|
|
|
|
} else {
|
|
|
|
return gas, nil
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
// RunWriteCapable runs the actual contract (that is it performs the staking)
|
|
|
|
func (c *stakingPrecompile) RunWriteCapable(
|
|
|
|
evm *EVM,
|
|
|
|
contract *Contract,
|
|
|
|
input []byte,
|
|
|
|
) ([]byte, error) {
|
|
|
|
if evm.Context.ShardID != shard.BeaconChainShardID {
|
|
|
|
return nil, errors.New("Staking not supported on this shard")
|
|
|
|
}
|
|
|
|
stakeMsg, err := staking.ParseStakeMsg(contract.Caller(), input)
|
|
|
|
if err != nil {
|
|
|
|
return nil, err
|
|
|
|
}
|
|
|
|
|
|
|
|
var rosettaBlockTracer RosettaTracer
|
|
|
|
if tmpTracker, ok := evm.vmConfig.Tracer.(RosettaTracer); ok {
|
|
|
|
rosettaBlockTracer = tmpTracker
|
|
|
|
}
|
|
|
|
|
Resolve harmony-one/bounties#77: Staking precompiles (#3906)
* Resolve harmony-one/bounties#77: Staking precompiles
Create write capable precompiles that can perform staking transactions
Add hard fork logic (EpochTBD) for these precompiles
Tests for new code with at least 80% unit test coverage
Staking library + tests in MaxMustermann2/harmony-staking-precompiles
* Fix small typo in comment
* Run goimports on files to fix Travis
* Do not activate staking precompile on shard 0
* Cascade readOnly to WriteCapableContract
* No overlap in readOnly + writeCapable precompiles
* Use function selector instead of directive
From Solidity, use abi.encodeWithSelector and match it against the
exact ABI of the functions. This allows us to remove the need for
a directive (32) being encoded, and thus saves 28 bytes of data.
* Do not allow contracts to become validators
As discussed with Jacky on #3906
* Merge harmony-one/harmony/main properly this time
* Run goimports
* Update gas calculation for staking precompile
Please see comment in core/vm/contracts_write.go RequiredGas
* Do not allow contract to become validator (2/2)
* Cache StakeMsgs from precompiled transactions
Add the StakeMsgs to ProcessorResult and cascade them in insertChain
* Remove ContractCode fields from validators
Since smart contracts can no longer beecome validators,
this field is superfluous. Remove it from the Wrapper
structure, and do not assign it a value when creating
a validator. Build and goimports checked
* Update comments in response to feedback
(1) Comments to start with function names
(2) Comments for public variables
(3) Comment to match function name RunPrecompiledContract
(4) Clarify that CreateValidatorFunc + EditValidatorFunc are still used
* Fix Travis build by reverting rosetta change
* Add revert capability to 3 staking tx types
- Delegate
- Undelegate
- CollectRewards
* Fix build: Update evm_test for ValidatorWrapper
* Merge main into harmony-staking-precompiles
* Add gas for precompile calls and allow EOA usage
- Each time the precompile is called, charge the base gas fee plus data
cost (if data can be parsed successfully). A gas fee is added to
prevent benevolent contract deployers from subsidizing the staking
transactions for EOAs through repeated assembly `delegatecall`.
- Allow EOAs to use the staking precompile directly. Some changes to
the Solidity library are associated with this change.
- Remove bytes from parsing address, since the ABI unpacks it into an
address format correctly.
- Add or update tests. Test coverage report to be attached to the PR
shortly.
* Run goimports
* Check read only and write capable for overlap
* Handle precompile stakeMsgs for block proposer
The staking precompile generates staking messages which are cascaded to
the block via the EVM in `state_processor.go`. This change cascades them
in `worker.go` to allow block proposers and block verifiers to keep the
same state.
* Run goimports for cf2dfac4081444e36a120c9432f4e..
* Update staking precompile epoch to 2 for localnet
Bring it in line with staking epoch. Change effects all configurations
except mainnet and testnet. `goimports` included.
* Add read only precompile to fetch the epoch num
* Move epoch precompile to 250
* precompiles: left pad the returned epoch number
* chainConfig: check epochs for precompiles
panic if staking precompile epoch < pre staking epoch
* Add staking migration precompile
- Lives at address 251
- Migrates delegations + pending undelegations from address A to B
- Useful if address A is hacked
- Charges gas of 21k + cost of bytes for two addresses
- Does not remove existing delegations, just sets them to zero.
Replicates current undelegate setup
- Unit tests and `goimports` included. Integration test following
shortly in MaxMustermann2/harmony-staking-precompiles
* Migration precompile: merge into staking
Merge the two precompiles into one, add gas calculation for migration
precompile. Move epoch precompile to 251 as a result. When migrating,
add undelegations to `To`'s existing undelegations, if any match the
epoch.
* Add migration gas test, remove panic, add check
In response to review comments, add tests for migration gas wherein
there are 0/1/2 delegations to migrate. Add the index out of bound check
to migration gas calculator and remove panics. Lastly, re-sort
migrated undelegations if no existing undelegation in the same epoch was
found on `To`.
* Move undelegations sorting to end of loop
3 years ago
|
|
|
if delegate, ok := stakeMsg.(*stakingTypes.Delegate); ok {
|
|
|
|
if err := evm.Delegate(evm.StateDB, rosettaBlockTracer, delegate); err != nil {
|
Resolve harmony-one/bounties#77: Staking precompiles (#3906)
* Resolve harmony-one/bounties#77: Staking precompiles
Create write capable precompiles that can perform staking transactions
Add hard fork logic (EpochTBD) for these precompiles
Tests for new code with at least 80% unit test coverage
Staking library + tests in MaxMustermann2/harmony-staking-precompiles
* Fix small typo in comment
* Run goimports on files to fix Travis
* Do not activate staking precompile on shard 0
* Cascade readOnly to WriteCapableContract
* No overlap in readOnly + writeCapable precompiles
* Use function selector instead of directive
From Solidity, use abi.encodeWithSelector and match it against the
exact ABI of the functions. This allows us to remove the need for
a directive (32) being encoded, and thus saves 28 bytes of data.
* Do not allow contracts to become validators
As discussed with Jacky on #3906
* Merge harmony-one/harmony/main properly this time
* Run goimports
* Update gas calculation for staking precompile
Please see comment in core/vm/contracts_write.go RequiredGas
* Do not allow contract to become validator (2/2)
* Cache StakeMsgs from precompiled transactions
Add the StakeMsgs to ProcessorResult and cascade them in insertChain
* Remove ContractCode fields from validators
Since smart contracts can no longer beecome validators,
this field is superfluous. Remove it from the Wrapper
structure, and do not assign it a value when creating
a validator. Build and goimports checked
* Update comments in response to feedback
(1) Comments to start with function names
(2) Comments for public variables
(3) Comment to match function name RunPrecompiledContract
(4) Clarify that CreateValidatorFunc + EditValidatorFunc are still used
* Fix Travis build by reverting rosetta change
* Add revert capability to 3 staking tx types
- Delegate
- Undelegate
- CollectRewards
* Fix build: Update evm_test for ValidatorWrapper
* Merge main into harmony-staking-precompiles
* Add gas for precompile calls and allow EOA usage
- Each time the precompile is called, charge the base gas fee plus data
cost (if data can be parsed successfully). A gas fee is added to
prevent benevolent contract deployers from subsidizing the staking
transactions for EOAs through repeated assembly `delegatecall`.
- Allow EOAs to use the staking precompile directly. Some changes to
the Solidity library are associated with this change.
- Remove bytes from parsing address, since the ABI unpacks it into an
address format correctly.
- Add or update tests. Test coverage report to be attached to the PR
shortly.
* Run goimports
* Check read only and write capable for overlap
* Handle precompile stakeMsgs for block proposer
The staking precompile generates staking messages which are cascaded to
the block via the EVM in `state_processor.go`. This change cascades them
in `worker.go` to allow block proposers and block verifiers to keep the
same state.
* Run goimports for cf2dfac4081444e36a120c9432f4e..
* Update staking precompile epoch to 2 for localnet
Bring it in line with staking epoch. Change effects all configurations
except mainnet and testnet. `goimports` included.
* Add read only precompile to fetch the epoch num
* Move epoch precompile to 250
* precompiles: left pad the returned epoch number
* chainConfig: check epochs for precompiles
panic if staking precompile epoch < pre staking epoch
* Add staking migration precompile
- Lives at address 251
- Migrates delegations + pending undelegations from address A to B
- Useful if address A is hacked
- Charges gas of 21k + cost of bytes for two addresses
- Does not remove existing delegations, just sets them to zero.
Replicates current undelegate setup
- Unit tests and `goimports` included. Integration test following
shortly in MaxMustermann2/harmony-staking-precompiles
* Migration precompile: merge into staking
Merge the two precompiles into one, add gas calculation for migration
precompile. Move epoch precompile to 251 as a result. When migrating,
add undelegations to `To`'s existing undelegations, if any match the
epoch.
* Add migration gas test, remove panic, add check
In response to review comments, add tests for migration gas wherein
there are 0/1/2 delegations to migrate. Add the index out of bound check
to migration gas calculator and remove panics. Lastly, re-sort
migrated undelegations if no existing undelegation in the same epoch was
found on `To`.
* Move undelegations sorting to end of loop
3 years ago
|
|
|
return nil, err
|
|
|
|
} else {
|
|
|
|
evm.StakeMsgs = append(evm.StakeMsgs, delegate)
|
|
|
|
return nil, nil
|
|
|
|
}
|
|
|
|
}
|
|
|
|
if undelegate, ok := stakeMsg.(*stakingTypes.Undelegate); ok {
|
|
|
|
return nil, evm.Undelegate(evm.StateDB, rosettaBlockTracer, undelegate)
|
Resolve harmony-one/bounties#77: Staking precompiles (#3906)
* Resolve harmony-one/bounties#77: Staking precompiles
Create write capable precompiles that can perform staking transactions
Add hard fork logic (EpochTBD) for these precompiles
Tests for new code with at least 80% unit test coverage
Staking library + tests in MaxMustermann2/harmony-staking-precompiles
* Fix small typo in comment
* Run goimports on files to fix Travis
* Do not activate staking precompile on shard 0
* Cascade readOnly to WriteCapableContract
* No overlap in readOnly + writeCapable precompiles
* Use function selector instead of directive
From Solidity, use abi.encodeWithSelector and match it against the
exact ABI of the functions. This allows us to remove the need for
a directive (32) being encoded, and thus saves 28 bytes of data.
* Do not allow contracts to become validators
As discussed with Jacky on #3906
* Merge harmony-one/harmony/main properly this time
* Run goimports
* Update gas calculation for staking precompile
Please see comment in core/vm/contracts_write.go RequiredGas
* Do not allow contract to become validator (2/2)
* Cache StakeMsgs from precompiled transactions
Add the StakeMsgs to ProcessorResult and cascade them in insertChain
* Remove ContractCode fields from validators
Since smart contracts can no longer beecome validators,
this field is superfluous. Remove it from the Wrapper
structure, and do not assign it a value when creating
a validator. Build and goimports checked
* Update comments in response to feedback
(1) Comments to start with function names
(2) Comments for public variables
(3) Comment to match function name RunPrecompiledContract
(4) Clarify that CreateValidatorFunc + EditValidatorFunc are still used
* Fix Travis build by reverting rosetta change
* Add revert capability to 3 staking tx types
- Delegate
- Undelegate
- CollectRewards
* Fix build: Update evm_test for ValidatorWrapper
* Merge main into harmony-staking-precompiles
* Add gas for precompile calls and allow EOA usage
- Each time the precompile is called, charge the base gas fee plus data
cost (if data can be parsed successfully). A gas fee is added to
prevent benevolent contract deployers from subsidizing the staking
transactions for EOAs through repeated assembly `delegatecall`.
- Allow EOAs to use the staking precompile directly. Some changes to
the Solidity library are associated with this change.
- Remove bytes from parsing address, since the ABI unpacks it into an
address format correctly.
- Add or update tests. Test coverage report to be attached to the PR
shortly.
* Run goimports
* Check read only and write capable for overlap
* Handle precompile stakeMsgs for block proposer
The staking precompile generates staking messages which are cascaded to
the block via the EVM in `state_processor.go`. This change cascades them
in `worker.go` to allow block proposers and block verifiers to keep the
same state.
* Run goimports for cf2dfac4081444e36a120c9432f4e..
* Update staking precompile epoch to 2 for localnet
Bring it in line with staking epoch. Change effects all configurations
except mainnet and testnet. `goimports` included.
* Add read only precompile to fetch the epoch num
* Move epoch precompile to 250
* precompiles: left pad the returned epoch number
* chainConfig: check epochs for precompiles
panic if staking precompile epoch < pre staking epoch
* Add staking migration precompile
- Lives at address 251
- Migrates delegations + pending undelegations from address A to B
- Useful if address A is hacked
- Charges gas of 21k + cost of bytes for two addresses
- Does not remove existing delegations, just sets them to zero.
Replicates current undelegate setup
- Unit tests and `goimports` included. Integration test following
shortly in MaxMustermann2/harmony-staking-precompiles
* Migration precompile: merge into staking
Merge the two precompiles into one, add gas calculation for migration
precompile. Move epoch precompile to 251 as a result. When migrating,
add undelegations to `To`'s existing undelegations, if any match the
epoch.
* Add migration gas test, remove panic, add check
In response to review comments, add tests for migration gas wherein
there are 0/1/2 delegations to migrate. Add the index out of bound check
to migration gas calculator and remove panics. Lastly, re-sort
migrated undelegations if no existing undelegation in the same epoch was
found on `To`.
* Move undelegations sorting to end of loop
3 years ago
|
|
|
}
|
|
|
|
if collectRewards, ok := stakeMsg.(*stakingTypes.CollectRewards); ok {
|
|
|
|
return nil, evm.CollectRewards(evm.StateDB, rosettaBlockTracer, collectRewards)
|
Resolve harmony-one/bounties#77: Staking precompiles (#3906)
* Resolve harmony-one/bounties#77: Staking precompiles
Create write capable precompiles that can perform staking transactions
Add hard fork logic (EpochTBD) for these precompiles
Tests for new code with at least 80% unit test coverage
Staking library + tests in MaxMustermann2/harmony-staking-precompiles
* Fix small typo in comment
* Run goimports on files to fix Travis
* Do not activate staking precompile on shard 0
* Cascade readOnly to WriteCapableContract
* No overlap in readOnly + writeCapable precompiles
* Use function selector instead of directive
From Solidity, use abi.encodeWithSelector and match it against the
exact ABI of the functions. This allows us to remove the need for
a directive (32) being encoded, and thus saves 28 bytes of data.
* Do not allow contracts to become validators
As discussed with Jacky on #3906
* Merge harmony-one/harmony/main properly this time
* Run goimports
* Update gas calculation for staking precompile
Please see comment in core/vm/contracts_write.go RequiredGas
* Do not allow contract to become validator (2/2)
* Cache StakeMsgs from precompiled transactions
Add the StakeMsgs to ProcessorResult and cascade them in insertChain
* Remove ContractCode fields from validators
Since smart contracts can no longer beecome validators,
this field is superfluous. Remove it from the Wrapper
structure, and do not assign it a value when creating
a validator. Build and goimports checked
* Update comments in response to feedback
(1) Comments to start with function names
(2) Comments for public variables
(3) Comment to match function name RunPrecompiledContract
(4) Clarify that CreateValidatorFunc + EditValidatorFunc are still used
* Fix Travis build by reverting rosetta change
* Add revert capability to 3 staking tx types
- Delegate
- Undelegate
- CollectRewards
* Fix build: Update evm_test for ValidatorWrapper
* Merge main into harmony-staking-precompiles
* Add gas for precompile calls and allow EOA usage
- Each time the precompile is called, charge the base gas fee plus data
cost (if data can be parsed successfully). A gas fee is added to
prevent benevolent contract deployers from subsidizing the staking
transactions for EOAs through repeated assembly `delegatecall`.
- Allow EOAs to use the staking precompile directly. Some changes to
the Solidity library are associated with this change.
- Remove bytes from parsing address, since the ABI unpacks it into an
address format correctly.
- Add or update tests. Test coverage report to be attached to the PR
shortly.
* Run goimports
* Check read only and write capable for overlap
* Handle precompile stakeMsgs for block proposer
The staking precompile generates staking messages which are cascaded to
the block via the EVM in `state_processor.go`. This change cascades them
in `worker.go` to allow block proposers and block verifiers to keep the
same state.
* Run goimports for cf2dfac4081444e36a120c9432f4e..
* Update staking precompile epoch to 2 for localnet
Bring it in line with staking epoch. Change effects all configurations
except mainnet and testnet. `goimports` included.
* Add read only precompile to fetch the epoch num
* Move epoch precompile to 250
* precompiles: left pad the returned epoch number
* chainConfig: check epochs for precompiles
panic if staking precompile epoch < pre staking epoch
* Add staking migration precompile
- Lives at address 251
- Migrates delegations + pending undelegations from address A to B
- Useful if address A is hacked
- Charges gas of 21k + cost of bytes for two addresses
- Does not remove existing delegations, just sets them to zero.
Replicates current undelegate setup
- Unit tests and `goimports` included. Integration test following
shortly in MaxMustermann2/harmony-staking-precompiles
* Migration precompile: merge into staking
Merge the two precompiles into one, add gas calculation for migration
precompile. Move epoch precompile to 251 as a result. When migrating,
add undelegations to `To`'s existing undelegations, if any match the
epoch.
* Add migration gas test, remove panic, add check
In response to review comments, add tests for migration gas wherein
there are 0/1/2 delegations to migrate. Add the index out of bound check
to migration gas calculator and remove panics. Lastly, re-sort
migrated undelegations if no existing undelegation in the same epoch was
found on `To`.
* Move undelegations sorting to end of loop
3 years ago
|
|
|
}
|
|
|
|
// Migrate is not supported in precompile and will be done in a batch hard fork
|
|
|
|
//if migrationMsg, ok := stakeMsg.(*stakingTypes.MigrationMsg); ok {
|
|
|
|
// stakeMsgs, err := evm.MigrateDelegations(evm.StateDB, migrationMsg)
|
|
|
|
// if err != nil {
|
|
|
|
// return nil, err
|
|
|
|
// } else {
|
|
|
|
// for _, stakeMsg := range stakeMsgs {
|
|
|
|
// if delegate, ok := stakeMsg.(*stakingTypes.Delegate); ok {
|
|
|
|
// evm.StakeMsgs = append(evm.StakeMsgs, delegate)
|
|
|
|
// } else {
|
|
|
|
// return nil, errors.New("[StakingPrecompile] Received incompatible stakeMsg from evm.MigrateDelegations")
|
|
|
|
// }
|
|
|
|
// }
|
|
|
|
// return nil, nil
|
|
|
|
// }
|
|
|
|
//}
|
Resolve harmony-one/bounties#77: Staking precompiles (#3906)
* Resolve harmony-one/bounties#77: Staking precompiles
Create write capable precompiles that can perform staking transactions
Add hard fork logic (EpochTBD) for these precompiles
Tests for new code with at least 80% unit test coverage
Staking library + tests in MaxMustermann2/harmony-staking-precompiles
* Fix small typo in comment
* Run goimports on files to fix Travis
* Do not activate staking precompile on shard 0
* Cascade readOnly to WriteCapableContract
* No overlap in readOnly + writeCapable precompiles
* Use function selector instead of directive
From Solidity, use abi.encodeWithSelector and match it against the
exact ABI of the functions. This allows us to remove the need for
a directive (32) being encoded, and thus saves 28 bytes of data.
* Do not allow contracts to become validators
As discussed with Jacky on #3906
* Merge harmony-one/harmony/main properly this time
* Run goimports
* Update gas calculation for staking precompile
Please see comment in core/vm/contracts_write.go RequiredGas
* Do not allow contract to become validator (2/2)
* Cache StakeMsgs from precompiled transactions
Add the StakeMsgs to ProcessorResult and cascade them in insertChain
* Remove ContractCode fields from validators
Since smart contracts can no longer beecome validators,
this field is superfluous. Remove it from the Wrapper
structure, and do not assign it a value when creating
a validator. Build and goimports checked
* Update comments in response to feedback
(1) Comments to start with function names
(2) Comments for public variables
(3) Comment to match function name RunPrecompiledContract
(4) Clarify that CreateValidatorFunc + EditValidatorFunc are still used
* Fix Travis build by reverting rosetta change
* Add revert capability to 3 staking tx types
- Delegate
- Undelegate
- CollectRewards
* Fix build: Update evm_test for ValidatorWrapper
* Merge main into harmony-staking-precompiles
* Add gas for precompile calls and allow EOA usage
- Each time the precompile is called, charge the base gas fee plus data
cost (if data can be parsed successfully). A gas fee is added to
prevent benevolent contract deployers from subsidizing the staking
transactions for EOAs through repeated assembly `delegatecall`.
- Allow EOAs to use the staking precompile directly. Some changes to
the Solidity library are associated with this change.
- Remove bytes from parsing address, since the ABI unpacks it into an
address format correctly.
- Add or update tests. Test coverage report to be attached to the PR
shortly.
* Run goimports
* Check read only and write capable for overlap
* Handle precompile stakeMsgs for block proposer
The staking precompile generates staking messages which are cascaded to
the block via the EVM in `state_processor.go`. This change cascades them
in `worker.go` to allow block proposers and block verifiers to keep the
same state.
* Run goimports for cf2dfac4081444e36a120c9432f4e..
* Update staking precompile epoch to 2 for localnet
Bring it in line with staking epoch. Change effects all configurations
except mainnet and testnet. `goimports` included.
* Add read only precompile to fetch the epoch num
* Move epoch precompile to 250
* precompiles: left pad the returned epoch number
* chainConfig: check epochs for precompiles
panic if staking precompile epoch < pre staking epoch
* Add staking migration precompile
- Lives at address 251
- Migrates delegations + pending undelegations from address A to B
- Useful if address A is hacked
- Charges gas of 21k + cost of bytes for two addresses
- Does not remove existing delegations, just sets them to zero.
Replicates current undelegate setup
- Unit tests and `goimports` included. Integration test following
shortly in MaxMustermann2/harmony-staking-precompiles
* Migration precompile: merge into staking
Merge the two precompiles into one, add gas calculation for migration
precompile. Move epoch precompile to 251 as a result. When migrating,
add undelegations to `To`'s existing undelegations, if any match the
epoch.
* Add migration gas test, remove panic, add check
In response to review comments, add tests for migration gas wherein
there are 0/1/2 delegations to migrate. Add the index out of bound check
to migration gas calculator and remove panics. Lastly, re-sort
migrated undelegations if no existing undelegation in the same epoch was
found on `To`.
* Move undelegations sorting to end of loop
3 years ago
|
|
|
return nil, errors.New("[StakingPrecompile] Received incompatible stakeMsg from staking.ParseStakeMsg")
|
|
|
|
}
|
|
|
|
|
|
|
|
var abiCrossShardXfer abi.ABI
|
|
|
|
|
|
|
|
func init() {
|
|
|
|
// msg.Value is used for transfer and is also a parameter
|
|
|
|
// otherwise it might be possible for a user to retrieve money from the precompile
|
|
|
|
// that was sent by someone else prior to the hard fork
|
|
|
|
// contract.Caller is used as fromAddress, not a parameter
|
|
|
|
// originating ShardID is pulled from the EVM object, not a parameter
|
|
|
|
crossShardXferABIJSON := `
|
|
|
|
[
|
|
|
|
{
|
|
|
|
"inputs": [
|
|
|
|
{
|
|
|
|
"internalType": "uint256",
|
|
|
|
"name": "value",
|
|
|
|
"type": "uint256"
|
|
|
|
},
|
|
|
|
{
|
|
|
|
"internalType": "address",
|
|
|
|
"name": "to",
|
|
|
|
"type": "address"
|
|
|
|
},
|
|
|
|
{
|
|
|
|
"internalType": "uint64",
|
|
|
|
"name": "toShardID",
|
|
|
|
"type": "uint32"
|
|
|
|
}
|
|
|
|
],
|
|
|
|
"name": "crossShardTransfer",
|
|
|
|
"outputs": [],
|
|
|
|
"stateMutability": "payable",
|
|
|
|
"type": "function"
|
|
|
|
}
|
|
|
|
]`
|
|
|
|
var err error
|
|
|
|
abiCrossShardXfer, err = abi.JSON(strings.NewReader(crossShardXferABIJSON))
|
|
|
|
if err != nil {
|
|
|
|
// means an error in the code
|
|
|
|
panic("Invalid cross shard transfer ABI JSON")
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
type crossShardXferPrecompile struct{}
|
|
|
|
|
|
|
|
// RequiredGas returns the gas required to execute the pre-compiled contract.
|
|
|
|
//
|
|
|
|
// This method does not require any overflow checking as the input size gas costs
|
|
|
|
// required for anything significant is so high it's impossible to pay for.
|
|
|
|
func (c *crossShardXferPrecompile) RequiredGas(
|
|
|
|
evm *EVM,
|
|
|
|
contract *Contract,
|
|
|
|
input []byte,
|
|
|
|
) (uint64, error) {
|
|
|
|
// multiple instances of the precompile in one transaction
|
|
|
|
// are blocked, so there is no way for a smart contract
|
|
|
|
// to subsidize this transaction by an EOA via delegatecall
|
|
|
|
// therefore no need to charge any gas
|
|
|
|
return 0, nil
|
|
|
|
}
|
|
|
|
|
|
|
|
// RunWriteCapable runs the actual contract
|
|
|
|
func (c *crossShardXferPrecompile) RunWriteCapable(
|
|
|
|
evm *EVM,
|
|
|
|
contract *Contract,
|
|
|
|
input []byte,
|
|
|
|
) ([]byte, error) {
|
|
|
|
// make sure that cxReceipt is already nil to
|
|
|
|
// prevent multiple calls to the precompile
|
|
|
|
// in the same transaction
|
|
|
|
if evm.CXReceipt != nil {
|
|
|
|
return nil, errors.New("cannot call cross shard precompile again in same tx")
|
|
|
|
}
|
|
|
|
fromAddress, toAddress, fromShardID, toShardID, value, err :=
|
|
|
|
parseCrossShardXferData(evm, contract, input)
|
|
|
|
if err != nil {
|
|
|
|
return nil, err
|
|
|
|
}
|
|
|
|
// validate not a contract (toAddress can still be a contract)
|
|
|
|
if len(evm.StateDB.GetCode(fromAddress)) > 0 && !evm.IsValidator(evm.StateDB, fromAddress) {
|
|
|
|
return nil, errors.New("cross shard xfer not yet implemented for contracts")
|
|
|
|
}
|
|
|
|
// can't have too many shards
|
|
|
|
if toShardID >= evm.Context.NumShards {
|
|
|
|
return nil, errors.New("toShardId out of bounds")
|
|
|
|
}
|
|
|
|
// not for simple transfers
|
|
|
|
if fromShardID == toShardID {
|
|
|
|
return nil, errors.New("from and to shard id can't be equal")
|
|
|
|
}
|
|
|
|
// make sure nobody sends extra or less money
|
|
|
|
if contract.Value().Cmp(value) != 0 {
|
|
|
|
return nil, errors.New("argument value and msg.value not equal")
|
|
|
|
}
|
|
|
|
// now do the actual transfer
|
|
|
|
// step 1 -> remove funds from the precompile address
|
|
|
|
if !evm.CanTransfer(evm.StateDB, contract.Address(), value) {
|
|
|
|
return nil, errors.New("not enough balance received")
|
|
|
|
}
|
|
|
|
evm.Transfer(evm.StateDB, contract.Address(), toAddress, value, types.SubtractionOnly)
|
|
|
|
// step 2 -> make a cross link
|
|
|
|
// note that the transaction hash is added by state_processor.go to this receipt
|
|
|
|
// and that the receiving shard does not care about the `From` but we use the original
|
|
|
|
// instead of the precompile address for consistency
|
|
|
|
evm.CXReceipt = &types.CXReceipt{
|
|
|
|
From: fromAddress,
|
|
|
|
To: &toAddress,
|
|
|
|
ShardID: fromShardID,
|
|
|
|
ToShardID: toShardID,
|
|
|
|
Amount: value,
|
|
|
|
}
|
|
|
|
return nil, nil
|
|
|
|
}
|
|
|
|
|
|
|
|
// parseCrossShardXferData does a simple parse with only data types validation
|
|
|
|
func parseCrossShardXferData(evm *EVM, contract *Contract, input []byte) (
|
|
|
|
common.Address, common.Address, uint32, uint32, *big.Int, error) {
|
|
|
|
method, err := abiCrossShardXfer.MethodById(input)
|
|
|
|
if err != nil {
|
|
|
|
return common.Address{}, common.Address{}, 0, 0, nil, err
|
|
|
|
}
|
|
|
|
input = input[4:]
|
|
|
|
args := map[string]interface{}{}
|
|
|
|
if err = method.Inputs.UnpackIntoMap(args, input); err != nil {
|
|
|
|
return common.Address{}, common.Address{}, 0, 0, nil, err
|
|
|
|
}
|
|
|
|
value, err := abi.ParseBigIntFromKey(args, "value")
|
|
|
|
if err != nil {
|
|
|
|
return common.Address{}, common.Address{}, 0, 0, nil, err
|
|
|
|
}
|
|
|
|
toAddress, err := abi.ParseAddressFromKey(args, "to")
|
|
|
|
if err != nil {
|
|
|
|
return common.Address{}, common.Address{}, 0, 0, nil, err
|
|
|
|
}
|
|
|
|
toShardID, err := abi.ParseUint32FromKey(args, "toShardID")
|
|
|
|
if err != nil {
|
|
|
|
return common.Address{}, common.Address{}, 0, 0, nil, err
|
|
|
|
}
|
|
|
|
return contract.Caller(), toAddress, evm.ShardID, toShardID, value, nil
|
|
|
|
}
|