From 14ab9697609215b178dd66e0d6e1a2367d9f4143 Mon Sep 17 00:00:00 2001 From: Chris Gianelloni Date: Tue, 5 Mar 2024 07:20:19 -0500 Subject: [PATCH] fix: nil pointers identified by nilaway (part 1) Signed-off-by: Chris Gianelloni --- bech32/bech32.go | 3 ++- cmd/common/cmdline.go | 12 ++++++++- cmd/gouroboros/chainsync.go | 3 +++ cmd/gouroboros/main.go | 12 ++++++++- cmd/tx-submission/main.go | 26 ++++++++----------- ledger/allegra.go | 21 ++++++++------- ledger/alonzo.go | 21 ++++++++------- ledger/babbage.go | 23 +++++++++-------- ledger/common.go | 2 ++ ledger/common_test.go | 6 +++++ ledger/conway.go | 21 ++++++++------- ledger/mary.go | 21 ++++++++------- ledger/shelley.go | 51 +++++++++++++++++++++---------------- 13 files changed, 136 insertions(+), 86 deletions(-) diff --git a/bech32/bech32.go b/bech32/bech32.go index 0c13cca7..5fe068cd 100644 --- a/bech32/bech32.go +++ b/bech32/bech32.go @@ -27,7 +27,8 @@ func toBytes(chars string) ([]byte, error) { for i := 0; i < len(chars); i++ { index := strings.IndexByte(charset, chars[i]) if index < 0 { - return nil, ErrNonCharsetChar(chars[i]) + // In the original code, this returns nil instead + return []byte{}, ErrNonCharsetChar(chars[i]) } decoded = append(decoded, byte(index)) } diff --git a/cmd/common/cmdline.go b/cmd/common/cmdline.go index 6eaa08e0..2cc219ed 100644 --- a/cmd/common/cmdline.go +++ b/cmd/common/cmdline.go @@ -33,8 +33,14 @@ type GlobalFlags struct { } func NewGlobalFlags() *GlobalFlags { + var name string + if os.Args == nil { + name = "gouroboros" + } else { + name = os.Args[0] + } f := &GlobalFlags{ - Flagset: flag.NewFlagSet(os.Args[0], flag.ExitOnError), + Flagset: flag.NewFlagSet(name, flag.ExitOnError), } f.Flagset.StringVar( &f.Socket, @@ -71,6 +77,10 @@ func NewGlobalFlags() *GlobalFlags { } func (f *GlobalFlags) Parse() { + if os.Args == nil { + fmt.Printf("failed to parse command line\n") + os.Exit(1) + } if err := f.Flagset.Parse(os.Args[1:]); err != nil { fmt.Printf("failed to parse command args: %s\n", err) os.Exit(1) diff --git a/cmd/gouroboros/chainsync.go b/cmd/gouroboros/chainsync.go index 7ca1f0ff..cc7771b5 100644 --- a/cmd/gouroboros/chainsync.go +++ b/cmd/gouroboros/chainsync.go @@ -294,6 +294,9 @@ func chainSyncRollForwardHandler( byronBlock.Hash(), ) default: + if block == nil { + return fmt.Errorf("block is nil") + } fmt.Printf( "era = %s, slot = %d, block_no = %d, id = %s\n", block.Era().Name, diff --git a/cmd/gouroboros/main.go b/cmd/gouroboros/main.go index f287fb93..9bda7ce8 100644 --- a/cmd/gouroboros/main.go +++ b/cmd/gouroboros/main.go @@ -35,8 +35,14 @@ type globalFlags struct { } func newGlobalFlags() *globalFlags { + var name string + if os.Args == nil { + name = "gouroboros" + } else { + name = os.Args[0] + } f := &globalFlags{ - flagset: flag.NewFlagSet(os.Args[0], flag.ExitOnError), + flagset: flag.NewFlagSet(name, flag.ExitOnError), } f.flagset.StringVar( &f.socket, @@ -73,6 +79,10 @@ func newGlobalFlags() *globalFlags { } func main() { + if os.Args == nil { + fmt.Printf("failed parsing command line\n") + os.Exit(1) + } f := newGlobalFlags() err := f.flagset.Parse(os.Args[1:]) if err != nil { diff --git a/cmd/tx-submission/main.go b/cmd/tx-submission/main.go index 4cc30f93..1b603e94 100644 --- a/cmd/tx-submission/main.go +++ b/cmd/tx-submission/main.go @@ -22,11 +22,9 @@ import ( "time" ouroboros "github.com/blinklabs-io/gouroboros" - "github.com/blinklabs-io/gouroboros/cbor" "github.com/blinklabs-io/gouroboros/cmd/common" + "github.com/blinklabs-io/gouroboros/ledger" "github.com/blinklabs-io/gouroboros/protocol/txsubmission" - - "golang.org/x/crypto/blake2b" ) type txSubmissionFlags struct { @@ -117,19 +115,17 @@ func main() { os.Exit(1) } - // Generate TX hash - // Unwrap raw transaction bytes into a CBOR array - var txUnwrap []cbor.RawMessage - if _, err := cbor.Decode(txBytes, &txUnwrap); err != nil { - fmt.Printf("ERROR: failed to unwrap transaction CBOR: %s", err) + // convert to tx + txType, err := ledger.DetermineTransactionType(txBytes) + if err != nil { + fmt.Printf("ERROR: could not parse transaction to determine type: %s", err) + os.Exit(1) + } + tx, err := ledger.NewTransactionFromCbor(txType, txBytes) + if err != nil { + fmt.Printf("failed to parse transaction CBOR: %s", err) os.Exit(1) } - // index 0 is the transaction body - // Store index 0 (transaction body) as byte array - txBody := txUnwrap[0] - - // Convert the body into a blake2b256 hash string - txHash = blake2b.Sum256(txBody) // Create our "done" channel doneChan = make(chan any) @@ -140,7 +136,7 @@ func main() { // Wait until we're done <-doneChan - fmt.Printf("Successfully sent transaction %x\n", txHash) + fmt.Printf("Successfully sent transaction %x\n", tx.Hash()) if err := o.Close(); err != nil { fmt.Printf("ERROR: failed to close connection: %s\n", err) diff --git a/ledger/allegra.go b/ledger/allegra.go index 3dc5d90b..e4d26e18 100644 --- a/ledger/allegra.go +++ b/ledger/allegra.go @@ -84,21 +84,24 @@ func (b *AllegraBlock) Transactions() []Transaction { } func (b *AllegraBlock) Utxorpc() *utxorpc.Block { - var block *utxorpc.Block - var body *utxorpc.BlockBody - var header *utxorpc.BlockHeader var txs []*utxorpc.Tx - header.Slot = b.SlotNumber() tmpHash, _ := hex.DecodeString(b.Hash()) - header.Hash = tmpHash - header.Height = b.BlockNumber() for _, t := range b.Transactions() { tx := t.Utxorpc() txs = append(txs, tx) } - body.Tx = txs - block.Body = body - block.Header = header + body := &utxorpc.BlockBody{ + Tx: txs, + } + header := &utxorpc.BlockHeader{ + Hash: tmpHash, + Height: b.BlockNumber(), + Slot: b.SlotNumber(), + } + block := &utxorpc.Block{ + Body: body, + Header: header, + } return block } diff --git a/ledger/alonzo.go b/ledger/alonzo.go index 24d74d51..1d3cf57c 100644 --- a/ledger/alonzo.go +++ b/ledger/alonzo.go @@ -94,21 +94,24 @@ func (b *AlonzoBlock) Transactions() []Transaction { } func (b *AlonzoBlock) Utxorpc() *utxorpc.Block { - var block *utxorpc.Block - var body *utxorpc.BlockBody - var header *utxorpc.BlockHeader var txs []*utxorpc.Tx - header.Slot = b.SlotNumber() tmpHash, _ := hex.DecodeString(b.Hash()) - header.Hash = tmpHash - header.Height = b.BlockNumber() for _, t := range b.Transactions() { tx := t.Utxorpc() txs = append(txs, tx) } - body.Tx = txs - block.Body = body - block.Header = header + body := &utxorpc.BlockBody{ + Tx: txs, + } + header := &utxorpc.BlockHeader{ + Hash: tmpHash, + Height: b.BlockNumber(), + Slot: b.SlotNumber(), + } + block := &utxorpc.Block{ + Body: body, + Header: header, + } return block } diff --git a/ledger/babbage.go b/ledger/babbage.go index 1751e5ca..6b10c5c0 100644 --- a/ledger/babbage.go +++ b/ledger/babbage.go @@ -94,21 +94,24 @@ func (b *BabbageBlock) Transactions() []Transaction { } func (b *BabbageBlock) Utxorpc() *utxorpc.Block { - var block *utxorpc.Block - var body *utxorpc.BlockBody - var header *utxorpc.BlockHeader var txs []*utxorpc.Tx - header.Slot = b.SlotNumber() tmpHash, _ := hex.DecodeString(b.Hash()) - header.Hash = tmpHash - header.Height = b.BlockNumber() for _, t := range b.Transactions() { tx := t.Utxorpc() txs = append(txs, tx) } - body.Tx = txs - block.Body = body - block.Header = header + body := &utxorpc.BlockBody{ + Tx: txs, + } + header := &utxorpc.BlockHeader{ + Hash: tmpHash, + Height: b.BlockNumber(), + Slot: b.SlotNumber(), + } + block := &utxorpc.Block{ + Body: body, + Header: header, + } return block } @@ -316,7 +319,7 @@ func (o BabbageTransactionOutput) DatumHash() *Blake2b256 { if o.DatumOption != nil { return o.DatumOption.hash } - return nil + return &Blake2b256{} } func (o BabbageTransactionOutput) Datum() *cbor.LazyValue { diff --git a/ledger/common.go b/ledger/common.go index 46f83cf0..871d0d08 100644 --- a/ledger/common.go +++ b/ledger/common.go @@ -375,6 +375,8 @@ func (a Address) MarshalJSON() ([]byte, error) { type IssuerVkey [32]byte func (i IssuerVkey) Hash() Blake2b224 { + // We can ignore the error return here because our fixed size/key arguments will + // never trigger an error hash, _ := blake2b.New(28, nil) hash.Write(i[:]) return Blake2b224(hash.Sum(nil)) diff --git a/ledger/common_test.go b/ledger/common_test.go index 78973272..70e1b842 100644 --- a/ledger/common_test.go +++ b/ledger/common_test.go @@ -237,6 +237,9 @@ func TestAddressPaymentAddress(t *testing.T) { if err != nil { t.Fatalf("failed to decode address: %s", err) } + if addr.PaymentAddress() == nil { + t.Fatalf("payment address is nil") + } if addr.PaymentAddress().String() != testDef.expectedPaymentAddress { t.Fatalf( "payment address did not match expected value, got: %s, wanted: %s", @@ -275,6 +278,9 @@ func TestAddressStakeAddress(t *testing.T) { if err != nil { t.Fatalf("failed to decode address: %s", err) } + if addr.StakeAddress() == nil { + t.Fatalf("stake address is nil") + } if addr.StakeAddress().String() != testDef.expectedStakeAddress { t.Fatalf( "stake address did not match expected value, got: %s, wanted: %s", diff --git a/ledger/conway.go b/ledger/conway.go index df7161de..a0221da0 100644 --- a/ledger/conway.go +++ b/ledger/conway.go @@ -93,21 +93,24 @@ func (b *ConwayBlock) Transactions() []Transaction { } func (b *ConwayBlock) Utxorpc() *utxorpc.Block { - var block *utxorpc.Block - var body *utxorpc.BlockBody - var header *utxorpc.BlockHeader var txs []*utxorpc.Tx - header.Slot = b.SlotNumber() tmpHash, _ := hex.DecodeString(b.Hash()) - header.Hash = tmpHash - header.Height = b.BlockNumber() for _, t := range b.Transactions() { tx := t.Utxorpc() txs = append(txs, tx) } - body.Tx = txs - block.Body = body - block.Header = header + body := &utxorpc.BlockBody{ + Tx: txs, + } + header := &utxorpc.BlockHeader{ + Hash: tmpHash, + Height: b.BlockNumber(), + Slot: b.SlotNumber(), + } + block := &utxorpc.Block{ + Body: body, + Header: header, + } return block } diff --git a/ledger/mary.go b/ledger/mary.go index ca18897e..d1ea8387 100644 --- a/ledger/mary.go +++ b/ledger/mary.go @@ -85,21 +85,24 @@ func (b *MaryBlock) Transactions() []Transaction { } func (b *MaryBlock) Utxorpc() *utxorpc.Block { - var block *utxorpc.Block - var body *utxorpc.BlockBody - var header *utxorpc.BlockHeader var txs []*utxorpc.Tx - header.Slot = b.SlotNumber() tmpHash, _ := hex.DecodeString(b.Hash()) - header.Hash = tmpHash - header.Height = b.BlockNumber() for _, t := range b.Transactions() { tx := t.Utxorpc() txs = append(txs, tx) } - body.Tx = txs - block.Body = body - block.Header = header + body := &utxorpc.BlockBody{ + Tx: txs, + } + header := &utxorpc.BlockHeader{ + Hash: tmpHash, + Height: b.BlockNumber(), + Slot: b.SlotNumber(), + } + block := &utxorpc.Block{ + Body: body, + Header: header, + } return block } diff --git a/ledger/shelley.go b/ledger/shelley.go index 79f26787..6d33f2bb 100644 --- a/ledger/shelley.go +++ b/ledger/shelley.go @@ -84,21 +84,24 @@ func (b *ShelleyBlock) Transactions() []Transaction { } func (b *ShelleyBlock) Utxorpc() *utxorpc.Block { - var block *utxorpc.Block - var body *utxorpc.BlockBody - var header *utxorpc.BlockHeader var txs []*utxorpc.Tx - header.Slot = b.SlotNumber() tmpHash, _ := hex.DecodeString(b.Hash()) - header.Hash = tmpHash - header.Height = b.BlockNumber() for _, t := range b.Transactions() { tx := t.Utxorpc() txs = append(txs, tx) } - body.Tx = txs - block.Body = body - block.Header = header + body := &utxorpc.BlockBody{ + Tx: txs, + } + header := &utxorpc.BlockHeader{ + Hash: tmpHash, + Height: b.BlockNumber(), + Slot: b.SlotNumber(), + } + block := &utxorpc.Block{ + Body: body, + Header: header, + } return block } @@ -216,28 +219,32 @@ func (b *ShelleyTransactionBody) TTL() uint64 { } func (b *ShelleyTransactionBody) Utxorpc() *utxorpc.Tx { - var tx *utxorpc.Tx var txi []*utxorpc.TxInput + var txo []*utxorpc.TxOutput for _, i := range b.Inputs() { input := i.Utxorpc() txi = append(txi, input) } - tx.Inputs = txi - var txo []*utxorpc.TxOutput for _, o := range b.Outputs() { output := o.Utxorpc() txo = append(txo, output) } - tx.Outputs = txo - tx.Fee = b.Fee() - // tx.Validity = b.Validity() - // tx.Certificates = b.Certificates() - // tx.Withdrawals = b.Withdrawals() - // tx.Witnesses = b.Witnesses() - // tx.Successful = b.Successful() - // tx.Auxiliary = b.AuxData() - tmpHash, _ := hex.DecodeString(b.Hash()) - tx.Hash = tmpHash + tmpHash, err := hex.DecodeString(b.Hash()) + if err != nil { + return &utxorpc.Tx{} + } + tx := &utxorpc.Tx { + Inputs: txi, + Outputs: txo, + Fee: b.Fee(), + Hash: tmpHash, + // Certificates: b.Certificates(), + // Validity: b.Validity(), + // Withdrawals: b.Withdrawals(), + // Witnesses: b.Witnesses(), + // Successful: b.Successful(), + // Auxiliary: b.AuxData(), + } return tx }