Skip to content

Commit

Permalink
feat: rename is registered output field (#253)
Browse files Browse the repository at this point in the history
BREAKING CHANGE: Node and UI server APIs have changed.
1. Node
* Modified:
  - UTXO and Output data structures "has_income" field have been renamed to "is_yielding"
  - Block data structure fields have been reordered:
    - Block data structure was:
    {
      "timestamp":                    int64
      "previous_hash":                [32]byte
      "transactions":                 []Transaction
      "added_registered_addresses":   []string
      "removed_registered_addresses": []string
    }
    - Block data structure is now:
    {
      "previous_hash":                [32]byte
      "added_registered_addresses":   []string
      "removed_registered_addresses": []string
      "timestamp":                    int64
      "transactions":                 []Transaction
    }
2. Node and UI server
* Modified:
  - Output data structure "has_income" field has been renamed to "is_yielding"
  • Loading branch information
JeremyPansier committed Oct 27, 2023
1 parent 883c86b commit c2e3808
Show file tree
Hide file tree
Showing 18 changed files with 203 additions and 198 deletions.
24 changes: 12 additions & 12 deletions src/node/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -112,35 +112,35 @@ Example

```
{
"timestamp": int64
"previous_hash": [32]byte
"transactions": []Transaction
"added_registered_addresses": []string
"removed_registered_addresses": []string
"timestamp": int64
"transactions": []Transaction
}
```
</td>
<td>

```
The block timestamp
The hash of the previous block in the chain
The block transactions
The added addresses registered in the PoH registry compared to the previous block
The removed addresses registered in the PoH registry compared to the previous block
The block timestamp
The block transactions
```
</td>
<td>

```
{
"timestamp": 1667768884780639700
"previous_hash": [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32]
"transactions": []
"added_registered_addresses": ["0xf14DB86A3292ABaB1D4B912dbF55e8abc112593a"]
"removed_registered_addresses": ["0xb1477DcBBea001a339a92b031d14a011e36D008F"]
"timestamp": 1667768884780639700
"transactions": []
}
```
</td>
Expand Down Expand Up @@ -211,9 +211,9 @@ Example

```
{
"address": string
"is_registered": bool
"value": uint64
"address": string
"is_yielding": bool
"value": uint64
}
```
</td>
Expand All @@ -232,7 +232,7 @@ The value at the transaction timestamp
```
{
"address": "0xf14DB86A3292ABaB1D4B912dbF55e8abc112593a"
"has_income": true
"is_yielding": true
"value": 0
}
```
Expand Down Expand Up @@ -348,7 +348,7 @@ Example
{
"address": string
"block_height": int
"has_income": bool
"is_yielding": bool
"output_index": uint16
"transaction_id": string
"value": uint64
Expand All @@ -375,7 +375,7 @@ The value at the transaction timestamp
{
"address": "0xf14DB86A3292ABaB1D4B912dbF55e8abc112593a"
"block_height": 0
"has_income": true
"is_yielding": true
"output_index": 0
"transaction_id": "8ae72a72c0c99dc9d41c2b7d8ea67b5a2de25ff4463b1a53816ba179947ce77d"
"value": 0
Expand Down
8 changes: 4 additions & 4 deletions src/node/protocol/validation/transactions_pool.go
Original file line number Diff line number Diff line change
Expand Up @@ -83,11 +83,11 @@ func (pool *TransactionsPool) Validate(timestamp int64) {
nextBlockTimestamp := lastBlockTimestamp + pool.settings.ValidationTimestamp()
var reward uint64
var newAddresses []string
var hasIncome bool
var isYielding bool
if lastBlockTimestamp == 0 {
reward = pool.settings.GenesisAmountInParticles()
newAddresses = []string{pool.validatorAddress}
hasIncome = true
isYielding = true
} else if lastBlockTimestamp == timestamp {
pool.logger.Error("unable to create block, a block with the same timestamp is already in the blockchain")
return
Expand Down Expand Up @@ -152,12 +152,12 @@ func (pool *TransactionsPool) Validate(timestamp int64) {
}
for _, transaction := range transactions {
for _, output := range transaction.Outputs() {
if output.IsRegistered() {
if output.IsYielding() {
newAddresses = append(newAddresses, output.Address())
}
}
}
rewardTransaction, err := verification.NewRewardTransaction(pool.validatorAddress, hasIncome, timestamp, reward)
rewardTransaction, err := verification.NewRewardTransaction(pool.validatorAddress, isYielding, timestamp, reward)
if err != nil {
pool.logger.Error(fmt.Errorf("unable to create block, failed to create reward transaction: %w", err).Error())
return
Expand Down
70 changes: 35 additions & 35 deletions src/node/protocol/verification/block.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,37 +7,23 @@ import (
)

type blockDto struct {
Timestamp int64 `json:"timestamp"`
PreviousHash [32]byte `json:"previous_hash"`
Transactions []*Transaction `json:"transactions"`
AddedRegisteredAddresses []string `json:"added_registered_addresses"`
RemovedRegisteredAddresses []string `json:"removed_registered_addresses"`
Timestamp int64 `json:"timestamp"`
Transactions []*Transaction `json:"transactions"`
}

type Block struct {
timestamp int64
previousHash [32]byte
transactions []*Transaction
addedRegisteredAddresses []string
removedRegisteredAddresses []string
timestamp int64
transactions []*Transaction
}

func NewBlock(timestamp int64, previousHash [32]byte, transactions []*Transaction, addedRegisteredAddresses []string, removedRegisteredAddresses []string) *Block {
return &Block{timestamp, previousHash, transactions, addedRegisteredAddresses, removedRegisteredAddresses}
}

func (block *Block) AddedRegisteredAddresses() []string {
return block.addedRegisteredAddresses
}

func (block *Block) Hash() (hash [32]byte, err error) {
marshaledBlock, err := block.MarshalJSON()
if err != nil {
err = fmt.Errorf("failed to marshal block: %w", err)
return
}
hash = sha256.Sum256(marshaledBlock)
return
func NewBlock(previousHash [32]byte, addedRegisteredAddresses []string, removedRegisteredAddresses []string, timestamp int64, transactions []*Transaction) *Block {
return &Block{previousHash, addedRegisteredAddresses, removedRegisteredAddresses, timestamp, transactions}
}

func (block *Block) UnmarshalJSON(data []byte) error {
Expand All @@ -46,28 +32,53 @@ func (block *Block) UnmarshalJSON(data []byte) error {
if err != nil {
return err
}
block.timestamp = dto.Timestamp
block.previousHash = dto.PreviousHash
block.transactions = dto.Transactions
block.addedRegisteredAddresses = dto.AddedRegisteredAddresses
block.removedRegisteredAddresses = dto.RemovedRegisteredAddresses
block.timestamp = dto.Timestamp
block.transactions = dto.Transactions
return nil
}

func (block *Block) MarshalJSON() ([]byte, error) {
return json.Marshal(blockDto{
Timestamp: block.timestamp,
PreviousHash: block.previousHash,
Transactions: block.transactions,
AddedRegisteredAddresses: block.addedRegisteredAddresses,
RemovedRegisteredAddresses: block.removedRegisteredAddresses,
Timestamp: block.timestamp,
Transactions: block.transactions,
})
}

func (block *Block) Hash() (hash [32]byte, err error) {
marshaledBlock, err := block.MarshalJSON()
if err != nil {
err = fmt.Errorf("failed to marshal block: %w", err)
return
}
hash = sha256.Sum256(marshaledBlock)
return
}

func (block *Block) ValidatorAddress() string {
var validatorAddress string
for i := len(block.transactions) - 1; i >= 0; i-- {
if block.transactions[i].HasReward() {
validatorAddress = block.transactions[i].RewardRecipientAddress()
break
}
}
return validatorAddress
}

func (block *Block) PreviousHash() [32]byte {
return block.previousHash
}

func (block *Block) AddedRegisteredAddresses() []string {
return block.addedRegisteredAddresses
}

func (block *Block) RemovedRegisteredAddresses() []string {
return block.removedRegisteredAddresses
}
Expand All @@ -79,14 +90,3 @@ func (block *Block) Timestamp() int64 {
func (block *Block) Transactions() []*Transaction {
return block.transactions
}

func (block *Block) ValidatorAddress() string {
var validatorAddress string
for i := len(block.transactions) - 1; i >= 0; i-- {
if block.transactions[i].HasReward() {
validatorAddress = block.transactions[i].RewardRecipientAddress()
break
}
}
return validatorAddress
}
12 changes: 6 additions & 6 deletions src/node/protocol/verification/blockchain.go
Original file line number Diff line number Diff line change
Expand Up @@ -85,7 +85,7 @@ func (blockchain *Blockchain) AddBlock(timestamp int64, transactionsBytes []byte
return fmt.Errorf("failed to unmarshal transactions: %w", err)
}
}
block := NewBlock(timestamp, previousHash, transactions, addedRegisteredAddresses, removedRegisteredAddresses)
block := NewBlock(previousHash, addedRegisteredAddresses, removedRegisteredAddresses, timestamp, transactions)
return blockchain.addBlock(block)
}

Expand Down Expand Up @@ -608,7 +608,7 @@ func (blockchain *Blockchain) verifyBlock(neighborBlock *Block, previousBlockTim
return fmt.Errorf("a neighbor block transaction timestamp is too old: transaction timestamp: %d, id: %s", transaction.Timestamp(), transaction.Id())
}
for _, output := range transaction.Outputs() {
if output.IsRegistered() {
if output.IsYielding() {
if err := blockchain.isRegistered(output.Address(), addedRegisteredAddresses, removedRegisteredAddresses); err != nil {
return err
}
Expand Down Expand Up @@ -691,13 +691,13 @@ func removeUtxo(utxos []*Utxo, transactionId string, outputIndex uint16) []*Utxo

func verifyIncomes(utxosByAddress map[string][]*Utxo) error {
for address, utxos := range utxosByAddress {
var hasIncome bool
var isYielding bool
for _, utxo := range utxos {
if utxo.IsRegistered() {
if hasIncome {
if utxo.IsYielding() {
if isYielding {
return fmt.Errorf("income requested for several UTXOs for address: %s", address)
}
hasIncome = true
isYielding = true
}
}
}
Expand Down
28 changes: 14 additions & 14 deletions src/node/protocol/verification/output.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,26 +5,26 @@ import (
)

type outputDto struct {
Address string `json:"address"`
IsRegistered bool `json:"is_registered"`
Value uint64 `json:"value"`
Address string `json:"address"`
IsYielding bool `json:"is_yielding"`
Value uint64 `json:"value"`
}

type Output struct {
address string
isRegistered bool
value uint64
address string
isYielding bool
value uint64
}

func NewOutput(address string, isRegistered bool, value uint64) *Output {
return &Output{address, isRegistered, value}
func NewOutput(address string, isYielding bool, value uint64) *Output {
return &Output{address, isYielding, value}
}

func (output *Output) MarshalJSON() ([]byte, error) {
return json.Marshal(outputDto{
Address: output.address,
IsRegistered: output.isRegistered,
Value: output.value,
Address: output.address,
IsYielding: output.isYielding,
Value: output.value,
})
}

Expand All @@ -35,7 +35,7 @@ func (output *Output) UnmarshalJSON(data []byte) error {
return err
}
output.address = dto.Address
output.isRegistered = dto.IsRegistered
output.isYielding = dto.IsYielding
output.value = dto.Value
return nil
}
Expand All @@ -44,8 +44,8 @@ func (output *Output) Address() string {
return output.address
}

func (output *Output) IsRegistered() bool {
return output.isRegistered
func (output *Output) IsYielding() bool {
return output.isYielding
}

func (output *Output) InitialValue() uint64 {
Expand Down
4 changes: 2 additions & 2 deletions src/node/protocol/verification/transaction.go
Original file line number Diff line number Diff line change
Expand Up @@ -25,8 +25,8 @@ type Transaction struct {
rewardValue uint64
}

func NewRewardTransaction(address string, hasIncome bool, timestamp int64, value uint64) (*Transaction, error) {
outputs := []*Output{NewOutput(address, hasIncome, value)}
func NewRewardTransaction(address string, isYielding bool, timestamp int64, value uint64) (*Transaction, error) {
outputs := []*Output{NewOutput(address, isYielding, value)}
var inputs []*Input
id, err := generateId(inputs, outputs, timestamp)
if err != nil {
Expand Down
8 changes: 4 additions & 4 deletions src/node/protocol/verification/utxo.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ import (
type utxoDto struct {
Address string `json:"address"`
Timestamp int64 `json:"timestamp"`
HasIncome bool `json:"has_income"`
IsYielding bool `json:"is_yielding"`
OutputIndex uint16 `json:"output_index"`
TransactionId string `json:"transaction_id"`
Value uint64 `json:"value"`
Expand All @@ -28,7 +28,7 @@ func (utxo *Utxo) MarshalJSON() ([]byte, error) {
return json.Marshal(utxoDto{
Address: utxo.Address(),
Timestamp: utxo.timestamp,
HasIncome: utxo.IsRegistered(),
IsYielding: utxo.IsYielding(),
OutputIndex: utxo.outputIndex,
TransactionId: utxo.transactionId,
Value: utxo.InitialValue(),
Expand All @@ -42,7 +42,7 @@ func (utxo *Utxo) UnmarshalJSON(data []byte) error {
return err
}
utxo.InputInfo = NewInputInfo(dto.OutputIndex, dto.TransactionId)
utxo.Output = NewOutput(dto.Address, dto.HasIncome, dto.Value)
utxo.Output = NewOutput(dto.Address, dto.IsYielding, dto.Value)
utxo.timestamp = dto.Timestamp
return nil
}
Expand All @@ -52,7 +52,7 @@ func (utxo *Utxo) Value(currentTimestamp int64, halfLifeInNanoseconds float64, i
return utxo.InitialValue()
}
x := float64(currentTimestamp - utxo.timestamp)
if utxo.IsRegistered() {
if utxo.IsYielding() {
return utxo.g(halfLifeInNanoseconds, incomeBase, incomeLimit, x)
} else {
return utxo.f(halfLifeInNanoseconds, x)
Expand Down
8 changes: 4 additions & 4 deletions src/ui/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -238,9 +238,9 @@ Example

```
{
"address": string
"is_registered": bool
"value": uint64
"address": string
"is_yielding": bool
"value": uint64
}
```
</td>
Expand All @@ -259,7 +259,7 @@ The value at the transaction timestamp
```
{
"address": "0xf14DB86A3292ABaB1D4B912dbF55e8abc112593a"
"has_income": true
"is_yielding": true
"value": 0
}
```
Expand Down
Loading

0 comments on commit c2e3808

Please sign in to comment.