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

Added Conversion Functionality #1559

Merged
merged 3 commits into from
Apr 23, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
42 changes: 42 additions & 0 deletions common/address.go
Original file line number Diff line number Diff line change
Expand Up @@ -75,6 +75,36 @@ func (a Address) InternalAndQuaiAddress() (InternalAddress, error) {
return *internal, nil
}

func CheckIfBytesAreInternalAndQiAddress(b []byte, nodeLocation Location) error {
if len(b) != AddressLength {
return fmt.Errorf("address %s is not %d bytes long", hexutil.Encode(b), AddressLength)
}
if !IsInChainScope(b, nodeLocation) {
return ErrInvalidScope
}
if AddressBytes(b).IsInQuaiLedgerScope() {
return ErrQuaiAddress
}
return nil
}

func (a Address) InternalAndQiAddress() (InternalAddress, error) {
if a.inner == nil {
return InternalAddress{}, ErrNilInner
}
if a.IsInQuaiLedgerScope() {
return InternalAddress{}, ErrQuaiAddress
}
internal, ok := a.inner.(*InternalAddress)
if !ok {
return InternalAddress{}, ErrInvalidScope
}
if internal == nil {
return InternalAddress{}, ErrNilInner
}
return *internal, nil
}

func (a Address) IsInQiLedgerScope() bool {
// The first bit of the second byte is set if the address is in the Qi ledger
return a.Bytes()[1] > 127
Expand Down Expand Up @@ -358,6 +388,18 @@ func (a AddressBytes) hex() []byte {
return buf[:]
}

func (a AddressBytes) Location() *Location {
// Extract nibbles
lowerNib := a[0] & 0x0F // Lower 4 bits
upperNib := (a[0] & 0xF0) >> 4 // Upper 4 bits, shifted right
return &Location{upperNib, lowerNib}
}

func (a AddressBytes) IsInQuaiLedgerScope() bool {
// The first bit of the second byte is not set if the address is in the Quai ledger
return a[1] <= 127
}

func MakeErrQiAddress(addr string) error {
return fmt.Errorf("address %s is in Qi ledger scope and is not in Quai ledger scope", addr)
}
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.

9 changes: 8 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 @@ -549,6 +550,13 @@ func (blake3pow *Blake3pow) Finalize(chain consensus.ChainHeaderReader, header *
nodeCtx := blake3pow.config.NodeLocation.Context()

if nodeCtx == common.ZONE_CTX && chain.IsGenesisHash(header.ParentHash(nodeCtx)) {
// Create the lockup contract account
lockupContract, err := vm.LockupContractAddresses[[2]byte{nodeLocation[0], nodeLocation[1]}].InternalAndQuaiAddress()
if err != nil {
panic(err)
}
state.CreateAccount(lockupContract)

alloc := core.ReadGenesisAlloc("genallocs/gen_alloc_"+nodeLocation.Name()+".json", blake3pow.logger)
blake3pow.logger.WithField("alloc", len(alloc)).Info("Allocating genesis accounts")

Expand All @@ -570,7 +578,6 @@ func (blake3pow *Blake3pow) Finalize(chain consensus.ChainHeaderReader, header *
continue
}
}

core.AddGenesisUtxos(state, nodeLocation, blake3pow.logger)
}
header.Header().SetUTXORoot(state.UTXORoot())
Expand Down
2 changes: 1 addition & 1 deletion consensus/misc/rewards.go
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,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
8 changes: 8 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 @@ -585,6 +586,13 @@ func (progpow *Progpow) Finalize(chain consensus.ChainHeaderReader, header *type
nodeCtx := progpow.NodeLocation().Context()

if nodeCtx == common.ZONE_CTX && chain.IsGenesisHash(header.ParentHash(nodeCtx)) {
// Create the lockup contract account
lockupContract, err := vm.LockupContractAddresses[[2]byte{nodeLocation[0], nodeLocation[1]}].InternalAndQuaiAddress()
if err != nil {
panic(err)
}
state.CreateAccount(lockupContract)

alloc := core.ReadGenesisAlloc("genallocs/gen_alloc_"+nodeLocation.Name()+".json", progpow.logger)
progpow.logger.WithField("alloc", len(alloc)).Info("Allocating genesis accounts")

Expand Down
4 changes: 3 additions & 1 deletion core/genesis.go
Original file line number Diff line number Diff line change
Expand Up @@ -533,6 +533,8 @@ func AddGenesisUtxos(state *state.StateDB, nodeLocation common.Location, logger
Denomination: uint8(utxo.Denomination),
}

state.CreateUTXO(hash, uint16(utxo.Index), newUtxo)
if err := state.CreateUTXO(hash, uint16(utxo.Index), newUtxo); err != nil {
panic(fmt.Sprintf("Failed to create genesis UTXO: %v", err))
}
}
}
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.

11 changes: 9 additions & 2 deletions 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 @@ -575,17 +574,25 @@ func (s *StateDB) DeleteUTXO(txHash common.Hash, outputIndex uint16) {
}

// CreateUTXO explicitly creates a UTXO entry.
func (s *StateDB) CreateUTXO(txHash common.Hash, outputIndex uint16, utxo *types.UtxoEntry) {
func (s *StateDB) CreateUTXO(txHash common.Hash, outputIndex uint16, utxo *types.UtxoEntry) error {
if metrics_config.MetricsEnabled() {
defer func(start time.Time) { stateMetrics.WithLabelValues("CreateUTXO").Add(float64(time.Since(start))) }(time.Now())
}
// This check is largely redundant, but it's a good sanity check. Might be removed in the future.
if err := common.CheckIfBytesAreInternalAndQiAddress(utxo.Address, s.nodeLocation); err != nil {
return err
}
if utxo.Denomination > types.MaxDenomination { // sanity check
wizeguyy marked this conversation as resolved.
Show resolved Hide resolved
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))
}
if err := s.utxoTrie.TryUpdate(utxoKey(txHash, outputIndex), data); err != nil {
s.setError(fmt.Errorf("createUTXO (%x) error: %v", txHash, err))
}
return nil
}

func (s *StateDB) CommitUTXOs() (common.Hash, error) {
Expand Down
Loading
Loading