Skip to content

Commit

Permalink
Added conversion processing with ETX to origin and destination
Browse files Browse the repository at this point in the history
  • Loading branch information
jdowning100 committed Apr 18, 2024
1 parent e694fe5 commit ce3873a
Show file tree
Hide file tree
Showing 24 changed files with 530 additions and 152 deletions.
4 changes: 2 additions & 2 deletions common/proto_common.pb.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

8 changes: 7 additions & 1 deletion consensus/blake3pow/consensus.go
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ import (
"github.com/dominant-strategies/go-quai/core"
"github.com/dominant-strategies/go-quai/core/state"
"github.com/dominant-strategies/go-quai/core/types"
"github.com/dominant-strategies/go-quai/core/vm"
"github.com/dominant-strategies/go-quai/params"
"github.com/dominant-strategies/go-quai/trie"
"modernc.org/mathutil"
Expand Down Expand Up @@ -570,8 +571,13 @@ func (blake3pow *Blake3pow) Finalize(chain consensus.ChainHeaderReader, header *
continue
}
}

core.AddGenesisUtxos(state, nodeLocation, blake3pow.logger)
// Create the lockup contract account
lockupContract, err := vm.LockupContractAddresses[[2]byte{nodeLocation[0], nodeLocation[1]}].InternalAndQuaiAddress()
if err != nil {
panic(err)
}
state.CreateAccount(lockupContract)
}
header.Header().SetUTXORoot(state.UTXORoot())
header.Header().SetEVMRoot(state.IntermediateRoot(true))
Expand Down
10 changes: 9 additions & 1 deletion consensus/misc/rewards.go
Original file line number Diff line number Diff line change
Expand Up @@ -17,12 +17,20 @@ func CalculateReward(header *types.WorkObject) *big.Int {
// Calculate the amount of Quai that Qi can be converted to. Expect the current Header and the Qi amount in "qits", returns the quai amount in "its"
func QiToQuai(currentHeader *types.WorkObject, qiAmt *big.Int) *big.Int {
quaiPerQi := new(big.Int).Div(calculateQuaiReward(currentHeader), calculateQiReward(currentHeader))
result := new(big.Int).Mul(qiAmt, quaiPerQi)
if result.Cmp(big.NewInt(0)) == 0 {
return big.NewInt(1)
}
return new(big.Int).Mul(qiAmt, quaiPerQi)
}

// Calculate the amount of Qi that Quai can be converted to. Expect the current Header and the Quai amount in "its", returns the Qi amount in "qits"
func QuaiToQi(currentHeader *types.WorkObject, quaiAmt *big.Int) *big.Int {
qiPerQuai := new(big.Int).Div(calculateQiReward(currentHeader), calculateQuaiReward(currentHeader))
result := new(big.Int).Mul(quaiAmt, qiPerQuai)
if result.Cmp(types.Denominations[0]) < 0 {
return types.Denominations[0]
}
return new(big.Int).Mul(quaiAmt, qiPerQuai)
}

Expand All @@ -43,7 +51,7 @@ func FindMinDenominations(reward *big.Int) map[uint8]uint8 {
amount := new(big.Int).Set(reward)

// Iterate over the denominations in descending order (by key)
for i := 15; i >= 0; i-- {
for i := types.MaxDenomination; i >= 0; i-- {
denom := types.Denominations[uint8(i)]

// Calculate the number of times the denomination fits into the remaining amount
Expand Down
7 changes: 7 additions & 0 deletions consensus/progpow/consensus.go
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ import (
"github.com/dominant-strategies/go-quai/core"
"github.com/dominant-strategies/go-quai/core/state"
"github.com/dominant-strategies/go-quai/core/types"
"github.com/dominant-strategies/go-quai/core/vm"
"github.com/dominant-strategies/go-quai/params"
"github.com/dominant-strategies/go-quai/trie"
"modernc.org/mathutil"
Expand Down Expand Up @@ -607,6 +608,12 @@ func (progpow *Progpow) Finalize(chain consensus.ChainHeaderReader, header *type
}
}
core.AddGenesisUtxos(state, nodeLocation, progpow.logger)
// Create the lockup contract account
lockupContract, err := vm.LockupContractAddresses[[2]byte{nodeLocation[0], nodeLocation[1]}].InternalAndQuaiAddress()
if err != nil {
panic(err)
}
state.CreateAccount(lockupContract)
}
header.Header().SetUTXORoot(state.UTXORoot())
header.Header().SetEVMRoot(state.IntermediateRoot(true))
Expand Down
4 changes: 2 additions & 2 deletions core/rawdb/db.pb.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

4 changes: 3 additions & 1 deletion core/state/statedb.go
Original file line number Diff line number Diff line change
Expand Up @@ -297,7 +297,6 @@ func (s *StateDB) GetBalance(addr common.InternalAddress) *big.Int {
}
return common.Big0
}

func (s *StateDB) GetNonce(addr common.InternalAddress) uint64 {
stateObject := s.getStateObject(addr)
if stateObject != nil {
Expand Down Expand Up @@ -583,6 +582,9 @@ func (s *StateDB) CreateUTXO(txHash common.Hash, outputIndex uint16, utxo *types
if err := common.CheckIfBytesAreInternalAndQiAddress(utxo.Address, s.nodeLocation); err != nil {
return err
}
if utxo.Denomination > types.MaxDenomination { // sanity check
return fmt.Errorf("tx %032x emits UTXO with value %d greater than max denomination", txHash, utxo.Denomination)
}
data, err := rlp.EncodeToBytes(utxo)
if err != nil {
panic(fmt.Errorf("can't encode UTXO entry at %x: %v", txHash, err))
Expand Down
143 changes: 105 additions & 38 deletions core/state_processor.go

Large diffs are not rendered by default.

13 changes: 7 additions & 6 deletions core/state_transition.go
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,7 @@ The state transitioning model does all the necessary work to work out a valid ne
6) Derive new state root
*/
type StateTransition struct {
gp *GasPool
gp *types.GasPool
msg Message
gas uint64
gasPrice *big.Int
Expand Down Expand Up @@ -83,6 +83,7 @@ type Message interface {
ETXSender() common.Address
Type() byte
Hash() common.Hash
Lock() *big.Int
}

// ExecutionResult includes all output after executing given evm
Expand Down Expand Up @@ -161,7 +162,7 @@ func IntrinsicGas(data []byte, accessList types.AccessList, isContractCreation b
}

// NewStateTransition initialises and returns a new state transition object.
func NewStateTransition(evm *vm.EVM, msg Message, gp *GasPool) *StateTransition {
func NewStateTransition(evm *vm.EVM, msg Message, gp *types.GasPool) *StateTransition {
return &StateTransition{
gp: gp,
evm: evm,
Expand All @@ -182,7 +183,7 @@ func NewStateTransition(evm *vm.EVM, msg Message, gp *GasPool) *StateTransition
// the gas used (which includes gas refunds) and an error if it failed. An error always
// indicates a core error meaning that the message would always fail for that particular
// state and would never be accepted within a block.
func ApplyMessage(evm *vm.EVM, msg Message, gp *GasPool) (*ExecutionResult, error) {
func ApplyMessage(evm *vm.EVM, msg Message, gp *types.GasPool) (*ExecutionResult, error) {
return NewStateTransition(evm, msg, gp).TransitionDb()
}

Expand Down Expand Up @@ -372,7 +373,7 @@ func (st *StateTransition) TransitionDb() (*ExecutionResult, error) {
return nil, err
}
st.state.SetNonce(from, st.state.GetNonce(addr)+1)
ret, st.gas, vmerr = st.evm.Call(sender, st.to(), st.data, st.gas, st.value)
ret, st.gas, vmerr = st.evm.Call(sender, st.to(), st.data, st.gas, st.value, st.msg.Lock())
}

// At this point, the execution completed, so the ETX cache can be dumped and reset
Expand All @@ -391,8 +392,8 @@ func (st *StateTransition) TransitionDb() (*ExecutionResult, error) {
if err != nil {
return nil, err
}
if coinbase.IsInQuaiLedgerScope() {
st.state.AddBalance(coinbase, new(big.Int).Mul(new(big.Int).SetUint64(st.gasUsed()), effectiveTip)) // todo: etxs no longer pay the miner a fee
if coinbase.IsInQuaiLedgerScope() && !st.msg.IsETX() {
st.state.AddBalance(coinbase, new(big.Int).Mul(new(big.Int).SetUint64(st.gasUsed()), effectiveTip))
}

return &ExecutionResult{
Expand Down
13 changes: 5 additions & 8 deletions core/tx_pool.go
Original file line number Diff line number Diff line change
Expand Up @@ -1053,11 +1053,6 @@ func (pool *TxPool) addTxs(txs []*types.Transaction, local, sync bool) []error {
}
continue
}
if tx.To() != nil && tx.To().IsInQiLedgerScope() {
errs[i] = common.MakeErrQiAddress(tx.To().Hex())
invalidTxMeter.Add(1)
continue
}
// Exclude transactions with invalid signatures as soon as
// possible and cache senders in transactions before
// obtaining lock
Expand Down Expand Up @@ -1128,7 +1123,7 @@ func (pool *TxPool) addQiTx(tx *types.Transaction, grabLock bool) error {

location := pool.chainconfig.Location
currentBlock := pool.chain.CurrentBlock()
gp := GasPool(currentBlock.GasLimit())
gp := types.GasPool(currentBlock.GasLimit())
etxRLimit := len(currentBlock.Transactions()) / params.ETXRegionMaxFraction
if etxRLimit < params.ETXRLimitMin {
etxRLimit = params.ETXRLimitMin
Expand All @@ -1142,11 +1137,13 @@ func (pool *TxPool) addQiTx(tx *types.Transaction, grabLock bool) error {
}
fee, _, err := ProcessQiTx(tx, pool.chain, false, pool.chain.CurrentBlock(), pool.currentState, &gp, new(uint64), pool.signer, location, *pool.chainconfig.ChainID, &etxRLimit, &etxPLimit)
if err != nil {
pool.mu.RUnlock()
if grabLock {
pool.mu.RUnlock()
}
pool.logger.WithFields(logrus.Fields{
"tx": tx.Hash().String(),
"err": err,
}).Error("Invalid qi tx")
}).Error("Invalid Qi transaction")
return err
}
if grabLock {
Expand Down
5 changes: 3 additions & 2 deletions core/gaspool.go → core/types/gaspool.go
Original file line number Diff line number Diff line change
Expand Up @@ -14,9 +14,10 @@
// You should have received a copy of the GNU Lesser General Public License
// along with the go-ethereum library. If not, see <http://www.gnu.org/licenses/>.

package core
package types

import (
"errors"
"fmt"
"math"
)
Expand All @@ -38,7 +39,7 @@ func (gp *GasPool) AddGas(amount uint64) *GasPool {
// available and returns an error otherwise.
func (gp *GasPool) SubGas(amount uint64) error {
if uint64(*gp) < amount {
return ErrGasLimitReached
return errors.New("gas limit reached")
}
*(*uint64)(gp) -= amount
return nil
Expand Down
38 changes: 24 additions & 14 deletions core/types/proto_block.pb.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions core/types/proto_block.proto
Original file line number Diff line number Diff line change
Expand Up @@ -167,4 +167,5 @@ message ProtoOutPoint {
message ProtoTxOut {
optional uint32 denomination = 1;
optional bytes address = 2;
optional bytes lock = 3;
}
1 change: 1 addition & 0 deletions core/types/qi_tx.go
Original file line number Diff line number Diff line change
Expand Up @@ -121,6 +121,7 @@ func CalculateQiTxGas(transaction *Transaction) uint64 {
if transaction.Type() != QiTxType {
panic("CalculateQiTxGas called on a transaction that is not a Qi transaction")
}
// TODO: This should check for ETXs (and conversion) and calculate expected gas for those as well
return uint64(len(transaction.TxIn()))*params.SloadGas + uint64(len(transaction.TxOut()))*params.CallValueTransferGas + params.EcrecoverGas
}

Expand Down
22 changes: 21 additions & 1 deletion core/types/transaction.go
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@ import (
"github.com/dominant-strategies/go-quai/common"
"github.com/dominant-strategies/go-quai/common/math"
"github.com/dominant-strategies/go-quai/log"
"github.com/dominant-strategies/go-quai/params"
"google.golang.org/protobuf/proto"

"github.com/dominant-strategies/go-quai/crypto"
Expand Down Expand Up @@ -546,7 +547,7 @@ func (tx *Transaction) To() *common.Address {
return &cpy
}

func (tx *Transaction) SetTo(addr common.Address) {
func (tx *Transaction) SetGas(addr common.Address) {
tx.inner.setTo(addr)
}

Expand Down Expand Up @@ -709,6 +710,10 @@ func (tx *Transaction) ConfirmationCtx(nodeLocation common.Location) int {
if ctx := tx.confirmCtx.Load(); ctx != nil {
return ctx.(int)
}
if tx.ETXSender().Location().Equal(*tx.To().Location()) {
// If the ETX sender and the destination chain are the same, the ETX is a conversion tx
return params.ConversionConfirmationContext
}

ctx := tx.To().Location().CommonDom(tx.FromChain(nodeLocation)).Context()
tx.confirmCtx.Store(ctx)
Expand Down Expand Up @@ -1018,6 +1023,7 @@ type Message struct {
etxsender common.Address // only used in ETX
txtype byte
hash common.Hash
lock *big.Int
}

func NewMessage(from common.Address, to *common.Address, nonce uint64, amount *big.Int, gasLimit uint64, gasPrice, gasFeeCap, gasTipCap *big.Int, data []byte, accessList AccessList, isETX bool) Message {
Expand Down Expand Up @@ -1082,6 +1088,7 @@ func (tx *Transaction) AsMessageWithSender(s Signer, baseFee *big.Int, sender *c
isETX: false,
txtype: tx.Type(),
hash: tx.Hash(),
lock: new(big.Int),
}
// If baseFee provided, set gasPrice to effectiveGasPrice.
if baseFee != nil {
Expand Down Expand Up @@ -1117,6 +1124,19 @@ func (m Message) IsETX() bool { return m.isETX }
func (m Message) ETXSender() common.Address { return m.etxsender }
func (m Message) Type() byte { return m.txtype }
func (m Message) Hash() common.Hash { return m.hash }
func (m Message) Lock() *big.Int { return m.lock }

func (m *Message) SetValue(v *big.Int) {
m.amount = v
}

func (m *Message) SetLock(lock *big.Int) {
m.lock = lock
}

func (m *Message) SetData(data []byte) {
m.data = data
}

// AccessList is an access list.
type AccessList []AccessTuple
Expand Down
Loading

0 comments on commit ce3873a

Please sign in to comment.